PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
				.LIST OFF	
				.OP	65C02
				.OR	$2000
				.TF /A2OSX.BOOT/DRV/LANCEGS.DRV
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/LIBTCPIP.I
*--------------------------------------
ZPTmpPTR		.EQ ZPDRV
*--------------------------------------
				.INB DRV/X.NET.91C96.S
*--------------------------------------
*			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 DEV.HEADER-CS.START		Device Header Offset
				.DA DRV.CS.START-CS.START	Driver Code Offset
				.DA DRV.CS.END-DRV.CS.START	Drv Code Length
*--------------------------------------
* 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.DEV.HEADER.NAME	.DA DEV.HEADER.NAME
				.DA 0					End Of Reloc Table
*--------------------------------------
Dev.Detect		>STYA Args
				>LDYA L.MSG.DETECT
				>SYSCALL SYS.PrintFYA
				
				ldx #$10
.1				lda L91C96.BSR+1,x
				cmp #DEVID
				beq .3
				
				inc DEV.HEADER.NAME+4
				txa
				clc
				adc #$10
				tax
				bpl .1					not yat at $80
				
				>LDYA L.MSG.DETECT.KO
				>SYSCALL SYS.PrintFYA

				lda #DEVMGR.ERRNOHW		Not Found in any slot, exiting
				sec
				rts
				
.3				stx DEVSLOTx0
				
				>LDYA ARGS
				>STYA ZPTmpPTR
				lda (ZPTmpPTR)
				beq .4
				
				sec
				ror USERMAC
				>SYSCALL SYS.GetMemPtrA
				>STYA ZPTmpPTR
				jsr DecodeMac
				bcc .4
				lda #DEVMGR.ERRICL
				sec
				rts
				
.4				>PUSHW L.DEV.HEADER.NAME
				>LDYA L.MSG.DETECT.OK
				>SYSCALL SYS.PrintFYA
				clc
				rts
*--------------------------------------
				.INB DRV/X.NET.DRV.S
*--------------------------------------
CS.END
MSG.DETECT		>CSTRING "LanCeGS/SMSC91C96 Driver.\n"
MSG.DETECT.OK	>CSTRING "LanCeGS/SMSC91C96 Installed As Device : %S\n"
MSG.DETECT.KO	>CSTRING "Hardware Not Found.\n"
Args			.BS 2
*--------------------------------------
*			Device Header (16 Bytes)
*--------------------------------------
DEV.HEADER		cld
				jmp (DRV.CS.START,x)
				.DA #S.DEV.F.SHARE+S.DEV.F.EVENT
DEV.HEADER.NAME	>PSTRING "ETH1"			NAME
				.HS 00.00
				.HS 00.00.00.00
*--------------------------------------
*			Driver Code
*--------------------------------------
DRV.CS.START	.DA OPEN
				.DA GETEVENT
				.DA $FFFF				no COUT
				.DA CLOSE
				.DA GETINFO
				.DA $FFFF				no IRQ
				.DA SEND
				.DA $FFFF				no SETIPCFG
L.DEVINFO		.DA DEVINFO
				.DA 0					end or relocation
*--------------------------------------
* input :
* none
* output :
* CC on success
* CS on error
*--------------------------------------				
OPEN			jsr Reset				will select L91C96.0

				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 MAC,y
				inx
				iny
				cpy #6
				bne .1
				bra .3

.2				lda 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
*--------------------------------------
* input :
*  pEvent
* output :
* CC no event
* CS event
*--------------------------------------				
GETEVENT		ldx DEVSLOTx0
				lda #2
				sta L91C96.BSR,x

				lda L91C96.2.IST,x
				and #L91C96.2.IST.RCV
				bne GETEVENT.RxOK
				lda #ERR.DEV.NOFRAME
				sec
				rts
				
GETEVENT.RxOK	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						#$60 = Broadcast?
				ldy #S.EVT.DATAHI
				sta (pEvent),y
				
				asl
				asl 					#$10 = odd?
				asl						if odd, CS
				
				lda L91C96.2.DATA,x		get lo byte count
				sbc	#5					compute FRAMELEN
				sta FRAMELEN
				tay
				lda L91C96.2.DATA,x		get hi byte count
				sbc #0
				sta FRAMELEN+1
				
				iny
				bne .1
				inc
.1				iny
				bne .11
				inc
.11				>PUSHYA					FRAMLEN+2
				>PUSHBI 0
				>SYSCALL SYS.GetMem
				bcs .99
				>STYA ZPTmpPTR
				txa
				ldy #S.EVT.DATALO
				sta (pEvent),y

				lda #S.EVT.F.NET+S.EVT.F.hMEM1
				sta (pEvent)
								
				lda FRAMELEN
				sta (ZPTmpPTR)
				ldy #1
				lda FRAMELEN+1
				sta (ZPTmpPTR),y

				iny
				
				ldx DEVSLOTx0
				
.2				jsr DecFrameLen
				beq .8
				lda L91C96.2.DATA,x
				sta (ZPTmpPTR),y
				iny
				bne .3
				inc ZPTmpPTR+1
.3				jsr DecFrameLen
				beq .8
				lda L91C96.2.DATA,x
				sta (ZPTmpPTR),y
				iny
				bne .2
				inc ZPTmpPTR+1
				bra .2

.8				lda #L91C96.2.MMUCR.REMREL
				sta L91C96.2.MMUCR,x
				clc
				rts
				
.99				sec				
				rts				
*--------------------------------------
CLOSE			jsr Reset
				clc
				rts
*--------------------------------------				
*  in:
*  out:
*   Y,A = BUFFER PTR
* 	CC on success
* 	CS on error
*--------------------------------------
GETINFO			lda #S.DEVINFO.NET.STATUS.10
				sta LINK.STATUS

				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 LINK.STATUS
				ora #S.DEVINFO.NET.STATUS.OK
				sta LINK.STATUS
	
.1				lda L91C96.0.TCR,x
				lda L91C96.0.TCR+1,x
				and /L91C96.0.TCR.FDSE
				bne .2
				lda LINK.STATUS
				ora #S.DEVINFO.NET.STATUS.FD
				sta LINK.STATUS
				
.2				>LDYA L.DEVINFO
				clc
				rts
*--------------------------------------				
*  in:
* 	PULLW = FRAME PTR
*   PULLW = FRAME LEN
*  out:
* 	CC on success
* 	CS on error
*--------------------------------------				
SEND			>PULLW ZPTmpPTR
				
				ldx DEVSLOTx0
				lda #2
				sta L91C96.BSR,x
			
				lda (ZPTmpPTR)
				sta FRAMELEN
				clc
				adc #6					3 WORDs more Status, len & Control

				bne .10
				clc						LO byte is 0, no need for an extra empty page
				
.10				ldy #1
				lda (ZPTmpPTR),y
				sta FRAMELEN+1
				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 #ERR.DEV.NOBUFFER
				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.ETH.SRCMAC+5		Add Src MAC Address
				ldx #5
.4				lda MAC,x
				sta (ZPTmpPTR),y
				dey
				dex
				bpl .4

				ldx DEVSLOTx0
				stz L91C96.2.DATA,x		write fake status word
				stz L91C96.2.DATA,x
				
				lda FRAMELEN
				pha
				eor #$01
				lsr
				pla
				adc #$05				add 5 if odd, 6 if even
				sta L91C96.2.DATA,x
				lda FRAMELEN+1
				adc #$00
				sta L91C96.2.DATA,x
				
				ldy #2
				
.5				jsr DecFrameLen
				beq .70
				lda (ZPTmpPTR),y
				iny
				bne .6
				inc ZPTmpPTR+1
				
.6				pha
				jsr DecFrameLen
				beq .71
				pla
				sta L91C96.2.DATA,x
				lda (ZPTmpPTR),y
				sta L91C96.2.DATA,x
				iny
				bne .5
				inc ZPTmpPTR+1
				bra .5
				
.70				lda #0
				sta L91C96.2.DATA,x
				sta L91C96.2.DATA,x
				bra .8
				
.71				pla
				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 
				clc
				rts
				
.9				sec
				rts
*--------------------------------------
* 				PRIVATE
*--------------------------------------
Reset			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
				rts
*--------------------------------------	
DecFrameLen		lda FRAMELEN
				bne .1
				lda FRAMELEN+1
				beq .8
				dec FRAMELEN+1
.1				dec FRAMELEN
				lda #1					Make something NZ
.8				rts
*--------------------------------------	
DRV.CS.END
*--------------------------------------	
DEVSLOTx0		.BS 1
USERMAC			.BS 1
FRAMELEN		.BS 2
*--------------------------------------	
DEVINFO			.DA #S.DEVINFO.TYPE.NET
DEVFLAGS		.DA #0
MAC				.BS 6
LINK.STATUS		.BS 1					OK/DUPLEX/SPEED
*--------------------------------------
MAN
SAVE DRV/LANCEGS.DRV.S
ASM
