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