780f5c2b452df06e5da55f2c4d1d9cb932058dfb
[fpgaboy.git] / diag.asm
1         SECTION "a",HOME[$00]
2
3 start: 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
13
14         SECTION "b",HOME[$100]
15 boot:   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
27 main:
28         ld a, $FF
29         ld c, $51
30         ld [c], a
31
32         ld sp, $DFF0
33         
34         ld a, $04       ;start timer, 4.096KHz
35         ld c, $07
36         ld [c], a
37         
38         ld hl, $DF81
39         xor a
40         ld [hli], a
41         ld [hli], a
42         
43         ld hl, signon
44         call puts
45
46         ld a, $91
47         ld [$FF40], a
48
49         call putscreen
50         
51         ei
52
53         call memtest
54
55         call insntest
56
57         call waitsw
58         
59         di
60
61         jr main
62
63 signon:
64         db $0D,$0A,$1B,"[1mFPGABoy Diagnostic ROM",$1B,"[0m",$0D,$0A,0
65
66 tiles:
67         db %01111100
68         db %11000110
69         db %11000110
70         db %11111110
71         db %11000110
72         db %11000110
73         db %11000110
74         db %00000000
75         
76         db %11111100
77         db %11000110
78         db %11000110
79         db %11111100
80         db %11000110
81         db %11000110
82         db %11111100
83         db %00000000
84
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
103 putscreen:
104         LD A,$fc                ; $001d  Setup BG palette
105         LD [$FF47],A    ; $001f
106
107         ; Wait for vblank
108         call .vblwait
109
110         ld hl, $8000    ; Copy two tiles.
111         ld de, tiles
112         ld c, $20
113 .cloop: ld a, [de]
114         inc de
115         ld [hli], a
116         ld [hli], a
117         dec c
118         xor a
119         cp c
120         jr nz, .cloop
121         
122         ld hl, $9800
123 .vloop: call .vblwait
124         ld c, $40
125         ld b, 0
126 .loop:  ld a, b
127         inc b
128         and $03
129         ld [hli], a
130         ld a, h
131         cp $9C
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
148         ret
149
150 vbl:
151         PUSH AF
152         PUSH BC
153         PUSH DE
154         PUSH HL
155         
156         xor a
157         ld [$FF0F], a
158
159         ld a, [$FF51]
160         bit 7, a
161         jr z, .nothing
162
163         bit 0, a
164         call nz, .scyup
165         
166         bit 1, a
167         call nz, .scydown
168         
169         bit 2, a
170         call nz, .scxup
171         
172         bit 3, a
173         call nz, .scxdown
174
175 .nothing:
176         POP HL
177         POP DE
178         POP BC
179         POP AF
180
181         RETI
182
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
200 lcdc:
201         PUSH AF
202         PUSH BC
203         
204         xor a
205         ld [$FF0F], a
206         
207         POP BC
208         POP AF
209         
210         reti
211         
212 tmro:
213         PUSH AF
214         PUSH BC
215         PUSH DE
216         PUSH HL
217         
218         xor a
219         ld [$FF0F], a
220         
221         ld c, $45       ; LYC
222         ld a, [c]
223         inc a
224         ld [c], a
225         
226         ld a, [$DF82]
227         cp 0
228         jr z, .noprint
229         ld a, $41       ; print A
230         call putc
231 .noprint:
232         ld a, [$DF81]
233         inc a
234         ld [$DF81], a
235         ld [$FF51], a
236
237         POP HL
238         POP DE
239         POP BC
240         POP AF
241         RETI
242
243 ; Memory tester: writes h ^ l to all addresses from C000 to DF80.
244 memtest:
245         ld hl,memteststr
246         call puts
247         
248         ld hl, $C000            ; Write loop
249 .wr:
250         ld a,h
251         xor l
252         ld [hli],a
253         ld a, h
254         cp $DF
255         jr nz, .wr
256         ld a, l
257         cp $80
258         jr nz, .wr
259
260         ld hl, $C000            ; Read loop
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         
269         ld a, h
270         cp $DF
271         jr nz, .rd
272         ld a, l
273         cp $80
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
281         dec [hl]
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
295 memteststr:
296         db "Testing memory from $C000 to $DF80...",0
297 testokstr:
298         db " OK!",$0D,$0A,0
299 failatstr:
300         db " Test failed at $",0
301
302 puthex:                         ; Put two hex nibbles to the serial console.
303         push af
304         rra
305         rra
306         rra
307         rra
308         and $0F
309         add $30
310         call putc
311         pop af
312         and $0F
313         add $30
314         call putc
315         ret
316
317 ; Wait for switches to be flipped on and off again.
318 waitsw:
319         ld hl,waitswstr
320         call puts
321         
322         ld hl,$DF82
323         ld a, 1
324         ld [hl], a
325
326         ld c, $51
327         xor a
328         ld [c],a
329         
330 .loop1:
331         ld a,[c]
332         cp $0
333         jr z,.loop1
334
335 .loop2: ld a,[c]
336         cp $0
337         jr nz,.loop2
338         ret
339
340 waitswstr:
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.
344 insntest:
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
380         cp $0
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
402         cp $20
403         jr nc,.fail
404         ld a, $20
405         cp $10
406         jr c,.fail
407         
408         ; Test CPL
409         ld hl, .cplfail
410         ld a, $55
411         cpl
412         cp $AA
413         jr nz,.fail
414
415         ; Test DI/EI delay
416         di
417         ld hl, .dinocausefail
418         ld c, $0F       ; First, wait until an interrupt happens...
419 .wait:  ld a, [c]
420         and $04
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]
426         and $04
427         cp 0
428         jr z, .fail
429         ld hl, .dicausefail
430         ei              ; Make sure that an IRQ does happen on EI/NOP/DI
431         nop
432         nop
433         di
434         ld a, [c]
435         and $04
436         cp 0
437         jr nz, .fail
438         ei
439         
440         ld hl, .ok
441         call puts
442         ret
443 .fail:
444         ei
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
467 .dinocausefail:
468         db "DI/EI does not cause interrupt",0
469 .dicausefail:
470         db "DI/NOP/EI cause interrupt",0
471 .testfailed:
472         db " test failed.",$0D,$0A,0
473 .ok:
474         db "OK!",$0D,$0A,0
475
476 ; Serial port manipulation functions.
477 putc:
478         ld c, $50
479         push af
480 .waitport:
481         ld a,[c]
482         cp $00
483         jr nz,.waitport
484         pop af
485         ld [c],a
486         ret
487
488 puts:
489         ld a, [hli]
490         cp $00
491         ret z
492         call putc
493         jr puts
494
This page took 0.033384 seconds and 2 git commands to generate.