This page contains notes for the game Thunder Spirits.
Configuration Mode#
Addresses correspond to the North American version.
open configuration menu
$05/91AC AF 90 03 7F LDA $7F0390[$7F:0390] //check if finished game. FFFF = no 0000 = yes
$05/91B0 D0 03 BNE $03 [$91B5]
$05/91B2 4C BD 92 JMP $92BD [$05:92BD] //yes, open expanded config mode. replace 4C BD 92 with 4C F2 91 (JMP $91F2) for debug mode
$05/91B5 20 1F 89 JSR $891F [$05:891F] //no
Pause cheat#
Addresses correspond to the North American version.
while paused...
$00/8D31 20 0D 88 JSR $880D [$00:880D]
$00/8D34 20 95 AB JSR $AB95 [$00:AB95]
$00/8D37 20 E1 B5 JSR $B5E1 [$00:B5E1]
$00/8D3A AD 69 1B LDA $1B69 [$00:1B69]
$00/8D3D 89 00 20 BIT #$2000 //check Select
$00/8D40 F0 03 BEQ $03 [$8D45]
Select button pressed
$00/8D42 EE 6D 1B INC $1B6D [$00:1B6D] //inc counter for times Select pressed
$00/8D45 89 20 00 BIT #$0020 //check L
$00/8D48 F0 08 BEQ $08 [$8D52]
L button pressed
$00/8D4A AD 6D 1B LDA $1B6D [$00:1B6D]
$00/8D4D C9 0A 00 CMP #$000A //check if Select pressed 10x
$00/8D50 F0 09 BEQ $09 [$8D5B] //if 10x, proceed to next section $8D5B
$00/8D52 AD 69 1B LDA $1B69 [$00:1B69]
$00/8D55 89 00 10 BIT #$1000 //check Start
$00/8D58 F0 D7 BEQ $D7 [$8D31]
$00/8D5A 60 RTS
second part of cheat entry
$00/8D5B 20 0D 88 JSR $880D [$00:880D]
$00/8D5E 20 95 AB JSR $AB95 [$00:AB95]
$00/8D61 20 E1 B5 JSR $B5E1 [$00:B5E1]
$00/8D64 AD 69 1B LDA $1B69 [$00:1B69]
$00/8D67 89 10 00 BIT #$0010 //check R
$00/8D6A F0 03 BEQ $03 [$8D6F]
R button pressed
$00/8D6C EE 6D 1B INC $1B6D [$00:1B6D] //inc counter for times R pressed
$00/8D6F 89 00 20 BIT #$2000 //check Select
$00/8D72 F0 08 BEQ $08 [$8D7C]
Select button pressed
$00/8D74 AD 6D 1B LDA $1B6D [$00:1B6D]
$00/8D77 C9 0C 00 CMP #$000C //Select pressed 10x + R 2x
$00/8D7A F0 09 BEQ $09 [$8D85] //if #$0C, code entry successful, proceed to $8D85
$00/8D7C AD 69 1B LDA $1B69 [$00:1B69]
$00/8D7F 89 00 10 BIT #$1000 //check Start
$00/8D82 F0 D7 BEQ $D7 [$8D5B]
$00/8D84 60 RTS
use cheat features
$00/8D85 20 0D 88 JSR $880D [$00:880D]
$00/8D88 20 95 AB JSR $AB95 [$00:AB95]
$00/8D8B 20 E1 B5 JSR $B5E1 [$00:B5E1]
$00/8D8E AD 69 1B LDA $1B69 [$00:1B69]
$00/8D91 89 80 00 BIT #$0080 //check A
$00/8D94 F0 11 BEQ $11 [$8DA7]
A button pressed - upgrade/add weapons
$00/8D96 20 F1 8D JSR $8DF1 [$00:8DF1]
$00/8D99 E2 20 SEP #$20
$00/8D9B A9 FF LDA #$FF
$00/8D9D 99 63 1B STA $1B63,y[$00:1B63]
$00/8DA0 C2 20 REP #$20
$00/8DA2 20 45 C1 JSR $C145 [$00:C145]
$00/8DA5 80 DE BRA $DE [$8D85]
$00/8DA7 89 00 80 BIT #$8000 //check B
$00/8DAA F0 14 BEQ $14 [$8DC0]
B button pressed - downgrade/remove weapons
$00/8DAC 20 F1 8D JSR $8DF1 [$00:8DF1]
$00/8DAF E2 20 SEP #$20
$00/8DB1 A9 00 LDA #$00
$00/8DB3 99 63 1B STA $1B63,y[$00:1B64]
$00/8DB6 C2 20 REP #$20
$00/8DB8 9C 61 1B STZ $1B61 [$00:1B61]
$00/8DBB 20 45 C1 JSR $C145 [$00:C145]
$00/8DBE 80 C5 BRA $C5 [$8D85]
$00/8DC0 89 40 00 BIT #$0040 //check X
$00/8DC3 F0 0B BEQ $0B [$8DD0]
X button pressed - add support guns
$00/8DC5 A9 01 00 LDA #$0001
$00/8DC8 8D 12 04 STA $0412 [$00:0412]
$00/8DCB 20 45 C1 JSR $C145 [$00:C145]
$00/8DCE 80 B5 BRA $B5 [$8D85]
$00/8DD0 89 00 40 BIT #$4000 //check Y
$00/8DD3 F0 0B BEQ $0B [$8DE0]
Y button pressed - add shield
$00/8DD5 A9 03 00 LDA #$0003
$00/8DD8 8D 14 04 STA $0414 [$00:0414]
$00/8DDB 20 45 C1 JSR $C145 [$00:C145]
$00/8DDE 80 A5 BRA $A5 [$8D85]
$00/8DE0 89 10 00 BIT #$0010 //check R
$00/8DE3 F0 03 BEQ $03 [$8DE8]
R button pressed - self-destruct
$00/8DE5 20 6C AD JSR $AD6C [$00:AD6C]
$00/8DE8 89 00 10 BIT #$1000 //check Start
$00/8DEB F0 98 BEQ $98 [$8D85]
Start button pressed
$00/8DED 9C 61 1B STZ $1B61 [$00:1B61] //related to collision?
$00/8DF0 60 RTS //exit
sub for weapons
$00/8DF1 AD 6F 1B LDA $1B6F [$00:1B6F]
$00/8DF4 1A INC A
$00/8DF5 C9 05 00 CMP #$0005
$00/8DF8 90 03 BCC $03 [$8DFD]
$00/8DFA A9 00 00 LDA #$0000
$00/8DFD 8D 6F 1B STA $1B6F [$00:1B6F]
$00/8E00 A8 TAY
$00/8E01 60 RTS
Name entry check#
|
|
To do: |
; format: ROM addr | logical addr of memory access
rep #$20 ; $28FD2
lda $7F0302,x ; $28FD4 | $7F0302 - first two initials
cmp #$4040 ; $28FD8 - " "
beq loc_28FE7 ; $28FDB - yes, see if we need to replace
cmp #$4141 ; $28FDD - "AA"
beq loc_28FE7 ; $28FE0 - yes, see if we need to replace
cmp #$4553 ; $28FE2 - "ES" (little-endian)
bne loc_29010 ; $28FE5 - no, do not replace
loc_28FE7:
lda $7F0304,x ; $28FE7 | $7F0304 - last initial
cmp #$0040 ; $28FEB - " "
beq loc_28FFA ; $28FEE - yes, replace
cmp #$0041 ; $28FF0 - "A"
beq loc_28FFA ; $28FF3 - yes, replace
cmp #$0058 ; $28FF5 - "X"
bne loc_29010 ; $28FF8 - no, do not replace
loc_28FFA:
sep #$20 ; $28FFA - switch to byte reads/writes
lda #$45 ; $28FFC - "E"
sta $7F0302,x ; $28FFE | $7F0302
lda #$4D ; $29002 - "M"
sta $7F0303,x ; $29004 | $7F0303
lda #$49 ; $29008 - "I"
sta $7F0304,x ; $2900A | $7F0304
rep #$20 ; $2900E - switch to word reads/writes
loc_29010:
andlabs's scattered notes#
$7F0000 - 'Ohda'
used for reset check
does not appear to be used by any other SNES game? no name match with any of the Thunder Force III staff
$7F0004 - $FF if 'Ohda'; $00 otherwise
sub_9CE - Toshiba EMI screen
- sub_B8000 - the actual gruntwork
sub_9DF - ending; starts after the fadeout for the final level but before the HUD is removed from the screen as well
-
sub_30003 -> loc_30107 -> sub_38000 -> loc_38005 - ending cutscene
- $381E3 is right after "was eventually extinguished." has been output
- $3823F is right after this block of text scrolls offscreen
- $3828A is right after this part of the cutscene ends, leading into the slideshow
- sub_3897E appears to be the routine that loads the slideshow image, with byte $7FFD80 choosing (zero for first, nonzero for second)
- $38391 is right before the THE END screen shows up
- verdict: seems to be nothing unused, unless I am missing extra data
00038262 4CD181 jmp loc_381D1 ; normal branch
00038265 A90100 lda #$0001 ; target 1 - NOTHING
00038268 8D901A sta $1A90
0003826B 4CDA83 jmp loc_383DA
0003826E 9C901A stz $1A90 ; target 2 - NOTHING, but controller input stops working?
00038271 4CDA83 jmp loc_383DA
00038274 A90200 lda #$0002 ; target 3 - NOTHING, but controller input stops working
00038277 8D901A sta $1A90
0003827A 4CDA83 jmp loc_383DA
0003827D 20 42 93 9C DB sub_3827D
if they all do nothing, I'll need to try subroutiune calls...
loc_383DA:
jsr sub_383DF ; $383DA
plb ; $383DD
rtl ; $383DE
sub_383DF:
; does stuff
so we want 20DF83 - and the game hangs ok final verdict: got nothing; off to the name entry code
$021A98 - level number (0..7; not sure what higher values would do)
huh? demo recording?
loc_B39:
sta $ABAD8C,x ; $B3B | $ABAD8C -> ROM $55AD8C
loc_B3D:
beq loc_B4D ; $B40
lda $1B69 ; $B42 | $1B69 -> $001B69
bit #$00 ; $B45
bpl loc_B39 ; $B47
loc_28BFD - actual start of name entry code (after following some jumps)
sub_2891F - PrintString - looks like I need to add a noreturn feature of sort, since this behaves like the PrintString in tecnosoft's MD games (pulls strings from instruction stream)
- actually here the string starts after three bytes and ends on a null byte so maybe I can do a string feature...
loc_28FC7 - start of built in name check
- loc_28FFA - loads EMI (replacement name)
- verdict - doe not appear to check any other names
00282e0: d0e4 9c14 1c20 2183 a900 00ab 6b4d 5354 ..... !.....kMST
00282f0: 0053 484f 004e 4153 0054 3a4b 0050 4950 .SHO.NAS.T:K.PIP
0028300: 0053 4d49 0045 584f 0059 4f55 0056 3132 .SMI.EXO.YOU.V12
0028310: 004e 414f 0054 4945 004b 5234 0038 3431 .NAO.TIE.KR4.841
are TIE, KR4, 841 names that do not appear?
bugs in the disassembler
rep #$20 ; $134F
lda $7F038A ; $1351 | $7F038A
bne loc_1360 ; $1355
lda #$F3 ; $1357
brk #$20 ; $1359
lda ($AC),y ; $135B | $AC + d=$00 -> $0000AC
jmp loc_A0D ; $135D
loc_1360:
lda #$00F4 ; $1360
jsr sub_2CB1 ; $1363
jmp loc_A0D ; $1367
(need to actually add environment saving/restoring)