mirror of https://github.com/stella-emu/stella.git
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:
parent
066331d082
commit
37724f1b00
|
@ -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
|
Program Counter hits a predefined address. You can set as many
|
||||||
breakpoints as you want.</li>
|
breakpoints as you want.</li>
|
||||||
<li>Conditional breakpoints - Break running program when some arbitrary
|
<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 && c}" will break when the
|
||||||
Accumulator value is $7f and the Carry flag is true, no matter where
|
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
|
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
|
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>
|
<h2>How to use the debugger</h2>
|
||||||
|
|
||||||
<p>Pressing ` (aka backtick, backquote, grave accent) toggles the debugger on
|
<p>Pressing ` (aka backtick, backquote, grave accent) toggles the debugger on
|
||||||
& off. When you exit the debugger, the emulation resumes at the current
|
& off. When you exit the debugger, the emulation resumes at the current
|
||||||
program counter, and continues until either a breakpoint/trap is hit,
|
program counter, and continues until either a breakpoint/trap is hit,
|
||||||
or the ` key is pressed again. Pressing Ctrl-Tab cycles between tabs
|
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.
|
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
|
are shown as 2 cycles, as though they're not going to be taken. A
|
||||||
branch that's taken adds a cycle, of course.
|
branch that's taken adds a cycle, of course.
|
||||||
|
|
||||||
The ">" is where your commands will appear as you type them.
|
The ">" is where your commands will appear as you type them.
|
||||||
</pre>
|
</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
|
can be as a hex constant ($ff, $1234), or as complex as
|
||||||
"the low byte of the 16-bit value located at the address
|
"the low byte of the 16-bit value located at the address
|
||||||
pointed to by the binary number 1010010110100101" (which
|
pointed to by the binary number 1010010110100101" (which
|
||||||
would be "@<\1010010110100101"). You can also use registers
|
would be "@<\1010010110100101"). You can also use registers
|
||||||
and labels in expressions.</p>
|
and labels in expressions.</p>
|
||||||
|
|
||||||
<p>You can use arithmetic and boolean operators in expressions. The
|
<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>
|
<pre>
|
||||||
+ - * / (add, subtract, multiply, divide: 2+2 is 4)
|
+ - * / (add, subtract, multiply, divide: 2+2 is 4)
|
||||||
% (modulus/remainder: 3%2 is 1)
|
% (modulus/remainder: 3%2 is 1)
|
||||||
& | ^ ~ (bitwise AND, OR, XOR, NOT: 2&3 is 2)
|
& | ^ ~ (bitwise AND, OR, XOR, NOT: 2&3 is 2)
|
||||||
&& || ! (logical AND, OR, NOT: 2&&3 is 1, 2||0 is 0)
|
&& || ! (logical AND, OR, NOT: 2&&3 is 1, 2||0 is 0)
|
||||||
( ) (parentheses for grouping: (2+2)*3 is 12)
|
( ) (parentheses for grouping: (2+2)*3 is 12)
|
||||||
* @ (byte and word pointer dereference: *$80 is the byte stored
|
* @ (byte and word pointer dereference: *$80 is the byte stored
|
||||||
at location $80)
|
at location $80)
|
||||||
[ ] (array-style byte pointer dereference: $80[1] is the byte
|
[ ] (array-style byte pointer dereference: $80[1] is the byte
|
||||||
stored at location ($80+1) or $81)
|
stored at location ($80+1) or $81)
|
||||||
< > (prefix versions: low and high byte. <$abcd is $cd)
|
< > (prefix versions: low and high byte. <$abcd is $cd)
|
||||||
== < > <= >= !=
|
== < > <= >= !=
|
||||||
(comparison: equality, less-than, greater-than, less-or-equals,
|
(comparison: equality, less-than, greater-than, less-or-equals,
|
||||||
greater-or-equals, not-equals)
|
greater-or-equals, not-equals)
|
||||||
<< >> (bit shifts, left and right: 1<<1 is 2, 2>>1 is 1)
|
<< >> (bit shifts, left and right: 1<<1 is 2, 2>>1 is 1)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Division by zero is not an error: it results in zero instead.</p>
|
<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
|
bitwise operators operate on all the bits of the operand (just like
|
||||||
AND, ORA, EOR in 6502 asm), while the logical operators treat their
|
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.
|
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&$5678 results in $1230, whereas $1234&&$5678 results in 1.
|
||||||
This is just like C or C++...</p>
|
This is just like C or C++...</p>
|
||||||
|
|
||||||
<h4>Prefixes</h4>
|
<h4>Prefixes</h4>
|
||||||
|
@ -291,14 +291,14 @@ to change the meaning of an expression. The prefixes are:</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>Hi/Lo Byte Prefixes:<br>
|
<li>Hi/Lo Byte Prefixes:<br>
|
||||||
<p>"<"<br>
|
<p>"<"<br>
|
||||||
Take the low byte of a 16-bit value. This has no effect on an 8-bit
|
Take the low byte of a 16-bit value. This has no effect on an 8-bit
|
||||||
value: "a" is equal to "<a". However, "<$1234" equals "$34".</p>
|
value: "a" is equal to "<a". However, "<$1234" equals "$34".</p>
|
||||||
|
|
||||||
<p>">"<br>
|
<p>">"<br>
|
||||||
Take the high byte of a 16-bit value. For 8-bit values such as
|
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,
|
the Accumulator, this will always result in zero. For 16-bit values,
|
||||||
"<$1234" = "$12".</p>
|
"<$1234" = "$12".</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>Number Base Prefixes:<br>
|
<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
|
<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,
|
assumed to be in the default base. When you first start Stella,
|
||||||
the default base is 16 (hexadecimal). You can change it with the
|
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
|
<p>Remember, you can use arbitrarily complex expressions with any
|
||||||
command that takes arguments (except the ones that take filenames,
|
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
|
<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.
|
set it. In the example, "break kernel" will remove the breakpoint.
|
||||||
The "break" command can be thought of as a *toggle*: it turns the
|
The "break" command can be thought of as a *toggle*: it turns the
|
||||||
breakpoint on & off, like a light switch.</p>
|
breakpoint on & off, like a light switch.</p>
|
||||||
|
|
||||||
<p>You could also use "clearbreaks" to remove all the breakpoints. Also,
|
<p>You could also use "clearbreaks" to remove all the breakpoints. Also,
|
||||||
there is a "listbreaks" command that will list them all.</p>
|
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>
|
"*SWCHB".</p>
|
||||||
|
|
||||||
<p>We're only wanting to look at bit 0, so let's mask off all the other
|
<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&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
|
almost there: this will be 1 (true) if the switch is NOT pressed. We
|
||||||
want to break if it IS pressed...</p>
|
want to break if it IS pressed...</p>
|
||||||
|
|
||||||
<p>So we invert the sense of the test with a logical NOT operator (which
|
<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
|
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
|
we want to apply the ! to the result of the &, not just the first term
|
||||||
(the "*SWCHB").</p>
|
(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>
|
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,
|
you're going to use readable expressions with spaces in them,
|
||||||
enclose the entire expression in curly braces {}.</p>
|
enclose the entire expression in curly braces {}.</p>
|
||||||
|
|
||||||
|
@ -400,7 +402,7 @@ if we wanted to use it again.</p>
|
||||||
"breakif function_name":</p>
|
"breakif function_name":</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
function gameReset { !(*SWCHB & 1 ) }
|
function gameReset { !(*SWCHB & 1 ) }
|
||||||
breakif gameReset
|
breakif gameReset
|
||||||
</pre>
|
</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>
|
presses both Select and Reset:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
breakif { gameReset && gameSelect }
|
breakif { gameReset && gameSelect }
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>If you've defined a lot of complex functions, you probably will
|
<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
|
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,
|
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
|
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 & off. You
|
||||||
can also get rid of all traps at once with the "cleartraps" command.</p>
|
can also get rid of all traps at once with the "cleartraps" command.</p>
|
||||||
|
|
||||||
<p>Use "listtraps" to see all enabled traps.</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).
|
Neg - Negate the current location (twos' complement negative).
|
||||||
++ - Increment the current location
|
++ - Increment the current location
|
||||||
-- - Decrement the current location
|
-- - Decrement the current location
|
||||||
<< - Shift the current location left. Any bits shifted off the left
|
<< - Shift the current location left. Any bits shifted off the left
|
||||||
are lost (they will NOT end up in the Carry flag).
|
are lost (they will NOT end up in the Carry flag).
|
||||||
>> - Shift the current location right, like << above.
|
>> - Shift the current location right (opposite of << above).
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>This widget also lets you search memory for values such as lives or remaining
|
<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>
|
<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>
|
<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>
|
but it helps to know at least a little about 6502 programming.</p>
|
||||||
|
|
||||||
<ol>
|
<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
|
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
|
the main menu. From there, click on "Game Information". For "Name", it
|
||||||
should say "Battlezone (1983) (Atari) [!]" and for MD5Sum it should say
|
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
|
<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>
|
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
|
This searches RAM for your value and highlights all addresses that match
|
||||||
the input. You should see two addresses highlighted: "00a5" and "00ba".
|
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
|
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
|
but now it has 4. This means that Battlezone (almost certainly) stores the
|
||||||
current number of lives at address $00ba.</li>
|
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
|
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
|
$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
|
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
|
Program Counter pointing to the instruction *after* the one that wrote
|
||||||
to location $ba.</li>
|
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
|
$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 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"
|
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
|
<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
|
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>
|
lives on the screen.</li>
|
||||||
|
|
||||||
<li>The crucial test: get killed again! After the explosion, you
|
<li>The crucial test: get killed again! After the explosion, you
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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"
|
#include "bspf.hxx"
|
||||||
|
@ -310,6 +310,10 @@ const string Debugger::getSourceLines(int addr) {
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Debugger::autoExec() {
|
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 file = myOSystem->romFile();
|
||||||
|
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// 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
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
// Copyright (C) 2002-2004 The ScummVM project
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
|
@ -509,10 +509,10 @@ void PromptWidget::loadConfig()
|
||||||
print(PROMPT);
|
print(PROMPT);
|
||||||
_promptStartPos = _promptEndPos = _currentPos;
|
_promptStartPos = _promptEndPos = _currentPos;
|
||||||
|
|
||||||
|
_firstTime = false;
|
||||||
|
|
||||||
// Take care of one-time debugger stuff
|
// Take care of one-time debugger stuff
|
||||||
instance()->debugger().autoExec();
|
instance()->debugger().autoExec();
|
||||||
|
|
||||||
_firstTime = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue