NEW
  AUTO 3,1
*--------------------------------------
FRM.GetTargetSKT.TCPUDP
				ldy #S.TCPUDP.SRCPORT
				lda (ZPFrameInPtr),y
				sta SKT.REM.ADDR+S.SOCKADDR.PORT+1
				iny
				lda (ZPFrameInPtr),y
				sta SKT.REM.ADDR+S.SOCKADDR.PORT
				iny						#S.TCPUDP.DSTPORT
				lda (ZPFrameInPtr),y
				sta SKT.LOC.ADDR+S.SOCKADDR.PORT+1
				iny
				lda (ZPFrameInPtr),y
				sta SKT.LOC.ADDR+S.SOCKADDR.PORT

FRM.GetTargetSKT.RAW
				ldy #S.IP.SRC+3
				ldx #3

.1				lda (ZPFrameInPtr),y
				sta SKT.REM.ADDR+S.SOCKADDR.ADDR,x
				dey
				dex
				bpl .1

				ldy #S.IP.DST+3
				ldx #3

.2				lda (ZPFrameInPtr),y
				sta SKT.LOC.ADDR+S.SOCKADDR.ADDR,x
				dey
				dex
				bpl .2

				rts
*--------------------------------------
* FRM.NewIP
*  In:
*  Y,A = DataLen
*  X = S.IP.PROTOCOL.xxx
* Out:
*  Y,A = Frame PTR
*  X = hMem
*--------------------------------------
FRM.NewIP		stx	.8+1
				>STYA ZPDataOutLen
				cpx #S.IP.PROTOCOL.TCP
				bne .1

				lda #S.TCP
				bra .4

.1				cpx #S.IP.PROTOCOL.UDP
				bne .2

				lda #S.UDP
				bra .4

.2				lda #S.IP

.4				sta	.5+1 				save Header len for reset later
				clc
				adc ZPDataOutLen
				sta ZPFrameOutLen
				tay
				lda #0
				adc ZPDataOutLen+1
				sta ZPFrameOutLen+1
				>SYSCALL2 getmem
				bcs .9

				stx hFrameOut
				>STYA ZPFrameOutPtr

				ldy #0
.5				ldx #$ff				Self Modified, header length
				lda #0

.6				sta (ZPFrameOutPtr),y
				iny
				dex
				bne .6

				tya
*				clc
				adc ZPFrameOutPtr
				sta ZPDataOutPtr
				lda #0
				adc ZPFrameOutPtr+1
				sta ZPDataOutPtr+1
				lda IPCFG+S.NETCFG.DevFlags
				and #S.DCB.NIC.FLAGS.IPOFFLOAD
				bne .7

				ldy #S.ETH.EII.TYPE
				lda /S.ETH.EII.TYPE.IP
				sta (ZPFrameOutPtr),y
				iny
				lda #S.ETH.EII.TYPE.IP
				sta (ZPFrameOutPtr),y

				ldy #S.IP.V.IHL.DSCP.ECN
				lda #$45
				sta (ZPFrameOutPtr),y
*				iny
*				lda #$0
*				sta (ZPFrameOutPtr),y

*				ldy #S.IP.FRAGMENT.FLAGS
*				sta (ZPFrameOutPtr),y
*				iny
*				sta (ZPFrameOutPtr),y
				ldy #S.IP.IDENTIFICATION+1
				lda IP.ID
				ldx IP.ID+1
				inc
				bne .61

				inx

				stx IP.ID+1

.61				sta IP.ID
				sta (ZPFrameOutPtr),y
				dey
				txa
				sta (ZPFrameOutPtr),y

				ldy #S.IP.TTL
				lda #K.IP.TTL
				sta (ZPFrameOutPtr),y

.7				ldy #S.IP.PROTOCOL

.8				lda #$ff
				sta (ZPFrameOutPtr),y
.9				rts
*--------------------------------------
*				clc						Queue if fail
*				sec						DONT Queue if fail
*--------------------------------------
FRM.SendIP		php
				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 (ZPFrameOutPtr),y
				dey
				dex
				bpl .1

				lda IPCFG+S.NETCFG.DevFlags
				and #S.DCB.NIC.FLAGS.IPOFFLOAD
				bne .21

				ldy #S.IP.TOTAL.LENGTH+1
				lda ZPFrameOutLen
				sec
				sbc #S.ETH.EII
				sta (ZPFrameOutPtr),y
				dey
				lda ZPFrameOutLen+1
				sbc /S.ETH.EII
				sta (ZPFrameOutPtr),y
				lda #0
				ldy #S.IP.HDR.CHECKSUM
				sta (ZPFrameOutPtr),y
				iny
				sta (ZPFrameOutPtr),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 (ZPFrameOutPtr),y
				adc IP.CHECKSUM
				sta IP.CHECKSUM

				iny
				lda (ZPFrameOutPtr),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 (ZPFrameOutPtr),y
				iny
				lda IP.CHECKSUM+1
				adc #0
				eor #$FF
				sta (ZPFrameOutPtr),y

.21				ldy #S.IP.PROTOCOL
				lda (ZPFrameOutPtr),y
				cmp #S.IP.PROTOCOL.TCP
				bne .3

				jsr IP.ComputeTCPChecksum
				bra .5

.3				cmp #S.IP.PROTOCOL.UDP
				bne .4

				lda ZPFrameOutLen
				sec
				sbc #S.IP
				ldy #S.UDP.LENGTH+1
				sta (ZPFrameOutPtr),y
				lda ZPFrameOutLen+1
				sbc /S.IP
				dey
				sta (ZPFrameOutPtr),y
				jsr IP.ComputeUDPChecksum
				bra .5

.4				cmp #S.IP.PROTOCOL.ICMP
				bne .5

				jsr IP.ComputeICMPChecksum

.5				lda IPCFG+S.NETCFG.DevFlags
				and #S.DCB.NIC.FLAGS.ARPOFFLOAD
				bne .6

				jsr IP.SetDestMAC
				bcs FRM.Queue

.6				jsr FRM.Send
				bcs FRM.Queue

				jsr	FRM.Discard

				plp
				clc
				rts
*--------------------------------------
FRM.Queue		plp
				bcs FRM.Discard			DONT queue

				ldy hFrameOut			no hFrame, cannot queue for retry
				beq FRM.Discard.9

				ldx FRM.QUEUE.Head
				inx
				cpx #K.FRMQUEUE.SIZE
				bne .1

				ldx #0

.1				cpx FRM.QUEUE.Tail
				beq FRM.Discard			CS
				ldy FRM.QUEUE.Head
				stx FRM.QUEUE.Head

				sta	FRM.QUEUE.State,y
				lda #K.FRMSEND.RETRY
				sta FRM.QUEUE.Retry,y
				lda hFrameOut
				sta FRM.QUEUE.hMem,y
				lda ZPFrameOutLen
				sta FRM.QUEUE.LenL,y
				lda ZPFrameOutLen+1
				sta FRM.QUEUE.LenH,y
				clc
.9				rts
*--------------------------------------
FRM.Discard		lda hFrameOut
				beq FRM.Discard.9

				stz hFrameOut
				>SYSCALL2 FreeMem

FRM.Discard.9	sec
				rts
*--------------------------------------
FRM.Retry		ldx FRM.QUEUE.Tail

.1				cpx FRM.QUEUE.Head
				beq .8					Queue is empty, exit...
				lda FRM.QUEUE.LenL,x
				sta ZPFrameOutLen
				lda FRM.QUEUE.LenH,x
				sta ZPFrameOutLen+1

				lda FRM.QUEUE.hMem,x
				>SYSCALL2 GetMemPtr
				>STYA ZPFrameOutPtr
				ldx FRM.QUEUE.Tail
				lda FRM.QUEUE.State,x
				cmp #ERR.ARP.PENDING
				bne .2

				jsr IP.SetDestMAC		Err is ARP or higher, retry getting MAC
				bcs .3					still error getting dest MAC
.2				jsr FRM.Send			try sending again to DRV
				bcc .4

.3				ldx FRM.QUEUE.Tail
				sta FRM.QUEUE.State,x	save error...
				dec FRM.QUEUE.Retry,x
				bne .8					exit....until next run!

.4				ldx FRM.QUEUE.Tail
				lda FRM.QUEUE.hMem,x	Success,or max retry, discard entry
				inx
				cpx #K.FRMQUEUE.SIZE
				bne .5

				ldx #0
.5				stx FRM.QUEUE.Tail
				>SYSCALL2 FreeMem
				bra FRM.Retry

.8				rts
*--------------------------------------
FRM.Send		ldx #3

.1				lda ZPFrameOutPtr,x		Get Frame Ptr & Len
				sta IOCTL+S.IOCTL.BUFPTR,x
				dex
				bpl .1

FRM.Send.IOCTL	>PUSHB IPCFG+S.NETCFG.DevID
				>PUSHBI IOCTL.WRITE
				>PUSHW L.IOCTL
				>SYSCALL2 IOCTL
				rts
*--------------------------------------
FRM.DiscardIn	lda hFrameIn
				beq .8
				stz hFrameIn

				>SYSCALL2 FreeMem
.8				clc
				rts
*--------------------------------------
MAN
SAVE usr/src/lib/libtcpip.s.frm
LOAD usr/src/lib/libtcpip.s
ASM
