Notes:Steven Seagal is The Final Option
This page contains notes for the game Steven Seagal is The Final Option.
Contents
RAM Addresses
7E0A71 cheat input upper 16 bits 7E0A73 cheat input lower 16 bits 7E128A Options: Continues range 0-5 ($00-05) 7E128C Options: Lives range 1-5 ($01-05) 7E1290 Options: 2 players: normal = 00, share = 01, team = 02 7E1292 Options: Difficulty: easy = 00, normal = 01, hard = 02 7E2194 Options: P1 Skill range 0-5, 2 is default ($00-05) 7E1296 Options: P2 Skill range 0-5, 2 is default ($00-05) 7E129A P1 continues 7E129C P2 continues 7E12A4 infinite lives cheat enabled 0001 = yes 7E12A6 1 hit kills cheat enabled 0001 = yes 7E12A8 P1 lives 7E12AA P2 lives 7E1CC8 P1 ??? 7E1CCA P2 ??? 7E1CCC P1 ammo (R button) 7E1CCE P2 ammo (R button) 7E1CD2 P1 knives (L button) 7E1CD4 P2 knives (L button) 7E1CEC collision box enabled 0001 = yes
Button Codes
Instead of having stored patterns of controller button presses to compare player input against, this game looks for specific 32-bit values. Pressing A, B, X, or Y on the controller loads different numbers, and with the correct combination the player input will match the stored value.
This cheat system is used in five SNES titles developed by Riedel: this, Beethoven: The Ultimate Canine Caper, Bobby's World, The Hunt for Red October, and Tom & Jerry.
Cheat Table
The stored 32-bit cheat values are located starting at ROM offset $019194 / SNES address $839194:
addr. value 019194 0000DC00 019198 0000B600 01919C 00008F00 0191A0 00009C00 0191A4 00007900 0191A8 00004700
None of the cheats use the upper 24 bits.
Cheat Input and Comparison
... $81/9570 BF 94 91 83 LDA $839194,x $81/9574 1F 96 91 83 ORA $839196,x $81/9578 F0 5D BEQ $5D [$95D7] //branch to $95D7 if reached the end of the cheat table $81/957A BF 94 91 83 LDA $839194,x $81/957E CD 71 0A CMP $0A71 [$83:0A71] //compare against upper 16 bits of player input $81/9581 D0 14 BNE $14 [$9597] //branch to $9597 if not a match $81/9583 BF 96 91 83 LDA $839196,x $81/9587 CD 73 0A CMP $0A73 [$83:0A73] //compare against lower 16 bits of player input $81/958A D0 0B BNE $0B [$9597] //branch to $9597 if not a match successful cheat entry $81/958C 9C 71 0A STZ $0A71 [$83:0A71] //reset player input upper 16 bits $81/958F 9C 73 0A STZ $0A73 [$83:0A73] //reset player input lower 16 bits $81/9592 8A TXA $81/9593 4A LSR A $81/9594 4A LSR A //accumulator now holds index value of cheat to award bonus $81/9595 80 49 BRA $49 [$95E0] //exit player input didn't match the stored value, increment to the next one $81/9597 E8 INX $81/9598 E8 INX $81/9599 E8 INX $81/959A E8 INX $81/959B 80 D3 BRA $D3 [$9570] //loop and check if player input matches the next stored value check button presses $81/959D 89 80 00 BIT #$0080 //A button $81/95A0 F0 05 BEQ $05 [$95A7] //branch to $95A7 if A not pressed $81/95A2 A9 00 00 LDA #$0000 $81/95A5 80 1C BRA $1C [$95C3] $81/95A7 89 00 80 BIT #$8000 //B button $81/95AA F0 05 BEQ $05 [$95B1] //branch to $95B1 if B not pressed $81/95AC A9 01 00 LDA #$0001 $81/95AF 80 12 BRA $12 [$95C3] $81/95B1 89 40 00 BIT #$0040 //X button $81/95B4 F0 05 BEQ $05 [$95BB] //branch to $95BB if X not pressed $81/95B6 A9 02 00 LDA #$0002 $81/95B9 80 08 BRA $08 [$95C3] $81/95BB 89 00 40 BIT #$4000 //Y button $81/95BE F0 17 BEQ $17 [$95D7] //branch to $95D7 if Y not pressed $81/95C0 A9 03 00 LDA #$0003 calculation $81/95C3 0E 73 0A ASL $0A73 [$83:0A73] //x2 $81/95C6 2E 71 0A ROL $0A71 [$83:0A71] $81/95C9 0E 73 0A ASL $0A73 [$83:0A73] //x2 $81/95CC 2E 71 0A ROL $0A71 [$83:0A71] $81/95CF 0D 73 0A ORA $0A73 [$83:0A73] //ORA #$0000 if A pressed, #$0001 for B, #$0002 for X, #$0003 for Y $81/95D2 8D 73 0A STA $0A73 [$83:0A73] $81/95D5 80 06 BRA $06 [$95DD] failed cheat entry $81/95D7 9C 71 0A STZ $0A71 [$83:0A71] //reset player input upper 16 bits $81/95DA 9C 73 0A STZ $0A73 [$83:0A73] //reset player input lower 16 bits unfinished cheat entry $81/95DD A9 FF FF LDA #$FFFF exit $81/95E0 FA PLX $81/95E1 C9 00 00 CMP #$0000 $81/95E4 6B RTL
Example Cheat
Here is an example of the first cheat: Y, B, Y, A, R. As this cheat doesn't use the upper 16-bits, the operations involving 7E0A71 can be ignored.
Y $81/95C3 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 0000 $81/95C6 2E 71 0A ROL $0A71 [$83:0A71] $81/95C9 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 0000 $81/95CC 2E 71 0A ROL $0A71 [$83:0A71] $81/95CF 0D 73 0A ORA $0A73 [$83:0A73] //accumulator = 0003 $81/95D2 8D 73 0A STA $0A73 [$83:0A73] //current total: 7E0A73 = 0003 $81/95D5 80 06 BRA $06 [$95DD] B $81/95C3 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 0006 $81/95C6 2E 71 0A ROL $0A71 [$83:0A71] $81/95C9 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 000C $81/95CC 2E 71 0A ROL $0A71 [$83:0A71] $81/95CF 0D 73 0A ORA $0A73 [$83:0A73] //accumulator = 0001 $81/95D2 8D 73 0A STA $0A73 [$83:0A73] //current total: 7E0A73 = 000D $81/95D5 80 06 BRA $06 [$95DD] Y $81/95C3 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 001A $81/95C6 2E 71 0A ROL $0A71 [$83:0A71] $81/95C9 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 0034 $81/95CC 2E 71 0A ROL $0A71 [$83:0A71] $81/95CF 0D 73 0A ORA $0A73 [$83:0A73] //accumulator = 0003 $81/95D2 8D 73 0A STA $0A73 [$83:0A73] //current total: 7E0A73 = 0037 $81/95D5 80 06 BRA $06 [$95DD] A $81/95C3 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 006E $81/95C6 2E 71 0A ROL $0A71 [$83:0A71] $81/95C9 0E 73 0A ASL $0A73 [$83:0A73] //7E0A73 = 00DC $81/95CC 2E 71 0A ROL $0A71 [$83:0A71] $81/95CF 0D 73 0A ORA $0A73 [$83:0A73] //accumulator = 00DC $81/95D2 8D 73 0A STA $0A73 [$83:0A73] //final total: 7E0A73 = 00DC (matches value stored at ROM offset 019196 - note the byte order is reversed) $81/95D5 80 06 BRA $06 [$95DD] R press R to confirm cheat entry is finished
Alternate Example
An easier way to understand the cheat system is that it takes two button presses to produce the 16 combinations necessary to represent a single hex digit:
AA=0 AB=1 AX=2 AY=3 BA=4 BB=5 BX=6 BY=7 XA=8 XB=9 XX=A XY=B YA=C YB=D YX=E YY=F
Using the same cheat as the previous example, it would appear as follows:
YB=D YA=C R
Award Bonus
$80/BAD7 10 03 BPL $03 [$BADC] //branch to $BADC if successful cheat entry ... first cheat $80/BADC C9 00 00 CMP #$0000 //YBYA cheat $80/BADF D0 0B BNE $0B [$BAEC] //branch to $BEAC if not a match $80/BAE1 A9 01 00 LDA #$0001 //stage clear $80/BAE4 8D 6C 12 STA $126C [$83:126C] $80/BAE7 8D 6E 12 STA $126E [$83:126E] $80/BAEA 80 6C BRA $6C [$BB58] second cheat $80/BAEC C9 01 00 CMP #$0001 //XYBX cheat $80/BAEF D0 08 BNE $08 [$BAF9] //branch to $BAF9 if not a match $80/BAF1 A9 01 00 LDA #$0001 //enable 1 hit kills $80/BAF4 8D A6 12 STA $12A6 [$83:12A6] $80/BAF7 80 5F BRA $5F [$BB58] third cheat $80/BAF9 C9 02 00 CMP #$0002 //XAYY cheat $80/BAFC D0 08 BNE $08 [$BB06] //branch to $BB06 if not a match $80/BAFE A9 01 00 LDA #$0001 //enable infinite lives $80/BB01 8D A4 12 STA $12A4 [$83:12A4] $80/BB04 80 52 BRA $52 [$BB58] fourth cheat $80/BB06 C9 03 00 CMP #$0003 //XBYA cheat $80/BB09 D0 1D BNE $1D [$BB28] //branch to $BB28 if not a match $80/BB0B A9 00 01 LDA #$0100 //256 $80/BB0E 8D A8 12 STA $12A8 [$83:12A8] //P1 lives $80/BB11 8D AA 12 STA $12AA [$83:12AA] //P2 lives $80/BB14 8D CC 1C STA $1CCC [$83:1CCC] //P1 ammo (R button) $80/BB17 8D CE 1C STA $1CCE [$83:1CCE] //P2 ammo (R button) $80/BB1A 8D D2 1C STA $1CD2 [$83:1CD2] //P1 knives (L button) $80/BB1D 8D D4 1C STA $1CD4 [$83:1CD4] //P2 knives (L button) $80/BB20 8D C8 1C STA $1CC8 [$83:1CC8] //P1 ??? $80/BB23 8D CA 1C STA $1CCA [$83:1CCA] //P2 ??? $80/BB26 80 30 BRA $30 [$BB58] fifth cheat $80/BB28 C9 04 00 CMP #$0004 //BYXB cheat $80/BB2B D0 0B BNE $0B [$BB38] //branch to $BB38 if not a match $80/BB2D AD EC 1C LDA $1CEC [$83:1CEC] $80/BB30 49 01 00 EOR #$0001 //toggle collision box $80/BB33 8D EC 1C STA $1CEC [$83:1CEC] $80/BB36 80 20 BRA $20 [$BB58] sixth cheat $80/BB38 C9 05 00 CMP #$0005 //BABY cheat $80/BB3B D0 18 BNE $18 [$BB55] //branch to $BB55 if not a match $80/BB3D A9 01 00 LDA #$0001 //level clear $80/BB40 8D 6C 12 STA $126C [$83:126C] $80/BB43 8D 6E 12 STA $126E [$83:126E] $80/BB46 AD 7A 12 LDA $127A [$83:127A] $80/BB49 AA TAX $80/BB4A BD F7 9F LDA $9FF7,x $80/BB4D 29 FF 00 AND #$00FF $80/BB50 8D 7C 12 STA $127C [$83:127C] $80/BB53 80 03 BRA $03 [$BB58] fail $80/BB55 18 CLC $80/BB56 80 01 BRA $01 [$BB59] success $80/BB58 38 SEC $80/BB59 FA PLX $80/BB5A 6B RTL
Infinite Lives Cheat Check
Executes when defeated.
... $80/D228 AD A4 12 LDA $12A4 [$83:12A4] //infinite lives cheat flag $80/D22B D0 07 BNE $07 [$D234] //branch to $D234 if enabled $80/D22D B9 A8 12 LDA $12A8,y[$83:12A8] $80/D230 3A DEC A //lives -1 $80/D231 99 A8 12 STA $12A8,y[$83:12A8] $80/D234 AD 86 12 LDA $1286 [$83:1286] ...
Start Status
... initial start status $80/B499 AD 8C 12 LDA $128C [$83:128C] //lives (set in Options) $80/B49C 8D A8 12 STA $12A8 [$83:12A8] //P1 lives $80/B49F 8D AA 12 STA $12AA [$83:12AA] //P2 lives $80/B4A2 AD 8A 12 LDA $128A [$83:128A] //continues (set in Options) $80/B4A5 8D 9A 12 STA $129A [$83:129A] //P1 continues $80/B4A8 8D 9C 12 STA $129C [$83:129C] //P2 continues $80/B4AB 9C C8 1C STZ $1CC8 [$83:1CC8] //zero P1 ??? $80/B4AE 9C CC 1C STZ $1CCC [$83:1CCC] //zero P1 ammo (R button) $80/B4B1 9C D2 1C STZ $1CD2 [$83:1CD2] //zero P1 knives (L button) $80/B4B4 9C CA 1C STZ $1CCA [$83:1CCA] //zero P2 ??? $80/B4B7 9C CE 1C STZ $1CCE [$83:1CCE] //zero P2 ammo (R button) $80/B4BA 9C D4 1C STZ $1CD4 [$83:1CD4] //zero P2 knives (L button) demo mode start status sets 256 for all stats $80/B4BD A9 00 01 LDA #$0100 //256 $80/B4C0 8D A8 12 STA $12A8 [$83:12A8] //P1 lives $80/B4C3 8D AA 12 STA $12AA [$83:12AA] //P2 lives $80/B4C6 8D CC 1C STA $1CCC [$83:1CCC] //P1 ammo (R button) $80/B4C9 8D CE 1C STA $1CCE [$83:1CCE] //P2 ammo (R button) $80/B4CC 8D D2 1C STA $1CD2 [$83:1CD2] //P1 knives (L button) $80/B4CF 8D D4 1C STA $1CD4 [$83:1CD4] //P2 knives (L button) $80/B4D2 8D C8 1C STA $1CC8 [$83:1CC8] //P1 ??? $80/B4D5 8D CA 1C STA $1CCA [$83:1CCA] //P2 ??? ...