Mercurial > hg > Members > kono > nitros9-code
changeset 731:bd7c8348adec
This is the serial printer driver from NitrOS-9, backported to OS-9 Level Two
Note, the previous revision was actually the Disto printer driver.
author | boisy |
---|---|
date | Sun, 05 Jan 2003 21:48:33 +0000 |
parents | 5ed7f616e80b |
children | 339845ea3507 |
files | level2/modules/printer.asm |
diffstat | 1 files changed, 320 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/level2/modules/printer.asm Sun Jan 05 21:47:48 2003 +0000 +++ b/level2/modules/printer.asm Sun Jan 05 21:48:33 2003 +0000 @@ -1,85 +1,347 @@ ******************************************************************** -* Printer - CoCo 3 serial port printer driver +* Printer - CoCo 3 Serial Printer Driver * * $Id$ * +* 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! +* * Ed. Comments Who YY/MM/DD * ------------------------------------------------------------------ -* 12 Original OS-9 L2 Tandy distribution +* NitrOS-9 2.00 distribution ??/??/?? +* 13 Back-ported to OS-9 Level Two BGP 03/01/05 - nam PRINTER - ttl CoCo 3 serial port printer driver - -* Disassembled 98/08/24 23:21:29 by Disasm v1.6 (C) 1988 by RML + nam Printer + ttl CoCo 3 Serial Printer Driver ifp1 use defsfile endc tylg set Drivr+Objct -atrv set ReEnt+rev +atrv set ReEnt+Rev rev set $01 -edition set 12 - - mod eom,name,tylg,atrv,start,size +edition set 13 -u0000 rmb 29 -u001D rmb 1 -u001E rmb 1 -u001F rmb 1 -size equ . - fcb $03 + mod eom,name,tylg,atrv,Start,Size + + fcb READ.+WRITE. name fcs /PRINTER/ - fcb edition + 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 +size equ . + +* Baud Rate Delay Table +BaudDly equ * + IFEQ NitrOS9 +* OS-9 Level Two delay values (1.89MHz) + 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.89MHz) + 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 + start equ * - lbra L006E - lbra L0028 - lbra L002C - lbra L005B - lbra L0057 - lbra L006C -L0028 comb - ldb #$CB - rts -L002C ldb >MPI.Slct - andb #$33 - pshs b - ldb #$33 - stb >MPI.Slct - tst >$FF52 - bmi L004A -L003D sta >$FF52 - sta >$FF52 + lbra Init + lbra Read + lbra Write + lbra GetStt + lbra SetStt +Term equ * + clrb + rts + +Init orcc #IntMasks + ldx #$FF20 + clr $01,X + ldd <$2C,Y get number of columns/rows + std <V.COL,U + lda #$FE + sta ,X + lda #$36 + sta $01,X + lda ,X + andcc #^IntMasks + ldd <$26,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 #$80 +I010 clr ,x+ we're more concerned with room + decb than with speed, so we don't use TFM + bne I010 + rts + +L005F ldb <PD.BAU,Y PD.BAU + andb #$0F keep lower nibble + cmpb #$07 get baud rate + lbhs Read + aslb + leax <BaudDly,PCR table of delay times + ldx b,X + stx <V.WAIT,U + clrb + rts + +Bit_2 ldb #$02 +L007D stb >$FF20 +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,d + +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 #$01 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 + 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 - stb >MPI.Slct + 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 a parity byte +L00BC bsr Bit_2 and a stop bit + tst <V.STP,U do another one? + beq L00C9 + bsr Bit_2 yes, dump out another stop byte +L00C9 andcc #^IntMasks +L00CA rts + +L0104 pshs b + ldb >$FF22 get a byte + lsrb + puls pc,b + +L00CB equ * + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std <V.TRY,U +L00D0 ldd #$0303 +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 -L004A ldx #$0001 - os9 F$Sleep - tst >$FF52 - bpl L003D - bra L004A -L0057 comb - ldb #$D0 + +L00DE lbsr L0080 wait for a while + deca try 3 times, + bne L00D3 + pshs x + ldx #$0001 + os9 F$Sleep sleep for the rest of this tick + puls x + ldd <V.TRY,U + IFNE H6309 + incd we've tried once more and failed... + ELSE + addd #$0001 + 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 + +GetStt cmpa #SS.EOF end of file? + bne L0112 + clrb if so, exit with no error rts -L005B cmpa #$26 - bne L0057 - ldx $06,y - clra - ldb <u001D,u - std $04,x - ldb <u001E,u - std $06,x -L006C clrb + +L0112 ldx PD.RGS,Y + cmpa #SS.ScSiz + beq L0123 + cmpa #SS.ComSt + bne L0173 + ldd <V.COM,U get Com status + std R$Y,X + clrb + rts + +* get screen size GetStt +L0123 clra + ldb <V.COL,U + std R$X,X + ldb <V.ROW,U + std R$Y,X + clrb + rts + +SetStt cmpa #SS.ComSt + bne Close if not, check if it's a close + ldx PD.RGS,Y + ldd R$Y,X +* A = Parity byte +* B = baud rate +L0138 std <V.COM,U save parity, baud rate in com status + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std <V.PAR,U + sta <V.STP,U + ldd <V.COM,U + tstb + bpl L014C + inc <V.STP,U do 2 stop bits +L014C bitb #$40 make sure the bit is zero + bne Read + 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 if high bit set (only for ACIA devices), error out + inc <V.PAR,U parity + bita #$40 + bne L0169 1=space, + inc <V.PAR,U 2=mark parity +L0169 anda #$0F + sta <V.RTRY,U rts -L006E ldd <$2C,y - std <u001D,u - lda <$26,y - sta <u001F,u - clrb - rts + +Read comb + ldb #E$BMode + rts + +L0173 comb + ldb #E$UnkSVc + rts + +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 #$01 wake up signal + os9 F$Send re-start the blocked process + +C020 clrb + rts emod eom equ *