fceux/help/DebuggerUsageIntermediate.html

171 lines
12 KiB
HTML

<html>
<head>
<title>Debugger Usage Guide (Intermediate)</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="HelpNDoc Personal Edition 3.6.0.345">
<link type="text/css" rel="stylesheet" media="all" href="css/reset.css" />
<link type="text/css" rel="stylesheet" media="all" href="css/base.css" />
<link type="text/css" rel="stylesheet" media="all" href="css/hnd.css" />
<!--[if lte IE 8]>
<link type="text/css" rel="stylesheet" media="all" href="css/ielte8.css" />
<![endif]-->
<style type="text/css">
#topic_header
{
background-color: #EFEFEF;
}
</style>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/hnd.js"></script>
<script type="text/javascript">
if (top.frames.length == 0)
{
var sTopicUrl = top.location.href.substring(top.location.href.lastIndexOf("/") + 1, top.location.href.length);
top.location.href = "fceux.html?" + sTopicUrl;
}
else if (top && top.FrameTOC && top.FrameTOC.SelectTocItem)
{
top.FrameTOC.SelectTocItem("DebuggerUsageIntermediate");
}
</script>
</head>
<body>
<div id="topic_header">
<div id="topic_header_content">
<h1>Debugger Usage Guide (Intermediate)</h1>
<div id="topic_breadcrumb">
<a href="FAQGuides.html">FAQ / Guides</a> &rsaquo;&rsaquo; </div>
</div>
<div id="topic_header_nav">
<a href="FAQGuides.html"><img src="img/arrow_up.png" alt="Parent"/></a>
<a href="NESRAMMappingFindingValues.html"><img src="img/arrow_left.png" alt="Previous"/></a>
<a href="Technicalinformation.html"><img src="img/arrow_right.png" alt="Next"/></a>
</div>
<div class="clear"></div>
</div>
<div id="topic_content">
<p><span class="rvts17">Debugger Usage (Intermediate)</span></p>
<p><br/></p>
<p><span class="rvts12">Intent</span></p>
<p><br/></p>
<p>This guide assumes that you have a working knowledge of how to interpret Assembly instructions, and are willing to look up the table of 6502 instructions on your own. This document describes the debugger, and to a much lesser degree, how to tell it what you want to do in terms of the assembly.</p>
<p><br/></p>
<p><span class="rvts12">Main Window</span></p>
<p><br/></p>
<p>In the main window, you'll see lines like this on the left:</p>
<p>1E:80E5:66 FF &nbsp; &nbsp; ROR $00FF = #$9A</p>
<p><br/></p>
<p>This is the disassembly area. The "&gt;" shows current line (usually it's the topmost line).</p>
<p><br/></p>
<p>On the right are Breakpoints, the stack window, status flags, PC and registers data, PPU state data, and several buttons and text boxes.</p>
<p><br/></p>
<p>Of the buttons, the one's you'll likely use the most are Run, Step Into, and Step Out.</p>
<p><br/></p>
<p>"Run" simply makes the program continue operating until it hits a condition that causes it to stop running, or until you stop it manually.</p>
<p><br/></p>
<p>"Step Into" allows you to move to the next line, and if you Step Into a JSR, you'll be taken to the address listed for it to continue running.</p>
<p><br/></p>
<p>"Step Out" attempts to run until the debugger is outside of the function you Stepped Into. This doesn't always work, and may appear to make the emulator 'Run' instead. The next time you use Step Out, it will tell you it will erase the old Step Out watch to do the new one. Press OK to do so.</p>
<p><br/></p>
<p>Other buttons include "Step Over", which basically tries to run to the PC address after the JSR, Run Line, which runs a single VBlank line, 128 lines, which is the last button's action 128 times, "Seek To:" and a text box, which lets you move around the disassembly window quickly, and Seek PC, which orients you back to the code to be run without doing anything else.</p>
<p><br/></p>
<p>Interpreting the line below is as follows:</p>
<p>1E:80E5:66 FF &nbsp; &nbsp; ROR $00FF = #$9A</p>
<p><br/></p>
<p>(1E:) is the bank used. A bank is 0x4000 in size for a .NES file(and 0x1000 for a .NSF file, but don't worry about this for now). 80E5, masked with 3FFF, equals 00E5. 0x1E multiplied by 4000 is 0x78000. Together, this gives 0x78000 + 0x00E5, which equals the address 0x780E5. Add 0x10 to this to account for the 0x10 byte .NES header, and you get 0x780F5, which is what the address is within the .NES file. That is all that this piece of information means.</p>
<p><br/></p>
<p>1E:(80E5) is the address that the data that follows is being read from. The banking stated above allows the same address to show different data, but (1E:80E5) will always be the same address on the same page of data.</p>
<p><br/></p>
<p>If you check the "Display ROM offsets" checkbox, you'll see real ROM addresses instead of bank:address format.</p>
<p><br/></p>
<p>1E:80E5:(66 FF &nbsp; &nbsp; ROR $00FF) is the byte code for ROR, followed by the parameter that tells it to use $00FF. After that is the interpreted assembly code. Note that just because code can be interpreted doesn't mean that it can be run. Even data that's for graphics will inevitable look like code to a certain degree to the disassembly window.</p>
<p><br/></p>
<p>1E:80E5:66 FF &nbsp; &nbsp; ROR $00FF( = #$9A) tells you what the value of $00FF is. $00FF refers to 00FF in RAM, and the value is 0x9A. If the program points to an address in ROM instead of RAM, it still shows the value for you.</p>
<p><br/></p>
<p><br/></p>
<p><span class="rvts12">Breakpoints</span></p>
<p><br/></p>
<p>The breakpoint buttons are Add, Delete, and Edit. These should be self-explanatory. Delete removes the selected breakpoint. Edit will allow you to change an existing entry. Add will open an empty window, which allows you to fill in several details. Double-clicking a breakpoint will enable and disable it, so you don't have to delete items to stop them from causing the debugger to halt the game (the short term for this is called 'breaking' the debugger, referred to in the same way as one would refer to a broken vase). Above the breakpoints list there's current number of enabled breakpoints and total number of breakpoints in the list.</p>
<p><br/></p>
<p>In the Add Breakpoint window, you have 2 Address boxes [ ] - [ ]. You must put in at least 1 value, preferable in the left box. If you want to use a range of values, you can fill in the first box as the start, and the second box as the end. The addresses can be either RAM (0000-07FF), ROM (8000-FFFF), or the special addresses(6000-7FFF, which can be extra RAM, ROM, or unused, depending on game)</p>
<p><br/></p>
<p>The Read, Write, and Execute checkboxes allow you to specify whether to break the debugger when that address is Read From, Written To, or Executed by the CPU. All of them can be checked at the same time if you don't know how the data is used, but are sure it's used somehow. Note that if it's the value to an assembly instruction, it won't cause a break, because the byte itself isn't the start of an instruction, and isn't read by the CPU so much as used for an instruction.</p>
<p><br/></p>
<p>The Option boxes CPU Mem, PPU Mem, and Sprite Mem tell the debugger where to look. The Hex Editor shows CPU Mem by default, but it can show you PPU Mem if you tell it to. PPU Mem is where data is written to display the actual images on the screen, rather than to decide what it is that should be put there. PPU debugging is more of an advanced skill, primarily because when something does go wrong, it's usually because an address outside of the normal PPU address is getting written to and causing very weird graphics errors.</p>
<p><br/></p>
<p>Name is simply a description for the breakpoint that can be seen to the right, if there's space for it.</p>
<p><br/></p>
<p>The "Forbid" option allows you to exclude a range of RAM or ROM from the breakpoint list. These can be enabled and disabled as well.</p>
<p><br/></p>
<p>Condition is part of the Conditional Debugging system. This system is slightly complicated, and extremely powerful when used correctly, and can make extremely hard problems turn into lazy clicking when you understand how to use the feature.</p>
<p><br/></p>
<p><br/></p>
<p><span class="rvts12">Conditional Debugging</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Conditions only apply to the breakpoint they are applied to. You can breakpoint the same address multiple times with different conditions applied to each one.</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Registers: A, X, Y, (P = PC) (A==#12, to break if A = 12) (P!=#804C to NOT break when the PC is on 804C)</span></p>
<p><span class="rvts22">Flags: N, C, Z, I, B, V, U, D (N==#0 for off, N==#1 for on)</span></p>
<p><span class="rvts22">Bank: K (K!=#1E to NOT break when the bank is 1E)</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Addresses: ($0000!=#00 makes it test RAM address 0000, and if it's NOT 00, it can break)</span></p>
<p><span class="rvts22">Numbers: (#0123 is interpreted as 123. It can be used in tests for known values to exclude or include)</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Numerical Comparisons:</span></p>
<p><span class="rvts22">== = Equal</span></p>
<p><span class="rvts22">!= = Not Equal</span></p>
<p><span class="rvts22">&lt;= = Less Than or Equal</span></p>
<p><span class="rvts22">&gt;= = Greater Than or Equal</span></p>
<p><span class="rvts22">&lt; Less Than</span></p>
<p><span class="rvts22">&gt; Greater Than</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Math Operators:</span></p>
<p><span class="rvts22">+, -, *, / (which are add, subtract, multiply, divide)</span></p>
<p><span class="rvts22">If you want to do complex math that involves 5 memory addresses, 2 ROM addresses, and a smattering of defined values, you can use these to do it. I've never had to, but if you want to, this is how.</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Multiple Tests:</span></p>
<p><span class="rvts22">(N==#0||A!=#0 makes it break if EITHER N is off, or A isn't 00)</span></p>
<p><span class="rvts22">(A!=#0&amp;&amp;X==#a5 makes it break is A isn't 00, AND X is A5)</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Brackets:</span></p>
<p><span class="rvts22">$[#2CC + X] == #34: The value of the byte at address $2CC + X is 0x34</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">Parentheses:</span></p>
<p><span class="rvts22">(#1 + #2)==#3 (This evaluates to true, so the breakpoint can break. If you need a different order of operation for math operators, you can use parentheses)</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22">This is what's currently found in the source file for Conditional Debugging:</span></p>
<p><span class="rvts22">P &nbsp; &nbsp; &nbsp; &nbsp; -&gt; Connect</span></p>
<p><span class="rvts22">Connect &nbsp; -&gt; Compare {('||' | '&amp;&amp;') Compare}</span></p>
<p><span class="rvts22">Compare &nbsp; -&gt; Sum {('==' | '!=' | '&lt;=' | '&gt;=' | '&lt;' | '&gt;') Sum}</span></p>
<p><span class="rvts22">Sum &nbsp; &nbsp; &nbsp; -&gt; Product {('+' | '-') Product}</span></p>
<p><span class="rvts22">Product &nbsp; -&gt; Primitive {('*' | '/') Primitive}</span></p>
<p><span class="rvts22">Primitive -&gt; Number | Address | Register | Flag | '(' Connect ')'</span></p>
<p><span class="rvts22">Number &nbsp; &nbsp;-&gt; '#' [1-9A-F]*</span></p>
<p><span class="rvts22">Address &nbsp; -&gt; '$' [1-9A-F]* | '$' '[' Connect ']'</span></p>
<p><span class="rvts22">Register &nbsp;-&gt; 'A' | 'X' | 'Y' | 'R'</span></p>
<p><span class="rvts22">Flag &nbsp; &nbsp; &nbsp;-&gt; 'N' | 'C' | 'Z' | 'I' | 'B' | 'V'</span></p>
<p><span class="rvts22">PC Bank &nbsp; -&gt; 'K'</span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22"><br/></span></p>
<p><span class="rvts22"><br/></span></p>
<p class="rvps2"><span class="rvts13">Created with the Personal Edition of HelpNDoc: </span><a class="rvts14" href="http://www.helpndoc.com">Free PDF documentation generator</a></p>
</div>
<div id="topic_footer">
<div id="topic_footer_content">
2012</div>
</div>
</body>
</html>