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