debugger.html 78.7 KB
Newer Older
1 2 3 4 5
<html>
<head>
	<title>Stella Debugger</title>
</head>

Stephen Kitt's avatar
Stephen Kitt committed
6
<body>
7

Stephen Kitt's avatar
Stephen Kitt committed
8
  <center><b><font size="7">Stella</font></b></center>
Stephen Kitt's avatar
Stephen Kitt committed
9
  <center><h4><b>Release 6.0</b></h4></center>
Stephen Kitt's avatar
Stephen Kitt committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
  <center><h1><b>Integrated Debugger</b></h1></center>
  <center><h4><b>(a work in progress)</b></h4></center>
  <br>

  <h2>Contents</h2>
  <ul>
    <li><a href="#Features">Features</a></li>
    <li><a href="#HowToDebugger">How to use the Debugger</a>
      <ul>
        <li><a href="#Startup">Startup</a></li>
        <li><a href="#GlobalButtons">Global Buttons</a></li>
        <li><a href="#ChangeTracking">Change Tracking</a></li>
        <li><a href="#PromptTab">Prompt Tab</a>
          <ul>
            <li><a href="#TabCompletion">Tab Key Auto-Complete</a></li>
            <li><a href="#Expressions">Expressions</a></li>
              <ul>
                <li><a href="#Prefixes">Prefixes</a></li>
              </ul>
            </li>
            <li><a href="#BreakpointsEtc">Breakpoints, watches and traps, oh my!</a>
              <ul>
                <li><a href="#Breakpoints">Breakpoints</a></li>
                <li><a href="#ConditionalBreaks">Conditional Breaks</a></li>
                <li><a href="#Functions">Functions</a></li>
                <li><a href="#BuiltInFunctions">Built-in Functions</a></li>
                <li><a href="#PseudoRegisters">Pseudo-Registers</a></li>
                <li><a href="#Watches">Watches</a></li>
                <li><a href="#Traps">Traps</a></li>
              </ul>
            </li>
            <li><a href="#SaveWork">Save your work!</a></li>
            <li><a href="#PromptCommands">Prompt Commands</a></li>
          </ul>
        </li>
        <li><a href="#IOTab">I/O Tab</a></li>
        <li><a href="#AudioTab">Audio Tab</a></li>
        <li><a href="#TIADisplay">TIA Display</a></li>
        <li><a href="#TIAInfo">TIA Information</a></li>
        <li><a href="#TIAZoom">TIA Zoom</a></li>
        <li><a href="#BreakpointStatus">Breakpoint/Trap Status</a></li>
        <li><a href="#CPURegisters">CPU Registers</a></li>
        <li><a href="#DataOpButtons">Data Operations Buttons</a></li>
        <li><a href="#M6532">M6532/RIOT RAM</a></li>
          <ul>
            <li><a href="#M6532Search">M6532/RIOT RAM (search/compare mode)</a></li>
          </ul>
        </li>
        <li><a href="#Disassembly">ROM Disassembly</a>
          <ul>
            <li><a href="#DisassemblySettings">ROM Disassembly Settings</a></li>
            <li><a href="#Limitations">Limitations</a></li>
          </ul>
        </li>
        <li><a href="#BankswitchInformation">Detailed Bankswitch Information</a></li>
        <li><a href="#CartridgeRAMInformation">Detailed Cartridge Extended RAM Information</a></li>
      </ul>
    </li>
    <li><a href="#DistellaConfiguration">Distella Configuration Files</a></li>
    <li><a href="#Howtohack">Tutorial: How to hack a ROM</a></li>
    </li>
  </ul>
  <br>

<h1><a name="Features">Features</a></h1>
75
<p>The debugger in Stella may never be complete, as we're constantly
Stephen Kitt's avatar
Stephen Kitt committed
76
adding new features requested by homebrew developers. However, even in its
77 78 79
current form it's still quite powerful, and is able to boast at least one
feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.</p>

Stephen Kitt's avatar
Stephen Kitt committed
80
<p>Here's a (non-comprehensive) list of what the debugger can do so far:</p>
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
<ul>
	<li>Display registers and memory.</li>

	<li>Dump state of TIA and RIOT, with things like joystick directions and
		NUSIZx decoded into English (more-or-less).</li>

	<li>Change registers/memory, including toggles for flags in P register.</li>

	<li>Single step/trace.</li>

	<li>Breakpoints - break running program and enter debugger when the
		Program Counter hits a predefined address; you can set as many
		breakpoints as you want.</li>

	<li>Conditional breakpoints - Break running program when some arbitrary
		condition is true (e.g. "breakif {a == $7f &amp;&amp; c}" will break when the	Accumulator value is $7f and the Carry flag is true, no matter where
		in the program this happens). Unlike the cond breaks in PCAE, Stella's
		are *fast*: the emulation will run at full speed unless you use lots
		of breakif's at the same time, or have a slow CPU.</li>

	<li>Watches - View contents of a location/register before every
		debugger prompt.</li>

	<li>Traps - Like breakpoints, but break on read/write/any access to
Stephen Kitt's avatar
Stephen Kitt committed
105 106
		*any* memory location. Traps can also be combined with conditions to
    become conditional traps.</li>
107 108 109 110

	<li>Frame advance (automatic breakpoint at beginning of next frame)
		You can advance multiple frames with one command.</li>

Stephen Kitt's avatar
Stephen Kitt committed
111 112
  <li>Rewind previous advance operations and undo rewinds.</li>

113
  <li>Supports Distella 'configuration directives', which may be used to
Stephen Kitt's avatar
Stephen Kitt committed
114
    override automatic code/data determination in the disassembly. For now,
115 116 117 118 119
    the following directives are supported: CODE, GFX, PGFX, DATA, ROW.
    These directives can be entered at the debugger prompt, or (automatically)
    loaded and saved in configuration files.</li>

	<li>Extensive disassembly support, both from the emulation core and with help
Stephen Kitt's avatar
Stephen Kitt committed
120
    from Distella. Where possible, the disassembly differentiates between code,
121
    player graphics and playfield graphics (ie, addresses stored in GRPx and PFx)
Stephen Kitt's avatar
Stephen Kitt committed
122
    and data (addresses used as an operand of a command). Code sections are also
123
    differentiated between actual code, and 'tentative' code (ie, areas that may
Stephen Kitt's avatar
Stephen Kitt committed
124
    represent code sections, but haven't actually been executed yet). Such
125 126 127 128
    tentative code is marked with a '*' symbol.</li>

  <li>Supports visual representation of the bitmap data of graphics areas,
    as well as the ability to directly edit these areas in either hex or binary.</li>
129 130 131 132 133

	<li>Support for DASM symbol files (created with DASM's -s option),
		including automatically loading symbol files if they're named
		romname.sym</li>

134 135 136 137
	<li>Support for DASM list files (created with DASM's -l option),
		including automatically loading list files if they're named
		romname.lst</li>

138 139
	<li>Built-in VCS.H symbols, if no symbol file is loaded.</li>

140
	<li>Symbolic names in disassembly.</li>
141 142

	<li>Symbolic names accepted as input.</li>
143 144 145 146

	<li>Ability to generate DASM-compatible disassembly files (currently single-bank
    only) with all the features mentioned above.</li>

147 148 149 150 151 152 153 154 155 156 157
	<li>Tab completion for commands, symbol names and functions.</li>
	<li>Graphical editor for RIOT and extended RAM. Acts a lot like a spreadsheet.
		Input in hex, with displays for label/decimal/binary for
		currently-selected location.</li>
	<li>GUI CPU state window.</li>
	<!--Cheat system (similar to MAME) (still needs a way to save/load cheats)-->
	<li>Reset the 6502.</li>
	<li>Start emulator in debugger (via command-line option "-debug").</li>
	<li>Save CLI session to a text file.</li>
	<li>Supports hex, decimal, and binary input and output almost everywhere.
		(disassembly is still hex).</li>
158 159
	<li>Support for bank switching. You can see how many banks a cart has and the
    currently selected bank, and manually change banks.</li>
160
	<li>Registers/memory that get changed by the CPU during debugging are
161
		highlighted when they're displayed.</li>
162 163
  <li>Data sources for the CPU SP/A/X/Y registers, showing the resolved/source
    address of of load operands.</li>
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
	<li>Scanline advance (like frame advance, break at beginning
		of next scanline).</li>
	<li>TIA display is updated during step/trace, so we can see our
		scanlines being drawn as it happens. This isn't 100% perfect: unlike
		a real TIA, the one in Stella only updates when it's written to.</li>
	<li>Graphical TIA tab, with register names and GUI buttons for
		various bits (e.g. click ENAM0 to turn it on).</li>
	<li>GUI Disassembly window, scrollable, with checkboxes for breakpoints.</li>
	<li>Script (batch) file support, including auto-running a script file
		named after the ROM image.</li>
	<li>Saving the current debugger state to a script file (including
		breakpoints, traps, etc).</li>
	<li>Built-in functions for use with "breakif", to support common conditions
		(such as breaking when the user presses Game Select...)</li>
	<li>Patching ROM in-place.</li>
Stephen Kitt's avatar
Stephen Kitt committed
179
	<li>Save patched ROM</li>
180 181
</ul>

Stephen Kitt's avatar
Stephen Kitt committed
182
<h3>Future planned features:</h3>
183 184 185 186 187 188 189 190 191 192 193

<ul>
	<li>GUI for cheat codes (Cheetah and normal codes).</li>
	<li>Perhaps 2 panes in the disassembly window (so you can see 2 parts of the
		code at once).</li>
	<li>Add bookmark support to disassembly window.</li>
	<li>More "special variables" for the expression parser.</li>
	<li>Possibly a mini-assembler</li>
	<li>Possibly support for recording and playing back input files, like
		MAME. This isn't a debugger feature per se, but it'll make it easier
		to reliably trigger a bug so you can debug it.</li>
194
<!--
195
	<li>Graphics ROM view, so you can see your sprite data (it might still
196
		be upside-down though :)</li> -->
197 198 199
	<li>Various new GUI enhancements</li>
</ul>

Stephen Kitt's avatar
Stephen Kitt committed
200 201
</br>
<h1><a name="HowToDebugger">How to use the Debugger</a></h1>
202 203 204 205 206 207 208 209 210 211 212 213 214

<p>Pressing ` (aka backtick, backquote, grave accent) toggles the debugger on
&amp; off. When you exit the debugger, the emulation resumes at the current
program counter, and continues until either a breakpoint/trap is hit,
or the ` key is pressed again.</p>

<p>The main debugger window will look similar to the following (note that the
letters here are for reference in the document below; they aren't actually
present in the debugger):</p>
<p><img src="graphics/debugger_main.png"></p>

<p>For space reasons, the Prompt, TIA, I/O and Audio displays are split into
4 tabs, only one of which is visible at a time. You can use the mouse or
Stephen Kitt's avatar
Stephen Kitt committed
215 216 217 218 219 220 221 222
keyboard to select which tab you want to view. Control/Cmd + Tab cycles between
tabs from left-to-right, Shift + Control/Cmd + Tab cycles right-to-left.
Pressing Tab (or Shift + Tab) cycles between widgets in the current tab (except
for in the Prompt Tab, where 'tab' is used for something else).</p>

<p>You can also enter the debugger at emulator startup by use the 'debug'
command on the command line, or alternatively within the ROM launcher in
'Power-on options':
223
<pre>
224 225
  ; will enter the debugger before any instructions run
  stella -debug mygame.bin
226

227
  ; alternatively, you can use 'break' to accomplish the same thing
228 229 230 231 232 233 234
  ; $fffc is the 6502/6507 init vector. This command will break and enter the
  ; debugger before the first 6507 instruction runs, so you can debug the
  ; startup code:
  stella -break "*($fffc)" mygame.bin
</pre>
</p>

Stephen Kitt's avatar
Stephen Kitt committed
235 236
<p>Using the ` key will always enter the debugger at the end of
the frame (for NTSC games usually scanline 262). This is because Stella only checks
237 238
for keystrokes once per frame. Once in the debugger, you can control
execution by stepping one instruction, scanline, or frame at a time
Stephen Kitt's avatar
Stephen Kitt committed
239
(or more than one at a time, using commands in the prompt). You can
240 241
also set breakpoints or traps, which will cause the emulator to enter
the debugger when they are triggered, even if it happens in mid-frame.</p>
Stephen Kitt's avatar
Stephen Kitt committed
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
</br>

<h2><a name="Startup">Startup</a></h2>
At startup, the debugger automatically tries load a number of files which
will provide additional information for the debugger and can make debugging
more convenient.

<ul>
  <li>
    "autoexec.script"</br>
    Use this plain text file to define e.g. your own functions or settings.
    They will be loaded at startup for each ROM.

    <p>The location of this file will depend on the OS as follows:</p>
    <p>
    <table cellpadding=4 border="1">
      <tr>
        <td><b>Linux/Unix</b></td>
        <td><i>~/.stella/autoexec.script</i></td>
      </tr>
      <tr>
        <td><b>Macintosh</b></td>
        <td><i>~/Library/Application Support/Stella/autoexec.script</i></td>
      </tr>
      <tr>
        <td><b>Windows</b></td>
        <td><i>%APPDATA%\Stella\autoexec.script</i>&nbsp;&nbsp;&nbsp;
          <b>or</b><br>
          <i>_BASEDIR_\autoexec.script</i>
            (if a file named 'basedir.txt' exists in the application
            directory containing the full pathname for _BASEDIR_)
        </td>
      </tr>
    </table>
    </p>
  </li>
  <li>
    "&lt;rom_filename&gt;.script"</br>
    In this ROM specific, plain text file you can store breaks, traps, watches
    etc. for future re-use. Use the "save" command to create this file using
    the current settings. You can also manually edit the file and add more commands.
    </br></br>
  </li>
  <li>
    "&lt;rom_filename&gt;.cfg"</br>
    This file is described in <a href="#DistellaConfiguration">
    <b>Distella Configuration Files</b></a>.
    </br></br>
  </li>
  <li>
    "&lt;rom_filename&gt;.lst"</br>
  </li>
  <li>
    "&lt;rom_filename&gt;.sym"</br>
    If you provied the -l and -s parameters DASM will create these two files during
    assembly. Stella uses the file content to display the correct labels.
  </li>
</ul>
<p>Note that all files are only accessed if you enter
the debugger at least once during a program run. This means you can create
these files, and not worry about slowing down emulation unless you're
actively using the debugger.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="GlobalButtons">Global Buttons</a></h2>

<p>There are some buttons on the right top that always show up no matter which
tab you are looking at. This is because these are the ones that are most frequently
used.</p>

<ul>
  <p><img src="graphics/debugger_globalbuttons.png"></p>
</ul>
317

Stephen Kitt's avatar
Stephen Kitt committed
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
<p>The larger button at the left top (labeled '&lt;') performs the rewind operation,
which will undo the previous Step/Trace/Scan/Frame... advance, the smaller button at
the left bottom (labeled '&gt;') performs the unwind operation, which will undo the
previous rewind operation. The rewind buffer is 100 levels deep by default, the
size can be configured e.g. in the
<b><a href="index.html#Debugger">Developer Settings</a> - Time Machine</b> dialog.<p>

<p>The other operations are Step, Trace, Scan+1, Frame+1 and Exit (debugger).</p>

<p>You can also use the buttons from anywhere in the GUI via hotkeys.</p>
<p>
<table BORDER=1 cellpadding=4>
  <tr>
    <th>Key</th>
    <th>Function</th>
  </tr>
  <tr>
    <td>Control-s</td>
    <td>Step</td>
  </tr>
  <tr>
    <td>Control-t</td>
    <td>Trace</td>
  </tr>
  <tr>
    <td>Control-L</td>
    <td>Scan+1</td>
  </tr>
  <tr>
    <td>Control-f</td>
    <td>Frame+1</td>
  </tr>
  <tr>
    <td>Alt-Left arrow</td>
    <td>Rewind 1</td>
  </tr>
  <tr>
    <td>Shift-Alt-Left arrow</td>
    <td>Rewind 10</td>
  </tr>
  <tr>
    <td>Alt-Down arrow</td>
    <td>Rewind all</td>
  </tr>
  <tr>
    <td>Alt-Right arrow</td>
    <td>Unwind 1</td>
  </tr>
  <tr>
    <td>Shift-Alt-Right arrow</td>
    <td>Unwind 10</td>
  </tr>
  <tr>
    <td>Alt-Up arrow</td>
    <td>Unwind all</td>
  </tr>
  <tr>
    <td>Backquote (`)</td>
    <td>Exit</td>
  </tr>
</table>
</p>
For MacOS use 'Cmd' instead of &nbsp;'Alt' key.
<p>To the left of the global buttons, you find the "Options..." button.</p>
<ul>
  <p><img src="graphics/debugger_options.png"></p>
</ul>
<p>This opens the <a href="index.html#Options">Options Menu</a> which is described
in detail in the <a href="index.html">User's Guide</a>.</p>

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
<h2><a name="ChangeTracking"></a>Change Tracking</h2>
391

Stephen Kitt's avatar
Stephen Kitt committed
392 393
<p>The debugger tracks changes to the CPU, TIA and RIOT registers and RAM by
displaying changed locations or registers with a red background after each step,
394 395 396 397 398 399 400 401 402 403
trace, scanline, or frame advance. This sounds simple, and it is, but
it's also amazingly useful.</p>

<p>One clarification about the change tracking: it only tracks when values
have <b>changed</b>. If the ROM writes a value into a RAM location that
already contained the same value, that's not considered a change (old
value was $whatever, new value is the same, so nothing got tracked). This
may change in a future version of Stella.</p>

<!-- /////////////////////////////////////////////////////////////////////////  -->
Stephen Kitt's avatar
Stephen Kitt committed
404 405
<br>
<h2><a name="PromptTab"><u>(A)</u> Prompt Tab</a></h2>
406 407 408 409 410 411 412

<p>This is a command-line interface, similar to the DOS DEBUG command
or Supermon for the C=64.</p>

<p>Editing keys work about like you'd expect them to in Windows, but many
Bash-style commands are also supported:</p>

Stephen Kitt's avatar
Stephen Kitt committed
413 414
<table border="1" cellpadding=4>
  <tr><th>Key</th><th>Function</th></tr>
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
	<tr><td>Home</td><td>Move cursor to beginning of line</td></tr>
	<tr><td>End</td><td>Move cursor to end of line</td></tr>
	<tr><td>Delete</td><td>Remove character to right of cursor</td></tr>
	<tr><td>Backspace</td><td>Remove character to left of cursor</td></tr>
	<tr><td>Control-a</td><td>Same function as 'Home'</td></tr>
	<tr><td>Control-e</td><td>Same function as 'End'</td></tr>
	<tr><td>Control-d</td><td>Same function as 'Delete'</td></tr>
	<tr><td>Control-k</td><td>Remove all characters from cursor to end of line</td></tr>
	<tr><td>Control-u</td><td>Remove all characters from cursor to beginning of line</td></tr>
	<tr><td>Control-w</td><td>Remove entire word to left of cursor</td></tr>
	<tr><td>Shift-PgUp</td><td>Scroll up through previous commands one screen/page</td></tr>
	<tr><td>Shift-PgDown</td><td>Scroll down through previous commands one screen/page</td></tr>
	<tr><td>Shift-Up</td><td>Scroll up through previous commands one line</td></tr>
	<tr><td>Shift-Down</td><td>Scroll down through previous commands one line</td></tr>
	<tr><td>Shift-Home</td><td>Scroll to beginning of commands</td></tr>
	<tr><td>Shift-End</td><td>Scroll to end of commands</td></tr>
</table>
Stephen Kitt's avatar
Stephen Kitt committed
432
<p>You can also scroll with the mouse. Copy and paste is not yet supported.</p>
433

Stephen Kitt's avatar
Stephen Kitt committed
434 435 436
<p>To see the available commands, enter "help". For extended help, type "help cmd",
where 'cmd' is the command you wish to know about. The available commands are listed
in <a href="#PromptCommands"><b>Prompt Commands</b></a> at the end of this section. Bash-style tab completion is supported for commands,
437
labels and functions (see below).</p>
438 439 440 441 442 443 444

<p>For now, there are some functions that only exist in the prompt. We
intend to add GUI equivalents for all (or almost all?) of the prompt
commands in future releases. People who like command prompts will be able to
use the prompt, but people who hate them will have a fully functional
debugger without typing (or without typing much, anyway).</p>

Stephen Kitt's avatar
Stephen Kitt committed
445 446 447 448 449 450
<p>Note: unlike the rest of the UI, whatever is shown in the prompt will not
be updated during debugging and thus eventually become "stale". You can update it
just by re-running the relevant commands in the prompt.</p>
</br>

<h3><a name="TabCompletion">Tab Key Auto-Complete</a></h3>
451 452 453 454

<p>While entering a command, label or function, you can type a partial name and
press the Tab key to attempt to auto-complete it. If you've ever used
"bash", this will be immediately familiar. If not, try it: load up
Stephen Kitt's avatar
Stephen Kitt committed
455 456 457 458 459 460 461 462
a ROM, go to the debugger, type "g" (but don't press Enter),
then hit Tab. The "g" will change to "gfx" (since this is the only
built-in command starting with a "g"). If there are multiple possible
completions (try with "tr" instead of "g"), you'll see a list of them,
and your partial name will be completed as far as possible.
After the first character, the autocompletion considers all
characters in the right order as a match (e.g. "twf" will be completed to
"trapwriteif").</p>
463 464 465 466 467

<p>Tab completion works on all labels: built-in, loaded from a symbol file,
or set during debugging with the "define" command. It also works with
built-in functions and those defined with the "function" command,
but it doesn't (yet) work on filenames.</p>
Stephen Kitt's avatar
Stephen Kitt committed
468
</br>
469

Stephen Kitt's avatar
Stephen Kitt committed
470
<h3><a name="Expressions">Expressions</a></h3>
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514

<p>Almost every command takes a value: the "a" command takes a
byte to stuff into the accumulator, the "break" command
takes an address to set/clear a breakpoint at. These values
can be as a hex constant ($ff, $1234), or as complex as
"the low byte of the 16-bit value located at the address
pointed to by the binary number 1010010110100101" (which
would be "@&lt;\1010010110100101"). You can also use registers
and labels in expressions.</p>

<p>You can use arithmetic and boolean operators in expressions. The
syntax is very C-like. The operators supported are:</p>

<pre>
      + - * /  (add, subtract, multiply, divide: 2+2 is 4)
      %        (modulus/remainder: 3%2 is 1)
      &amp; | ^ ~  (bitwise AND, OR, XOR, NOT: 2&amp;3 is 2)
      &amp;&amp; || !  (logical AND, OR, NOT: 2&amp;&amp;3 is 1, 2||0 is 0)
      ( )      (parentheses for grouping: (2+2)*3 is 12)
      * @      (byte and word pointer dereference: *$80 is the byte stored
                at location $80)
      [ ]      (array-style byte pointer dereference: $80[1] is the byte
                stored at location ($80+1) or $81)
      &lt; &gt;      (prefix versions: low and high byte. &lt;$abcd is $cd)
      == &lt; &gt; &lt;= &gt;= !=
               (comparison: equality, less-than, greater-than, less-or-equals,
                greater-or-equals, not-equals)
      &lt;&lt; &gt;&gt;    (bit shifts, left and right: 1&lt;&lt;1 is 2, 2&gt;&gt;1 is 1)
</pre>

<p>Division by zero is not an error: it results in zero instead.</p>

<p>None of the operators change the values of their operands. There
are no variable-assignment or increment/decrement operators. This
may change in the future, which is why we used "==" for equality
instead of just "=".</p>

<p>The bitwise and logical boolean operators are different in that the
bitwise operators operate on all the bits of the operand (just like
AND, ORA, EOR in 6502 asm), while the logical operators treat their
operands as 0 for false, non-zero for true, and return either 0 or 1.
So $1234&amp;$5678 results in $1230, whereas $1234&amp;&amp;$5678 results in 1.
This is just like C or C++...</p>

Stephen Kitt's avatar
Stephen Kitt committed
515
<h4><a name="Prefixes">Prefixes</a></h4>
516 517 518 519 520 521 522

<p>Like some programming languages, the debugger uses prefixed characters
to change the meaning of an expression. The prefixes are:</p>

<ul>
	<li>Dereference prefixes:<br>

Stephen Kitt's avatar
Stephen Kitt committed
523
    <p><pre>'*'</pre>
524 525 526
    	  Dereference a byte pointer. "*a" means "the byte at the address that
	      the A register points to". If A is 255 (hex $ff), the result will be
    	  the value currently stored in memory location 255. This operator
Stephen Kitt's avatar
Stephen Kitt committed
527
	      will be very familiar to you if you're a C or C++ developer. It's
528 529 530 531 532
    	  equivalent to the PEEK() function in most 8-bit BASICs. Also, the
	      debugger supports array-like byte dereferences: *address can be
    	  written as address[0]. *(address+1) can be written as address[1],
	      etc.</p>

Stephen Kitt's avatar
Stephen Kitt committed
533
    <p><pre>'@'</pre>
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
    	  Dereference a pointer to a word. This is just like the "*" byte deref,
	      except it refers to a 16-bit value, occupying 2 locations, in
    	  low-byte-first format (standard for the 6507).</p>

		<p>The following are equivalent:</p>
		<pre>
         @address
         *address+$100**(address+1)
         address[0]+#256*address[1]
		</pre>

		<p>(TODO: add (indirect),y and (indirect,x) syntax)</p>
	</li>

	<li>Hi/Lo Byte Prefixes:<br>
Stephen Kitt's avatar
Stephen Kitt committed
549
    <p><pre>'&lt;'</pre>
550 551 552
		Take the low byte of a 16-bit value. This has no effect on an 8-bit
		value: "a" is equal to "&lt;a". However, "&lt;$1234" equals "$34".</p>

Stephen Kitt's avatar
Stephen Kitt committed
553
    <p><pre>'&gt;'</pre>
554 555 556 557 558 559
		Take the high byte of a 16-bit value. For 8-bit values such as
		the Accumulator, this will always result in zero. For 16-bit values,
		"&lt;$1234" = "$12".</p>
	</li>

	<li>Number Base Prefixes:<br>
Stephen Kitt's avatar
Stephen Kitt committed
560
    <p><pre>'#'</pre>
561 562
		Treat the input as a decimal number.</p>

Stephen Kitt's avatar
Stephen Kitt committed
563
    <p><pre>'$'</pre>
564 565
		Treat the input as a hex number.</p>

Stephen Kitt's avatar
Stephen Kitt committed
566
    <p><pre>'\'</pre>
567 568 569 570 571 572 573 574 575 576 577
		Treat the input as a binary number.</p>

		<p>These only have meaning when they come before a number, not a
		label or a register. "\1010" means 10 decimal. So do "$0a" and
		"#10". "a" by itself is always the Accumulator, no matter what
		the default base is set to.</p>

		<p>If you don't specify any number base prefix, the number is
		assumed to be in the default base. When you first start Stella,
		the default base is 16 (hexadecimal). You can change it with the
		"base" command. If you want to change the default base to decimal permanently,
Stephen Kitt's avatar
Stephen Kitt committed
578 579 580 581 582 583 584
		you can put a
    <pre>
      base #10
    </pre>
    command in your "autoexec.script" file (for details
    see <a href="#Startup"><b>Startup</b></a>).</p>
  </li>
585
</ul>
Stephen Kitt's avatar
Stephen Kitt committed
586 587
<p>Remember, you can use arbitrarily complex expressions with any
command that takes arguments.</p>
588

Stephen Kitt's avatar
Stephen Kitt committed
589 590
</br>
<h3><a name="BreakpointsEtc">Breakpoints, watches and traps, oh my!</a></h3>
591

Stephen Kitt's avatar
Stephen Kitt committed
592
<h4><a name="Breakpoints">Breakpoints</a></h4>
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617

<p>A breakpoint is a "hotspot" in your program that causes the emulator
to stop emulating and jump into the debugger. You can set as many
breakpoints as you like. The command is "break xx" where xx is any
expression. If you've created a symbol file, you can use labels.</p>

<p>Example: you've got a label called "kernel". To break there,
the command is "break kernel". After you've set the breakpoint,
exit the debugger ("quit" or click the Exit button). The emulator
will run until it gets to the breakpoint, then it will enter the
debugger with the Program Counter pointing to the instruction
at the breakpoint.</p>

<p>Breakpoints happen *before* an instruction is executed: the
instruction at the breakpoint location will be the "next"
instruction.</p>

<p>To remove a breakpoint, you just run the same command you used to
set it. In the example, "break kernel" will remove the breakpoint.
The "break" command can be thought of as a *toggle*: it turns the
breakpoint on &amp; off, like a light switch.</p>

<p>You could also use "clearbreaks" to remove all the breakpoints. Also,
there is a "listbreaks" command that will list them all.</p>

Stephen Kitt's avatar
Stephen Kitt committed
618
<h4><a name="ConditionalBreaks">Conditional Breaks</a></h4>
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650

<p>A conditional breakpoint causes the emulator to enter the debugger when
some arbitrary condition becomes true. "True" means "not zero" here:
"2+2" is considered true because it's not zero. "2-2" is false, because
it evaluates to zero. This is exactly how things work in C and lots
of other languages, but it might take some getting used to if you've
never used such a language.</p>

<p>Suppose you want to enter the debugger when the Game Reset switch is
pressed. Looking at the Stella Programmers' Guide, we see that this
switch is read at bit 0 of SWCHB. This bit will be 0 if the switch is
pressed, or 1 otherwise.</p>

<p>To have an expression read the contents of an address, we use the
dereference operator "*". Since we're looking at SWCHB, we need
"*SWCHB".</p>

<p>We're only wanting to look at bit 0, so let's mask off all the other
bits: "*SWCHB&amp;1". The expression now evaluates to bit 0 of SWCHB. We're
almost there: this will be 1 (true) if the switch is NOT pressed. We
want to break if it IS pressed...</p>

<p>So we invert the sense of the test with a logical NOT operator (which
is the "!" operator): !(*SWCHB&amp;1). The parentheses are necessary as
we want to apply the ! to the result of the &amp;, not just the first term
(the "*SWCHB").</p>

<p>"breakif !(*SWCHB&amp;1)" will do the job for us. However, it's an ugly mess
of letters, numbers, and punctuation. We can do a little better:</p>

<p>"breakif { !(*SWCHB &amp; 1 ) }" is a lot more readable, isn't it? If
you're going to use readable expressions with spaces in them,
651
enclose the entire expression in curly braces.</p>
652 653 654 655 656 657 658

<p>Remember that Stella only checks for input once per frame, so a break
condition that depends on input (like SWCHB) will always happen at the
end of a frame. This is different from how a real 2600 works, but most
ROMs only check for input once per frame anyway.</p>

<p>Conditional breaks appear in "listbreaks", numbered starting from
Stephen Kitt's avatar
Stephen Kitt committed
659 660
zero. You can remove a cond-break with "delbreakif number", where
the number comes from "listbreaks" or by entering the same conditional break again.</p>
661 662

<p>Any time the debugger is entered due to a trap, breakpoint, or
Stephen Kitt's avatar
Stephen Kitt committed
663 664
conditional break, the reason will be displayed in the
<a href="#BreakpointStatus"><b>Breakpoint/Trap Status</b></a> area.
665

Stephen Kitt's avatar
Stephen Kitt committed
666
<h4><a name="Functions">Functions</a></h4>
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691

<p>There is one annoyance about complex expressions: once we
remove the conditional break with "delbreakif" or "clearbreaks",
we'd have to retype it (or search backwards with the up-arrow key)
if we wanted to use it again.</p>

<p>We can avoid this by defining the expression as a function, then using
"breakif function_name":</p>

<pre>
	function gameReset { !(*SWCHB &amp; 1 ) }
	breakif gameReset
</pre>

<p>Now we have a meaningful name for the condition, so we can use it again.
Not only that: we can use the function as part of a bigger expression.
Suppose we've also defined a gameSelect function that evaluates to true
if the Game Select switch is pressed. We want to break when the user
presses both Select and Reset:</p>

<pre>
	breakif { gameReset &amp;&amp; gameSelect }
</pre>

<p>User-defined functions appear in "listfunctions", which shows the label
Stephen Kitt's avatar
Stephen Kitt committed
692
and expression for each function. Functions can be removed with
693 694
"delfunction label", where the labels come from "listfunctions".</p>

Stephen Kitt's avatar
Stephen Kitt committed
695
<h4><a name="BuiltInFunctions">Built-in Functions</a></h4>
696 697

<p>Stella has some pre-defined functions for use with the "breakif"
Stephen Kitt's avatar
Stephen Kitt committed
698
command. These allow you to break and enter the debugger on various
699 700 701 702 703 704 705
conditions without having to define the conditions yourself.</p>

<p>Built-in functions and pseudo-registers always start with an _
(underscore) character. It is suggested that you don't start labels in
your game's source with underscores, if you plan to use them with the
Stella debugger.</p>

Stephen Kitt's avatar
Stephen Kitt committed
706
<table border="1" cellpadding=4>
707 708 709 710 711 712 713 714 715 716 717
<tr><th>Function</th><th>Definition</th><th>Description</th></tr>
<tr><td> _joy0left</td><td> !(*SWCHA &amp; $40)</td><td> Left joystick moved left</td></tr>
<tr><td> _joy0right</td><td> !(*SWCHA &amp; $80)</td><td> Left joystick moved right</td></tr>
<tr><td> _joy0up</td><td> !(*SWCHA &amp; $10)</td><td> Left joystick moved up</td></tr>
<tr><td> _joy0down</td><td> !(*SWCHA &amp; $20)</td><td> Left joystick moved down</td></tr>
<tr><td> _joy0button</td><td> !(*INPT4 &amp; $80)</td><td> Left joystick button pressed</td></tr>
<tr><td> _joy1left</td><td> !(*SWCHA &amp; $04)</td><td> Right joystick moved left</td></tr>
<tr><td> _joy1right</td><td> !(*SWCHA &amp; $08)</td><td> Right joystick moved right</td></tr>
<tr><td> _joy1up</td><td> !(*SWCHA &amp; $01)</td><td> Right joystick moved up</td></tr>
<tr><td> _joy1down</td><td> !(*SWCHA &amp; $02)</td><td> Right joystick moved down</td></tr>
<tr><td> _joy1button</td><td> !(*INPT5 &amp; $80)</td><td> Right joystick button pressed</td></tr>
718 719
<tr><td> _select</td><td> !(*SWCHB &amp; $02)</td><td> Game Select pressed</td></tr>
<tr><td> _reset</td><td> !(*SWCHB &amp; $01)</td><td> Game Reset pressed</td></tr>
720 721 722 723 724 725 726 727 728 729 730
<tr><td> _color</td><td> *SWCHB &amp; $08</td><td> Color/BW set to Color</td></tr>
<tr><td> _bw</td><td> !(*SWCHB &amp; $08)</td><td> Color/BW set to BW</td></tr>
<tr><td> _diff0b</td><td> !(*SWCHB &amp; $40)</td><td> Left difficulty set to B (easy)</td></tr>
<tr><td> _diff0a</td><td> *SWCHB &amp; $40</td><td> Left difficulty set to A (hard)</td></tr>
<tr><td> _diff1b</td><td> !(*SWCHB &amp; $80)</td><td> Right difficulty set to B (easy)</td></tr>
<tr><td> _diff1a</td><td> *SWCHB &amp; $80</td><td> Right difficulty set to A (hard)</td></tr>
</table>

<p>Don't worry about memorizing them all: the Prompt "help" command
will show you a list of them.</p>

Stephen Kitt's avatar
Stephen Kitt committed
731
<h4><a name="PseudoRegisters">Pseudo-Registers</a></h4>
732 733 734

<p>These "registers" are provided for you to use in your conditional breaks.
They're not registers in the conventional sense, since they don't exist in
Stephen Kitt's avatar
Stephen Kitt committed
735
a real system. For example, while the debugger keeps track of the number
736 737
of scanlines in a frame, a real system would not (there is no register
that holds 'number of scanlines' on an actual console).</p>
Stephen Kitt's avatar
Stephen Kitt committed
738
<table border="1" cellpadding=4>
739 740 741
<tr><th>Function</th><th>Description</th></tr>
<tr><td> _bank</td><td> Currently selected bank</td></tr>
<tr><td> _cclocks</td><td> Color clocks on a scanline</td></tr>
Stephen Kitt's avatar
Stephen Kitt committed
742 743 744 745 746
<tr><td> _cycleshi</td><td> Higher 32 bits of number of cycles since emulation started</td></tr>
<tr><td> _cycleslo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
<tr><td> _fcount</td><td> Number of frames since emulation started</td></tr>
<tr><td> _fcycles</td><td> Number of cycles since frame started</td></tr>
<tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
747
<tr><td> _scan</td><td> Current scanline count</td></tr>
Stephen Kitt's avatar
Stephen Kitt committed
748
<tr><td> _scycles</td><td> Number of cycles in current scanline</td></tr>
749
<tr><td> _vblank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
Stephen Kitt's avatar
Stephen Kitt committed
750
<tr><td> _vsync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
</table>

<p><b>_scan</b> always contains the current scanline count. You can use
this to break your program in the middle of your kernel. Example:</p>
<pre>
    breakif _scan==#64
</pre>
<p>This will cause Stella to enter the debugger when the TIA reaches the
beginning of the 64th scanline.</p>

<p><b>_bank</b> always contains the currently selected bank. For 2K or 4K
(non-bankswitched) ROMs, it will always contain 0. One useful use is:</p>

<pre>
    breakif { pc==myLabel &amp;&amp; _bank==1 }
</pre>

<p>This is similar to setting a regular breakpoint, but it will only trigger
when bank 1 is selected.</p>

Stephen Kitt's avatar
Stephen Kitt committed
771
<h4><a name="Watches">Watches</a></h4>
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788

<p>A watch is an expression that gets evaluated and printed before
every prompt. This is useful for e.g. tracking the contents of a
memory location while stepping through code that modifies it.</p>

<p>You can set up to 10 watches (in future the number will be unlimited).
Since the expression isn't evaluated until it's used, you can include
registers: "watch *y" will show you the contents of the location
pointed to by the Y register, even if the Y register changes.</p>

<p>The watches are numbered. The numbers are printed along with the
watches, so you can tell which is which. To delete a watch use the
"delwatch" command with the watch number (1 to whatever). You can
also delete them all with the "clearwatches" command.</p>

<p>Note that there's no real point in watching a label or CPU register
without dereferencing it: Labels are constants, and CPU registers
Stephen Kitt's avatar
Stephen Kitt committed
789
are already visible in the <a href="#CPURegisters"><b>CPU Registers</b></a> widget</p>
790

Stephen Kitt's avatar
Stephen Kitt committed
791
<h4><a name="Traps">Traps</a></h4>
792 793 794 795 796 797

<p>A trap is similar to a breakpoint, except that it catches
accesses to a memory address, rather than specific location in the
program. They're useful for finding code that modifies TIA registers
or memory.</p>

Stephen Kitt's avatar
Stephen Kitt committed
798 799 800 801 802
<p>Traps can also combined with a condition ("trapif"). If an access
to a memory address is caught, the condition is evaluated additionally.
Only if the condition is true too, the emulations stops. For details
about conditions see <a href="#ConditionalBreaks"><b>Conditional Breaks</b></a> described above.</p>

803 804 805 806 807 808 809 810 811 812 813 814 815
<p>An example: you are debugging a game, and you want to stop the
emulation and enter the debugger whenever RESP0 is strobed. You'd use
the command "trap RESP0" to set the trap, then exit the debugger. The
emulator will run until the next time RESP0 is accessed (either read
or write). Once the trap is hit, you can examine the TIA state to
see what the actual player 0 position is, in color clocks (or you
can in the future when we implement that feature in the TIA dump!)</p>

<p>Unlike breakpoints, traps stop the emulation *after* the instruction
that triggered the trap. The reason for this is simple: until the
instruction is executed, the emulator can't know it's going to hit a
trap. After the trap is hit, the instruction is done executing, and
whatever effects it may have had on e.g. the TIA state have already
Stephen Kitt's avatar
Stephen Kitt committed
816
happened... but we don't have a way to run the emulated VCS in reverse,
817 818 819 820 821
so the best we can do is stop before the next instruction runs.</p>

<p>Traps come in two varieties: read access traps and write access traps.
It is possible to set both types of trap on the same address (that's
what the plain "trap" command does). To set a read or write only trap,
Stephen Kitt's avatar
Stephen Kitt committed
822
use "trapread(if)" or "trapwrite(if)".
823

Stephen Kitt's avatar
Stephen Kitt committed
824 825 826 827
<p>All traps appear in "listtraps", numbered starting from zero. You
can remove a trap with "deltrap number", where the number comes from
"listtraps" or by entering the identical trap again. You can get rid of
all traps at once with the "cleartraps" command.</p></p>
828

Stephen Kitt's avatar
Stephen Kitt committed
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
</br>
<h3><a name="SaveWork">Save your work!</a></h3>
<p>Stella offers several commands to save your work inside the debugger for
later re-use.</p>

<ul>
  <li>
    <b><a name="savecmd">save</a></b>: If you've defined a lot of complex functions, you probably will
    want to re-use them in future runs of the debugger. You can save all
    your functions, breakpoints, conditional breaks, traps and watches with the
    "save" command. If you name your saved file the same as the ROM filename
    and place it in the ROM directory, it will be auto-loaded next time you
    load the same ROM in Stella. The saved file is just a plain text file
    called "&lt;rom_filename&gt;.script", so you can edit it and add new functions, etc.
    <p>Note: While "save" is ROM specific, you can also create a file called
    "autoexec.script" which will be loaded when the debugger starts, no matter
    what ROM you have loaded.<p>
    See <a href="#Startup"><b>Startup</b></a> for details.
  </li>
  <li>
    <b>saveconfig</b>: The "saveconfig" command creates a
    <a href="#DistellaConfiguration"><b>DiStella Configuration File</b></a> which is
    based on Stella's dynamic and static analysis of the current ROM.
    <p>This will be automatically loaded the next time your start the debugger.
    From there on, you can continue analyzing the ROM and then use "saveconfig"
    again to update the configuration. You can also use "loadconfig" to load it
    manually.
    <p>Note that this is not tested for multi-banked ROMs.</p>
  </li>
  <li>
    <b>savedis</b>:
    While your are playing or debugging a game, Stella will gather dynamic
    information about the ROM. It can then use that information together with
    a static analysis of the ROM and therefore create a better disassembly
    than DiStella alone. "savedis" allows you to save that disassembly as the
    result of this combined analysis.
    <p>Note that this currently only works for single banked ROMs. For larger
    ROMs, the created disassembly is incomplete.</p>
  </li>
  <li>
    <p><b>saverom</b>:
    If you have manipulated a ROM, you can save it with "saverom". The file is
    named "&lt;rom_filename&gt;.a26".</p>
  </li>
  <li>
    <p><b>saveses</b>:
    The "saveses" command dumps the whole prompt session into a file named
    "&lt;YYYY-MM-DD_HH-mm-ss&gt;.txt". So you can later lookup what you did exactly
    when you were debugging at that time.</p>
  </li>
  <li>
  <p><b>savestate</b>:
    This command works identical to the save state hotkey (F9) during emulation.
    Any previously saved state can be loaded with "loadstate" plus the slot
    number (0-9).</p>
  </li>
</ul>
</br>

<h3><a name="PromptCommands">Prompt Commands</a></h3>
889

890 891
<p>Type "help" to see this list in the debugger.<br/>
Type "help 'cmd'" to see extended information about the given command.</p>
892 893

<pre>
Stephen Kitt's avatar
Stephen Kitt committed
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985
                a - Set Accumulator to &lt;value&gt;
             base - Set default number base to &lt;base&gt; (bin, dec, hex)
            break - Set/clear breakpoint at &lt;address&gt;
          breakif - Set/clear breakpoint on &lt;condition&gt;
                c - Carry Flag: set (0 or 1), or toggle (no arg)
            cheat - Use a cheat code (see manual for cheat types)
      clearbreaks - Clear all breakpoints
      clearconfig - Clear Distella config directives [bank xx]
clearsavestateifs - Clear all savestate points
       cleartraps - Clear all traps
     clearwatches - Clear all watches
              cls - Clear prompt area of text
             code - Mark 'CODE' range in disassembly
        colortest - Show value xx as TIA color
                d - Decimal Mode Flag: set (0 or 1), or toggle (no arg)
             data - Mark 'DATA' range in disassembly
      debugcolors - Show Fixed Debug Colors information
           define - Define label xx for address yy
       delbreakif - Delete conditional breakif &lt;xx&gt;
      delfunction - Delete function with label xx
   delsavestateif - Delete conditional savestate point &lt;xx&gt;
          deltrap - Delete trap &lt;xx&gt;
         delwatch - Delete watch &lt;xx&gt;
           disasm - Disassemble address xx [yy lines] (default=PC)
             dump - Dump data at address &lt;xx&gt; [to yy] [1: memory; 2: CPU state; 4: input regs]
             exec - Execute script file &lt;xx&gt; [prefix]
          exitrom - Exit emulator, return to ROM launcher
            frame - Advance emulation by &lt;xx&gt; frames (default=1)
         function - Define function name xx for expression yy
              gfx - Mark 'GFX' range in disassembly
             help - help &lt;command&gt;
           joy0up - Set joystick 0 up direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy0down - Set joystick 0 down direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy0left - Set joystick 0 left direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
        joy0right - Set joystick 0 right direction to value <x> (0 or 1), or toggle (no arg)
         joy0fire - Set joystick 0 fire button to value &lt;x&gt; (0 or 1), or toggle (no arg)
           joy1up - Set joystick 1 up direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy1down - Set joystick 1 down direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy1left - Set joystick 1 left direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
        joy1right - Set joystick 1 right direction to value &lt;x&gt; (0 or 1), or toggle (no arg)
         joy1fire - Set joystick 1 fire button to value &lt;x&gt; (0 or 1), or toggle (no arg)
             jump - Scroll disassembly to address xx
       listbreaks - List breakpoints
       listconfig - List Distella config directives [bank xx]
    listfunctions - List user-defined functions
 listsavestateifs - List savestate points
        listtraps - List traps
       loadconfig - Load Distella config file
        loadstate - Load emulator state xx (0-9)
                n - Negative Flag: set (0 or 1), or toggle (no arg)
          palette - Show current TIA palette
               pc - Set Program Counter to address xx
             pgfx - Mark 'PGFX' range in disassembly
            print - Evaluate/print expression xx in hex/dec/binary
              ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
            reset - Reset system to power-on state
           rewind - Rewind state by one or [xx] steps/traces/scanlines/frames...
             riot - Show RIOT timer/input status
              rom - Set ROM address xx to yy1 [yy2 ...]
              row - Mark 'ROW' range in disassembly
              run - Exit debugger, return to emulator
            runto - Run until string xx in disassembly
          runtopc - Run until PC is set to value xx
                s - Set Stack Pointer to value xx
             save - Save breaks, watches, traps and functions to file xx
       saveconfig - Save Distella config file (with default name)
          savedis - Save Distella disassembly (with default name)
          saverom - Save (possibly patched) ROM (with default name)
          saveses - Save console session (with default name)
         savesnap - Save current TIA image to PNG file
        savestate - Save emulator state xx (valid args 0-9)
      savestateif - Create savestate on &lt;condition&gt;
         scanline - Advance emulation by &lt;xx&gt; scanlines (default=1)
             step - Single step CPU [with count xx]
        stepwhile - Single step CPU while &lt;condition&gt; is true
              tia - Show TIA state
            trace - Single step CPU over subroutines [with count xx]
             trap - Trap read/write access to address(es) xx [yy]
           trapif - On &lt;condition&gt; trap R/W access to address(es) xx [yy]
         trapread - Trap read access to address(es) xx [yy]
       trapreadif - On &lt;condition&gt; trap read access to address(es) xx [yy]
        trapwrite - Trap write access to address(es) xx [yy]
      trapwriteif - On &lt;condition&gt; trap write access to address(es) xx [yy]
             type - Show disassembly type for address xx [yy]
             uhex - Toggle upper/lowercase HEX display
            undef - Undefine label xx (if defined)
           unwind - Unwind state state by one or [xx] steps/traces/scanlines/frames...
                v - Overflow Flag: set (0 or 1), or toggle (no arg)
            watch - Print contents of address xx before every prompt
                x - Set X Register to value xx
                y - Set Y Register to value xx
                z - Zero Flag: set (0 or 1), or toggle (no arg)
986 987 988 989
</pre>

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
990
<h2><a name="TIATab"></a><u>(B)</u> TIA Tab</a></h2>
991 992 993 994 995 996

<p>When selected, this tab shows detailed status of all the TIA registers
(except for audio; use the Audio tab for those).</p>
<p><img src="graphics/debugger_tiatab.png"></p>

<p>Most of the values on the TIA tab will be self-explanatory to a 2600
Stephen Kitt's avatar
Stephen Kitt committed
997
developer.<p>
998 999

<p>Many of the variables inside the TIA can only be written to by the
Stephen Kitt's avatar
Stephen Kitt committed
1000
6502. The debugger lets you get inside the TIA and see the contents
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
of these variables. These include the color registers, player/missile
graphics and positions, and the playfield.</p>

<p>You can control almost every aspect of the TIA from here, too: most
of the displays are editable. You can even toggle individual bits in
the GRP0/1 and playfield registers (remember to double-click).</p>

<p>The group of buttons labelled "Strobes" allows you to write to any
of the strobe registers at any time.</p>

<p>The collision registers are displayed in decoded format, in a table.
You can see exactly which objects have hit what. These are read-only
displays; you can't toggle the bits in the current release of Stella. Of
course, you can clear all the collisions with the CXCLR Strobe button.</p>

<p>To the right of each color register, you'll see a small rectangle
drawn in the current color. Changing a color register will change the
color of this rectangle.</p>

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
<p>Both player graphics registers (GRP0 and GRP1) come in two versions:
a "new" and an "old" register. Writing GRP0 updates the value in the "new"
version of GRP0 and, at the same time, copies the value in the "new" GRP1
register into its "old" counterpart. Writing to GRP1 behaves the same way,
with the roles of GRP0 and GRP1 switched. The debugger shows both registers,
the "old" register being located below the "new" one. If VDEL is off, the
TIA displays the content of the "new" register, and the debugger tab reflects
this by crossing out the old register. If VDEL is enabled, the TIA displays
the "old" register, and the lines are removed in the tab.</p>

<p>The "enable ball" register (ENABL) also comes in a "new" and an "old"
version. The content of "new" is copied into "old" on writes to GRP1, and
VDELBL selects the register that is used to control the ball. This is
visualized in the debugger in the same way as the two copies of GRP0 and
GRP1</p>

<p>For many registers, writes don't take effect immediatelly as the
TIA takes some color clocks to change state. In Stella's TIA core, this
is implemented by queueing the writes, and the contents of this queue
Stephen Kitt's avatar
Stephen Kitt committed
1039
are visualized in the debugger in the "Queued Writes" area of the TIA tab.</p>
1040 1041 1042

<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1043
<h2><a name="IOTab"><u>(C)</u> I/O Tab</a></h2>
1044 1045 1046 1047 1048 1049 1050

<p>When selected, this tab shows detailed status of the Input, Output,
and Timer portion of the RIOT/M6532 chip (the RAM portion is accessed
in another part of the debugger).</p>
<p><img src="graphics/debugger_iotab.png"></p>

<p>As with the TIA tab, most of the values here will be self-explanatory to a 2600
Stephen Kitt's avatar
Stephen Kitt committed
1051
developer, and almost all can be modified. However, the SWCHx registers need
1052
further explanation:<p>
Stephen Kitt's avatar
Stephen Kitt committed
1053 1054
<p>SWCHx(W) can be modified; here, the (W) stands for write. Similarly,
SWACNT/SWBCNT can be directly modified. However, the results of reading back from
1055
the SWCHx register are influenced by SWACNT/SWBCNT, and SWCHx(R) is a read-only display
1056 1057 1058 1059 1060
reflecting this result.</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1061
<h2><a name="AudioTab"><u>(D)</u> Audio Tab</a></h2>
1062

Stephen Kitt's avatar
Stephen Kitt committed
1063 1064 1065 1066 1067 1068
<p>This tab lets you view the contents of the TIA audio registers and the effective
volume resulting from the two channel volumes.</p>

<p><img src="graphics/debugger_audiotab.png"></p>

<p>This tab will grow some features in a future release.</p>
1069 1070 1071 1072


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1073
<h2><a name="TIADisplay"><u>(E)</u> TIA Display</a></h2>
1074 1075 1076 1077 1078

<p>In the upper left of the debugger, you'll see the current frame of
video as generated by the TIA. If a complete frame hasn't been drawn,
the partial contents of the current frame will be displayed up to the
current scanline, with the contents of the old frame (in black &amp;
Stephen Kitt's avatar
Stephen Kitt committed
1079
white) filling the rest of the display. Note that if 'phosphor mode'
1080
or TV effects are enabled, you won't see the effects here; this shows the
Stephen Kitt's avatar
Stephen Kitt committed
1081
<b>raw</b> TIA image only.</p>
1082

Stephen Kitt's avatar
Stephen Kitt committed
1083 1084
<p>To e.g. watch the TIA draw the frame one scanline at a time, you can
use the "Scan+1" button, the prompt "scan" command or the Control-L key.</p>
1085 1086 1087 1088 1089 1090

<p>You can also right-click anywhere in this window to show a context menu,
as illustrated:</p>
<p><img src="graphics/debugger_tiaoutcmenu.png"></p>
<p>The options are as follows:</p>
<ul>
Stephen Kitt's avatar
Stephen Kitt committed
1091 1092
	<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
  vertical position where the	mouse was clicked.</li>
Stephen Kitt's avatar
Stephen Kitt committed
1093 1094 1095
	<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
	scanline where the mouse was clicked. You can also use
	the Prompt Tab commands to list and turn off the breakpoint.</li>
1096
	<li><b>Set zoom position</b>: Influences what is shown in the TIA
Stephen Kitt's avatar
Stephen Kitt committed
1097 1098 1099
  zoom area (further described in <a href="#TIAZoom"><b>TIA Zoom</b></a>).
  The zoom area will contain the area centered at the position where the
  mouse was	clicked.</li>
1100 1101 1102
	<li><b>Save snapshot</b>: Saves the TIA image currently shown,
	including any current 'effects' (fixed debug colors, partial fill, etc).
  </li>
1103 1104 1105 1106 1107
</ul>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1108 1109
<h2><a name="TIAInfo"><u>(F)</u> TIA Information</a></h2>
<p>To the right of the <a href="#TIADisplay"><b>TIA Display</b></a> area, TIA information is displayed:</p>
1110
<p><img src="graphics/debugger_tiainfo.png"></p>
1111
<p>The indicators are as follows (note that all these are read-only):</p>
1112
<ul>
1113 1114
<li><b>Frame Count</b>: The current frame number, since this ROM was loaded or reset.</li>
<li><b>Frame Cycle</b>: The number of CPU cycles that have been executed this frame, since
1115
VSYNC was cleared at scanline 0.</li>
1116 1117
<li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for 3 scanlines, as per the Stella
1118
Programmer's Guide)</li>
1119
<li><b>Scan Cycle</b>: The number of CPU cycles that have been executed since the beginning
1120 1121 1122 1123 1124 1125 1126
of the current scanline.</li>
<li><b>VSYNC &amp; VBLANK</b>: Self explanatory.</li>
<li><b>Pixel Pos</b>: The current number of visible color clocks that have been displayed on
the current scanline, starting from the beginning of the Horizontal Blank period.
During HBLANK, this value will be negative (representing the number of clocks
until the first visible one). Since there are 68 color clocks per HBLANK and
160 visible clocks per scanline, the Pixel Position will range from -68 to 159.</li>
1127
<li><b>Color Clock</b>: The current number of total color clocks since the beginning of this
1128 1129 1130 1131 1132 1133 1134 1135
scanline's HBLANK. This counter starts at zero, but otherwise displays the same
information as the Pixel Position (so Color Clock will always be 68 more than Pixel
Position, and will range from 0 to 228).</li>
</ul>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1136 1137 1138 1139 1140
<h2><a name="TIAZoom"><u>(G)</u> TIA Zoom</a></h2>
<p>Below the <a href="#TIAInfo"><b>TIA Information</b></a> is the TIA Zoom area. This allows you to enlarge
part of the TIA display, so you can see fine details. Like the
<a href="#TIADisplay"><b>TIA Display</b></a> area,
this one does generate frames as the real system would.</p>
1141 1142 1143 1144 1145
<p>You can also right-click anywhere in this window to show a context menu,
as illustrated:</p>
<p><img src="graphics/debugger_tiazoomcmenu.png"></p>
<p>These options allow you to zoom in on the image for even greater detail.
If you click on the output window, you can scroll around using the cursor,
Stephen Kitt's avatar
Stephen Kitt committed
1146 1147
PageUp/Dn and Home/End keys. You can also select the zoom position from
a context menu in the <a href="#TIADisplay"><b>TIA Display</b></a>.</p>
1148 1149 1150 1151


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1152 1153 1154 1155
<h2><a name="BreakpointStatus"></a><u>(H)</u> Breakpoint/Trap Status</a></h2>
<p>Below the <a href="#TIAZoom"><b>TIA Zoom</b></a> there is a status line that
shows the reason and the address the debugger was entered (if a breakpoint or
trap was hit), as shown:</p>
1156
<p><img src="graphics/debugger_bpstatus.png"></p>
Stephen Kitt's avatar
Stephen Kitt committed
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
<p>The output here will generally be self-explanatory. Due to space concerns,
the reason will be shown as follows:
<ul>
  <li>"CBP:" for conditional breakpoints</li>
  <li>"BP:" for normal breakpoints</li>
  <li>"RTrap:" for read traps</li>
  <li>"WTrap:" for write traps</li>
  <li>"RTrapIf:" for conditional read traps</li>
  <li>"WTrapIf:" for conditional write traps</li>
</ul>
</p>
See the <a href="#BreakpointsEtc"><b>Breakpoints, watches and traps...</b></a>
section for details.</p>
1170 1171 1172 1173


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1174
<h2><a name="CPURegisters"><u>(I)</u> CPU Registers</a></h2>
1175 1176 1177 1178 1179
<p>This displays the current CPU state, as shown:</p>
<p><img src="graphics/debugger_cpuregs.png"></p>
<p>All the registers and flags are displayed, and can be changed by
double-clicking on them (to the left). Flags are toggled on double-click.
Selected registers here can also be changed by using the "Data Operations" buttons,
Stephen Kitt's avatar
Stephen Kitt committed
1180 1181
further described in (J). All items are shown in hex. Any label defined for the
current PC value is shown to the right. Decimal and binary equivalents
1182
are shown for SP/A/X/Y to the right (first decimal, then binary).</p>
1183
<p>The column to the far right shows the 'source' of contents of the respective
Stephen Kitt's avatar
Stephen Kitt committed
1184
registers. For example, consider the command 'LDA ($80),Y'. The operand of
1185
the command resolves to some address, which isn't always easy to determine at
Stephen Kitt's avatar
Stephen Kitt committed
1186
first glance. The 'Src Addr' area shows the actual resulting operand/address
1187
being used with the given opcode.</p>
Stephen Kitt's avatar
Stephen Kitt committed
1188
<p>There's not much else to say about the CPU Registers widget: if you know 6502
1189 1190 1191 1192 1193 1194
assembly, it's pretty self-explanatory. If you don't, well, you should
learn :)</p>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1195 1196 1197 1198 1199 1200
<h2><a name="DataOpButtons"><u>(J)</u> Data Operations Buttons</a></h2>
<p>These buttons can be used to change values in either
<a href="#CPURegisters"><b>CPU Registers</b></a>,
the <a href="#M6532"><b>M6532/RIOT RAM</b></a> or
<a href="#CartridgeRAMInformation"><b>Detailed Cartridge Extended RAM Information</b></a>,
depending on which of these widgets is currently in focus.
1201 1202
<p><img src="graphics/debugger_dataops.png"></p>
<p>Each of these buttons also have a keyboard shortcut (indicated in square
Stephen Kitt's avatar
Stephen Kitt committed
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
brackets). In fact, many of the inputboxes in various parts of the debugger
respond to these same keyboard shortcuts. If in doubt, give them a try.</p>
<table border="1" cellpadding=4>
  <tr>
    <th>Button</th><th>Shortut</th><th>Description</th>
  </tr>
  <tr>
    <td>0</td><td><pre>'z'</pre></td><td>Set the current location/register to zero.</td>
  </tr><tr>
    <td>Inv</td><td><pre>'i' or '!'</pre></td><td>Invert the current location/register (toggle all its bits)</td>
  </tr><tr>
    <td>Neg</td><td><pre>'n'</pre></td><td>Negate the current location/register (twos' complement negative)</td>
  </tr><tr>
    <td>++</td><td><pre>'+' or '='</pre></td><td>Increment the current location/register.</td>
  </tr><tr>
    <td>--</td><td><pre>'-'</pre></td><td>Decrement the current location/register.</td>
  </tr><tr>
    <td>&lt;&lt;</td><td><pre>'&lt;' or ','</pre></td><td>Shift the current location/register left.</td>
  </tr><tr>
    <td>&gt;&gt;</td><td><pre>'&gt;' or '.'</pre></td><td>Shift the current location/register right.</td>
  </tr>
</table>
<p>Any bits shifted out of the location/register with &lt;&lt; or &gt;&gt;
are lost (they will NOT end up in the Carry flag).</p>
1227 1228 1229 1230


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1231
<h2><a name="M6532"><u>(K)</u> M6532/RIOT RAM</a></h2>
1232
<p>This is a spreadsheet-like GUI for inspecting and changing the contents
1233
of the 2600's zero-page RAM.</p>
1234 1235 1236 1237
<p>You can navigate with either the mouse or the keyboard arrow keys.
To change a RAM location, either double-click on it or press Enter while
it's highlighted. Enter the new value (hex only for now, sorry), then
press Enter to make the change. If you change your mind, press Escape
Stephen Kitt's avatar
Stephen Kitt committed
1238 1239 1240 1241
and the original value will be restored. The currently selected RAM cell
can also be changed by using the
<a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
shortcut keys.</p>
1242 1243
<p><img src="graphics/debugger_ram.png"></p>
<p>The 'Undo' button in the upper right should be self-explanatory; it will
Stephen Kitt's avatar
Stephen Kitt committed
1244 1245
undo the most previous operation to one cell only. The 'Revert' button is
more comprehensive. It will undo <b>all</b> operations on <b>all</b> cells
1246 1247
since you first made a change.</p>
<p>The UI objects at the bottom refer to the currently selected RAM cell.
Stephen Kitt's avatar
Stephen Kitt committed
1248 1249 1250 1251
The 'Label' textbox shows the label attached to this RAM location (if any),
and the other two textboxes show the decimal and binary equivalent value.</p>

<p>The remaining buttons to the right are further explained in the next section.</p>
1252 1253 1254


<!-- /////////////////////////////////////////////////////////////////////////  -->
Stephen Kitt's avatar
Stephen Kitt committed
1255
<h3><a name="M6532Search"><u>(L)</u> M6532/RIOT RAM (search/compare mode)</a></h3>
1256 1257 1258 1259
<p>The RAM widget also lets you search memory for values such as lives or remaining
energy, but it's also very useful when debugging to determine which
memory location holds which quantity.</p>
<p><img src="graphics/debugger_ramsearch.png"></p>
Stephen Kitt's avatar
Stephen Kitt committed
1260 1261 1262
<p>To search the RAM, click 'Search...' and enter a byte value into the search editbox (0-255).
All matching values will be highlighted in the RAM widget. If no value was entered,
all RAM locations will be highlighted.</p>
1263

Stephen Kitt's avatar
Stephen Kitt committed
1264 1265 1266
<p>The 'Compare...' button is used to compare the given value using all
addresses currently highlighted. This may be an absolute number (such as 2),
or a comparative number (such as -1). Using a '+' or '-' operator
1267
means 'search addresses for values that have changed by that amount'.</p>
1268
<p>The 'Reset' button resets the entire operation; it clears the highlighted
1269 1270 1271 1272
addresses and allows another search.</p>
<p>The following is an example of inspecting all addresses that have
decreased by 1:</p>
<ul>
Stephen Kitt's avatar
Stephen Kitt committed
1273
	<li>Click 'Search...' and then 'OK' (no value entered). All address/values are highlighted</li>
1274 1275
	<li>Exit debugger mode and lose a life, let your energy decrease, or
		do whatever it is you're trying to debug</li>
Stephen Kitt's avatar
Stephen Kitt committed
1276
	<li>Enter debugger mode again, click 'Compare...' and and enter a '-1' for input.
1277 1278 1279 1280 1281
		This finds all values that have decreased by 1 (as compared to their current
		values)</li>
	<li>Repeatedly following these steps may help to narrow number of
		addresses under consideration, and eventually you'll find the
		memory address you're looking for</li>
1282
	<li>Click 'Reset' when you're finished</li>
1283 1284 1285 1286 1287
</ul>


<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1288
<h2><a name="Disassembly"></a><u>(M)</u> ROM Disassembly</a></h2>
1289
<p>This area contains a disassembly of the current bank of ROM. If a symbol
Stephen Kitt's avatar
Stephen Kitt committed
1290
file is loaded, the disassembly will have labels. Even without a symbol file, the standard TIA/RIOT labels will still be present.</p>
1291
<p>The disassembly is often quite extensive, and whenever possible tries to automatically
Stephen Kitt's avatar
Stephen Kitt committed
1292 1293 1294
differentiate between code, graphics, data and unused bytes. There are actually two
levels of disassembly in Stella. First, the emulation core tracks accesses as a game
is running, making for very accurate results. This is known as a <b>dynamic</b> analysis.
1295 1296 1297 1298 1299 1300
Second, the built-in Distella code does a <b>static</b> analysis, which tentatively fills
in sections that the dynamic disassembler missed (usually because the addresses haven't
been accessed at runtime yet).</p>
<p>As such, code can be marked in two ways (absolute, when done by the emulation core),
and tentative (when done by Distella, and the emulation core hasn't accessed it yet).
Such 'tentative' code is marked with the '*' symbol, indicating that it has the potential
Stephen Kitt's avatar
Stephen Kitt committed
1301
to be accessed as code sometime during the program run. This gives very useful information,
1302
since it can indicate areas toggled by an option in the game (ie, when a player dies,
Stephen Kitt's avatar
Stephen Kitt committed
1303
when difficulty level changes, etc). It can also indicate whether blocks of code after
1304 1305 1306
a relative jump are in fact code, or simply data.</p>


1307 1308
<p><img src="graphics/debugger_rom.png"></p>

1309
<p>The <B>"Bank state"</B> is self-explanatory, and shows a summary of the current
Stephen Kitt's avatar
Stephen Kitt committed
1310 1311 1312
bank information. For normal bankswitched ROMs, this will be the current bank number,
however more advanced schemes will show other types of information here. More detailed
information is available in <a href="#BankswitchInformation"><b>Detailed Bankswitch Information</b></a>.</p>
1313 1314 1315 1316 1317 1318 1319 1320

<p>Each line of disassembly has four fields:</p>
<ul>
<li><b>Breakpoint</b>: This is the area at the far left, to the left of the
labels. Normally there will be nothing there: this indicates that there's
no breakpoint set at that address. You can set and clear breakpoints by
clicking in this area. When a breakpoint is set, there will be a
red circle in this area. These are the same breakpoints as used
Stephen Kitt's avatar
Stephen Kitt committed
1321 1322
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakif" breakpoints
(which makes sense: conditional breaks can break on any condition, the Program
1323
Counter isn't necessarily involved).</li>
1324 1325
<li><b>Labels</b>: Any labels assigned to the given address, either generated
automatically by Distella, read from a DASM symbol file or custom
Stephen Kitt's avatar
Stephen Kitt committed
1326 1327 1328
labels created by the user. If 'Show PC addresses'
(see <a href="#DisassemblySettings"><b>ROM Disassembly Settings</b></a>) is enabled,
the address will be shown in grey.</li>
1329
<li><b>Disassembled bytes</b>: This is either a standard 6502 mnemonic (possibly with operand),
Stephen Kitt's avatar
Stephen Kitt committed
1330 1331 1332
or information about graphics and/or data. For instructions, the cycle count will be
included, separated by a semicolon. For graphics, a bitmap of the data, and the address
of the data is included. For actual data, only the address is included.</li>
1333 1334
<li><b>Hex bytes</b>: These are the raw machine bytes for the code/graphics/data.
Note that only code, graphics or data will show bytes and can be edited.</li>
1335 1336
</ul>

1337
<p>At this point, we should explain the various 'types' that the disassembler
Stephen Kitt's avatar
Stephen Kitt committed
1338 1339
can use. These are known as 'directives', and partly correspond to configuration
options from the standalone Distella program. They are listed in order of
1340
decreasing hierarchy:</p>
Stephen Kitt's avatar
Stephen Kitt committed
1341
<table border="1" cellpadding=4>
1342
<tr><td><b>CODE</b></td><td>Addresses which have appeared in the program counter, or
Stephen Kitt's avatar
Stephen Kitt committed
1343
which tentatively can appear in the program counter. These can be edited in hex.</td></tr>
1344
<tr><td><b>GFX</b></td><td>Addresses which contain data stored in the player graphics registers
Stephen Kitt's avatar
Stephen Kitt committed
1345 1346
(GRP0/GRP1). These addresses are shown with a bitmap of the graphics, which
can be edited in either hex or binary. The bitmap is shown as large blocks.</td></tr>
1347
<tr><td><b>PGFX</b></td><td>Addresses which contain data stored in the playfield graphics registers
Stephen Kitt's avatar
Stephen Kitt committed
1348 1349 1350
(PF0/PF1/PF2). These addresses are shown with a bitmap of the graphics, which
can be edited in either hex or binary. The bitmap is shown as small dashes.</td></tr>
<tr><td><b>DATA</b></td><td>Addresses used as an operand for some opcode. These can be edited
1351
in hex.</td></tr>
Stephen Kitt's avatar
Stephen Kitt committed
1352
<tr><td><b>ROW</b></td><td>Addresses not used as any of the above. These are shown up
1353 1354 1355 1356 1357
to 8 per line, and cannot be edited.</td></tr>
</table>


<p>For code sections, the 6502 mnemonic will be UPPERCASE for all standard instructions,
1358 1359
or lowercase for "illegal" 6502 instructions (like "dcp"). If automatic resolving
of code sections has been disabled for any reason, you'll likely see a lot
Stephen Kitt's avatar
Stephen Kitt committed
1360
of illegal opcodes if you scroll to a data table in ROM. This can also
1361 1362 1363
occur if the disassembler hasn't yet encountered addresses in the PC.
If you step/trace/scanline/frame advance into such an area, the disassembler
will make note of it, and disassemble it correctly from that point on.</p>
1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379

<!-- TODO - is this true any longer?
<p>Beware: the cycle counts don't take into account any penalty cycles
for crossing page boundaries. All branches are shown as 2 cycles, which
is how long they take if the branch isn't taken. Branches that are
taken will actually take 3 cycles (plus a penalty cycle if they cross
page boundaries).</p> -->

<p>You can scroll through the disassembly with the mouse or keyboard. To
center the display on the current PC, press the Space bar.</p>

<p>Any time the Program Counter changes (due to a Step, Trace, Frame
or Scanline advance, or manually setting the PC), the disassembly will
scroll to the current PC location.</p>

<p>Even though ROM is supposed to be Read Only Memory, this is an
Stephen Kitt's avatar
Stephen Kitt committed
1380
emulator: you can change ROM all you want within the debugger. The hex
1381 1382 1383 1384
bytes in the ROM Widget are editable. Double-click on them to edit
them. When you're done, press Enter to accept the changes (in which case
the cart will be re-disasembled) or Escape to cancel them.
Note that only instructions that have been fully disassembled
Stephen Kitt's avatar
Stephen Kitt committed
1385 1386 1387
can be edited. In particular, blank lines or 'ROW' directives
cannot be edited. Also note that certain ROMs can have
sections of address space swapped in and out dynamically. As such, changing
1388
the contents of a certain address will change the area pointed to <b>at
Stephen Kitt's avatar
Stephen Kitt committed
1389 1390
that time</b>. In particular, modifying an address that points to internal
RAM will change the RAM, not the underlying ROM. A future release may
1391 1392
graphically differentiate between RAM and ROM areas.</p>

Stephen Kitt's avatar
Stephen Kitt committed
1393 1394
<h3><a name="DisassemblySettings"></a>ROM Disassembly Settings</a></h3>

1395
<p>The ROM Disassembly also contains a Settings dialog, accessible by right-clicking
1396 1397
anywhere in the listing:</p>
<p><img src="graphics/debugger_romcmenu.png"></p>
1398
<p>The following options are available:</p>
1399
<ul>
1400 1401
<li><b>Set PC @ current line</b>: Set the Program Counter to the address of the
disassembly line where the mouse was clicked (highlighted in green).</li>
1402

1403 1404
<li><b>RunTo PC @ current line</b>: Single-step through code until the Program Counter
matches the address of the disassembly line where the mouse was clicked (highlighted in green)</li>
1405

1406 1407
<li><b>Re-disassemble</b>: Self-explanatory; force the current bank to be
disassembled, regardless of whether anything has changed.</li>
1408

1409
<li><b>Show tentative code</b>: Allow Distella to do a static analysis/disassembly.</li>
1410

1411 1412
<li><b>Show PC addresses</b>: Show Program Counter addresses as labels (where there
isn't already a defined label).</li>
1413

1414 1415 1416 1417
<li><b>Show GFX as binary</b>: Switch between displaying/editing GFX and PGFX sections
in either binary or hexidecimal.</li>

<li><b>Use address relocation</b>: Corresponds to the Distella '-r' option
1418 1419
(Relocate calls out of address range).</li>

1420 1421
</ul>

Stephen Kitt's avatar
Stephen Kitt committed
1422
<h3><a name="Limitations">Limitations</a></h3>
1423 1424 1425

<ul>

1426 1427
<li>The ROM Widget only works on ROM or zero-page RAM separately. If your game runs
code from zero-page RAM, the disassembly will show addresses $80 to $FF (zero-page
Stephen Kitt's avatar
Stephen Kitt committed
1428 1429
RAM address space) only. Once your RAM routine returns, the ROM Widget will switch
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disasm"
1430
command; it will show either ROM or RAM space, not both at the same time.</li>
1431 1432

<li>The standard VCS memory map has the cartridge port at locations
Stephen Kitt's avatar
Stephen Kitt committed
1433
$F000-$FFFF. However, not all the address lines exist on a 6507, so
1434
the cartridge port is "mirrored" at every other 4K chunk of address
Stephen Kitt's avatar
Stephen Kitt committed
1435
space ($1000, $3000, up to $D000). Some developers find it easier
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449
to think of the different banks of ROM as being at different addresses
(such as: Bank 0 at $D000 and bank 1 at $F000). When such a ROM runs,
the Program Counter can point to one of the mirrors instead of the main
area at $F000. This is perfectly OK, and everything works just fine.
However, breakpoints are set on actual addresses. If there were a breakpoint
set at $F010, and the bank later switched to mirror $D000, the breakpoint
will not be shown, and will not break on $D010, even though it's technically
the same address.</li>

</ul>

<p>These limitations will be addressed in a future release of Stella.</p>


1450 1451
<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1452
<h2><a name="BankswitchInformation"><u>(N)</u> Detailed Bankswitch Information</a></h2>
1453

Stephen Kitt's avatar
Stephen Kitt committed
1454
<p>This area shows a detailed breakdown of the bankswitching scheme. Since
1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
the bankswitch schemes can greatly vary in operation, this tab will be
different for each scheme, but its specific functionality should be self-explanatory.
An example of both 4K (non-bankswitched) and DPC (Pitfall II) is as follows:</p>

<p><img src="graphics/debugger_banksimple.png"></p>
<p><img src="graphics/debugger_bankcomplex.png"></p>

<p>In many cases, quite a bit of the scheme functionality can be modified.
Go ahead and try to change something!</p>


1466 1467
<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1468
<h2><a name="CartridgeRAMInformation"><u>(O)</u> Detailed Cartridge Extended RAM Information</a></h2>
1469 1470

<p>If applicable, this area shows a detailed breakdown of any extra RAM supported by
Stephen Kitt's avatar
Stephen Kitt committed
1471
the bankswitching scheme. Since the bankswitch schemes can greatly vary in operation,
1472
this tab will be different for each scheme, but its specific functionality should be
Stephen Kitt's avatar
Stephen Kitt committed
1473
self-explanatory. An example of both F8SC (8K Atari + ram) and DPC (Pitfall II) is
1474 1475 1476 1477 1478 1479
as follows:</p>

<p><img src="graphics/debugger_ram-f8sc.png"></p>
<p><img src="graphics/debugger_ram-dpc.png"></p>

<p>The RAM is shown in a grid similar to how zero-page RAM is shown in M6532/RIOT RAM
Stephen Kitt's avatar
Stephen Kitt committed
1480
(K) and (L). See those sections for a description of usage.
1481 1482

<p>In the cases where RAM is always mapped into the same place in the cartridge
Stephen Kitt's avatar
Stephen Kitt committed
1483
address space (such as Sara-chip), the RAM addresses are labeled as such. In other
1484 1485
cases, such as when the RAM is either quiescent (and mapped in at different places),
or not viewable by the 6507 at all, the RAM addresses are labeled as the cart sees them.
Stephen Kitt's avatar
Stephen Kitt committed
1486
In the examples above, F8SC RAM is labeled starting at its read port, or $F080. However,
1487 1488
the RAM in the DPC scheme is not viewable by the 6507, so its addresses start from $0.

1489 1490
<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1491 1492 1493 1494
<h1><a name="DistellaConfiguration">Distella Configuration Files</a></h1>
<p>As mentioned in <a href="#Disassembly"><b>ROM Disassembly</b></a>, Stella supports the following directives:
CODE/GFX/PGFX/DATA/ROW. While the debugger will try to automatically mark address
space with the appropriate directive, there are times when it will fail. There are
1495 1496 1497
several options in this case:</p>
<ol>
<li><b>Manually set the directives</b>: Directives can be set in the debugger
Stephen Kitt's avatar
Stephen Kitt committed
1498 1499
prompt with the code/gfx/pgfx/data/row commands. These accept an address range
for the given directive type. Setting a range with the same type a second time
1500 1501
will remove that directive from the range.</li>
<li><b>Use configuration files</b>: Configuration files can be used to automatically
Stephen Kitt's avatar
Stephen Kitt committed
1502 1503
load a list of directives when a ROM is loaded. These files can be generated with the
'saveconfig' command, and loaded with the 'loadconfig' command. There are also
1504
'listconfig' and 'clearconfig' commands to show and erase (respectively) the current
Stephen Kitt's avatar
Stephen Kitt committed
1505 1506 1507
directive listing. Upon opening the debugger for the first time, Stella attempts
to load a configuration file from several places. For this example, assume a ROM
named "rr.a26", with properties entry "River Raid". Attempts will be made as follows:
1508 1509 1510 1511 1512
<ul>
<li>ROM dir based on properties entry name: <i>River Raid.cfg</i></li>
<li>ROM dir based on actual ROM name: <i>rr.cfg</i></li>
<li>CFG dir based on properties entry name: <i>configdir/River Raid.cfg</i></li>
</ul>
Stephen Kitt's avatar
Stephen Kitt committed
1513
<p>The location of 'configdir' will depend on the OS as follows:</p>
1514

Stephen Kitt's avatar
Stephen Kitt committed
1515
	<p><table cellpadding=4 border="1">
1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
		<tr>
			<td><b>Linux/Unix</b></td>
			<td><i>~/.stella/cfg/</i></td>
		</tr>
		<tr>
			<td><b>Macintosh</b></td>
			<td><i>~/Library/Application Support/Stella/cfg/</i></td>
		</tr>
		<tr>
			<td><b>Windows</b></td>
			<td><i>%APPDATA%\Stella\cfg\</i>&nbsp;&nbsp;&nbsp;
				<b>OR</b><br>
				<i>_BASEDIR_\cfg\</i>
					(if a file named 'basedir.txt' exists in the application
					directory containing the full pathname for _BASEDIR_)
			</td>
		</tr>
	</table>
</table>
</li>
</ol>


1539 1540
<!-- /////////////////////////////////////////////////////////////////////////  -->
<br>
Stephen Kitt's avatar
Stephen Kitt committed
1541
<h1><a name="HowToHack">Tutorial: How to hack a ROM</a></h1>
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560

<p>Here is a step-by-step guide that shows you how to use the debugger to
actually do something useful. No experience with debuggers is necessary,
but it helps to know at least a little about 6502 programming.</p>

<ol>
	<li>Get the Atari Battlezone ROM image. Make sure you've got the
		regular NTSC version. Load it up in Stella and press TAB to get to
		the main menu. From there, click on "Game Information". For "Name", it
		should say "Battlezone (1983) (Atari)" and for MD5Sum it should say
		"41f252a66c6301f1e8ab3612c19bc5d4". The rest of this tutorial assumes
		you're using this version of the ROM; it may or may not work with the
		PAL version, or with any of the various "hacked" versions floating around
		on the 'net.</li>

	<li>Start the game. You begin the game with 5 lives (count the tank
		symbols at the bottom of the screen).</li>

	<li>Enter the debugger by pressing the ` (backquote) key. Don't get
Stephen Kitt's avatar
Stephen Kitt committed
1561
		killed before you do this, though. You should still have all 5 lives.</li>
1562

1563
	<li>In the RAM display, click the "Search" button and enter "5" for input.
1564
		This searches RAM for your value and highlights all addresses that match
Stephen Kitt's avatar
Stephen Kitt committed
1565
		the input. You should see two addresses highlighted: "00a5" and "00ba".
1566 1567 1568
		These are the only two addresses that currently have the value 5, so they're
		the most likely candidates for "number of lives" counter. (However, some
		games might actually store one less than the real number of lives, or
Stephen Kitt's avatar
Stephen Kitt committed
1569
		one more, so you might have to experiment a bit. Since this is a "rigged
1570 1571 1572 1573 1574 1575 1576 1577 1578
		demo", I already know Battlezone stores the actual number of lives.
		Most games do, actually).</li>

	<li>Exit the debugger by pressing ` (backquote) again. The game will
		pick up where you left off.</li>

	<li>Get killed! Ram an enemy tank, or let him shoot you. Wait for
		the explosion to finish. You will now have 4 lives.</li>

Stephen Kitt's avatar
Stephen Kitt committed
1579 1580 1581
	<li>Enter the debugger again. Click the "Compare" button in RAM widget and enter
		a value of 4. Now the RAM widget should only show one highlighted address:
		"00ba". What we did was search within our previous results (the ones that
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
		were 5 before) for the new value 4. Address $00ba used to have the value 5,
		but now it has 4. This means that Battlezone (almost certainly) stores the
		current number of lives at address $00ba.</li>

	<li>Test your theory. Go to the RAM display and change address $ba to
		some high number like $ff (you could use the Prompt instead: enter "ram
		$ba $ff"). Exit the debugger again (or advance the frame). You should now see lots of lives
		at the bottom of the screen (of course, there isn't room to display $ff
		(255) of them!)... play the game, get killed a few times, notice that
		you have lots of lives.</li>

	<li>Now it's time to decide what sort of "ROM hack" we want to
		accomplish. We've found the "lives" counter for the game, so we can
		either have the game start with lots of lives, or change the game
		code so we can't get killed (AKA immortality), or change the code
		so we always have the same number of lives (so we never run out, AKA
		infinite lives). Let's go for infinite lives: it's a little harder than
		just starting with lots of lives, but not as difficult as immortality
		(for that, we have to disable the collision checking code, which means
		we have to find and understand it first!)</li>

	<li>Set a Write Trap on the lives counter address: "trapwrite $ba"
		in the Prompt. Exit the debugger and play until you get killed. When
		you die, the trap will cause the emulator to enter the debugger with the
		Program Counter pointing to the instruction *after* the one that wrote
		to location $ba.</li>

Stephen Kitt's avatar
Stephen Kitt committed
1609
	<li>Once in the debugger, look at the ROM display. The PC should be at address
1610
		$f238, instruction "LDA $e1". You want to examine a few instructions before
Stephen Kitt's avatar
Stephen Kitt committed
1611
		the PC, so scroll up using the mouse or arrow keys. Do you see
1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635
		the one that affects the lives counter? That's right, it's the "DEC $ba"
		at location $f236.</li>

	<li>Let's stop the DEC $ba from happening. We can't just delete the
		instruction (it would mess up the addressing of everything afterwards,
		if it were even possible), but we can replace it with some other
		instruction(s).

		<p>Since we just want to get rid of the instruction, we can replace it with
		NOP (no operation). From looking at the disassembly, you can see that
		"DEC $ba" is a 2-byte long instruction, so we will need two one-byte
		NOP instructions to replace it. From reading the prompt help (the "help"
		command), you can see that the "rom" command is what we use to patch ROM.

		<p>Unfortunately, Stella doesn't contain an assembler, so we can't just
		type NOP to put a NOP instruction in the code. We'll have to use the
		hex opcode instead.

		<p>Now crack open your 6502 reference manual and look up the NOP
		instruction's opcode... OK, OK, I'll just tell you what it is: it's $EA
		(234 decimal). We need two of them, so the bytes to insert will look like:

		<pre>    $ea $ea</pre>

Stephen Kitt's avatar
Stephen Kitt committed
1636 1637 1638
		<p>Select the line at address $f236 and enter 'ROM patch' mode. This is done
		by either double-clicking the line, or pressing enter. Then delete the bytes
		with backspace key and enter "ea ea". Another way to do this would have been
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650
		to enter "rom $f236 $ea $ea" in the Prompt widget.
	</li>

	<li>Test your patch. First, set location $ba to some number of
		lives that can be displayed on the screen ("poke $ba 3" or enter directly into
		the RAM display). Now exit the debugger and play the game. You should see 3
		lives on the screen.</li>

	<li>The crucial test: get killed again! After the explosion, you
		will *still* see 3 lives: Success! We've hacked Battlezone to give us
		infinite lives.</li>

1651
	<li>Save your work. In the prompt: "saverom". You now
1652
		have your very own infinite-lives version of Battlezone. The file will
1653
		be saved in your HOME directory (NOT your ROM directory), so you might
1654
		want to move it to your ROM directory if it isn't the current directory.
1655
  </li>
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674

	<li>Test the new ROM: exit Stella, and re-run it. Open your ROM
		(or give its name on the command line) and play the game. You can play
		forever! It worked.</li>
</ol>

<p>Now, try the same techniques on some other ROM image (try Pac-Man). Some
games store (lives+1) or (lives-1) instead of the actual number,
so try searching for those if you can't seem to make it work.</p>

<p>If you successfully patch a ROM in the debugger, but the saved version
won't work, or looks funny, you might need to add an entry to the
stella.pro file, to tell Stella what bankswitch and/or TV type to use.
That's outside the scope of this tutorial :)</p>

<p>Of course, the debugger is useful for a lot more than cheating and
hacking ROMs. Remember, with great power comes great responsibility,
so you have no excuse to avoid writing that game you've been thinking
about for so long now :)</p>