NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF LIB/LIBTCPIP
*--------------------------------------
AUXPIPE			.EQ 1
IPDEBUG			.EQ 0
*--------------------------------------
				.MA	ADC16
				clc
				lda ]1
				adc ]2
				sta ]1
				lda ]1+1
				adc ]2+1
				sta ]1+1
				.EM
*--------------------------------------
				.MA	SBC16
				sec
				lda ]1
				sbc ]2
				sta ]1
				lda ]1+1
				sbc ]2+1
				sta ]1+1
				.EM
*--------------------------------------
				.INB INC/MACROS.I
				.DO AUXPIPE=1
				.INB INC/IO.I
				.FIN
				.INB INC/A2OSX.I
				.INB INC/MLI.E.I
				.INB INC/NIC.I
				.INB INC/ETH.I
				.INB INC/LIB.NET.I
				.INB INC/LIBTCPIP.I
*--------------------------------------
ZPFrameInPtr	.EQ ZPLIB
ZPFrameInLen	.EQ ZPLIB+2

ZPDataInPtr		.EQ ZPLIB+4
ZPDataInLen		.EQ ZPLIB+6

ZPFrameOutPtr	.EQ ZPLIB+8
ZPFrameOutLen 	.EQ ZPLIB+10

ZPDataOutPtr	.EQ ZPLIB+12
ZPDataOutLen	.EQ ZPLIB+14

ZPTmpPtr1		.EQ ZPLIB+16
ZPPtrSKT		.EQ ZPLIB+18

ZPCode			.EQ ZPLIB+20			12 bytes

ZPPtrIP			.EQ ZPLIB+20
ZPPtrMAC		.EQ ZPLIB+22
ZPPtrDNS		.EQ ZPLIB+24
ZPCachePtr		.EQ ZPLIB+26

IP.CHECKSUM		.EQ ZPLIB+28
IP.CHECKSUM.TMP	.EQ ZPLIB+30

TmpDWord		.EQ ZPLIB+28
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA 0
				.DA CS.END-CS.START
				.DA 0
				.DA 0
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA LIB.LOAD
				.DA LIB.UNLOAD	
				
				.DA CFG.SET
				.DA CFG.GET
				
				.DA INCOMING
				.DA PULSE
				
				.DA ARP.CLEAR
				.DA ARP.QUERY
				.DA ARP.ADD
				.DA ARP.GetCACHE
				
				.DA DNS.CLEAR
				.DA DNS.QUERY
				.DA DNS.ADD
				.DA DNS.GetCACHE
				
				.DA HST.GETBYNAME
				.DA HST.GETBYADDR

				.DA SKT.Socket	
				.DA SKT.Bind
				.DA SKT.Connect
				.DA SKT.Listen

				.DA SKT.Accept
				.DA SKT.Shutdown
				
				.DA SKT.Read
				.DA SKT.Write
				.DA SKT.Recv
				.DA SKT.Send
				
				.DA SKT.RecvFrom
				.DA SKT.SendTo
				
				.DA SKT.getsockopt
				.DA SKT.setsockopt

				.DA SKT.EOF
				.DA SKT.GetTable
*--------------------------------------
L.IPCFG			.DA IPCFG
L.ARP.REQ		.DA ARP.REQ
L.ARP.REP		.DA ARP.REP
L.SA.LOCAL		.DA SA.LOCAL
L.SA.REMOTE		.DA SA.REMOTE
L.DNS.MSG		.DA DNS.MSG
L.DNS.CACHE		.DA DNS.CACHE
L.SKT.Table		.DA SKT.Table
L.HST.SScanF	.DA HST.SScanF
L.IOCTL			.DA IOCTL
L.DCB.NIC		.DA DCB.NIC
J.TCP.IN		.DA TCP.IN.JMP.CLOSED
				.DA TCP.IN.JMP.LISTEN
				.DA TCP.IN.JMP.SYNSENT
				.DA TCP.IN.JMP.SYNRCVD
				.DA TCP.IN.JMP.ESTBLSH
				.DA TCP.IN.JMP.CLWAIT
				.DA TCP.IN.JMP.LASTACK
				.DA TCP.IN.JMP.FINWT1
				.DA TCP.IN.JMP.FINWT2
				.DA TCP.IN.JMP.CLOSING
				.DA TCP.IN.JMP.TIMEWT
J.SKT.Socket	.DA SKT.Socket.RAW
				.DA SKT.Socket.DGRAM
				.DA SKT.Socket.SEQPACKET
				.DA SKT.Socket.STREAM
J.SKT.connect	.DA SKT.connect.RAW
				.DA SKT.connect.DGRAM
				.DA SKT.connect.SEQPACKET
				.DA SKT.connect.STREAM
J.SKT.send		.DA SKT.send.RAW
				.DA SKT.send.DGRAM
				.DA SKT.send.SEQPACKET
				.DA SKT.send.STREAM
				.DO IPDEBUG=1
L.MSG.IPID		.DA MSG.IPID
L.MSG.FRM.Dump	.DA MSG.FRM.Dump
L.MSG.SKT.Dump	.DA MSG.SKT.Dump
				.FIN
				.DA 0
*--------------------------------------
LIB.LOAD		ldx RefCount
				bne .8

				sta FD.DSOCK+S.FD.DSOCK.IOHANDLER
				sta FD.SSOCK+S.FD.SSOCK.IOHANDLER

				jsr ARP.CLEAR
				jsr DNS.CLEAR
						
.8				inc RefCount

				clc
				rts
*--------------------------------------
LIB.UNLOAD		dec RefCount
						
				clc
				rts
*--------------------------------------
INCOMING		sta hFrameIn

				>PULLW ZPTmpPtr1
				ldy #S.IOCTL.BUFPTR+3
				
.1				lda (ZPTmpPtr1),y		Get Frame Ptr & Len
				sta ZPFrameInPtr-S.IOCTL.BUFPTR,y
				dey
				bpl .1
				
				ldy #S.ETH.EII.TYPE
				lda (ZPFrameInPtr),y
				cmp /S.ETH.EII.TYPE.IP
				bne .9
				
				iny
				lda (ZPFrameInPtr),y
				
				cmp #S.ETH.EII.TYPE.ARP
				bne .2
				
				jmp	ARP.IN
				
.2				cmp #S.ETH.EII.TYPE.IP
				bne .9
				
				jmp IP.IN
				
.9				sec
INCOMING.RTS
				rts
*--------------------------------------
* A = S.EVT.F
* Expire = every sec
* Retry = every 100 msec
*--------------------------------------
PULSE			and #S.EVT.F.T1SEC
				beq .1

				jsr ARP.EXPIRE			every sec
				jsr DNS.EXPIRE
				
.1				jsr FRM.RETRY			every 100ms
				jsr DNS.POLL

*				lda A2osX.TIMER16
*				lsr
*				bcs INCOMING.RTS		Only every 200ms
				
				jmp TCP.SENDCLOSE
*--------------------------------------
GetDynPort		inc DYNPORT.LAST
				bne .1
				inc DYNPORT.LAST+1
				
				lda DYNPORT.LAST
				cmp #K.DYNPORT.END
				lda DYNPORT.LAST+1
				sbc /K.DYNPORT.END
				
				bcs .1
				
				lda #K.DYNPORT.START
				ldx /K.DYNPORT.START
				sta DYNPORT.LAST
				stx DYNPORT.LAST+1
				rts						CC
				
.1				lda DYNPORT.LAST
				ldx DYNPORT.LAST+1
				clc
				rts
*--------------------------------------
				.DO IPDEBUG=1
FRM.Dump		ldy #S.TCPUDP.DSTPORT
				lda (ZPFrameInPtr),y
				>PUSHA
				iny
				lda (ZPFrameInPtr),y
				>PUSHA
				
				ldy #S.IP.DST+3
				lda (ZPFrameInPtr),y
				>PUSHA
				dey
				lda (ZPFrameInPtr),y
				>PUSHA
				dey
				lda (ZPFrameInPtr),y
				>PUSHA
				dey
				lda (ZPFrameInPtr),y
				>PUSHA
				
				ldy #S.TCPUDP.SRCPORT
				lda (ZPFrameInPtr),y
				>PUSHA
				iny
				lda (ZPFrameInPtr),y
				>PUSHA
				
				ldy #S.IP.SRC+3
				lda (ZPFrameInPtr),y
				>PUSHA
				dey
				lda (ZPFrameInPtr),y
				>PUSHA
				dey
				lda (ZPFrameInPtr),y
				>PUSHA
				dey
				lda (ZPFrameInPtr),y
				>PUSHA
				
				>PUSHBI 12
				>LDYA L.MSG.FRM.Dump
				>SYSCALL2 Printf
				rts
*--------------------------------------
SKT.Dump		ldy #S.SOCKET.REM.PORT+1
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				
				ldy #S.SOCKET.REM.ADDR+3
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				
				ldy #S.SOCKET.LOC.PORT+1
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				
				ldy #S.SOCKET.LOC.ADDR+3
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				dey
				lda (ZPPtrSKT),y
				>PUSHA
				
				>PUSHBI 12
				>LDYA L.MSG.SKT.Dump
				>SYSCALL2 Printf
				rts
				.FIN
*--------------------------------------
				.INB USR/SRC/LIB/LIBTCPIP.S.ARP
				.INB USR/SRC/LIB/LIBTCPIP.S.CFG
				.INB USR/SRC/LIB/LIBTCPIP.S.DNS
				.INB USR/SRC/LIB/LIBTCPIP.S.FRM
				.INB USR/SRC/LIB/LIBTCPIP.S.HST
				.INB USR/SRC/LIB/LIBTCPIP.S.ICMP
				.INB USR/SRC/LIB/LIBTCPIP.S.IP
				.INB USR/SRC/LIB/LIBTCPIP.S.SKT
				.INB USR/SRC/LIB/LIBTCPIP.S.TCP
*--------------------------------------
CS.END
*--------------------------------------
				.DO AUXPIPE=1
ZP.CODE			sta SETREADAUX
				lda (ZPTmpPtr1),y
				sta CLRREADAUX
				rts
ZP.CODE.Len		.EQ *-ZP.CODE
				.FIN
*--------------------------------------
SA.LOCAL		.DA #AF.INET			S.SOCKADDR.AF
				.BS 1
				.BS 4					S.SOCKADDR.ADDR
				.BS 2					S.SOCKADDR.PORT
*--------------------------------------
SA.REMOTE		.DA #AF.INET			S.SOCKADDR.AF
				.BS 1
				.BS 4					S.SOCKADDR.ADDR
				.BS 2					S.SOCKADDR.PORT
*--------------------------------------
FD.DSOCK		.DA #S.FD.T.DSOCK
				.DA #0					S.FD.HANDLER
				.BS 1					S.FD.DSOCK.IOHANDLER
				.DA #0					S.FD.DSOCK.OPEN
				.DA #LIBTCPIP.shutdown
				.DA #LIBTCPIP.Recv
				.DA #LIBTCPIP.Send
				.DA #0					S.FD.DSOCK.STATUS
*--------------------------------------
				.DA #AF.INET			S.SOCKET.AF
				.BS 1					S.SOCKET.T
				.BS 1					S.SOCKET.PROTO
FD.DSOCK.SIZE	.EQ *-FD.DSOCK				
*--------------------------------------
FD.SSOCK		.DA #S.FD.T.SSOCK
				.DA #0					S.FD.HANDLER
				.BS 1					S.FD.SSOCK.IOHANDLER
				.DA #0					S.FD.SSOCK.OPEN
				.DA #LIBTCPIP.shutdown
				.DA #LIBTCPIP.Read
				.DA #LIBTCPIP.Write
				.DA #LIBTCPIP.EOF
*--------------------------------------
				.DA #AF.INET			S.SOCKET.AF
				.DA #S.SOCKET.T.STREAM
				.DA #S.IP.PROTOCOL.TCP
FD.SSOCK.SIZE	.EQ *-FD.SSOCK				
*--------------------------------------
IOCTL			.BS S.IOCTL
DCB.NIC			.BS S.DCB.NIC
IPCFG			.BS S.IPCFG
DNS.CACHE		.BS K.DNSCACHE.SIZE*S.DNSCACHE
*--------------------------------------
ARP.REQ			.HS FFFFFFFFFFFF		S.ETH.DSTMAC
ARP.REQ.SRCMAC	.BS 6
ARP.REQ.ETYPE	.DA /S.ETH.EII.TYPE.ARP
				.DA #S.ETH.EII.TYPE.ARP
				.HS 0001.0800.06.04
ARP.REQ.OP		.DA /S.ARP.OPERATION.REQ
				.DA #S.ARP.OPERATION.REQ
ARP.REQ.SHA		.BS 6
ARP.REQ.SPA		.BS 4
ARP.REQ.THA		.BS 6
ARP.REQ.TPA		.BS 4
*--------------------------------------
ARP.REP			.EQ *
ARP.REP.DSTMAC	.BS 6
ARP.REP.SRCMAC	.BS 6
ARP.REP.ETYPE	.DA /S.ETH.EII.TYPE.ARP
				.DA #S.ETH.EII.TYPE.ARP
				.HS 0001.0800.06.04
ARP.REP.OP		.DA /S.ARP.OPERATION.REP
				.DA #S.ARP.OPERATION.REP
ARP.REP.SHA		.BS 6
ARP.REP.SPA		.BS 4
ARP.REP.THA		.BS 6
ARP.REP.TPA		.BS 4
*--------------------------------------
DNS.MSG
DNS.MSG.ID		.BS 2
				.DA /S.DNS.F.RD			Flags=query
				.DA #S.DNS.F.RD			
				.DA $100				QDCOUNT
				.BS 6					ANCOUNT,NSCOUNT,ARCOUNT
DNS.MSG.NAME	.BS K.DNS.MAXLEN+6
*--------------------------------------
DNS.MSG.LEN		.BS 2
*--------------------------------------
FRM.QUEUE.Tail	.BS 1
FRM.QUEUE.Head	.BS 1 
FRM.QUEUE.hMem	.BS K.FRMQUEUE.SIZE
FRM.QUEUE.State	.BS K.FRMQUEUE.SIZE
FRM.QUEUE.Retry	.BS K.FRMQUEUE.SIZE
FRM.QUEUE.LenL	.BS K.FRMQUEUE.SIZE
FRM.QUEUE.LenH	.BS K.FRMQUEUE.SIZE
*--------------------------------------
RefCount		.DA #0
hARPCache		.DA #0
DYNPORT.LAST	.DA K.DYNPORT.START
hDNSSocket		.BS 1
DNS.TmpCache	.BS	S.DNSCACHE
ARP.TmpCache	.BS S.ARPCACHE
*--------------------------------------
SKT.Index		.BS 1
SKT.TABLE		.BS K.SKTTABLE.SIZE
SKT.LOC.ADDR	.BS S.SOCKADDR
SKT.REM.ADDR	.BS S.SOCKADDR
SKT.Cache		.EQ *-S.SOCKET.TCP.INTAIL
				.BS S.SOCKET.TCP-S.SOCKET.TCP.INTAIL
hFrameIn		.BS 1
hFrameOut		.BS 1
HST.SScanF		.AZ "%d.%d.%d.%d"
IP.ID			.BS 2
				.DO IPDEBUG=1
MSG.IPID		.AZ "IPID:%H\r\n"
MSG.FRM.Dump	.AZ "FRM:SRC=%d.%d.%d.%d:%D DST=%d.%d.%d.%d:%D\r\n"
MSG.SKT.Dump	.AZ "SKT:LOC=%d.%d.%d.%d:%D REM=%d.%d.%d.%d:%D\r\n"
				.FIN
*--------------------------------------
MAN
SAVE USR/SRC/LIB/LIBTCPIP.S
ASM
