Fix tileaddr bug. Make bus interface more explicit.
[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         ld c, $41
56 .stat:  ld a, [c]
57         ld [$FF51], a
58         and $03         ; mode
59         cp $01          ; VBLANK
60         jr nz, .stat
61
62         ld hl, $8000    ; Copy two tiles.
63         ld a, $AA
64         ld [hli], a
65         ld [hli], a
66         ld a, $55
67         ld [hli], a
68         ld [hli], a
69         ld a, $AA
70         ld [hli], a
71         ld [hli], a
72         ld a, $55
73         ld [hli], a
74         ld [hli], a
75         ld a, $AA
76         ld [hli], a
77         ld [hli], a
78         ld a, $55
79         ld [hli], a
80         ld [hli], a
81         ld a, $AA
82         ld [hli], a
83         ld [hli], a
84         ld a, $55
85         ld [hli], a
86         ld [hli], a
87         xor 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         ld [hli], a
100         ld [hli], a
101         ld [hli], a
102         ld [hli], a
103         ld [hli], a
104         
105         ld hl, $9800
106 .loop:  ld a, $01
107         ld [hli], a
108         xor a
109         ld [hli], a
110         ld a, h
111         cp $9C
112         jp nz,.loop
113         ret
114
115 vbl:
116         PUSH AF
117         PUSH BC
118         PUSH DE
119         PUSH HL
120         
121         xor a
122         ld [$FF0F], a
123
124         ld c, $42       ; SCY
125         ld a, [c]
126         inc a
127         ld [c], a
128         
129         ld c, $43       ; SCX
130         ld a, [c]
131         inc a
132         ld [c], a
133
134         POP HL
135         POP DE
136         POP BC
137         POP AF
138
139         RETI
140
141 lcdc:
142         PUSH AF
143         PUSH BC
144         
145         xor a
146         ld [$FF0F], a
147         
148         POP BC
149         POP AF
150         
151         reti
152         
153 tmro:
154         PUSH AF
155         PUSH BC
156         PUSH DE
157         PUSH HL
158         
159         xor a
160         ld [$FF0F], a
161         
162         ld c, $45       ; LYC
163         ld a, [c]
164         inc a
165         ld [c], a
166         
167         ld a, [$DF82]
168         cp 0
169         jr z, .noprint
170         ld a, $41       ; print A
171         call putc
172 .noprint:
173         ld a, [$DF81]
174         inc a
175         ld [$DF81], a
176         ld [$FF51], a
177
178         POP HL
179         POP DE
180         POP BC
181         POP AF
182         RETI
183
184 ; Memory tester: writes h ^ l to all addresses from C000 to DF80.
185 memtest:
186         ld hl,memteststr
187         call puts
188         
189         ld hl, $C000            ; Write loop
190 .wr:
191         ld a,h
192         xor l
193         ld [hli],a
194         ld a, h
195         cp $DF
196         jr nz, .wr
197         ld a, l
198         cp $80
199         jr nz, .wr
200
201         ld hl, $C000            ; Read loop
202 .rd:
203         ld a,h
204         xor l
205         ld b,a
206         ld a, [hli]
207         cp b
208         jr nz, .memfail
209         
210         ld a, h
211         cp $DF
212         jr nz, .rd
213         ld a, l
214         cp $80
215         jr nz, .rd
216         
217         ld hl, testokstr        ; Say we're OK
218         call puts
219         ret
220 .memfail:                       ; Say we failed (sadface)
221         ; decrement hl the easy way
222         dec [hl]
223         push hl
224         ld hl, failatstr
225         call puts
226         pop hl
227         ld a, h
228         call puthex
229         ld a, l
230         call puthex
231         ld a, $0A
232         call putc
233         ld a, $0D
234         call putc
235         ret
236 memteststr:
237         db "Testing memory from $C000 to $DF80...",0
238 testokstr:
239         db " OK!",$0D,$0A,0
240 failatstr:
241         db " Test failed at $",0
242
243 puthex:                         ; Put two hex nibbles to the serial console.
244         push af
245         rra
246         rra
247         rra
248         rra
249         and $0F
250         add $30
251         call putc
252         pop af
253         and $0F
254         add $30
255         call putc
256         ret
257
258 ; Wait for switches to be flipped on and off again.
259 waitsw:
260         ld hl,waitswstr
261         call puts
262         
263         ld hl,$DF82
264         ld a, 1
265         ld [hl], a
266
267         ld c, $51
268         xor a
269         ld [c],a
270         
271 .loop1:
272         ld a,[c]
273         cp $0
274         jr z,.loop1
275 .loop2:
276         ld a,[c]
277         cp $0
278         jr nz,.loop2
279         ret
280
281 waitswstr:
282         db "Diagnostic ROM complete; flip switches to nonzero and then to zero to reset. Expect A.",$0D,$0A,0
283
284 ; Core instruction basic acceptance tests.
285 insntest:
286         ld hl, .insnteststr
287         call puts
288         
289         ; Test PUSH and POP.
290         ld b, $12
291         ld c, $34
292         ld d, $56
293         ld e, $78
294         push bc
295         pop de
296         ld hl, .pushpopfail
297         ld a, d
298         cp b
299         jr nz,.fail
300         ld a, e
301         cp c
302         jr nz,.fail
303         
304         ; Test ALU (HL).
305         ld hl, .ff
306         ld a, $FF
307         xor [hl]
308         ld hl, .xorhlfail
309         jr nz, .fail
310         
311         ; Test JP (HL)
312         ld hl, .jphl
313         jp [hl]
314         ld hl, .jphlfail
315         jr .fail
316         rst $00
317 .jphl:
318
319         ; Test JR
320         ld a, $FF
321         cp $0
322         jr nz,.jr
323         ld hl, .jrfail
324         jr .fail
325         rst $00
326 .jr:
327
328         ; Test inc16
329         ld d, $12
330         ld e, $FF
331         ld hl, .inc16fail
332         inc de
333         ld a, $13
334         cp d
335         jr nz, .fail
336         ld a, $00
337         cp e
338         jr nz, .fail
339         
340         ; Test CP.
341         ld hl, .cpfail
342         ld a, $10
343         cp $20
344         jr nc,.fail
345         ld a, $20
346         cp $10
347         jr c,.fail
348         
349         ; Test CPL
350         ld hl, .cplfail
351         ld a, $55
352         cpl
353         cp $AA
354         jr nz,.fail
355
356         ; Test DI/EI delay
357         di
358         ld hl, .dinocausefail
359         ld c, $0F       ; First, wait until an interrupt happens...
360 .wait:  ld a, [c]
361         and $04
362         cp 0
363         jr z, .wait
364         ei              ; Now make sure that an IRQ didn't happen on EI/DI
365         di
366         ld a, [c]
367         and $04
368         cp 0
369         jr z, .fail
370         ld hl, .dicausefail
371         ei              ; Make sure that an IRQ does happen on EI/NOP/DI
372         nop
373         nop
374         di
375         ld a, [c]
376         and $04
377         cp 0
378         jr nz, .fail
379         ei
380         
381         ld hl, .ok
382         call puts
383         ret
384 .fail:
385         ei
386         call puts
387         ld hl, .testfailed
388         call puts
389         ret
390 .insnteststr:
391         db "Testing instructions... ",0
392 .pushpopfail:
393         db "PUSH/POP",0
394 .ff:
395         db $FF
396 .xorhlfail:
397         db "XOR [HL]",0
398 .jphlfail:
399         db "JP [HL]",0
400 .jrfail:
401         db "JR",0
402 .cpfail:
403         db "CP",0
404 .cplfail:
405         db "CPL",0
406 .inc16fail:
407         db "INC16",0
408 .dinocausefail:
409         db "DI/EI does not cause interrupt",0
410 .dicausefail:
411         db "DI/NOP/EI cause interrupt",0
412 .testfailed:
413         db " test failed.",$0D,$0A,0
414 .ok:
415         db "OK!",$0D,$0A,0
416
417 ; Serial port manipulation functions.
418 putc:
419         ld c, $50
420         push af
421 .waitport:
422         ld a,[c]
423         cp $00
424         jr nz,.waitport
425         pop af
426         ld [c],a
427         ret
428
429 puts:
430         ld a, [hli]
431         cp $00
432         ret z
433         call putc
434         jr puts
435
This page took 0.040039 seconds and 4 git commands to generate.