Here is one solution to the injury bug. ASM below.
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.
;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
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
+ 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)
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
+ RTS ;Return to above subroutine
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
Hoping this might prompt any takers to peek at my initial questions above and perhaps provide some thoughts/guidance?