EnHacklopedia EnHacklopedia » Individual Systems - In Depth » Hacking NES

Hacking NES

Creative Commons License

All files (HTML, CSS, images) included in EnHacklopedia are licensed under the Creative Commons Attribution-ShareAlike 3.0 License. All authors contributing to EnHacklopedia should be made aware of the license before contributing. If the author does not agree to the licensing, his or her contributions will not be accepted into the project.


  • 08-26-2007
    • Revalidated documented, fixed typo. (dlong)
  • 04-12-2007
    • Merged GG sections, added PAR section
    • Added screenshot of NES GG. (dlong)
  • 04-10-2007
    • Added images. (dlong)
  • 04-09-2007
    • Updated Footer, again (dlong)
  • 04-08-2007
    • Updated Footer (dlong)
  • 04-06-2007
    • Initial Release (dlong)

Hacking using FCE Ultra Debug

FCE Ultra Debug's cheat console

FCE Ultra Debug is a highly compatible NES emulator that helps facilitate code hacking. It includes a RAM searcher as well as a debugger. The RAM searcher is labeled "Cheats" under the Tools menu and can also be accessed by the "Shift+F1" key combination. Cheats can be both added, removed, and searched for here. The "Known value" options searches for the specific byte entered in the space next to that button. Below this, the unknown value options exist. If the check box next to any of the bottom three options is checked, then the value is restricted to being with in the difference supplied. The RAM searcher only searches for 8-byte values and performs all searches in hexadecimal.

FCE Ultra Debug's debugger

Also under the tools menu is the debugger, labeled "Debug"; It can also be accessed with F1. On the left is the disassembled 6502 code, with the top instruction being the current instruction to be executed. In the middle are several options. "Run" resumes the game, while "Step in" executes the next instruction. Step out continues execution until the subroutine is exected. Finally, step over skips the next instruction. The "seek to" option simply moves the disassembly to the location specified, while the seek PC moves the disassembly to the PC. Underneath this, the registers A, X, and Y are displayed, with the stack underneath. Finally, at the bottom, PPU and Sprite are listed.

6502 Assembly

The 6502 processor that the NES uses is an 8-bit processor. The 6502 provides 2 8-bit general purpose registers (X and Y), an 8-bit accumulator, an 8-bit stack pointer, an 8-bit status register, and a 16-bit program counter. With only 151 instructions defined, many desirable operations are missing, including any multi-byte operations; multiply, divide, and modulus operations, and several branch instructions. Additionally, the 6502 contains several potentially problematic bugs. The JMP instruction is partially broken. If JMP $xxFF is executed, the PC will not jump to the address stored in $xxFF and $xxFF+1 like it should but rather to the address stored in $xxFF and $xx00. Additionally, the 105 undefined instructions result in undocumented and hard to prevent effects, instead of a NOP or BRK instruction. A list of all the 6502 opcodes and their effects on the NES can be found in the 6502 reference.

Game Genie

NES Game Genie Code Entry Screen


The Game Genie, made by Galoob, is a cheat device, like the Pro Action Replay. However, unlike the Pro Action Replay, the Game Genie patches ROM, whereas the Pro Action Replay edits RAM. For example, a code may patch the address 0x8000 with the value 0x3F. This means that instead of modifying 0x8000 to be 0x3F, instead the Game Genie will watch for the game to access 0x8000, and whenever that happens it will send 0x3F to the location that requested 0x8000. This method, however, has one drawback. Because the 6502 only has a 16-bit program counter, only 64 KB of memory can be referenced at a time. To get around this limitation, the NES employs what is known as "bank switching". Basically, the NES references the entire ROM in 64 KB pages, and when necessary switches the page. What this means is that the assembly code referenced at our location 0x8000 is not always the same. It may refer to 0x8000 or 0x18000 or something else, but all will be patched. This can cause bugs, which is obviously undesirable. To combat this, Galoob provides an 8-character Game Genie code, which an extra byte called "compare". For this example, compare will be 0x5A. What the Game Genie will do is watch the address 0x8000 to be called. When it is called, if the value at that location is 0x5A, then 0x3F will be return. Otherwise, the Game Genie will allow the game to operate as intended. Game Genie codes also have to be encoded. Encoding and decoding Game Genie codes is explained in the sections below. It is worthwhile to learn how to do these operations by hand. However, while not very hard, it is quite tedious. GG Encoder automates this process for you. Finally, decoded Game Genie codes are expressed in the format aabb:cc for 6-character and aabb?dd:cc, where aabb is the address to patch, cc is the patch value, and dd is the compare byte.

Decoding Game Genie codes

Game Genie codes for the NES code in two formats: 6-character and 8-character. In any Game Genie code, only 16 different letters are used: A, E. P, O, Z, X, L, U, G, K, I, S, T, V, Y, and N. Left to right, each of these characters is assigned the bytes 0x0 through 0xF. To decode a game genie code, first rewrite the code in the for of hexadecimal. For example, the code GOSSIP would become 0x49DD51. To get the address out of a 6-character game genie code, the C-style equation is "addr = 0x8000 + ((n3 & 7) << 12) | ((n5 & 7) << 8) | ((n4 & 8) << 8) | ((n2 & 7) << 4) | ((n1 & 8) << 4 | (n4 & 7) | (n3 & 8);", where n0 is the highest nybble, n1 the next highest, etc., with n5 being the lowest nybble. This equation also works for 8-character Game Genie codes. The equations for decoding the data vary slightly between the two formats. For 6-character, it's "data = ((n1 & 7) << 4) | ((n0 & 8) << 4) | (n0 & 7) | (n5 & 8);" while for 8-character it is "data = ((n1 & 7) << 4) | ((n0 & 8) << 4) | (n0 & 7) | (n7 & 8);" Finally, 8-character Game Genie codes have the extra compare byte, which is decoded with "compare = ((n7 & 7) << 4) | ((n6 & 8) << 4) | (n6 & 7) | (n5 & 8);"

Example 6-character Game Genie Code Decoding

Decoding GOSSIP. First convert into hex, which gives us 0x49DD51. Then extract the address: addr = 0x8000 + ((0xD & 7) << 12) | ((1 & 7) << 8) | ((5 & 8) << 8) | ((0xD & 7) << 4) | (9 & 8) << 4) | (5 & 7) | (0xD & 8). This simplifies to 0x8000 + (5 << 12) | (1 << 8) | (0 << 8) | (5 << 4) | (8 << 4) | 5 | 8 = 0x8000 + 0x5000 | 0x100 | 0 | 0x50 | 0x80 | 5 | 8 = 0x8000 + 0x51DD = 0xD1DD. The only thing left to do is to grab the data: data = ((9 & 7) << 4) | ((4 & 8) << 4) | (4 & 7) | (1 & 8) = (1 << 4) | (0 << 4) | 4 | 0 = 0x10 | 4 = 0x14. The decoded Game Genie code is D1DD:14.

Example 8-character Game Genie Code Decoding

Decoding ZEXPYGLA. In hex, this gives us 0x28A17430. Extracting the address is the same as in the 6-character example: addr = 0x8000 + ((1 & 7) << 12) | ((4 & 7) << 8) | ((7 & 8) << 8) | ((0xA & 7) << 4) | ((8 & 8) << 4) | (7 & 7) | (1 & 8) = 0x8000 + (1 << 12) | (4 << 8) | (0 << 8) | (2 << 4) | (8 << 4) | 7 | 0 = 0x8000 + 0x1000 | 0x400 | 0 | 0x20 | 0x80 | 7 | 0 = 0x8000 + 0x14A7 = 0x94A7. Now get the data and compare values: data = ((8 & 7) << 4) | ((2 & 8) << 4) | (2 & 7) | (0 & 8) = (0 << 4) | (0 << 4) | 2 | 0 = 0 | 0 | 2 | 0 = 2; compare = ((0 & 7) << 4) | ((3 & 8) << 4) | (3 & 7) | (4 & 8) = (0 << 4) | (0 << 4) | 3 | 0 = 3. The final decoded version is 94A7?03:02.

Encoding Game Genie codes

Example 6-character Game Genie Code Encoding

Example 8-character Game Genie Code Encoding

Pro Action Replay

Known Value Searching - Metroid - Infinite Missiles

This hack is performed on the Metroid (U) (PRG0) [!] rom. Results on the (E) or bad or overdump versions may be different. Boot up FCEUXD and start a game. Play through the game until you obtain missiles. If necessary, consult GameFAQs. Samus starts off with 5 missiles. This is plenty. Make a save state, just in case. Go to the cheat menu and do a known value search for 5. For me, this cut down the possibilities to 37. Shoot a missile then search for 4. I have 2 possibilies left. You may have more. While it's possible to just go ahead test each possibility, we can try to get rid of one. Walk around for a bit, but don't shoot. Then search for 4. Still 2 possibilities. Shoot another missile. Down to 3. Search for 3. Still two possibilities (0x0000 and 0x6879). Let's test them. Select the first possibility on the far right menu ($0000). Click on it. On the left, the address and value will be added. Click "add". The game froze. This is not good. So the other possibility is likely the right one. Load the save state, at the code, and test. You have infinite missiles.

Basic Game Genie Code - Metroid - Infinite Missiles

While the code just hacked is good for PAR, it won't work with a Game Genie. This section shows how to make the code into Game Genie. Because Game Genie patches ROM, we need to modify the assembly code to give us infinite missiles. We already have a starting point - the address where the number of missiles is stored out - 0x6879. Delete all codes and go to the debug menu. Under breakpoints, click add. In the left address box, put in our address, 0x6879. We're only looking at one address, so leave the right box blank. Underneath this, we can choose whether we want to break when the address is read from, written to, or executed, or any combination of the three. The missile address is subtracted from when a missile is shot, so this qualifies as a write. Choose this and click OK. Click the run button and shoot a missile. The game pauses and the debug menu comes up. This means that one of our breakpoints occurred, in this case our only one. On the left, the disassembly is shown, with the instruction on top being the one just executed. Here it is $D333: CE 79 68 DEC $6879 = #$04. DEC stands for decrement, or subtract one. It is subtracting one from the address given - our missile addresss! The rest is added on by FCEU. This tells you that after the operation, the value at $6879 will be 4. We want to disable this operation. The easiest way is to just NOP the instruction. NOP means nothing happens. While this would certainly achieve our goal, NOP is a one byte instruction (0xEA), whereas this DEC is three. The NOP would have to be used three times. Because the NES Game Genie only allows three codes to begin with, this is certainly undesirable. If only one NOP were to be used, all subsequent opcodes would be messed up. Indeed, here changing only 0xD333 to a NOP causes the game to reset when a missile is shot. Another option is to find some unused memory, and change the instruction so that the decrement occurs there. Opening the hex editor up and going to the 0x6800 block, there is much RAM that appears to be unused, including 0x6800. Our code will change DEC $6879 to DEC $6800. Just as CE 79 68 is DEC $6879, CE 00 68 is DEC $6800. Go in the hex editor to 0xD334 and modify 0x79 to 0x00. When shooting missiles, the missile count does not go down, and there are no apparent side effects. The final step is to format the code. We want to change the byte 0x79 to 0x00 at 0xD334. This makes the code D334?79:00, or AAUIGUPY.