Diag rom now runs from bootloader!
[fpgaboy.git] / diag.asm
CommitLineData
00573fd5
JW
1 SECTION "a",HOME[$00]
2
3start: jp main
4
5 section "vbl",HOME[$40]
6 jp vbl
7
8 section "lcdc",HOME[$48]
9 jp lcdc
10
11 section "tmro",HOME[$50]
12 jp tmro
5bac4cf0 13
2bcaaabf
JW
14 SECTION "b",HOME[$100]
15boot: jr main ; $0100
16 nop ; $0102
17 nop ; $0103
18 ;Nintendo Logo ; $0104
19 DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D
20 DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99
21 DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E
22 ;$0134
23 DB $00,$E7,$00,$00,$00,$00,$00,$00, $00,$00,$00,$00,$00,$00,$00,$00
24 ;$0144
25 DB $00,$00,$00,$00,$00,$00,$00,$00, $00,$00,$00,$00,$00,$00,$00,$00
26
5bac4cf0 27main:
5bac4cf0 28 ld a, $FF
fe3dc890
JW
29 ld c, $51
30 ld [c], a
00573fd5 31
5bac4cf0
JW
32 ld sp, $DFF0
33
30ef1ae0 34 ld a, $04 ;start timer, 4.096KHz
00573fd5
JW
35 ld c, $07
36 ld [c], a
03202f62 37
30ef1ae0
JW
38 ld hl, $DF81
39 xor a
7e4f4505
JW
40 ld [hli], a
41 ld [hli], a
30ef1ae0 42
5bac4cf0
JW
43 ld hl, signon
44 call puts
39a68cde 45
a42afaa9
JW
46 ld a, $91
47 ld [$FF40], a
48
39a68cde 49 call putscreen
30ef1ae0
JW
50
51 ei
5bac4cf0
JW
52
53 call memtest
54
55 call insntest
56
57 call waitsw
30ef1ae0
JW
58
59 di
5bac4cf0
JW
60
61 jr main
62
63signon:
64 db $0D,$0A,$1B,"[1mFPGABoy Diagnostic ROM",$1B,"[0m",$0D,$0A,0
65
0dea04d3 66tiles:
ec727403
JW
67 db %01111100
68 db %11000110
69 db %11000110
70 db %11111110
71 db %11000110
72 db %11000110
73 db %11000110
0dea04d3 74 db %00000000
ec727403
JW
75
76 db %11111100
77 db %11000110
78 db %11000110
79 db %11111100
80 db %11000110
81 db %11000110
82 db %11111100
0dea04d3
JW
83 db %00000000
84
14778cde
JW
85 db %01111100
86 db %11000110
87 db %11000010
88 db %11000000
89 db %11000010
90 db %11000110
91 db %01111100
92 db %00000000
93
94 db %11111100
95 db %11000110
96 db %11000110
97 db %11000110
98 db %11000110
99 db %11000110
100 db %11111100
101 db %00000000
102
39a68cde 103putscreen:
b4f3ac35
JW
104 LD A,$fc ; $001d Setup BG palette
105 LD [$FF47],A ; $001f
106
4d90f272 107 ; Wait for vblank
80ecd2fe 108 call .vblwait
4d90f272
JW
109
110 ld hl, $8000 ; Copy two tiles.
0dea04d3 111 ld de, tiles
14778cde 112 ld c, $20
4fd47c85 113.cloop: ld a, [de]
0dea04d3 114 inc de
39a68cde
JW
115 ld [hli], a
116 ld [hli], a
0dea04d3 117 dec c
39a68cde 118 xor a
0dea04d3
JW
119 cp c
120 jr nz, .cloop
39a68cde
JW
121
122 ld hl, $9800
80ecd2fe
JW
123.vloop: call .vblwait
124 ld c, $40
0dea04d3 125 ld b, 0
14778cde
JW
126.loop: ld a, b
127 inc b
128 and $03
39a68cde
JW
129 ld [hli], a
130 ld a, h
131 cp $9C
80ecd2fe
JW
132 ret z
133 dec c
134 xor a
135 cp c
136 jr nz,.loop
137 jr .vloop
138
139.vblwait:
140.stat1: ld a, [$FF41] ; STAT
141 and $03
142 cp $00
143 jp nz, .stat1
144.stat2: ld a, [$FF41]
145 and $03
146 cp $01
147 jr nz, .stat2
39a68cde
JW
148 ret
149
00573fd5 150vbl:
03202f62
JW
151 PUSH AF
152 PUSH BC
153 PUSH DE
154 PUSH HL
155
156 xor a
f6fa1d6e
JW
157 ld [$FF0F], a
158
80ecd2fe 159 ld a, [$FF51]
ee31adcb
JW
160 bit 7, a
161 jr z, .nothing
162
163 bit 0, a
80ecd2fe
JW
164 call nz, .scyup
165
ee31adcb 166 bit 1, a
80ecd2fe
JW
167 call nz, .scydown
168
ee31adcb 169 bit 2, a
80ecd2fe
JW
170 call nz, .scxup
171
ee31adcb 172 bit 3, a
80ecd2fe
JW
173 call nz, .scxdown
174
175.nothing:
03202f62
JW
176 POP HL
177 POP DE
178 POP BC
179 POP AF
180
181 RETI
182
80ecd2fe
JW
183.scyup: ld hl, $FF42
184 inc [hl]
185 ret
186
187.scydown: ld hl, $FF42
188 dec [hl]
189 ret
190
191.scxup: ld hl, $FF43
192 inc [hl]
193 ret
194
195.scxdown: ld hl, $FF43
196 dec [hl]
197 ret
198
199
00573fd5
JW
200lcdc:
201 PUSH AF
fe3dc890 202 PUSH BC
00573fd5
JW
203
204 xor a
f6fa1d6e 205 ld [$FF0F], a
00573fd5 206
fe3dc890 207 POP BC
00573fd5
JW
208 POP AF
209
210 reti
211
212tmro:
30ef1ae0
JW
213 PUSH AF
214 PUSH BC
215 PUSH DE
216 PUSH HL
217
218 xor a
f6fa1d6e 219 ld [$FF0F], a
30ef1ae0 220
03202f62
JW
221 ld c, $45 ; LYC
222 ld a, [c]
223 inc a
224 ld [c], a
225
f6fa1d6e 226 ld a, [$DF82]
7e4f4505
JW
227 cp 0
228 jr z, .noprint
30ef1ae0
JW
229 ld a, $41 ; print A
230 call putc
7e4f4505 231.noprint:
f6fa1d6e
JW
232 ld a, [$DF81]
233 inc a
234 ld [$DF81], a
235 ld [$FF51], a
30ef1ae0 236
30ef1ae0
JW
237 POP HL
238 POP DE
239 POP BC
240 POP AF
241 RETI
30ef1ae0 242
5bac4cf0
JW
243; Memory tester: writes h ^ l to all addresses from C000 to DF80.
244memtest:
245 ld hl,memteststr
246 call puts
247
f6fa1d6e 248 ld hl, $C000 ; Write loop
5bac4cf0
JW
249.wr:
250 ld a,h
251 xor l
252 ld [hli],a
f888201b
JW
253 ld a, h
254 cp $DF
5bac4cf0 255 jr nz, .wr
f888201b
JW
256 ld a, l
257 cp $80
5bac4cf0
JW
258 jr nz, .wr
259
f6fa1d6e 260 ld hl, $C000 ; Read loop
5bac4cf0
JW
261.rd:
262 ld a,h
263 xor l
264 ld b,a
265 ld a, [hli]
266 cp b
267 jr nz, .memfail
268
f888201b
JW
269 ld a, h
270 cp $DF
5bac4cf0 271 jr nz, .rd
f888201b
JW
272 ld a, l
273 cp $80
5bac4cf0
JW
274 jr nz, .rd
275
276 ld hl, testokstr ; Say we're OK
277 call puts
278 ret
279.memfail: ; Say we failed (sadface)
280 ; decrement hl the easy way
f6fa1d6e 281 dec [hl]
5bac4cf0
JW
282 push hl
283 ld hl, failatstr
284 call puts
285 pop hl
286 ld a, h
287 call puthex
288 ld a, l
289 call puthex
290 ld a, $0A
291 call putc
292 ld a, $0D
293 call putc
294 ret
295memteststr:
296 db "Testing memory from $C000 to $DF80...",0
297testokstr:
298 db " OK!",$0D,$0A,0
299failatstr:
300 db " Test failed at $",0
301
302puthex: ; Put two hex nibbles to the serial console.
303 push af
304 rra
305 rra
306 rra
307 rra
f888201b
JW
308 and $0F
309 add $30
5bac4cf0
JW
310 call putc
311 pop af
f888201b
JW
312 and $0F
313 add $30
5bac4cf0
JW
314 call putc
315 ret
316
317; Wait for switches to be flipped on and off again.
318waitsw:
319 ld hl,waitswstr
320 call puts
7e4f4505
JW
321
322 ld hl,$DF82
323 ld a, 1
324 ld [hl], a
5bac4cf0
JW
325
326 ld c, $51
327 xor a
328 ld [c],a
329
5bac4cf0
JW
330.loop1:
331 ld a,[c]
f888201b 332 cp $0
5bac4cf0 333 jr z,.loop1
b4f3ac35
JW
334
335.loop2: ld a,[c]
f888201b 336 cp $0
5bac4cf0
JW
337 jr nz,.loop2
338 ret
339
340waitswstr:
341 db "Diagnostic ROM complete; flip switches to nonzero and then to zero to reset. Expect A.",$0D,$0A,0
342
343; Core instruction basic acceptance tests.
344insntest:
345 ld hl, .insnteststr
346 call puts
347
348 ; Test PUSH and POP.
349 ld b, $12
350 ld c, $34
351 ld d, $56
352 ld e, $78
353 push bc
354 pop de
355 ld hl, .pushpopfail
356 ld a, d
357 cp b
358 jr nz,.fail
359 ld a, e
360 cp c
361 jr nz,.fail
362
363 ; Test ALU (HL).
364 ld hl, .ff
365 ld a, $FF
366 xor [hl]
367 ld hl, .xorhlfail
368 jr nz, .fail
369
370 ; Test JP (HL)
371 ld hl, .jphl
372 jp [hl]
373 ld hl, .jphlfail
374 jr .fail
375 rst $00
376.jphl:
377
378 ; Test JR
379 ld a, $FF
f888201b 380 cp $0
5bac4cf0
JW
381 jr nz,.jr
382 ld hl, .jrfail
383 jr .fail
384 rst $00
385.jr:
386
387 ; Test inc16
388 ld d, $12
389 ld e, $FF
390 ld hl, .inc16fail
391 inc de
392 ld a, $13
393 cp d
394 jr nz, .fail
395 ld a, $00
396 cp e
397 jr nz, .fail
398
399 ; Test CP.
400 ld hl, .cpfail
401 ld a, $10
f888201b 402 cp $20
5bac4cf0
JW
403 jr nc,.fail
404 ld a, $20
f888201b 405 cp $10
5bac4cf0
JW
406 jr c,.fail
407
408 ; Test CPL
409 ld hl, .cplfail
410 ld a, $55
5bac4cf0 411 cpl
f888201b 412 cp $AA
5bac4cf0 413 jr nz,.fail
f9000d73
JW
414
415 ; Test DI/EI delay
416 di
00573fd5 417 ld hl, .dinocausefail
f9000d73
JW
418 ld c, $0F ; First, wait until an interrupt happens...
419.wait: ld a, [c]
00573fd5 420 and $04
f9000d73
JW
421 cp 0
422 jr z, .wait
423 ei ; Now make sure that an IRQ didn't happen on EI/DI
424 di
425 ld a, [c]
00573fd5 426 and $04
f9000d73
JW
427 cp 0
428 jr z, .fail
00573fd5 429 ld hl, .dicausefail
f9000d73
JW
430 ei ; Make sure that an IRQ does happen on EI/NOP/DI
431 nop
00573fd5 432 nop
f9000d73
JW
433 di
434 ld a, [c]
00573fd5 435 and $04
f9000d73
JW
436 cp 0
437 jr nz, .fail
438 ei
5bac4cf0
JW
439
440 ld hl, .ok
441 call puts
442 ret
443.fail:
f9000d73 444 ei
5bac4cf0
JW
445 call puts
446 ld hl, .testfailed
447 call puts
448 ret
449.insnteststr:
450 db "Testing instructions... ",0
451.pushpopfail:
452 db "PUSH/POP",0
453.ff:
454 db $FF
455.xorhlfail:
456 db "XOR [HL]",0
457.jphlfail:
458 db "JP [HL]",0
459.jrfail:
460 db "JR",0
461.cpfail:
462 db "CP",0
463.cplfail:
464 db "CPL",0
465.inc16fail:
466 db "INC16",0
00573fd5
JW
467.dinocausefail:
468 db "DI/EI does not cause interrupt",0
469.dicausefail:
470 db "DI/NOP/EI cause interrupt",0
5bac4cf0
JW
471.testfailed:
472 db " test failed.",$0D,$0A,0
473.ok:
474 db "OK!",$0D,$0A,0
475
476; Serial port manipulation functions.
477putc:
3db3fc27 478 ld c, $53
5bac4cf0
JW
479 push af
480.waitport:
481 ld a,[c]
3db3fc27 482 and $01
5bac4cf0
JW
483 jr nz,.waitport
484 pop af
3db3fc27 485 ld [$FF52],a
5bac4cf0
JW
486 ret
487
488puts:
489 ld a, [hli]
f888201b 490 cp $00
5bac4cf0
JW
491 ret z
492 call putc
493 jr puts
fe3dc890 494
This page took 0.074478 seconds and 4 git commands to generate.