changeset 1320:68bc2285ea17

Back-ported from OS-9 Level Two
author boisy
date Thu, 04 Sep 2003 20:43:25 +0000
parents 11e1351de632
children acc63d0452bd
files level1/modules/p_bbp.asm level1/modules/printer.asm
diffstat 2 files changed, 315 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/level1/modules/p_bbp.asm	Thu Sep 04 20:43:11 2003 +0000
+++ b/level1/modules/p_bbp.asm	Thu Sep 04 20:43:25 2003 +0000
@@ -1,20 +1,18 @@
 ********************************************************************
-* P - CoCo serial printer device descriptor
+* P - CoCo serial priner device descriptor
 *
 * $Id$
 *
 * Ed.    Comments                                       Who YY/MM/DD
 * ------------------------------------------------------------------
-*        From Tandy OS-9 Level One VR 02.00.00
 
          nam   P
-         ttl   CoCo serial printer device descriptor
+         ttl   CoCo serial priner device descriptor
 
 * Disassembled 98/08/23 21:15:24 by Disasm v1.6 (C) 1988 by RML
 
          ifp1  
          use   defsfile
-         use   scfdefs
          endc  
 
 tylg     set   Devic+Objct
@@ -24,8 +22,8 @@
          mod   eom,name,tylg,atrv,mgrnam,drvnam
 
          fcb   READ.+WRITE. mode byte
-         fcb   HW.Page    extended controller address
-         fdb   $0000      physical controller address
+         fcb   $07        extended controller address
+         fdb   $FF22      physical controller address
          fcb   initsize-*-1 initilization table size
          fcb   DT.SCF     device type:0=scf,1=rbf,2=pipe,3=scf
          fcb   $00        case:0=up&lower,1=upper only
@@ -56,9 +54,9 @@
          fcb   66         (szy) number of rows for display
 initsize equ   *
 
-name     fcs   /P/
+name     fcs   /p/
 mgrnam   fcs   /SCF/
-drvnam   fcs   /PRINTER/
+drvnam   fcs   /Printer/
 
          emod  
 eom      equ   *
--- a/level1/modules/printer.asm	Thu Sep 04 20:43:11 2003 +0000
+++ b/level1/modules/printer.asm	Thu Sep 04 20:43:25 2003 +0000
@@ -1,67 +1,111 @@
 ********************************************************************
-* PRINTER - CoCo serial port printer driver
+* Printer - CoCo Serial Printer Driver
 *
 * $Id$
 *
-* Ed.    Comments                                       Who YY/MM/DD
+* Enhanced and re-written by Alan DeKok
+*
+* Problems with original:
+*   returns wrong error on Read/SetStt
+*   doesn't block output.  The printer is a single-user device!
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
 * ------------------------------------------------------------------
-*  10    From Tandy OS-9 Level One VR 02.00.00
+*  13      2003/01/05  Boisy G. Pitre
+* Back-ported to OS-9 Level Two.
+*
+*          2003/09/04  Boisy G. Pitre
+* Back-ported to OS-9 Level One.
 
-         nam   PRINTER
-         ttl   CoCo serial port printer driver
-
-* Disassembled 98/08/23 17:32:06 by Disasm v1.6 (C) 1988 by RML
+         nam   Printer
+         ttl   CoCo Serial Printer Driver
 
          ifp1
          use   defsfile
-	 use   scfdefs
          endc
 
-tylg     set   Drivr+Objct
-atrv     set   ReEnt+rev
+tylg     set   Drivr+Objct   
+atrv     set   ReEnt+Rev
 rev      set   $00
-edition  set   10
+edition  set   13
+
+         mod   eom,name,tylg,atrv,Start,Size
 
-         mod   eom,name,tylg,atrv,start,size
+         fcb   READ.+WRITE.
+
+name     fcs   /Printer/
+         fcb   edition    one more revision level than the stock printer
 
-         rmb   V.SCF
-u001D    rmb   1
-u001E    rmb   1
-u001F    rmb   1
-u0020    rmb   2
-u0022    rmb   1
-u0023    rmb   1
-u0024    rmb   2
-u0026    rmb   2
-u0028    rmb   1
+* 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
 size     equ   .
 
-         fcb   UPDAT.
-
-name     fcs   /PRINTER/
-         fcb   edition
+* Baud Rate Delay Table
+BaudDly  equ   *
+         IFEQ  Level-1
+* OS-9 Level One delay values (0.89MHz)
+         fdb   $0482    110 baud
+         fdb   $01A2    300 baud
+         fdb   $00CD    600 baud
+         fdb   $0063    1200 baud
+         fdb   $002D    2400 baud
+         fdb   $0013    4800 baud
+         fdb   $0005    9600 baud
+         ELSE
+         IFEQ  NitrOS9
+* OS-9 Level Two delay values (1.78MHz)
+         fdb   $090C    110 baud
+         fdb   $034C    300 baud
+         fdb   $01A2    600 baud
+         fdb   $00CE    1200 baud
+         fdb   $0062    2400 baud
+         fdb   $002E    4800 baud
+         fdb   $0012    9600 baud
+         fdb   $0003    32000 baud
+         ELSE   
+* NitrOS-9 Level Two delay values (1.78MHz)
+         fdb   $090C    110 baud (Unchanged, unknown)
+         fdb   $03D0    300 baud
+         fdb   $01A2    600 baud (Unchanged, unknown)
+         fdb   $00F0    1200 baud
+         fdb   $0073    2400 baud
+         fdb   $0036    4800 baud
+         fdb   $0017    9600 baud
+         fdb   $0003    32000 baud (Unchanged, unknown)
+         ENDC
+         ENDC
 
-L0016    fcb   $04
-         fcb   $82
-         fcb   $01
-         fcb   $A2 "
-         fcb   $00
-         fcb   $CD M
-         fcb   $00
-         fcb   $63 c
-         fcb   $00
-         fcb   $2D -
-         fcb   $00
-         fcb   $13
-         fcb   $00
-         fcb   $05
 
-start    lbra  Init
+start    equ   *
+         lbra  Init
          lbra  Read
          lbra  Write
-         lbra  GetStat
-         lbra  SetStat
-         lbra  Term
+         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
 *
@@ -73,55 +117,52 @@
 *    CC = carry set on error
 *    B  = error code
 *
-Init     pshs  cc
-         orcc  #IntMasks
+Init     orcc  #IntMasks
          ldx   #PIA1Base
          clr   $01,x
-         ldd   <IT.COL,y		get column size
-         std   <u0022,u
+         ldd   <IT.COL,y	get number of columns/rows
+         std   <V.COL,u 	save it in statics
          lda   #$FE
          sta   ,x
          lda   #$36
          sta   $01,x
          lda   ,x
-         ldd   <IT.PAR,y		get parity/baud
-         lbsr  L0155
-         puls  cc
-         lbsr  L0104
-         lbcs  L0100
-
-* Term
-*
-* Entry:
-*    U  = address of device memory area
-*
-* Exit:
-*    CC = carry set on error
-*    B  = error code
-*
-Term     rts
+         andcc #^IntMasks
+         ldd   <IT.PAR,y	parity and baud rate
+         lbsr  L0138		setup parity/baud in device memory
+         lbsr  L0104		get low bit of $FF22 into carry
+         lbcs  L0100		it's the ready flag
+* clear out buffer
+         leax  V.BUFF,u   room for 128 blocked processes
+         ldb   #128
+I010     clr   ,x+        we're more concerned with room
+         decb             than with speed, so we don't use TFM
+         bne   I010
+         rts
 
-L005F    pshs  a
-         lda   <$35,y
-         anda  #$0F
-         cmpa  #$07
-         bcc   L0076
-         lsla
-         leax  <L0016,pcr
-         ldd   a,x
-         std   <u0024,u
-         clrb
-         puls  pc,a
-L0076    ldb   #E$BMode
-         puls  a
-L007A    orcc  #Carry
+L005F    ldb   <PD.BAU,y	get baud rate in path desc.
+         andb  #$0F		keep lower nibble
+         cmpb  #$07		compare against highest
+         lbhs  Read
+         aslb  
+         leax  <BaudDly,pc	table of delay times
+         ldx   b,x		get delay counter
+         stx   <V.WAIT,u	save it off
+         clrb  
          rts
+
+Bit_2    ldb   #$02
 L007D    stb   >PIA1Base
-L0080    pshs  b,a
-         ldd   <u0024,u
-L0085    subd  #$0001
+L0080    pshs  d
+         ldd   <V.WAIT,u	get wait count for baud rate
+L0085    equ   *
+         IFNE  H6309
+         decd             count down by one
+         ELSE
+         subd  #$0001
+         ENDC
          bne   L0085
-         puls  pc,b,a
+         puls  pc,d
 
 * Write
 *
@@ -134,81 +175,135 @@
 *    CC = carry set on error
 *    B  = error code
 *
-Write    bsr   L005F
-         bcs   L007A
-         pshs  b,a
-         bsr   L00CB
-         puls  b,a
-         bcs   L0100
-         ldb   #$09
-         pshs  b,cc
-         orcc  #IntMasks
-         tst   <u001E,u
-         beq   L00A5
-         dec   $01,s
-L00A5    andcc #^Carry
-L00A7    ldb   #$02
-         bcs   L00AC
+Write    equ   *
+         leax  V.BUFF,u   point to the buffer
+         ldb   V.BUSY,u   get my process number
+         tst   ,x         get allowed process number
+         bne   W010       if not zero, else
+         stb   ,x         I'm the only one allowed to use it
+
+W010     cmpb  ,x         am I allowed to use /p?
+         beq   W030       if yes, go write a character
+
+***************************************************************
+* WARNING: If more than 128 processes try to use the printer,
+* this will CRASH BADLY.  Since Level II on the Coco is limited
+* to 32 processes, I don't think it's a problem.
+***************************************************************
+
+W020     tst   ,x+		if not, find the first non-zero entry
+         bne   W020
+         stb   -1,x		and save my process number at the first zero
+         pshs  a
+         lda   V.BUFF,u		process that's allowed to use /p
+         sta   V.BUSY,u		make it the busy one
+         ldb   #S$Wake		wake it up
+         os9   F$Send		send a signal to wake it
+         IFNE  H6309
+         tfr   0,x
+         ELSE
+         ldx   #$0000
+         ENDC
+         os9   F$Sleep		and go to sleep forever
+         puls  a		restore character to be sent, and continue
+
+W030     bsr   L005F		set up baud rate, etc in memory
+         bcs   L00CA
+         pshs  a
+         bsr   L00CB      make sure that the device is ready
+         puls  a
+         bcs   L00CA      if the device is not ready
+         IFNE  H6309
+         lde   #$09       9 bits to send out
+         ELSE
+         pshs b,a
+         lda  #$09
+         sta  1,s
+         puls a
+         ENDC
+         orcc  #IntMasks  turn off interrupts
+         tst   <V.BIT,u   number of bits
+         beq   L00AC      if 7 bits, count down by one
+         IFNE  H6309
+         dece             initially send out start bit
+         ELSE
+         dec   ,s
+         ENDC
+
+L00AC    bsr   L007D      write B to $FF20 and wait
          clrb
-L00AC    bsr   L007D
-         lsra
-         dec   $01,s
-         bne   L00A7
-         ldb   <u001D,u
-         beq   L00BC
-         andb  #$FE
-         bsr   L007D
-L00BC    ldb   #$02
-         bsr   L007D
-         tst   <u001F,u
+         lsra             move A into carry
+         rolb
+         rolb
+         IFNE  H6309
+         dece             count down on the number of bits to send
+         ELSE
+         dec   ,s
+         ENDC
+         bne   L00AC
+         IFEQ  H6309
+         puls  b
+         ENDC
+         ldb   <V.PAR,u		space/mark parity
+         beq   L00BC		0=no parity
+         andb  #$FE		1=space, 0=mark parity
+* should be andb #$FD I think...
+         bsr   L007D		dump out parity
+L00BC    bsr   Bit_2		and a stop bit
+         tst   <V.STP,u		do another one?
          beq   L00C9
-         ldb   #$02
-         bsr   L007D
-L00C9    puls  pc,b,cc
-L00CB    clra
+         bsr   Bit_2		yes, dump out another stop bit
+L00C9    andcc #^IntMasks
+L00CA    rts
+
+L0104    pshs  b
+         ldb   >PIA1Base+$02	get a byte
+         lsrb  
+         puls  pc,b
+
+L00CB    equ   *
+         IFNE  H6309
+         clrd
+         ELSE
+         clra
          clrb
-         std   <u0026,u
+         ENDC
+         std   <V.TRY,u
 L00D0    ldd   #$0303
-L00D3    bsr   L0104
-         bcs   L00DE
-         bsr   L0080
-         decb
-         bne   L00D3
-         clrb
-         rts
-L00DE    bsr   L0080
-         deca
+L00D3    bsr   L0104		get device ready status
+         bcs   L00DE		if not ready, wait for a bit
+         IFNE  H6309
+         bsr   L0080		wait
+         ELSE
+         lbsr  L0080		wait
+         ENDC
+         decb  
+         bne   L00D3		try again
+         clrb  
+         rts   
+
+L00DE    lbsr  L0080		wait for a while
+         deca			try 3 times,
          bne   L00D3
          pshs  x
          ldx   #$0001
-         os9   F$Sleep
+         os9   F$Sleep		sleep for the rest of this tick
          puls  x
-         ldd   <u0026,u
+         ldd   <V.TRY,u
+         IFNE  H6309
+         incd			we've tried once more and failed...
+         ELSE
          addd  #$0001
-         std   <u0026,u
-         ldb   <u0028,u
-         beq   L00D0
-         cmpb  <u0026,u
-         bhi   L00D0
-L0100    comb
+         ENDC
+         std   <V.TRY,u
+         ldb   <V.RTRY,u	number of retries to do
+         beq   L00D0		if unspecified, keep retrying
+         cmpb  <V.TRY,u		if exceeded number of retries,
+         bhi   L00D0		then we crap out
+
+L0100    comb  
          ldb   #E$NotRdy
-         rts
-L0104    pshs  x,b,a
-         ldb   >PIA1Base+2
-         lda   >$FF69
-         bpl   L0126
-         lda   >PIA1Base+3
-         bita  #$01
-         beq   L0126
-         bita  #$80
-         beq   L0126
-         orcc  #Entire
-         leax  <L0126,pcr
-         pshs  x
-         pshs  u,y,x,dp,b,a,cc
-         jmp   [D.SvcIRQ]
-L0126    lsrb
-         puls  pc,x,b,a
+         rts   
 
 * GetStat
 *
@@ -219,28 +314,33 @@
 *
 * Exit:
 *    CC = carry set on error
-*    B  = error code
+*    B  = error code 
 *
-GetStat  cmpa  #SS.EOF
-         bne   L012F
-L012D    clrb
-         rts
-L012F    ldx   PD.RGS,y
+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   L0140
+         beq   L0123
          cmpa  #SS.ComSt
-         bne   L0190
-         ldd   <u0020,u
+         bne   L0173
+         ldd   <V.COM,u		get Com status
          std   R$Y,x
-         bra   L012D
-L0140    clra
-         ldb   <u0022,u
+         clrb
+         rts
+
+* get screen size GetStt
+L0123    clra  
+         ldb   <V.COL,u
          std   R$X,x
-         ldb   <u0023,u
+         ldb   <V.ROW,u
          std   R$Y,x
-         bra   L012D
+         clrb
+         rts
 
-* GetStat
+* SetStat
 *
 * Entry:
 *    A  = function code
@@ -249,58 +349,68 @@
 *
 * Exit:
 *    CC = carry set on error
-*    B  = error code
+*    B  = error code 
 *
-SetStat  cmpa  #SS.ComSt
-         bne   L0190
+SetStt   cmpa  #SS.ComSt
+         bne   Close		if not, check if it's a close
          ldx   PD.RGS,y
          ldd   R$Y,x
-L0155    std   <u0020,u
+* A = Parity byte
+* B = baud rate
+L0138    std   <V.COM,u		save parity, baud rate in com status
+         IFNE  H6309
+         clrd
+         ELSE
          clra
          clrb
-         std   <u001D,u
-         sta   <u001F,u
-         ldd   <u0020,u
+         ENDC
+         std   <V.PAR,u
+         sta   <V.STP,u
+         ldd   <V.COM,u
          tstb
-         bpl   L0169
-         inc   <u001F,u
-L0169    bitb  #$40
+         bpl   L014C
+         inc   <V.STP,u		do 2 stop bits
+L014C    bitb  #$40		make sure the bit is zero
          bne   Read
-         bitb  #$20
-         beq   L0174
-         inc   <u001E,u
-L0174    bita  #$20
-         beq   L0186
+         bitb  #$20		0=8, 1=7 bits
+         beq   L0157
+         inc   <V.BIT,u
+L0157    bita  #$20
+         beq   L0169		if=0, no parity
          bita  #$80
-         beq   Read
-         inc   <u001D,u
+         beq   Read		if high bit set (only for ACIA devices), error out
+         inc   <V.PAR,u		parity
          bita  #$40
-         bne   L0186
-         inc   <u001D,u
-L0186    anda  #$0F
-         sta   <u0028,u
+         bne   L0169		1=space,
+         inc   <V.PAR,u		2=mark parity
+L0169    anda  #$0F
+         sta   <V.RTRY,u
+         rts   
+
+Read     comb  
+         ldb   #E$BMode
          rts
 
-* Read
-*
-* Entry:
-*    Y  = address of path descriptor
-*    U  = address of device memory area
-*
-* Exit:
-*    A  = character read
-*    CC = carry set on error
-*    B  = error code
-*
-Read     comb
-         ldb   <E$BMode
+L0173    comb
+         ldb   #E$UnkSVc
          rts
 
-L0190    comb
-         ldb   #E$UnkSvc
+Close    cmpa  #SS.Close	close the device?
+         bne   L0173
+         leax  V.BUFF,u		point to blocked process buffer
+
+C010     lda   1,x		get next process number
+         sta   ,x+
+         bne   C010		do until we have a zero byte
+
+         lda   V.BUFF,u		get the first process in the queue
+         beq   C020		if none left
+         ldb   #S$Wake		wake up signal
+         os9   F$Send		re-start the blocked process
+
+C020     clrb
          rts
 
          emod
 eom      equ   *
          end
-