VM02/src/sscdrvr.s

345 lines
4.8 KiB
ArmAsm
Executable File

;*
;* SUPER SERIAL CARD DEVICE DRIVER
;*
;
; SERIAL PORT DEFINES
;
;HW_FLOWCTRL EQU 1
XON EQU $11
XOFF EQU $13
SSC_INIT: LDA #$00 ; ZERO OUT INBUFF GET/PUT INDECES
STA $0578,Y
STA $05F8,Y
STA $07F8,Y ; CLEAR FLAGS
LDX SLOT2IO,Y
LDA #$00
STA $C089,X ; PROGRAMMED RESET
CLC
RTS
SSC_DRIVER:
SSC_DRVR_SZ: .WORD SSC_DRVR_END - SSC_DRVR_START
SSC_READ_OFS: .WORD SSC_READ - SSC_DRVR_START
SSC_WRITE_OFS: .WORD SSC_WRITE - SSC_DRVR_START
SSC_CTRL_OFS: .WORD SSC_CTRL - SSC_DRVR_START
SSC_IRQ_OFS: .WORD SSC_IRQ - SSC_DRVR_START
SSC_DRVR_START:
SSC_READ: TYA ; READ CHARACTER FROM BUFFER
TAX
SSCRRETRY: SEI
LDA $0578,X ; GET INDEX
CMP $05F8,X ; CHECK FOR EMPTY
BNE :+
CLI
TXA
PHA
LDY CURRENT_THREAD
JSR THREAD_NOTIMEOUT
PLA
TAY ; LOAD SLOT #
PHA
JSR THREAD_WAITIO
PLA
TAX
LDA $07F8,X
AND #$01 ; PORT STILL ACTIVE?
BNE SSCRRETRY
RTS ; NOPE
: LDY $0678,X ; SET UP BUFFER POINTERS
STY TMPTR
LDY $06F8,X
STY TMPTR+1
TAY
LDA (TMPTR),Y
PHA
INY
TYA
STA $0578,X ; INCREMENT GET INDEX
CMP $05F8,X
BEQ :+
TXA
PHA
TAY
JSR THREAD_NOTIFYIO ; NOTIFY SELECT_IO
PLA
TAX
: PLA
LDY $07F8,X
BMI :+ ; CHECK FOR XON/XOFF
CLC
RTS
: PHA
TYA
AND #$40
BEQ SSCXONEXIT
LDA $05F8,X
SEC
SBC $0578,X
CMP #$10
BCS SSCXONEXIT
TYA
AND #$BF
STA $07F8,X
LDY SLOT2IO,X
.IFDEF HW_FLOWCTRL
LDA $C08A,Y ; ENABLE RECEIVER
ORA #$01
STA $C08A,Y
.ELSE
: LDA $C089,Y
AND #$10
BEQ :-
LDA #XON ; SEND XON
STA $C088,Y
.ENDIF
SEI
TXA
TAY
JSR THREAD_NOTIFYIO ; WAKE UP ANY WAITING WRITES
SSCXONEXIT: PLA
CLC
RTS
SSC_WRITE: PHA ; WRITE CHARACTER TO SERIAL PORT
LDA $07F8,Y
BPL SSCWRETRY ; CHECK FOR FLOW CONTROL
AND #$40
BEQ SSCWRETRY
TYA
PHA
LDY CURRENT_THREAD
JSR THREAD_NOTIMEOUT
PLA
TAY ; LOAD SLOT #
PHA
JSR THREAD_WAITIO
PLA
TAY
LDA $07F8,Y
AND #$01 ; PORT STILL ACTIVE?
TAX
PLA
DEX
BEQ SSC_WRITE
RTS
SSCWRETRY: LDX SLOT2IO,Y
: LDA $C089,X ; DO THIS WITH INTS ENABLED
AND #$10 ; SO READS DON'T GET STARVED
BEQ :- ; HOPEFULLY WON'T CLEAR INT BEFORE IRQ
PLA
STA $C088,X
CLC
RTS
SSC_CTRL: PHA
TYA ; GET ENCODED IOCTL
AND #$F8 ; MASK OFF SLOT #
PHA
TYA
AND #$07 ; GET SLOT #
TAY
PLA
CMP #IOCTL_AVAIL
BNE :+
PLA
SEI ; AVAILABLE CHARS IN BUFFER
LDA $05F8,Y ; GET INDEX
SEC
SBC $0578,Y ; MINUS PUT INDEX
CLC
RTS
: CMP #IOCTL_SPACE
BNE :+
PLA
LDA $07F8,Y ; CHECK FOR FLOW CONTROL
AND #$40
ASL
ASL
ROL
EOR #$01
RTS
: CMP #SERCTL_BAUD
BNE :+
PLA
STX TMP
LDX SLOT2IO,Y
LDA $C08B,X
AND #$E0
ORA TMP
EOR #$10
STA $C08B,X
CLC
RTS
: CMP #SERCTL_DATABITS
BNE :+
PLA
TXA
ASL
ASL
ASL
ASL
ASL
STA TMP
LDX SLOT2IO,Y
LDA $C08B,X
AND #$9F
ORA TMP
STA $C08B,X
CLC
RTS
: CMP #SERCTL_PARITYBITS
BNE :+
PLA
TXA
ASL
ASL
ASL
ASL
ASL
STA TMP
LDX SLOT2IO,Y
LDA $C08A,X
AND #$1F
ORA TMP
STA $C08A,X
CLC
RTS
: CMP #SERCTL_STOPBITS
BNE :+
PLA
TXA
LSR
ROR
STA TMP
LDX SLOT2IO,Y
LDA $C08B,X
AND #$7F
ORA TMP
STA $C08B,X
CLC
RTS
: CMP #SERCTL_XONXOFF
BNE :+
PLA
LDA $07F8,Y
AND #$7F
STA $07F8,Y
TXA
LSR
LDA #$00
ROR
ORA $07F8,Y
STA $07F8,Y
CLC
RTS
: CMP #IOCTL_INBUFF
BNE :+
TXA
STA $06F8,Y
PLA
STA $0678,Y
CLC
RTS
;: CMP #IOCTL_INBUFFSZL
; BNE :+
;: CMP #IOCTL_INBUFFSZH
; BNE :+
: CMP #IOCTL_OPEN
BNE :+
PLA
LDX SLOT2IO,Y
LDA $C08A,X
AND #$F0 ; ENABLE XFER & INTS
ORA #$09
STA $C08A,X
LDA $07F8,Y ; SET ENABLE FLAG
ORA #$01
STA $07F8,Y
LDA #$00
STA $04F8,Y ; CLEAR STATUS ON IIC
CLC
RTS
: CMP #IOCTL_CLOSE
BNE :+
LDA #IOCTL_DEACTIVATE
: CMP #IOCTL_DEACTIVATE
BNE :+
PLA
LDX SLOT2IO,Y
LDA $C08A,X
AND #$F0 ; DISABLE XFER & INTS
STA $C08A,X
LDA $07F8,Y ; CLEAR ENABLE FLAG
AND #$FE
STA $07F8,Y
; TYA
JSR THREAD_NOTIFYIO ; WAKE UP ANY WAITING THREADS
CLC
RTS
: CMP #IOCTL_ID
BEQ :+
PLA
SEC
RTS
: PLA
LDA #$31 ; SSC ID
CLC
RTS
SSC_IRQ: TAX ; A = IRQ SLOT #
LDA MACHID
AND #$08 ; CHECK FOR IIC
BNE SSC_IRQIIC
LDY SLOT2IO,X
LDA $C089,Y ; LOAD STATUS
BMI SSCSERVINT ; IRQ = BIT 7
SEC
RTS
SSC_IRQIIC: LDA $04F8,X ; LOAD SAVED STATUS
BMI SSCSERVINTIIC
SEC
RTS
SSCSERVINTIIC: AND #$7F ; MARK INT CLEAR
STA $04F8,X
LDY SLOT2IO,X
SSCSERVINT: AND #$08 ; RECEIVE DATA
BEQ SSCEXIT
LDA $C088,Y ; READ CHARACTER
LDY $0678,X ; SET UP BUFFER POINTERS
STY TMPTR
LDY $06F8,X
STY TMPTR+1
LDY $05F8,X ; PUT INDEX
STA (TMPTR),Y ; STORE CHAR IN BUFF
INY
TYA
CMP $0578,X ; CHECK FOR FULL
BEQ SSCEXIT ; FULL, SKIP INC
STA $05F8,X ; INC PUT INDEX
LDY $07F8,X ; CHECK FOR XON/XOFF ENABLE
BMI :+
SSCEXIT: CLC
RTS
: SEC
SBC $0578,X
CMP #$E0 ; ABOVE THRESHOLD?
BCC SSCEXIT+1
TYA
AND #$40 ; ALREAD SENT XOFF?
BNE SSCEXIT
LDY SLOT2IO,X
.IFDEF HW_FLOWCTRL
LDA $C08A,Y ; DISABLE RECEIVER
AND #$FE
STA $C08A,Y
.ELSE
: LDA $C089,Y
BMI SSCSERVINT
AND #$10
BEQ :-
LDA #XOFF ; SEND XOFF
STA $C088,Y
.ENDIF
LDA $07F8,X
ORA #$40 ; SET XOFF FLAG
STA $07F8,X
CLC
RTS
SSC_DRVR_END EQU *