aboutsummaryrefslogtreecommitdiffstats
path: root/src/socket.asm
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/socket.asm97
1 files changed, 68 insertions, 29 deletions
diff --git a/src/socket.asm b/src/socket.asm
index 9ce1daa..3b2b0c9 100644
--- a/src/socket.asm
+++ b/src/socket.asm
@@ -21,11 +21,11 @@ DEF SK_HASRX EQU 9 ; 1 rxbuf holds a datagram
DEF SK_RXLEN EQU 10 ; 1 payload length
DEF SK_SRCIP EQU 11 ; 4 sender IP
DEF SK_SRCPORT EQU 15 ; 2 sender port
-DEF SK_RXBUF EQU 17 ; 208 payload (>= one max segment at MSS 200)
-DEF SK_STATE EQU 225 ; 1 TCP state (see TCP_* below)
-DEF SK_SND EQU 226 ; 4 snd_nxt (our next sequence number)
-DEF SK_RCV EQU 230 ; 4 rcv_nxt (next sequence we expect from peer)
-DEF SK_SIZE EQU 234
+DEF SK_RXBUF EQU 17 ; 288 payload (holds a DHCP reply, or a max segment)
+DEF SK_STATE EQU 305 ; 1 TCP state (see TCP_* below)
+DEF SK_SND EQU 306 ; 4 snd_nxt (our next sequence number)
+DEF SK_RCV EQU 310 ; 4 rcv_nxt (next sequence we expect from peer)
+DEF SK_SIZE EQU 314
DEF TCP_MSS EQU 200
; TCP connection states
@@ -48,9 +48,9 @@ wNetReq:: DS NR_SIZE
wNetSockPtr:: DS 2
wNetIhl:: DS 1
wNetSeq:: DS 1
-wNetTx:: DS 256 ; tx build buffer
-wNetRxBuf:: DS 256 ; rx frame assembly / parse
-wNetRxLen:: DS 1
+wNetTx:: DS 320 ; tx build buffer
+wNetRxBuf:: DS 320 ; rx frame assembly / parse
+wNetRxLen:: DS 2 ; 16-bit: frames can exceed 255 bytes (DHCP/BOOTP)
wNetRxEsc:: DS 1
wNetUdpPort:: DS 2 ; scratch: UDP dst port being demuxed
wNetTO:: DS 3 ; recv timeout counter (net_pump clobbers registers)
@@ -74,19 +74,31 @@ net_init::
ld a, b
or c
jr nz, .clr
- ld a, 10
- ld [wNetOurIP+0], a
xor a
+ ld [wNetOurIP+0], a ; 0.0.0.0 until DHCP assigns an address
ld [wNetOurIP+1], a
ld [wNetOurIP+2], a
- ld a, 2
ld [wNetOurIP+3], a
- xor a
ld [wNetRxLen], a
+ ld [wNetRxLen+1], a
ld [wNetRxEsc], a
ld [wNetSeq], a
ret
+; net_setip - store our IPv4 address (from wNetReq.NR_IP). Used by the DHCP
+; client once it has a lease.
+net_op_setip:
+ ld a, [wNetReq+NR_IP+0]
+ ld [wNetOurIP+0], a
+ ld a, [wNetReq+NR_IP+1]
+ ld [wNetOurIP+1], a
+ ld a, [wNetReq+NR_IP+2]
+ ld [wNetOurIP+2], a
+ ld a, [wNetReq+NR_IP+3]
+ ld [wNetOurIP+3], a
+ xor a
+ ret
+
; -----------------------------------------------------------------------------
; low-level link port (byte at a time). Preserve BC/DE/HL; use A only.
net_putbyte: ; A = byte to transmit
@@ -113,13 +125,13 @@ net_getbyte_nb: ; -> A = byte, CF set if none
ret
; -----------------------------------------------------------------------------
-; net_slip_send(HL = buf, B = len) - transmit a SLIP frame.
+; net_slip_send(HL = buf, DE = len) - transmit a SLIP frame (len may exceed 255).
net_slip_send:
ld a, SLIP_END
call net_putbyte
.loop
- ld a, b
- or a
+ ld a, d
+ or e
jr z, .end
ld a, [hl+]
cp SLIP_END
@@ -128,7 +140,7 @@ net_slip_send:
jr z, .esc_esc
call net_putbyte
.cont
- dec b
+ dec de
jr .loop
.esc_end
ld a, SLIP_ESC
@@ -235,6 +247,8 @@ sys_net::
jp z, net_op_bind
cp NET_POLL
jp z, net_op_poll
+ cp NET_SETIP
+ jp z, net_op_setip
ld a, $FF
ret
@@ -580,7 +594,8 @@ icmp_send:
; transmit: 28 + payload
ld a, [wNetReq+NR_LEN]
add 28
- ld b, a
+ ld e, a
+ ld d, 0
ld hl, wNetTx
call net_slip_send
xor a
@@ -594,10 +609,12 @@ udp_send:
ld [wNetTx+0], a
xor a
ld [wNetTx+1], a
- ld [wNetTx+2], a
ld a, [wNetReq+NR_LEN]
add 28 ; 20 IP + 8 UDP + payload
- ld [wNetTx+3], a
+ ld [wNetTx+3], a ; IP total length low
+ ld a, 0
+ adc 0
+ ld [wNetTx+2], a ; IP total length high (carry, for DHCP)
xor a
ld [wNetTx+4], a
ld [wNetTx+5], a
@@ -727,7 +744,10 @@ udp_send:
ld [wNetTx+11], a
ld a, [wNetReq+NR_LEN]
add 28
- ld b, a
+ ld e, a
+ ld a, 0
+ adc 0
+ ld d, a
ld hl, wNetTx
call net_slip_send
xor a
@@ -774,20 +794,32 @@ net_pump:
.store
ld a, c
.store2
- ; store A at wNetRxBuf[wNetRxLen] if room
- ld c, a
+ ld c, a ; C = byte to store
+ ; index = wNetRxLen (16-bit); drop if >= 320 (buffer size)
+ ld a, [wNetRxLen+1]
+ or a
+ jr z, .instore ; high 0 -> index < 256, room
+ cp 1
+ jr nz, .next ; high >= 2 -> overflow, drop
+ ld a, [wNetRxLen]
+ cp 64 ; high 1 -> room iff low < 64 (index < 320)
+ jr nc, .next
+.instore
ld a, [wNetRxLen]
- cp 255
- jr nc, .next ; overflow: drop
ld e, a
- ld d, 0
+ ld a, [wNetRxLen+1]
+ ld d, a
ld hl, wNetRxBuf
add hl, de
ld a, c
ld [hl], a
- ld a, [wNetRxLen]
+ ld a, [wNetRxLen] ; index++
inc a
ld [wNetRxLen], a
+ jr nz, .next
+ ld a, [wNetRxLen+1]
+ inc a
+ ld [wNetRxLen+1], a
jr .next
.frame
; END: if we have a frame, process it and return (one frame per pump, so a
@@ -795,11 +827,13 @@ net_pump:
xor a
ld [wNetRxEsc], a
ld a, [wNetRxLen]
- or a
+ ld hl, wNetRxLen+1
+ or [hl]
jr z, .next ; empty frame, keep reading
call process_frame
xor a
ld [wNetRxLen], a
+ ld [wNetRxLen+1], a
ret
; -----------------------------------------------------------------------------
@@ -891,7 +925,9 @@ icmp_request:
ld [wNetRxBuf+11], a
; send it back
ld a, [wNetRxLen]
- ld b, a
+ ld e, a
+ ld a, [wNetRxLen+1]
+ ld d, a
ld hl, wNetRxBuf
call net_slip_send
ret
@@ -1406,7 +1442,10 @@ tcp_send_seg:
ld b, a
ld a, [wNetTcpDlen]
add b
- ld b, a
+ ld e, a
+ ld a, 0
+ adc 0
+ ld d, a
ld hl, wNetTx
call net_slip_send
ret