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