[Coco] drivewire serial port: term_win80.dt vs my code
Aaron Wolfe
aawolfe at gmail.com
Mon Nov 9 01:36:20 EST 2009
So, things were going so well with my serial over DW project that I
decided to merge the driver into my main boot disk.
(My test system was level 1 just because it builds faster and I have
to build a lot)
I've discovered that when I use term_win80 for my coco terminal, i
make my coco insane whenever I try to access my virtual serial port.
read or write makes no difference. The console goes nuts, usually
switching graphics modes or losing sync altogether and writing
randomish junk everywhere on the screen. no response to keys.
Meanwhile, the operation I invoked on the serial port will actually
run for a few seconds until the machine goes completely out to lunch,
so I can at least see that read and write ops in my driver are
actually working, despite whatever else my driver is doing to the
system.
Switching the console driver to VDG makes everything work fine again..
level 2, 6309, etc all working great with the driver under heavy use.
Any ideas what I've done here? I'm assuming I have some bug in my
driver that so far only surfaces when term_win80 is around, but I'm
worried it will show up in other places too. I'm not even sure how to
test this, again apologies for my massive ignorance.
If anyone wants to look, here is the driver code as of now:
********************************************************************
* scdwp.asm - CoCo DriveWire Virtual Serial Driver
*
* most parts copied or only slightly modified from other modules in
the DriveWire project
*
* Aaron Wolfe
* v0.1 11/08/09
*
nam scdws
ttl CoCo DriveWire Virtual Serial Driver
ifp1
use defsfile
use dwdefs.d
endc
tylg set Drivr+Objct
atrv set ReEnt+Rev
rev set $00
edition set 1
mod eom,name,tylg,atrv,Start,Size
fcb READ.+WRITE.
name fcs /scdws/
fcb edition one more revision level than the stock printer
* Device memory area: offset from U
org V.SCF V.SCF: free memory for driver to use
V.PAR rmb 1 1=space, 2=mark parity
V.BIT rmb 1 0=7, 1=8 bits
V.STP rmb 1 0=1 stop bit, 1=2 stop bits
V.COM rmb 2 Com Status baud/parity (=Y from SS.Comst Set/GetStt
V.COL rmb 1 columns
V.ROW rmb 1 rows
V.WAIT rmb 2 wait count for baud rate?
V.TRY rmb 2 number of re-tries if printer is busy
V.RTRY rmb 1 low nibble of parity=high byte of number of retries
V.BUFF rmb $80 room for 128 blocked processes
RSleep rmb 1
size equ .
start equ *
lbra Init
lbra Read
lbra Write
lbra GetStt
lbra SetStt
* Term
*
* Entry:
* U = address of device memory area
*
* Exit:
* CC = carry set on error
* B = error code
*
Term equ *
clrb
rts
* Init
*
* Entry:
* Y = address of device descriptor
* U = address of device memory area
*
* Exit:
* CC = carry set on error
* B = error code
*
Init
* set RSleep to 0
clra
sta <RSleep
* Check if D.DWSUB already holds a valid subroutine module pointer
IFGT Level-1
ldx <D.DWSUB
ELSE
ldx >D.DWSUB
ENDC
bne InitEx
* If here, D.DWSUB is 0, so we must link to subroutine module
IFGT Level-1
ldx <D.Proc
pshs x
ldx <D.SysPrc
stx <D.Proc
ENDC
clra
leax dw3name,pcr
os9 F$Link
IFGT Level-1
puls x
stx <D.Proc
ENDC
bcs InitEx
IFGT Level-1
sty <D.DWSUB
ELSE
sty >D.DWSUB
ENDC
jsr ,y call init routine
InitEx rts
dw3name fcs /dw3/
* Write
*
* Entry:
* A = character to write
* Y = address of path descriptor
* U = address of device memory area
*
* Exit:
* CC = carry set on error
* B = error code
*
Write equ *
tfr a,b
lda #OP_SERWRITE
pshs d
leax ,s
ldy #$0002
IFGT Level-1
ldu <D.DWSUB
ELSE
ldu >D.DWSUB
ENDC
jsr 6,u
* handle errors
beq WriteOK
ldb #E$Write
bra WriteExit
WriteOK clrb
WriteExit puls d,pc
* Read - my crazy attempt
Read equ *
* see if we should sleep some more - this has got to be the wrong way to do this
lda <RSleep
cmpa #$00
bne ReadSleepAgain
* check if we have data waiting on server
lda #OP_SERCHECK
pshs a
leax ,s
ldy #$0001
IFGT Level-1
ldu <D.DWSUB
ELSE
ldu >D.DWSUB
ENDC
jsr 6,u
ldy #$0001
leax ,s
jsr 3,u
puls a
cmpa #$00 ; if 00, server buffer is empty
bne ReadFromServer
* nothing, lets sleep and try again
lda #$FF ; sleep 256 slices, this seems to = about 8-10
polls per second..
sta <RSleep
ReadSleep ldx #$0001
os9 F$Sleep ; sleep for this slice, try again next slice -
probably very wasteful
bra Read
ReadSleepAgain
* dec sleep counter - its already in A
deca
sta <RSleep
bra ReadSleep
ReadFromServer
lda #OP_SERREAD
pshs a
leax ,s
ldy #$0001
IFGT Level-1
ldu <D.DWSUB
ELSE
ldu >D.DWSUB
ENDC
* ask for byte
jsr 6,u
ldy #$0001
leax ,s
* read byte from server
jsr 3,u
* handle errors
beq ReadOK
ldb #E$Read
bra ReadExit
ReadOK clrb
ReadExit puls a,pc
* GetStat
*
* Entry:
* A = function code
* Y = address of path descriptor
* U = address of device memory area
*
* Exit:
* CC = carry set on error
* B = error code
*
GetStt cmpa #SS.EOF end of file?
bne L0112
clrb if so, exit with no error
rts
L0112 ldx PD.RGS,y
cmpa #SS.ScSiz
beq L0123
cmpa #SS.ComSt
bne L0173
clra
clrb
std R$Y,x
clrb
rts
* get screen size GetStt
L0123 clra
ldb #80
std R$X,x
ldb #24
std R$Y,x
clrb
rts
* SetStat
*
* Entry:
* A = function code
* Y = address of path descriptor
* U = address of device memory area
*
* Exit:
* CC = carry set on error
* B = error code
*
SetStt
Close cmpa #SS.Close close the device?
bne L0173
lda #OP_NOP
pshs a
ldy #$0001
leax ,s
IFGT Level-1
ldu <D.DWSUB
ELSE
ldu >D.DWSUB
ENDC
jsr 6,u
puls a,pc
L0173 comb
ldb #E$UnkSVc
rts
emod
eom equ *
end
More information about the Coco
mailing list