|
|
|
@ -102,10 +102,10 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
|
|
|
|
breakpoints as you want.</li>
|
|
|
|
|
|
|
|
|
|
<li>Conditional breakpoints - Break running program when some arbitrary
|
|
|
|
|
condition is true (e.g. "breakif {a == $7f && c}" will break when the Accumulator value is $7f and the Carry flag is true, no matter where
|
|
|
|
|
condition is true (e.g. "breakIf {a == $7f && 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>
|
|
|
|
|
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>
|
|
|
|
@ -172,7 +172,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
|
|
|
|
<li>Data sources for the CPU SP/A/X/Y registers, showing the resolved/source
|
|
|
|
|
address of of load operands.</li>
|
|
|
|
|
<li>Scanline advance (like frame advance, break at beginning
|
|
|
|
|
of next scanline).</li>
|
|
|
|
|
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>
|
|
|
|
@ -183,7 +183,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
|
|
|
|
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
|
|
|
|
|
<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>
|
|
|
|
|
<li>Save patched ROM</li>
|
|
|
|
@ -251,9 +251,9 @@ command on the command line, or alternatively within the ROM launcher in
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<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
|
|
|
|
|
the frame (for NTSC games usually scanLine 262). This is because Stella only checks
|
|
|
|
|
for keystrokes once per frame. Once in the debugger, you can control
|
|
|
|
|
execution by stepping one instruction, scanline, or frame at a time
|
|
|
|
|
execution by stepping one instruction, scanLine, or frame at a time
|
|
|
|
|
(or more than one at a time, using commands in the prompt). You can
|
|
|
|
|
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>
|
|
|
|
@ -408,7 +408,7 @@ in detail in the <a href="index.html">User's Guide</a>.</p>
|
|
|
|
|
|
|
|
|
|
<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,
|
|
|
|
|
trace, scanline, or frame advance. This sounds simple, and it is, but
|
|
|
|
|
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
|
|
|
|
@ -476,7 +476,8 @@ 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>
|
|
|
|
|
"trapWriteIf"). Alternatively you can make use of the camel case names and type
|
|
|
|
|
e.g. "tWI" ("trapWriteIf") or "lAS" ("LoadAllStates").</p>
|
|
|
|
|
|
|
|
|
|
<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
|
|
|
|
@ -630,10 +631,10 @@ 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 & 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>
|
|
|
|
|
<p>You could also use "clearBreaks" to remove all the breakpoints. Also,
|
|
|
|
|
there is a "listBreaks" command that will list them all.</p>
|
|
|
|
|
|
|
|
|
|
<p>¹ By enabling "logbreaks" you can log the current state into
|
|
|
|
|
<p>¹ By enabling "logBreaks" you can log the current state into
|
|
|
|
|
the System Log and continue emulation instead.</p>
|
|
|
|
|
|
|
|
|
|
<h4><a name="ConditionalBreaks">Conditional Breaks</a></h4>
|
|
|
|
@ -664,10 +665,10 @@ is the "!" operator): !(*SWCHB&1). The parentheses are necessary as
|
|
|
|
|
we want to apply the ! to the result of the &, not just the first term
|
|
|
|
|
(the "*SWCHB").</p>
|
|
|
|
|
|
|
|
|
|
<p>"breakif !(*SWCHB&1)" will do the job for us. However, it's an ugly mess
|
|
|
|
|
<p>"breakIf !(*SWCHB&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 & 1 ) }" is a lot more readable, isn't it? If
|
|
|
|
|
<p>"breakIf { !(*SWCHB & 1 ) }" is a lot more readable, isn't it? If
|
|
|
|
|
you're going to use readable expressions with spaces in them,
|
|
|
|
|
enclose the entire expression in curly braces.</p>
|
|
|
|
|
|
|
|
|
@ -676,9 +677,9 @@ 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
|
|
|
|
|
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>
|
|
|
|
|
<p>Conditional breaks appear in "listBreaks", numbered starting from
|
|
|
|
|
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>
|
|
|
|
|
|
|
|
|
|
<p>Any time the debugger is entered due to a trap, breakpoint, or
|
|
|
|
|
conditional break, the reason will be displayed in the
|
|
|
|
@ -687,16 +688,16 @@ conditional break, the reason will be displayed in the
|
|
|
|
|
<h4><a name="Functions">Functions</a></h4>
|
|
|
|
|
|
|
|
|
|
<p>There is one annoyance about complex expressions: once we
|
|
|
|
|
remove the conditional break with "delbreakif" or "clearbreaks",
|
|
|
|
|
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>
|
|
|
|
|
"breakIf function_name":</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
function gameReset { !(*SWCHB & 1 ) }
|
|
|
|
|
breakif gameReset
|
|
|
|
|
breakIf gameReset
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Now we have a meaningful name for the condition, so we can use it again.
|
|
|
|
@ -706,16 +707,16 @@ if the Game Select switch is pressed. We want to break when the user
|
|
|
|
|
presses both Select and Reset:</p>
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
breakif { gameReset && gameSelect }
|
|
|
|
|
breakIf { gameReset && gameSelect }
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>User-defined functions appear in "listfunctions", which shows the label
|
|
|
|
|
<p>User-defined functions appear in "listFunctions", which shows the label
|
|
|
|
|
and expression for each function. Functions can be removed with
|
|
|
|
|
"delfunction label", where the labels come from "listfunctions".</p>
|
|
|
|
|
"delFunction label", where the labels come from "listFunctions".</p>
|
|
|
|
|
|
|
|
|
|
<h4><a name="BuiltInFunctions">Built-in Functions</a></h4>
|
|
|
|
|
|
|
|
|
|
<p>Stella has some pre-defined functions for use with the "breakif"
|
|
|
|
|
<p>Stella has some pre-defined functions for use with the "breakIf"
|
|
|
|
|
command. These allow you to break and enter the debugger on various
|
|
|
|
|
conditions without having to define the conditions yourself.</p>
|
|
|
|
|
|
|
|
|
@ -726,24 +727,24 @@ Stella debugger.</p>
|
|
|
|
|
|
|
|
|
|
<table border="1" cellpadding=4>
|
|
|
|
|
<tr><th>Function</th><th>Definition</th><th>Description</th></tr>
|
|
|
|
|
<tr><td> _joy0left</td><td> !(*SWCHA & $40)</td><td> Left joystick moved left</td></tr>
|
|
|
|
|
<tr><td> _joy0right</td><td> !(*SWCHA & $80)</td><td> Left joystick moved right</td></tr>
|
|
|
|
|
<tr><td> _joy0up</td><td> !(*SWCHA & $10)</td><td> Left joystick moved up</td></tr>
|
|
|
|
|
<tr><td> _joy0down</td><td> !(*SWCHA & $20)</td><td> Left joystick moved down</td></tr>
|
|
|
|
|
<tr><td> _joy0button</td><td> !(*INPT4 & $80)</td><td> Left joystick button pressed</td></tr>
|
|
|
|
|
<tr><td> _joy1left</td><td> !(*SWCHA & $04)</td><td> Right joystick moved left</td></tr>
|
|
|
|
|
<tr><td> _joy1right</td><td> !(*SWCHA & $08)</td><td> Right joystick moved right</td></tr>
|
|
|
|
|
<tr><td> _joy1up</td><td> !(*SWCHA & $01)</td><td> Right joystick moved up</td></tr>
|
|
|
|
|
<tr><td> _joy1down</td><td> !(*SWCHA & $02)</td><td> Right joystick moved down</td></tr>
|
|
|
|
|
<tr><td> _joy1button</td><td> !(*INPT5 & $80)</td><td> Right joystick button pressed</td></tr>
|
|
|
|
|
<tr><td> _joy0Left</td><td> !(*SWCHA & $40)</td><td> Left joystick moved left</td></tr>
|
|
|
|
|
<tr><td> _joy0Right</td><td> !(*SWCHA & $80)</td><td> Left joystick moved right</td></tr>
|
|
|
|
|
<tr><td> _joy0Up</td><td> !(*SWCHA & $10)</td><td> Left joystick moved up</td></tr>
|
|
|
|
|
<tr><td> _joy0Down</td><td> !(*SWCHA & $20)</td><td> Left joystick moved down</td></tr>
|
|
|
|
|
<tr><td> _joy0Fire</td><td> !(*INPT4 & $80)</td><td> Left joystick fire button pressed</td></tr>
|
|
|
|
|
<tr><td> _joy1Left</td><td> !(*SWCHA & $04)</td><td> Right joystick moved left</td></tr>
|
|
|
|
|
<tr><td> _joy1Right</td><td> !(*SWCHA & $08)</td><td> Right joystick moved right</td></tr>
|
|
|
|
|
<tr><td> _joy1Up</td><td> !(*SWCHA & $01)</td><td> Right joystick moved up</td></tr>
|
|
|
|
|
<tr><td> _joy1Down</td><td> !(*SWCHA & $02)</td><td> Right joystick moved down</td></tr>
|
|
|
|
|
<tr><td> _joy1Fire</td><td> !(*INPT5 & $80)</td><td> Right joystick fire button pressed</td></tr>
|
|
|
|
|
<tr><td> _select</td><td> !(*SWCHB & $02)</td><td> Game Select pressed</td></tr>
|
|
|
|
|
<tr><td> _reset</td><td> !(*SWCHB & $01)</td><td> Game Reset pressed</td></tr>
|
|
|
|
|
<tr><td> _color</td><td> *SWCHB & $08</td><td> Color/BW set to Color</td></tr>
|
|
|
|
|
<tr><td> _bw</td><td> !(*SWCHB & $08)</td><td> Color/BW set to BW</td></tr>
|
|
|
|
|
<tr><td> _diff0b</td><td> !(*SWCHB & $40)</td><td> Left difficulty set to B (easy)</td></tr>
|
|
|
|
|
<tr><td> _diff0a</td><td> *SWCHB & $40</td><td> Left difficulty set to A (hard)</td></tr>
|
|
|
|
|
<tr><td> _diff1b</td><td> !(*SWCHB & $80)</td><td> Right difficulty set to B (easy)</td></tr>
|
|
|
|
|
<tr><td> _diff1a</td><td> *SWCHB & $80</td><td> Right difficulty set to A (hard)</td></tr>
|
|
|
|
|
<tr><td> _diff0B</td><td> !(*SWCHB & $40)</td><td> Left difficulty set to B (easy)</td></tr>
|
|
|
|
|
<tr><td> _diff0A</td><td> *SWCHB & $40</td><td> Left difficulty set to A (hard)</td></tr>
|
|
|
|
|
<tr><td> _diff1B</td><td> !(*SWCHB & $80)</td><td> Right difficulty set to B (easy)</td></tr>
|
|
|
|
|
<tr><td> _diff1A</td><td> *SWCHB & $80</td><td> Right difficulty set to A (hard)</td></tr>
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
<p>Don't worry about memorizing them all: the Prompt "help" command
|
|
|
|
@ -759,36 +760,36 @@ that holds 'number of scanlines' on an actual console).</p>
|
|
|
|
|
<table border="1" cellpadding=4>
|
|
|
|
|
<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>
|
|
|
|
|
<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> _ftimreadcycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
|
|
|
|
<tr><td> _fwsynccycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
|
|
|
|
<tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
|
|
|
|
|
<tr><td> _scan</td><td> Current scanline count</td></tr>
|
|
|
|
|
<tr><td> _scanend</td><td> Scanline count at end of last frame</td></tr>
|
|
|
|
|
<tr><td> _scycles</td><td> Number of cycles in current scanline</td></tr>
|
|
|
|
|
<tr><td> _timwrapread</td><td> Timer read wrapped on this cycle</td></tr>
|
|
|
|
|
<tr><td> _timwrapwrite</td><td> Timer write wrapped on this cycle</td></tr>
|
|
|
|
|
<tr><td> _vblank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
|
|
|
|
|
<tr><td> _vsync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
|
|
|
|
|
<tr><td> _cClocks</td><td> Color clocks on a scanLine</td></tr>
|
|
|
|
|
<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> _fTimReadCycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
|
|
|
|
<tr><td> _fWsyncCycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
|
|
|
|
<tr><td> _iCycles</td><td> Number of cycles of last instruction</td></tr>
|
|
|
|
|
<tr><td> _scan</td><td> Current scanLine count</td></tr>
|
|
|
|
|
<tr><td> _scanEnd</td><td> Scanline count at end of last frame</td></tr>
|
|
|
|
|
<tr><td> _sCycles</td><td> Number of cycles in current scanLine</td></tr>
|
|
|
|
|
<tr><td> _timWrapRead</td><td> Timer read wrapped on this cycle</td></tr>
|
|
|
|
|
<tr><td> _timWrapWrite</td><td> Timer write wrapped on this cycle</td></tr>
|
|
|
|
|
<tr><td> _vBlank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
|
|
|
|
|
<tr><td> _vSync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
<p><b>_scan</b> always contains the current scanline count. You can use
|
|
|
|
|
<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
|
|
|
|
|
breakIf _scan==#64
|
|
|
|
|
</pre>
|
|
|
|
|
<p>This will cause Stella to enter the debugger when the TIA reaches the
|
|
|
|
|
beginning of the 64th scanline.</p>
|
|
|
|
|
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 && _bank==1 }
|
|
|
|
|
breakIf { pc==myLabel && _bank==1 }
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>This is similar to setting a regular breakpoint, but it will only trigger
|
|
|
|
@ -807,8 +808,8 @@ 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>
|
|
|
|
|
"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
|
|
|
|
@ -821,7 +822,7 @@ 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>
|
|
|
|
|
|
|
|
|
|
<p>Traps can also combined with a condition ("trapif"). If an access
|
|
|
|
|
<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>
|
|
|
|
@ -845,12 +846,12 @@ 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,
|
|
|
|
|
use "trapread(if)" or "trapwrite(if)".
|
|
|
|
|
use "trapRead(if)" or "trapWrite(if)".
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
</br>
|
|
|
|
|
<h3><a name="SaveWork">Save your work!</a></h3>
|
|
|
|
@ -872,45 +873,45 @@ later re-use.</p>
|
|
|
|
|
See <a href="#Startup"><b>Startup</b></a> for details.
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<b>saveconfig</b>: The "saveconfig" command creates a
|
|
|
|
|
<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
|
|
|
|
|
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>:
|
|
|
|
|
<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
|
|
|
|
|
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
|
|
|
|
|
<p><b>saveRom</b>:
|
|
|
|
|
If you have manipulated a ROM, you can save it with "saveRom". The file is
|
|
|
|
|
named "<rom_filename>.a26".</p>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<p><b>saveses</b>:
|
|
|
|
|
The "saveses" command dumps the whole prompt session into a file named
|
|
|
|
|
<p><b>saveSes</b>:
|
|
|
|
|
The "saveSes" command dumps the whole prompt session into a file named
|
|
|
|
|
"<YYYY-MM-DD_HH-mm-ss>.txt". So you can later lookup what you did exactly
|
|
|
|
|
when you were debugging at that time.</p>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<p><b>saveallstates</b>:
|
|
|
|
|
<p><b>saveAllStates</b>:
|
|
|
|
|
This command works identical to the save all states hotkey (Alt + F9) during emulation.
|
|
|
|
|
The saved states can be loaded with "loadallstates".</p>
|
|
|
|
|
The saved states can be loaded with "loadAllStates".</p>
|
|
|
|
|
</li>
|
|
|
|
|
<li>
|
|
|
|
|
<p><b>savestate</b>:
|
|
|
|
|
<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
|
|
|
|
|
Any previously saved state can be loaded with "loadState" plus the slot
|
|
|
|
|
number (0-9).</p>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
@ -925,63 +926,63 @@ Type "help 'cmd'" to see extended information about the given command.</p>
|
|
|
|
|
a - Set Accumulator to <value>
|
|
|
|
|
aud - Mark 'AUD' range in disassembly
|
|
|
|
|
base - Set default number base to <base> (bin, dec, hex)
|
|
|
|
|
bcol - Mark 'BCOL' range in disassembly
|
|
|
|
|
bCol - Mark 'BCOL' range in disassembly
|
|
|
|
|
break - Set/clear breakpoint at <address> and <bank>
|
|
|
|
|
breakif - Set/clear breakpoint on <condition>
|
|
|
|
|
breaklabel - Set/clear breakpoint on <address> (no mirrors, all banks)
|
|
|
|
|
breakIf - Set/clear breakpoint on <condition>
|
|
|
|
|
breakLabel - Set/clear breakpoint on <address> (no mirrors, all banks)
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
col - Mark 'COL' range in disassembly
|
|
|
|
|
colortest - Show value xx as TIA color
|
|
|
|
|
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
|
|
|
|
|
debugColors - Show Fixed Debug Colors information
|
|
|
|
|
define - Define label xx for address yy
|
|
|
|
|
delbreakif - Delete conditional breakif <xx>
|
|
|
|
|
delfunction - Delete function with label xx
|
|
|
|
|
delsavestateif - Delete conditional savestate point <xx>
|
|
|
|
|
deltrap - Delete trap <xx>
|
|
|
|
|
delwatch - Delete watch <xx>
|
|
|
|
|
disasm - Disassemble address xx [yy lines] (default=PC)
|
|
|
|
|
delBreakIf - Delete conditional breakIf <xx>
|
|
|
|
|
delFunction - Delete function with label xx
|
|
|
|
|
delSaveStateIf - Delete conditional saveState point <xx>
|
|
|
|
|
delTrap - Delete trap <xx>
|
|
|
|
|
delWatch - Delete watch <xx>
|
|
|
|
|
disAsm - Disassemble address xx [yy lines] (default=PC)
|
|
|
|
|
dump - Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
|
|
|
|
|
exec - Execute script file <xx> [prefix]
|
|
|
|
|
exitrom - Exit emulator, return to ROM launcher
|
|
|
|
|
exitRom - Exit emulator, return to ROM launcher
|
|
|
|
|
frame - Advance emulation by <xx> frames (default=1)
|
|
|
|
|
function - Define function name xx for expression yy
|
|
|
|
|
gfx - Mark 'GFX' range in disassembly
|
|
|
|
|
help - help <command>
|
|
|
|
|
joy0up - Set joystick 0 up direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy0down - Set joystick 0 down direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy0left - Set joystick 0 left direction to value <x> (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 <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1up - Set joystick 1 up direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1down - Set joystick 1 down direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1left - Set joystick 1 left direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1right - Set joystick 1 right direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1fire - Set joystick 1 fire button to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy0Up - Set joystick 0 up direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy0Down - Set joystick 0 down direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy0Left - Set joystick 0 left direction to value <x> (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 <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1Up - Set joystick 1 up direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1Down - Set joystick 1 down direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1Left - Set joystick 1 left direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1Right - Set joystick 1 right direction to value <x> (0 or 1), or toggle (no arg)
|
|
|
|
|
joy1Fire - Set joystick 1 fire button to value <x> (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
|
|
|
|
|
loadallstates - Load all emulator states
|
|
|
|
|
loadstate - Load emulator state xx (0-9)
|
|
|
|
|
logbreaks - Logs breaks and traps and continues emulation
|
|
|
|
|
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
|
|
|
|
|
loadAllStates - Load all emulator states
|
|
|
|
|
loadState - Load emulator state xx (0-9)
|
|
|
|
|
logBreaks - Logs breaks and traps and continues emulation
|
|
|
|
|
n - Negative Flag: set (0 or 1), or toggle (no arg)
|
|
|
|
|
palette - Show current TIA palette
|
|
|
|
|
pc - Set Program Counter to address xx
|
|
|
|
|
pcol - Mark 'PCOL' range in disassembly
|
|
|
|
|
pgfx - Mark 'PGFX' range in disassembly
|
|
|
|
|
pCol - Mark 'PCOL' range in disassembly
|
|
|
|
|
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
|
|
|
|
@ -990,32 +991,32 @@ clearsavestateifs - Clear all savestate points
|
|
|
|
|
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
|
|
|
|
|
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 or ?>
|
|
|
|
|
saveaccess - Save access counters to CSV file [?]
|
|
|
|
|
saveconfig - Save DiStella config file (with default name)
|
|
|
|
|
savedis - Save DiStella disassembly to file [?]
|
|
|
|
|
saverom - Save (possibly patched) ROM to file [?]
|
|
|
|
|
saveses - Save console session to file [?]
|
|
|
|
|
savesnap - Save current TIA image to PNG file
|
|
|
|
|
saveallstates - Save all emulator states
|
|
|
|
|
savestate - Save emulator state xx (valid args 0-9)
|
|
|
|
|
savestateif - Create savestate on <condition>
|
|
|
|
|
scanline - Advance emulation by <xx> scanlines (default=1)
|
|
|
|
|
saveAccess - Save access counters to CSV file [?]
|
|
|
|
|
saveConfig - Save DiStella config file (with default name)
|
|
|
|
|
saveDis - Save DiStella disassembly to file [?]
|
|
|
|
|
saveRom - Save (possibly patched) ROM to file [?]
|
|
|
|
|
saveSes - Save console session to file [?]
|
|
|
|
|
saveSnap - Save current TIA image to PNG file
|
|
|
|
|
saveAllStates - Save all emulator states
|
|
|
|
|
saveState - Save emulator state xx (valid args 0-9)
|
|
|
|
|
saveStateIf - Create saveState on <condition>
|
|
|
|
|
scanLine - Advance emulation by <xx> scanlines (default=1)
|
|
|
|
|
step - Single step CPU [with count xx]
|
|
|
|
|
stepwhile - Single step CPU while <condition> is true
|
|
|
|
|
stepWhile - Single step CPU while <condition> 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 <condition> trap R/W access to address(es) xx [yy]
|
|
|
|
|
trapread - Trap read access to address(es) xx [yy]
|
|
|
|
|
trapreadif - On <condition> trap read access to address(es) xx [yy]
|
|
|
|
|
trapwrite - Trap write access to address(es) xx [yy]
|
|
|
|
|
trapwriteif - On <condition> trap write access to address(es) xx [yy]
|
|
|
|
|
trapIf - On <condition> trap R/W access to address(es) xx [yy]
|
|
|
|
|
trapRead - Trap read access to address(es) xx [yy]
|
|
|
|
|
trapReadIf - On <condition> trap read access to address(es) xx [yy]
|
|
|
|
|
trapWrite - Trap write access to address(es) xx [yy]
|
|
|
|
|
trapWriteIf - On <condition> trap write access to address(es) xx [yy]
|
|
|
|
|
type - Show disassembly type for address xx [yy]
|
|
|
|
|
uhex - Toggle upper/lowercase HEX display
|
|
|
|
|
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)
|
|
|
|
@ -1115,12 +1116,12 @@ volume resulting from the two channel volumes.</p>
|
|
|
|
|
<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 &
|
|
|
|
|
current scanLine, with the contents of the old frame (in black &
|
|
|
|
|
white) filling the rest of the display. Note that if 'phosphor mode'
|
|
|
|
|
or TV effects are enabled, you won't see the effects here; this shows the
|
|
|
|
|
<b>raw</b> TIA image only.</p>
|
|
|
|
|
|
|
|
|
|
<p>To e.g. watch the TIA draw the frame one scanline at a time, you can
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
<p>You can also right-click anywhere in this window to show a context menu,
|
|
|
|
@ -1128,10 +1129,10 @@ as illustrated:</p>
|
|
|
|
|
<p><img src="graphics/debugger_tiaoutcmenu.png"></p>
|
|
|
|
|
<p>The options are as follows:</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
|
|
|
|
|
<li><b>Fill to scanLine</b>: This option will draw all scanlines up to the
|
|
|
|
|
vertical position where the mouse was clicked (see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
|
|
|
|
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
|
|
|
|
scanline where the mouse was clicked. You can also use a left-click or
|
|
|
|
|
scanLine where the mouse was clicked. You can also use a left-click or
|
|
|
|
|
the Prompt Tab commands to list and turn off the breakpoint
|
|
|
|
|
(see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
|
|
|
|
<li><b>Set zoom position</b>: Influences what is shown in the TIA
|
|
|
|
@ -1152,27 +1153,27 @@ as illustrated:</p>
|
|
|
|
|
<p>The indicators are as follows (note that all these are read-only):</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li><b>Frame Cycls</b>: The number of CPU cycles that have been executed this frame since
|
|
|
|
|
VSYNC was cleared at scanline 0.</li>
|
|
|
|
|
VSYNC was cleared at scanLine 0.</li>
|
|
|
|
|
<li><b>WSync Cycls</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
|
|
|
|
|
VSYNC was cleared at scanline 0.</li>
|
|
|
|
|
VSYNC was cleared at scanLine 0.</li>
|
|
|
|
|
<li><b>Timer Cycls</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
|
|
|
|
|
VSYNC was cleared at scanline 0.</li>
|
|
|
|
|
VSYNC was cleared at scanLine 0.</li>
|
|
|
|
|
<li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
|
|
|
|
|
<li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
|
|
|
|
|
interrupt.</li>
|
|
|
|
|
<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
|
|
|
|
|
<li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
|
|
|
|
|
<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 Programmer's Guide).</li>
|
|
|
|
|
<li><b>Scan Cycle</b>: The number of CPU cycles that have been executed since the beginning
|
|
|
|
|
of the current scanline.</li>
|
|
|
|
|
of the current scanLine.</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.
|
|
|
|
|
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>
|
|
|
|
|
160 visible clocks per scanLine, the Pixel Position will range from -68 to 159.</li>
|
|
|
|
|
<li><b>Color Clock</b>: The current number of total color clocks since the beginning of this
|
|
|
|
|
scanline's HBLANK. This counter starts at zero, but otherwise displays the same
|
|
|
|
|
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>
|
|
|
|
@ -1190,10 +1191,10 @@ as illustrated:</p>
|
|
|
|
|
<p><img src="graphics/debugger_tiazoomcmenu.png"></p>
|
|
|
|
|
<p>These options allow you to:</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
|
|
|
|
|
<li><b>Fill to scanLine</b>: This option will draw all scanlines up to the
|
|
|
|
|
vertical position where the mouse was clicked.</li>
|
|
|
|
|
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
|
|
|
|
scanline where the mouse was clicked. You can also
|
|
|
|
|
scanLine where the mouse was clicked. You can also
|
|
|
|
|
the Prompt Tab commands to list and turn off the breakpoint.</li>
|
|
|
|
|
<li><b>2x|4x|8x zoom</b>: Zoom in on the image for even greater detail.</li>
|
|
|
|
|
</ul>
|
|
|
|
@ -1379,7 +1380,7 @@ 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
|
|
|
|
|
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakif" breakpoints
|
|
|
|
|
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
|
|
|
|
|
Counter isn't necessarily involved).</li>
|
|
|
|
|
<li><b>Labels</b>: Any labels assigned to the given address, either generated
|
|
|
|
@ -1477,7 +1478,7 @@ or lowercase for "illegal" 6502 instructions (like "dcp"). If automatic resolvin
|
|
|
|
|
of code sections has been disabled for any reason, you'll likely see a lot
|
|
|
|
|
of illegal opcodes if you scroll to a data table in ROM. This can also
|
|
|
|
|
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
|
|
|
|
|
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>
|
|
|
|
|
|
|
|
|
|
<!-- TODO - is this true any longer?
|
|
|
|
@ -1545,7 +1546,7 @@ Note: The code will continue to run fine, but the ROM image will be altered.</li
|
|
|
|
|
<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
|
|
|
|
|
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"
|
|
|
|
|
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disAsm"
|
|
|
|
|
command; it will show either ROM or RAM space, not both at the same time.</li>
|
|
|
|
|
|
|
|
|
|
<li>The standard VCS memory map has the cartridge port at locations
|
|
|
|
@ -1614,13 +1615,13 @@ space with the appropriate directive, there are times when it will fail. There a
|
|
|
|
|
several options in this case:</p>
|
|
|
|
|
<ol>
|
|
|
|
|
<li><b>Manually set the directives</b>: Directives can be set in the debugger
|
|
|
|
|
prompt with the aud/code/col/bcol/gfx/pcol/pgfx/data/row commands. These accept an address range
|
|
|
|
|
prompt with the aud/code/col/bcol/gfx/pCol/pGfx/data/row commands. These accept an address range
|
|
|
|
|
for the given directive type. Setting a range with the same type a second time
|
|
|
|
|
will remove that directive from the range.</li>
|
|
|
|
|
<li><b>Use configuration files</b>: Configuration files can be used to automatically
|
|
|
|
|
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
|
|
|
|
|
'listconfig' and 'clearconfig' commands to show and erase (respectively) the current
|
|
|
|
|
'saveConfig' command, and loaded with the 'loadConfig' command. There are also
|
|
|
|
|
'listConfig' and 'clearConfig' commands to show and erase (respectively) the current
|
|
|
|
|
directive listing. Upon opening the debugger for the first time, Stella attempts
|
|
|
|
|
to load a configuration file from the folder containing the ROM. Assuming a ROM named "rr.a26" exists, the config file must be named <i>rr.cfg</i>.
|
|
|
|
|
</ul>
|
|
|
|
@ -1693,7 +1694,7 @@ but it helps to know at least a little about 6502 programming.</p>
|
|
|
|
|
(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"
|
|
|
|
|
<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
|
|
|
|
@ -1741,7 +1742,7 @@ but it helps to know at least a little about 6502 programming.</p>
|
|
|
|
|
will *still* see 3 lives: Success! We've hacked Battlezone to give us
|
|
|
|
|
infinite lives.</li>
|
|
|
|
|
|
|
|
|
|
<li>Save your work. In the prompt: "saverom". You now
|
|
|
|
|
<li>Save your work. In the prompt: "saveRom". You now
|
|
|
|
|
have your very own infinite-lives version of Battlezone. The file will
|
|
|
|
|
be saved in your HOME directory (NOT your ROM directory), so you might
|
|
|
|
|
want to move it to your ROM directory if it isn't the current directory.
|
|
|
|
|