]> Joshua Wise's Git repositories - fpgaboy.git/blobdiff - ethernet.asm
ARP responder
[fpgaboy.git] / ethernet.asm
index 85d66e1b38e1a1fe8d2528e50719eaf5e29dd379..5e49ef62f3b564dd4d9c67aa6537c7dbfcb30176 100644 (file)
@@ -1,35 +1,10 @@
+       INCLUDE "serial.inc"
+
 ETH_STATUS EQU $FF68
 ETH_DATA EQU $FF69
+ARP_ENTRIES EQU 6
+ARP_ENTRY_SIZE EQU 13
 
-PUTC: MACRO
-       ld a, \1
-       call putc
-       ENDM
-
-PUTS: MACRO
-       ld hl, \1
-       call puts
-       ENDM
-
-PUTSI: MACRO
-       push hl
-       call putsi
-       db \1, 0
-       pop hl
-       ENDM
-
-PUTSIL: MACRO
-       push hl
-       call putsi
-       db \1, 13, 10, 0
-       pop hl
-       ENDM
-
-PUTHEX: MACRO
-       ld a, \1
-       call puthex
-       ENDM
-       
        SECTION "config", HOME[$0]
 myMAC: db $12, $34, $56, $78, $9A, $00
 myIP:  db $0A, $00, $00, $02
@@ -99,7 +74,7 @@ getpacket:
        PUTHEX b
        PUTHEX c
        PUTSIL " byte packet from hardware."
-       ld hl, $D000
+       ld hl, packet
        call ether_input
        ret
 
@@ -192,86 +167,136 @@ ether_input:
        ret
 
 arp_input:
+       ; First, verify that this is an ARP packet that we can handle.
+       ld c, 7
+       ld de, .expectedarp
+.cklp: xor a
+       cp c
+       jr z, .ckdone
+       ld a, [de]
+       cp [hl]
+       jr nz, .badarp
+       inc de
+       inc hl
+       dec c
+       jr .cklp
+.ckdone:
+       ld a, [hli]
+       cp 1
+       jr z, .req
+       cp 2
+       jp z, .resp
+.badarp:
+       PUTSIL "arp_input: Unknown protocol hardware or request"
+       ret
+.expectedarp:
+       db $00, $01, $08, $00, $06, $04, $00
+
+.req:
+       PUTSIL "arp_input.req: Request"
+       ; Is it asking about us?
+       push hl
+       ld b, 0
+       ld c, $10       ; SHA + SPA + THA
+       add hl, bc
+       ld de, myIP
+       ld c, 4
+.iplp: ld a, [de]
+       cp [hl]
+       jp nz, .notourip
+       inc de
+       inc hl
+       dec c
+       jr nz, .iplp
+       PUTSIL "arp_input.req: Aimed at us."
+       pop hl  ; Now synthesize a response packet.
+       push hl
+       dec hl
+       ld a, $02       ; Reply!
+       ld [hli], a
+       ld d, h
+       ld e, l
+       ld hl, 10       ; SHA + SPA
+       add hl, de      ; Now DE points at SHA, and HL points at THA
+       ld c, 10
+.dcl:  ld a, [de]
+       ld [hli], a
+       inc de
+       dec c
+       jr nz, .dcl
+       pop hl          ; HL now points at SHA
+       ld de, myMAC
+       ld c, $06
+.mcl:  ld a, [de]
+       ld [hli], a
+       inc de
+       dec c
+       jr nz, .mcl
+       ld de, myIP     ; HL now points at SPA
+       ld c, $04
+.icl:  ld a, [de]
+       ld [hli], a
+       inc de
+       dec c
+       jr nz, .icl
+       ld d, h
+       ld e, l         ; HL now points at THA
+       ld hl, -32
+       add hl, de      ; HL has now been backed up to the start of the ethernet header.
+       ld d, h
+       ld e, l         ; DE now points at the dest
+       ld hl, 6
+       add hl, de      ; HL now points at the source
+       ld c, $06
+.sdcl: ld a, [hli]
+       ld [de], a
+       inc de
+       dec c
+       jr nz, .sdcl
+       ld hl, myMAC    ; DE now points at the source
+       ld c, $06
+.smcl: ld a, [hli]
+       ld [de], a
+       inc de
+       dec c
+       jr nz, .smcl
+       ld hl, -12
+       add hl, de      ; HL now points at the start of the packet -- should be C000!
+       ld b, 0
+       ld c, 64        ; Minimum size packet; avoid transmitting a runt
+       call packet_send
+       PUTSIL "arp_input.req: sent response!"
+       ret
+.notourip:
+       PUTSIL "arp_input.req: Not aimed at us; ignoring."
+       pop hl
+       ret
+       
+.resp:
+       PUTSIL "arp_input.resp: Response"
        ret
 
 ip_input:
        ret
 
+packet_send:
+       ld a, [ETH_STATUS]      ; Wait for the port to become available.
+       and $01
+       jr nz, packet_send
+       ld a, b
+       ld [ETH_DATA], a
+       ld a, c
+       ld [ETH_DATA], a
+.pkts: ld a, b
+       or c
+       ret z
+       dec bc
+       ld a, [hli]
+       ld [ETH_DATA], a
+       jr .pkts
+
        SECTION "ethdata", BSS
 bssstart       DS 0
 packet         DS 1552
+arptable       DS ARP_ENTRIES * ARP_ENTRY_SIZE
 bssend         DS 0
-
-
-; SERIAL ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-       SECTION "serial", HOME
-
-putc:
-       push af
-.waitport:
-       ld a,[$FF53]
-       and $01
-       jr nz,.waitport
-       pop af
-       ld [$FF52],a
-       ret
-
-puts:
-       ld a, [hli]
-       cp $00
-       ret z
-       call putc
-       jr puts
-
-EX_SP_HL: MACRO
-       push de
-       di
-       add sp, 2
-       pop de
-       push hl
-       ld l, e
-       ld h, d
-       add sp, -2
-       ei
-       pop de
-       ENDM
-
-putsi:
-       pop hl
-       push af
-       push bc
-       push de
-.lp:   ld a, [hli]
-       or a
-       jr z, .done
-       call putc
-       jr .lp
-.done: pop de
-       pop bc
-       pop af
-       push hl
-       ret
-
-puthex:                                ; Put two hex nibbles to the serial console.
-       push bc
-       push hl
-       push af
-       swap a
-       and $0F
-       ld hl,hex
-       ld b,0
-       ld c,a
-       add hl,bc
-       ld a, [hl]
-       call putc
-       pop af
-       and $0F
-       ld hl,hex
-       ld c,a
-       add hl,bc
-       ld a, [hl]
-       call putc
-       pop hl
-       pop bc
-       ret
-hex:   db "0123456789ABCDEF"
This page took 0.033754 seconds and 4 git commands to generate.