How to make Game Genie codes for the Nintendo's NES
Code making overview
First, the ugly but necessary disclaimer: This document is not intended to encourage the use of emulator programs for the playing of illegal games. Please do not download images of games that you do not own. The author will not accept liability for any wrong-doing under the premise of cheat code creating. If you need games to work with, Zophar's Domain hosts several freeware and public domain programs that you can legally download.
That said, let's go over what you will need. You will need an image (aka ROM) of the game you want to make codes for. An emulator for that system is helpful, but not always necessary. You can find emulator software at Zophar's Domain (link above). To find a copy of your game, you will probably have to use a search engine, as the sites move around and generally drop like flies.
On your part, you should have a working knowledge of hex and binary math. Almost every number involved in this process is a hex number, and you must not be afraid of adding 6 and D together. If you are unfamiliar with these concepts, a good place to start is Matt Johnson's assembly math tutorial. (Read every single word, no matter how boring it is--it won't be explained later, but you'll need to know it) You will not be expected to do any real math in hex or binary, however, as both Windows and the MacOS come with scientific calculators that can do it for you.
Next, you should have a hex editor and a disassembler for your system. A graphic editor also comes in handy. Once you find the right place in the game, you will need a numbered list of assembly instructions or a program that looks up the number for you. Finally, you may want a program that converts your hex codes into Genie codes, although you can do this by hand. All are available in the file section.
What we're going to do here is strip your game down to the bone and disassemble it. It isn't necessary to do this, but I find the resulting pseudo-assembly much easier to read than the original raw machine code. When the game has been disassembled, you will have in your hands essentially the source code of the game. Mind you, it isn't going to be pretty, nor will it be easy to follow. We only want to pick at the bits and pieces that affect gameplay.
If you've ever worked with another programming language, you will probably find our "assembly" very crude. Unlike BASIC, C++, or even real assembly, there are no variable or function names. Everything is referred to by a number. It takes a lot of detective work to figure out the number that represents your health, or the number that holds your ammo. Once you find it, though, the rest generally isn't too difficult.
In each section, only those assembly instructions that consistently find their way into Game Genie codes will be explained in detail. A few others that you will see often will be mentioned, and the rest will be left as background color. A number of documents in the file section explain the purpose of each instruction, so feel free to look up any you are curious about.
A look inside a computer
To understand what each command in a program does, you must first understand the way a computer is structured. More specific information will be given in the appropriate section. For now, remember these parts of a computer:
CPU: The "main brain," the thinking cap of the computer. The CPU is the central station through which almost all data passes. It is responsible for running the game's program and for giving the other parts of the system their orders. All of the parts we are concerned with are contained inside the CPU or are closely linked to it.
ROM: The incoming data stored in the cartridge. ROM stands for "read-only memory," meaning that it never changes. Remember the introduction to the Game Genie? You don't change ROM; you replace or side-step it. The cartridge ROM contains the program, the graphics, the sound, and every other permanent component of the game. Small parts of the program in ROM are copied into the CPU to be run; this area of the CPU is called... wait for it... the CPU ROM area!
RAM: The data generated during gameplay. RAM stands for "random-access memory," a fact which you may now forget completely. This is the part that can change during the game, and is used to store changing values such as ammo and screen position.
Registers: Small, fast, expensive bits of RAM inside the CPU itself. The computer can work with the registers much more quickly than it can with the rest of RAM, but the special memory used in them is hard to come by, so there are relatively few registers in the average computer. You will see enough of registers as you read these tutorials that you will want to puke.
Stack: A holding area similar to the registers, but larger and more limited. As the name is supposed to suggest (geek humor, I guess), the stack is similar to a stack of sticky pancakes. You can only put a new pancake on top of the pile, and you can only take the top pancake off. As far as you're concerned, the stack is entirely forgettable.
Explanation of symbols (to be) used
Somewhere along the line, somebody decided that every term associated with this information should be given a cryptic symbol. Then, someone else decided that each term should also be given a cryptic name. I learned the symbols first, so I tend to use those in print. Anyway, each term/symbol/name will be explained in full here. There will also be reminders in the tutorials themselves, so don't try to memorize them all now.
$n
A hex number. $5 is 5, $B is 11, etc.
Immediate: #n
A number to be taken literally. For example, $5 is a CPU address, but #$5 is the actual number. On the NES, #n is always one byte long. On the SNES, it may be one or two bytes depending on the situation.
Program counter relative: L
Used in branch instructions. Instead of specifying an address, this tells the computer how far ahead of its current location to go. L is always one byte long.
Program counter relative long: ?? (I think I used Lq in the program)
Similar to the above, but always two bytes long. Only on the SNES.
Implied: n/a
Used in instructions that aren't followed by a number at all.
Stack relative: S
Instead of specifying an address, this tells the computer to use the current "height" of the stack. Only on the SNES.
Direct page: Z
A one-byte CPU address. On the NES, this is always the address it looks like, i.e. $3C is simply $003C. On the SNES, the starting offset can be moved around, so be careful.
Direct indexed: Z,X / Z,Y
A one-byte CPU address, to which will be added the current contents of the index register (X or Y as stated).
Direct stack-relative: Z,S
Like the above, but it adds the stack pointer--the stack "height"--to Z. Only on the SNES.
Direct indirect: (Z)
A one-byte CPU address that will be looked inside to find the address the computer really wants. For example, if address $5 contains #$12, ($5) really means address $12. Also an oxymoron.
Direct indirect indexed: (Z,X) / (Z),Y
As always, Z is a one-byte CPU address, and X or Y is the index register. With X, Z and X are added together, then the computer gets the number out of the resulting address and uses that as the final address. With Y, it gets the address it wants from inside Z, then adds Y to it. Don't ask me why.
Direct indirect stack-relative indexed: (Z,S),Y
First it adds the contents of Z to the stack pointer. Then it goes to the address given by that number and gets a new number. Finally, it adds Y to the result. Not fun to type, either. Only on the SNES.
Direct indirect long: [Z]
Wish I knew. I think this is like (Z), but it reads two bytes from the address given at Z, then uses that as a new absolute address (see below). Only on the SNES.
Direct indirect long indexed: [Z],Y
Like (Z),Y, but it takes two bytes from the address given by Z, then adds Y to that (provided the above is correct). Only on the SNES.
Absolute: Q
A two-byte CPU address. Again, there are no tricks on the NES. On the SNES, this refers to an address within that page--that is, an address with the same first two digits.
Absolute indexed: Q,X / Q,Y
Like direct indexed, this adds the two-byte CPU address given to the current contents of either X or Y.
Absolute indirect: (Q)
Like (Z), this goes to the two-byte CPU address given and takes the number inside as the address it really wants.
Absolute indirect indexed: (Q,X)
This adds Q (the two-byte address) and X together, uses the result as an address, goes to that address and gets the number inside, then uses that as the final address.
Absolute long: M (probably incorrect)
A three-byte CPU address. Only on the SNES.
Absolute long indexed: M,X
Like the other indexed numbers, this adds the three-byte CPU address given to the current contents of X. I'm not sure why there isn't also a M,Y. Only on the SNES.