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