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