diff level1/modules/rbdw.asm @ 2724:05b648103e78 lwtools-port

Renamed dw3.sb to dwio.sb and rbdw3 to rbdw
author Boisy Pitre <boisy.pitre@nuance.com>
date Mon, 30 Jul 2012 19:35:05 -0500
parents level1/modules/rbdw3.asm@329fc1f6319f
children 28ed72477814
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/rbdw.asm	Mon Jul 30 19:35:05 2012 -0500
@@ -0,0 +1,400 @@
+********************************************************************
+* rbdw - DriveWire RBF driver
+*
+* $Id$
+*
+* This driver works in conjuction with the DriveWire Server on Linux,
+* Mac or Windows, providing the CoCo with pseudo-disk access through
+* the serial port.
+*
+* It adheres to the DriveWire Version 3 Protocol.
+*
+* The baud rate is set at 115200 and the communications requirements
+* are set to 8-N-1.  For OS-9 Level One on a CoCo 2, the baud rate
+* is 57600.
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2008/02/08  Boisy G. Pitre
+* Started from drivewire.asm in DriveWire 2 Product folder.
+*
+*   2      2008/04/22  Boisy G. Pitre
+* Verified working operation on a CoCo 3 running NitrOS-9/6809 Level 1 @ 57.6Kbps
+*
+*   3      2009/03/09  Boisy G. Pitre
+* Added checks for size after reading as noted by Darren A's email.
+*
+*   4      2009/12/31  Boisy G. Pitre
+* Fixed a crash in Term by adding a check for DWSubAddr of $0000 
+* (possible if Init fails due to subroutine module not being in
+*  memory and I$Detach calls Term)
+
+         nam   rbdw
+         ttl   DriveWire RBF driver
+
+NUMRETRIES equ  8
+
+         ifp1
+         use   defsfile
+         use   drivewire.d
+         endc
+
+NumDrvs  set   4
+
+tylg     set   Drivr+Objct   
+atrv     set   ReEnt+rev
+rev      set   $01
+edition  set   4
+
+         mod   eom,name,tylg,atrv,start,size
+
+         rmb   DRVBEG+(DRVMEM*NumDrvs)
+driveno  rmb   1
+retries  rmb   1
+size     equ   .
+
+         fcb   DIR.+SHARE.+PEXEC.+PREAD.+PWRIT.+EXEC.+UPDAT.
+
+name     fcs   /rbdw/
+         fcb   edition
+
+start    bra   Init
+         nop
+         lbra   Read
+         lbra  Write
+         lbra  GetStat
+         lbra  SetStat
+
+* Term
+*
+* Entry:
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Term
+         clrb
+         pshs cc
+* Send OP_TERM to the server
+          IFGT  LEVEL-1
+         ldu   <D.DWSubAddr
+         ELSE
+         ldu   >D.DWSubAddr
+         ENDC
+* Fix crash in certain cases
+         beq   no@
+         ldy   #$0001
+         lda   #OP_TERM
+         pshs a
+         leax ,s
+         orcc  #IntMasks
+         jsr   DW$Write,u
+         clrb
+         puls a
+no@      puls cc,pc
+
+* Init
+*
+* Entry:
+*    Y  = address of device descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Init
+         IFGT  Level-1
+* Perform this so we can successfully do F$Link below
+         ldx   <D.Proc
+         pshs  a,x
+         ldx   <D.SysPrc
+         stx   <D.Proc 
+         ELSE
+         pshs  a
+         ENDC
+
+         ldb   #NumDrvs
+         stb   V.NDRV,u
+         leax  DRVBEG,u
+         lda   #$FF
+Init2    sta   DD.TOT,x			invalidate drive tables
+         sta   DD.TOT+1,x
+         sta   DD.TOT+2,x
+         leax  DRVMEM,x
+         decb
+         bne   Init2
+
+* Check if subroutine module has already been linked
+         IFGT  LEVEL-1
+         ldu   <D.DWSubAddr
+         ELSE
+         ldu   >D.DWSubAddr
+         ENDC
+         bne   InitEx
+* Link to subroutine module
+         clra
+         leax  dwiosub,pcr
+         os9   F$Link
+         bcs   InitEx 
+         tfr   y,u		 
+         IFGT  LEVEL-1
+         stu   <D.DWSubAddr
+         ELSE
+         stu   >D.DWSubAddr
+         ENDC
+* Initialize the low level device
+         jsr   DW$Init,u
+         lda   #OP_INIT
+         sta   ,s
+         leax  ,s
+         ldy   #$0001
+         jsr   DW$Write,u
+         clrb
+
+InitEx
+         IFGT  Level-1
+         puls  a,x
+         stx   <D.Proc
+InitEx2
+         rts
+         ELSE
+InitEx2
+         puls  a,pc
+         ENDC
+
+* Read
+*
+* Entry:
+*    B  = MSB of LSN
+*    X  = LSB of LSN
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Read 
+         lda   #NUMRETRIES
+         sta   retries,u
+         cmpx  #$0000			LSN 0?
+         bne   ReadSect			branch if not
+         tstb	   			LSN 0?
+         bne   ReadSect			branch if not
+* At this point we are reading LSN0
+         bsr   ReadSect			read the sector
+         bcs   CpyLSNEx			if error, exit
+         leax  DRVBEG,u			point to start of drive table
+         ldb   <PD.DRV,y		get drive number
+NextDrv  beq   CopyLSN0			branch if terminal count
+         leax  <DRVMEM,x		else move to next drive table entry
+         decb				decrement counter
+         bra   NextDrv			and continue
+CopyLSN0 ldb   #DD.SIZ			get size to copy
+         ldy   PD.BUF,y			point to buffer
+CpyLSNLp lda   ,y+			get byte from buffer
+         sta   ,x+			and save in drive table
+         decb
+         bne   CpyLSNLp
+CpyLSNEx rts
+
+
+ReadSect pshs  cc
+         pshs  u,y,x,b,a,cc			then push CC and others on stack
+* Send out op code and 3 byte LSN
+         lda   PD.DRV,y			get drive number
+         cmpa  #NumDrvs
+         blo   Read1
+         ldb   #E$Unit
+         bra   ReadEr2
+Read1    sta   driveno,u
+         lda   #OP_READEX		load A with READ opcode
+         
+Read2
+         ldb   driveno,u
+         leax  ,s
+         std   ,x
+         ldy   #5 
+         IFGT  LEVEL-1
+         ldu   <D.DWSubAddr
+         ELSE
+         ldu   >D.DWSubAddr
+         ENDC
+         orcc  #IntMasks
+         jsr   DW$Write,u
+		 
+* Get 256 bytes of sector data
+         ldx   5,s
+         ldx   PD.BUF,x			get buffer pointer into X
+         ldy   #$0100
+         jsr   DW$Read,u
+         bcs   ReadEr1
+         bne   ReadEr1
+         pshs  y
+         leax  ,s
+         ldy   #$0002
+         jsr   DW$Write,u				write checksum to server
+
+* Get error code byte
+         leax  ,s
+         ldy   #$0001
+         jsr   DW$Read,u
+         puls  d
+         bcs   ReadEr0			branch if we timed out
+         bne   ReadEr0
+         tfr   a,b				transfer byte to B (in case of error)
+         tstb					is it zero?
+         beq   ReadEx			if not, exit with error
+         cmpb  #E$CRC
+         bne   ReadEr2
+         ldu   7,s				get U from stack
+         dec   retries,u		decrement retries
+         beq   ReadEr1
+         
+         lda   #OP_REREADEX		reread opcode
+         bra   Read2			and try getting sector again
+ReadEr0 
+ReadEr1  ldb   #E$Read			read error
+ReadEr2  lda   9,s
+         ora   #Carry
+         sta   9,s
+ReadEx   leas  5,s
+         puls  y,u
+         puls  cc,pc
+
+* Write
+*
+* Entry:
+*    B  = MSB of LSN
+*    X  = LSB of LSN
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Write    lda   #NUMRETRIES
+         sta   retries,u
+         pshs  cc
+         pshs  u,y,x,b,a,cc
+         ENDC
+* Send out op code and 3 byte LSN
+         lda   PD.DRV,y
+         cmpa  #NumDrvs
+         blo   Write1
+         comb			set Carry
+         ldb   #E$Unit
+         bra   WritEx
+Write1   sta   driveno,u
+         lda   #OP_WRITE
+Write15
+         ldb   driveno,u
+         leax  ,s
+         std   ,x
+         ldy   #$0005
+         IFGT  LEVEL-1
+         ldu   <D.DWSubAddr
+         ELSE
+         ldu   >D.DWSubAddr
+         ENDC
+         orcc  #IntMasks
+         jsr   DW$Write,u
+
+* Compute checksum on sector we just sent and send checksum to server
+         ldy   5,s				get Y from stack
+         ldx   PD.BUF,y			point to buffer
+         ldy   #256
+         jsr   6,u
+         leax  -256,x
+         bsr   DoCSum
+         pshs  d
+         leax  ,s
+         ldy   #$0002
+         jsr   DW$Write,u
+
+* Await acknowledgement from server on receipt of sector
+         leax  ,s
+         ldy   #$0001
+         jsr   DW$Read,u				read ack byte from server
+         bcs   WritEx0
+         bne   WritEx0
+         puls  d				  
+         tsta
+         beq   WritEx			yep
+         tfr   a,b
+         cmpb  #E$CRC			checksum error?
+         bne   WritEx2
+         ldu   7,s				get U from stack
+         dec   retries,u		decrement retries
+         beq   WritEx1			exit with error if no more
+         lda   #OP_REWRIT		else resend
+         bra   Write15
+WritEx0  puls  d
+WritEx1  ldb   #E$Write
+WritEx2  lda   9,s
+         ora   #Carry
+         sta   9,s
+WritEx   leas  5,s
+         puls  y,u
+         puls  cc,pc
+ 
+         use   dwcheck.asm
+		 
+* SetStat
+*
+* Entry:
+*    R$B = function code
+*    Y   = address of path descriptor
+*    U   = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+SetStat  lda   #OP_SETSTA
+* Size optimization
+		 fcb   $8C  skip next two bytes
+
+
+* GetStat
+*
+* Entry:
+*    R$B = function code
+*    Y   = address of path descriptor
+*    U   = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+GetStat  
+         lda   #OP_GETSTA
+         clrb				clear Carry
+         pshs  cc			and push CC on stack
+         leas  -3,s
+         sta   ,s
+         lda   PD.DRV,y			get drive number
+         ldx   PD.RGS,y
+         ldb   R$B,x
+         std   1,s
+         leax  ,s
+         ldy   #$0003
+         IFGT  LEVEL-1
+         ldu   <D.DWSubAddr
+         ELSE
+         ldu   >D.DWSubAddr
+         ENDC
+         jsr   6,u
+         leas  3,s
+         puls  cc,pc
+
+dwiosub  fcs   /dwio/
+		 
+         emod
+eom      equ   *
+         end