SECTION "a",HOME
+
main:
- ld c, $51
+ ld c, $51 ; Note that we are alive.
ld a, $FF
ld [c],a
- ld sp,$DFFF
+
+ ld sp, $DFFF
- ld hl,text
+ ld hl, signon
call puts
+
+ ld c, $07
+ ld a, $04 ;start timer, 4.096KHz
+ ld [c], a
+ ei
call memtest
+
+ call insntest
+
call waitsw
- jp main
+ di
-text:
+ jr main
+
+ section "fuq",HOME[$100]
+irqhand:
+ PUSH AF
+ PUSH BC
+ PUSH DE
+ PUSH HL
+ xor a
+ ld c, $0F ; ack the irq
+ ld [c], a
+ ld a, $41 ; print A
+ call putc
+ POP HL
+ POP DE
+ POP BC
+ POP AF
+ RETI
+
+signon:
db $0D,$0A,$1B,"[1mFPGABoy Diagnostic ROM",$1B,"[0m",$0D,$0A,0
+; Memory tester: writes h ^ l to all addresses from C000 to DF80.
memtest:
ld hl,memteststr
call puts
- ld hl, $C000
+ ld hl, $C000 ; Write loop
.wr:
ld a,h
xor l
ld [hli],a
ld a, $DF
cp h
- jp nz, .wr
+ jr nz, .wr
ld a, $80
cp l
- jp nz, .wr
+ jr nz, .wr
- ld hl, $C000
+ ld hl, $C000 ; Read loop
.rd:
ld a,h
xor l
ld b,a
ld a, [hli]
cp b
- jp nz, .memfail
+ jr nz, .memfail
ld a, $DF
cp h
- jp nz, .rd
+ jr nz, .rd
ld a, $80
cp l
- jp nz, .rd
+ jr nz, .rd
- ld hl, testokstr
+ ld hl, testokstr ; Say we're OK
call puts
ret
-.memfail:
- @ decrement hl the easy way
+.memfail: ; Say we failed (sadface)
+ ; decrement hl the easy way
ld a,[hld]
push hl
ld hl, failatstr
ld a, $0D
call putc
ret
-
memteststr:
db "Testing memory from $C000 to $DF80...",0
testokstr:
db " OK!",$0D,$0A,0
failatstr:
db " Test failed at $",0
-puthex:
+
+puthex: ; Put two hex nibbles to the serial console.
push af
rra
rra
call putc
ret
+; Wait for switches to be flipped on and off again.
waitsw:
ld hl,waitswstr
call puts
-
+
ld c, $51
- ld a, $00
+ xor a
ld [c],a
- ld c, $51
ld b, $0
.loop1:
ld a,[c]
cp b
- jp z,.loop1
+ jr z,.loop1
.loop2:
ld a,[c]
cp b
- jp nz,.loop2
+ jr nz,.loop2
ret
waitswstr:
- db "Diagnostic ROM complete; flip switches to nonzero and then to zero to reset.",$0D,$0A,0
+ db "Diagnostic ROM complete; flip switches to nonzero and then to zero to reset. Expect A.",$0D,$0A,0
+
+; Core instruction basic acceptance tests.
+insntest:
+ ld hl, .insnteststr
+ call puts
+
+ ; Test PUSH and POP.
+ ld b, $12
+ ld c, $34
+ ld d, $56
+ ld e, $78
+ push bc
+ pop de
+ ld hl, .pushpopfail
+ ld a, d
+ cp b
+ jr nz,.fail
+ ld a, e
+ cp c
+ jr nz,.fail
+
+ ; Test ALU (HL).
+ ld hl, .ff
+ ld a, $FF
+ xor [hl]
+ ld hl, .xorhlfail
+ jr nz, .fail
+
+ ; Test JP (HL)
+ ld hl, .jphl
+ jp [hl]
+ ld hl, .jphlfail
+ jr .fail
+ rst $00
+.jphl:
+
+ ; Test JR
+ ld a, $FF
+ ld b, $00
+ cp b
+ jr nz,.jr
+ ld hl, .jrfail
+ jr .fail
+ rst $00
+.jr:
+ ; Test inc16
+ ld d, $12
+ ld e, $FF
+ ld hl, .inc16fail
+ inc de
+ ld a, $13
+ cp d
+ jr nz, .fail
+ ld a, $00
+ cp e
+ jr nz, .fail
+
+ ; Test CP.
+ ld hl, .cpfail
+ ld a, $10
+ ld b, $20
+ cp b
+ jr nc,.fail
+ ld a, $20
+ ld b, $10
+ cp b
+ jr c,.fail
+
+ ; Test CPL
+ ld hl, .cplfail
+ ld a, $55
+ ld b, $AA
+ cpl
+ cp b
+ jr nz,.fail
+
+ ld hl, .ok
+ call puts
+ ret
+.fail:
+ call puts
+ ld hl, .testfailed
+ call puts
+ ret
+.insnteststr:
+ db "Testing instructions... ",0
+.pushpopfail:
+ db "PUSH/POP",0
+.ff:
+ db $FF
+.xorhlfail:
+ db "XOR [HL]",0
+.jphlfail:
+ db "JP [HL]",0
+.jrfail:
+ db "JR",0
+.cpfail:
+ db "CP",0
+.cplfail:
+ db "CPL",0
+.inc16fail:
+ db "INC16",0
+.testfailed:
+ db " test failed.",$0D,$0A,0
+.ok:
+ db "OK!",$0D,$0A,0
+
+; Serial port manipulation functions.
putc:
- push af
ld b, 0
ld c, $50
+ push af
.waitport:
ld a,[c]
cp b
- jp nz,.waitport
+ jr nz,.waitport
pop af
ld [c],a
ret
ld a, [hli]
ld b, $00
cp b
- jp z, .done
+ jr z, .done
call putc
- jp puts
+ jr puts
.done:
ret
-