Jump to content
NHL'94 Forums

Activating Teams for Playoffs in 97


TheTome

Recommended Posts

For those wondering and just joining this topic, we have figured out how to do it, so feel free to follow along and teach yourself to hack, theres a surprising amount of ground covered here. Otherwise wait till after the trade deadline and I'll throw out my updated ROM and you can just play with that.

Original Post:

I was wondering if anyone knows how to enable extra teams for the playoffs in NHL 97 similar to in Wboy's 30 team rom for 94. I'm almost finished work on a second updated version of my update for NHL 97 and one of the biggest features I'm missing is the ability to use teams like the Nashville Predators in the playoffs.

Edited by TheTome
Link to comment
Share on other sites

OK, my guide for hacking this...

I'll post it in parts.

1. (This part) Finding the selected-team address in RAM

2. Finding where the address is accessed/changed

3. Generating a code trace

4. Reading the code trace and creating the hack

If I'm unclear or things don't work, please ask..

Initial Setup

1.

Open up Gens Rerecording

2.

Open the ROM, select playoffs, and hit start to get to the matchup selection screen

3.

Scroll through the teams until you have selected Anaheim as one of the teams. use the DOWN button while doing this. make sure that if you press DOWN again, you get Boston.. then UP again gives you Anaheim again.. so you know you have the lowest alphabetical team selected (and they aren't just coincidentally against the team you actually have selected..). I didn't explain this well, but I hope it's understood.

4.

Make a savestate by pressing the F5 key, so you can come back to this point easily/quickly if you need to.

5.

Hit the ESC key to pause the game (so the game doesn't start the playoffs before you're ready)

6.

Go to Tools->RAM Search, which brings up the RAM Search window

7.

Set the options to "Greater Than", "Previous Value", "1 byte", "Signed"

8.

Right now, we suspect that Anaheim is team "0".. the lowest number.. so we want to increase the team number by going to Boston next.. we could use the RAM Search to look for these values exactly, but we'll use Greater Than/Previous Value just because it's a useful skill to learn, and we don't know for sure that Anaheim is 0...

9.

In the RAM search, press "Reset"

Searching for the Address

RAM, if you don't know, is "Random Access Memory." It's like your short-term memory. While the game is running, the CPU reads/writes data to/from the RAM, like you would write your work on paper while doing a long math problem.

In contrast, the game's code (and graphics, etc) is stored in ROM, "Read-Only Memory." This is like your long-term/permanent memory, or like a book.

So we want to find the address in RAM that the game is using to store the currently selected team value.

1.

Unpause (ESC) and hit DOWN to go to Boston.

2.

Pause (ESC)

3.

in the RAM search, press "Search". some addresses will be eliminated because their values didn't change to be Greater Than the Previous Value.

4.

Unpause (ESC) and hit DOWN to go to Buffalo.

5.

Pause (ESC)

6.

in the RAM search, press "Search", which eliminates some more values.

7.

Continue doing this, until you see the obvious result. It takes 3 or 4 teams. If all the memory addresses are eliminated, then reload and try again, you must have made a mistake (possibly hit Search without switching teams, or switched teams in the wrong direction)

Results

1.

What is the memory address?

2.

What is the value when Anaheim is selected?

3.

What is the value when Washington (the last team before it wraps back around to Anaheim again) is selected?

Answers

1.

00FFD275

2.

0

3.

25

Next time, we'll use the address value to do a RAM Hook trace.

Link to comment
Share on other sites

Hey Smozoma, I will say its nice getting help from a fellow Leafs Fan.

Anyway, I'm in the middle of digging through the ROM at the moment and I'll post detailed findings soon, but I did stumble upon an interesting feature.

01:59AE - This Opcode is activated when people press up on the D-Pad in Playoff Team Select. Disabling it means that you can only scroll through teams going forward in the alphabet. Pressing Up however still triggers a new playoff bracket. This means you can press down to select your team, and then press up to select who they face off against.

Link to comment
Share on other sites

Hey Smozoma, I will say its nice getting help from a fellow Leafs Fan.

Anyway, I'm in the middle of digging through the ROM at the moment and I'll post detailed findings soon, but I did stumble upon an interesting feature.

01:59AE - This Opcode is activated when people press up on the D-Pad in Playoff Team Select. Disabling it means that you can only scroll through teams going forward in the alphabet. Pressing Up however still triggers a new playoff bracket. This means you can press down to select your team, and then press up to select who they face off against.

That's a pretty cool find

basically what you're looking for is something like "CMP A,26 / BNE ..." and you'd change the 26 (or maybe it's 25) to a 30 or whatever.. and the reverse (if they're at 0 and try to go lower, go to team 25.. change it to 30 or whatever). That's where I'm going with my tutorial.

Link to comment
Share on other sites

Sweet, I'll keep an eye out for that. I definitely wasn't sure what I was looking for, so that will help a lot.

but if you (or someone) find the memory location in my tutorial, i can post the next part :P

Link to comment
Share on other sites

Well it gets tricky as each select menu (Regular Game, Season, Playoff Select, and Playoff Tree) all have multiple adresses. Some unique, some common.

The one I'm working off of right now is:

FFD275

Its only used in the playoff bracket screen, and always displays the value of the "selected" team.

In all memory adresses for this screen:

Anaheim = 0

Washington =25

Upon running a Hook on it I get this:

MEMORY ACCESS LOGGING STARTED

[[02:6DB4] W16 = 0005 [FFD274] (Happens During Bootup)

[02:9844] W08 = 18 [FFD275] (Happens when selecting Playoffs, possibly number of teams in hex)

[02:72A6] W16 = 0017 [FFD274]

[02:72A6] W16 = 0017 [FFD274]

[01:5A56] W16 = 0018 [FFD274] (pressed down)

[02:72B6] W16 = 0018 [FFD274]

[01:5A56] W16 = 0019 [FFD274] (pressed down)

[02:72A6] W16 = 0019 [FFD274]

[01:5A56] W16 = 001A [FFD274] (pressed down, went from washington to anaheim)

[01:5A64] W16 = 0000 [FFD274]

[02:72A6] W16 = 0000 [FFD274]

[01:5A56] W16 = 0001 [FFD274] (pressed down)

[02:72A6] W16 = 0001 [FFD274]

[01:5A56] W16 = 0002 [FFD274] (pressed down)

[02:72B6] W16 = 0002 [FFD274]

[01:59B0] W16 = 0001 [FFD274] (pressed up)

[02:72A6] W16 = 0001 [FFD274]

[01:59B0] W16 = 0000 [FFD274] (pressed up)

[02:72A6] W16 = 0000 [FFD274]

[01:59B0] W16 = FFFF [FFD274] (pressed up, went from Anaheim to Washington)

[01:59BA] W16 = 0019 [FFD274]

[02:72A6] W16 = 0019 [FFD274]

MEMORY ACCESS LOGGING STOPPED

Things I know:

1: By changing the seeds in NOSE, you can have the extra teams show up with no problems in the Playoff screen.

2: You cannot select those teams yourself (Washington still goes right to Anaheim)

3: The game sometimes selects the extra teams as part of its random selection when entering the menu.

4: When you enter the playoff tree the names of the extra teams are garbled and the game will crash if you try to continue with them in.

NEW DISCOVERY

1D:E2DE - Change 001A to 001E to allow for 30 teams to be selected in the playoff tree (this does not affect the first playoff select screen). Unfortunately the text for the extra teams is garbled and the game crashes if you attempt to use them. Still, getting there...

Edited by TheTome
Link to comment
Share on other sites

You got ahead of me :D

Playoff tree.. I had no idea about that feature. OK, guess we'll have to get to that, too...

Here's the steps for people to know how to use the tracer.

In my previous tutorial post, we figured out that the RAM memory location storing the current team value was FFD275:

post-253-005240900 1330138989_thumb.png

(the other address, FFFE20, appears to be some kind of timer that counts upwards)

Set Up the RAM Trace (Hook RAM)

1.

Shut down Gens Rerecording. The RAM hook is really poorly integrated into the emulator, and you need to close the emulator, edit a file, and restart the emulator before it works.

2.

Open the file "hook_log.txt". It starts with some lines that look like this:

hook_pc1 0 -1 -1
hook_pc2 1 -1 -1
...
hook_ppu3 1 -1 -1

The ones we are interested in are the ones starting with hook_rd (read) and hook_wr (write).

3.

Edit hook_rd1 and hook_wr1 to look like this:

hook_rd1 0 FFD275 FFD275

hook_wr1 0 FFD275 FFD275

We'll use these to be able to see what code lines read or write that value in RAM.

Do the RAM Hook Trace

1.

Run the emulator again, and go back to the playoff matchup selection screen (press F8 to load the save you made in the last tutorial).

2.

Select Tools->Tracer Tools->RAM Hook. You'll see it give a message on the screen, "RAM logging started". The shortcut for this is Ctrl+Shift+. (period). Anaheim should be selected.

3.

Press DOWN 2 times to see Buffalo, then press UP 4 times to get to Vancouver, then press DOWN 2 times again to go back to Anaheim.

4.

Turn off the RAM hook, either from the menu or the shortcut (Ctrl+Shift+.).

View the RAM Hook Log

Open up the file hook.txt:

[01:5A56] R16 = 0000 [FFD274]  (starting on Anaheim)
[01:5A56] W16 = 0001 [FFD274] (boston)
[01:5A5C] R16 = 0001 [FFD274]
[02:6EBC] R16 = 0001 [FFD274]
[02:72B6] W16 = 0001 [FFD274]
[01:5A56] R16 = 0001 [FFD274]
[01:5A56] W16 = 0002 [FFD274] (buffalo)
[01:5A5C] R16 = 0002 [FFD274]
[02:6EBC] R16 = 0002 [FFD274]
[02:72B6] W16 = 0002 [FFD274]
[01:59B0] R16 = 0002 [FFD274]
[01:59B0] W16 = 0001 [FFD274] (boston)
[02:6EBC] R16 = 0001 [FFD274]
[02:72B6] W16 = 0001 [FFD274]
[01:59B0] R16 = 0001 [FFD274]
[01:59B0] W16 = 0000 [FFD274] (anaheim)
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:72A6] W16 = 0000 [FFD274]
[01:59B0] R16 = 0000 [FFD274]
[01:59B0] W16 = FFFF [FFD274] (invalid!)
[01:59BA] W16 = 0019 [FFD274] (washington.  19 hex = 25 decimal)
[02:6EBC] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:72A6] W16 = 0019 [FFD274]
[01:59B0] R16 = 0019 [FFD274]
[01:59B0] W16 = 0018 [FFD274] (vancouver)
[02:6EBC] R16 = 0018 [FFD274]
[02:72B6] W16 = 0018 [FFD274]
[01:5A56] R16 = 0018 [FFD274]
[01:5A56] W16 = 0019 [FFD274] (washington)
[01:5A5C] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:72A6] W16 = 0019 [FFD274]
[01:5A56] R16 = 0019 [FFD274]
[01:5A56] W16 = 001A [FFD274] (invalid!)
[01:5A5C] R16 = 001A [FFD274]
[01:5A64] W16 = 0000 [FFD274] (anaheim)
[02:6EBC] R16 = 0000 [FFD274]
[02:72A6] W16 = 0000 [FFD274]

The first line is [01:5A56] R16 = 0000 [FFD274].

[01:5A56] .... This is the ROM code address that did the memory access.

R16 ............ This means a Read of 16-bits. W16 would be Write. You can also sometimes see R8 or W8.

= 0000 ........ This is the value that was read. 4 characters (0000) is a 16-bit value. 2 characters (00) would be an 8-bit value.

[FFD274] ..... This is the RAM address that was read.

You might notice that the RAM address accessed is actually FFD274, not FFD275. So the team value is actually stored in a 16-bit variable.

Understanding Hex values

We have 10 numbers in the decimal system -- 0,1,2,3,4,5,6,7,8,9. When you get to 9, you go to 10 after that.

In the hexadecimal system, there are 16 numbers: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. 'A' means 10(decimal). When you get to F, you go to 10(hex) after that. 10(hex) is 16(dec).

Hex = Dec
 0 =   0
 1 =   1
 2 =   2
 ...
 9 =   9
 A =  10
 B =  11
 C =  12
 D =  13
 E =  14
 F =  15
10 =  16
11 =  17
...
18 =  24
19 =  25
1A =  26
1B =  27
...
1E =  30
1F =  31
20 =  32
...

Analyze the RAM Hook Log

The parts we are really interested in are the parts where we go from Anaheim to Washington, and from Washington to Anaheim.

Anaheim -> Washington

[01:59B0] W16 = 0000 [FFD274] (anaheim)
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:6EBC] R16 = 0000 [FFD274]
[02:72A6] W16 = 0000 [FFD274]
[01:59B0] R16 = 0000 [FFD274]
[01:59B0] W16 = FFFF [FFD274] (invalid!)
[01:59BA] W16 = 0019 [FFD274] (washington.  19 hex = 25 decimal)

All those R16 at code address [02:6EBC] are pretty weird. Why would it need to read that value so many times? Oh well, the really interesting part is that it it goes from 0000 to FFFF at [01:59B0].

When you subtract 1 from 0000, you actually end up with FFFF, so FFFF is like -1 (negative 1). So it looks like when you press UP from Anaheim and go to Washington, the game subtracts 1 from the team value (0000) and then it becomes -1 (FFFF). Then the game realizes that's not allowed, and writes 0019 (25 hex) into the value, and Washington becomes selected.

[01:59B0] is where the subtraction happened in the code, and

[01:59BA] is where the code sets the team value to 0019, washington.

Washington->Anaheim

[01:5A56] W16 = 0019 [FFD274] (washington)
[01:5A5C] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:6EBC] R16 = 0019 [FFD274]
[02:72A6] W16 = 0019 [FFD274]
[01:5A56] R16 = 0019 [FFD274]
[01:5A56] W16 = 001A [FFD274] (invalid!)
[01:5A5C] R16 = 001A [FFD274]
[01:5A64] W16 = 0000 [FFD274] (anaheim)

[01:5A56] is where the code adds to the team value, going from 0019 to 001A. Then it reads 001A at [01:5A5C], decides it's invalid, and then changes it to 0000 (anaheim) at [01:5A64].

Next time, we'll do a code trace and see how the game actually works.

Link to comment
Share on other sites

Well said. You definitely have a better grasp of it than I do so far, and I'm learning a hell of a lot following along. As it stands, I've discovered the following:

Playoff Select Screen

01:5A5A - Sets the highest team you can select. Original Value: 001A New Value: 001D (It should be 001E but so far I can't get Europe to work right)

01:59B8 - Sets top team to jump to after Anaheim. Original Value: 0019 New Value: 001D (Same problem)

Playoff Tree

1D:E2DE - Sets highest team you can select. Original Value: 001A New Value: 001E

1D:E270 - Set top team to jump to after Anaheim. Original Value: 0019 New Value: 001D

I've attached a proof of concept ROM which includes a fully functional team select for the Playoffs, however as you'll notice it's currently impossible to move past the Playoff Tree. Thats going to be my main focus for now, and I'll try to get Europe (Nashville in this ROM) to function properly once the rest is working. I will admit it doesn't look simple however...

NHL 12 (97) proof o concept.bin

Link to comment
Share on other sites

Now we're going to make a code trace.

You'll want to download a good text editor for this, because you're going to be playing with large text files. Go get Notepad++.

Also, Notepad++ has some nice syntax highlighting features that can make it easier to read the logs...

Generate the Code Trace

1.

Run Gens Rerecording.

2.

Open the NHL 97 ROM and load your saved game again (or go to the playoffs selection screen and select Anaheim).

3.

Press ESC to pause the game. I recommend always pausing the game before enabling code tracing, because you want to have code tracing on for the shortest time possible, because the trace files get HUUUGE faaast.

4.

Put the emulator in slow mode: Tools->Slow mode->Slow mode enabled. Then set it to a speed around 20%. This slows the execution of the game down, so you can do whatever button presses in the game you need to do with as little wasted execution (extra trace data) as possible.

5.

Enable tracing, by going to Tools->Tracer Tools->Trace (or hitting the shorcut key, Ctrl+Shift+/ (beside the period)). You'll see "Instruction logging started" appear on the screen.

6.

Press UP to go from Anaheim to Washington, then DOWN to go from Washington to Anaheim. Remember that since you're in Slow Mode, the game will not be very responsive.

7.

Pause (ESC)

8.

Disable tracing (Ctrl+Shift+/).

My trace file was about 6MB.

About the Code Trace

Open up trace.log in Notepad++.

Your first lines are probably something ugly like this:

01:589A  67 FA  BEQ     #$FA [01:5896]           A0=0002000E A1=001A9660 A2=001A6B9E A3=FFFFD2B2 A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDBA D0=000004AD D1=00000000 D2=00000000 D3=00000000 D4=00000187 D5=00000000 D6=00000000 D7=00000000 xnZvc
01:5896  B0 78  CMP.W   ($B054),D0               A0=0002000E A1=001A9660 A2=001A6B9E A3=FFFFD2B2 A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDBA D0=000004AD D1=00000000 D2=00000000 D3=00000000 D4=00000187 D5=00000000 D6=00000000 D7=00000000 xnZvc

01:589A ......... The code address (would have been surrounded by square brackets in the RAM hook trace, like [01:589A])

67 FA ............. The hex code of the game code instruction

BEQ #$FA ...... The game code instruction in the assembly language for the Genesis CPU.

[01:5896] ......... When the instruction is a Branch instruction, the target address of the branch will be given here.

A0=0002000E .. The CPU has a bunch of 'registers' that hold data. It's like super-fast RAM. There are 16 of them, A0-A7,D0-D7.

xnZvc .............. The CPU flags. Can be difficult to understand, but I think we're going to get a good example of them in this hack.

About that code instruction: It's in the assembly language for the type of CPU in the Genesis, 68k assembly language. The first part is the name of the instruction (BEQ, Branch EQual) and the second part is the parameter for the instruction (ignore the #, $ means it's a hex number, and FA is the hex number).

Finding Our RAM Hooked Code Addresses

Going back to our RAM Hook trace, we were interested in a couple things:

Going from Anaheim to Washington:

[01:59B0] W16 = FFFF [FFD274] (invalid!)
[01:59BA] W16 = 0019 [FFD274] (washington.  19 hex = 25 decimal)

And from WSH to ANA:

[01:5A56] W16 = 001A [FFD274] (invalid!)
[01:5A5C] R16 = 001A [FFD274]
[01:5A64] W16 = 0000 [FFD274] (anaheim)

So, you try to search for "01:59B0" in the trace.log... but it's not there! It turns out, you usually need to subtract 2 from the RAM hook to get the trace.log address. There's a reason for this, but I won't go into it.

So, subtract 2 from 01:59B0. It's 01:59AE. (counting up in hex: AE, AF, B0..)

Search for that, and you get this:

01:59AE  53 78  SUBQ.W  #1,($D274)           xnZvc    
01:59B2  6A 00  BPL     #$0008 [01:59BC]     XNzvC    
01:59B6  31 FC  MOVE.W  #$0019,($D274)       XNzvC    

Analyzing the Code

Note that the "flags" change on the second line, from xnZvc to XNzvC. When "N" is capitalized, that means the result of the previous instruction was a negative number. I won't mention the other ones...

Remember our RAM address for the team value was FFD274? In the code, that's ($D274)

SUBQ.W #1,($D274) .......... SUBtract 1 from ($D274)

BPL #$0008 [01:59BC] ....... Branch if PLus, +8 bytes (i.e., skip the next few instructions if the subtract result was positive)

MOVE.W #$0019,($D274) ... MOVE the value 0019 into ($D274)

So, when we are Anaheim, and we try to select the team before Anaheim by SUBtracting 1 from FFD274 (which was 0000), we get a negative value (FFFF). This changes the "negative" flag from "n" (not negative) to "N" (negative).

The next instruction is an instruction in the Branch family. Branch instructions are used to jump forward or backwards in the code, depending on the results of the previous instructions. In this case, BPL notices that the negative flag is capitalized to "N", so the result of the subtraction was not Positive (PLus). Because it was not Positive, it doesn't do the Branch and skip over the next instructions. Instead, it runs the very next command.

That next command MOVEs the value 0019 into our RAM location.

So, now we have our first hack! To change the team we move to when going backward before Anaheim, we'll change 0019 to a different value.

(You don't need to know this for this hack, but maybe it's interesting:

The Q in SUBQ means Quick, which you can use to subtract a value from 1 to 8 really quickly.

.W means it's a Word command -- a "Word" is 16 bits, whereas a "Byte" (.B ) is 8 bits, and a "Long" (.L) is 32 bits.)

And Again, for the Other Direction

The RAM hook lines when going from from WSH to ANA:

[01:5A56] W16 = 001A [FFD274] (invalid!)
[01:5A5C] R16 = 001A [FFD274]
[01:5A64] W16 = 0000 [FFD274] (anaheim)

Subtract 2 from 01:5A56 gives 01:5A54. Search for that in the trace.log and you get this code:

01:5A54	52 78	ADDQ.W  #1,($D274)              	xnZvc
01:5A58	0C 78	CMPI.W  #$001A,($D274)          	xnzvc
01:5A5E	6D 00	BLT     #$0006 [01:5A66]        	xnZvc
01:5A62	42 78	CLR.W   ($D274)                 	xnZvc

ADDQ.W #1,($D274) .......... ADD 1 to the team value in ($D274)

CMPI.W #$001A,($D274) ......... CoMPare the value 001A to the team value.

BLT #$0006 [01:5A66] ......... Branch forward 6 bytes (past the next instruction) if 001A is Less Than (LT) the team value.

CLR.W ($D274) .......... CLeaR the value in RAM (i.e., set it to zero)

So, easy enough... Add 1 to the team value. If the value is less than 001A, branch over the next line -- but the value wasn't less than (it was equal), so do the next line instead: set the team value to 0000.

And here is our second hack! Change the 001A in the CMPI instruction to another value.

Next time, we'll actually hack the ROM.

Link to comment
Share on other sites

Now, we hack the ROM!

Get yourself a hex editor. The free hex editor I use is HxD. There are others, but I find this one pretty good.

If your version of the ROM is in .smd format, you need to change it to .bin. Try one of these utilities.

If for your .bin copy of NHL 97 doesn't load in the emulator (you just get a blank screen), open it in the hex editor, go to offset 00766, and change "4EB9001E24D0" to "4E714E714E71" and save it. Then re-open it.

Hack It!

Make a backup copy of your ROM! Always have a working backup!

Open the ROM in the hex editor. The first 4 bytes of NHL 97 should be 00 FF FF F6. If it's not... ask and I'll try to figure it out...

NHL 97 has 31 teams. 26 NHL teams, 2 All Star teams, and 3 Geographical teams (Canada, USA, Europe -- no Russia!). There appear to be 2 additional teams, as well, actually, but I'm not quite sure they're usable...

In hex, 31 is 1F. However, in programming, we usually start counting at 0, so the teams are 0-30 (decimal) or 0000-001E (hex).

We found these sections of code that we wanted to hack:

01:59AE  53 78  SUBQ.W  #1,($D274)           xnZvc    
01:59B2  6A 00  BPL     #$0008 [01:59BC]     XNzvC    
01:59B6  31 FC  MOVE.W  #$0019,($D274)       XNzvC  

01:5A54 52 78   ADDQ.W  #1,($D274)                      xnZvc
01:5A58 0C 78   CMPI.W  #$001A,($D274)                  xnzvc
01:5A5E 6D 00   BLT     #$0006 [01:5A66]                xnZvc
01:5A62 42 78   CLR.W   ($D274)                         xnZvc

For the upper section of code, we want to change the 0019 (25 decimal) to 001E (30 decimal). That line of code has the address 01:59B6.

In the hex editor, hit Ctrl+G to bring up the GoTo window, type in 0159B6, and hit OK.

You'll end up on a line like this (ignore the colours, that's the forum doing that, not me):

000159B0 D2 74 6A 00 00 08 31 FC 00 19 D2 74 4E B9 00 02

The MOVE.W instruction is this part:

31 FC 00 19 D2 74

So, change that 19 to 1E:

31 FC 00 1E D2 74

In the second section of code, we want to change the 001A (26) to 001F (31).

The address of the CMPI.W instruction is 01:5A58. GoTo that in the hex editor.

Change

0C 78 00 1A D2 74

to

0C 78 00 1F D2 74

Save.

(note: in HxD, once you save, you can't Undo anymore)

Try Out the Hacked ROM

Open the ROM in the emulator, go to the playoffs, and press up or down to try to access the additional teams.

Whoops, the ROM freezes. This is because the all star and world teams don't appear in any playoff matchups. So open up the ROM in NOSE, go the playoff matchups, and add the following teams so they are all in at least one playoff matchup (for some reason the list has duplicates of the teams -- only use the teams in the top half of the list):

* EA Sports (turns into All Stars East)

* Renegades (turns into All Stars West)

* Team Canada (first instance.. near the middle of the list)

* Team USA (first instance.. near the middle of the list)

* Team Europe (first instance.. near the middle of the list)

Re-open the ROM from the File menu (Open or Rom History) in the emulator. You can't just reboot it (ctrl+shift+R) since that doesn't reload the ROM with the new changes.

Try again.

WTF

If you're pressing DOWN, you get this behaviour: vancouver, washington, all stars east, all stars west, canada, canada.. canada...

If you're pressing UP, you get this behaviour: boston, anaheim, canada, all stars west, all stars east, washington, vancouver, etc..

So something funny is going on! How can it go from Anaheim to Canada? We are telling it go to to team 001E (30 decimal) after Anaheim, but it's going to 001C (28)!

Open Tools->RAM Watch.

New -> FFD274, Hexadecimal, 2 bytes -> OK

Now, try using UP or DOWN and watch the value.

If you're going DOWN, you'll see it go from 001C (canada) to 001D (USA), but then suddenly jump back to 001C (Canada).

If you're going UP, you'll see it go from 0000 (anaheim) to 001E (Europe), but then suddenly jump down to 001C (Canada).

It seems there is more to this than we thought... So... You need to go back to my 2nd big post, Set Up the RAM Trace (Hook RAM), and do some more work!

Generate another RAM hook, to see what other code locations are writing to FFD274 when this odd team canada-related issue happens.

Run another code trace and find the code that is causing this broken behaviour.

I think what is happening is there is some 'protection' in the code that searches for the playoff matchups that assumes 001C is the highest possible team. So we need to find that and override it. Probably a CMPI command.

Link to comment
Share on other sites

Found It!

02:6EC6 brings in "1C" as as limit to how high you can go.

To raise the limit change opcode

741C

to

741E

To gain proper access to all 31 teams! (or 741D if your going for just the current 30 teams)

Unfortunately the playoff tree is still broken. Some of the extra teams cause the game to think there are duplicate teams when there aren't any, and the others cause the game to crash. I'm going to start looking into whats causing the duplicate team bug first.

Also, if anyone knows much about how tiles are accessed by the game (or knows where I can find that information), the names of the extra teams are also loading wrong, but thats an area of code I don't currently understand at all.

Edited by TheTome
Link to comment
Share on other sites

All 30 teams working in the playoffs!!!

Thats right, got it working... well sort of. In order to get this to work you need to go to

1D:E270 and change 1219 to 6002

The original opcode is MOVE.B (moves bytes around) and is the equation responsible for looking for duplicate teams. 6002 basically bypasses this operation as there is something in the extra teams that are messing it up. I'm still trying to translate the entire process into something I understand so I can modify it. However disabling it works in the short term.

This fixes a bug where the game would think there were duplicate teams when there weren't (only with certain extra teams in the playoff tree). It also appears to be the equation that crashes the game when trying to use the extra teams, as they now work perfectly, and can be used for the entire playoffs.

There is only one problem, this completely disables the computer looking for duplicates, so while you can now use all 30 teams, there is nothing to check and see if if you used the same team more than once. Thankfully, you can have as many duplicates as you want and it won't affect the game in any negative fashion. So if you don't mind the possibility of being able to set up duplicates then we're basically set! Otherwise, I'm looking to see how to keep the duplication check on without breaking compatibility with the new teams.

Finally, there is still a graphic loading glitch in the playoff tree. All new team names fail to load leading to the following graphic error:

post-4393-041331100 1330216539_thumb.png

This is more cosmetic than anything, but is really the only real problem left for perfect playoffs. However I have no idea how graphics are loaded at all, and my searches have not brought anything up. If anyone has any leads or suggestions I'm all ears!

Link to comment
Share on other sites

Damn, when I saw the playoff tree, I was really hoping those team names were drawn using text/fonts, not graphics, but obviously they're using graphics. Boo.

I'm not familiar with Genesis graphics, either, so I can't help beyond this.

But, nice work getting the playoffs working with the extra teams.

Hmm.. can you find those team name graphics in the ROM? That could be a start for fixing this.. I have a bit of an idea..

Link to comment
Share on other sites

Yea, I've found and edited all the team name graphics. The ones being used are at offset 17:CBF6, and there are graphics for all 31 teams (33 if you count the secret teams).

I've used Genesis save state editor to look at whats going on in the playoff tree and it appears the game is only loading all the graphics up to Washington into the VPD (video ram). Hypothetically all we need to do is to change the loading opcode to load up to a higher offset and we'll be fine.

Link to comment
Share on other sites

Alright, slight progress update.

I've managed to isolate to opcodes that appear to be responsible for loading in the graphics exclusively for the playoff tree. They are located at:

1D:E042 and 1D:E044

I found these by finding the first finding the offset of the first tile for one of the loaded graphics:

post-4393-034116100 1330235015_thumb.png

Next I pulled up the trace in Notepad. I didn't search for the entire offset as the actual one loaded may be a few bytes off in either direction. Instead I searched for the middle bit (ie. for 17CBF6 I searched for CBF or 7CBF):

post-4393-022600400 1330235591_thumb.png

NOTE: Do not run this through Trace.Nicefier in this instance as it will remove all relevant graphical data from the file.

Since it is the previous expression that writes the information we get to 1D:E042. I have checked and this offset is not used when loading any other screens, thus it is purely for the playoff graphics. I also looked up a number of other graphics and it appears it runs once for each individual graphic (Anaheim text, Toronto text, etc.)

Luckily it is 1D:E042 every single time, so this means it is likely possible to change the expression/condition that fires it off to go a little farther and grab the missing names for the Video Ram.

Here is the trace Data I have on it so far. I've included a few instructions before and after it to give a sense of what was going on. This is its first occurrence in the trace while it is loading in the Anaheim graphic.

1D:E038  30 C4  MOVE.W  D4,(A0)+                 A0=FFFFD058 A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E03A  30 02  MOVE.W  D2,D0                    A0=FFFFD05A A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E03C  E5 40  ASL.W   #2,D0                    A0=FFFFD05A A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E03E  24 71  MOVE.L  $00(A1,D0),A2            A0=FFFFD05A A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc

1D:E042  50 4A  ADDQ.W  #8,A2                    A0=FFFFD05A A1=00016BC4 A2=0017CBEC A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc

1D:E044  4E B9  JSR     ($00020376)              A0=FFFFD05A A1=00016BC4 A2=0017CBF4 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
02:0376  42 B8  CLR.L   ($D048)                  A0=FFFFD05A A1=00016BC4 A2=0017CBF4 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF2 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
02:037A  48 E7  MOVEM.L {d0-a7}[c0 fe],-(SP)     A0=FFFFD05A A1=00016BC4 A2=0017CBF4 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF2 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
02:037E  20 4A  MOVE.L  A2,A0                    A0=FFFFD05A A1=00016BC4 A2=0017CBF4 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDCE D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc

As you can see it loads the data into Address 2 (A2). I'm assuming all the 1D:#### addresses run in sequence, so I'll try and follow them back and see what triggers them off and where they loop. I'll get back when I know more.

Link to comment
Share on other sites

Yea, I've found and edited all the team name graphics. The ones being used are at offset 17:CBF6, and there are graphics for all 31 teams (33 if you count the secret teams).

I've used Genesis save state editor to look at whats going on in the playoff tree and it appears the game is only loading all the graphics up to Washington into the VPD (video ram). Hypothetically all we need to do is to change the loading opcode to load up to a higher offset and we'll be fine.

Yeah, that's roughly what I was thinking.

Where can I get this save state editor?

Are there any graphics after Washington in the VPD? I'm confused about how it appears to load fragments of the Anaheim and Boston name for the additional teams. Is it maybe looping back somehow? Is there extra room in the VPD, or is it full?

Terminology note:

Here is an assembly instruction: MOVE.W #0019,$(D274)

Here is that instruction in machine code: 31FC 0019 D274

The opcode is 31FC, and 0019 and D274 are the operands.

Link to comment
Share on other sites

You can get the Genesis Savestate viewer here.

It appears there is still room in the VPD, and there are a number of graphics after Washington. All the graphics after Washington are sourced from different sections of the ROM however which likely explains why it jumps back to the start and grabs at the Anaheim and Boston tiles.

Link to comment
Share on other sites

You can get the Genesis Savestate viewer here.

It appears there is still room in the VPD, and there are a number of graphics after Washington. All the graphics after Washington are sourced from different sections of the ROM however which likely explains why it jumps back to the start and grabs at the Anaheim and Boston tiles.

Thanks for the link.

That's going to be a problem, if there are other graphics right after Washington. If you manage to get the other graphics to draw into the video memory, it'll probably just get overwritten by the other graphics.

To load the other team name graphics, I think I figured it out, though.. (but like I said they'll get overwritten by the other graphics the game needs!

1D:E018 32 3C MOVE.W #$0019,D1

Change the 0019 to correspond to the number of additional team name graphics you want to load. (Notice that the D1 value counts down after each name graphic is loaded)

However, if the game is going back and grabbing the ANA/BOS tiles, I think it will ignore the additional name graphics even if you got them to go in there. I would have expected to see the graphics after Washington, not ANA/BOS. That's a code thing that would have to be solved.

Link to comment
Share on other sites

Alright, so if you go to offset 1D:E04C we may have a solution.

The opcode here is DBFa so its setting some kind of a condition. It appears every time a graphic is loaded, however once it gets past Washington it triggers a new set of instructions (starting at 1D:E050).

Here is the trace for the Anaheim graphic (it's basically identical for all the team names):

1D:E04A  52 42  ADDQ.W  #1,D2                    A0=FFFFD08A A1=00016BC4 A2=00181C44 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000060 D1=00000001 D2=00000018 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E04C  51 C9  DBFa    D1,#$FFEA [1D:E038]      A0=FFFFD08A A1=00016BC4 A2=00181C44 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000060 D1=00000001 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc

1D:E038  30 C4  MOVE.W  D4,(A0)+                 A0=FFFFD08A A1=00016BC4 A2=00181C44 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000060 D1=00000000 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E03A  30 02  MOVE.W  D2,D0                    A0=FFFFD08C A1=00016BC4 A2=00181C44 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000060 D1=00000000 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E03C  E5 40  ASL.W   #2,D0                    A0=FFFFD08C A1=00016BC4 A2=00181C44 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000019 D1=00000000 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E03E  24 71  MOVE.L  $00(A1,D0),A2            A0=FFFFD08C A1=00016BC4 A2=00181C44 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=00000000 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E042  50 4A  ADDQ.W  #8,A2                    A0=FFFFD08C A1=00016BC4 A2=0018202A A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=00000000 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E044  4E B9  JSR     ($00020376)              A0=FFFFD08C A1=00016BC4 A2=00182032 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=00000000 D2=00000019 D3=00000000 D4=00000203 D5=00000009 D6=00000000 D7=0000001A xnzvc

And Here is the trace for the first graphic after Washington:

1D:E04A  52 42  ADDQ.W  #1,D2                    A0=FFFFD08C A1=00016BC4 A2=00182032 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=00000000 D2=00000019 D3=00000000 D4=0000021C D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E04C  51 C9  DBFa    D1,#$FFEA [1D:E038]      A0=FFFFD08C A1=00016BC4 A2=00182032 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=00000000 D2=0000001A D3=00000000 D4=0000021C D5=00000009 D6=00000000 D7=0000001A xnzvc

1D:E050  31 C4  MOVE.W  D4,($B01C)               A0=FFFFD08C A1=00016BC4 A2=00182032 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=0000FFFF D2=0000001A D3=00000000 D4=0000021C D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E054  24 7C  MOVE.L  #$001AA33A,A2            A0=FFFFD08C A1=00016BC4 A2=00182032 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=0000FFFF D2=0000001A D3=00000000 D4=0000021C D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E05A  4E B9  JSR     ($0002036A)              A0=FFFFD08C A1=00016BC4 A2=001AA33A A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000064 D1=0000FFFF D2=0000001A D3=00000000 D4=0000021C D5=00000009 D6=00000000 D7=0000001A xnzvc

Link to comment
Share on other sites

A tile map eh? Not sure I know the significance of that statement...

The graphics are broken up into tiles (notice the grid on the graphic you posted earlier). Those are 8x8 pixel tiles.

When I hacked extra teams into NHLPA93 on the SNES, there were tile maps associated with those graphics. Each tile in VPD is referenced by a number, and the game loads each tile onto the screen.

Unfortunately, the tile maps tend not to be 01, 02, 03.. The SNES ones were 2 bytes for each tile, something like 4D01, 4D02, etc.

Link to comment
Share on other sites

Got it!!!!!

Alright, so if you run a trace on the loading of the playoff tree you'll discover everything we already have, but if you look at the first time that we get a graphic loaded:

1D:E014  38 3C  MOVE.W  #$0002,D4                A0=00C00000 A1=001A9660 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=0000001C D2=000007FF D3=00000000 D4=0000FFFF D5=00000009 D6=00000000 D7=0000001A xnZvc

1D:E018  32 3C  MOVE.W  #$0019,D1                A0=00C00000 A1=001A9660 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=0000001C D2=000007FF D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E01C  42 42  CLR.W   D2                       A0=00C00000 A1=001A9660 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=000007FF D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnzvc

1D:E01E  20 7C  MOVE.L  #$FFFFD058,A0            A0=00C00000 A1=001A9660 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E024  22 7C  MOVE.L  #$00016BC4,A1            A0=FFFFD058 A1=001A9660 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E02A  4A 78  TST.W   ($DEA6)                  A0=FFFFD058 A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E02E  67 00  BEQ     #$0008 [1D:E038]         A0=FFFFD058 A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E038  30 C4  MOVE.W  D4,(A0)+                 A0=FFFFD058 A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E03A  30 02  MOVE.W  D2,D0                    A0=FFFFD05A A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000080 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnzvc
1D:E03C  E5 40  ASL.W   #2,D0                    A0=FFFFD05A A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E03E  24 71  MOVE.L  $00(A1,D0),A2            A0=FFFFD05A A1=00016BC4 A2=001A6B9E A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E042  50 4A  ADDQ.W  #8,A2                    A0=FFFFD05A A1=00016BC4 A2=0017CBEC A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc
1D:E044  4E B9  JSR     ($00020376)              A0=FFFFD05A A1=00016BC4 A2=0017CBF4 A3=FFFFBF4D A4=00000000 A5=00000000 A6=00000504 A7=FFFFFDF6 D0=00000000 D1=00000019 D2=00000000 D3=00000000 D4=00000002 D5=00000009 D6=00000000 D7=0000001A xnZvc

If you look at 1D:E018 you'll notice the opcode MOVE.W places the number 19 at D1. If you follow the trace all the way down to the Washington graphic you will notice that the number in D1 counts down the entire way. When it reaches zero it switches to the next set of graphics. By raising the operand from 0019 to 001E it now loads in the graphics for all 31 teams!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...