·( Rom hacking from PAR codes )·

This page will show you how I, as someone who really doesn't understand assembler much at all, took a Pro Action Replay cheat code, and used it to hack a game, to make it easier to rip the music.
-Maxim

Dragon Crystal title screen The problem

I wanted to play through Dragon Crystal (partly to rip the VGMs, partly to see how it ends). But I'm not that good at it. I could play it a lot, practice day and night, hone my skills to perfection and then be able to battle through the game; but I'm a busy guy. So I wanted to cheat.


Game Gear Pro Action Replay (photo by Rid Hughes) Step 1: look for a cheat

My laziness knows no bounds; I started by looking for existing cheats. Well, there are none built in to the game, and I couldn't find anything useful. But I did find this...

00C6 2160 Unlimited hit points

It's a Pro Action Replay code. A PAR is a device which plugs between the console and cartridge and enables you to cheat in games - the Game Gear one is shown to the right. I know enough about them to know that this basically means that the game stores the "hit points" (I'll call it energy) in RAM at offset 0xC621. That's a hexadecimal number; if you don't know anything about them you might want to read the box on the right below.

All PAR codes store the required offset in the middle four digits. While there's currently no VGM-logging emulator which supports PAR codes, it can be useful for easy rom hacking...


Hexadecimal numbers

Normal (decimal) numbers count from 0 to 9, before increasing the second ("tens") digit. We use this "base 10" system because we have 10 fingers. Hexadecimal (often abbreviated to "hex") numbers count from 0 to 9, then A to F, before increasing the second ("sixteens") digit. This "base 16" system is used when dealing with computers because it is compatible with binary numbers (base 2) which computers use. It's compatible because one hex digit corresponds to 4 binary digits, so one byte can be represented by 2 digits; one decimal digit corresponds to about 3.322 binary digits which is no use at all. (Mathematical note: the number of digits in base a represented by each digit in base b can be shown to be given by log b / log a.)

You can convert between hex and decimal (and other number bases) using a scientific calculator. Windows' calculator will do this quite easily.

If a hex number happens not to contain any letters, you wouldn't be able to tell if it was decimal or hexadecimal. So various notations are used to signify a hex number:

Put 0x before0xc621
Put $ before$c621
Put & before&c621
Put h afterc621h

I tend to use the first (because it's the notation used in C) or the second (used in Delphi, and by the disassembler used on this page).

Also, the case of the letters doesn't matter. It's just easier to type 0xc621 than 0xC621.

Part B: Disassemble!

Now, to hack a rom you must first disassemble it. This basically turns stuff like this:

4E 06 00 EB 21 20 C0 09 22 A4 C0 13 1A 32 A3 C0 1B EB
(unintelligible code from a Master System game)

into this:

ld     c,(hl)          ; 000475 4E 
ld     b,$00           ; 000476 06 00 
ex     de,hl           ; 000478 EB 
ld     hl,$c020        ; 000479 21 20 C0 
add    hl,bc           ; 00047C 09 
ld     ($c0a4),hl      ; 00047D 22 A4 C0 
inc    de              ; 000480 13 
ld     a,(de)          ; 000481 1A 
ld     ($c0a3),a       ; 000482 32 A3 C0 
dec    de              ; 000485 1B 
ex     de,hl           ; 000486 EB 
(the same code made marginally less unintelligible)

To do this, you need to download a disassembler from the S8-Dev tools section. For this page I used z80dasm (because I like the way it formats the information) but they're all much the same. Then you need to disassemble the rom using a commandline like this:

z80dasm "Dragon Crystal.sms" > dragoncrystal.asm

This program will disassemble the file to the screen, so I added that > filename to send it to a file instead. This is the kind of thing you'd know if you'd been using computers before 1995...

Then I opened the dragoncrystal.asm file created; it's a big file (4MB), so I used Word because it can handle it much better than WordPad, let alone Notepad. If you have Windows XP, maybe you'll be OK with Notepad. I then used the Search feature to look for c621; there's 57 or so. That's a lot. But I do know a tiny bit of Z80 assembler, mostly thanks to Mike G and Bock, and a bit more about how computers work. I know that if it stores the energy in 0xc621 then some of the time it will read from there, and sometimes write to there. If I can stop it writing to there when it wants to decrease it, the energy will never decrease. I know that to write it has to use a command like this:

ld ($c621),?

Registers and a tiny bit of Z80 assembler

Because of the way it works, the Z80 CPU inside a Master System or Game Gear has to use registers as go-betweens when it wants to alter values in memory. Basically, registers are a small number of memory locations inside the processor. They have names like A, B, C, D, E, H and L; each stores one byte. Some can be paired up to make 2-byte stores, and are referred to by the two letters together, like BC and HL. To change a value in memory, you use code like this:

ld a,($c123) Load A with the byte stored at 0xc123
dec a Change its value (in this case, decrease it by 1)
ld ($c123),a Write it back to memory

My scheme for hacking the rom is to remove this last line.

where the question mark could be various things - generally a or hl or something like that (see the box on the right). The ld is short for load - this command means, "load 0xc621 with ?". So I searched for ld ($c621), instead. Well, there are 21 of those. So 21 times in the game, it writes to that memory location.


Stage III: Waste some time

I then tried to look at the places where that code was, trying to understand what was going on. Some of it I understood, as you'll see below, and some I didn't. Anyway, it wasn't much use, but it took me plenty of time. I hope some of it was helpful to me in some way, but...


Fourth level: Trial and error

The disassembly tells me this, for the first line found when searching:

    ld     hl,$03e7        ; 000CA8 21 E7 03 
    ld     ($c621),hl      ; 000CAB 22 21 C6 
Can you follow this? Load register hl with the value $03e7 (999 in decimal); then load our memory offset with that. I can see that getting rid of this won't be much use; getting 999 energy would be useful, so I don't want to stop it happening. Also, I know that that doesn't actually happen in the game so this must be something else. The next match does the same, but with $0064 (100). In fact these two situations appear quite a few times. I tried changing the 100s to 999s, and did find the one setting the initial value, but the game became quite buggy.

So I searched again, looking for more complicated code. When I did, I tried deleting the line writing the value to memory. To delete something in assembler, you need to turn it into nop (no operation) codes; for the Z80, this is 00. So, to get rid of this:

    ld     ($c621),hl      ; 002D64 22 21 C6 
I need to write three 00s starting at offset 0x002D64. I could do this to the file, using a hex editor, but instead I'll use Meka's patching feature. I opened meka.pat, and at the end I added a section like this:
[6C4E00641D7F6ADC]
seek,2D64
write,00
write,00
write,00
You can find the code to put between the square brackets by looking in meka.nam - it's the first 16 characters of the line with the game's name on it. (Notice the hexadecimal number again?)

Then I saved the file, and loaded the game in Meka. And guess what? It didn't work - the energy still went down when monsters attacked me. So I changed the offset to the next suspicious-looking line, and tried again. Several tries later, at offset 0x5346, I had success. So I could play through the game much more easily, and got all the music I wanted. (Well, there's the fact that the game tends to crash before the ending sequence, but that's another story.)

Dragon Crystal ending... note the sophisticated use of French


World 1-5: bonus stage

As it happens I found that the Game Gear version of Dragon Crystal has different music, so I wanted that too. Playing through 30 levels took a long time, so I looked for a better shortcut. How about this?

00C61Fxx Level select

Much better! I can go straight to level 30 this way. This one was much easier - there are only 5 writes to this location; the first is simply loading the value 01 into it, and the rest are more complicated. The first one is the one I want. I changed it similarly to before:

    ld     a,$01           ; 000FEC 3E 01 
    ld     ($c61f),a       ; 000FEE 32 1F C6 
requires
seek,FED
write,1E
The things to notice here are that to change the 01 in the first line, I want to skip over 0xFEC (which contains the "ld a," bit) to 0xFED (C + 1 = D); and that 30 in hexadecimal is 0x1E. I loaded the game and hey presto, it worked. I start at level 30, albeit with crappy weapons and armour, and I can get the music and also (with luck) finish the game before the dragons kill me by applying the famous "Run away! Run away!" principle.

Game Gear Dragon Crystal ending


Chapter vi: almost finished now, don't worry!

So you see, if you don't mind possibly wasting some time, not fully understanding everything you see, and applying a little trial and error once you've got the number of possibilities down to a reasonable amount, you too can hack a game. Just don't do it all the time - playing games properly is much more satisfying and fun. I know I'll come back to Dragon Crystal and play it properly when I have time, because it's quite good.



Return to VGM Tools
Return to Music
Return to SMS Power