;* ;* 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