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