(Original guide by Mustapha)
This guide is intended to show you how to get the options and sound menu that was in Sonic 2 and leftover in Sonic 3. For those of you who have been living under a rock, Nemesis a long time ago discovered a way to load the Sonic 2 menu remains in the form of a savestate. Now I'm going to show you the result of nearly a months work by having it loaded in ROM. (in a slightly usable) form.
- Binary knowledge.
- Hex Workshop (Recommended)
- Sonic the Hedgehog 3 rom in .bin format.
- saxman's Sonic 2 Hacking Guide.
- Ambil's ASM to hex guide.
- Ambil's binary knowledge.
- drx's i/o guide.
Now now, I'm sure you want to know how this was done..well it's time I tell you. :P
What the hell started this?
I was looking around in saxman's guide just to "reinfluence" my hacking again. Yea, the boss stuff kind of got boring and repetitive afterwards. Anways, when I got to the point called "Advanced Configuration", something snapped. It was that weird fire inside that tells you.. hack hack hack!! I started with the first visible section: Screen modes. I fucked around in a savestate for a bit, but that died fast, I wondered... How could I make my changes permanent. I then started to experiment around with Sonic 2 and Sonic 3.
So, I noted the RAM address that saxman noted down for the current screen mode. I ran a search for it in ROM... Results! I started editing until I fucked up the Sega screen - Bingo! I then messed around with the surrounding bytes. I soon learned that it was done through a simple move instruction that added the screen mode ID to F600. Thanks to my weird logic and way of finding things, I find out the machine code syntax, which is 11FC 00XX F600, which after was checked in Ambil's guide to be move.b #$xx,($FFFFF600).w in Assembler. For those who are confused as hell, it's just a simple move instruction.
First of all, you need to know that a screen mode change is a simple move command. The syntax of a screen mode change is as follows: move.b #$XX,($FFFFF600).w in ASM , where XX is screen mode ID that you're looking for. In machine code (which we'll be working with) it's 11FC 00xx F600.
Alrightly, let's get started with this.
- 1) Open your rom in an hex editor, I personally recommend Hex Workshop, but that's just me, you can use whatever the hell you want!
- 2) Do a search for 11FC 0028 F600 in your rom..
- 3) Normally, there will be two instances found. Go to the second one, or $3973.
- 3.5) Change 28 to 24.
- 4) Now, activate the level select cheat (Up, Up, Down, Down, Up, Up, Up, and Up), and go to the sound test mode, voila, you have the S2 option menu. You see, the ID for the level select is 28, while the ID for the options screen is 24. However, you're NOT out of the woods yet, this isn't over, we still have to do part two.
- 5) Now, grab a copy of saxman's S2 guide and go to the advanced configurations section.
- 6) Note down the address that is listed for "Screen mode". If you're a blind dumbass, the address is $011A78 in savestate.
- 7) Take a savestate at the title screen, open the savestate and go to $011A78. The value there will be 04.
- 8) Now, in your ROM, run a search for 11FC 0004 F600.
- 9) Now at $3560, you will do something rather tricky. You will execute a jmp command. We need to jump to offset $200000. jmp in machine code is 4EF9, so write 4EF9 0020 0000. Make sure to write it over 11FC 0004 F600, as inserting will fuck your ROM over.
- 10) Now go to $200000. Now, at this point, we're going to activate the level select cheat by default. Get ready General...
- 11) Expand your rom and write. 21FC 0101 0100 FFD0 -- With this, we're writing a long at FFD0 that activates all the flags for the level select cheats. In ASM, this is move.l #$01010100, ($FFFFFFD0).w
- 12) Now after 21FC 0101 0100 FFD0, write 11FC 0004 F600. This switches our screen mode to the title screen.
- 13) Be sure to end that string with a 4E75 (or RTS)
- 14) Save your ROM, open it in your emulator and you'll see that the level select cheat has been enabled by default. Select the option "Sound Test" and voila. The Sonic 2 options screen appears in its leftover glory.
You can give up now, or you can continue!
This next part will fix the VS option to point to the S3 VS. mode, rather than the leftover S2 one (which doesn't work). If you want to keep it for some unfathomable reason, then skip this step.
- 15) Go back to your ROM and do a search for 11FC 001C F600. (or $6644).
- 16) Go back into your emulator, and head to the competition menu. Select Match Race, and make a save state.
- 17) Now go to $11A78 and note the value (If you're lazy, it's 40)
- 18) Go back to your ROM, and head back to $6651 and replace 1C with 40.
- 19) Go back to your emulator, open the options menu and select VS mode. You should get the character select menu for Match Race. Grand Prix has a few glitches, so we're not going to use it.
Yay, are you with me?
Now, this next part is optional, you can quit at this point, though you should go "the whole mile!" Because without it, you have no entrance to the level select screen. =P
- 20) Now, go to the file select screen and make a savestate.
- 21) Open up the newly created savestate, and go to that amazing address ($011A78) and nab the value (4C)
- 22) Now, search for 11FC 004C F600 in the ROM. It should be located at $395C
- 23) Now, you need to figure out the location of your free space, which should be $200010
- 24) Replace 11FC 004C F600 ($395C) with 4EF9 xxxxxxxx, where xxxxxxxx is the location of your free space. By default, it should be with 4EF9 0020 0010.
- 25) Open up Windows Calculator. Set the mode to scientific, and binary, and input this "11000000". It should give you a C0. This is the button combination of "A" and "Start" being pressed at the same time. This tell you that A and Start are on, but the rest of the buttons are off.
How I got that is simple.
7 6 5 4 3 2 1 0 (this is a byte represented in bits)
S A C B R L D U
(these are the bits translated to show what each key is)
Here we have the key format by Ambil and drx's I/O guide. We want Start and A to be active. So each active one earns a 1 (or on in Binary) and each inactive one earns a 0 (or off in binary) In all, this produces. 11000000.
- 26) It's time to write our code. We are going to use the Compare Immediate instruction for this! (Thanks to icon 68000 Pocket Reference at Eidolon's Inn for the name.)
- 27) Our code will be as follows. cmpi.b #$C0, F604.w or 0C38 00C0 F604. This is a check to see if our current buttons are A and Start.
- 28) Now, our last bit of code will be 6708 11FC 004C F600 4E75 11FC 0028 F600 4E75
- 29) We'll break the last bit down. 6708 is the Branch if Equal instruction. In ASM, this would be beq *label*. What it does is branch 8 bytes if F604 is indeed C0. If not, it'll simply move on with the rest of the code. The next 8 bytes changes our screen mode to the file select, then returns using an RTS (4E75, meaning return from subroutine). The 8 bytes after that change our screen mode to the level select, then returns. This code is executed if our compare returns a positive result.
- 30) Now, open your ROM, and go A+Start while having 1 Player selected and volia, level select.
And there you have it. Magic.
- saxman's guide.
- Ambil's awesome-omatic ASM to hex guide.
- 68000 Pocket Reference
- 68000 Programmer Guide