Added support for executing "autoexec.stella" batch file on debugger start.

This happens before "$romname.stella" is loaded.

Fixed bug that caused the emulator to crash if either of the startup batch
files contained a "base" command.

Minor work on documentation (still in progress).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@835 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-10-15 16:38:17 +00:00
parent 066331d082
commit 37724f1b00
3 changed files with 45 additions and 36 deletions

View File

@ -22,7 +22,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
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 && c}" will break when the
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
@ -105,7 +105,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
<h2>How to use the debugger</h2>
<p>Pressing ` (aka backtick, backquote, grave accent) toggles the debugger on
& off. When you exit the debugger, the emulation resumes at the current
&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. Pressing Ctrl-Tab cycles between tabs
from left to right, and Shift-Ctrl-Tab cycles from right to left.
@ -192,7 +192,7 @@ it hasn't been executed yet.</p>
are shown as 2 cycles, as though they're not going to be taken. A
branch that's taken adds a cycle, of course.
The ">" is where your commands will appear as you type them.
The "&gt;" is where your commands will appear as you type them.
</pre>
-->
@ -220,7 +220,7 @@ 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 "@<\1010010110100101"). You can also use registers
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
@ -229,18 +229,18 @@ 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)
& | ^ ~ (bitwise AND, OR, XOR, NOT: 2&3 is 2)
&& || ! (logical AND, OR, NOT: 2&&3 is 1, 2||0 is 0)
&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)
< > (prefix versions: low and high byte. <$abcd is $cd)
== < > <= >= !=
&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)
<< >> (bit shifts, left and right: 1<<1 is 2, 2>>1 is 1)
&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>
@ -254,7 +254,7 @@ instead of just "=".</p>
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&$5678 results in $1230, whereas $1234&&$5678 results in 1.
So $1234&amp;$5678 results in $1230, whereas $1234&amp;&amp;$5678 results in 1.
This is just like C or C++...</p>
<h4>Prefixes</h4>
@ -291,14 +291,14 @@ to change the meaning of an expression. The prefixes are:</p>
</li>
<li>Hi/Lo Byte Prefixes:<br>
<p>"<"<br>
<p>"&lt;"<br>
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, "<$1234" equals "$34".</p>
value: "a" is equal to "&lt;a". However, "&lt;$1234" equals "$34".</p>
<p>">"<br>
<p>"&gt;"<br>
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,
"<$1234" = "$12".</p>
"&lt;$1234" = "$12".</p>
</li>
<li>Number Base Prefixes:<br>
@ -319,7 +319,9 @@ to change the meaning of an expression. The prefixes are:</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.</p>
"base" command. If you want to change the default base to decimal permanently,
you can put a "base #10" command in your "autoexec.stella" file (see
the section on "Startup").</p>
<p>Remember, you can use arbitrarily complex expressions with any
command that takes arguments (except the ones that take filenames,
@ -351,7 +353,7 @@ 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 & off, like a light switch.</p>
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>
@ -375,19 +377,19 @@ 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&1". The expression now evaluates to bit 0 of SWCHB. We're
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&1). The parentheses are necessary as
we want to apply the ! to the result of the &, not just the first term
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&1)" will do the job for us. However, it's an ugly mess
<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 & 1 ) }" is a lot more readable, isn't it? If
<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,
enclose the entire expression in curly braces {}.</p>
@ -400,7 +402,7 @@ if we wanted to use it again.</p>
"breakif function_name":</p>
<pre>
function gameReset { !(*SWCHB & 1 ) }
function gameReset { !(*SWCHB &amp; 1 ) }
breakif gameReset
</pre>
@ -411,7 +413,7 @@ 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 &amp;&amp; gameSelect }
</pre>
<p>If you've defined a lot of complex functions, you probably will
@ -473,7 +475,7 @@ in reverse.</p>
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" or "trapwrite". To remove a trap, you just attempt
to set it again: the commands actually toggle the trap on & off. You
to set it again: the commands actually toggle the trap on &amp; off. You
can also get rid of all traps at once with the "cleartraps" command.</p>
<p>Use "listtraps" to see all enabled traps.</p>
@ -564,9 +566,9 @@ currently-selected memory location. The buttons are:</p>
Neg - Negate the current location (twos' complement negative).
++ - Increment the current location
-- - Decrement the current location
<< - Shift the current location left. Any bits shifted off the left
&lt;&lt; - Shift the current location left. Any bits shifted off the left
are lost (they will NOT end up in the Carry flag).
>> - Shift the current location right, like << above.
&gt;&gt; - Shift the current location right (opposite of &lt;&lt; above).
</pre>
<p>This widget also lets you search memory for values such as lives or remaining
@ -605,7 +607,10 @@ decreased by 1:
<h2>ROM Widget</h2>
<p>TODO: add documentation</p>
<p>The ROM Widget is a disassembly of the current bank of ROM. If a symbol
file is loaded, the disassembly will have labels. Even without a symbol
file, the standard TIA/RIOT labels will still be present.</p>
<h2>Global Buttons</h2>
@ -628,7 +633,7 @@ 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
<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
@ -643,7 +648,7 @@ but it helps to know at least a little about 6502 programming.</p>
<li>Enter the debugger by pressing the ` (backquote) key. Don't get
killed before you do this, though. You should still have all 5 lives.</li>
<li>In the RAM Widget, click the "Search" button and enter "5" for input.
<li>In the RAM display, click the "Search" button and enter "5" for input.
This searches RAM for your value and highlights all addresses that match
the input. You should see two addresses highlighted: "00a5" and "00ba".
These are the only two addresses that currently have the value 5, so they're
@ -666,7 +671,7 @@ but it helps to know at least a little about 6502 programming.</p>
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 widget and change address $ba to
<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. You should now see lots of lives
at the bottom of the screen (of course, there isn't room to display $ff
@ -689,7 +694,7 @@ but it helps to know at least a little about 6502 programming.</p>
Program Counter pointing to the instruction *after* the one that wrote
to location $ba.</li>
<li>Once in the debugger, look at the ROM widget. The PC should be at address
<li>Once in the debugger, look at the ROM display. The PC should be at address
$f238, instruction "LDA $e1". You want to examine a few instructions before
the PC, so scroll up using the mouse or arrow keys. Do you see
the one that affects the lives counter? That's right, it's the "DEC $ba"
@ -724,7 +729,7 @@ but it helps to know at least a little about 6502 programming.</p>
<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 widget). Now exit the debugger and play the game. You should see 3
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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Debugger.cxx,v 1.100 2005-10-13 01:13:20 urchlay Exp $
// $Id: Debugger.cxx,v 1.101 2005-10-15 16:38:17 urchlay Exp $
//============================================================================
#include "bspf.hxx"
@ -310,6 +310,10 @@ const string Debugger::getSourceLines(int addr) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::autoExec() {
// autoexec.stella is always run
myPrompt->print("autoExec():\n" + myParser->exec(myOSystem->baseDir() + "/autoexec.stella") + "\n");
// also, "romname.stella" if present
string file = myOSystem->romFile();
string::size_type pos;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PromptWidget.cxx,v 1.4 2005-10-11 17:14:35 stephena Exp $
// $Id: PromptWidget.cxx,v 1.5 2005-10-15 16:38:17 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -509,10 +509,10 @@ void PromptWidget::loadConfig()
print(PROMPT);
_promptStartPos = _promptEndPos = _currentPos;
_firstTime = false;
// Take care of one-time debugger stuff
instance()->debugger().autoExec();
_firstTime = false;
}
}