Mercurial > hg > Members > kono > nitros9-code
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 -