A2osX/LIB/LIBTCPIP.S.SKT.txt
2023-01-06 15:02:35 +01:00

1486 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
*/--------------------------------------
* # Socket
* Create a new socket
* ## C
* `hFD socket(short int type, short int protocol);`
* ## ASM
* **In:**
* `>PUSHB type`
* `>PUSHB protocol`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.socket`
* ## RETURN VALUE
* CC: A = hSOCKET
* CS: A = EC
*\--------------------------------------
SKT.Socket >PULLA get protocol (RAW)
pha
>PULLA
tax
pla
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
jsr SKT.Socket.FindFree
bcs SKT.Socket.RTS
ldy #0
.1 lda FD.DSOCK,y
sta (ZPTmpPtr1),y
iny
cpy #FD.DSOCK.SIZE
bne .1
bra SKT.Socket.ZERO
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
jsr SKT.Socket.FindFree
bcs SKT.Socket.RTS
ldy #0
.1 lda FD.SSOCK,y
sta (ZPTmpPtr1),y
iny
cpy #FD.SSOCK.SIZE
bne .1
SKT.Socket.ZERO lda #0
.1 sta (ZPTmpPtr1),y
iny
cpy TmpDWord
bne .1
txa
clc
SKT.Socket.RTS rts
*--------------------------------------
SKT.Socket.FindFree
sty TmpDWord Y = socket.size
ldx #0
.1 lda SKT.TABLE,x
beq .2
inx
cpx #K.SKTTABLE.SIZE
bne .1
lda #E.OOH
* sec
rts
.2 stx .8+1
* lda #0 Y,A = socket.size
>SYSCALL2 GetMem
bcs SKT.Socket.RTS
>STYA ZPTmpPtr1
txa
.8 ldy #$FF SELF MODIFIED
sta SKT.TABLE,y
* clc
rts
*/--------------------------------------
* # Bind
* bind a name to a socket
* ## C
* `int bind(hFD fd, const struct sockaddr *addr);`
* ## ASM
* **In:**
* `>PUSHB fd`
* `>PUSHW addr`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.socket`
* ## RETURN VALUE
* CC: A = hSOCKET
* CS: A = EC
*\--------------------------------------
SKT.bind jsr SKT.PullLocAddr
jsr SKT.PullhFD
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:**
* `>PUSHB fd`
* `>PUSHW addr`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.socket`
* ## RETURN VALUE
* CC: A = hSOCKET
* CS: A = EC
*\--------------------------------------
SKT.connect jsr SKT.PullRemAddr
jsr SKT.PullhFD
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 jsr SKT.GetFD
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 jsr SKT.GetFD
ldy #S.SOCKET.O
lda (ZPPtrSKT),y
and #S.SOCKET.O.ACCEPTCONN
beq SKT.listen.9
*--------------------------------------
SKT.GetFromQueue
ldy #S.SOCKET.HQ.TAIL
lda (ZPPtrSKT),y
iny #S.SOCKET.HQ.HEAD
cmp (ZPPtrSKT),y
beq .9 CS
pha
inc
cmp #S.SOCKET.HQ.MAX
bne .1
lda #0
.1 dey #S.SOCKET.HQ.TAIL
sta (ZPPtrSKT),y
pla
clc
adc #S.SOCKET.HQ
tay
lda (ZPPtrSKT),y
* clc
.9 rts
*/--------------------------------------
* # Shutdown
* Close socket
* ## C
* `int shutdown(int fd);`
* ## ASM
* **In:**
* `lda fd`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.shutdown`
* ## RETURN VALUE
*\--------------------------------------
SKT.shutdown pha
jsr SKT.GetFD
ldy #S.SOCKET.O
lda (ZPPtrSKT),y
and #S.SOCKET.O.ACCEPTCONN
bne SKT.shutdown.HQ
ldy #S.SOCKET.T
lda (ZPPtrSKT),y
cmp #S.SOCKET.T.SEQPKT
bcc SKT.shutdown.HQ
ldy #S.SOCKET.TCP.S
lda (ZPPtrSKT),y
cmp #S.SOCKET.TCP.S.CLOSING
bne .10
inc S.SOCKET.TCP.S.TIMEWT
sta (ZPPtrSKT),y
pla
clc
rts
.10 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
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
.3 lda #S.SOCKET.TCP.S.TIMEWT
jmp SKT.StoreTCB.S
*--------------------------------------
SKT.shutdown.HQ jsr SKT.GetFromQueue
bcs .3
>SYSCALL2 FreeMem
bra SKT.shutdown.HQ
.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
*/--------------------------------------
* # Read (STREAM)
* ## C
* `int skt.read(hFD fd, void *buf, int count);`
* ## ASM
* **In:**
* `>PUSHB fd`
* `>PUSHW buf`
* `>PUSHW count`
* `>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 ldy #S.SOCKET.TCP.O
lda (ZPPtrSKT),y
and #S.TCP.OPTIONS.ACK
beq .8
jmp TCP.OUT.SendOptA
.8 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
* lda #S.TCP.OPTIONS.ACK
* jsr TCP.OUT.SendOptA
>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:**
* `>PUSHB fd`
* `>PUSHW buf`
* `>PUSHW count`
* `>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
*/--------------------------------------
* # RecvFrom (RAW,DGRAM,SEQPKT)
* ## C
* `hMem recvfrom(hFD fd, struct sockaddr *addr);`
* ## ASM
* **In:**
* `>PUSHB fd`
* `>PUSHW addr` (RecvFrom)
* `>LIBCALL hLIBTCPIP,LIBTCPIP.Recv`
* ## RETURN VALUE
* CC: A = hMem
* CS: A = EC
*\--------------------------------------
SKT.RecvFrom >PULLW ZPTmpPtr1 addr
>PULLA
sec
.HS 90 BCC
*/--------------------------------------
* # Recv (RAW,DGRAM,SEQPKT)
* ## C
* `hMem recv(hFD fd);`
* ## ASM
* **In:**
* `lda fd`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.Recv`
* ## RETURN VALUE
* CC: A = hMem
* CS: A = EC
*\--------------------------------------
SKT.Recv clc
php
jsr SKT.GetFD
ldy #S.SOCKET.T
lda (ZPPtrSKT),y
cmp #S.SOCKET.T.SEQPKT
bcc .10 RAW,DGRAM
bne .99 STREAM
jsr SKT.GetFromQueue SEQPKT
bcc .1
jsr SKT.CheckTCP
bcs .91
.90 lda #E.NODATA
.91 plp
sec
rts
.10 jsr SKT.GetFromQueue
bcs .90
.1 plp if CS, RecvFrom
bcc .9 CC, Recv : 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 ldy #S.SOCKADDR-1
.80 lda SA.REMOTE,y
sta (ZPTmpPtr1),y
dey
bpl .80
pla
clc
.9 rts
.99 lda #ERR.SKT.BAD
plp
sec
rts
*/--------------------------------------
* # SendTo (RAW,DGRAM,SEQPKT)
* ## C
* `int skt.sendto(hFD fd, const void *buf, int count, const struct sockaddr *addr);`
* ## ASM
* **In:**
* `>PUSHB fd`
* `>PUSHW buf`
* `>PUSHWI count`
* `>PUSHW addr`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.sendto`
* ## RETURN VALUE
* CC: Y,A = bytes written
* CS: A = EC
*\--------------------------------------
SKT.SendTo jsr SKT.PullRemAddr
*/--------------------------------------
* # Send (RAW,DGRAM,SEQPKT)
* ## C
* `int skt.send(hFD fd, const void *buf, int count);`
* ## ASM
* **In:**
* `>PUSHB fd`
* `>PUSHW buf`
* `>PUSHWI count`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.send`
* ## RETURN VALUE
* CC: Y,A = bytes written
* CS: A = EC
*\--------------------------------------
SKT.Send jsr SKT.PullhFDDataInPtrLen
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 jsr SKT.GetFD
ldy #S.SOCKET.O
lda (ZPPtrSKT),y
* clc
rts
*/--------------------------------------
* # SetSockOpt
* Set Socket Options
* ## C
* `int setsockopt(hFD fd, short int opts);`
* ## ASM
* **In:**
* `>PUSHB fd`
* `>PUSHB opts`
* `>LIBCALL hLIBTCPIP,LIBTCPIP.SetSockOpt`
* ## RETURN VALUE
*\--------------------------------------
SKT.setsockopt >PULLA
pha
jsr SKT.PullhFD
pla
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 jsr SKT.GetFD
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 SKT.BAD
ldy #S.SOCKET.TCP.S
lda (ZPPtrSKT),y
cmp #S.SOCKET.TCP.S.ESTBLSH
beq .8
bcc .9
lda #MLI.E.IO
* sec
rts
.8 lda #0
clc
rts
.9 lda #ERR.SKT.NOCONN
sec
rts
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
>PULLW ZPDataInLen !!!use DataInPtr/Len
>PULLW ZPDataInPtr !!!DataOut trashed when sending ACK in TCP.OUT
SKT.PullhFD >PULLA
SKT.GetFD >SYSCALL2 GetMemPtr
>STYA ZPPtrSKT
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
jsr SKT.GetFD
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 clc x = SKT.TABLE index
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 dey #S.SOCKET.HQ.TAIL
cmp (ZPPtrSKT),y
beq .9 Queue full!!
iny #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