diff options
Diffstat (limited to '')
| -rw-r--r-- | src/programs.asm | 7 | ||||
| -rw-r--r-- | src/socket.asm | 97 |
2 files changed, 75 insertions, 29 deletions
diff --git a/src/programs.asm b/src/programs.asm index 9ae7f58..e89fe0c 100644 --- a/src/programs.asm +++ b/src/programs.asm @@ -127,6 +127,9 @@ ProgPing: SECTION "prog_nslookup", ROMX[$4000], BANK[30] ProgNslookup: INCBIN "c/nslookup.bin" +SECTION "prog_dhcp", ROMX[$4000], BANK[31] +ProgDhcp: + INCBIN "c/dhcp.bin" ; ----------------------------------------------------------------------------- ; PROG_SH (bank 3) - the shell, now written in C (c/sh.c): parses >/</| and @@ -227,6 +230,8 @@ ProgramTable:: dw ProgPing db LOW(BANK(ProgNslookup)), HIGH(BANK(ProgNslookup)) dw ProgNslookup + db LOW(BANK(ProgDhcp)), HIGH(BANK(ProgDhcp)) + dw ProgDhcp ; ----------------------------------------------------------------------------- ; NameTable (ROM0) - command name -> program id, searched by sys_lookup. @@ -291,4 +296,6 @@ NameTable:: db PROG_PING db "nslookup", 0 db PROG_NSLOOKUP + db "dhcp", 0 + db PROG_DHCP db 0 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 |
