smozoma Posted August 28, 2010 Report Posted August 28, 2010 Since the original message is old and newer tools are out, I'm updating TonyH's post.Without Tony's posts, I would never have done any ROM hacking.It was his posts that let me find the weight bug code and fix it.------------------------A few people here in the NHL94 forums are interested infinding out how I find useful ROM addresses in Genesisgames (ie. NHL 94). I (TonyH) have decided to writea guide that explains how to do it. If anyone has anyquestions as I go along, please feel free to ask. I'mtyping this in a hurry, so I may not explain everythingtoo well.Here's a list of what you'll need...1) Gens ReRecording2) A hex editor (your choice. suggestions: HxD (it's free) or bpsoft.com (free trial version).3) NHL94 ROM (in bin format -- use the Maha/swos versionbecause the checksum has been removed)4) NotePad++5a) Some basic 68000 assembly language knowledge ishelpful, but not absolutely necessary.5b) Knowing hexadecimal numbers might be useful, tooHere's what that stuff is for...- We'll use Gens ReRecorder to find RAM addressesand make memory traces and assembly trace logs.Some people use Kega Fusion to find RAM addresses.- The hex editor is for finding ROMaddresses, and the NHL94 ROM is what we'll be pokingaround in trying to find ROM addresses.- Notepad++ is used to open the really huge 'trace'files that Gens ReRecording creates. The normalnotepad that comes with Windows can't really handlehow big they are (in XP anyway). You can omit it anduse the default Notepad in windows, but it'll takea long time to open the files.To try to keep this relatively simple, we'll find theROM address that determines how much time you get foreach period. The game normally lets you select from5, 10 and 20 minute periods, and there is the "cheat"that lets you have 30 second periods. I'll show youhow to find those values in the ROM so you can changethem to any value you want, and I'll show you how tostop the clock completely so you'll have infinite time.Not that you'd want infinite time, but mainly to showyou how it's done.Since making Game Genie codes is kinda my "thing", I'llalso show you how to make Game Genie codes for all thisstuff.Okay, lets get to the good stuff...FIND THE CLOCK VALUE IN RAM- The first thing we need to do is find the RAM addressfor the clock. This is very easy to do. Just start upGens ReRecording, load your NHL94 ROM, and starta game of the updated Maha/swos ROM.- When the clock starts to count down, click the ESCkey to pause the game. Then, click on "Tools ->RAM Search". Click the "reset" button.- Click back on the emulator and then hit ESC againto resume the game. Let the clock count down 1 or 2seconds and click ESC again to pause.- Now, in the RAM Search window, make sure "less than","Previous Value", and "1 byte", are all checked,then click on "Search".- Go back to the game (ESC to unpause) and let the clockcount down a few more seconds. click on "Search" again.- Keep repeating this until you only have a few RAM addresses left.- Unpause the game again, and watch the numbers. You'llsee one that decrements each game second. That's the clockvalue in RAM. (It won't have the same time as the clock,but it'll be decreasing at the same rate as the clock)- For this example, I'll tell you that the RAM address forthe clock is FFC469. It's actually FFC468, but for ourpurposes (and to keep this shorter), FFC469 will workfine.Okay, so we know that the RAM address for the clockis FFC469. Now we need to find out where in the ROMthis RAM address is being loaded, modified, etc.FIND THE CODE THAT MODIFIES THE CLOCK TIMEIn the Gens ReRecorder directory, there is a text file called"hook_log.txt". Open up that text fileand change it so it looks exactly like this... hook_pc1 0 -1 -1 hook_pc2 1 -1 -1 hook_pc3 1 -1 -1 hook_rd1 0 -1 -1 hook_rd2 0 -1 -1 hook_rd3 0 -1 -1 hook_wr1 0 ffc469 ffc469 hook_wr2 0 -1 -1 hook_wr3 0 -1 -1 hook_ppu1 1 -1 -1 hook_ppu2 1 -1 -1 hook_ppu3 1 -1 -1 (There's other stuff down here, but just leave it as is). As you can see, we put our RAM address for the clockin there for a hook on write (hook_wr1). What thisdoes is tells ReRecorder to make a note every timethat RAM address is changed, and what ROM addresscaused it to change. This is similar to breakpoints.Save the changes you made to your "hook_log.txt" file.IMPORTANT: You need to close and re-run Gens ReRecordereach time you change this file, so it sees your changes. (^ No longer true as of version r304)- Load the ROM.- As soon as you see the "NHL Hockey 94" title screen, go to"Tools -> Tracer Tools -> Hook RAM". This starts the memory(RAM) tracer.- Now keep pressing the "Start" button (usually the"Enter/Return" key on your keyboard) until the game starts.- Wait until the clock counts down about 3 or 4 secondsand go to "Tools -> Tracer Tools -> Hook RAM" again (or usethe Ctrl+Shift+[period] shortcut key). This stops thememory tracer. Exit Gens ReRecording.The memory trace that you just made for RAM addressFFC469 has been saved to a text file called "hook.txt".When you open up "hook.txt", this is what you shouldsee...(NOTE: if you had 10 minute periods, you'll see 0258.5 minute periods, 012C. 7 minute periods, 01A4)MEMORY ACCESS LOGGING STARTED[01:730A] W32 = 00000000 [FFC468][00:7830] W16 = 0258 [FFC468][00:7830] W16 = 0258 [FFC468][01:5DFC] W16 = 0257 [FFC468][01:5DFC] W16 = 0256 [FFC468][01:5DFC] W16 = 0255 [FFC468][01:5DFC] W16 = 0254 [FFC468]MEMORY ACCESS LOGGING STOPPEDThere's some very useful info in this file. A quickbreakdown:[01:730A] - this is the address of the instruction inthe game ROM that wrote to the RAM address we traced.It is usually not exactly right, but close.W32 - "W" means "write." "R" means "read"."W32" means it was a write of 32 bits. W16 meanswrite of 16 bits.00000000 - the value written to RAM[FFC468] - The address of the RAM that was writtento. Notice that it's FFC468 not FFC469. So the gameactually wrote to FFC468 (and the number size was biggerthan 8 bits, so also modified the next byte(s))Next I'll show you how to use the info in the "hook.txt"file to find the ROM addresses we're looking for.Tony.P.S. Let me know if there's something I didn't explaintoo well.(See next message for more...) 1 Quote
smozoma Posted August 28, 2010 Report Posted August 28, 2010 Part 2 of Tony's guide, updated for new tools In this section, you see CPU instructions. If you want to learn about the instructions, try either of these tutorials: tutorial one tutorial two (no particular order.. use the one you find easier..) ----------------------------------------- Glad to see some interest in this post. That will help motivate me to finish. Okay, lets get started again. In my last post, here was the memory trace we made: MEMORY ACCESS LOGGING STARTED [01:730A] W32 = 00000000 [FFC468] [00:7830] W16 = 0258 [FFC468] [00:7830] W16 = 0258 [FFC468] [01:5DFC] W16 = 0257 [FFC468] [01:5DFC] W16 = 0256 [FFC468] [01:5DFC] W16 = 0255 [FFC468] [01:5DFC] W16 = 0254 [FFC468] MEMORY ACCESS LOGGING STOPPED (NOTE: if you had 10 minute periods, you'll see 0258. 5 minute periods, 012C. 7 minute periods, 01A4) Here's what each of those lines mean... [01:730A] W32 = 00000000 [FFC468] This one just sets the value to 00000000. nothing we need. [00:7830] W16 = 0258 [FFC468] This one tells us which ROM address moves the value 0258 to our RAM address for the clock. 0258 is a hex number. 0258 = 600 in decimal. There are 60 seconds in a minute, so 600 divided by 60 = 10 minutes. 10 minutes is the amount of time that is on the clock when the game started. We can use the ROM address in this line to help us find the actual ROM address we're looking for (the ROM address to change the amount of time you start the game with). [01:5DFC] W16 = 0257 [FFC468] This one tells us the ROM address that is subtracting one number from the clock value for every second that goes by. We can use this ROM address to help us find the instruction that is causing the clock to count down. By changing this instruction, we can stop the clock (infinite time). This is where a little 68000 assembly knowledge can be helpful. [01:5DFC] W16 = 0256 [FFC468] Same as above, except one second less. [01:5DFC] W16 = 0255 [FFC468] Same as above, except one second less. And so on. After you've done several of these memory traces, you can quite often just open up the ROM with a hex editor and go to the ROM address listed and figure out what you need to know. For example, I can open up my NHL94 ROM with a hex editor, go to ROM address $015DFC, and instantly see what instruction I need to change to have infinite time. But since learning how to read raw 68000 assembly is something most people don't want to do, here is how you can make an assembly trace log that will show you everything that's going on in the CPU, and send it all to a text file in a "relatively" easy to read format. When you first see your assembly trace log, it's easy to be overwhelmed by all the crap in there, but don't let it scare you off. After you get used to it, it's not really that hard to understand. An assembly trace log is getting down into the real nuts and bolts of how a Genesis game works. If you can learn how to "read" it, you can find all kinds of very useful ROM addresses. Okay, here's how to make an assembly trace log. Open up your NHL94 ROM using Gens ReRecorder. Get to the first option screen (the one where you can change Play Mode, Per Length, etc). Go to "Tools -> Tracer tools -> Trace" (or press the Ctrl+Shift+/ keyboard shortcut. This starts the assembly trace log (which slows the emulator down). Now press your "Start" button 3 times so that you're on the ice and ready to start playing. Wait for the clock to count down a few seconds and then go to "Tools -> Tracer tools -> Trace" again to stop the assembly trace log. Exit Gens ReRecorder. Your newly created assembly trace log has been sent to a file called "trace.log" Keep in mind that the Genesis CPU is operating at about 4Mhz (roughly 400,000 instructions per second) so the trace.log files can be very big. Gens ReRecorder is different from the old trace tool: if you make a second trace, it will not overwite the old trace.log, but will append the new trace to the end of the old one. So, the file can get really really big if you run several traces. I like to rename each trace file to something that describes what I was looking for when I made the trace. Then if I make another trace, they are separate. Now lets open up our new Trace.log file and take a look at it. I recommend using something like Notepad++ or MS Word to open it with. We'll start off by figuring out how to make the game have infinite time. When you have the file opened, use the "Find" option and type in 01:5DFA. Here's how I came up with that number... Look at the memory trace we made: [01:730A] W32 = 00000000 [FFC468] [00:7830] W16 = 0258 [FFC468] [00:7830] W16 = 0258 [FFC468] [01:5DFC] W16 = 0257 [FFC468] [01:5DFC] W16 = 0256 [FFC468] [01:5DFC] W16 = 0255 [FFC468] [01:5DFC] W16 = 0254 [FFC468] See where it shows the time starting to count down... [01:5DFC] W16 = 0257 [FFC468] [01:5DFC] W16 = 0256 [FFC468] [01:5DFC] W16 = 0255 [FFC468] [01:5DFC] W16 = 0254 [FFC468] 0257 seconds 0256 seconds 0255 seconds 0254 seconds The ROM address shown for each time a second is subtracted is always the same: 01:5DFC, so we know that the instruction we're looking for is near by that ROM address. The way that this memory trace works, you usually need to subtract 2 from the ROM address listed. So to get the ROM address we need to look for in our Trace.log file, we just need to subtract 2 from 01:5DFC => 01:5DFA. That's how I came up with the number to put in the "Find" box. Alright, back to the Trace.log file... type in the ROM address we're looking for (01:5DFA) into the "Find" box and click on "Find Next". Your first match should look like this: 01:5DFA 53 78 SUBQ.W #1,($C468) A0=FFFFBDEC A1=FFFFCA32 A2=FFFFC6CE A3=FFFFB74A A4=FFFFB892 A5=FFFFB8B4 A6=FFFFC060 A7=FFFFFF62 D0=FFFF0100 D1=00000122 D2=00000000 D3=00000183 D4=00000006 D5=0000000C D6=0000000A D7=00000001 XNZvC This tells us exactly what we need to know to give us infinite time. SUBQ.W #1,($C468) means that it is subtracting 1 from RAM address $C468. If you remember, FFC468 is our RAM address for time. All we have to do to get the clock to stop counting down (inf time), is figure out how to kill that SUBQ.W instruction. We can easily do this by changing the "53 78" opcode shown above to a branch opcode (6002) instead. This will make the game jump right over the subtraction part. We can test this out by making a quick Game Genie code... MAKE A GAME GENIE CODE TO TEST IT (smozoma: Or, go to the next section where you edit the ROM instead) (smozoma: NOTE: I can't get the game genie codes to work in Gens ReRecorder... so just go to the next section!) Just use a Game Genie conversion program (you can get one from my (Tony_H's) web site): 015DFA:6002 = AKRT-CA94 015DFA is the ROM address, and 6002 is the replacement opcode. Because it is beyond the scope of this guide, I'm not going to go into how I came up with 6002 for the opcode to kill the subtraction. This is where some 68000 assembly knowledge is helpful. Here's a quick tip... using a branch opcode (usually 6002 or 6004) is the most common way to kill many opcodes (subtraction, addition, etc). 6002 will "jump" 2 bytes, and 6004 will "jump" 4 bytes. You'll usually want to jump to the next opcode. NEVER jump to an operand (this can cause the game to freeze). Anyways, if you try our new Game Genie code (AKRT-CA94) with your favorite emulator, or on a real Genesis, you'll see that you now have infinite time. A little short cut... Gens emulator will let you enter Game Genie codes in raw format, so instead of converting the ROM address and opcode into a Game Genie code, Gens lets you enter it like this: 015DFA:6002. Saves a little time. EDIT THE ROM TO ADD THE HACK You can easily hack infinite time into your ROM by going to ROM address 015DFA and changing the 5378 to 6002. Of course you'll also need to hack the master code too (or else you'll get a blank screen) (smozoma: this is why I say to use the Maha/swos ROM or any other edited ROM, since it'll have the checksum removed so you don't need "the master code"). Well, that's it for now. Next we'll find out how to find the ROM addresses for period lengths. I'll also explain what some of that stuff is in the assembly trace log. Tony. P.S. As always, if something is confusing, let me know and I'll try to explain it better. ------------- I (smozoma) made a program called "trace nice-ifier" that makes the trace files in this tutorial a little easier to read. Here it is: trace nice-ifier.zip Download and unzip to location of your choice. Drag-and-drop a trace.log file onto "trace_niceifier.exe" It'll create another file called trace.nice.log that'll be a bit easier to read. 1 Quote
kingraph Posted February 4, 2013 Report Posted February 4, 2013 In this section, you see CPU instructions. If you want to learn about the instructions, try either of these tutorials: tutorial one tutorial two (no particular order.. use the one you find easier..) FYI, tutorial two is dead. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.