e3afaa42e685f0dfbbb131de8069ca677b93913d
[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         ei
37
38         call memtest
39
40         call insntest
41
42         call waitsw
43         
44         di
45
46         jr main
47
48 signon:
49         db $0D,$0A,$1B,"[1mFPGABoy Diagnostic ROM",$1B,"[0m",$0D,$0A,0
50
51 vbl:
52 lcdc:
53         PUSH AF
54         PUSH BC
55         
56         xor a
57         ld c, $0F
58         ld [c], a
59         
60         POP BC
61         POP AF
62         
63         reti
64         
65 tmro:
66         PUSH AF
67         PUSH BC
68         PUSH DE
69         PUSH HL
70         
71         xor a
72         ld c, $0F
73         ld [c], a
74         
75         ld hl, $DF82
76         ld a, [hld]
77         cp 0
78         jr z, .noprint
79         ld a, $41       ; print A
80         call putc
81 .noprint:
82         inc [hl]
83         ld a, [hl]
84         ld c, $51
85         ld [c], a
86
87         POP HL
88         POP DE
89         POP BC
90         POP AF
91         RETI
92
93 ; Memory tester: writes h ^ l to all addresses from C000 to DF80.
94 memtest:
95         ld hl,memteststr
96         call puts
97         
98         ld hl, $C001            ; Write loop
99 .wr:
100         ld a,h
101         xor l
102         ld [hli],a
103         ld a, h
104         cp $DF
105         jr nz, .wr
106         ld a, l
107         cp $80
108         jr nz, .wr
109
110         ld hl, $C001            ; Read loop
111 .rd:
112         ld a,h
113         xor l
114         ld b,a
115         ld a, [hli]
116         cp b
117         jr nz, .memfail
118         
119         ld a, h
120         cp $DF
121         jr nz, .rd
122         ld a, l
123         cp $80
124         jr nz, .rd
125         
126         ld hl, testokstr        ; Say we're OK
127         call puts
128         ret
129 .memfail:                       ; Say we failed (sadface)
130         ; decrement hl the easy way
131         ld a,[hld]
132         push hl
133         ld hl, failatstr
134         call puts
135         pop hl
136         ld a, h
137         call puthex
138         ld a, l
139         call puthex
140         ld a, $0A
141         call putc
142         ld a, $0D
143         call putc
144         ret
145 memteststr:
146         db "Testing memory from $C000 to $DF80...",0
147 testokstr:
148         db " OK!",$0D,$0A,0
149 failatstr:
150         db " Test failed at $",0
151
152 puthex:                         ; Put two hex nibbles to the serial console.
153         push af
154         rra
155         rra
156         rra
157         rra
158         and $0F
159         add $30
160         call putc
161         pop af
162         and $0F
163         add $30
164         call putc
165         ret
166
167 ; Wait for switches to be flipped on and off again.
168 waitsw:
169         ld hl,waitswstr
170         call puts
171         
172         ld hl,$DF82
173         ld a, 1
174         ld [hl], a
175
176         ld c, $51
177         xor a
178         ld [c],a
179         
180 .loop1:
181         ld a,[c]
182         cp $0
183         jr z,.loop1
184 .loop2:
185         ld a,[c]
186         cp $0
187         jr nz,.loop2
188         ret
189
190 waitswstr:
191         db "Diagnostic ROM complete; flip switches to nonzero and then to zero to reset. Expect A.",$0D,$0A,0
192
193 ; Core instruction basic acceptance tests.
194 insntest:
195         ld hl, .insnteststr
196         call puts
197         
198         ; Test PUSH and POP.
199         ld b, $12
200         ld c, $34
201         ld d, $56
202         ld e, $78
203         push bc
204         pop de
205         ld hl, .pushpopfail
206         ld a, d
207         cp b
208         jr nz,.fail
209         ld a, e
210         cp c
211         jr nz,.fail
212         
213         ; Test ALU (HL).
214         ld hl, .ff
215         ld a, $FF
216         xor [hl]
217         ld hl, .xorhlfail
218         jr nz, .fail
219         
220         ; Test JP (HL)
221         ld hl, .jphl
222         jp [hl]
223         ld hl, .jphlfail
224         jr .fail
225         rst $00
226 .jphl:
227
228         ; Test JR
229         ld a, $FF
230         cp $0
231         jr nz,.jr
232         ld hl, .jrfail
233         jr .fail
234         rst $00
235 .jr:
236
237         ; Test inc16
238         ld d, $12
239         ld e, $FF
240         ld hl, .inc16fail
241         inc de
242         ld a, $13
243         cp d
244         jr nz, .fail
245         ld a, $00
246         cp e
247         jr nz, .fail
248         
249         ; Test CP.
250         ld hl, .cpfail
251         ld a, $10
252         cp $20
253         jr nc,.fail
254         ld a, $20
255         cp $10
256         jr c,.fail
257         
258         ; Test CPL
259         ld hl, .cplfail
260         ld a, $55
261         cpl
262         cp $AA
263         jr nz,.fail
264
265         ; Test DI/EI delay
266         di
267         ld hl, .dinocausefail
268         ld c, $0F       ; First, wait until an interrupt happens...
269 .wait:  ld a, [c]
270         and $04
271         cp 0
272         jr z, .wait
273         ei              ; Now make sure that an IRQ didn't happen on EI/DI
274         di
275         ld a, [c]
276         and $04
277         cp 0
278         jr z, .fail
279         ld hl, .dicausefail
280         ei              ; Make sure that an IRQ does happen on EI/NOP/DI
281         nop
282         nop
283         di
284         ld a, [c]
285         and $04
286         cp 0
287         jr nz, .fail
288         ei
289         
290         ld hl, .ok
291         call puts
292         ret
293 .fail:
294         ei
295         call puts
296         ld hl, .testfailed
297         call puts
298         ret
299 .insnteststr:
300         db "Testing instructions... ",0
301 .pushpopfail:
302         db "PUSH/POP",0
303 .ff:
304         db $FF
305 .xorhlfail:
306         db "XOR [HL]",0
307 .jphlfail:
308         db "JP [HL]",0
309 .jrfail:
310         db "JR",0
311 .cpfail:
312         db "CP",0
313 .cplfail:
314         db "CPL",0
315 .inc16fail:
316         db "INC16",0
317 .dinocausefail:
318         db "DI/EI does not cause interrupt",0
319 .dicausefail:
320         db "DI/NOP/EI cause interrupt",0
321 .testfailed:
322         db " test failed.",$0D,$0A,0
323 .ok:
324         db "OK!",$0D,$0A,0
325
326 ; Serial port manipulation functions.
327 putc:
328         ld c, $50
329         push af
330 .waitport:
331         ld a,[c]
332         cp $00
333         jr nz,.waitport
334         pop af
335         ld [c],a
336         ret
337
338 puts:
339         ld a, [hli]
340         cp $00
341         ret z
342         call putc
343         jr puts
344
This page took 0.028215 seconds and 2 git commands to generate.