Chemist's Hacking Method:
Emulator to use: Gens(Version 2.11 at the time of this writing)
http://www.gens.ws/
Neccesary Utilities
ArtMoney Freeware(Version 7.13 at the time of this writing):
http://www.artmoney.ru/e_download_se.htm
1st-time steps:
Download and install both Gens and Freeware ArtMoney
Open Gens, and load the ROM you want to use.
1. Finding a PAR code or Memory Address to use for a ROM hack:
Enter these 5 PAR codes:
FF0000:0005
FF0001:0001
FF0002:0009
FF0003:0009
FF0004:0003
Click all 5, so they're selected(this enables them), then click 'OK' to go back to the game
Now, run ArtMoney, click the drop-down 'Select process' list, and select the process that starts with 'Gens'
Click the 'Search' button.
Click the 'Type' drop down box, and select 'Custom'
Click the '...' button next to the 'Type' drop down box.
Make sure the only check-boxes checked are 'Integer 1 byte', 'Integer 2 bytes', and 'Integer 4 bytes'. Set the 'Type' drop down box to 'Custom', and the 'Bytes order' box to 'Normal'
Click 'OK' to save the changes, and get back to the 'Search' button window.
Set the 'Search' drop down box to 'Sequence of values', then set the 'Number of values' box to 5
Click 'OK' to go to another definition window.
Set the 'Value 1' through 'Value 5' boxes to 5, 1, 9, 9, 3 respectively
Click 'OK' to search
It should find at least 1 match.
If you find more, change a value in the codes used, and search again, replacing the same number in the sequence in the 'Value 1' through 'Value 5' boxes.
Once you get only 1 match, copy the match down somewhere as the 'Start Address'.
Take the match address, and add FFFF to it, and record this new value as well, as the 'End Address'. The reason for this is that genesis memory is FFFF long.
Click the 'Options' button, then click the 'Searching' tab. Put the 'Start Address' in the 'from' box, and the 'End Address' in the 'to' box.
Click the 'Search in address range' box to check it, so you'll only be using that range.
Click 'OK' to save the changes.
Click the 'Search' button again
In 'ArtMoney' freeware, you're limited to fewer search types than with the registered version. You can still easily find an 'Exact value', or use one of it's other search types to find the value you want.
To find a lives counter, use an 'Exact value' search, and search for the number of lives, and if that fails, the number of lives minus 1.
(This is somewhat beyond my ability to explain in detail. You may have to study other guides on programs like ArtMoney in order to gain a good understanding on how to use it.)
If you do find a value to test, double click it in the left window pane, then click the box in the 'F' column to put an 'X' in the box, meaning the value is frozen at it's current value. In the game, lose a life to see if that frozen value is the one that freezes lives at their current value.
From here on, I'll describe an actual game I'm finding a code for, using this method.
The game will be Rocket Knight Adventures (E)
I've already setup the Search Range, which will continue to work for multiple games, as long as I don't close the emulator.
In this case, lives are listed under 'Rest' in the game. It starts at 2, so that's by first search.
I'll use the 'Filter' button with the same value a few times to help reduce the entries. Moving in the game without dying, and filtering again.
I'll lose a life, then use the 'Filter' button again, with a value of 1.
I immediately got a single result from this. I'll freeze it, and die again to test if it's correct. It is. The address is 82A00C.
Subtract the 'Start Address' value from it(81A500 for me), and 82A00C - 81A500 = FB0C. Add FF0000 to it(or, just put FF on the left of the number), to get your PAR code.
The PAR code is FFFB0C:0009 for Infinite 9 lives. A test of the code FFFB0C:0009 in Gens(after I disable the 'Freeze' markers in ArtMoney) shows that it works.
With this working code in hand, we continue on to the Game Genie portion of the attempt.
2. Making a Game Genie code
You can now close ArtMoney if you don't plan to use it again.
Before I begin, know that I use Save-States to make my work efficient, and sometimes they're the only way to make it feasable.
Also know that I was never able to fully comprehend Chemist's method, but this has proven to be a working method.
In Gens, you can manage save states like so:
F5-Save State
F6-Decrement Slot
F7-Increment Slot
F8-Load State
Since I'm going to continue looking for lives, I'll want to get a state near death in one of the slots. I'll put it in Slot 3, in case I need to go back to the beginning.
In this game, it's easy to see exactly when lives are decremented visually. Making a Save-State fairly close to this point is helpful.
Now, for the first incursion into the Debugger environment...
I want to see if the lives address is actually decremented when it's visually decremented.
To get to the debugger you want to view, go to the 'CPU' toolbar, hover over 'Debug', and click 'Genesis - 68000'. This will get you into a text-based environment describing the program.
What you want to look at is the 'xx MAIN 68000 MEM xx' area in the lower-left area of the screen.
Each of those numbers represents the last 4 digits of an FF???? PAR code address. the PAR code for Lives was FFFB0C, so you need to navigate to the place FB0C is shown.
Memory Window Movement Keys:
R-Up 1 Line
F-Down 1 Line
E-Up 12 Lines
D-Down 12 Lines
W-Up 144 Lines
S-Down 144 Lines
Navigate to a line that starts as close to a point before FB0C as you can find.
In my case, it's FB08. Every set of 2 digits represents 1 byte, or +1 to the address at the start of the line. In the case of the PAR code, 2 bytes are written at once, so count by 2 by looking at the space between sets of 2 bytes. The third set from the right is the Lives value.
Now that the location of the value has been determined, you'll use this as a test.
As soon as possible after the lives visually change in your Save-State near dying, check to see of FB0C has changed.
In this game's case, it has, so you have a general time frame to activate the debugger for easiest debugging.
This method of visual testing can also be used to find the exact moment something changes, which can help you immensely.
Get as close as you can to the value changing before you click the 'CPU' toolbar, which freezes emulation at that moment. If you feel you're close enough, continue the process to open the Debugger for the 68000.
Now that you're in th debugger, you'll need 2 more Save-State's for your ease. Press F6/F7 to navigate to a slot you can use, and Save a State while in the debugger, to 2 different slots.
The point in the process you choose to update them is really up to you, but I'll explain my preferences later on.
Debugger Tracing Keys:
T - Trace 1 command
Y - Trace 10 commands
U - Trace 100 commands
I - Trace 1000 commands
O - Trace 10000 commands
P - Trace 100000 commands
The next step in the process is to press, and hold, 'P'.
More likely than not, you'll get stuck on 1 piece of code, where you can't go any farther in it. The short answer to the solution is to recode the part that you get stuck on, meaning the 'Branch' instruction (B?? #$FC, usually). The long answer is as follows:
Instructions like 'B?? #$FC' that you get stopped at are part of the 'Vector' or 'Vertical Interrupt' cycle. The main program executes until this moment. When the job of main program is done, it enters this cycle, waiting for the interrupt.
When the video processor has drawn the entire screen (60 times in second, because it's 60 FPS), it sends the signal to the m68000.
What needs to be done is to disable this cycle, so the program can continue. 4E71 is the NOP code for Genesis, so if we replace the Branch with 4E71, the program will be able to continue.
In my case, I run into the following such address first: 03CA
So, I make a code 0003CA:4E71, add it to the File>Game Genie menu, and enable it by selecting it. You may want to name the code 'Disable empty cycle', or 'DEC', since these codes represent a way around these empty cycles.
Save-states are helpful at this point, because of what you need to do after you have the code active.
With the code active, go to CPU>Debug and click the checked option Genesis - 68000, which will exit the debugger. Immediately repeat the steps to enter the debugger, and load the state you saved near death while you were in the debugger.
The reason you need to exit the debugger after you enter codes is that the debugger doesn't recieve the changes the codes make until it's been exited and entered again.
I'll repeat the step of holding 'P', and recoding every Empty Cycle branch with a 4E71.
If recoding empty cycles leads to a 'Dead end' of coding that can't really be escaped using more GG codes, try to make Save-States even closer to the point the address changes while out of the debug menu. In the course of making this code, this is what I've already had to do.
If holding P changes the value you want to change, regardless of whether it hits a Dead-End or an Empty Cycle, then you're ready to find a GG code address.
If you can get the value to change by holding 'P', you should reload the most recent save-state you made, and update your 2 'working' Save-States with the loaded one.
I'm to this point now in this game. I left the codes on while I made the Save-States, so I'm still ready to go.
Now, it's a simple numbers game, when put into context.
It'll be a certain combination of Ps, Os, Is, Us, Ys, and Ts that lead you to the code that changes the address.
I'm back to the start of the save-states, and I'll count out the number of button presses I need to do to change the Lives value in the memory window...
1 P changes it, so 1-1=0. Push P No times when you load the Save-State next time.
1 O changes it. No Os.
1 I changes it. No Is.
2 Us change it. 2-1=1. Push U 1 time.
I'll press U 1 time, then save my 2 'Working' Save-States.
From the new Save-States, press Y until it changes.
1 Y changes it, so No Ys.
5 Ts changes it, so reload and do the following:
0 Ys
4 Ts
The instruction you're on is what Decrements the lives value:
1195E SBCD -(A2),-(A0)
The line number of the instruction following this one is 11960. This means that the instruction at 1195E is only 2 bytes long.
This can be accomidated in a single Genesis Game Genie code. The reccomended way of removing a 2-byte instruction is 4E71. You can jump over a longer instruction by coding the value 60??. the ?? can't equal 00, but you can jump over a 4 byte instruction by making the first 2 bytes of the replaced instruction 6002. 60?? can also be used to jump forward up to 7F bytes. Using the address following where the 60?? will be inserted, subtract that address from the address you want to jump to. If the number is less than 7F Hex, then you can code a single Game Genie code to jump over all of it.
I'll use the Game Genie Code Convertor 4.0 (http://www.angelfire.com/nc/ugetab/GGAssembly.html) to make this work.
Using that program, 01195E:4E71 produces the code RENT-C6W8
That's the last step. When you have a Game Genie code(or multiple Game Genie codes) that work, you're done.
You should note the code for the European version won't work for the US version. This is almost always the case for region differences.
Ugetab's Additions To This Method:
Pre-requisites:
Understanding of disassembly code.
A genesis ROM to disassemble.
A PAR code that has some effect on the thing you want to change.
genSuite (Can convert SMD Roms to BIN. http://mipagina.cantv.net/tomman/genSuite/gs_en.htm)
Sega Genesis Disassembler (Note: The following disassembler isn't designed to handle 32X games. It will disassemble part of the code, but it appears to fail with the other type of assembly in the file.)
http://www.classicgaming.com/epr/genesis.htm
Download sega-asm.zip
There are other documents you can download also.
GenRomSuite(This program can convert an SMD formatted ROM into a BIN formatted one, so it can be decompiled)
http://mipagina.cantv.net/tomman/genSuite/gs_en.htm
This is a DOS-prompt based program.
Learn how to use a DOS-prompt program correctly.
If you simply double-click on the disasm program, it'll flash a black screen for a second. This is not an error on the program's part.
If your ROM is ends with .SMD, then you'll need to use genSuite to convert it to .BIN format before you can get meaningful data from disassembling it.
When disassembling a file, use this format:
disasm -a -x (source ROM file) (storage file for disassembly)
The -a and -x allow you to find the address of the code to change, and shows you the original value of the assembly code in the file. This is essential, as far as I'm concerned.
Get OP Codes from within the disassembled game, to make your life easier. The OP codes are the first 2 bytes worth of code on the line.
If you're not inserting a JMP or an RTS, make sure that, when partially replacing an instruction, you replace the rest of the partially overwritten instruction with NOPs. If you don't do this, you could end up with perfect coding for the effect, but imperfect resulting code, because the game will do something unexpected or invalid after partially changing the code, and that almost always crashes the game, or less often, only has an undesireable effect, or even less often, has no immediate effect on the game.
---
Get and use PAR codes whenever possible. A PAR code usage example would be:
FF0123:1234
FF0123 is the address of this PAR code.
Also note that this address isn't going to be found in the ROM, even if it is accessed.
The actual address to search for is FF0122. If the address on a PAR code isn't Even(Even = (Address Modulus 2 = 0)), subtract 1 from the address.
With FF0122, arrange it as such:
$00FF0122
Search for that string to find places where the value gets read from or written to.
If you find no occurances of $00FF0122, then trim the first 4 numbers out of the address, so that is looks like $0122, and search for that.
If that also fails, you could be dealing with code that is something to the effect of:
MOVE.W #$0003,$005C(A2)
meaning, essentially, the address is 5C + Register A2, where Register A2 is unknown.
If you use the Gens debugger, you can sometimes make a calculation based on the existing values in the A# registers when it's almost ready to affect the change you're searching for, and often times, a short while after the change has been affected. You only need to worry about tests that check for values after the address of the A2 register. If the first 2 bytes of the register are 00FF, or FFFF, it's a plausable memory address register to use.
The above line of disassembly is part of Megaman: The Wily Wars, which determines whether or not to allow access to the Wily Tower game.
I defeated this particular system by converting addresses for values that are consistent from the save-state file, and searching for those exact values, used within 1 page of each-other. That would have given me the A2, except when I found Write code for all 3 values in a row, with a test for "#$0003", I skipped the A2 calculations, and went for the juggular with a code. The code worked, so I posted it.
I also use Decompilations to track known memory modifying addresses, such as knowing an address is affected by $002C(A5), so I search for all occurances of that modifier. I used this to find the instruction in the routine that removes all your health in Megaman: The Wily Wars. Someone else hacked an Infinite Health code, so I used the info to make codes until one of the made it so you didn't lose health by touching spikes. Once I had that, I made it so all of the related code was always skipped, which made you invincible to spikes.
Megaman: The Wily Wars:
Can always access Wily Tower game(This works for new and existing saves):
ATNA-CAFG
I use Fusion/Gens-compatible save states for my code entry and for the Save-State files I read from. These calculations won't access the total memory for a 32X game's memory, even if you do find the area in the Save-State that allows you to change what you want.
You may get lucky, and be able to get codes for a portion of a 32X game, but the 32X games almost always hold something important in an area where PAR codes can't reach.
My Genesis Save-State to PAR Code/Memory Address calculation is as follows:
Replace (Address) with the address you want converted to a PAR Code/Memory Address.
For Hexidecimal Addresses:
Set Calculator to Hex
((Address) - 2478)+FF0000=
Copy Code
Or...
For Decimal Addresses:
Set Calculator to Dec
((Address) - 9336)+16711680=
Set Calculator to Hex
Copy Code
---
When converting a ROM address into a PAR-style code, the values of the disassembled OP codes should be put in exactly as seen in the disassembled Hex codes.
Instructions list I've used a lot, across all systems I've hacked for follows. Note that these are Genesis OP codes only. Don't try sticking them into a Gameboy GG code or anything of the sort.
NOP - 4E71
RTS - 4E75
Xs = Exact ROM Address to jump to:
4-Byte JMP Instruction(limited to $0000-$FFFF):
4EF8 XXXX
6-Byte JMP Instruction(limited to $00000000-$FFFFFFFF):
4EF9 XXXXXXXX
Branch Always(A Small Mini Jump, if it's needed. 00-7F = Forward, 80-FF = Backwards):
60XX
See the game's code for other instructions, and so that you can deduce their useage.
--------
PAR Code Creation:
I've debugged and tested my alghorithm some more, and also learned a bit more about the Genesis PAR format.
I'll return to my previous example:
FF0123:1234
The above code won't work correctly. It's not an even number, so you have to split the code into 2:
FF0123:12
FF0124:34
If the code was an Even number, such as what follows, then it would be perfectly fine to use 2 values in the code:
FF0122:1234
Also, if you have a big string of stuff to put into memory with PAR codes, and it starts on an odd number, use this method:
FF0123:01
FF0124:0203
FF0126:0405
FF0128:06
The first code in the above set takes care of the 1 odd number, while codes 2 and 3 deals with the information on an Even-number basis. The last code enters the final byte of information in an attempt to keep from modifying data at address FF0129, which could hold information on something that shouldn't be changed.



Reply With Quote


