A2osX/LIB/LIBTCPIP.S.SKT.txt
2019-10-06 14:50:43 +02:00

1440 lines
27 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
bra SKT.Socket.DSOCK
SKT.Socket.SEQPACKET
lda #S.IP.PROTOCOL.TCP
ldy #S.SOCKET.TCP
SKT.Socket.DSOCK
stx FD.DSOCK+S.SOCKET.T save type
sta FD.DSOCK+S.SOCKET.PROTO ICMP,UDP,TCP
lda #0 Y = socket.size
>SYSCALL2 GetMem0
bcs .9
>STYA ZPTmpPtr1
jsr SKT.Socket.FindFree
bcs .9
ldy #FD.DSOCK.SIZE-1
.1 lda FD.DSOCK,y
sta (ZPTmpPtr1),y
dey
bpl .1
txa
clc
.9 rts
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
lda #0 Y = socket.size
>SYSCALL2 GetMem0
bcs .9
>STYA ZPTmpPtr1
jsr SKT.Socket.FindFree
bcs .9
ldy #FD.SSOCK.SIZE-1
.1 lda FD.SSOCK,y
sta (ZPTmpPtr1),y
dey
bpl .1
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.SEQPACKET
ldy #S.SOCKET.TCP.S
lda (ZPPtrSKT),y
beq .1
cmp #S.SOCKET.TCP.S.ESTBLSH
beq .8
bcs .9
cmp #S.SOCKET.TCP.S.OPENED
beq .2
cmp #S.SOCKET.TCP.S.SYNSENT
beq .3
bra .9
.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 .3
lda #S.SOCKET.TCP.S.SYNSENT
jsr SKT.StoreTCB.S
.3 lda #ERR.SKT.NOCONN
sec
rts
.8 clc
rts
.9 lda #ERR.SKT.BAD
sec
.99 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.SEQPACKET+1
bcc .9
ldy #S.SOCKET.TCP.S
lda (ZPPtrSKT),y
bne .9
lda #S.SOCKET.TCP.S.LISTEN
sta (ZPPtrSKT),y
ldy #S.SOCKET.O
lda #S.SOCKET.O.ACCEPTCONN
sta (ZPPtrSKT),y
clc
rts
.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
*--------------------------------------
SKT.shutdown.LISTEN
SKT.shutdown.RAW
SKT.shutdown.DGRAM
SKT.shutdown.SEQPACKET
.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
beq .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
rts
*--------------------------------------
SKT.shutdown.STREAM
pla
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
.8 clc
.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,SEQPACKET)
* # RecvFrom (RAW,DGRAM,SEQPACKET)
* ## 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.STREAM
beq .99
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
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 plp
lda #ERR.SKT.BAD
sec
rts
.90 plp
lda #0 no data
sec
rts
*/--------------------------------------
* # Send (RAW,DGRAM,SEQPACKET)
* # SendTo (RAW,DGRAM,SEQPACKET)
* ## 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
* jsr SKT.SetRemAddr
.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.STREAM lda #ERR.SKT.BAD
sec
SKT.Send.9 rts
*--------------------------------------
SKT.Send.SEQPACKET
bra *
>LDYA ZPDataInLen
jsr TCP.NewFrame
bcs SKT.Send.9
jsr SKT.CopyDataInToOut
sec DONT Queue if fail
jmp FRM.SendIP
*/--------------------------------------
* # 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 ldy #S.SOCKET.T
lda (ZPPtrSKT),y
cmp #S.SOCKET.T.STREAM
bne .99
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
cmp #S.SOCKET.TCP.S.CLWAIT
bne .91 more than CLWAIT
.8 lda #0
clc
rts
.90 lda #ERR.SKT.NOCONN
sec
rts
.91 lda #MLI.E.IO
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
.DO IPDEBUG=1
jsr FRM.Dump
.FIN
ldx #0
.1 lda SKT.TABLE,x
beq .8
phx
>SYSCALL2 GetMemPtr
>STYA ZPPtrSKT
.DO IPDEBUG=1
jsr SKT.Dump
.FIN
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 recieved 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
.9 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
>LDYAI K.TCP.WSIZE
>STYA SKT.Cache+S.SOCKET.TCP.INFREE
.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
ldx #3
.2 lda A2osX.TIMER16,x
sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x
dex
bpl .2
* 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