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