NEW AUTO 3,1 .LIST OFF *-------------------------------------- TCP.IN jsr FRM.GetTargetSKT.TCPUDP jsr SKT.FindMatchingLocRem bcs TCP.IN.JMP.DISCARD no socket, go discard ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.RST RST ? go Kill this socket... bne TCP.IN.RST ...and discard frame ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y asl tax jmp (J.TCP.IN,x) *-------------------------------------- TCP.IN.RST lda SKT.TABLE,x jsr SKT.shutdown *-------------------------------------- TCP.IN.JMP.OPENED TCP.IN.JMP.CLOSED TCP.IN.JMP.DISCARD jmp FRM.DiscardIn *-------------------------------------- TCP.IN.JMP.LISTEN ldy #S.SOCKET.T Create a new client socket lda (ZPPtrSKT),y tax Same type a listening socket iny #S.SOCKET.PROTO lda (ZPPtrSKT),y jsr SKT.Socket.I get new socket in ZPTmpPtr1 bcs TCP.IN.JMP.DISCARD jsr SKT.AddToQueueA Queued successfully ? bcs TCP.IN.JMP.DISCARD no, discard frame and new socket jsr ARP.AddFromFrameInPtr lda ZPTmpPtr1 sta ZPPtrSKT lda ZPTmpPtr1+1 sta ZPPtrSKT+1 jsr SKT.SetLocAddr jsr SKT.SetRemAddr jsr SKT.NewTCB bcs .99 jsr TCP.IN.ACKTheSYN lda #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA SYN received, Send SYN.ACK bcs .9 lda #S.SOCKET.TCP.S.SYNRCVD jmp SKT.StoreTCB.S .9 lda #ERR.SKT.OOS .99 rts *-------------------------------------- TCP.IN.JMP.SYNSENT ldy #S.TCP.OPTIONS SYN Send, only accept SYN.ACK packet, then Send ACK lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK cmp #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK bne .9 jsr SKT.GetTCB ldx #3 ldy #S.TCP.ACKNUM+3 sec Check if ACK=OUTNEXTSEQ+1 .1 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x adc #0 sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x eor (ZPFrameInPtr),y bne .9 dey dex bpl .1 jsr TCP.IN.ACKTheSYN lda #S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA SYN.ACK received, Send, ACK bcs .9 lda #S.SOCKET.TCP.S.ESTBLSH jmp SKT.StoreTCB.S .9 lda #S.TCP.OPTIONS.RST jsr TCP.OUT.SendOptA Send RST ldx SKT.Index lda SKT.TABLE,x jmp SKT.shutdown *-------------------------------------- TCP.IN.JMP.SYNRCVD ldy #S.TCP.OPTIONS SYN Received, SYN.ACK Sent, only accept ACK packet lda (ZPFrameInPtr),y cmp #S.TCP.OPTIONS.ACK bne .8 jsr SKT.GetTCB ldx #3 ldy #S.TCP.ACKNUM+3 sec .1 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x Check if ACK=OUTNEXTSEQ+1 adc #0 sta SKT.Cache+S.SOCKET.TCP.OUTSENTSEQ,x setup SEQNUM sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x ...and update NEXTSEQ eor (ZPFrameInPtr),y bne .8 dey dex bpl .1 lda #S.SOCKET.TCP.S.ESTBLSH jmp SKT.StoreTCB.S .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.ESTBLSH .DO IPDEBUG=1 jsr DEBUG.IPID .FIN jsr SKT.GetTCB ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.ACK Remote side ACKed data ? beq .4 * Ack sent data ldy #S.TCP.ACKNUM+3 Get new ACK number from FrameIn... ldx #3 Substract old ACK from socket sec .1 lda (ZPFrameInPtr),y pha sbc SKT.Cache+S.SOCKET.TCP.OUTSENTSEQ,x sta TmpDWord,x pla ....and Set SEQ = new SEQ sta SKT.Cache+S.SOCKET.TCP.OUTSENTSEQ,x dey dex bpl .1 lda TmpDWord+3 ldx TmpDWord+2 bne .2 tay beq .4 .2 pha clc adc SKT.Cache+S.SOCKET.TCP.OUTTAIL sta SKT.Cache+S.SOCKET.TCP.OUTTAIL txa adc SKT.Cache+S.SOCKET.TCP.OUTTAIL+1 and /K.TCP.WSIZE-1 sta SKT.Cache+S.SOCKET.TCP.OUTTAIL+1 pla clc adc SKT.Cache+S.SOCKET.TCP.OUTFREE sta SKT.Cache+S.SOCKET.TCP.OUTFREE txa adc SKT.Cache+S.SOCKET.TCP.OUTFREE+1 sta SKT.Cache+S.SOCKET.TCP.OUTFREE+1 lda SKT.Cache+S.SOCKET.TCP.OUTUSED sec sbc TmpDWord+3 sta SKT.Cache+S.SOCKET.TCP.OUTUSED lda SKT.Cache+S.SOCKET.TCP.OUTUSED+1 sbc TmpDWord+2 sta SKT.Cache+S.SOCKET.TCP.OUTUSED+1 jsr SKT.StoreTCB * Store incoming data .4 jsr TCP.IN.SetDataInPtrAndLen lda ZPDataInLen Incoming Data in this frame ? ora ZPDataInLen+1 beq .7 No data, ... ldy #S.TCP.SEQNUM+3 ldx #3 .5 lda (ZPFrameInPtr),y eor SKT.Cache+S.SOCKET.TCP.INSEQNUM,x bne .9 Missed a frame..... .51 dey dex bpl .5 ldy #S.SOCKET.T Create a new client socket lda (ZPPtrSKT),y cmp #S.SOCKET.T.STREAM bne .52 jsr SKT.AddDataToSktIn yes, queue data if there is room for.... bra .59 .52 lda hFrameIn jsr SKT.AddToQueueA bcs .9 .59 lda ZPDataInLen ldy ZPDataInLen+1 ldx #S.SOCKET.TCP.INSEQNUM jsr TCP.AddAYToSktCacheAtX .6 jsr SKT.StoreTCB update socket * jsr TCP.SetSocketTCPO.ACK ...and ack data lda #S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA * bcs * .7 ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.FIN beq .8 lda #S.SOCKET.TCP.S.CLWAIT ldy #S.SOCKET.TCP.S sta (ZPPtrSKT),y jsr TCP.IN.ACKTheFIN lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK jsr TCP.SetSocketTCPO FIN received, Send FIN.ACK * jsr TCP.OUT.SendOptA .8 clc rts .9 sec rts *-------------------------------------- TCP.IN.JMP.LASTACK ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.ACK beq .8 ldy #S.SOCKET.TCP.S lda #S.SOCKET.TCP.S.TIMEWT sta (ZPPtrSKT),y .8 *-------------------------------------- TCP.IN.JMP.CLWAIT clc Wait for SKT.shutdown rts *-------------------------------------- TCP.IN.JMP.FINWT1 jsr SKT.GetTCB ldy #S.TCP.OPTIONS FIN sent, accept ACK or FIN/ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.FIN bne .1 lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA Send FIN.ACK bcs TCP.IN.JMP.TIMEWT.RTS lda #S.SOCKET.TCP.S.FINWT2 jmp SKT.StoreTCB.S .1 jsr TCP.IN.ACKTheFIN FIN/ACK lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK bra TCP.IN.JMP.FINWT.ACK Send FIN.ACK *-------------------------------------- TCP.IN.JMP.FINWT2 ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.ACK beq TCP.IN.JMP.TIMEWT jsr SKT.GetTCB jsr TCP.IN.ACKTheFIN lda #S.TCP.OPTIONS.ACK TCP.IN.JMP.FINWT.ACK jsr TCP.OUT.SendOptA FIN received, Send ACK bcs TCP.IN.JMP.TIMEWT.RTS lda #S.SOCKET.TCP.S.TIMEWT jmp SKT.StoreTCB.S *-------------------------------------- TCP.IN.JMP.CLOSING ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.ACK beq .1 ldy #S.SOCKET.TCP.S lda #S.SOCKET.TCP.S.TIMEWT sta (ZPPtrSKT),y .1 * clc * rts *-------------------------------------- TCP.IN.JMP.TIMEWT clc Wait for TCP.Close TCP.IN.JMP.TIMEWT.RTS rts *-------------------------------------- TCP.IN.ACKTheSYN ldy #S.TCP.SEQNUM+3 Get Remote SEQ ldx #3 sec .3 lda (ZPFrameInPtr),y Set OUTACK=SEQ+1 for new socket... adc #0 sta SKT.Cache+S.SOCKET.TCP.INSEQNUM,x dey dex bpl .3 rts *-------------------------------------- TCP.IN.ACKTheFIN jsr TCP.SetSocketTCPO.ACK ldx #3 .1 inc SKT.Cache+S.SOCKET.TCP.INSEQNUM,x bne .8 dex bpl .1 .8 rts *-------------------------------------- TCP.IN.SetDataInPtrAndLen ldy #S.IP.TOTAL.LENGTH+1 lda (ZPFrameInPtr),y sec sbc #S.IP-S.ETH.EII sta ZPDataInLen dey lda (ZPFrameInPtr),y sbc /S.IP-S.ETH.EII sta ZPDataInLen+1 ldy #S.TCP.DATAOFFSET lda (ZPFrameInPtr),y and #$F0 Get TCP Header len in DWORD lsr lsr sta ZPDataInPtr TMP Storage lda ZPDataInLen sec sbc ZPDataInPtr TMP Storage sta ZPDataInLen bcs .1 dec ZPDataInLen+1 .1 lda ZPFrameInPtr clc adc #S.IP pha lda ZPFrameInPtr+1 adc /S.IP tax pla clc adc ZPDataInPtr TMP Storage bcc .2 inx .2 sta ZPDataInPtr stx ZPDataInPtr+1 TCP.IN.RTS rts *-------------------------------------- TCP.SENDCLOSE ldx #0 .1 phx lda SKT.TABLE,x beq .8 >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.AF lda (ZPPtrSKT),y cmp #AF.INET bne .8 iny #S.SOCKET.T lda (ZPPtrSKT),y cmp #S.SOCKET.T.SEQPACKET bcc .8 ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y cmp #S.SOCKET.TCP.S.TIMEWT beq .4 cmp #S.SOCKET.TCP.S.ESTBLSH bne .2 jsr SKT.GetTCB jsr TCP.OUT bra .8 .2 cmp #S.SOCKET.TCP.S.OPENED bne .8 jsr SKT.GetTCB lda #S.TCP.OPTIONS.SYN jsr TCP.OUT.SendOptA Send SYN bcs .8 failed ARP lookup.... lda #S.SOCKET.TCP.S.SYNSENT jsr SKT.StoreTCB.S bra .8 lda #S.TCP.OPTIONS.SYN jsr TCP.OUT.SendOptA Send SYN bra .8 .4 ldy #S.SOCKET.SQ.hInMem lda (ZPPtrSKT),y beq .5 .DO AUXPIPE=1 >SYSCALL2 FreeStkObj .ELSE >SYSCALL2 freemem .FIN .5 ldy #S.SOCKET.SQ.hOutMem lda (ZPPtrSKT),y beq .6 .DO AUXPIPE=1 >SYSCALL2 FreeStkObj .ELSE >SYSCALL2 freemem .FIN .6 plx phx lda SKT.TABLE,x stz SKT.TABLE,x >SYSCALL2 freemem .8 plx inx cpx #K.SKTTABLE.SIZE bne .1 .9 rts *-------------------------------------- TCP.OUT lda SKT.Cache+S.SOCKET.TCP.OUTTOSEND+1 ldy SKT.Cache+S.SOCKET.TCP.OUTTOSEND bne .1 tax bne .1 * Y,A=0 : no data to send ldy #S.SOCKET.TCP.O lda (ZPPtrSKT),y bne TCP.OUT.SendOptA a least an option... clc No data, no flag....exit .9 rts .1 cpy #K.TCP.MSS pha sbc /K.TCP.MSS OUTDATA > MSS ? pla bcc .2 no....keep data len >LDYAI K.TCP.MSS yes send only MSS .2 jsr TCP.NewFrame bcs .9 jsr SKT.GetDataFromSktOut ldy #S.TCP.WINDOW lda SKT.Cache+S.SOCKET.TCP.INFREE+1 sta (ZPFrameOutPtr),y iny lda SKT.Cache+S.SOCKET.TCP.INFREE sta (ZPFrameOutPtr),y TCP.OUT.SEQSEND lda #S.TCP.OPTIONS.ACK+S.TCP.OPTIONS.PSH jsr TCP.OUT.Send bcs TCP.OUT.Send.RTS lda ZPDataOutLen ldy ZPDataOutLen+1 ldx #S.SOCKET.TCP.OUTNEXTSEQ jsr TCP.AddAYToSktCacheAtX jmp SKT.StoreTCB exits with CC *-------------------------------------- TCP.OUT.SendOptA jsr TCP.SetSocketTCPO >LDYAI 0 jsr TCP.NewFrame bcs TCP.OUT.Send.RTS ldy #S.SOCKET.TCP.INFREE+1 lda (ZPPtrSKT),y tax dey lda (ZPPtrSKT),y ldy #S.TCP.WINDOW+1 sta (ZPFrameOutPtr),y dey txa sta (ZPFrameOutPtr),y ldy #S.SOCKET.TCP.O lda (ZPPtrSKT),y TCP.OUT.Send ldy #S.TCP.OPTIONS sta (ZPFrameOutPtr),y bit #S.TCP.OPTIONS.ACK beq .2 ldx #3 ldy #S.TCP.ACKNUM+3 .1 lda SKT.Cache+S.SOCKET.TCP.INSEQNUM,x sta (ZPFrameOutPtr),y dey dex bpl .1 .2 ldx #3 ldy #S.TCP.SEQNUM+3 .3 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x sta (ZPFrameOutPtr),y dey dex bpl .3 sec DONT Queue if fail jsr FRM.SendIP bcs TCP.OUT.Send.RTS ldy #S.SOCKET.TCP.O lda #0 sta (ZPPtrSKT),y * clc TCP.OUT.Send.RTS rts *-------------------------------------- TCP.SetSocketTCPO.ACK lda #S.TCP.OPTIONS.ACK TCP.SetSocketTCPO ldy #S.SOCKET.TCP.O ora (ZPPtrSKT),y sta (ZPPtrSKT),y rts *-------------------------------------- TCP.NewFrame ldx #S.IP.PROTOCOL.TCP jsr FRM.NewIP bcs .9 jsr SKT.SetFrameOutDstIP jsr SKT.SetFrameOutTCPUDPPorts ldy #S.TCP.DATAOFFSET lda #$50 Header size = 5 DWORDS sta (ZPFrameOutPtr),y clc .9 rts *-------------------------------------- TCP.AddAYToSktCacheAtX clc adc SKT.Cache+3,x sta SKT.Cache+3,x tya adc SKT.Cache+2,x sta SKT.Cache+2,x bcc .8 inc SKT.Cache+1,x bne .8 inc SKT.Cache,x .8 rts *-------------------------------------- .DO IPDEBUG=1 DEBUG.IPID ldy #S.IP.IDENTIFICATION lda (ZPFrameInPtr),y >PUSHA iny lda (ZPFrameInPtr),y >PUSHA >PUSHBI 2 >LDYA L.MSG.IPID >SYSCALL PrintF rts .FIN *-------------------------------------- MAN SAVE USR/SRC/LIB/LIBTCPIP.S.TCP LOAD USR/SRC/LIB/LIBTCPIP.S ASM