News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: NBA Jam TE (SNES) ASM Tidbits  (Read 581 times)

eskayelle

  • Jr. Member
  • **
  • Posts: 17
    • View Profile
NBA Jam TE (SNES) ASM Tidbits
« on: June 13, 2018, 03:38:58 pm »
I wanted to throw this onto the forum in case there are some folks out there pondering an annual update to NBA Jam TE but looking for more data before digging in.  With a big shout-out to phonymike for all his guidance to date regarding ASM, team values, etc., I provide below some assembly code that should mimic the current order of teams in Jam TE, such that a hacker could modify it, re-assemble, and effectively re-sort the 27 teams (such as based on current year standings, if that were the intent).

Code: [Select]
lorom

org $CCFDB2
dw #$0007 ;Mavs
dw #$000A ;T-Wolves
dw #$0015 ;Heat
dw #$001A ;Bullets
dw #$0019 ;76ers
dw #$0006 ;Kings
dw #$0008 ;Nuggets
dw #$0013 ;Bucks
dw #$0012 ;Indiana
dw #$000D ;Atlanta
dw #$0001 ;Clippers
dw #$0018 ;Magic
dw #$0011 ;Pistons
dw #$0000 ;Warriors
dw #$0014 ;Celtics
dw #$000E ;Hornets
dw #$0002 ;Lakers
dw #$0016 ;Nets
dw #$0010 ;Cavs
dw #$000B ;Spurs
dw #$0017 ;Knicks
dw #$0004 ;Blazers
dw #$000C ;Jazz
dw #$0005 ;Sonics
dw #$0003 ;Suns
dw #$000F ;Bulls
dw #$0009 ;Rockets

Please forgive any apparent syntax errors, and hopefully it's a value to someone!

June 19, 2018, 10:33:09 am - (Auto Merged - Double Posts are not allowed before 7 days.)
For those interested in hacking NBA Jam TE, I figured I'd tack on to this thread some additional discoveries as I have them.  This portion of the ROM would allow anyone to change the maximum amount of injuries that can be accumulated in the game.

Please forgive any syntax errors, copy/paste errors (players 1 through 4 have the same 5 operations, just hitting 4 different RAM addresses) or transpositions.

Code: [Select]
lorom

;===
;NBA Jam TE
;Injury Max Disassembly
;===
org $8085E6 ;PC address $0005E6
LDA $1677 ;AD 77 16 ;Load into A the P1 injury value stored in RAM ($7E001677)
CMP #$0019 ;C9 19 00 ;Compare value in A to #$19 (25 in base 10/decimal)
BCC #$06 ;90 06 ;Branch if Carry Clear (goto a label (06?)) if injuries < #$19; otherwise...
LDA #$0019 ;A9 19 00 ;Reset A to the max injury value of #$19
STA $1677 ;8D 77 16 ;Store that max injury value into RAM
LDA $1679 ;AD 79 16 ;Load into A the P2 injury value stored in RAM ($7E001679)
CMP #$0019 ;C9 19 00 ;Compare value in A to #$19 (25 in base 10/decimal)
BCC #$06 ;90 06 ;Branch if Carry Clear (goto a label (06?)) if injuries < #$19; otherwise...
LDA #$0019 ;A9 19 00 ;Reset A to the max injury value of #$19
STA $1679 ;8D 79 16 ;Store that max injury value into RAM
LDA $167B ;AD 7B 16 ;Load into A the P3 injury value stored in RAM ($7E00167B)
CMP #$0019 ;C9 19 00 ;Compare value in A to #$19 (25 in base 10/decimal)
BCC #$06 ;90 06 ;Branch if Carry Clear (goto a label (06?)) if injuries < #$19; otherwise...
LDA #$0019 ;A9 19 00 ;Reset A to the max injury value of #$19
STA $167B ;8D 7B 16 ;Store that max injury value into RAM
LDA $167D ;AD 7D 16 ;Load into A the P4 injury value stored in RAM ($7E00167D)
CMP #$0019 ;C9 19 00 ;Compare value in A to #$19 (25 in base 10/decimal)
BCC #$06 ;90 06 ;Branch if Carry Clear (goto a label (06?)) if injuries < #$19; otherwise...
LDA #$0019 ;A9 19 00 ;Reset A to the max injury value of #$19
STA $167D ;8D 7D 16 ;Store that max injury value into RAM


3.3 [6/18 and 6/19/18 - 2.5 hrs]:
Having previously performed a cheat search in the ROM using SNES9X Geiger, and having determined that the following RAM values store injuries:
1) Player 1 = $7E1677 (SNES LOROM Address)
2) Player 2 = $7E1679
3) Player 3 = $7E167B
4) Player 4 = $7E167D
conducted a search in the hex code for a byte-swapped string "AD 77 16" (translates to LDA $1677).
Looked for a CMP, BCC, or BCS function near that code, with a value of #$19 (25 in decimal).  Located such at PC address $0005E6.
Using an opcode/hex code table from assembler.it/portale/5/65816_guide/opcode_reference.asp, translated by hand the hex codes to opcodes near that address.
(I didn't have my tools at the time...)
Based on the above, replaced 8 instances of #$19 (hex code 19; decimal 25) with #$63 (decimal 99). 
Effectively replaced the value in the compare function and the store function to increase the max injury value allowed from 25 (decimal) to 99.
Playtest was successful!

« Last Edit: June 20, 2018, 08:14:35 am by eskayelle »

eskayelle

  • Jr. Member
  • **
  • Posts: 17
    • View Profile
Re: NBA Jam TE (SNES) ASM Tidbits
« Reply #1 on: June 23, 2018, 12:47:46 pm »
Addendum to my post on changing the team order in the ROM...

While the code I cited will change the order in the attract mode screen and the game itself, it will not change the following:
1) The order of the names of the "Next Opponent" when looking at one's record.  To accomplish this, the order of the teams' strings must be changed in the ROM.  This can easily be done by doing a search on the string DALLAS in the ROM.  You'll find the 27 teams in order of play there, 0x10 bytes apiece (0x0D of them being the actual team names.)
2) After re-ordering those strings above, this will solve the "Next Opponent" dilemma, but not the "Last Opponent".  "Last Opponent" uses pointers at PC address $267DE8, original order of pointers as follows:
Code: [Select]
0D Golden State
0A L.A. Clippers
10 L.A. Lakers
18 Phoenix
15 Portland
17 Seattle
05 Sacramento
00 Dallas
06 Denver
1A Houston
01 Minnesota
13 San Antonio
16 Utah
09 Atlanta
0F Charlotte
19 Chicago
12 Cleveland
0C Detroit
08 Indiana
07 Milwaukee
0E Boston
02 Miami
11 New Jersey
14 New York
0B Orlando
04 Philadelphia
03 Washington

eskayelle

  • Jr. Member
  • **
  • Posts: 17
    • View Profile
Re: NBA Jam TE (SNES) ASM Tidbits
« Reply #2 on: July 01, 2018, 07:38:53 pm »
For those of you who may be working on (or interested in working on) NBA Jam TE, here is some information on team logos.

Pointer Table for Palettes - $067A5F - $067AD2 (PC Address Range)
Byteswap these and convert from LoRom to PC address.
Example: 6F F8 0C 00 --> $0C:F86F --> $06786F
(In the 3 columns of pointers, all $xx:xxxx references are SNES LoRom.)

Code: [Select]
6F F8 0C 00; Golden State ($0C:F86F)
52 F7 0C 00; L.A. Clippers ($0C:F752)
72 F7 0C 00; L.A. Lakers ($0C:F772)
92 F7 0C 00; Phoenix ($0C:F792)
B2 F7 0C 00; Portland ($0C:F7B2)
9F 8D 29 00; Seattle ($29:8D9F)
20 80 10 00; Sacramento ($10:8020)
40 80 10 00; Dallas ($10:8040)
00 80 0F 00; Denver ($0F:8000)
20 80 0F 00; Houston ($0F:8020)
40 80 0F 00; Minnesota ($0F:8040)
7D FF 0F 00; San Antonio ($0F:FF7D)
9D FF 0F 00; Utah ($0F:FF9D)
BD FF 0F 00; Atlanta ($0F:FFBD)
DD FF 0F 00; Charlotte ($0F:FFDD)
00 80 10 00; Chicago ($10:8000)
34 8F 29 00; Cleveland ($29:8F34)
3E 9F 2A 00; Detroit ($2A:9F3E)
5E 9F 2A 00; Indiana ($2A:9F5E)
7E 9F 2A 00; Milwaukee ($2A:9F7E)
9E 9F 2A 00; Boston ($2A:9F9E)
BE 9F 2A 00; Miami ($2A:9FBE)
DE 9F 2A 00; New Jersey ($2A:9FDE)
FE 9F 2A 00; New York ($2A:9FFE)
1E A0 2A 00; Orlando ($2A:A01E)
3E A0 2A 00; Philadelphia ($2A:A03E)
5E A0 2A 00; Washington ($2A:A05E)
7E A0 2A 00; Rookies or All-Stars ($2A:A07E)
7E A0 2A 00; Rookies or All-Stars ($2A:A07E)

The table after palette pointers is (PC address) $67AD3-$67BD3.
8 bytes apiece x 58 blocks.  4 words, including upper word and lower word pointers.
The second set of 29 ($67BBB - $67BD3) appears to be team logo pointers (the bottom part).  From $67AD3 is the first part, so to change a logo, two sets of 8 byte logo pointers and one palette pointer must be changed.

Logo Pointer Table (see below)
Byte 00 and 01 = byte-swapped lower word for logo
Byte 02 and 03 = Size of logo (matches DMA trace) in bytes
Byte 04 and 05 = byte-swapped lower word for sprite table (credit to phonymike)
Byte 06 and 07 = byte-swapped upper word (bank) for logo and sprite table

Pointer Table for First Part of Logo
Start at $67AD3 to $67BBA (first half of logo)
Example: Golden State -  35 81 is byte-swapped word for Golden State logo location- the 0F in byte 06 appears to be the bank.  Replacing this line and that for the palette pointer with the Clippers info appears to give the first section of the Clippers logo to Golden State.

Code: [Select]
35 81 E0 01 EB 80 0F 00; Golden State ($0F:8135)
37 88 E0 01 ED 87 0F 00; Clippers ($0F:8837)
67 8E E0 01 1D 8E 0F 00; Lakers ($0F:8E67)
44 93 00 02 CD 92 0F 00; Phoenix ($0F:9344)
A9 97 80 01 44 97 0F 00; Portland ($0F:97A9)
F3 9A 00 02 A9 9A 0F 00; Seattle ($0F:9AF3)
3E A2 C0 01 EB A1 0F 00; Sacramento ($0F:A23E)
1A AA 80 01 E2 A9 0F 00; Dallas ($0F:AA1A)
9A AD 00 02 1A AD 0F 00; Denver ($0F:AD9A)
E4 B1 00 02 9A B1 0F 00; Houston ($0F:E1E4)
4B B7 C0 01 0A B7 0F 00; Minnesota ($0F:B74B)
E0 BD C0 01 84 BD 0F 00; San Antonio ($0F:BDE0)
B3 C1 E0 01 60 C1 0F 00; Utah ($0F:C1B3)
BD C5 00 02 73 C5 0F 00; Atlanta ($0F:C5BD)
A4 CB 00 02 5A CB 0F 00; Charlotte ($0F:CBA4)
01 D1 00 02 9C D0 0F 00; Chicago ($0F:D101)
4B D5 E0 01 01 D5 0F 00; Cleveland ($0F:D54B)
F2 DA A0 01 A8 DA 0F 00; Detroit ($0F:DAF2)
FD E1 00 02 B3 E1 0F 00; Indiana ($0F:E1FD)
11 E8 00 02 AC E7 0F 00; Milwaukee ($0F:E811)
D3 EC E0 01 65 EC 0F 00; Boston ($0F:ECD3)
EF F0 A0 01 93 F0 0F 00; Miami ($0F:F0EF)
79 F4 00 02 2F F4 0F 00; New Jersey ($0F:F479)
20 FA 00 02 D6 F9 0F 00; New York ($0F:FA20)
2F F3 80 01 CA F2 16 00; Orlando ($16:F32F)
0A 93 00 02 C0 92 16 00; Philadelphia ($16:930A)
83 8F 40 01 54 8F 29 00; Washington ($29:8F83)
4D 92 00 02 03 92 29 00; Rookies or All-Stars ($29:924D)
4D 92 00 02 03 92 29 00; Rookies or All-Stars ($29:924D)

Pointer Table for Second Part of Logo
Start at $67BBB-$67BD3 (second half of logo)

Code: [Select]
2D 85 60 01 F5 84 0F 00; 2D 85 is byte-swapped word for Golden State logo location ($0F:852D)
1D 8C 00 01 F7 8B 0F 00; Clippers ($0F:8C1D)
4D 92 40 00 27 92 0F 00; Lakers ($0F:924D)
44 93 00 02 CD 92 0F 00; Phoenix ($0F:9344)
A9 97 80 01 44 97 0F 00; Portland ($0F:97A9)
2B 9F 60 01 F3 9E 0F 00; Seattle ($0F:9F2B)
08 A6 E0 01 BE A5 0F 00; Sacramento ($0F:A608)
1A AA 80 01 E2 A9 0F 00; Dallas ($0F:AA1A)
9A AD 00 02 1A AD 0F 00; Denver ($0F:AD9A)
0A B6 80 00 E4 B5 0F 00; Houston ($0F:B60A)
FA BA 40 01 CB BA 0F 00; Minnesota ($0F:BAFA)
E0 BD C0 01 84 BD 0F 00; San Antonio ($0F:BDE0)
B3 C1 E0 01 60 C1 0F 00; Utah ($0F:C1B3)
DA C9 C0 00 BD C9 0F 00; Atlanta ($0F:C9DA)
DC CF 60 00 A4 CF 0F 00; Charlotte ($0F:CFDC)
01 D1 00 02 9C D0 0F 00; Chicago ($0F:D101)
28 D9 C0 00 0B D9 0F 00; Cleveland ($0F:D928)
73 DE A0 01 32 DE 0F 00; Detroit ($0F:DE73)
2C E6 C0 00 FD E5 0F 00; Indiana ($0F:E62C)
25 EC 20 00 11 EC 0F 00; Milwaukee ($0F:EC25)
D3 EC E0 01 65 EC 0F 00; Boston ($0F:ECD3)
EF F0 A0 01 93 F0 0F 00; Miami ($0F:F0EF)
96 F8 A0 00 79 F8 0F 00; New Jersey ($0F:F896)
3D FE A0 00 20 FE 0F 00; New York ($0F:FE3D)
2F F3 80 01 CA F2 16 00; Orlando ($16:F32F)
30 97 80 00 0A 97 16 00; Philadelphia ($16:9730)
83 8F 40 01 54 8F 29 00; Washington ($29:8F83)
4D 92 00 02 03 92 29 00; Rookies or All-Stars ($29:924D)
4D 92 00 02 03 92 29 00; Rookies or All-Stars ($29:924D)

July 03, 2018, 04:47:39 pm - (Auto Merged - Double Posts are not allowed before 7 days.)


Jumping over to banners.
Banners are 9x5 tiles (tiles are 8x8 pixels), 0x5A0 bytes apart.   
The tiles include the banner areas, plus shadows for the floor.  Different palettes are used.   
   
Code: [Select]
Banner locations (PC Addresses):
$2C0000 NBA
$2C05A0 Jam
$2C0B40 Acclaim
$2C10E0 Iguana
$2C1680 MK II
$2C1C20 NBA Jam Session
$2C21C0 Midway
$2C2760 Recycle
$2C2D00 Basketball
$2C32A0 I Love This Game!
$2C3840 Winners Don't Smoke
$2C3DE0 Air Morris
$2C4380 Winners Don’t Use Drugs
$2C4920 Please Handle With Care
$2C4EC0 NBA JAM
$2C5460 MK Logo
$2C5A00 Liu Kang

Banners come in sets of two on the court.   The following are their assignments:
Code: [Select]
Set PC Address Hex Code Points to (PC Address)
1 $1FD418 00 80 58 $2C0000 NBA
1 $1FD41B A0 85 58 $2C05A0 Jam
2 $1FD41E 40 8B 58 $2C0B40 Acclaim
2 $1FD421 E0 90 58 $2C10E0 Iguana
3 $1FD424 40 8B 58 $2C1680 MK II
3 $1FD427 20 9C 58 $2C1C20 NBA Jam Session
4 $1FD42A C0 A1 58 $2C21C0 Midway
4 $1FD42D 60 A7 58 $2C2760 Recycle
5 $1FD430 00 AD 58 $2C2D00 Basketball
5 $1FD433 A0 B2 58 $2C32A0 I Love This Game!
6 $1FD436 40 B8 58 $2C0B40 Acclaim
6 $1FD439 E0 90 58 $2C10E0 Iguana
7 $1FD43C 40 8B 58 $2C0B40 Acclaim
7 $1FD43F 20 C9 58 $2C4920 Please Handle With Care
8 $1FD442 C0 CE 58 $2C4EC0 NBA JAM
8 $1FD445 E0 90 58 $2C10E0 Iguana

I think Mattrizzle also covered a good amount of the within The Cutting Room Floor or another site, particularly where those unused (MK, Air Morris...) banners are concerned.  So I'm crediting him too, to be safe.
« Last Edit: July 03, 2018, 04:47:39 pm by eskayelle »

eskayelle

  • Jr. Member
  • **
  • Posts: 17
    • View Profile
Re: NBA Jam TE (SNES) ASM Tidbits
« Reply #3 on: July 10, 2018, 08:19:36 am »
Today's post provides one method by which the injury bug in NBA Jam TE may be fixed, for those of you who may be working on the game and might want to clear that problem out.  Moderators, I apologize if any of this is inappropriate (like the bumps of my own post)... I'm basically using this thread as a tutorial or dumping ground for concepts to arm others with as much info as I can learn myself about NBA Jam TE for SNES.

The Issue:
In the original game, there appears to be a bug whereby, if two games are played sequentially, with the same team selected, and the same line-up from quarter 4 of game 1 selected for quarter 1 of game 2, the first game's injury stats do not reset to zero in game 2, so you come off the bench with a potential handicap.

The caveats to this code:
1) I didn't necessarily consider SEPs and REPs, i.e., the 8 v. 16-bit status in the accumulators.  It ended up not causing an issue and thus created more efficient code (because I didn't add in those SEP and REP commands), but...
a) If one were to hack the game and increase the timer from 180 (decimal) seconds to 256 or more, I suspect the game will crash.
b) If one were to hack the game and increase the maximum injury value permitted from 25 (decimal) to 256 or more, I suspect the game will crash.
2) I believe the bug is in large part due to the ram values for the visual injury stats not properly resetting, but to be safe, I'm resetting those to zero AND the actual injury values in ram.  It's incredibly likely that more efficient code can be written to solve this bug, but this particular hack does the trick.
3) I'm using expanded rom (i.e., I expanded the rom to 32Mbit -- it's originally 24).  So, one would either need to relocate where they're putting this code or expand their rom size for this to work.

Code: [Select]
;===
;NBA Jam Injury Bugfix
;Written by eskayelle
;Proofread/debugged by phonymike
;General Idea - If the Timer is 3 minutes, check the quarter value
;Then, if the quarter value is zero, zero out all the injury stats
;Otherwise, leave those injury stats alone
;===
lorom

org $A7F429 ;Need to find a place around tip-off to move about 4 bytes of original code into the hack below so I can create this JSL
NOP #2 ;Taking 6 bytes, since 2 commands will need to be moved to fit the 4 byte JSL $E08050 command
JSL $E08050 ;Jump to the subroutine at $E08050 (the injury bugfix hack); hex code will be 22 50 80 E0

org $E08050 ;Goto expanded rom
PHX ;Push X onto stack in case it's in use
PHY ;Same for Y
LDX $0D95 ;Load quarter value (seems to increment from 0 to 3 at start of each quarter, no matter the game) into X ($7E0D95)
LDY $0D89 ;Load timer value into Y ($7E0D89)
CPY #$B4 ;Timer always starts at 3 minutes (unless hacked), or 180 seconds, at start of quarter, so compare Y to this - needs to be 8 bit
BNE + ;If Y <> 180 seconds (B4 in hex), goto +; otherwise, move on to next step
JSR Timer
+ PLY ;Pull back Y from stack like nothing happened
PLX ;Same for X
LDA $07D8 ;First 3 bytes of the original code moved here to make up for putting in the JSL above
CMP $1756 ;Last 3 of the original code - like we never moved it...
RTL ;Return to original code (RTL goes to the most recent JSL/JSR executed (i.e., the original code)

Timer:
CPX #$00 ;Value in $7E0D7B in Q1 is zero, so compare value in X to zero
BNE + ;If X <> zero, goto +; otherwise, move on to next step
JSR Quarter
+ RTS ;Return to above subroutine

Quarter:
STZ $1677 ;Player 1 injury stat in RAM; accumulator bit size is not an issue as long as max injury allowed < 256
STZ $1758 ;$1677 is pulling from $1758 in the code (below where I injected this)
STZ $1679 ;Player 2 injury stat in RAM
STZ $175C ;$1679 is pulling from $175C in the code (below where I injected this)
STZ $167B ;Player 3 injury stat in RAM
STZ $1760 ;$167B is pulling from $1760 in the code (below where I injected this)
STZ $167D ;Player 4 injury stat in RAM
STZ $1764 ;$167D is pulling from $1764 in the code (below where I injected this)
RTS ;Return to above subroutine; disassemble $A7F429 thru $A7F4A9 to see the injury routine

Thanks for reading, thanks to phonymike for teaching me ASM, and please consider sharing this information (and trying out your own hacks of NBA Jam TE!).