If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!

Notes:Tom & Jerry (SNES)

From The Cutting Room Floor
Jump to navigation Jump to search

This page contains notes for the game Tom & Jerry (SNES).

Addresses are for the USA game unless noted.

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 buttons 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 Riedel Software Productions (RSP) developed SNES titles:

Cheat Table

The stored 32-bit cheat values are located starting at ROM offset $00954B / SNES address $81954B:

addr.  value
00954B 00003D02
00954F 0000BDD4
009553 0000BFDC
009557 00008B4B
00955B 0000F153
00955F 0000F987
009563 00006342

None of the cheats use the upper 16 bits.

Cheat Input and Comparison

$81/D735 89 10 00    BIT #$0010              //R button
$81/D738 F0 30       BEQ $30    [$D76A]      //branch to to $D76A if R not pressed
cheat comparison mode
$81/D73A A2 00 00    LDX #$0000              //start of cheat table
$81/D73D BF 90 94 81 LDA $81954B,x
$81/D741 1F 92 94 81 ORA $81954D,x
$81/D745 F0 5D       BEQ $5D    [$D7A4]      //branch to $D7A4 if reached the end of the cheat table
$81/D747 BF 90 94 81 LDA $81954B,x
$81/D74B CD 58 09    CMP $0A08  [$81:0A08]   //compare against upper 16 bits of player input
$81/D74E D0 14       BNE $14    [$D764]      //branch to $D764 if not a match
$81/D750 BF 92 94 81 LDA $81954D,x
$81/D754 CD 5A 09    CMP $0A0A  [$81:0A0A]   //compare against lower 16 bits of player input
$81/D757 D0 0B       BNE $0B    [$D764]      //branch to $D764 if not a match
successful cheat entry
$81/D759 9C 58 09    STZ $0A08  [$81:0A08]   //reset player input upper 16 bits
$81/D75C 9C 5A 09    STZ $0A0A  [$81:0A0A]   //reset player input lower 16 bits
$81/D75F 8A          TXA                     
$81/D760 4A          LSR A
$81/D761 4A          LSR A                   //accumulator now holds index value of cheat to award bonus
$81/D762 80 49       BRA $49    [$D7AD]      //exit
player input didn't match the stored value, increment to the next one
$81/D764 E8          INX
$81/D765 E8          INX
$81/D766 E8          INX
$81/D767 E8          INX
$81/D768 80 D3       BRA $D3    [$D73D]      //loop and check if player input matches the next stored value
check button presses
$81/D76A 89 80 00    BIT #$0080              //A button
$81/D76D F0 05       BEQ $05    [$D774]      //branch to $D774 if A not pressed
$81/D76F A9 00 00    LDA #$0000
$81/D772 80 1C       BRA $1C    [$D790]      //branch to calculation
$81/D774 89 00 80    BIT #$8000              //B button
$81/D777 F0 05       BEQ $05    [$D77E]      //branch to $D77E if B not pressed
$81/D779 A9 01 00    LDA #$0001
$81/D77C 80 12       BRA $12    [$D790]      //branch to calculation
$81/D77E 89 40 00    BIT #$0040              //X button
$81/D781 F0 05       BEQ $05    [$D788]      //branch to $D788 if X not pressed
$81/D783 A9 02 00    LDA #$0002
$81/D786 80 08       BRA $08    [$D790]      //branch to calculation
$81/D788 89 00 40    BIT #$4000              //Y button
$81/D78B F0 17       BEQ $17    [$D7A4]      //branch to $D7A4 if Y not pressed
$81/D78D A9 03 00    LDA #$0003
calculation
$81/D790 0E 5A 09    ASL $0A0A  [$81:0A0A]   //x2
$81/D793 2E 58 09    ROL $0A08  [$81:0A08]
$81/D796 0E 5A 09    ASL $0A0A  [$81:0A0A]   //x2
$81/D799 2E 58 09    ROL $0A08  [$81:0A08]
$81/D79C 0D 5A 09    ORA $0A0A  [$81:0A0A]   //ORA #$0000 if A pressed, #$0001 for B, #$0002 for X, #$0003 for Y
$81/D79F 8D 5A 09    STA $0A0A  [$81:0A0A]
$81/D7A2 80 06       BRA $06    [$D7AA]
failed cheat entry
$81/D7A4 9C 58 09    STZ $0A08  [$81:0A08]   //reset player input upper 16 bits
$81/D7A7 9C 5A 09    STZ $0A0A  [$81:0A0A]   //reset player input lower 16 bits
unfinished cheat entry
$81/D7AA A9 FF FF    LDA #$FFFF
exit
$81/D7AD FA          PLX
$81/D7AE FA          PLX
$81/D7AF C9 00 00    CMP #$0000
$81/D7B2 6B          RTL

Example Cheat

Here is an example of the first cheat: X, A, Y, Y, B, R. As this cheat doesn't use the upper 16-bits, the operations involving 7E0A08 can be ignored.

X
$81/D790 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0000
$81/D793 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D796 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0000
$81/D799 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D79C 0D 0A 0A    ORA $0A0A  [$81:0A0A]   //accumulator = 0002
$81/D79F 8D 0A 0A    STA $0A0A  [$81:0A0A]   //current total: 7E0A0A = 0002
$81/D7A2 80 06       BRA $06    [$D7AA]

A
$81/D790 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0004
$81/D793 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D796 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0008
$81/D799 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D79C 0D 0A 0A    ORA $0A0A  [$81:0A0A]   //accumulator = 0000
$81/D79F 8D 0A 0A    STA $0A0A  [$81:0A0A]   //current total: 7E0A0A = 0008
$81/D7A2 80 06       BRA $06    [$D7AA]

Y
$81/D790 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0010
$81/D793 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D796 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0020
$81/D799 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D79C 0D 0A 0A    ORA $0A0A  [$81:0A0A]   //accumulator = 0003
$81/D79F 8D 0A 0A    STA $0A0A  [$81:0A0A]   //current total: 7E0A0A = 0023
$81/D7A2 80 06       BRA $06    [$D7AA]

Y
$81/D790 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 0046
$81/D793 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D796 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 008C
$81/D799 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D79C 0D 0A 0A    ORA $0A0A  [$81:0A0A]   //accumulator = 0003
$81/D79F 8D 0A 0A    STA $0A0A  [$81:0A0A]   //current total: 7E0A0A = 008F
$81/D7A2 80 06       BRA $06    [$D7AA]

B
$81/D790 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 011E
$81/D793 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D796 0E 0A 0A    ASL $0A0A  [$81:0A0A]   //7E0A0A = 023C
$81/D799 2E 08 0A    ROL $0A08  [$81:0A08]
$81/D79C 0D 0A 0A    ORA $0A0A  [$81:0A0A]   //accumulator = 0001
$81/D79F 8D 0A 0A    STA $0A0A  [$81:0A0A]   //final total: 7E0A0A = 023D (matches value stored at ROM offset 00954D - note the byte order is reversed)
$81/D7A2 80 06       BRA $06    [$D7AA]

R
press R to confirm cheat entry is finished

Alternate Example

An easier way to understand the cheat system is that it takes 2 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:

AA=0 
AX=2
AY=3
YB=D
R

The 6 most significant bits are zero, meaning the three A button presses at the beginning aren't required and allows the cheat to be shortened from A, A, A, X, A, Y, Y, B, R to X, A, Y, Y, B, R.

Award Bonus

first cheat
$80/B10A C9 00 00    CMP #$0000              //XAYYBR cheat
$80/B10D D0 0B       BNE $0B    [$B11A]      //branch to $B11A if not a match
$80/B10F A9 01 00    LDA #$0001              //stage clear
$80/B112 8D D2 14    STA $14D2  [$81:14D2]
$80/B115 8D D4 14    STA $14D4  [$81:14D4]
$80/B118 80 64       BRA $64    [$B17E]
second cheat
$80/B11A C9 01 00    CMP #$0001              //YBBAXYYBR cheat
$80/B11D D0 08       BNE $08    [$B127]      //branch to $B127 if not a match
$80/B11F A9 63 00    LDA #$0063              //99
$80/B122 9D FC 14    STA $14FC,x[$81:14FC]   //lives
$80/B125 80 57       BRA $57    [$B17E]
third cheat
$80/B127 C9 02 00    CMP #$0002              //YBYAXYYYR cheat
$80/B12A D0 13       BNE $13    [$B13F]      //branch to $B13F if not a match
$80/B12C A9 63 00    LDA #$0063              //99 hearts
$80/B12F 8D 42 12    STA $1242  [$81:1242]   //hearts
$80/B132 BD 5E 15    LDA $155E,x[$81:155E]
$80/B135 F0 47       BEQ $47    [$B17E]
$80/B137 A9 63 00    LDA #$0063              //99
$80/B13A 9D 5E 15    STA $155E,x[$81:155E]   //marbles
$80/B13D 80 3F       BRA $3F    [$B17E]
fourth cheat
$80/B13F C9 03 00    CMP #$0003              //BAXYXAXYR cheat
$80/B142 D0 08       BNE $08    [$B14C]      //branch to $B14C if not a match
$80/B144 A9 01 00    LDA #$0001
$80/B147 8D EC 14    STA $14EC  [$81:14EC]   //activate infinite mid-air jumps
$80/B14A 80 32       BRA $32    [$B17E]
$80/B14C 80 2D       BRA $2D    [$B17B]      //branches over the remaining cheats! use Pro Action Replay code 80B14D00 or Game Genie code DD80-170D to set branch distance to #$00
sixth cheat (notice there's no CMP #$0004 for the fifth cheat...)
$80/B14E C9 05 00    CMP #$0005              //XABYYYXBR cheat
$80/B151 D0 15       BNE $15    [$B168]      //branch to $B168 if not a match
$80/B153 BD 58 15    LDA $1558,x[$81:1558]   //cheese bits
$80/B156 3A          DEC A
$80/B157 3A          DEC A
$80/B158 8D DE 14    STA $14DE  [$81:14DE]
$80/B15B 29 01 00    AND #$0001
$80/B15E 0A          ASL A
$80/B15F AA          TAX
$80/B160 AD DE 14    LDA $14DE  [$81:14DE]
$80/B163 9D 00 15    STA $1500,x[$81:1500]
$80/B166 80 A7       BRA $A7    [$B10F]      //branch to $B10F cheat (stage clear)
seventh cheat
$80/B168 C9 06 00    CMP #$0006              //BAAXBXAYR cheat
$80/B16B D0 0E       BNE $0E    [$B17B]      //branch to $B17B if not a match
$80/B16D A9 63 00    LDA #$0063              //99
$80/B170 9D FC 14    STA $14FC,x[$81:14FC]   //lives
$80/B173 A9 01 00    LDA #$0001
$80/B176 8D EC 14    STA $14EC  [$81:14EC]   //activate infinite mid-air jumps
$80/B179 80 B1       BRA $B1    [$B12C]      //branch to $B12C cheat (99 hearts, 99 marbles)
fail
$80/B17B 18          CLC
$80/B17C 80 01       BRA $01    [$B17F]
success
$80/B17E 38          SEC
exit
$80/B17F FA          PLX
$80/B180 6B          RTL