update debugger docs

add missing debugger commands for enhanced DiStella data detection
This commit is contained in:
thrust26 2020-03-29 12:30:26 +02:00
parent 09fb69f397
commit 1beaf64edd
7 changed files with 204 additions and 101 deletions

View File

@ -20,9 +20,9 @@
a game. This allows the user to save high scores for these games. For each
game and variation, the top 10 scores can be saved. (TOOD: Doc)
* Added displaying last write address in debugger. (TOOD: Doc)
* Added displaying last write address in debugger.
* Added detection of color and audio data in DiStella. (TOOD: Doc)
* Added detection of color and audio data in DiStella.
6.0.2 to 6.1: (March 22, 2020)

View File

@ -121,13 +121,14 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
<li>Supports Distella 'configuration directives', which may be used to
override automatic code/data determination in the disassembly. For now,
the following directives are supported: CODE, GFX, PGFX, DATA, ROW.
These directives can be entered at the debugger prompt, or (automatically)
the following directives are supported: CODE, GFX, PGFX, COL, PCOL, BCOL, AUD, DATA, ROW.
These directives can be entered at the debugger prompt, or be (automatically)
loaded and saved in configuration files.</li>
<li>Extensive disassembly support, both from the emulation core and with help
from Distella. Where possible, the disassembly differentiates between code,
player graphics and playfield graphics (ie, addresses stored in GRPx and PFx)
player and playfield graphics, colors and audio (ie, addresses stored in
GRPx, PFx, COLUxx, AUDxx)
and data (addresses used as an operand of a command). Code sections are also
differentiated between actual code, and 'tentative' code (ie, areas that may
represent code sections, but haven't actually been executed yet). Such
@ -906,7 +907,9 @@ Type "help 'cmd'" to see extended information about the given command.</p>
<pre>
a - Set Accumulator to &lt;value&gt;
aud - Mark 'AUD' range in disassembly
base - Set default number base to &lt;base&gt; (bin, dec, hex)
bcol - Mark 'BCOL' range in disassembly
break - Set/clear breakpoint at &lt;address&gt; and &lt;bank&gt;
breakif - Set/clear breakpoint on &lt;condition&gt;
breaklabel - Set/clear breakpoint on &lt;address&gt; (no mirrors, all banks)
@ -919,6 +922,7 @@ clearsavestateifs - Clear all savestate points
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
d - Decimal Mode Flag: set (0 or 1), or toggle (no arg)
data - Mark 'DATA' range in disassembly
@ -959,6 +963,7 @@ clearsavestateifs - Clear all savestate points
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
print - Evaluate/print expression xx in hex/dec/binary
ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
@ -1217,6 +1222,8 @@ registers. For example, consider the command 'LDA ($80),Y'. The operand of
the command resolves to some address, which isn't always easy to determine at
first glance. The 'Src Addr' area shows the actual resulting operand/address
being used with the given opcode.</p>
<p>The destination address of the last write is shown besides 'Dest'.</p>
<p>There's not much else to say about the CPU Registers widget: if you know 6502
assembly, it's pretty self-explanatory. If you don't, well, you should
learn :)</p>
@ -1371,21 +1378,78 @@ can use. These are known as 'directives', and partly correspond to configuration
options from the standalone Distella program. They are listed in order of
decreasing hierarchy:</p>
<table border="1" cellpadding=4>
<tr><td><b>CODE</b></td><td>Addresses which have appeared in the program counter, or
which tentatively can appear in the program counter. These can be edited in hex.</td></tr>
<tr><td><b>GFX</b></td><td>Addresses which contain data stored in the player graphics registers
(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>
<tr><td><b>PGFX</b></td><td>Addresses which contain data stored in the playfield graphics registers
(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
in hex.</td></tr>
<tr><td><b>ROW</b></td><td>Addresses not used as any of the above. These are shown up
to 8 per line, and cannot be edited.</td></tr>
<tr>
<td>
<b>CODE</b>
</td><td>
Addresses which have appeared in the program counter, or
which tentatively can appear in the program counter. These can be edited in hex.
</td>
</tr><tr>
<td>
<b>GFX</b>
</td><td>
Addresses which contain data stored in the player graphics registers
(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><tr>
<td>
<b>PGFX</b>
</td><td>
Addresses which contain data stored in the playfield graphics registers
(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>COL</b>
</td><td>
Addresses which contain data stored in the player color registers
(COLUP0/COLUP1). These addresses are shown as color constants, which
can be edited in hex. The color constant names are depending on the ROM's TV type.
</td>
</tr><tr>
<td>
<b>PCOL</b>
</td><td>
Addresses which contain data stored in the playfield color register
(COLUPF). These addresses are shown as color constants, which
can be edited in hex. The color constant names are depending on the ROM's TV type.
</td>
</tr><tr>
<td>
<b>BCOL</b>
</td><td>
Addresses which contain data stored in the background color register
(COLUBK). These addresses are shown as color constants, which
can be edited in hex. The color constant names are depending on the ROM's TV type.
</td>
</tr><tr>
<td>
<b>AUD</b>
</td><td>
Addresses which contain data stored in the audio registers
(AUDC0/AUDC1/AUDF0/AUDF1/AUDV0/AUDV1). These can be edited
in hex.
</td>
</tr><tr>
<td>
<b>DATA</b>
</td><td>
Addresses used as an operand for some opcode. These can be edited
in hex.
</td>
</tr><tr>
<td>
<b>ROW</b>
</td><td>
Addresses not used as any of the above. These are shown up
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,
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
@ -1523,12 +1587,12 @@ the RAM in the DPC scheme is not viewable by the 6507, so its addresses start fr
<br>
<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
CODE, GFX, PGFX, COL, PCOL, BCOL, AUD, 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
several options in this case:</p>
<ol>
<li><b>Manually set the directives</b>: Directives can be set in the debugger
prompt with the code/gfx/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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -678,6 +678,44 @@ string DebuggerParser::saveScriptFile(string file)
return "saved " + node.getShortPath() + " OK";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::executeDirective(Device::AccessType type)
{
if(argCount != 2)
{
outputCommandError("specify start and end of range only", myCommand);
return;
}
else if(args[1] < args[0])
{
commandResult << red("start address must be <= end address");
return;
}
bool result = debugger.cartDebug().addDirective(type, args[0], args[1]);
string typeStr;
switch(type)
{
case Device::CODE: typeStr = "CODE"; break;
case Device::GFX: typeStr = "GFX"; break;
case Device::PGFX: typeStr = "PGFX"; break;
case Device::COL: typeStr = "COL"; break;
case Device::PCOL: typeStr = "PCOL"; break;
case Device::BCOL: typeStr = "BCOL"; break;
case Device::AUD: typeStr = "AUD"; break;
case Device::DATA: typeStr = "DATA"; break;
case Device::ROW: typeStr = "ROW"; break;
default: typeStr = "NONE";
}
commandResult << (result ? "added " : "removed ")
<< typeStr << " directive on range $"
<< hex << args[0] << " $" << hex << args[1];
debugger.rom().invalidate();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// executor methods for commands[] array. All are void, no args.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -689,6 +727,13 @@ void DebuggerParser::executeA()
debugger.cpuDebug().setA(uInt8(args[0]));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "aud"
void DebuggerParser::executeAud()
{
executeDirective(Device::AUD);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "base"
void DebuggerParser::executeBase()
@ -720,6 +765,13 @@ void DebuggerParser::executeBase()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "bcol"
void DebuggerParser::executeBCol()
{
executeDirective(Device::BCOL);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "break"
void DebuggerParser::executeBreak()
@ -912,22 +964,14 @@ void DebuggerParser::executeCls()
// "code"
void DebuggerParser::executeCode()
{
if(argCount != 2)
{
outputCommandError("specify start and end of range only", myCommand);
return;
}
else if(args[1] < args[0])
{
commandResult << red("start address must be <= end address");
return;
}
executeDirective(Device::CODE);
}
bool result = debugger.cartDebug().addDirective(
Device::CODE, args[0], args[1]);
commandResult << (result ? "added" : "removed") << " CODE directive on range $"
<< hex << args[0] << " $" << hex << args[1];
debugger.rom().invalidate();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "col"
void DebuggerParser::executeCol()
{
executeDirective(Device::COL);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -953,22 +997,7 @@ void DebuggerParser::executeD()
// "data"
void DebuggerParser::executeData()
{
if(argCount != 2)
{
outputCommandError("specify start and end of range only", myCommand);
return;
}
else if(args[1] < args[0])
{
commandResult << red("start address must be <= end address");
return;
}
bool result = debugger.cartDebug().addDirective(
Device::DATA, args[0], args[1]);
commandResult << (result ? "added" : "removed") << " DATA directive on range $"
<< hex << args[0] << " $" << hex << args[1];
debugger.rom().invalidate();
executeDirective(Device::DATA);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1270,22 +1299,7 @@ void DebuggerParser::executeFunction()
// "gfx"
void DebuggerParser::executeGfx()
{
if(argCount != 2)
{
outputCommandError("specify start and end of range only", myCommand);
return;
}
else if(args[1] < args[0])
{
commandResult << red("start address must be <= end address");
return;
}
bool result = debugger.cartDebug().addDirective(
Device::GFX, args[0], args[1]);
commandResult << (result ? "added" : "removed") << " GFX directive on range $"
<< hex << args[0] << " $" << hex << args[1];
debugger.rom().invalidate();
executeDirective(Device::GFX);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1626,26 +1640,18 @@ void DebuggerParser::executePc()
debugger.cpuDebug().setPC(args[0]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "pcol"
void DebuggerParser::executePCol()
{
executeDirective(Device::PCOL);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "pgfx"
void DebuggerParser::executePGfx()
{
if(argCount != 2)
{
outputCommandError("specify start and end of range only", myCommand);
return;
}
else if(args[1] < args[0])
{
commandResult << red("start address must be <= end address");
return;
}
bool result = debugger.cartDebug().addDirective(
Device::PGFX, args[0], args[1]);
commandResult << (result ? "added" : "removed") << " PGFX directive on range $"
<< hex << args[0] << " $" << hex << args[1];
debugger.rom().invalidate();
executeDirective(Device::PGFX);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1722,22 +1728,7 @@ void DebuggerParser::executeRom()
// "row"
void DebuggerParser::executeRow()
{
if(argCount != 2)
{
outputCommandError("specify start and end of range only", myCommand);
return;
}
else if(args[1] < args[0])
{
commandResult << red("start address must be <= end address");
return;
}
bool result = debugger.cartDebug().addDirective(
Device::ROW, args[0], args[1]);
commandResult << (result ? "added" : "removed") << " ROW directive on range $"
<< hex << args[0] << " $" << hex << args[1];
debugger.rom().invalidate();
executeDirective(Device::ROW);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2300,7 +2291,7 @@ void DebuggerParser::executeZ()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// List of all commands available to the parser
std::array<DebuggerParser::Command, 95> DebuggerParser::commands = { {
std::array<DebuggerParser::Command, 99> DebuggerParser::commands = { {
{
"a",
"Set Accumulator to <value>",
@ -2311,6 +2302,16 @@ std::array<DebuggerParser::Command, 95> DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeA)
},
{
"aud",
"Mark 'AUD' range in disassembly",
"Start and end of range required\nExample: aud f000 f010",
true,
false,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE },
std::mem_fn(&DebuggerParser::executeAud)
},
{
"base",
"Set default number base to <base>",
@ -2321,6 +2322,17 @@ std::array<DebuggerParser::Command, 95> DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeBase)
},
{
"bcol",
"Mark 'BCOL' range in disassembly",
"Start and end of range required\nExample: bcol f000 f010",
true,
false,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE },
std::mem_fn(&DebuggerParser::executeBCol)
},
{
"break",
"Break at <address> and <bank>",
@ -2442,6 +2454,16 @@ std::array<DebuggerParser::Command, 95> DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executeCode)
},
{
"col",
"Mark 'COL' range in disassembly",
"Start and end of range required\nExample: col f000 f010",
true,
false,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE },
std::mem_fn(&DebuggerParser::executeCol)
},
{
"colortest",
"Show value xx as TIA color",
@ -2847,6 +2869,16 @@ std::array<DebuggerParser::Command, 95> DebuggerParser::commands = { {
std::mem_fn(&DebuggerParser::executePc)
},
{
"pcol",
"Mark 'PCOL' range in disassembly",
"Start and end of range required\nExample: col f000 f010",
true,
false,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE },
std::mem_fn(&DebuggerParser::executePCol)
},
{
"pgfx",
"Mark 'PGFX' range in disassembly",

View File

@ -27,6 +27,7 @@ class FilesystemNode;
struct Command;
#include "bspf.hxx"
#include "Device.hxx"
class DebuggerParser
{
@ -97,7 +98,7 @@ class DebuggerParser
std::array<Parameters, 10> parms;
std::function<void (DebuggerParser*)> executor;
};
static std::array<Command, 95> commands;
static std::array<Command, 99> commands;
struct Trap
{
@ -140,9 +141,13 @@ class DebuggerParser
// output the error with the example provided for the command
void outputCommandError(const string& errorMsg, int command);
void executeDirective(Device::AccessType type);
// List of available command methods
void executeA();
void executeAud();
void executeBase();
void executeBCol();
void executeBreak();
void executeBreakif();
void executeBreaklabel();
@ -155,6 +160,7 @@ class DebuggerParser
void executeClearwatches();
void executeCls();
void executeCode();
void executeCol();
void executeColortest();
void executeD();
void executeData();
@ -195,6 +201,7 @@ class DebuggerParser
void executeN();
void executePalette();
void executePc();
void executePCol();
void executePGfx();
void executePrint();
void executeRam();