NEW
  AUTO 3,1
				.LIST OFF	
				.OP	65C02
				.OR	$2000
				.TF DRV/LANCEGS.DRV
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/MLI.E.I
				.INB INC/NIC.I
				.INB INC/NIC.91C96.I
				.INB INC/ETH.I
*--------------------------------------
ZPArgPtr		.EQ ZPDRV
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp Dev.Detect			cld,jmp abs=DRV
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					DRV Layout Version 1
				.DA 0
				.DA CS.END-CS.START			Code Length
				.DA 0
				.DA 0
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
L.MSG.DETECT	.DA MSG.DETECT
L.MSG.DETECT.OK	.DA MSG.DETECT.OK
L.MSG.DETECT.KO	.DA MSG.DETECT.KO
L.DRV.CS.START	.DA DRV.CS.START
L.FD.DEV		.DA FD.DEV
L.FD.DEV.NAME	.DA FD.DEV.NAME
L.SSCANF.MAC	.DA SSCANF.MAC
L.MAC0			.DA DCB+S.DCB.NIC.MAC
L.MAC1			.DA DCB+S.DCB.NIC.MAC+1
L.MAC2			.DA DCB+S.DCB.NIC.MAC+2
L.MAC3			.DA DCB+S.DCB.NIC.MAC+3
L.MAC4			.DA DCB+S.DCB.NIC.MAC+4
L.MAC5			.DA DCB+S.DCB.NIC.MAC+5
				.DA 0					End Of Reloc Table
*--------------------------------------
Dev.Detect		>STYA ARGS

				>LDYA L.MSG.DETECT
				>SYSCALL puts
				
				ldx #$70
				ldy #7
				
.1				lda A2osX.S,y		IO based detection, avoid scanning in Disk Controller IO!!!!
				bne .2
				
				lda L91C96.BSR+1,x
				cmp #DEVID
				beq .3
				
.2				dec FD.DEV.NAME+3
				txa
				sec
				sbc #$10
				tax
				dey
				bne .1
				
				>LDYA L.MSG.DETECT.KO
				>SYSCALL puts

				lda #MLI.E.NODEV
				sec
				rts
				
.3				stx DEVSLOTx0
				lda #A2osX.S.NIC
				sta A2osX.S,y

				jsr Dev.ParseArgs
				bcs .9
				
.8				>PUSHW L.FD.DEV.NAME
				>PUSHBI 2
				>LDYA L.MSG.DETECT.OK
				>SYSCALL printf
				
				>PUSHWI DRV.END
				>PUSHWI DRV.CS.END
				>PUSHWI DRV.CS.START
				>LDYA L.DRV.CS.START
				>SYSCALL InsDrv
				bcs .9
				>STYA FD.DEV+S.FD.DEV.DRVPTR
				
				>PUSHW L.FD.DEV.NAME
				>LDYA L.FD.DEV
				>SYSCALL MKDEV

.9				rts
*--------------------------------------
Dev.ParseArgs	>LDYA ARGS
				>STYA ZPArgPTR
				lda (ZPArgPTR)
				bne .1
				
				lda A2osX.RANDOM16
				eor A2osX.TIMER16
				sta DCB+S.DCB.NIC.MAC+3
				eor A2osX.RANDOM16+1
				sta DCB+S.DCB.NIC.MAC+4
				eor A2osX.TIMER16+1
				sta DCB+S.DCB.NIC.MAC+5
				clc
				rts
				
.1				>PUSHW L.MAC5
				>PUSHW L.MAC4
				>PUSHW L.MAC3
				>PUSHW L.MAC2
				>PUSHW L.MAC1
				>PUSHW L.MAC0
				>PUSHBI 12				6 x byte PTRs
				>PUSHW L.SSCANF.MAC
				>LDYA ZPArgPtr
				>SYSCALL sscanf
				bcc .8
				
				lda #E.SYN
				sec
.8				rts
*--------------------------------------
CS.END
ARGS			.BS 2
MSG.DETECT		.AZ "LanCeGS/SMSC91C96 Driver."
MSG.DETECT.OK	.AZ "LanCeGS/SMSC91C96 Installed As Device : %S\r\n"
MSG.DETECT.KO	.AZ "Hardware Not Found."
SSCANF.MAC		.AZ "%h:%h:%h:%h:%h:%h"
*--------------------------------------
FD.DEV			.DA #S.FD.T.CDEV
				.DA #0					HANDLER
				.DA #0					BUSID
				.DA #0					DEVID
				.DA 0					BUSPTR
				.BS 2					DRVPTR
				.DA 0					DCBPTR
				.DA 0					BUFPTR
FD.DEV.NAME		.AZ "ETH7"
*--------------------------------------
*			Driver Code
*--------------------------------------
ZPIOCTL			.EQ ZPDRV
ZPBufPtr		.EQ ZPDRV+2
Size			.EQ ZPDRV+4
Counter			.EQ ZPDRV+6
*--------------------------------------
DRV.CS.START	cld
				jmp (.1,x)
.1				.DA STATUS
				.DA A2osX.BADCALL
				.DA A2osX.BADCALL
				.DA A2osX.BADCALL
				.DA A2osX.BADCALL
				.DA A2osX.BADCALL
				.DA OPEN
				.DA CLOSE
				.DA READ
				.DA WRITE
				.DA A2osX.BADCALL		IRQ
				.DA 0					end or relocation
*--------------------------------------
STATUS			>STYA ZPIOCTL

				ldy #S.IOCTL.STATCODE
				lda (ZPIOCTL),y
				beq .1
				
				cmp #S.IOCTL.STATCODE.GETDIB
				bne STATUS.DCB
				
				ldx #S.DIB-1
				.HS 2C					bit abs
.1				ldx #3

				ldy #S.IOCTL.BUFPTR
				lda (ZPIOCTL),y
				sta .3+1
				iny
				lda (ZPIOCTL),y
				sta .3+2
				
.2				lda DIB,x
.3				sta $ffff,x				SELF MODIFIED
				dex
				bpl .2
				
				clc
				rts
				
STATUS.DCB		cmp #S.IOCTL.STATCODE.GETDCB
				bne STATUS.9

				stz DCB+S.DCB.NIC.LINK

				ldx DEVSLOTx0

				stz L91C96.BSR,x
				lda L91C96.0.EPHSR,x
				lda L91C96.0.EPHSR+1,x
				and /L91C96.0.EPHSR.LINK
				beq .1
				
				lda #S.DCB.NIC.LINK.OK
				tsb DCB+S.DCB.NIC.LINK
	
				lda L91C96.0.TCR,x
				lda L91C96.0.TCR+1,x
				and /L91C96.0.TCR.FDSE
				beq .1

				lda #S.DCB.NIC.LINK.FD
				tsb DCB+S.DCB.NIC.LINK
				
.1				ldy #S.IOCTL.BUFPTR
				lda (ZPIOCTL),y
				sta .4+1
				iny
				lda (ZPIOCTL),y
				sta .4+2
				
				ldx #S.DCB.NIC-1
				
.3				lda DCB,x
.4				sta $ffff,x				SELF MODIFIED
				dex
				bpl .3

				clc
				rts
				
STATUS.9		lda #MLI.E.BADCTL
				sec
				rts				
*--------------------------------------
OPEN			lda #S.DIB.S.OPENED
				bit DIB+S.DIB.S
				bne .9
				
				jsr CLOSE

*				ldx DEVSLOTx0			Done by CLOSE

				lda #L91C96.0.TCR.FDSE+L91C96.0.TCR.FUDPLX+L91C96.0.TCR.PADEN+L91C96.0.TCR.TXENA
				sta L91C96.0.TCR,x
				lda /L91C96.0.TCR.FDSE+L91C96.0.TCR.FUDPLX+L91C96.0.TCR.PADEN+L91C96.0.TCR.TXENA
				sta L91C96.0.TCR+1,x
				
				lda #L91C96.0.RCR.NOCRC+L91C96.0.RCR.RXENA+L91C96.0.RCR.ALLMUL
				sta L91C96.0.RCR,x
				lda /L91C96.0.RCR.NOCRC+L91C96.0.RCR.RXENA+L91C96.0.RCR.ALLMUL
				sta L91C96.0.RCR+1,x
				
				lda #1
				sta L91C96.BSR,x
				
				lda #L91C96.1.CR.NOWAIT
				sta L91C96.1.CR,x
				lda /L91C96.1.CR.NOWAIT
				sta L91C96.1.CR+1,x

				ldy #0
				bit USERMAC
				bmi .2
	
.1				lda L91C96.1.IAR,x
				sta S.DCB.NIC.MAC,y
				inx
				iny
				cpy #6
				bne .1
				bra .3

.2				lda S.DCB.NIC.MAC,y
				sta L91C96.1.IAR,x
				inx
				iny
				cpy #6
				bne .2
				
.3				ldx DEVSLOTx0
				lda #L91C96.1.CTR.DEFAULT+L91C96.1.CTR.AUTOREL
				sta L91C96.1.CTR,x
				lda /L91C96.1.CTR.DEFAULT+L91C96.1.CTR.AUTOREL
				sta L91C96.1.CTR+1,x
				
				clc
				rts

.9				lda #MLI.E.OPEN
				sec
				rts				
*--------------------------------------
CLOSE			ldx DEVSLOTx0
				stz L91C96.BSR,x
				
				lda #L91C96.0.RCR.RESET
				sta L91C96.0.RCR,x
				lda /L91C96.0.RCR.RESET
				sta L91C96.0.RCR+1,x
				
				lda $C019				we can use VBL as we are not on //c
.1				eor $C019
				bpl .1
				
				lda $C019
.2				eor $C019
				bpl .2
				
				stz L91C96.0.RCR,x
				stz L91C96.0.RCR+1,x
				
				clc
				rts
*--------------------------------------
READ			php
				sei

				>STYA ZPIOCTL
				
				ldx DEVSLOTx0
				lda #2
				sta L91C96.BSR,x

				lda L91C96.2.IST,x
				and #L91C96.2.IST.RCV
				bne .1
				lda #E.NODATA
				
.9				plp
				sec
				rts
				
.1				lda #L91C96.2.PTR.RCVD+L91C96.2.PTR.AUTOI+L91C96.2.PTR.READ
				sta L91C96.2.PTR,x
				lda /L91C96.2.PTR.RCVD+L91C96.2.PTR.AUTOI+L91C96.2.PTR.READ
				sta L91C96.2.PTR+1,x 

				lda L91C96.2.DATA,x		Get Frame Status Word (lo)
				lda L91C96.2.DATA,x		Get Frame Status Word (HI)
				
				asl
				asl
				asl 					#$10 = odd?
				asl						if odd, CS
				
				lda L91C96.2.DATA,x		get lo byte count
				sbc	#5					compute Size
				sta Size
				pha
				ldy #S.IOCTL.BYTECNT
				sta (ZPIOCTL),y
				eor #$ff
				sta Counter
				
				lda L91C96.2.DATA,x		get hi byte count
				sbc #0
				sta Size+1
				iny
				sta (ZPIOCTL),y
				eor #$ff
				sta Counter+1
				eor #$ff
				
				ply
				
				>SYSCALL2 getmem
				bcs .9
				>STYA ZPBufPtr
				phx
								
				phy
				ldy #S.IOCTL.BUFPTR+1
				sta (ZPIOCTL),y
				dey
				pla
				sta (ZPIOCTL),y
				
				ldx DEVSLOTx0

				ldy #0
				
.2				inc Counter
				bne .21
				inc Counter+1
				beq .4
				
.21				lda L91C96.2.DATA,x
				sta (ZPBufPtr),y
				iny
				bne .3
				inc ZPBufPtr+1
				
.3				inc Counter
				bne .31
				inc Counter+1
				beq .4
				
.31				lda L91C96.2.DATA,x
				sta (ZPBufPtr),y
				iny
				bne .2
				inc ZPBufPtr+1
				bra .2

.4				lda #L91C96.2.MMUCR.REMREL
				sta L91C96.2.MMUCR,x
				
.8				pla						hMem

				plp
				clc
				rts
*--------------------------------------				
WRITE			php
				sei
				
				>STYA ZPIOCTL

				ldx DEVSLOTx0
				
				lda #2
				sta L91C96.BSR,x
			
				ldy #S.IOCTL.BYTECNT
				lda (ZPIOCTL),y
				sta Size
				eor #$ff
				sta Counter
				eor #$ff
				
				clc
				adc #6					3 WORDs more Status, len & Control

				bne .10
				clc						LO byte is 0, no need for an extra empty page
				
.10				iny
				lda (ZPIOCTL),y
				sta Size+1
				eor #$ff
				sta Counter+1
				eor #$ff
				
				adc #0
				
.1				ora #L91C96.2.MMUCR.ALLOC
				sta L91C96.2.MMUCR,x

				ldy #0
				
.2				lda L91C96.2.IST,x
				and #L91C96.2.IST.ALLOC
				bne .3
				dey
				bne .2
				
				lda #E.NODATA
				
.9				plp
				sec
				rts				
				
.3				lda L91C96.2.AAR,x
				sta L91C96.2.PNR,x
				
				lda #L91C96.2.PTR.AUTOI
				sta L91C96.2.PTR,x
				lda /L91C96.2.PTR.AUTOI
				sta L91C96.2.PTR+1,x
				
				ldy #S.IOCTL.BUFPTR
				lda (ZPIOCTL),y
				sta ZPBufPtr
				iny
				lda (ZPIOCTL),y
				sta ZPBufPtr+1
				
				ldy #S.ETH.SRCMAC+5		Add Src MAC Address
				ldx #5
.4				lda S.DCB.NIC.MAC,x
				sta (ZPBufPtr),y
				dey
				dex
				bpl .4

				ldx DEVSLOTx0
				stz L91C96.2.DATA,x		write fake status word
				stz L91C96.2.DATA,x
				
				lda Size
				pha
				eor #$01
				lsr
				pla
				adc #$05				add 5 if odd, 6 if even
				sta L91C96.2.DATA,x
				lda Size+1
				adc #$00
				sta L91C96.2.DATA,x
				
				ldy #2
				
.5				inc Counter
				bne .51
				inc Counter+1
				beq .70
				
.51				lda (ZPBufPtr),y
				iny
				bne .6
				inc ZPBufPtr+1
				
.6				inc Counter
				bne .61
				inc Counter+1
				beq .71
				
.61				sta L91C96.2.DATA,x
				lda (ZPBufPtr),y
				sta L91C96.2.DATA,x
				iny
				bne .5
				inc ZPBufPtr+1
				bra .5
				
.70				lda #0
				sta L91C96.2.DATA,x
				sta L91C96.2.DATA,x
				bra .8
				
.71				sta L91C96.2.DATA,x
				lda #%00100000			signal an extra (odd) byte
				sta L91C96.2.DATA,x
				
.8				lda #L91C96.2.MMUCR.NQPKT
				sta L91C96.2.MMUCR,x
				
				plp
				clc
				rts
*--------------------------------------	
DRV.CS.END
DEVSLOTx0		.BS 1
USERMAC			.BS 1
*--------------------------------------
DIB				.DA #0
				.DA #0,#0,#0			size
				>PSTR "LanCEGS/L91C96"
				.BS 1
				.DA #S.DIB.T.NIC
				.BS 1					Subtype
				.BS 2					Version
*--------------------------------------
DCB				.DA #S.DCB.T.NIC
				.BS 1					FLAGS
				.BS 1					LINK
				.DA #S.DCB.NIC.SPEED.10
				.HS 000E3A123456		MAC
				.BS 12					IP/MASK/GW
*--------------------------------------
DRV.END
MAN
SAVE USR/SRC/DRV/LANCEGS.DRV.S
ASM
