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
|
||||
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 && 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
|
||||
& 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 ">" 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 "@<\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)
|
||||
& | ^ ~ (bitwise AND, OR, XOR, NOT: 2&3 is 2)
|
||||
&& || ! (logical AND, OR, NOT: 2&&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)
|
||||
== < > <= >= !=
|
||||
< > (prefix versions: low and high byte. <$abcd is $cd)
|
||||
== < > <= >= !=
|
||||
(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)
|
||||
<< >> (bit shifts, left and right: 1<<1 is 2, 2>>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&$5678 results in $1230, whereas $1234&&$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>"<"<br>
|
||||
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
|
||||
the Accumulator, this will always result in zero. For 16-bit values,
|
||||
"<$1234" = "$12".</p>
|
||||
"<$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 & 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&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&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>
|
||||
|
||||
|
@ -400,7 +402,7 @@ if we wanted to use it again.</p>
|
|||
"breakif function_name":</p>
|
||||
|
||||
<pre>
|
||||
function gameReset { !(*SWCHB & 1 ) }
|
||||
function gameReset { !(*SWCHB & 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 && 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 & 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
|
||||
<< - 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.
|
||||
>> - Shift the current location right (opposite of << 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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue