PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
				.LIST OFF	
*--------------------------------------
RCVD.FRAMEA		sta hFrame1
				>SYSCALL SYS.GetMemPtrA
				>STYA ZPFrameBase1
				jsr FRM.GetLen1
				
				ldy #S.ETH.ETHERTYPE
				lda (ZPFrameBase1),y
				tax
				iny
				lda (ZPFrameBase1),y
				
				cmp #S.ETH.ETHERTYPE.ARP
				bne .1
				cpx /S.ETH.ETHERTYPE.ARP
				bne .1
				
				jmp	ARP.IN			
				
.1				cmp #S.ETH.ETHERTYPE.IP
				bne .9
				cpx /S.ETH.ETHERTYPE.IP
				bne .9
				
				jmp IP.IN
				
.9				sec
				rts
*--------------------------------------
*  Out:
*	Y,A = Frame PTR
*	X = hMem
*--------------------------------------
NEW.ICMP.FRAME	jsr NEW.IP.FRAME
				bcs .9
				ldy #S.IP.PROTOCOL
				lda #S.IP.PROTOCOL.ICMP
				sta (ZPFrameBase1),y
				>LDYA ZPFrameBase1
				clc
.9				rts
*--------------------------------------
*  Out:
*	Y,A = Frame PTR
*	X = hMem
*--------------------------------------
NEW.TCP.FRAME	jsr NEW.IP.FRAME
				bcs .9
				ldy #S.IP.PROTOCOL
				lda #S.IP.PROTOCOL.TCP
				sta (ZPFrameBase1),y
				>LDYA ZPFrameBase1
				clc
.9				rts
*--------------------------------------
*  Out:
*	Y,A = Frame PTR
*	X = hMem
*--------------------------------------
NEW.UDP.FRAME	jsr NEW.IP.FRAME
				bcs .9
				ldy #S.IP.PROTOCOL
				lda #S.IP.PROTOCOL.UDP
				sta (ZPFrameBase1),y
				>LDYA ZPFrameBase1
				clc
.9				rts
*--------------------------------------
*  Out:
*	Y,A = Frame PTR
*	X = hMem
*--------------------------------------
NEW.IP.FRAME	>PUSHWI K.ETH.FRAME.LEN
				>PUSHBI S.MEM.F.INIT0
				>SYSCALL SYS.GetMem
				bcs .9
				>STYA ZPFrameBase1

				lda DevFlags
				and #S.DEVINFO.NET.FLAGS.IPOFFLOAD
				bne .9
				
				ldy #S.ETH.ETHERTYPE
				lda /S.ETH.ETHERTYPE.IP
				sta (ZPFrameBase1),y		
				iny
				lda #S.ETH.ETHERTYPE.IP
				sta (ZPFrameBase1),y

				ldy #S.IP.V.IHL.DSCP.ECN
				lda #$45
				sta (ZPFrameBase1),y
				iny
				lda #$0
				sta (ZPFrameBase1),y
				
				ldy #S.IP.IDENTIFICATION
				sta (ZPFrameBase1),y
				inc
				iny
				sta (ZPFrameBase1),y
				dec
				ldy #S.IP.FRAGMENT.FLAGS 
				sta (ZPFrameBase1),y
				iny
				sta (ZPFrameBase1),y

				ldy #S.IP.TTL
				lda #K.IP.TTL
				sta (ZPFrameBase1),y
				>LDYA ZPFrameBase1
.9				rts
*--------------------------------------
SEND.ICMP.FRAME	>PULLW ZPFrameBase1
				jsr FRM.GetLen1
				stz hFrame1
SEND.ICMP.FRAME.I				
				>PUSHW ZPFrameLen1
				>PUSHWI S.ICMP.TYPE-2

				ldy #S.ICMP.CHECKSUM
				lda #0
				sta (ZPFrameBase1),y
				iny
				sta (ZPFrameBase1),y

				jsr IP.ComputeChecksum

				phy
				ldy #S.ICMP.CHECKSUM
				sta (ZPFrameBase1),y
				iny
				pla
				sta (ZPFrameBase1),y
				
				bra SEND.IP.FRAME.I
*--------------------------------------
SEND.TCP.FRAME	>PULLW ZPFrameBase1
				jsr FRM.GetLen1
				stz hFrame1
SEND.TCP.FRAME.I

				bra SEND.IP.FRAME.I
*--------------------------------------
SEND.UDP.FRAME	>PULLW ZPFrameBase1
				jsr FRM.GetLen1
				stz hFrame1
SEND.UDP.FRAME.I				
				ldy #S.UDP.LENGTH+1
				lda ZPFrameLen1
				sec
				sbc #S.IP-2
				sta (ZPFrameBase1),y
				dey
				lda ZPFrameLen1+1
				sbc /S.IP-2
				sta (ZPFrameBase1),y
				bra SEND.IP.FRAME.I
*--------------------------------------
SEND.IP.FRAME	>PULLW ZPFrameBase1
				jsr FRM.GetLen1
				stz hFrame1
				
SEND.IP.FRAME.I	ldx #3					Copy SRC.IP even if IP offload
				ldy #S.IP.SRC+3			for proper UDP/TCP CRC calculation
				
.1				lda IPCFG+S.IPCFG.IP,x
				sta (ZPFrameBase1),y	
				dey
				dex
				bpl .1
				
				lda DevFlags
				and #S.DEVINFO.NET.FLAGS.IPOFFLOAD
				bne .21
				
				ldy #S.IP.TOTAL.LENGTH+1
				lda ZPFrameLen1
				sec
				sbc #S.ETH-2
				sta (ZPFrameBase1),y
				dey
				lda ZPFrameLen1+1
				sbc /S.ETH-2
				sta (ZPFrameBase1),y
				
				lda #0
				ldy #S.IP.HDR.CHECKSUM
				sta (ZPFrameBase1),y
				iny
				sta (ZPFrameBase1),y
				
				stz IP.CHECKSUM			RESET.IP.CHECKSUM	
				stz IP.CHECKSUM+1

				clc

				ldy #S.IP.V.IHL.DSCP.ECN
				ldx #10					10 words for IP Header
				
.2				lda (ZPFrameBase1),y
				adc IP.CHECKSUM
				sta IP.CHECKSUM

				iny
				lda (ZPFrameBase1),y
				adc IP.CHECKSUM+1
				sta IP.CHECKSUM+1
				iny
				dex
				bne .2
				
				ldy #S.IP.HDR.CHECKSUM
				lda IP.CHECKSUM
				adc #0
				eor #$FF
				sta (ZPFrameBase1),y
				iny
				lda IP.CHECKSUM+1
				adc #0
				eor #$FF
				sta (ZPFrameBase1),y

.21				ldy #S.IP.PROTOCOL
				lda (ZPFrameBase1),y
				cmp #S.IP.PROTOCOL.TCP
				bne .3
				jsr TCP.ComputeChecksum
				bra .4
				
.3				cmp #S.IP.PROTOCOL.UDP
				bne .4
				jsr UDP.ComputeChecksum
				
.4				lda DevFlags
				and #S.DEVINFO.NET.FLAGS.ARPOFFLOAD
				bne .5

				jsr IP.SetDestMAC
				bcs FRM.Queue
				
.5				>PUSHW ZPFrameBase1
				ldx #DEVMGR.NET.SEND
				jsr NetDevJmp
				bcs FRM.Queue
				lda hFrame1
				beq .9
				>SYSCALL SYS.FreeMemA
				
				clc				
.9				rts
*--------------------------------------
FRM.Queue		ldy hFrame1				no hFrame, cannot queue for retry
				beq .9

				ldx FRM.QUEUE.Head
				inx
				cpx #K.FRMQUEUE.SIZE
				bne .1
				ldx #0
.1				cpx FRM.QUEUE.Tail
				beq .9
				ldy FRM.QUEUE.Head
				stx FRM.QUEUE.Head

				sta	FRM.QUEUE.State,y
				lda #K.FRMSEND.RETRY
				sta FRM.QUEUE.Retry,y
				lda hFrame1
				sta FRM.QUEUE.hMem,y
				clc
				rts
				
.9				sec
				rts
*--------------------------------------
FRM.Retry		ldx FRM.QUEUE.Tail

.10				cpx FRM.QUEUE.Head
				beq .8					Queue is empty, exit....
				lda FRM.QUEUE.hMem,x
				>SYSCALL SYS.GetMemPtrA
				>STYA ZPFrameBase1
				
				ldx FRM.QUEUE.Tail
				lda FRM.QUEUE.State,x
				cmp #ERR.DEV+1			Device error ?
				bcc .1					yes, retry sending...
				jsr IP.SetDestMAC		Err is ARP or higher, retry getting MAC
				bcs .2					still error getting dest MAC
				
.1				>PUSHW ZPFrameBase1		try sending again to DRV
				ldx #DEVMGR.NET.SEND
				jsr NetDevJmp
				bcc .3
	
.2				ldx FRM.QUEUE.Tail		save error...
				sta FRM.QUEUE.State,x	
				dec FRM.QUEUE.Retry,x	
				bne .8					exit....until next run!
	
.3				ldx FRM.QUEUE.Tail		Success,or max retry, discard entry
				lda FRM.QUEUE.hMem,x
				>SYSCALL SYS.FreeMemA
				
.4				ldx FRM.QUEUE.Tail
				inx
				cpx #K.FRMQUEUE.SIZE
				bne .5
				ldx #0
.5				stx FRM.QUEUE.Tail
				bra .10
				
.8				rts
*--------------------------------------
FRM.GetLen1		lda (ZPFrameBase1)		Get Frame Len
				sta ZPFrameLen1
				ldy #1
				lda (ZPFrameBase1),y
				sta ZPFrameLen1+1
				rts
*--------------------------------------
MAN
SAVE LIB/LIBTCPIP.S.FRM
LOAD LIB/LIBTCPIP.S
ASM
