
 lib environment
 lib acia
 lib macdefs
 lib sptab
 data
 sttl Serial Printer Driver
 pag
 name sprdrvr
 global spopn,spcls,spwrt,spntr,spspc

*
* This file contains serial printer driver
* routines provided with the standard configuration.
*

SPLOC equ 35 low water count
XONXOF equ %01000000 enable XON/XOFF processing

*
* spopn
*
* Open the serial port.
*

spopn cmpb #SPMAX legal device number?
 bhi spopn6 if not - error
 pshs b save dev number
 bsr spsel select printer structure
 tst spstat,x is it open?
 puls b reset dev number
 bne spopn4 if open - exit
 aslb
 aslb
 ldy #sptabl point to table
 leay b,y point to this guys data
 ldd 0,y get buffer address
 std spiptr,x set up info in structure
 std spoptr,x
 std spbfst,x
 addd #SPBFSZ calc buffer end
 std spbfen,x set end
 ldd 2,y get acia address
 std spacia,x
 clr spxoff,x clear holding flag
 ldy spacia,x get address
 lda #3 set up for reset
 sta csr,y reset acia
 lda #ENBRIN|AWORD|ADIVID set up control
 sta csr,y
 inc spstat,x set open status
spopn4 rts return
spopn6 lda #EBDEV set error
 sta uerror
 rts return

*
* select printer structure - return in X.
*

spsel ldx #spstrc point to structures
 lda #SPSZ
 mul calc offset
 leax d,x adjust ptr
 rts return

*
* spcls
*
* Close the acia - no operation now.
*

spcls bsr spsel select printer
 clr spstat,x zero status
 rts return

*
* spwrt
*
* Write to serial printer.
*

spwrt bsr spsel select printer
spwrt1 jsr cpass get a character from user
 bmi spwrt6 none left?
 pshs b save character
spwrt2 lda spcntr,x get char count
** cmpa #SPBFSZ-2 upper limit?
 adda #2
 cmpa #SPBFSZ upper limit?
 blo spwrt4
 pshs cc save cpu status
 seti mask interrupts
 jsr spstrt start output
 puls cc reset status
 pshs x
 ldy spbfst,x point to queue
 ldb #TTYOPR set priority
 jsr sleep sleep on queue
 puls x
 bra spwrt2 repeat
spwrt4 puls b get character
 bsr spout output it
 bra spwrt1 repeat loop
spwrt6 pshs cc save status
 seti mask interrupts
 bsr spstrt kick port
 puls cc,pc return

*
* spntr
*
* Serial port interrupt handler
*

spntr bsr spsel select printer
 ldy spacia,x get ACIA address
 lda csr,y check interrupt type
 bita #%00000101 XMIT interrupt?
 beq spntr1 skip if so
 bita #%00110100 RCV interrupt?
 beq spntr4 skip if so
* if we get here, it's an error
 ldb dbuf,y clear unknown interrupt
 rts
spntr1 bsr spstrt kick port
 lda spcntr,x get char count
 beq spntr2 zero?
 cmpa #SPLOC low water mark?
 bne spntr3
spntr2 ldy spbfst,x point to queue
 jsr wakeup wakeup time
spntr3 rts return
spntr4 ldb dbuf,y get the character
 tst spspcl,x doing XON/XOFF?
 beq spntr9 exit if not
 cmpb #XOFFC is char an XOFF?
 bne spntr5
 stb spxoff,x start holding
 rts
spntr5 cmpb #XONC is char an XON?
 bne spntr9
 tst spxoff,x are we currently holding?
 beq spntr9 skip if not
 clr spxoff,x restart output
 lda #ENBRIN|ENBXIN|AWORD|ADIVID enable interrupts
 sta csr,y
spntr9 rts

*
* spout
*
* Output char to serial printer queue.
*

spout ldy spiptr,x get queue pointer
 stb 0,y+ place in q
 cmpy spbfen,x end of q?
 bne spout2
 ldy spbfst,x reset q pointer
spout2 sty spiptr,x save pointer
 cmpb #$d is it cr?
 bne spout4
 inc spcntr,x bump count
 ldb #$a set up line feed
 bra spout repeat
spout4 inc spcntr,x bump char counter
 tst spxoff,x are we holding?
 bne spout5 skip if so
 lda #ENBRIN|ENBXIN|AWORD|ADIVID enable interrupts
 ldy spacia,x
 sta csr,y
spout5 rts return

*
* spstrt
*
* Start output on the serial port.
*

spstrt ldy spacia,x point to acia
 lda csr,y get status
 bita #ACTBSY transmit busy?
 beq spstr4 if so - exit
 tst spxoff,x are we holding?
 bne spstr6 branch if so
 tst spcntr,x any characters?
 beq spstr6
 ldy spoptr,x get q pointer
 ldb 0,y+ get character
 cmpy spbfen,x end of q?
 bne spstr2
 ldy spbfst,x reset to beginning
spstr2 sty spoptr,x save pointer
 ldy spacia,x get acia
 stb dbuf,y output char
 dec spcntr,x dec char count
spstr4 rts return
spstr6 lda #ENBRIN|DSBXIN|AWORD|ADIVID disable ints
 ldy spacia,x get acia
 sta csr,y
 rts return

*
* spspc
*
* special routine (like ttyset/ttyget)
*

spspc pshs x save argument
 lbsr spsel point to printer structure
 puls y restore argument
 cmpy #0 doing put or get?
 bne spspc4 branch if get
* put
 ldd usarg2 get hold processing byte in b
 andb #XONXOF clear unnecessary bits
 stb spspcl,x put in proper place
 rts
* get
spspc4 ldd #0 fake data
 std 0,y++
 std 0,y++
 ldb spspcl,x get XON/XOFF flag
 std 0,y
 rts

