VM02/src/utherdrvr.s

491 lines
8.7 KiB
ArmAsm
Executable File

;*
;* UTHERNET CARD DEVICE DRIVER
;*
;
; UTHER PROBE AND INIT CODE
;
.IF .DEFINED (UTHERSLOT7)
UTHER_PROBE7:
.SCOPE
UTHERSLOT = 7
SLOTIO = $70
SLOTROM = $C700
.ELSEIF .DEFINED (UTHERSLOT6)
UTHER_PROBE6:
.SCOPE
UTHERSLOT = 6
SLOTIO = $60
SLOTROM = $C600
.ELSEIF .DEFINED (UTHERSLOT5)
UTHER_PROBE5:
.SCOPE
UTHERSLOT = 5
SLOTIO = $50
SLOTROM = $C500
.ELSEIF .DEFINED (UTHERSLOT4)
UTHER_PROBE4:
.SCOPE
UTHERSLOT = 4
SLOTIO = $40
SLOTROM = $C400
.ELSEIF .DEFINED (UTHERSLOT2)
UTHER_PROBE2:
.SCOPE
UTHERSLOT = 2
SLOTIO = $20
SLOTROM = $C200
.ELSEIF .DEFINED (UTHERSLOT1)
UTHER_PROBE1:
.SCOPE
UTHERSLOT = 1
SLOTIO = $10
SLOTROM = $C100
.ENDIF
SRCHUTHR: STA TMPTR
@CHKSIG: LDA SLOTROM+$05 ; NO ROM SIG FOR UTHERNET
CMP #$38
BNE @CHKAUTOSTRT
LDA SLOTROM+$07
CMP #$18
BNE @CHKAUTOSTRT
JMP @SKIPUTHR
@CHKAUTOSTRT: LDA SLOTROM+$01
CMP #$20
BNE @CHKGT ; MAKE SURE IT ISN'T AUTOSTART DEVICE
LDA SLOTROM+$05
CMP #$03
BNE @CHKGT
JMP @SKIPUTHR
@CHKGT: LDA SLOTROM+$01 ; MAKE SURE IT ISN'T GRAPHICS TABLET
CMP #$B0
BNE @CHKUTHR
LDA SLOTROM+$09
CMP #$20
BNE @CHKUTHR
@SKIPUTHR: SEC
RTS
@CHKUTHR: LDA #$00 ; SET PACKET PAGE POINTER
STA $C08A+SLOTIO
STA $C08B+SLOTIO
LDA $C08C+SLOTIO
CMP #$0E ; LOOK FOR MAGIC VENDOR ID
BNE @SKIPUTHR
LDA $C08D+SLOTIO
CMP #$63
BNE @SKIPUTHR
@UTHER_INIT: LDA #$00
STA $07F8+UTHERSLOT ; CLEAR FLAGS
LDA #$14 ; RESET CHIP
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA #$55
STA $C08C+SLOTIO
LDA #$00
STA $C08D+SLOTIO
CLC
RTS
.ENDSCOPE
;
; UTHER DRIVER CODE
;
.IF .DEFINED (UTHERSLOT7)
UTHER_DRIVER7:
.SCOPE
UTHERSLOT = 7
SLOTIO = $70
.ELSEIF .DEFINED (UTHERSLOT6)
UTHER_DRIVER6:
.SCOPE
UTHERSLOT = 6
SLOTIO = $60
.ELSEIF .DEFINED (UTHERSLOT5)
UTHER_DRIVER5:
.SCOPE
UTHERSLOT = 5
SLOTIO = $50
.ELSEIF .DEFINED (UTHERSLOT4)
UTHER_DRIVER4:
.SCOPE
UTHERSLOT = 4
SLOTIO = $40
.ELSEIF .DEFINED (UTHERSLOT2)
UTHER_DRIVER2:
.SCOPE
UTHERSLOT = 2
SLOTIO = $20
.ELSEIF .DEFINED (UTHERSLOT1)
UTHER_DRIVER1:
.SCOPE
UTHERSLOT = 1
SLOTIO = $10
.ENDIF
@UTHER_DRVR_SZ: .WORD @UTHER_DRVR_END - @UTHER_DRVR_START
@UTHER_READ_OFS: .WORD @UTHER_READ - @UTHER_DRVR_START
@UTHER_WRITE_OFS: .WORD @UTHER_WRITE - @UTHER_DRVR_START
@UTHER_CTRL_OFS: .WORD @UTHER_CTRL - @UTHER_DRVR_START
@UTHER_IRQ_OFS: .WORD @UTHER_IRQ - @UTHER_DRVR_START
@UTHER_DRVR_START:
@UTHER_POLL: PHP ; CHECK FOR PENDING PACKET
SEI
LDA $07F8+UTHERSLOT ; CHECK NOT BUSY + ENABLE BITS
BEQ :+ ; NOT ENABLED, CHECK KEYBOARD
LSR
BNE :+ ; BUSY, CHECK KEYBOARD
LDA #$24
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA $C08D+SLOTIO
LSR
BCC :+
LDA #$05
STA $07F8+UTHERSLOT
PLP
JMP FAKE_IRQ ; HANDLE IT
: PLP
JMP KEYBD_POLL ; NO, POLL KEYBOARD
@UTHER_READ: PHA ; READ DATA FROM PACKET MEMORY: BYTE COUNT IN AX
LDA $0678+UTHERSLOT ; SET UP BUFFER POINTERS
STA TMPTR
LDA $06F8+UTHERSLOT
STA TMPTR+1
TXA
TAY
BEQ :+
LDY #$00
STA TMPTR+2
@UTHRRDPAGES: LDA $C080+SLOTIO ; READ 256 BYTE PAGES
STA (TMPTR),Y
INY
LDA $C081+SLOTIO
STA (TMPTR),Y
INY
BNE @UTHRRDPAGES
INC TMPTR+1
DEC TMPTR+2
BNE @UTHRRDPAGES
: PLA
LSR
BEQ @UTHRRDBYTE
STA TMPTR+2
@UTHRRDSHORTS: LDA $C080+SLOTIO ; READ 16 BIT SHORTS
STA (TMPTR),Y
INY
LDA $C081+SLOTIO
STA (TMPTR),Y
INY
DEC TMPTR+2
BNE @UTHRRDSHORTS
@UTHRRDBYTE: BCC :+ ; CHECK FOR FINAL BYTE TO READ
LDA $C080+SLOTIO
STA (TMPTR),Y
CLC
: RTS
@UTHER_WRITE: PHA ; WRITE DATA TO PACKET MEMORY: BYTECOUNT IN AX
LDA $0578+UTHERSLOT ; SET UP BUFFER POINTERS
STA TMPTR
LDA $05F8+UTHERSLOT
STA TMPTR+1
TXA
TAY
BEQ :+
LDY #$00
STA TMPTR+2
@UTHRWRPAGES: LDA (TMPTR),Y ; WRITE 256 BYTE PAGES
STA $C080+SLOTIO
INY
LDA (TMPTR),Y
STA $C081+SLOTIO
INY
BNE @UTHRWRPAGES
INC TMPTR+1
DEC TMPTR+2
BNE @UTHRWRPAGES
: PLA
LSR
BEQ @UTHRWRBYTE
STA TMPTR+2
@UTHRWRSHORTS: LDA (TMPTR),Y ; WRITE 16 BIT SHORTS
STA $C080+SLOTIO
INY
LDA (TMPTR),Y
STA $C081+SLOTIO
INY
DEC TMPTR+2
BNE @UTHRWRSHORTS
@UTHRWRBYTE: BCC :+ ; CHECK FOR FINAL BYTE TO WRITE
LDA (TMPTR),Y
STA $C080+SLOTIO
CLC
: RTS
@UTHER_CTRL: PHA
TYA ; GET IOCTL ENCODED WITH SLOT #
AND #$F8 ; MASK OFF SLOT
CMP #IOCTL_INBUFF
BNE :+
TXA
STA $06F8+UTHERSLOT
PLA
STA $0678+UTHERSLOT
CLC
RTS
: CMP #IOCTL_OUTBUFF
BNE :+
TXA
STA $05F8+UTHERSLOT
PLA
STA $0578+UTHERSLOT
CLC
RTS
: CMP #ETHRCTL_RECVPKT
BNE :+
SEI
LDA $07F8+UTHERSLOT ; CHECK FLAGS
BEQ @UTHRBADSTATE ; NOT ENABLED
LSR
; BCC UTHRBADSTATE ; NOT ENABLED
LSR
BCS @UTHRRCVWAIT ; BUSY, WAIT
LSR
BCS @UTHRRCVLEN ; PENDING PACKET
LDA #$24 ; SET POINTER TO RECEIVE STATUS
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA $C08D+SLOTIO
LSR
BCS @UTHRRCVNOW ; PACKET ALREADY WAITING
@UTHRRCVWAIT: CLI
LDY CURRENT_THREAD
JSR THREAD_NOTIMEOUT
LDY #UTHERSLOT
JSR THREAD_WAITIO
SEI
LDA $07F8+UTHERSLOT ; CHECK FLAGS
CMP #$05
BEQ @UTHRRCVLEN
BNE @UTHRBADSTATE
@UTHRRCVNOW: LDA SLOT2MASK+UTHERSLOT ; CLEAR ANY PENDING IRQ NOTIFIES
EOR #$FF
AND IO_NOTIFY ; HAS THIS SLOT NOTIFIED?
STA IO_NOTIFY
@UTHRRCVLEN: PLA ; DISCARD SAVED ACCUM
LDA #$03 ; SET BUSY FLAG
STA $07F8+UTHERSLOT
LDA $C081+SLOTIO ; SKIP STATUS
LDA $C080+SLOTIO
LDX $C081+SLOTIO ; RETURN PACKET LENGTH
LDA $C080+SLOTIO
CLC
RTS
.IFDEF DEBUG
@UTHRBADSTATE: JSR PUTSLN
.ASCIIZ "BAD UTHERNET STATE"
JMP THROW_INTERNALERR
.ELSE
@UTHRBADSTATE: PLA
LDA #$00
TAX
SEC
RTS
.ENDIF
: CMP #ETHRCTL_XMITPKT
BNE :+
SEI
LDA $07F8+UTHERSLOT
CMP #$01
BNE @UTHRBADSTATE ; NOT ENABLED OR BUSY
LDA #$03
STA $07F8+UTHERSLOT ; SET BUSY FLAG
@UTHRXMTCMD: STX TMP
LDA #$C9
STA $C084+SLOTIO
LDA #$00
STA $C085+SLOTIO
PLA
STA $C086+SLOTIO
LDA TMP
STA $C087+SLOTIO
@UTHRXMTRETRY: LDA #$38 ; SET POINTER TO BUS STATUS
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA $C08D+SLOTIO
LSR
BCC @UTHRXMTNOTRDY
CLC
RTS
@UTHRXMTNOTRDY: TXA
CLI
PHA
.IFDEF DEBUG
JSR KEYBD_POLL
.ELSE
JSR THREAD_YIELD
.ENDIF
PLA
SEI
TAX
BNE @UTHRXMTRETRY ; ALWAYS TAKEN
: CMP #ETHRCTL_DONEPKT
BNE :+
.IFDEF DEBUG
LDA $07F8+UTHERSLOT ; CHECK FLAGS
CMP #$03
BNE @UTHRBADSTATE ; NOT ENABLED
.ENDIF
PLA
SEI
LDA #$24 ; SET POINTER TO RECEIVE STATUS
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA $C08D+SLOTIO
ASL
ASL
ORA #$01 ; CLEAR BUSY AND UPDATE PENDING FLAGS
STA $07F8+UTHERSLOT
LSR
BNE @UTHRDONENOTIFY ; NOTIFY IF PENDING PACKET
RTS
@UTHRDONENOTIFY: LDY #UTHERSLOT
JMP THREAD_NOTIFYIO
: CMP #ETHRCTL_SETMAC01
BNE :+
STX TMP
LDA #$58 ; SET POINTER TO MAC 0/1
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
PLA
STA $C08C+SLOTIO
LDA TMP
STA $C08D+SLOTIO
CLC
RTS
: CMP #ETHRCTL_SETMAC23
BNE :+
STX TMP
LDA #$5A ; SET POINTER TO MAC 2/3
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
PLA
STA $C08C+SLOTIO
LDA TMP
STA $C08D+SLOTIO
CLC
RTS
: CMP #ETHRCTL_SETMAC45
BNE :+
LDA #$5C ; SET POINTER TO MAC 4/5
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
PLA
STA $C08C+SLOTIO
LDA TMP
STA $C08D+SLOTIO
CLC
RTS
: CMP #IOCTL_OPEN
BNE :+
PLA
LDA #$04 ; ONLY RECEIVE VALID PACKETS
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA #$05
STA $C08C+SLOTIO
LDA #$0D
STA $C08D+SLOTIO
LDA #$12 ; ENABLE RX, TX
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA #$D3
STA $C08C+SLOTIO
LDA #$00
STA $C08D+SLOTIO
; LDA #$02 ; ENABLE IRQ
; STA $C08A,X ; IRQ ISN'T CONNECTED BUT MAKES IT
; LDA #$01 ; EASIER TO POLL FOR RECEIVED PACKETS
; STA $C08B,X
; LDA #$03
; STA $C08C,X
; LDA #$01
; STA $C08D,X
; LDA #$16
; STA $C08A,X
; LDA #$01
; STA $C08B,X
; LDA #$17
; STA $C08C,X
; LDA #$80
; STA $C08D,X
LDA #$01 ; SET ENABLE FLAG
STA $07F8+UTHERSLOT
CLC
RTS
: CMP #IOCTL_CLOSE
BNE :+
LDA #IOCTL_DEACTIVATE
: CMP #IOCTL_DEACTIVATE
BNE :+
PLA
LDA #$12 ; DISABLE RX, TX, AND IRQ
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA #$00
STA $C08C+SLOTIO
LDA #$00
STA $C08D+SLOTIO
LDA #$16
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA #$17
STA $C08C+SLOTIO
LDA #$00
STA $C08D+SLOTIO
LDA #$00 ; CLEAR FLAGS
STA $07F8+UTHERSLOT
LDY #UTHERSLOT
JSR THREAD_NOTIFYIO ; WAKE UP ANY WAITING THREADS
CLC
RTS
: CMP #IOCTL_ID
BEQ :+
PLA
SEC
RTS
: PLA
LDA #$E1 ; UTHER ID
CLC
RTS
@UTHER_IRQ: LDA $07F8+UTHERSLOT
BNE :+ ; SKIP IF NOT ENABLED
@UTHRNOSERV: SEC
RTS
: CMP #$05 ; CHECK PENDING FLAG
BNE :+
CLC
RTS
: CMP #$01 ; CHECK ENABLED FLAG
BNE @UTHRNOSERV ; BUSY, DON'T SERVICE YET
LDA #$24 ; SET POINTER TO RECEIVE STATUS
STA $C08A+SLOTIO
LDA #$01
STA $C08B+SLOTIO
LDA $C08D+SLOTIO
LSR
BCC @UTHRNOSERV
LDA #$05 ; SET BUSY AND PENDING FLAG
STA $07F8+UTHERSLOT
CLC
RTS
@UTHER_DRVR_END EQU *
.ENDSCOPE