aboutsummaryrefslogtreecommitdiffstats
path: root/src/socket.asm
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/socket.asm88
1 files changed, 78 insertions, 10 deletions
diff --git a/src/socket.asm b/src/socket.asm
index 3b2b0c9..fa6b245 100644
--- a/src/socket.asm
+++ b/src/socket.asm
@@ -52,6 +52,10 @@ 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
+wNetInFrame:: DS 1 ; net_pump: currently inside a SLIP frame?
+wConRing:: DS 16 ; console-input ring: non-framed bytes from the link
+wConHead:: DS 1
+wConTail:: DS 1
wNetUdpPort:: DS 2 ; scratch: UDP dst port being demuxed
wNetTO:: DS 3 ; recv timeout counter (net_pump clobbers registers)
wNetTcpFlags:: DS 1 ; TCP flags for the segment being built
@@ -82,9 +86,56 @@ net_init::
ld [wNetRxLen], a
ld [wNetRxLen+1], a
ld [wNetRxEsc], a
+ ld [wNetInFrame], a
+ ld [wConHead], a
+ ld [wConTail], a
ld [wNetSeq], a
ret
+; con_push(A) - queue a console-input byte (dropped if the ring is full)
+con_push::
+ ld b, a
+ ld a, [wConTail]
+ inc a
+ and 15
+ ld c, a
+ ld a, [wConHead]
+ cp c
+ ret z ; full -> drop
+ ld a, [wConTail]
+ ld e, a
+ ld d, 0
+ ld hl, wConRing
+ add hl, de
+ ld [hl], b
+ ld a, c
+ ld [wConTail], a
+ ret
+
+; con_pop -> A = byte, CF set if the ring is empty
+con_pop::
+ ld a, [wConHead]
+ ld b, a
+ ld a, [wConTail]
+ cp b
+ jr nz, .have
+ scf
+ ret
+.have
+ ld a, b
+ ld e, a
+ ld d, 0
+ ld hl, wConRing
+ add hl, de
+ ld c, [hl]
+ ld a, b
+ inc a
+ and 15
+ ld [wConHead], a
+ ld a, c
+ and a ; CF = 0
+ ret
+
; net_setip - store our IPv4 address (from wNetReq.NR_IP). Used by the DHCP
; client once it has a lease.
net_op_setip:
@@ -757,14 +808,20 @@ udp_send:
; net_pump - read available serial bytes, assemble SLIP frames, process each.
; Non-blocking: returns when the link has no more bytes ready.
; =============================================================================
-net_pump:
+net_pump::
.next
call net_getbyte_nb
ret c ; no byte ready
- ; SLIP decode using wNetRxLen / wNetRxEsc
cp SLIP_END
- jr z, .frame
+ jr z, .delim
ld c, a ; save byte
+ ld a, [wNetInFrame]
+ or a
+ jr nz, .inframe
+ ld a, c ; outside a frame -> console input
+ call con_push
+ jr .next
+.inframe
ld a, [wNetRxEsc]
or a
jr nz, .escaped
@@ -816,25 +873,36 @@ net_pump:
ld a, [wNetRxLen] ; index++
inc a
ld [wNetRxLen], a
- jr nz, .next
+ jp 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
- ; recv drains each segment before the next is delivered - no rx overwrite).
+ jp .next
+.delim
+ ; 0xC0 delimiter: end the current frame (process it) or start a new one.
xor a
ld [wNetRxEsc], a
+ ld a, [wNetInFrame]
+ or a
+ jr z, .startframe
ld a, [wNetRxLen]
ld hl, wNetRxLen+1
or [hl]
- jr z, .next ; empty frame, keep reading
+ jr z, .resetframe ; empty frame
call process_frame
+.resetframe
xor a
+ ld [wNetInFrame], a
ld [wNetRxLen], a
ld [wNetRxLen+1], a
- ret
+ ret ; one frame per pump
+.startframe
+ ld a, 1
+ ld [wNetInFrame], a
+ xor a
+ ld [wNetRxLen], a
+ ld [wNetRxLen+1], a
+ jp .next
; -----------------------------------------------------------------------------
; process_frame - IPv4 demux of the frame in wNetRxBuf (wNetRxLen bytes).