;------------------------------- ; Space Invaders Test ROM ; Documented by Timothy Shiels ; 11/16/2007 ; www.outerworldarcade.com ;------------------------------- ;-------- ; Set-up ;-------- 0000: 00 nop ; do nothing 0001: 00 nop ; do nothing 0002: 00 nop ; do nothing 0003: AF xor a 0004: D3 03 out ($03),a ;--------------------------------------- ; First RAM test ;--------------------------------------- 0006: 0E 03 ld c,$03 ; We'll do the ram tests three times - keep track in c ;--------------------------------------- ;Store #$55 in all memory $2000 - $4000 ;--------------------------------------- 0008: 06 55 ld b,$55 000A: 21 00 20 ld hl,$2000 000D: 70 ld (hl),b 000E: 23 inc hl 000F: 7C ld a,h 0010: FE 40 cp $40 0012: C2 0D 00 jp nz,$000d ;--------------------------------------- ;Check each stored value $2000 - $4000 ;--------------------------------------- 0015: 21 00 20 ld hl,$2000 0018: 7E ld a,(hl) 0019: A8 xor b 001A: C2 90 01 jp nz,$0190 ; jump to $0190 if not what we expect 001D: 23 inc hl 001E: 7C ld a,h 001F: FE 40 cp $40 0021: C2 18 00 jp nz,$0018 ;--------------------------------------- ; Store #$AA in all memory $2000 - $4000 ;--------------------------------------- 0024: 06 AA ld b,$aa 0026: 21 00 20 ld hl,$2000 0029: 70 ld (hl),b 002A: 23 inc hl 002B: 7C ld a,h 002C: FE 40 cp $40 002E: C2 29 00 jp nz,$0029 ;--------------------------------------- ;Check each stored value $2000 - $4000 ;--------------------------------------- 0031: 21 00 20 ld hl,$2000 0034: 7E ld a,(hl) 0035: A8 xor b 0036: C2 90 01 jp nz,$0190 ; jump to $0190 if not what we expect 0039: 23 inc hl 003A: 7C ld a,h 003B: FE 40 cp $40 003D: C2 34 00 jp nz,$0034 0040: 0D dec c 0041: C2 08 00 jp nz,$0008 ; start again if not done with 3 tests ;---------------------------------------------- ; Second RAM test ; fill memory with incremental values $00 - $FF ;---------------------------------------------- 0044: 21 00 20 ld hl,$2000 0047: 06 00 ld b,$00 0049: 78 ld a,b 004A: 77 ld (hl),a 004B: 23 inc hl 004C: 04 inc b 004D: 78 ld a,b 004E: FE FF cp $ff 0050: C2 55 00 jp nz,$0055 0053: 06 00 ld b,$00 ;start back at $00 0055: 7C ld a,h 0056: FE 40 cp $40 0058: C2 49 00 jp nz,$0049 ;--------------------- ; verify each one ;--------------------- 005B: 21 00 20 ld hl,$2000 005E: 06 00 ld b,$00 0060: 7E ld a,(hl) 0061: A8 xor b 0062: C2 90 01 jp nz,$0190 ; jump to $190 if not what we were expecting 0065: 04 inc b 0066: 78 ld a,b 0067: FE FF cp $ff 0069: C2 6E 00 jp nz,$006e 006C: 06 00 ld b,$00 006E: 23 inc hl 006F: 7C ld a,h 0070: FE 40 cp $40 0072: C2 60 00 jp nz,$0060 ;--------------------------------- ;RAM tests GOOD ;Draw Port and Sounds Test Screen ;--------------------------------- 0075: 31 00 24 ld sp,$2400 ; set stack pointer to $2400 0078: CD 83 01 call $0183 ; Clear Screen -> Zero out memory $2400 - $4000 007B: 11 48 03 ld de,$0348 ; Load DE with the staring address of the character codes 007E: 21 01 25 ld hl,$2501 ; print ">OK ALL RAMS" 0081: CD 55 01 call $0155 0084: 21 01 27 ld hl,$2701 ; print ">CHECK INPORT" 0087: CD 55 01 call $0155 008A: 21 01 33 ld hl,$3301 ; print ">CHECK SOUND" 008D: CD 55 01 call $0155 0090: 21 07 2A ld hl,$2a07 0093: 0E 0F ld c,$0f 0095: 11 6F 03 ld de,$036f 0098: D5 push de 0099: CD 57 01 call $0157 ; print "PORT 1 01234567" 009C: D1 pop de 009D: 21 07 2E ld hl,$2e07 00A0: 0E 0F ld c,$0f 00A2: CD 57 01 call $0157 ; print "PORT 1 01234567" (will be port 2) 00A5: 3E 1D ld a,$1d 00A7: 21 0B 2E ld hl,$2e0b 00AA: CD 66 01 call $0166 ; print "2" FOR PORT2 ; PRINT 11 SOUNDS LABELS 00AD: 06 0B ld b,$0b ; b=$0b (11 times) 00AF: 21 0E 34 ld hl,$340e ; screen location 00B2: 11 7E 03 ld de,$037e ; text location 00B5: 0E 06 ld c,$06 00B7: C5 push bc 00B8: CD 57 01 call $0157 ; draw it on the screen 00BB: 01 FA 00 ld bc,$00fa 00BE: 09 add hl,bc 00BF: C1 pop bc 00C0: 05 dec b 00C1: C2 B5 00 jp nz,$00b5 00C4: 06 02 ld b,$02 00C6: C5 push bc 00C7: 21 0D 34 ld hl,$340d ; load HL with location on screen to draw "0" next to sound played 00CA: 22 00 20 ld ($2000),hl ; store screen location in $2000 ;--------------------------- ; Sound Test ; Port 3 ; A = (01) 21 = UFO.F Sound ; A = (02) 22 = MISSL Sound ; A = (04) 24 = LAU.H Sound ; A = (08) 28 = INV.H Sound ; A = (10) 30 = EXTRA Sound ;---------------------------- 00CD: 3E 01 ld a,$01 ; A = sound to play 00CF: F5 push af 00D0: F6 20 or $20 00D2: D3 03 out ($03),a ; play the sound 00D4: CD 05 01 call $0105 ; draw "O" and update port info for awhile 00D7: 3E 20 ld a,$20 00D9: D3 03 out ($03),a ; quit playing the sound 00DB: CD 10 01 call $0110 ; clear "O" and update port info for awhile 00DE: F1 pop af 00DF: 07 rlca 00E0: FE 20 cp $20 00E2: C2 CF 00 jp nz,$00cf ;--------------------------- ; Sound Test ; Port 5 ; A = 01 = Invader 1 Sound ; A = 02 = Invader 2 Sound ; A = 04 = Invader 3 Sound ; A = 08 = Invader 4 Sound ; A = 10 = UFO.H Sound ; A = 20 = VID.R Sound ;---------------------------- 00E5: 3E 01 ld a,$01 ; A = sound to play 00E7: F5 push af 00E8: D3 05 out ($05),a ; play the sound 00EA: CD 05 01 call $0105 ; draw "O" and update port info for awhile 00ED: AF xor a 00EE: D3 05 out ($05),a ; quit playing the sound 00F0: CD 10 01 call $0110 ; clear "O" and update port info for awhile 00F3: F1 pop af 00F4: 07 rlca 00F5: FE 40 cp $40 00F7: C2 E7 00 jp nz,$00e7 00FA: C1 pop bc 00FB: 05 dec b 00FC: C2 C6 00 jp nz,$00c6 ; no more sounds - just update port info forever 00FF: CD 29 01 call $0129 ; update the port info 0102: C3 FF 00 jp $00ff ; do it again forever 0105: 2A 00 20 ld hl,($2000) ; load HL with screen loaction to draw "O" 0108: 3E 0F ld a,$0f ; load A with character "O" 010A: CD 66 01 call $0166 ; draw the "O" 010D: C3 1F 01 jp $011f 0110: CD 1F 01 call $011f 0113: 2A 00 20 ld hl,($2000) ; load HL with screen loaction to draw " " (clearing the "O") 0116: 3E 28 ld a,$28 ; load A with character " " 0118: CD 66 01 call $0166 ; draw the " " 011B: 22 00 20 ld ($2000),hl ; save HL in $2000 011E: C9 ret 011F: 3E 60 ld a,$60 ;counter do this 96 ($60) times. Pause?? 0121: CD CE 01 call $01ce ;draw status of ports to screen and output A to Port 6 0124: 3D dec a 0125: C2 21 01 jp nz,$0121 0128: C9 ret ;----------------------------- ;draw current status of ports ;----------------------------- 0129: F5 push af ;save af 012A: 21 0E 2B ld hl,$2b0e ;screen location of port 1 012D: DB 01 in a,($01) ;load A with info on port 1 012F: CD 3C 01 call $013c ;draw it on screen 0132: 21 0E 2F ld hl,$2f0e ;screen location of port 2 0135: DB 02 in a,($02) ;load A with info on port 2 0137: CD 3C 01 call $013c ;draw it on screen 013A: F1 pop af ;restore af 013B: C9 ret ;--------------------------------- ;print binary *'s for what's in A ;---------------------------------- 013C: 06 08 ld b,$08 013E: C5 push bc 013F: E5 push hl 0140: 0F rrca 0141: F5 push af 0142: 3E 28 ld a,$28 ;" " (blank) 0144: DA 49 01 jp c,$0149 0147: 3E 25 ld a,$25 ;"*" 0149: CD 66 01 call $0166 ;draw "*" or " " to screen 014C: F1 pop af 014D: E1 pop hl 014E: 23 inc hl 014F: C1 pop bc 0150: 05 dec b ;decrement counter 0151: C2 3E 01 jp nz,$013e ;if not at end of eight cycles do it again 0154: C9 ret ;------------------------------------- ; Draw a text string to screen ; INPUTS: ; C = number of characters to draw ; HL = screen location memory address ; DE = location of text characters ;------------------------------------- 0155: 0E 0D ld c,$0d ;number of characters to draw 0157: 1A ld a,(de) ;load A with character number from address in DE 0158: D5 push de ;save DE 0159: E5 push hl ;save HL 015A: CD 66 01 call $0166 ;draw character 015D: E1 pop hl ;restore HL (screen location memory address) 015E: 23 inc hl ;increment it by 1 015F: D1 pop de ;restore DE (location of text character to draw) 0160: 13 inc de ;increment it by 1 0161: 0D dec c ;decrement number of characters left to draw 0162: C2 57 01 jp nz,$0157 ;done? 0165: C9 ret ;------------------------------------- ; draw a character to the screen ;------------------------------------- 0166: 11 00 02 ld de,$0200 ;character images start at $200 0169: E5 push hl ;save memory location to draw to 016A: 6F ld l,a 016B: 26 00 ld h,$00 016D: 29 add hl,hl ;calcuate memory address of data for character to draw 016E: 29 add hl,hl 016F: 29 add hl,hl 0170: 19 add hl,de 0171: EB ex de,hl ;transfer memory address to DE 0172: E1 pop hl ;restore memory location to draw to 0173: 06 08 ld b,$08 0175: C5 push bc 0176: 1A ld a,(de) 0177: 77 ld (hl),a 0178: 13 inc de 0179: 01 20 00 ld bc,$0020 017C: 09 add hl,bc 017D: C1 pop bc 017E: 05 dec b 017F: C2 75 01 jp nz,$0175 0182: C9 ret ;--------------------------------------------- ;Clear Screen -> Zero out memory $2400 - $4000 ;--------------------------------------------- 0183: 21 00 24 ld hl,$2400 0186: 36 00 ld (hl),$00 0188: 23 inc hl 0189: 7C ld a,h 018A: FE 40 cp $40 018C: C2 86 01 jp nz,$0186 018F: C9 ret ;-------------- ;Bad RAM found ;-------------- 0190: 06 01 ld b,$01 ;B = counter for where error exists in byte 0192: 0F rrca ;rotate byte right 0193: DA 9A 01 jp c,$019a ;did we find an "ON" bit? 0196: 04 inc b ;NO- increment counter 0197: C3 92 01 jp $0192 ;try again 019A: 7D ld a,l ;YES- load L into A 019B: 21 D8 02 ld hl,$02d8 ;starting address for images of number error codes 019E: 0F rrca 019F: D2 A5 01 jp nc,$01a5 ;if bad memory location address is even number stay with numbers 01A2: 21 B8 03 ld hl,$03b8 ;starting address for images of letter error codes 01A5: 78 ld a,b ;load result from counter where error exists 01A6: 07 rlca 01A7: 07 rlca 01A8: 07 rlca 01A9: 47 ld b,a 01AA: 58 ld e,b 01AB: 16 00 ld d,$00 01AD: 19 add hl,de 01AE: EB ex de,hl ;DE= character location pointer 01AF: 06 08 ld b,$08 ;B= 8 lines 01B1: 21 11 30 ld hl,$3011 ;HL = location to draw to the screen 01B4: 1A ld a,(de) ;load A with a byte of character image 01B5: 77 ld (hl),a ;draw a line of error code image to screen 01B6: 78 ld a,b ;save B 01B7: 01 20 00 ld bc,$0020 ;next screen location is +$20 01BA: 09 add hl,bc ;add +$20 to HL 01BB: 47 ld b,a ;restore B 01BC: 13 inc de ;increment character location pointer 01BD: 05 dec b 01BE: C2 B4 01 jp nz,$01b4 ;continue to next line if B isn't zero 01C1: 06 08 ld b,$08 ;B=8 lines 01C3: 21 12 30 ld hl,$3012 ;HL = location to draw to the screen 01C6: 11 40 03 ld de,$0340 ;DE = location of " " character to draw 01C9: D3 06 out ($06),a 01CB: C3 B4 01 jp $01b4 ;keep drawing blank character forever 01CE: CD 29 01 call $0129 ;draw current state of ports 01D1: D3 06 out ($06),a 01D3: C9 ret 01D4: FF rst $38 ;BLANK SPACE 01D5: FF rst $38 01D6: FF rst $38 01D7: FF rst $38 01D8: FF rst $38 01D9: FF rst $38 01DA: FF rst $38 01DB: FF rst $38 01DC: FF rst $38 01DD: FF rst $38 01DE: FF rst $38 01DF: FF rst $38 01E0: FF rst $38 01E1: FF rst $38 01E2: FF rst $38 01E3: FF rst $38 01E4: FF rst $38 01E5: FF rst $38 01E6: FF rst $38 01E7: FF rst $38 01E8: FF rst $38 01E9: FF rst $38 01EA: FF rst $38 01EB: FF rst $38 01EC: FF rst $38 01ED: FF rst $38 01EE: FF rst $38 01EF: FF rst $38 01F0: FF rst $38 01F1: FF rst $38 01F2: FF rst $38 01F3: FF rst $38 01F4: FF rst $38 01F5: FF rst $38 01F6: FF rst $38 01F7: FF rst $38 01F8: FF rst $38 01F9: FF rst $38 01FA: FF rst $38 01FB: FF rst $38 01FC: FF rst $38 01FD: FF rst $38 01FE: FF rst $38 01FF: FF rst $38 ; CHARACTER IMAGES 0200: 00 70 88 A8 E8 68 08 F0 ;"@" ($00) 0208: 00 20 50 88 88 F8 88 88 ;"A" ($01) 0210: 00 78 88 88 78 88 88 78 ;"B" ($02) 0218: 00 70 88 08 08 08 88 70 ;"C" ($03) 0220: 00 78 88 88 88 88 88 78 ;"D" ($04) 0228: 00 F8 08 08 78 08 08 F8 ;"E" ($05) 0230: 00 F8 08 08 78 08 08 08 ;"F" ($06) 0238: 00 F0 08 08 08 C8 88 F0 ;"G" ($07) 0240: 00 88 88 88 F8 88 88 88 ;"H" ($08) 0248: 00 70 20 20 20 20 20 70 ;"I" ($09) 0250: 00 80 80 80 80 80 88 70 ;"J" ($0a) 0258: 00 88 48 28 18 28 48 88 ;"K" ($0b) 0260: 00 08 08 08 08 08 08 F8 ;"L" ($0c) 0268: 00 88 D8 A8 A8 88 88 88 ;"M" ($0d) 0270: 00 88 88 98 A8 C8 88 88 ;"N" ($0e) 0278: 00 70 88 88 88 88 88 70 ;"O" ($0f) 0280: 00 78 88 88 78 08 08 08 ;"P" ($10) 0288: 00 70 88 88 88 A8 48 B0 ;"Q" ($11) 0290: 00 78 88 88 78 28 48 88 ;"R" ($12) 0298: 00 70 88 08 70 80 88 70 ;"S" ($13) 02A0: 00 F8 20 20 20 20 20 20 ;"T" ($14) 02A8: 00 88 88 88 88 88 88 70 ;"U" ($15) 02B0: 00 88 88 88 88 88 50 20 ;"V" ($16) 02B8: 00 88 88 88 A8 A8 D8 88 ;"W" ($17) 02C0: 00 88 88 50 20 50 88 88 ;"X" ($18) 02C8: 00 88 88 50 20 20 20 20 ;"Y" ($19) 02D0: 00 F8 80 40 20 10 08 F8 ;"Z" ($1a) 02D8: 00 70 88 C8 A8 98 88 70 ;"0" ($1b) 02E0: 00 20 30 20 20 20 20 70 ;"1" ($1c) 02E8: 00 70 88 80 60 10 08 F8 ;"2" ($1d) 02F0: 00 F8 80 40 60 80 88 70 ;"3" ($1e) 02F8: 00 40 60 50 48 F8 40 40 ;"4" ($1f) 0300: 00 F8 08 78 80 80 88 70 ;"5" ($20) 0308: 00 E0 10 08 78 88 88 70 ;"6" ($21) 0310: 00 F8 80 40 20 10 10 10 ;"7" ($22) 0318: 00 70 88 88 70 88 88 70 ;"8" ($23) 0320: 00 70 88 88 F0 80 40 38 ;"9" ($24) 0328: 00 20 A8 70 20 70 A8 20 ;"*" ($25) 0330: 00 10 20 40 80 40 20 10 ;>" ($26) 0338: 00 00 00 00 00 00 00 20 ;"." ($27) 0340: 00 00 00 00 00 00 00 00 ;" " ($28) ; TEXT STRINGS 0348: 26 0F 0B 28 01 0C 0C 28 12 01 0D 13 28 ; ">OK ALL RAMS " 0355: 26 03 08 05 03 0b 28 09 0E 10 0F 12 14 ; ">CHECK INPORT" 0362: 26 03 08 05 03 0B 28 13 0F 15 0E 04 28 ; ">CHECK SOUND " 036F: 10 0F 12 14 1C 28 28 1B 1C 1D 1E 1F 20 21 22 ; "PORT1 01234567" 037e: 25 15 06 0F 27 06 ; "*UFO.F" 0384: 25 0D 09 13 13 0C ; "*MISSL" 038A: 25 0C 01 15 27 08 ; "*LAU.H" 0390: 25 09 0E 16 27 08 ; "*INV.H" 0396: 25 05 18 14 12 01 ; "*EXTRA" 039C: 25 09 0E 16 27 1C ; "*INV.1" 03A2: 25 09 0E 16 27 1D ; "*INV.2" 03A8: 25 09 0E 16 27 1E ; "*INV.3" 03AE: 25 09 0E 16 27 1F ; "*INV.4" 03B4: 25 15 06 0F 27 08 ; "*UFO.H" 03BA: 25 16 09 04 27 12 ; "*VID.R" ; CHARACTER IMAGES USED BY BAD RAM ROUTINE 03C0: 20 50 88 88 F8 88 88 00 ;"A" 03C8: 78 88 88 78 88 88 78 00 ;"B" 03D0: 70 88 08 08 08 88 70 00 ;"C" 03D8: 70 90 90 90 90 90 70 00 ;"D" 03E0: E0 20 20 E0 20 20 E0 00 ;"E" 03E8: 3E 02 02 1E 02 02 02 00 ;"F" 03F0: 3C 02 02 02 32 22 3C 00 ;"G" 03F8: 22 22 22 3E 22 22 22 00 ;"H"