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