
 lib environment
 lib tty
 data
 sttl 8274 interface routines
 pag
 name tty_8274
 global ttconf,ttputc,ttgetc,ttenxr,ttdisx,ttenr,ttenx,ttenno
 global ttxbsy,tttstx,tttstr,tttstb,tttstc,tttste,ttend,ttsbrg
 global ttiscts,ttwcts,ttwdcd,tttsts

* The routines in this file are specific to an 8274.
* They are called from the "ttyhan" and "ttydrv" files.

* constants

cont equ 2 control reg
data equ 0 data reg
CTSBIT equ $20 Clear To Send bit in status reg.
DCDBIT equ $08 Data Carrier Detect bit in status reg.

*
* ttconf
*
* Configure the port pointed at by the Y register.  The X
* register is pointing to the terminal table.  All registers
* except D should be preserved.
*

ttconf
 lbsr clstat reset status
 ldb #$ee load configuration byte
 bsr setupx do auto enable and DTR/RTS
 lbsr clstat reset status
 lda cont,y read status
 bita #CTSBIT is CTS on?
 bne ttcnf2 skip if on
 clc Zero bit already set, no Carry->no CTS
 rts
ttcnf2 pshs d
 ldd usarg1 get open type
 cmpd #3 is it special open?
 puls d
 beq ttcnf3 skip if special open
 bita #DCDBIT is DCD on?
 bne ttcnf4 skip if on
 sec Zero bit already set, Carry->no DCD
 rts
ttcnf3 lda #3 select control reg. 3
 sta cont,y
 lda #$C1 turn off auto enables
 sta cont,y
 lda tstat2,x get open status
 ora #TOPWOC show special open
 sta tstat2,x
ttcnf4 lbsr reset reset pending interrupts
 ldb #1 select interrupt cntrl reg
 stb cont,y
 ldb #$1F turn on interrupts
 stb cont,y
 bra true return true

*
* ttputc
*
* Send the character in the B register to the ACIA.  All
* registers should be preserved.  Y points to the device.
*

ttputc stb data,y send character
 rts return


*
* ttgetc
*
* Get the character from the device and return in the B
* register.  Y points to the device and all registers
* should be preserved.
*

ttgetc ldb data,y get the character
* fall through to "rts" in next routine

*
* ttenxr
*
* Enable the transmit interrupts and leave the receive
* interrupt enabled (it is enabled upon routine entry).
* Y points to the device and X points to to the terminal
* table entry.  Preserve all registers but D.
*
*

ttenxr
* fall through to "rts" in next routine


*
* ttenr
*
* Enable the receive interrupts only.  The transmit
* interrupts should be turned off.  Y points to the device
* and X point to the terminal table entry.  Preserve all
* but the D register.
*

ttenr
* fall through to "rts" in next routine


*
* ttenx
*
* Enable the transmit interrupts only.  The receive
* interrupts should be left disabled.  Y points to the
* device and X points to the terminal table entry.
* All registers but D shoud be preserved.
*

ttenx rts do nothing for now


*
* ttdisx
*
* Disable the transmit interrupt and leave the receive
* interrupt enabled.  Y points to the device and X points
* to the terminal table entry.  Preserve all but D.
*

ttdisx
 lda #$28 reset transmit interrupt command
 sta cont,y
 rts


*
* ttenno
*
* Disable all interrupts from device and drop the RTS
* line.  Y points to the device and X points to the
* terminal table entry.  Preserve all but D register.
*

ttenno lda #1 select interrupt cntrl reg
 sta cont,y select reg 1
 clr cont,y reset all bits
 ldb #$6c turn off DTR and RTS
setupx lda #3 select register 3
 sta cont,y
 lda #$E1 restore to auto enables
 sta cont,y
 lda #5 select xmit control reg
 sta cont,y
 stb cont,y store pre-loaded configuration
 rts return

*
* ttxbsy
*
* Test if the transmit buffer is empty.  Return TRUE if
* it is empty (N.E. status). Y points to the device and
* all but A needs preserved.
*

ttxbsy
 lda cont,y
 bita #4
 rts

*
* tttstx
*
* Test device pointed at by Y for a transmit interrupt.
* Return TRUE if interrupt present.  Preserve all but
* the A register.
*

tttstx ldd 6,s get status
 tsta -- cmpa #0
 bne false is it xmit int?
 bra true

*
* ttiscts
*
* Test device pointed at by X for "Clear to Send"
* -- Return TRUE (not equal) if yes
*
ttiscts lda cont,x check for CTS
 bita #%00100000 is CTS down?
 beq false
true clz no - return TRUE
 rts


*
* tttstr
*
* Test device pointed at by Y for a receive interrupt.
* Return TRUE if interrupt present.  Preserve all
* registers.
*

tttstr cmpa #2 is it rcv int?
 bne false
 bra true


*
* tttstb
*
* Test device pointed at by Y for a "break" condition.
* Return TRUE if found.  Preserve all registers
* and return NULL in B (for break character).
*

tttstb cmpa #1 is it break condition?
 bne false
 bitb #$80
 bne clsint clear int. & show true
false sez yes - return FALSE
 rts


* Test device pointed at by Y for a "CTS" interrupt.
*

tttsts cmpa #1 is it special interrupt?
 bne false
 lda #CTSBIT use CTS bit position
 bsr hilo see if bit went hi
 beq clsint if lo, go clear int.
 bsr chkopn was terminal open?
 bne clsint clear int & exit if so
 bsr wake wakeup blocked open

*
* clear interrupt and return true status
*

clsint lda #1 select int. control reg.
 sta cont,y
 lda cont,y clear interrupt
clstat lda #$10 reset port
 sta cont,y
 rts return true



*
* check for device open
*
chkopn pshs a
 lda tstate,x
 bita #TOPEN
 puls a,pc


*
* tttstc
*
* Test device pointed at by Y for drop "Carrier Detect"
* type interrupt.  Return TRUE if so.  Preserve all registers
* but A.
*

tttstc cmpa #1 special interrupt type?
 bne false exit if not
 lda #DCDBIT setup DCD bit position
 bsr hilo see if bit went hi or lo
 bne 3f branch if high
 bsr chkopn was terminal open?
 beq flsclr if not, clear int. & show false
 bra clsint clr int & show true (HANGUP)
3 bsr chkopn was terminal open?
 bne flsclr if so, clr int & show false
 bsr wake waken blocked open

flsclr pshs a
 bsr clsint clear interrupt
 puls a
 lbra false show false response

*
* See if bit in position supplied in a went high or low
*

hilo pshs a save bit position
 tfr b,a
 eora tstat2,x see if bit has changed
 anda 0,s look at only the desired bit
 bne 1f branch if changed
 leas 3,s remove return address
 lda #1 restore interrupt type
 bra false go straight to false
1 lda tstat2,x preload saved bits
 bitb 0,s did bit go high?
 bne 2f branch if went high
 com 0,s prepare to clear bit
 anda 0,s+ clear saved bit
 bsr 3f put back
 bra false show bit went low
2 ora 0,s+ set saved bit
3 sta tstat2,x
 lda #1 restore interrupt type
 rts (returning true (NE))


*
* wakeup routine for CTS and DCD
*
wake pshs d,x,y,u
 ldy tqout,x get address for wakeup
 jsr wakeup
 puls d,x,y,u,pc


*
* tttste
*
* Test device pointed at by Y for error conditions.
* Handle all errors local to this routine - no status
* returned.  Preserve all but A.
*

tttste cmpa #1 special condition?
 beq flsclr yes - jump
 lda #1 reset error condition
 sta cont,y
 lda cont,y
 lda #$30
 sta cont,y
 lda data,y read data register - just to be sure
 bra clstat clear status


*
* reset impending interrupts and determine current
* status of CTS and DCD
*

reset bsr clsint clear interrupts
 lda cont,y get status
 anda #CTSBIT|DCDBIT just CTS and DCD
 ldb tstat2,x
 andb #!(CTSBIT|DCDBIT) turn off
 stb tstat2,x
 ora tstat2,x add in new bits
 sta tstat2,x
 rts


*
* ttend
*
* Terminate i/o operation for device pointed at by Y.
* Preserve all but D.
*

ttend pshs d,y save port address
 ldd 2,s compute base address for chip
 andb #$FE
 tfr d,y
 lda #$38 reset port
 sta cont,y
 puls d,y,pc return


*
* ttsbrg
*
* Set up the baud rate generators - if any.  On entry,
* Y points to xmit BRG and U points to rcvr BRG.  X is
* pointing to the terminal table entry (tbaud2,x has
* byte for baud rate generator).
*

ttsbrg lda tbaud2,x get speed byte
 sta 0,y set xmit speed
 sta 0,u set rcvr speed
ret rts return




*
* ttwcts
*
* Wait for CTS to go high.  (Sleep on it).
*

* Same as ttwdcd, so fall through

*
* ttwdcd
*
* Wait for DCD to go high.  (Sleep on it).
*

ttwcts lda #CTSBIT
 bra ttw2
ttwdcd lda #DCDBIT
ttw2 pshs a
 bsr reset reset impending interrupts
 lda #1  select interrupt control reg.
 sta cont,y
 lda #$05 enable only ext/status interrupts
 sta cont,y
 lbsr clstat
 lda cont,y get status
 anda 0,s+
 bne ret
 ldb #TTYOPR set priority
 ldy tqout,x point to something
 jmp sleep sleep on DCD
