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