FCEUd, Tutorial #1 (Hacking Character Stats)

FCEUd, Tutorial #1 (Hacking Character Stats)
by Parasyte of DES (http://www.dragoneyestudios.net/)

1) Warm-Up

   Before beginning, it's best to know what is needed in order to use this
document to it's full potential. First, you must know the very basics of
assembly programming. (The basics are simple, understand each opcode addressing
mode, and each opcode type) You must also be well versed in binary, including
binary math. Overall, not much is needed to start using FCEUd.
   For 6502 assembly documents and tutorials, check out Zophar's Domain and
ROM Hacking.com at the URLs below. As an alternative, search for
"6502 Assembly" in everyone's favorite search engine - Google.

Things you'll need:
 FCEUd (get from http://www.dragoneyestudios.net/)
 Metroid ROM
 6502 ASM docs, available from:

2) The FCEUd Debug Console

   When you load up FCEUd, you'll be treated to the familiar interface of FCE
Ultra 0.81. You will also find a "Debug" option in the "NES" menu. This option
opens the FCEUd debug console. The console is made up of several groups. On the
left, you have the verbose disassembler. In the center, you can find the
program control buttons. Under the program control buttons is the PC control
group. Under that you have the registers and stack dump. In the upper right
corner of the console, you'll see the breakpoint group. Under the breakpoint
group is the program status flags group.
   The verbose disassembler is setup so it will do all addressing mode
calculations for you, given the correct register settings. When you step
through ASM, the disassembler will take the current register values and
calculate everything "on-the-fly." This method of disassembly has it's
disadvantages, but the advantages easily outweigh them. Due to the way which
many games have been programmed, the only guarenteed correct addressing mode
calculation will be performed on the opcode at the current PC. For example, if
you halt the game on address $8096, then only the opcode at $8096 will be 100%
correctly displayed as verbose. Other opcodes will be disassembled correctly.
However, depending on the address mode they use, the extra information could be
incorrect until they are ready to be executed.

   Here is an example of how verbose information can help you. Take this random

$E322:FD 85 51  SBC $5185,X @ $518A = #$8D

   What you are seeing is the address first, followed by the data which makes
up the following opcode. The opcode in this case is "SBC," and it's operands
are "$5185,X." This is obviously an indexed addressing mode instruction. The
next piece of information tells us the actual address which the instruction
will operate on, followed by the data currently at that address. In this
example, the value currently loaded into X is #$05. You could've esily added
the 5 to the address in the operand, but the verbose information should have
you worrying less about figuring out the address which each instruction is
operating on.
   Here is another example, one which would normally take you much longer to
find the operating address:

$E1D7:01 18     ORA ($18,X) @ $0300 = #$00

   Once again, the disassembly follows the same format. The "@" character
symbolizes the operating address, while the "=" character symbolizes the data
at the operating address. In each case, the main purpose of this disassembly
feature is to make it easier for you to hack.

3) A Quick Description of Breakpoints

   A breakpoint is a simple method of powerful debugging. Breakpoitns allow
you to halt a program at any time during execution, and check out what it is
doing. You don't exactly tell the program where to halt with breakpoints, you
actually tell it why to halt. FCEUd supports the 3 most common types of
breakpoints. The original breakpoint, which will halt when a given address is
executed. And read and write watchpoints, which will halt when a given address
is read or written to.

   In the FCEUd console, breakpoints can be added, as well as deleted or edited
in the breakpoint group. Clicking the Add button will open a new window which
will allow you to set a single address, or an address range, as well as the
breakpoint type. To set a single address, leave the 2nd address box blank. To
set an address range, set the first address box to the start address, then set
the second address box to the end address. You can enter up to 64 breakpoints.
   The breakpoint selection box will allow you to select a breakpoint to delete
or edit. Simply click on a breakpoint to select it. To enable and disable
breakpoints, double click them in the breakpoint selection box.

   An address or address range will be shown as a breakpoint in the selection
box after being added. Changing the breakpoint type, or enabling\disabling a
breakpoint will change the breakpoint flags, displayed directly after the
breakpoint address or address range. The flags are listed as follows: "ERWX."
"E" means the breakpoint is enabled, "R" means the breakpoint is set for reads
"W" means the breakpoint is set for writes, and "X" means the breakpoint is set
for executions. When a flag is disabled, it is replaced with a hyphen.

4) Program and Disassembler Control

   The program control buttons will allow you to control how the game is run.
When "Run" is pushed, the game will run like normal until it is halted. (either
by you, or by a breakpoint) The "Step Into" button will systematically run a
single opcode when pushed. This is the button which you use when you want to
move slowly through code to precisely watch how it is working. The "Step Over"
button works the same as Step Into, with the exception that it will 'step over'
sub routines. Stepping over will work exactly like Step Into until you come
across a JSR opcode. When you push Step Over on the JSR, all code inside that
subroutine will be executed as normal until the subroutine exits. (or until you
or a breakpoint halts execution) Due to the way which some games have been
programmed, not all subroutines will exit as Step Over expects. This may lead
to some strange events, such as the subroutine never returning, or the return
address may not be the expect address right after the calling JSR.
   The "Step Out" button will litterally step out of the current subroutine to
the calling code. This is useful in many cases which may not be apparent at
this point in time.

   The disassembler controls allow you to quickly navigate NES memory through
the disassembler. You can Seek the disassembler to any address quickly, as well
as seeking directly to the PC incase you've wondered off and need a quick way

5) Hacking That Bad Chicken

   For this first tutorial, we're going to change Samus' jump height in
Metroid. This is a bit easier than it sounds. The first thing we need is a RAM
address to work with. Since we're messing with jump height, let's use an
address that deals with jumping! I loaded NESten (currently has a better cheat
search than FCEUd :P) and did a simple cheat search. While Samus was on the
ground, not moving, the value was always equal to the last. I would then jump,
and search for "changed" values while Samus was in the air. And then search for
"changed" values when she was back on the ground. I repeated this several times
until I ended up with three addresses: $01EE, $01F0, $0312. I know that any
address in the range between $0100 - $01FF is stack space, so those get
ommited. This left me with just one address - $0312.

   Now that we have an address to work with, load Metroid in FCEUd and open the
debug console. Add a new breakpoint of type "write" with that address. The game
will happily halt as soon as that address is written to. Push Run several times
to make sure no other opcodes write to the address. Here's the address which
snapped the debug console for me:

$E3AE:8D 12 03  STA $0312 = #$00

   It's just a simple STA $0312, big surprise. Now I scroll up a bit in the
disassembler to find what is setting A. Here's what I find:

$E3A7:AD 12 03  LDA $0312 = #$00
$E3AA:18        CLC
$E3AB:6D 14 03  ADC $0314 = #$00
$E3AE:8D 12 03  STA $0312 = #$00

   A value is loaded from our address, cool, and then the value at $0314 is
added to it. The sum is placed into our address. So now, we need to find out
what is setting address $0314. First disable the current breakpoint, then add a
new one of type "write" on address $0314. Press Run and the game will continue
running like normal. Press the jump button, and AHA! The console snaps. Scroll
up some in the disassembler and check out what's going on...

$CFF3:A0 18     LDY #$18
$CFF5:AD 78 68  LDA $6878 = #$00
$CFF8:29 02     AND #$02
$CFFA:F0 02     BEQ $CFFE
$CFFC:A0 12     LDY #$12
$CFFE:8C 14 03  STY $0314 = #$00

   The STY is what snapped the debugger, and those LDYs tells us what value
gets stored to that address! LDY #$12, eh? Let's just change that! To find
this ASM in the ROM, copy down the data which the disassembler shows:
A0 12 8C 14 03. Hex search for this data in the ROM file. I found it at file
address $1D00C. Now All I have to do is change that $12 to something else,
like $15. Save the file and test the hack. Does it work? Well, yes and no.
   If you're up on your Metroid cheating, you'll know what address $6878 is.
It's the address which contains the items Samus currently has. The AND #$02
is checking for the high jump boots! The BEQ will skip that second LDY if
you do not have the high jump boots. So, that means you have two different
values for jump height, depending on whether you have high jump boots or not.

   The first LDY sets the jump height when you do not have high jump boots.
The second LDY sets the jump height when you do have the high jump boots. And
as you may have guessed, the lower the value, the higher Samus will jump.

6) Some Conciderations

   This is only the first of a proposed series of tutorials for FCEUd. All
tutorials will be readily available from DES (http://dragoneye.cg-games.net/)
as they become available. Each tutorial will focus on certain key aspects of
using FCEUd, and 6502 ASM hacking in general.
   It's important to remember that not every game will work like Metroid, and
not every hack will be the same as the last. If you do not keep this in mind,
you may become frustrated when a game does something unexpected. And we all
know that frustration is the hackers worst enemy.

7) Legal Information

   This document is Copyright 2003 Parasyte\Dragon Eye Studios. This doument
may not be modified in any way, in part or whole without permission of the
author. Parasyte and Dragon Eye Studios are in no way affiliated with Nintendo.
Metroid, Samus, NES and Nintendo are registered trademarks of Nintendo.
   Parasyte and Dragon Eye Studios are not responsible for how you use the
information contained in this document. We are not responsible for the fact
that it may eat your homework and your dog. Please brush your teeth.