]> Joshua Wise's Git repositories - fpgaboy.git/blob - ethernet.asm
ARP responder
[fpgaboy.git] / ethernet.asm
1         INCLUDE "serial.inc"
2
3 ETH_STATUS EQU $FF68
4 ETH_DATA EQU $FF69
5 ARP_ENTRIES EQU 6
6 ARP_ENTRY_SIZE EQU 13
7
8         SECTION "config", HOME[$0]
9 myMAC:  db $12, $34, $56, $78, $9A, $00
10 myIP:   db $0A, $00, $00, $02
11 myMask: db $FF, $00, $00, $00
12 myGW:   db $0A, $00, $00, $01
13
14         SECTION "boot", HOME[$100]
15         jr start
16         nop
17         nop
18         
19         db $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83       ;<<< no $00,$c3,$50,$01
20         db $00,$0C,$00,$0D,$00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6
21         db $DD,$DD,$D9,$99,$BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F
22         db $BB,$B9,$33,$3E     ; Standard Nintendo DO NOT CHANGE...
23
24         db "GB Ethernet     "  ; Cart name   16bytes
25         db $00,$00,$00         ; Not used
26         db $00                 ; Cart type   ROM Only
27         db $00                 ; ROM Size    32k
28         db $00                 ; RAM Size     0k
29         db $cf,$08             ; Maker ID Matthew Johnson
30         db $01                 ; Version     =1
31         db $87                 ; Complement check (Important)
32         db $ff,$ff             ; Cheksum, fix this if you are going to
33
34 start:
35         ld sp, $D800
36         call zerobss
37         PUTSIL "Ethernet test ROM"
38 .lp:    xor a                   ; Reset state machines
39         ld [ETH_STATUS], a
40         ld a, [ETH_STATUS]      ; Load current status
41         ld [$FF51], a
42         and $02         ; New packet?
43         call nz, getpacket
44         jr .lp
45
46 zerobss:
47         ld hl, bssstart
48         ld bc, bssend - bssstart
49 .lp:    ld a, b
50         or c
51         ret z
52         dec bc
53         xor a
54         ld [hli], a
55         ld a, h
56         jr .lp
57
58 getpacket:
59         ld a, [ETH_DATA]
60         ld b, a
61         ld a, [ETH_DATA]
62         ld c, a
63         push bc
64         ld hl, packet
65 .cplp:  ld a, b
66         or c
67         jr z, .done
68         dec bc
69         ld a, [ETH_DATA]
70         ld [hli], a
71         jr .cplp
72 .done:  pop bc
73         PUTSI "getpacket: Got "
74         PUTHEX b
75         PUTHEX c
76         PUTSIL " byte packet from hardware."
77         ld hl, packet
78         call ether_input
79         ret
80
81 ether_input:
82         push hl
83         PUTSI "ether_input: Packet to "
84         PUTHEX [hli]
85         PUTC $3A
86         PUTHEX [hli]
87         PUTC $3A
88         PUTHEX [hli]
89         PUTC $3A
90         PUTHEX [hli]
91         PUTC $3A
92         PUTHEX [hli]
93         PUTC $3A
94         PUTHEX [hli]
95         PUTSI " from "
96         PUTHEX [hli]
97         PUTC $3A
98         PUTHEX [hli]
99         PUTC $3A
100         PUTHEX [hli]
101         PUTC $3A
102         PUTHEX [hli]
103         PUTC $3A
104         PUTHEX [hli]
105         PUTC $3A
106         PUTHEX [hli]
107         PUTSI " protocol "
108         PUTHEX [hli]
109         PUTHEX [hli]
110         PUTSIL "."
111         pop hl
112         
113         ; Verify the destination MAC.
114         push hl
115         ld de, myMAC
116         ld c, $06
117 .maclp: ld a, [de]
118         cp [hl]
119         jr nz, .notus
120         inc de
121         inc hl
122         dec c
123         jr nz, .maclp
124         ; Done? Then it was to us!
125         jr .us
126 .notus: ; Was it to broadcast?
127         pop hl
128         push hl
129         ld c, $06
130 .bclp:  ld a, [hli]
131         cp $FF
132         jr nz, .notbc
133         dec c
134         jr nz, .bclp
135
136 .us:    PUTSIL "ether_input: It's to us!"
137         ; Which protocol does it belong to?
138         pop hl
139         ld b, $00
140         ld c, 12
141         add hl, bc      ; Skip source and dest MAC.
142         ld a, [hli]
143         cp $08
144         jr nz, .unknownproto
145         ld a, [hli]
146         cp $06
147         jr z, .arp
148         cp $00
149         jp z, .ip
150         jr .unknownproto
151
152 .notbc: pop hl
153         PUTSIL "ether_input: Not addressed to us and not broadcast."
154         ret
155         
156 .unknownproto:
157         PUTSIL "ether_input: Unknown protocol; dropping"
158         ret
159
160 .arp:
161         PUTSIL "ether_input: ARP packet"
162         call arp_input
163         ret
164 .ip:
165         PUTSIL "ether_input: IP packet"
166         call ip_input
167         ret
168
169 arp_input:
170         ; First, verify that this is an ARP packet that we can handle.
171         ld c, 7
172         ld de, .expectedarp
173 .cklp:  xor a
174         cp c
175         jr z, .ckdone
176         ld a, [de]
177         cp [hl]
178         jr nz, .badarp
179         inc de
180         inc hl
181         dec c
182         jr .cklp
183 .ckdone:
184         ld a, [hli]
185         cp 1
186         jr z, .req
187         cp 2
188         jp z, .resp
189 .badarp:
190         PUTSIL "arp_input: Unknown protocol hardware or request"
191         ret
192 .expectedarp:
193         db $00, $01, $08, $00, $06, $04, $00
194
195 .req:
196         PUTSIL "arp_input.req: Request"
197         ; Is it asking about us?
198         push hl
199         ld b, 0
200         ld c, $10       ; SHA + SPA + THA
201         add hl, bc
202         ld de, myIP
203         ld c, 4
204 .iplp:  ld a, [de]
205         cp [hl]
206         jp nz, .notourip
207         inc de
208         inc hl
209         dec c
210         jr nz, .iplp
211         PUTSIL "arp_input.req: Aimed at us."
212         pop hl  ; Now synthesize a response packet.
213         push hl
214         dec hl
215         ld a, $02       ; Reply!
216         ld [hli], a
217         ld d, h
218         ld e, l
219         ld hl, 10       ; SHA + SPA
220         add hl, de      ; Now DE points at SHA, and HL points at THA
221         ld c, 10
222 .dcl:   ld a, [de]
223         ld [hli], a
224         inc de
225         dec c
226         jr nz, .dcl
227         pop hl          ; HL now points at SHA
228         ld de, myMAC
229         ld c, $06
230 .mcl:   ld a, [de]
231         ld [hli], a
232         inc de
233         dec c
234         jr nz, .mcl
235         ld de, myIP     ; HL now points at SPA
236         ld c, $04
237 .icl:   ld a, [de]
238         ld [hli], a
239         inc de
240         dec c
241         jr nz, .icl
242         ld d, h
243         ld e, l         ; HL now points at THA
244         ld hl, -32
245         add hl, de      ; HL has now been backed up to the start of the ethernet header.
246         ld d, h
247         ld e, l         ; DE now points at the dest
248         ld hl, 6
249         add hl, de      ; HL now points at the source
250         ld c, $06
251 .sdcl:  ld a, [hli]
252         ld [de], a
253         inc de
254         dec c
255         jr nz, .sdcl
256         ld hl, myMAC    ; DE now points at the source
257         ld c, $06
258 .smcl:  ld a, [hli]
259         ld [de], a
260         inc de
261         dec c
262         jr nz, .smcl
263         ld hl, -12
264         add hl, de      ; HL now points at the start of the packet -- should be C000!
265         ld b, 0
266         ld c, 64        ; Minimum size packet; avoid transmitting a runt
267         call packet_send
268         PUTSIL "arp_input.req: sent response!"
269         ret
270 .notourip:
271         PUTSIL "arp_input.req: Not aimed at us; ignoring."
272         pop hl
273         ret
274         
275 .resp:
276         PUTSIL "arp_input.resp: Response"
277         ret
278
279 ip_input:
280         ret
281
282 packet_send:
283         ld a, [ETH_STATUS]      ; Wait for the port to become available.
284         and $01
285         jr nz, packet_send
286         ld a, b
287         ld [ETH_DATA], a
288         ld a, c
289         ld [ETH_DATA], a
290 .pkts:  ld a, b
291         or c
292         ret z
293         dec bc
294         ld a, [hli]
295         ld [ETH_DATA], a
296         jr .pkts
297
298         SECTION "ethdata", BSS
299 bssstart        DS 0
300 packet          DS 1552
301 arptable        DS ARP_ENTRIES * ARP_ENTRY_SIZE
302 bssend          DS 0
This page took 0.046869 seconds and 4 git commands to generate.