[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