NEW AUTO 3,1 .LIST OFF */-------------------------------------- * # Socket * Create a new socket * ## C * `hFD socket(short int type, short int protocol);` * ## ASM * **In:** * `>PUSHB protocol` * `lda type` * `>LIBCALL hLIBTCPIP,LIBTCPIP.socket` * ## RETURN VALUE * CC: A = hSOCKET * CS: A = EC *\-------------------------------------- SKT.Socket tax >PULLA get protocol (RAW) SKT.Socket.I jmp (J.SKT.Socket,x) SKT.Socket.RAW ldy #S.SOCKET bra SKT.Socket.DSOCK SKT.Socket.DGRAM lda #S.IP.PROTOCOL.UDP ldy #S.SOCKET SKT.Socket.DSOCK stx FD.DSOCK+S.SOCKET.T save type sta FD.DSOCK+S.SOCKET.PROTO ICMP,UDP,TCP sty TmpDWord lda #0 Y = socket.size >SYSCALL2 GetMem bcs .9 >STYA ZPTmpPtr1 jsr SKT.Socket.FindFree bcs .9 ldy #0 .1 lda FD.DSOCK,y sta (ZPTmpPtr1),y iny cpy #FD.DSOCK.SIZE bne .1 lda #0 .2 sta (ZPTmpPtr1),y iny cpy TmpDWord bne .2 txa clc .9 rts SKT.Socket.SEQPKT SKT.Socket.STREAM lda #S.IP.PROTOCOL.TCP ldy #S.SOCKET.TCP stx FD.SSOCK+S.SOCKET.T save type sta FD.SSOCK+S.SOCKET.PROTO sty TmpDWord lda #0 Y = socket.size >SYSCALL2 GetMem bcs .9 >STYA ZPTmpPtr1 jsr SKT.Socket.FindFree bcs .9 ldy #0 .1 lda FD.SSOCK,y sta (ZPTmpPtr1),y iny cpy #FD.SSOCK.SIZE bne .1 lda #0 .2 sta (ZPTmpPtr1),y iny cpy TmpDWord bne .2 txa clc .9 rts SKT.Socket.FindFree ldy #0 .1 lda SKT.TABLE,y beq .2 iny cpy #K.SKTTABLE.SIZE bne .1 txa >SYSCALL2 freemem lda #E.OOH sec rts .2 txa sta SKT.TABLE,y clc rts */-------------------------------------- * # Bind * bind a name to a socket * ## C * `int bind(hFD fd, const struct sockaddr *addr);` * ## ASM * **In:** * `>PUSHW addr` * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.socket` * ## RETURN VALUE * CC: A = hSOCKET * CS: A = EC *\-------------------------------------- SKT.bind >SYSCALL2 GetMemPtr >STYA ZPPtrSKT jsr SKT.PullLocAddr lda SKT.LOC.ADDR+S.SOCKADDR.PORT ora SKT.LOC.ADDR+S.SOCKADDR.PORT+1 bne .1 jsr GetDynPort sta SKT.LOC.ADDR+S.SOCKADDR.PORT stx SKT.LOC.ADDR+S.SOCKADDR.PORT+1 .1 ldx #0 .2 lda SKT.TABLE,x beq .7 phx >SYSCALL2 GetMemPtr >STYA ZPTmpPtr1 plx ldy #S.SOCKET.AF lda (ZPTmpPtr1),y cmp #AF.INET bne .7 ldy #S.SOCKET.LOC.ADDR .3 lda (ZPTmpPtr1),y cmp SKT.LOC.ADDR+S.SOCKADDR.ADDR-S.SOCKET.LOC.ADDR,y bne .7 iny cpy #S.SOCKET.LOC.PORT+2 bne .3 lda #ERR.SKT.BUSY * sec rts .7 inx cpx #K.SKTTABLE.SIZE bne .2 jmp SKT.SetLocAddr */-------------------------------------- * # Connect * Initiate a connection on a socket * ## C * `int connect(hFD fd, const struct sockaddr *addr);` * ## ASM * **In:** * `>PUSHW addr` * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.socket` * ## RETURN VALUE * CC: A = hSOCKET * CS: A = EC *\-------------------------------------- SKT.connect >SYSCALL2 GetMemPtr >STYA ZPPtrSKT jsr SKT.PullRemAddr ldy #S.SOCKET.T lda (ZPPtrSKT),y tax jmp (J.SKT.connect,x) SKT.connect.RAW SKT.connect.DGRAM jmp SKT.SetRemAddr SKT.connect.STREAM SKT.connect.SEQPKT ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y beq .1 cmp #S.SOCKET.TCP.S.ESTBLSH beq SKT.listen.8 bcs .9 cmp #S.SOCKET.TCP.S.OPENED beq .2 cmp #S.SOCKET.TCP.S.SYNSENT beq .99 .9 lda #ERR.SKT.BAD sec rts .1 jsr SKT.SetRemAddr jsr SKT.NewTCB bcs SKT.listen.RTS lda #S.SOCKET.TCP.S.OPENED jsr SKT.StoreTCB.S .2 lda #S.TCP.OPTIONS.SYN jsr TCP.OUT.SendOptA Send SYN bcs .99 lda #S.SOCKET.TCP.S.SYNSENT jsr SKT.StoreTCB.S .99 lda #ERR.SKT.NOCONN sec rts */-------------------------------------- * # Listen * Listen for connections on a socket * ## C * `int listen(hFD fd);` * ## ASM * **In:** * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.listen` * ## RETURN VALUE * CS: A = EC *\-------------------------------------- SKT.listen >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.T lda (ZPPtrSKT),y cmp #S.SOCKET.T.SEQPKT bcc SKT.listen.9 ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y bne SKT.listen.9 lda #S.SOCKET.TCP.S.LISTEN sta (ZPPtrSKT),y ldy #S.SOCKET.O lda #S.SOCKET.O.ACCEPTCONN sta (ZPPtrSKT),y SKT.listen.8 clc rts SKT.listen.9 lda #ERR.SKT.BAD sec SKT.listen.RTS rts */-------------------------------------- * # Accept * Accept a connection on a socket * ## C * `hFD Accept(hFD fd);` * ## ASM * **In:** * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.accept` * ## RETURN VALUE * A = hSocket *\-------------------------------------- SKT.Accept >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.O lda (ZPPtrSKT),y and #S.SOCKET.O.ACCEPTCONN beq .99 ldy #S.SOCKET.HQ.TAIL lda (ZPPtrSKT),y ldy #S.SOCKET.HQ.HEAD cmp (ZPPtrSKT),y beq .9 CS pha inc cmp #S.SOCKET.HQ.MAX bne .1 lda #0 .1 ldy #S.SOCKET.HQ.TAIL sta (ZPPtrSKT),y pla clc adc #S.SOCKET.HQ tay lda (ZPPtrSKT),y clc rts .99 lda #ERR.SKT.BAD sec .9 rts */-------------------------------------- * # Shutdown * Close socket * ## C * `int shutdown(int fd);` * ## ASM * **In:** * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.shutdown` * ## RETURN VALUE *\-------------------------------------- SKT.shutdown pha >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.O lda (ZPPtrSKT),y and #S.SOCKET.O.ACCEPTCONN bne SKT.shutdown.LISTEN ldy #S.SOCKET.T lda (ZPPtrSKT),y cmp #S.SOCKET.T.STREAM beq SKT.shutdown.STREAM *-------------------------------------- cmp #S.SOCKET.T.SEQPKT bne SKT.shutdown.DGRAM pla pha jsr SKT.shutdown.TCP * bcs SKT.shutdown.RTS *-------------------------------------- SKT.shutdown.LISTEN SKT.shutdown.RAW SKT.shutdown.DGRAM SKT.shutdown.SEQPKT .1 ldy #S.SOCKET.HQ.TAIL lda (ZPPtrSKT),y ldy #S.SOCKET.HQ.HEAD cmp (ZPPtrSKT),y beq .3 No frame in Queue, close.. pha save tail... clc adc #S.SOCKET.HQ tax pla inc cmp #S.SOCKET.HQ.MAX bne .2 lda #0 .2 ldy #S.SOCKET.HQ.TAIL sta (ZPPtrSKT),y txa tay lda (ZPPtrSKT),y >SYSCALL2 FreeMem bra .1 .3 pla get hFD... ldx #0 .4 cmp SKT.TABLE,x beq .5 inx cpx #K.SKTTABLE.SIZE bne .4 .5 stz SKT.TABLE,x >SYSCALL2 freemem * clc SKT.shutdown.RTS rts *-------------------------------------- SKT.shutdown.STREAM pla SKT.shutdown.TCP jsr SKT.GetTCB ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y cmp #S.SOCKET.TCP.S.ESTBLSH bne .1 lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA Send FIN/ACK bcs .9 lda #S.SOCKET.TCP.S.FINWT1 jmp SKT.StoreTCB.S .1 cmp #S.SOCKET.TCP.S.CLWAIT beq .3 .2 lda #S.TCP.OPTIONS.RST jsr TCP.OUT.SendOptA Send RST bcs .9 .3 lda #S.SOCKET.TCP.S.TIMEWT jmp SKT.StoreTCB.S .9 rts */-------------------------------------- * # Read (STREAM) * ## C * `int skt.read(hFD fd, void *buf, int count);` * ## ASM * **In:** * `>PUSHWI count` * `>PUSHW buf` * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.read` * ## RETURN VALUE * CC: Y,A = bytes read * CS: A = EC *\-------------------------------------- SKT.Read jsr SKT.PullhFDDataInPtrLen ldy #S.SOCKET.TCP.INUSED lda (ZPPtrSKT),y tax iny ora (ZPPtrSKT),y beq .7 no data, go check SKT status cpx ZPDataInLen XA = Data in pipe lda (ZPPtrSKT),y sbc ZPDataInLen+1 bcs SKT.GetDataFromSktIn more data in pipe, get full buffer of data stx ZPDataInLen less data than INUSED, Get only INUSED data lda (ZPPtrSKT),y sta ZPDataInLen+1 bra SKT.GetDataFromSktIn .7 jsr SKT.CheckStream bcs .99 I/O error lda #E.NODATA sec .99 rts *-------------------------------------- * In: * Src : hInMem/INTAIL * Dst : ZPDataOutPtr/ZPDataOutLen * Out: * Y,A = bytes read *-------------------------------------- SKT.GetDataFromSktIn jsr SKT.GetTCB ldy #S.SOCKET.SQ.hInMem lda (ZPPtrSKT),y .DO AUXPIPE=1 >SYSCALL2 GetStkObjPtr .ELSE >SYSCALL2 GetMemPtr .FIN sty ZPTmpPtr1 * clc adc SKT.Cache+S.SOCKET.TCP.INTAIL+1 sta ZPTmpPtr1+1 jsr SKT.GetNotDataInLen pha .DO AUXPIPE=1 jsr SKT.SetupZPCode .FIN ldy SKT.Cache+S.SOCKET.TCP.INTAIL .1 inx Check if room left in dest buffer bne .2 pla inc beq .8 pha .2 .DO AUXPIPE=1 jsr ZPCode .ELSE lda (ZPTmpPtr1),y .FIN sta (ZPDataInPtr) inc ZPDataInPtr bne .3 inc ZPDataInPtr+1 .3 iny bne .1 inc ZPTmpPtr1+1 inc SKT.Cache+S.SOCKET.TCP.INTAIL+1 lda SKT.Cache+S.SOCKET.TCP.INTAIL+1 cmp /K.TCP.WSIZE bne .1 stz SKT.Cache+S.SOCKET.TCP.INTAIL+1 lda ZPTmpPtr1+1 * sec sbc /K.TCP.WSIZE sta ZPTmpPtr1+1 bra .1 .8 sty SKT.Cache+S.SOCKET.TCP.INTAIL * >ADC16 SKT.Cache+S.SOCKET.TCP.INFREE,ZPDataInLen ldx #S.SOCKET.TCP.INFREE jsr SKT.AddDataInLenAtSktX * >SBC16 SKT.Cache+S.SOCKET.TCP.INUSED,ZPDataInLen ldx #S.SOCKET.TCP.INUSED jsr SKT.SubDataInLenAtSktX jsr SKT.StoreTCB jsr TCP.SetSocketTCPO.ACK ACK=1 -> send WSIZE >LDYA ZPDataInLen clc rts *-------------------------------------- * From TCP.IN * Src : ZPDataInPtr/ZPDataInLen * Dst : hInMem/INHEAD *-------------------------------------- SKT.AddDataToSktIn lda SKT.Cache+S.SOCKET.TCP.INFREE sec sbc ZPDataInLen tax lda SKT.Cache+S.SOCKET.TCP.INFREE+1 sbc ZPDataInLen+1 bcc .9 Not enough room in Q stx SKT.Cache+S.SOCKET.TCP.INFREE sta SKT.Cache+S.SOCKET.TCP.INFREE+1 ldy #S.SOCKET.SQ.hInMem lda (ZPPtrSKT),y .DO AUXPIPE=1 >SYSCALL2 GetStkObjPtr .ELSE >SYSCALL2 GetMemPtr .FIN sty ZPTmpPtr1 * clc adc SKT.Cache+S.SOCKET.TCP.INHEAD+1 sta ZPTmpPtr1+1 jsr SKT.GetNotDataInLen pha ldy SKT.Cache+S.SOCKET.TCP.INHEAD .1 .DO AUXPIPE=1 sta SETWRITEAUX .FIN .2 inx bne .3 pla inc beq .8 pha .3 lda (ZPDataInPtr) sta (ZPTmpPtr1),y inc ZPDataInPtr bne .4 inc ZPDataInPtr+1 .4 iny bne .2 .DO AUXPIPE=1 sta CLRWRITEAUX .FIN inc ZPTmpPtr1+1 inc SKT.Cache+S.SOCKET.TCP.INHEAD+1 lda SKT.Cache+S.SOCKET.TCP.INHEAD+1 cmp /K.TCP.WSIZE bne .1 stz SKT.Cache+S.SOCKET.TCP.INHEAD+1 lda ZPTmpPtr1+1 * sec sbc /K.TCP.WSIZE sta ZPTmpPtr1+1 bra .1 .9 sec rts .8 .DO AUXPIPE=1 sta CLRWRITEAUX .FIN sty SKT.Cache+S.SOCKET.TCP.INHEAD * >ADC16 SKT.Cache+S.SOCKET.TCP.INUSED,ZPDataInLen ldx #S.SOCKET.TCP.INUSED jsr SKT.AddDataInLenAtSktX clc rts */-------------------------------------- * # Write (STREAM) * ## C * `int skt.write(hFD fd, const void *buf, int count);` * ## ASM * **In:** * `>PUSHWI count` * `>PUSHW buf` * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.write` * ## RETURN VALUE * CC: Y,A = bytes written * CS: A = EC *\-------------------------------------- SKT.Write jsr SKT.PullhFDDataInPtrLen jsr SKT.CheckStream bcs .99 jsr SKT.GetTCB ldx SKT.Cache+S.SOCKET.TCP.OUTFREE cpx ZPDataInLen lda SKT.Cache+S.SOCKET.TCP.OUTFREE+1 sbc ZPDataInLen+1 bcs SKT.AddDataToSktOut lda #E.NODATA Not enough room in Q,no data transfered sec .99 rts *-------------------------------------- * Src : ZPDataInPtr/ZPDataInLen * Dst : hOutMem/OUTHEAD *-------------------------------------- SKT.AddDataToSktOut ldy #S.SOCKET.SQ.hOutMem lda (ZPPtrSKT),y .DO AUXPIPE=1 >SYSCALL2 GetStkObjPtr .ELSE >SYSCALL2 GetMemPtr .FIN sty ZPTmpPtr1 * clc adc SKT.Cache+S.SOCKET.TCP.OUTHEAD+1 sta ZPTmpPtr1+1 ldy SKT.Cache+S.SOCKET.TCP.OUTHEAD jsr SKT.GetNotDataInLen pha .1 .DO AUXPIPE=1 sta SETWRITEAUX .FIN .2 inx bne .3 pla inc beq .8 pha .3 lda (ZPDataInPtr) sta (ZPTmpPtr1),y inc ZPDataInPtr bne .4 inc ZPDataInPtr+1 .4 iny bne .2 inc ZPTmpPtr1+1 .DO AUXPIPE=1 sta CLRWRITEAUX .FIN inc SKT.Cache+S.SOCKET.TCP.OUTHEAD+1 lda SKT.Cache+S.SOCKET.TCP.OUTHEAD+1 cmp /K.TCP.WSIZE bne .1 stz SKT.Cache+S.SOCKET.TCP.OUTHEAD+1 lda ZPTmpPtr1+1 * sec sbc /K.TCP.WSIZE sta ZPTmpPtr1+1 bra .1 .8 .DO AUXPIPE=1 sta CLRWRITEAUX .FIN sty SKT.Cache+S.SOCKET.TCP.OUTHEAD * >SBC16 SKT.Cache+S.SOCKET.TCP.OUTFREE,ZPDataInLen ldx #S.SOCKET.TCP.OUTFREE jsr SKT.SubDataInLenAtSktX * >ADC16 SKT.Cache+S.SOCKET.TCP.OUTUSED,ZPDataInLen ldx #S.SOCKET.TCP.OUTUSED jsr SKT.AddDataInLenAtSktX * >ADC16 SKT.Cache+S.SOCKET.TCP.OUTTOSEND,ZPDataInLen ldx #S.SOCKET.TCP.OUTTOSEND jsr SKT.AddDataInLenAtSktX jsr SKT.StoreTCB >LDYA ZPDataInLen clc rts *-------------------------------------- SKT.AddDataInLenAtSktX clc lda SKT.Cache,x adc ZPDataInLen sta SKT.Cache,x inx lda SKT.Cache,x adc ZPDataInLen+1 sta SKT.Cache,x rts *-------------------------------------- SKT.SubDataInLenAtSktX sec lda SKT.Cache,x sbc ZPDataInLen sta SKT.Cache,x inx lda SKT.Cache,x sbc ZPDataInLen+1 sta SKT.Cache,x rts *-------------------------------------- * From TCP.OUT * Src : hOutMem/OUTTAIL * Dst : ZPDataOutPtr/ZPDataOutLen *-------------------------------------- SKT.GetDataFromSktOut ldy #S.SOCKET.SQ.hOutMem lda (ZPPtrSKT),y .DO AUXPIPE=1 >SYSCALL2 GetStkObjPtr .ELSE >SYSCALL2 GetMemPtr .FIN sty ZPTmpPtr1 * clc adc SKT.Cache+S.SOCKET.TCP.OUTTAILSENT+1 sta ZPTmpPtr1+1 lda ZPDataOutLen eor #$FF tax lda ZPDataOutLen+1 eor #$FF pha .DO AUXPIPE=1 jsr SKT.SetupZPCode .FIN ldy SKT.Cache+S.SOCKET.TCP.OUTTAILSENT .1 inx bne .2 pla inc beq .8 pha .2 .DO AUXPIPE=1 jsr ZPCode .ELSE lda (ZPTmpPtr1),y .FIN sta (ZPDataOutPtr) inc ZPDataOutPtr bne .3 inc ZPDataOutPtr+1 .3 iny bne .1 inc ZPTmpPtr1+1 inc SKT.Cache+S.SOCKET.TCP.OUTTAILSENT+1 lda SKT.Cache+S.SOCKET.TCP.OUTTAILSENT+1 cmp /K.TCP.WSIZE bne .1 stz SKT.Cache+S.SOCKET.TCP.OUTTAILSENT+1 lda ZPTmpPtr1+1 * sec sbc /K.TCP.WSIZE sta ZPTmpPtr1+1 bra .1 .8 sty SKT.Cache+S.SOCKET.TCP.OUTTAILSENT >SBC16 SKT.Cache+S.SOCKET.TCP.OUTTOSEND,ZPDataOutLen clc rts */-------------------------------------- * # Recv (RAW,DGRAM,SEQPKT) * # RecvFrom (RAW,DGRAM,SEQPKT) * ## C * `hMem recv(hFD fd);` * `hMem recvfrom(hFD fd, struct sockaddr *addr);` * ## ASM * **In:** * `>PUSHW addr` (RecvFrom) * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.Recv` * ## RETURN VALUE * CC: A = hMem * CS: A = EC *\-------------------------------------- SKT.RecvFrom pha >PULLW ZPTmpPtr1 addr pla sec .HS 90 BCC SKT.Recv clc php >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.T lda (ZPPtrSKT),y cmp #S.SOCKET.T.SEQPKT bcc .10 bne .99 STREAM jsr SKT.CheckTCP bcs .91 .10 ldy #S.SOCKET.HQ.TAIL lda (ZPPtrSKT),y tax ldy #S.SOCKET.HQ.HEAD cmp (ZPPtrSKT),y beq .90 inc cmp #S.SOCKET.HQ.MAX bne .1 lda #0 .1 ldy #S.SOCKET.HQ.TAIL sta (ZPPtrSKT),y txa clc adc #S.SOCKET.HQ tay lda (ZPPtrSKT),y plp if CS, RecvFrom bcc .9 Exit with CC and A=hFrame pha >SYSCALL2 GetMemPtr >STYA ZPFrameInPtr ldy #S.IP.SRC .2 lda (ZPFrameInPtr),y sta SA.REMOTE+S.SOCKADDR.ADDR-S.IP.SRC,y iny cpy #S.IP.SRC+4 bne .2 ldy #S.IP.PROTOCOL lda (ZPFrameInPtr),y cmp #S.IP.PROTOCOL.ICMP bne .3 ldy #S.ICMP.IDENTIFIER bra .7 .3 cmp #S.IP.PROTOCOL.TCP beq .6 cmp #S.IP.PROTOCOL.UDP bne .8 .6 ldy #S.TCPUDP.SRCPORT .7 lda (ZPFrameInPtr),y sta SA.REMOTE+S.SOCKADDR+1 iny lda (ZPFrameInPtr),y sta SA.REMOTE+S.SOCKADDR .8 lda #S.SOCKADDR-1 .80 lda SA.REMOTE,y sta (ZPTmpPtr1),y dey bpl .80 pla clc .9 rts .99 lda #ERR.SKT.BAD .91 plp sec rts .90 lda #0 no data plp sec rts */-------------------------------------- * # Send (RAW,DGRAM,SEQPKT) * # SendTo (RAW,DGRAM,SEQPKT) * ## C * `int skt.send(hFD fd, const void *buf, int count);` * `int skt.sendto(hFD fd, const void *buf, int count, const struct sockaddr *addr);` * ## ASM * **In:** * `>PUSHW addr` (SendTo) * `>PUSHWI count` * `>PUSHW buf` * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.send` * ## RETURN VALUE * CC: Y,A = bytes written * CS: A = EC *\-------------------------------------- SKT.SendTo sec .HS 90 BCC SKT.Send clc php jsr SKT.PullhFDDataInPtrLen plp bcc .1 jsr SKT.PullRemAddr .1 ldy #S.SOCKET.T lda (ZPPtrSKT),y tax jmp (J.SKT.send,x) *-------------------------------------- SKT.Send.RAW ldy #S.SOCKET.PROTO lda (ZPPtrSKT),y tax >LDYA ZPDataInLen jsr FRM.NewIP bcc SKT.Send.8 rts *-------------------------------------- SKT.Send.DGRAM ldx #S.IP.PROTOCOL.UDP >LDYA ZPDataInLen jsr FRM.NewIP bcs SKT.Send.9 jsr SKT.SetFrameOutTCPUDPPorts SKT.Send.8 jsr SKT.SetFrameOutDstIP jsr SKT.CopyDataInToOut clc Queue if fail jmp FRM.SendIP *-------------------------------------- SKT.Send.SEQPKT jsr SKT.CheckTCP bcs SKT.Send.9 >LDYA ZPDataInLen jsr TCP.NewFrame bcs SKT.Send.9 jsr SKT.GetTCB jsr SKT.CopyDataInToOut jmp TCP.OUT.SEQSEND *-------------------------------------- SKT.Send.STREAM lda #ERR.SKT.BAD sec SKT.Send.9 rts */-------------------------------------- * # GetSockOpt * Set Socket Options * ## C * `int getsockopt(hFD fd);` * ## ASM * **In:** * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.GetSockOpt` * ## RETURN VALUE *\-------------------------------------- SKT.getsockopt >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.O lda (ZPPtrSKT),y * clc rts */-------------------------------------- * # SetSockOpt * Set Socket Options * ## C * `int setsockopt(hFD fd, short int opts);` * ## ASM * **In:** * `>PUSHBI opts` * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.SetSockOpt` * ## RETURN VALUE *\-------------------------------------- SKT.setsockopt >SYSCALL2 GetMemPtr >STYA ZPPtrSKT >PULLA ldy #S.SOCKET.O sta (ZPPtrSKT),y * clc rts */-------------------------------------- * # EOF * End Of File * ## C * `int eof(hFD fd);` * ## ASM * **In:** * `lda fd` * `>LIBCALL hLIBTCPIP,LIBTCPIP.EOF` * ## RETURN VALUE * CC : A = 0 if some data, A = $ff if EOF * CS : A = Socket Error *\-------------------------------------- SKT.EOF >SYSCALL2 GetMemPtr >STYA ZPPtrSKT SKT.EOF.I ldy #S.SOCKET.TCP.INUSED lda (ZPPtrSKT),y iny ora (ZPPtrSKT),y bne .8 some DATA... jsr SKT.CheckStream bcs .9 lda #$ff no DATA, EOF = true * clc rts .8 lda #0 ...EOF = false clc .9 rts *-------------------------------------- SKT.CheckStream lda #S.SOCKET.T.STREAM ldy #S.SOCKET.T cmp (ZPPtrSKT),y bne SKT.BAD SKT.CheckTCP ldy #S.SOCKET.O lda (ZPPtrSKT),y and #S.SOCKET.O.ACCEPTCONN bne .99 ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y cmp #S.SOCKET.TCP.S.ESTBLSH beq .8 bcc .90 lda #MLI.E.IO * sec rts .8 lda #0 clc rts .90 lda #ERR.SKT.NOCONN sec rts .99 SKT.BAD lda #ERR.SKT.BAD sec rts */-------------------------------------- * # GetTable * Get socket table * ## C * `void * gettable();` * ## ASM * **In:** * `>LIBCALL hLIBTCPIP,LIBTCPIP.GetTable` * ## RETURN VALUE *\-------------------------------------- SKT.GetTable >LDYA L.SKT.Table clc rts *-------------------------------------- SKT.PullhFDDataInPtrLen >SYSCALL2 GetMemPtr >STYA ZPPtrSKT >PULLW ZPDataInPtr !!!DataOut trashed when sending ACK in TCP.OUT >PULLW ZPDataInLen !!!use DataInPtr/Len rts *-------------------------------------- SKT.PullLocAddr clc .HS B0 BCS *-------------------------------------- SKT.PullRemAddr sec >PULLW ZPTmpPtr1 ldy #S.SOCKADDR-1 ldx #S.SOCKADDR-1 bcc .1 ldx #S.SOCKADDR+S.SOCKADDR-1 .1 lda (ZPTmpPtr1),y sta SKT.LOC.ADDR,x dex dey bpl .1 rts *-------------------------------------- SKT.SetLocAddr ldy #S.SOCKET.LOC.PORT+1 .1 lda SKT.LOC.ADDR+S.SOCKADDR.ADDR-S.SOCKET.LOC.ADDR,y sta (ZPPtrSKT),y dey cpy #S.SOCKET.LOC.ADDR bcs .1 rts *-------------------------------------- SKT.SetRemAddr ldy #S.SOCKET.REM.PORT+1 .1 lda SKT.REM.ADDR+S.SOCKADDR.ADDR-S.SOCKET.REM.ADDR,y sta (ZPPtrSKT),y dey cpy #S.SOCKET.REM.ADDR bcs .1 rts *-------------------------------------- * SKT.REM.ADDR = Incoming Frame SRC * SKT.LOC.ADDR = Incoming Frame DST *-------------------------------------- SKT.FindMatchingLocRem ldx #0 .1 lda SKT.TABLE,x beq .8 phx >SYSCALL2 GetMemPtr >STYA ZPPtrSKT plx ldy #S.SOCKET.AF lda (ZPPtrSKT),y cmp #AF.INET bne .8 ldy #S.SOCKET.PROTO lda (ZPPtrSKT),y ldy #S.IP.PROTOCOL cmp (ZPFrameInPtr),y bne .8 ldy #S.SOCKET.LOC.ADDR .2 lda (ZPPtrSKT),y bne .4 ldy #S.SOCKET.LOC.PORT bound to 0.0.0.0,check only LOC port .3 lda (ZPPtrSKT),y .4 cmp SKT.LOC.ADDR+S.SOCKADDR.ADDR-S.SOCKET.LOC.ADDR,y bne .8 iny cpy #S.SOCKET.LOC.PORT+2 bne .3 ldy #S.SOCKET.O lda (ZPPtrSKT),y and #S.SOCKET.O.ACCEPTCONN beq .6 ldy #S.TCP.OPTIONS Listening, only SYN packet.... lda (ZPFrameInPtr),y cmp #S.TCP.OPTIONS.SYN beq .7 SYN received on a LISTEN socket, ok bne .8 bad packet for this listening .6 lda SKT.REM.ADDR+S.SOCKADDR.ADDR cmp #$ff incoming frame is FF.FF.FF.FF, Broadcast ? bne .41 * ldy #S.SOCKET.O lda (ZPPtrSKT),y and #S.SOCKET.O.BROADCAST bne .43 * sec rts this socket does not accept broadcast .41 ldy #S.SOCKET.REM.ADDR lda (ZPPtrSKT),y bne .44 .43 ldy #S.SOCKET.REM.PORT Frame is Broadcast, or listening is 0.0.0.0 check port only .42 lda (ZPPtrSKT),y .44 cmp SKT.REM.ADDR+S.SOCKADDR.ADDR-S.SOCKET.REM.ADDR,y bne .8 wrong remote host, exit.... iny cpy #S.SOCKET.REM.PORT+2 bne .42 .7 stx SKT.Index x = SKT.TABLE index clc rts .8 inx cpx #K.SKTTABLE.SIZE bne .1 * sec rts *-------------------------------------- SKT.AddToQueueA pha ldy #S.SOCKET.HQ.HEAD lda (ZPPtrSKT),y tax inc cmp #S.SOCKET.HQ.MAX bne .1 lda #0 .1 ldy #S.SOCKET.HQ.TAIL cmp (ZPPtrSKT),y beq .9 Queue full!! ldy #S.SOCKET.HQ.HEAD sta (ZPPtrSKT),y txa clc adc #S.SOCKET.HQ tay pla sta (ZPPtrSKT),y clc rts .9 pla dicard hFrame * sec rts *-------------------------------------- SKT.NewTCB ldx #S.SOCKET.TCP.INSEQNUM .1 stz SKT.Cache,x inx cpx #S.SOCKET.TCP bne .1 ldx #3 .2 lda A2osX.TIMER16,x sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x dex bpl .2 ldy #S.SOCKET.T lda (ZPPtrSKT),y cmp #S.SOCKET.T.SEQPKT bcc .8 tax >LDYAI K.TCP.WSIZE >STYA SKT.Cache+S.SOCKET.TCP.INFREE cpx #S.SOCKET.T.STREAM bcc .8 .DO AUXPIPE=1 >SYSCALL2 NewStkObj .ELSE >SYSCALL2 getmem .FIN bcs .9 txa ldy #S.SOCKET.SQ.hInMem sta (ZPPtrSKT),y >LDYAI K.TCP.WSIZE >STYA SKT.Cache+S.SOCKET.TCP.OUTFREE .DO AUXPIPE=1 >SYSCALL2 NewStkObj .ELSE >SYSCALL2 getmem .FIN bcs .9 txa ldy #S.SOCKET.SQ.hOutMem sta (ZPPtrSKT),y .8 * clc .9 rts *-------------------------------------- SKT.GetTCB ldy #S.SOCKET.TCP.INSEQNUM .1 lda (ZPPtrSKT),y sta SKT.Cache,y iny cpy #S.SOCKET.TCP bne .1 rts *-------------------------------------- SKT.StoreTCB.S ldy #S.SOCKET.TCP.S sta (ZPPtrSKT),y SKT.StoreTCB ldy #S.SOCKET.TCP.INSEQNUM .1 lda SKT.Cache,y sta (ZPPtrSKT),y iny cpy #S.SOCKET.TCP bne .1 clc rts *-------------------------------------- SKT.SetFrameOutDstIP ldx #3 ldy #S.SOCKET.REM.ADDR lda (ZPPtrSKT),y beq .3 Socket Bound to 0.0.0.0... .1 lda (ZPPtrSKT),y pha iny dex bpl .1 ldy #S.IP.DST+3 ldx #3 .2 pla sta (ZPFrameOutPtr),y dey dex bpl .2 rts .3 ldy #S.IP.DST+3 ...sent to provided SentTo ADDR .4 lda SKT.REM.ADDR+S.SOCKADDR.ADDR,x sta (ZPFrameOutPtr),y dey dex bpl .4 rts *-------------------------------------- SKT.SetFrameOutTCPUDPPorts ldy #S.SOCKET.LOC.PORT lda (ZPPtrSKT),y tax iny lda (ZPPtrSKT),y ldy #S.TCPUDP.SRCPORT sta (ZPFrameOutPtr),y iny txa sta (ZPFrameOutPtr),y ldy #S.SOCKET.REM.PORT lda (ZPPtrSKT),y beq .1 tax iny lda (ZPPtrSKT),y bra .2 .1 lda SKT.REM.ADDR+S.SOCKADDR.PORT+1 ldx SKT.REM.ADDR+S.SOCKADDR.PORT .2 ldy #S.TCPUDP.DSTPORT sta (ZPFrameOutPtr),y iny txa sta (ZPFrameOutPtr),y rts *-------------------------------------- SKT.GetNotDataInLen lda ZPDataInLen eor #$FF tax lda ZPDataInLen+1 eor #$FF rts *-------------------------------------- SKT.CopyDataInToOut lda ZPDataInPtr+1 pha lda ZPDataOutPtr+1 pha jsr SKT.GetNotDataInLen pha ldy #0 .1 inx bne .2 pla inc beq .9 pha .2 lda (ZPDataInPtr),y sta (ZPDataOutPtr),y iny bne .1 inc ZPDataInPtr+1 inc ZPDataOutPtr+1 bne .1 .9 pla sta ZPDataOutPtr+1 pla sta ZPDataInPtr+1 rts *-------------------------------------- .DO AUXPIPE=1 SKT.SetupZPCode ldy #ZP.CODE.Len-1 .1 lda ZP.CODE,y sta ZPCode,y dey bpl .1 rts .FIN *-------------------------------------- MAN SAVE usr/src/lib/libtcpip.s.skt LOAD usr/src/lib/libtcpip.s ASM