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