<p><spanclass="rvts45">Execution and CPU State</span></p>
<p><br/></p>
<p>Execution is controlled by a series of buttons at the top-middle of the window. These allow you to break (pause) execution and inspect the current state of the NES.</p>
<p><br/></p>
<p>When an NES ROM is opened, it will be normally be running. Most of the debugger window does not update while the game is running. To begin debugging you may click one of the buttons that will break (pause) execution, such as "Step Into", or add a breakpoint.</p>
<li>Run - runs the program continuously until the next breakpoint is hit. The same effect can be achieved by pressing the Pause hotkey which will unpause emulator when it's paused.</li>
<li>Step Into - runs one instruction and then breaks.</li>
<li>Step Out - attempt to run until the current subroutine ends with an RTS; in some cases will behave the same as Run.</li>
<li>Step Over - runs one instruction, unless it is a JSR instruction, which will run until its RTS.</li>
<li>Run Line - runs one scanline before breaking.</li>
<li>128 Lines - runs 128 scanlines before breaking.</li>
<p>When execution is paused, the disassembly view will begin with the memory at the current program counter location (PC) at the top of the window. You can scroll the disassembly up or down to observe the code. Then you can click "Seek PC" to return to the program counter at any time.</p>
<p><br/></p>
<p>You can also use "Seek To" button that will navigate to the specified address. When entering the address, these convenient strings may be used instead of the hexadecimal memory address:</p>
<p>While execution is broken, the program counter (PC) can be edited, as well as the three registers A/X/Y, and the status flags. Normally they should be left as-is, but changing them at runtime can be useful for more advanced debugging.</p>
<p><br/></p>
<p>The contents of memory starting at the stack pointer (somewhere in the range $0100-01FF) is displayed in the Stack frame below the A/X/Y registers.</p>
<p><br/></p>
<p>The current PPU memory address, sprite memory address, scanline, and rendering pixel are displayed below the stack and status flags.</p>
<p><br/></p>
<p>Examples of Scanline number: -1 it means Prerender time, 240 is Idle scanline, 0-239 are visible scanlines, 241-260/310 are VBlank scanlines.</p>
<p><br/></p>
<p>To the right from PPU section there's Cycles counter and Instructions counter that keep counting while the game is running. You can use the information for keeping statistics, for code profiling or writing PPU-synchronized code (e.g. raster effects). You can also make the debugger break automatically based on the counters values. The "Reset counters" button resets both counters to 0.</p>
<p>This large frame takes up the left side of the debugger window. It displays the current contents of memory accessible by the CPU with an automatic disassembly of that data into assembly instructions. The following memory ranges may contain useful data for inspection:</p>
<li>bb - 16k iNES bank, designates which 16k bank from the iNES file is mapped here. Note that the number may be not the same as mapper bankswitching current bank.</li>
<li>mmmm - physical address on the NES CPU data bus.</li>
<li>dd - data bytes belonging to the instruction beginning at this address.</li>
<li>iiii - assembly description of the instruction.</li>
</ul>
<p><br/></p>
<p>When debugging an NSF program, the bank designation will be a 4k NSF bank instead of the 16k iNES bank.</p>
<p>A single instruction may be one to three bytes, and will all appear on the line before the assembly code description of that instruction. An instruction with "= #$xx" at the end indicates the value currently in memory at the address referenced by the instruction (before it executes).</p>
<p>There is an empty column to the left of the memory view. Hovering the mouse here will display at the bottom of the window more detailed information about the location of this code in the iNES file. Left clicking on this column will open the Inline Assembler, which allows you to patch the ROM at runtime. Right clicking on this column will open the Hex Editor, which allows you to directly edit the ROM. Middle-clicking on this column will bring up the <aclass="rvts18"href="GameGenieEncoderDecoder.html">Game Genie Encoder</a> at that address, so you can easily make Game Genie codes.</p>
<p>Breakpoints will break execution when chosen conditions are met. To create a breakpoint, click the Add button in the BreakPoints frame in the upper right corner of the debugger.</p>
<p>Each breakpoint has an address range to watch (use only the left address field if you wish to watch a single byte address). When entering the address of a breakpoint, you can also use convenient strings (such as IRQ) instead of hexadecimal memory addresses.</p>
<p><br/></p>
<p>Check one or more of the options to watch for Read, Write, or Execute at an address. Note that fetching of code from an address will not break as a Read; use the Execute box for this. Breakpoints can be given a name that will appear in the breakpoint window. The condition field can be used to break only on particular conditions; see "Conditional Breakpoints" below.</p>
<p>Double click on a breakpoint in the BreakPoints list to quickly disable or enable it. So you don't have to delete breakpoints to stop them from causing the debugger to halt the game.</p>
<p><br/></p>
<p>A special kind of breakpoints with the Forbid option will prevent any breakpoints from occurring within the specified memory address range. This can be enabled and disabled like other breakpoints.</p>
<p><br/></p>
<p>A quicker way to add PC breakpoints is to double click on the Disassembly where you want to set the breakpoint. Example: when you need to quickly advance emulation to a given line of code, doubleclick on the line in Disassembly window, and the "Add Execute breakpoint here" dialog will appear, click "OK" and then hit "Run", Debugger will break at this line of code.</p>
<p><br/></p>
<p>There is also an option to "Break on Bad Opcode" which will halt execution if a bad instruction opcode is reached.</p>
<p><br/></p>
<p>Finally, you can make the debugger break after certain number of instructions or CPU cycles.</p>
<p><br/></p>
<p>More advanced conditions and automation may be achieved through Lua script breakpoints. See the <aclass="rvts18"href="LuaFunctionsList.html#LuaBreakpoints">Lua reference</a> for more information.</p>
<p><br/></p>
<p>Breakpoints are listed in the following form:</p>
<p>Breakpoints may also have a conditional statement that causes them to execute only if that statement evaluates to true. The conditional breakpoint grammar has this form:</p>
<p>The parser is very strict. All numbers are hexadecimal. Always prefix a number with # for an immediate value, or $ for a memory address. If a memory address needs to be calculated use $[] with the calculation inside the brackets.</p>
<p><br/></p>
<p>Registers A/X/Y are 8-bit unsigned values. Register P is the 16-bit program counter.</p>
<p><br/></p>
<p>Flags evaluate to 1 if set, 0 if clear.</p>
<p><br/></p>
<p>Connecting operators || or && combine boolean terms. Parentheses dictate order of operations.</p>
<p><br/></p>
<p>Example conditions:</p>
<p><br/></p>
<p>Break if register A is less than value at memory address $0005:</p>
<p><spanclass="rvts46">A < $0005</span></p>
<p><br/></p>
<p>Break if the program counter is 8123:</p>
<p><spanclass="rvts46">P == #8123</span></p>
<p><br/></p>
<p>Break if the value at the indirect address on zeropage $10 is not equal to FF:</p>
<p>A list of bookmark addresses can be kept in the Bookmark frame to make memory navigation easier. Simply type a hexadecimal address (or a convenient string, such as NMI) and click "Add" to add it to your bookmarks. Next time you wish to go to this address just double click on the bookmark.</p>
<p>When you exit the emulator, bookmarks are saved in a .deb file. Next time you return to debugging the list of bookmarks will be automatically loaded from the file.</p>
<p>Open the inline assembler by left-clicking in the empty column to the left of the memory view.</p>
<p><br/></p>
<p>The starting memory address is displayed in the PC field at the top of the inline assembler window. Type a line of assembly to add in the empty field just below this, and hit enter. The assembled code of your patch will appear below as you enter each line.</p>
<p><br/></p>
<p>Click Apply to apply your patch to the ROM in memory. Click Undo to remove the last assembled line. After applying a patch, clicking Save will allow you to save this patch directly to the ROM file.</p>
<p>This feature makes it possible to rename addresses in the disassembly window (e.g. $C022) to easily understandable names (e.g. AddHealthpoints). You can also add comments to lines in the disassembly window. You can enable symbolic debugging by clicking the checkbox "Symbolic Debugging".</p>
<p><br/></p>
<p>To use this feature, create name list files (Filename should be like this: *.(bank).nl / *.ram.nl, Example: NES Test Cart (PD).nes.0.nl, NES Test Cart (PD).nes.ram.nl) which contain all names and comments you wish to display in the disassembly window. These are ASCII files.</p>
<p>Every line contains two # characters which separate the three parts of one line: The first part (starting with a $ character) is the address to be renamed. Optionally you can add a "/number" part which marks the offsets as a beginning of an array of the given size (the size must be specified in hex form). The second (optional) part is the new name of that address. Whenever the line of that address is shown in the disassembly window an extra line saying "Name: NewName" is shown above it. Instructions referencing this address, for example JSR $C000 are also changed to JSR NewName1 (in that example). The third (optional) part is the comment that's also added above the disassembly line the comment refers to. It works exactly like the additional name line, only the prefix of that line is different. Comment lines start with "Comment: " rather than with "Name: ". Multi-lines comments are possible. Lines starting with a \ character are just appended to the comment of the preceding line. Multi-line comments are also shown in multiple lines in the disassembly window.</p>
<p><br/></p>
<p>In the example above, the first line contains all three parts. Using this NL file all references to the address $C000 are replaced with NewName1 and whenever line $C000 is shown in the disassembly window an additional comment is also visible right above the actual disassembled line. The second example line defines only a comment while the third line defines only a name. Following that there's a multi-line comment definition for address $C006. The last line defines an array called NewName4 of size 0x10 (= 16) bytes starting at offset $C008.</p>
<p><br/></p>
<p>NL files must follow a specific naming convention to account for bank swapping. Each bank needs its own NL file with a hexadecimal bank number. RAM can also be given its own NL file. For instance, an NES file named "mygame.nes" that has 4 banks would have these NL files:</p>
<p><br/></p>
<p>mygame.nes</p>
<p>mygame.nes.ram.nl</p>
<p>mygame.nes.0.nl</p>
<p>mygame.nes.1.nl</p>
<p>mygame.nes.2.nl</p>
<p>mygame.nes.3.nl</p>
<p><br/></p>
<p>All NL files must be into the same directory as the ROM file itself.</p>
<p><br/></p>
<p>In the *.ram.nl file you can name and comment RAM addresses instead of ROM addresses. In this case, you might use a line such as:</p>
<p>If the ".DEB files" checkbox in the lower right corner of the debugger window is checked, the emulator will automatically save debug settings such as breakpoints and bookmarks in a .deb file alongside the NES ROM, and load these settings next time you open the ROM.</p>
<pclass="rvps2"><spanclass="rvts13">Created with the Personal Edition of HelpNDoc: </span><aclass="rvts14"href="http://www.helpndoc.com/create-epub-ebooks">Full featured EBook editor</a></p>