
 opt nol
 lib environment
 lib sptab
 lib macdefs
 opt lis
 data
 sttl Pennywise Serial Printer Driver
 pag
 name sprdrvr
 global spopn,spcls,spwrt,spint,spspcl

*
* This file contains serial printer driver
* routines for use with the DMFP-58 Controller
*

SPLOC equ 35 low water count

*
* 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
 lda #7 length of initialization table
 mul
 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 CPB address
 std spacia,x
 ldd 4,y get initial baud rate
 std spbaud,x
 lda 6,y get initial serial mode
 sta spmode,x
 ldy spacia,x get address
 jsr spinit go initialize interface
 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
 ldb #SPBFSZ get buffer size
 subb #2
 pshs b
 cmpa 0,s+ 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

*
* spspcl
*  -- Set serial printer device characteristics
*
spspcl cmpx #0 ttyset call?
 beq 10f
 lda #EBARG no - illegal system call
 sta uerror
 rts
10 pshs d save device number
 jsr spsel select printer
 puls d restore device #
 ldy #sptabl point to table
 lda #7 length of initialization table
 mul
 leay b,y point to this guys data
 ldd usarg0 get baud rate
 std spbaud,x
 std 4,y save in initialization table
 lda usarg1 get serial format
 sta spmode,x
 sta 6,y
 ldy spacia,x re-initialize interface
 jsr spinit
 rts

*
* spntr
*
* Serial port interrupt handler
*

spint bsr spsel select printer
 ldy spacia,x get CPB address
 lda 0,y get handshake/command byte
 anda #%00011111 strip handshake bits
 ora #%11100000 set "acknowledge interrupt"
 sta 0,y
 jsr cpb_idle wait for interface idle
 bsr spstr1 start output
 lda spcntr,x get char count
 beq 4f
 cmpa #SPLOC low water mark?
 bne 5f
4 pshs y save port address
 ldy spbfst,x point to queue
 jsr wakeup
 puls y
5 rts return

*
* 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
 jmp speint enable ints

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

spstrt ldy spacia,x point to acia
 jsr sptbsy xmit busy?
 beq spstr4 if so - exit
spstr1 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
 jsr spputc output char
 dec spcntr,x dec char count
spstr4 rts return
spstr6 ldy spacia,x get port address
 jmp spdisx disable xmit ints


* put in sep. file

speint rts

sptbsy lda 0,y get handshake byte
 anda #%11100000
 cmpa #%00000000 controller idle state
 beq 0f jump if idle
 lda #0 return 0 - controller busy
 rts return
0 lda #1 return not 0 - controller idle
 rts

spputc clr sp_opt,y clear status/option byte
 stb sp_char,y set up character to send
 lda #$41 write one character
 sta 0,y
 rts return

spdisx rts

*
* Serial Printer Initialize
*
spinit pshs d,x,y,u save registers
 ldd spbaud,x get printer baud rate
 std sp_abr,y
 lda spmode,x get serial format
 sta sp_fmt,y
 clr sp_status,y
 lda #$00 Initialize interface command
 jsr cpb_cmd
99 puls d,x,y,u,pc

*
* cpb_cmd - send command to CPB and wait for idle
*    (Y) - CPB address
*    (A) - CPB command
*    jsr cpb_cmd
*
cpb_cmd
 ora #$20 start command/no interrupt
 sta 0,y
cpb_idle lda 0,y command complete?
 anda #%11100000 get handshake bits only
 bne cpb_idle wait for idle
 rts
