Slightly reworked the debugger commandline handling. Commands are now

contained in the Debugger class methods, since they need to be accessible
from both the console and the GUI code.

Implemented console commands for dumping RAM (ram) and TIA (tia), and
implemented the console 'quit' command (it returns to emulation mode).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@484 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-06-12 18:18:01 +00:00
parent 47b471bc1a
commit 330ca1bd7c
12 changed files with 322 additions and 184 deletions

View File

@ -13,17 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DCmdQuit.cxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
// $Id: DCmdQuit.cxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#include "bspf.hxx"
#include "Debugger.hxx"
#include "DCmdQuit.hxx"
#include "DebuggerParser.hxx"
DCmdQuit::DCmdQuit(DebuggerParser* p) {
parser = p;
DCmdQuit::DCmdQuit(Debugger* d) {
debugger = d;
}
string DCmdQuit::getName() {
@ -35,7 +33,6 @@ int DCmdQuit::getArgCount() {
}
string DCmdQuit::execute(int c, int *args) {
parser->setDone();
//FIXME parser->setDone();
return "If you quit the debugger, I'll summon Satan all over your hard drive!";
}

View File

@ -13,20 +13,20 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DCmdQuit.hxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
// $Id: DCmdQuit.hxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#ifndef DCMDQUIT_HXX
#define DCMDQUIT_HXX
#include "bspf.hxx"
#include "DebuggerParser.hxx"
class Debugger;
#include "DebuggerCommand.hxx"
class DCmdQuit: public DebuggerCommand
{
public:
DCmdQuit(DebuggerParser* p);
DCmdQuit(Debugger* d);
string getName();
int getArgCount();

View File

@ -1,4 +1,3 @@
//============================================================================
//
// SSSS tt lll lll
@ -14,20 +13,19 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DCmdTrace.cxx,v 1.1 2005-06-11 20:02:25 urchlay Exp $
// $Id: DCmdTrace.cxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#include "bspf.hxx"
#include "DCmdTrace.hxx"
#include "DebuggerParser.hxx"
#include "Debugger.hxx"
#include "Console.hxx"
#include "System.hxx"
#include "M6502.hxx"
DCmdTrace::DCmdTrace(DebuggerParser* p) {
parser = p;
DCmdTrace::DCmdTrace(Debugger* d) {
debugger = d;
}
string DCmdTrace::getName() {
@ -39,7 +37,7 @@ int DCmdTrace::getArgCount() {
}
string DCmdTrace::execute(int c, int *args) {
parser->getOSystem()->console().system().m6502().execute(1);
// parser->getOSystem()->console().system().m6502().execute(1);
debugger->trace();
return "OK";
}

View File

@ -14,20 +14,20 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DCmdTrace.hxx,v 1.1 2005-06-11 20:02:25 urchlay Exp $
// $Id: DCmdTrace.hxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#ifndef DCMDTRACE_HXX
#define DCMDTRACE_HXX
#include "bspf.hxx"
#include "DebuggerParser.hxx"
#include "Debugger.hxx"
#include "DebuggerCommand.hxx"
class DCmdTrace: public DebuggerCommand
{
public:
DCmdTrace(DebuggerParser* p);
DCmdTrace(Debugger* d);
string getName();
int getArgCount();

View File

@ -0,0 +1,184 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// 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.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#include "bspf.hxx"
#include <sstream>
#include "Version.hxx"
#include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "DebuggerDialog.hxx"
#include "DebuggerParser.hxx"
#include "Console.hxx"
#include "System.hxx"
#include "D6502.hxx"
#include "Debugger.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::Debugger(OSystem* osystem)
: DialogContainer(osystem),
myConsole(NULL),
mySystem(NULL),
myParser(NULL),
myDebugger(NULL)
{
// Init parser
myParser = new DebuggerParser(this);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::~Debugger()
{
delete myParser;
delete myDebugger;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::initialize()
{
int x = 0,
y = myConsole->mediaSource().height(),
w = kDebuggerWidth,
h = kDebuggerHeight - y;
delete myBaseDialog;
myBaseDialog = new DebuggerDialog(myOSystem, this, x, y, w, h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::initializeVideo()
{
string title = string("Stella version ") + STELLA_VERSION + ": Debugger mode";
myOSystem->frameBuffer().initialize(title, kDebuggerWidth, kDebuggerHeight, false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setConsole(Console* console)
{
assert(console);
// Keep pointers to these items for efficiency
myConsole = console;
mySystem = &(myConsole->system());
// Create a new 6502 debugger for this console
delete myDebugger;
myDebugger = new D6502(mySystem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::run(const string& command)
{
return myParser->run(command);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::state()
{
string result;
char buf[255];
result += "\nPC=";
result += to_hex_16(myDebugger->pc());
result += " A=";
result += to_hex_8(myDebugger->a());
result += " X=";
result += to_hex_8(myDebugger->x());
result += " Y=";
result += to_hex_8(myDebugger->y());
result += " S=";
result += to_hex_8(myDebugger->sp());
result += " P=";
result += to_hex_8(myDebugger->ps());
result += "\n ";
myDebugger->disassemble(myDebugger->pc(), buf);
result += buf;
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Debugger::readRAM(uInt16 addr)
{
return mySystem->peek(addr + kRamStart);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::writeRAM(uInt16 addr, uInt8 value)
{
mySystem->poke(addr + kRamStart, value);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::dumpRAM(uInt16 start)
{
string result;
char buf[128];
for (uInt8 i = 0x00; i < kRamStart; i += 0x10)
{
sprintf(buf, "%.4x: ", start+i);
result += buf;
for (uInt8 j = 0; j < 0x010; j++)
{
sprintf(buf, "%.2x ", mySystem->peek(start+i+j));
result += buf;
if(j == 0x07) result += "- ";
}
result += "\n";
}
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::dumpTIA()
{
string result;
char buf[128];
sprintf(buf, "%.2x: ", 0);
result += buf;
for (uInt8 j = 0; j < 0x010; j++)
{
sprintf(buf, "%.2x ", mySystem->peek(j));
result += buf;
if(j == 0x07) result += "- ";
}
result += "\n";
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::quit()
{
myOSystem->eventHandler().leaveDebugMode();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::trace()
{
mySystem->m6502().execute(1);
}

View File

@ -13,32 +13,45 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Debugger.hxx,v 1.3 2005-06-09 15:08:23 stephena Exp $
// $Id: Debugger.hxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#ifndef DEBUGGER_HXX
#define DEBUGGER_HXX
class OSystem;
class Console;
class DebuggerParser;
class Console;
class System;
class D6502;
#include "DialogContainer.hxx"
#include "M6502.hxx"
#include "bspf.hxx"
enum {
kDebuggerWidth = 511,
kDebuggerHeight = 383
};
// Constants for RAM area
enum {
kRamStart = 0x80,
kRamSize = 128
};
/**
The base dialog for the ROM launcher in Stella. Also acts as the parent
for all debugging operations in Stella (parser, etc).
The base dialog for all debugging widgets in Stella. Also acts as the parent
for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony
@version $Id: Debugger.hxx,v 1.3 2005-06-09 15:08:23 stephena Exp $
@version $Id: Debugger.hxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
*/
class Debugger : public DialogContainer
{
friend class DebuggerParser;
public:
/**
Create a new menu stack
@ -61,16 +74,57 @@ class Debugger : public DialogContainer
*/
void initializeVideo();
/**
Inform this object of a console change.
*/
void setConsole(Console* console);
/** Convenience methods to convert to hexidecimal values */
static char *to_hex_8(int i)
{
static char out[3];
sprintf(out, "%02x", i);
return out;
}
static char *to_hex_16(int i)
{
static char out[5];
sprintf(out, "%04x", i);
return out;
}
public:
/**
Run the debugger command and return the result.
*/
const string run(const string& command);
void setConsole(Console* console) { myConsole = console; }
/**
Give the contents of the CPU registers and disassembly of
next instruction.
*/
const string state();
private:
/**
Return a formatted string containing the contents of the specified
device.
*/
const string dumpRAM(uInt16 start);
const string dumpTIA();
// Read and write 128-byte RAM area
uInt8 readRAM(uInt16 addr);
void writeRAM(uInt16 addr, uInt8 value);
void quit();
void trace();
protected:
Console* myConsole;
System* mySystem;
DebuggerParser* myParser;
D6502* myDebugger;
};
#endif

View File

@ -13,17 +13,17 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DebuggerCommand.cxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
// $Id: DebuggerCommand.cxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#include "bspf.hxx"
#include "Debugger.hxx"
#include "DebuggerCommand.hxx"
#include "DebuggerParser.hxx"
DebuggerCommand::DebuggerCommand() {
}
DebuggerCommand::DebuggerCommand(DebuggerParser* p) {
parser = p;
DebuggerCommand::DebuggerCommand(Debugger* d) {
debugger = d;
}

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: DebuggerCommand.hxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
// $Id: DebuggerCommand.hxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#ifndef DEBUGGER_COMMAND_HXX
@ -21,13 +21,14 @@
#include "bspf.hxx"
class DebuggerParser;
//class DebuggerParser;
class Debugger;
class DebuggerCommand
{
public:
DebuggerCommand();
DebuggerCommand(DebuggerParser* p);
DebuggerCommand(Debugger* d);
virtual string getName() = 0;
virtual int getArgCount() = 0;
@ -35,7 +36,8 @@ class DebuggerCommand
protected:
int *args;
DebuggerParser *parser;
Debugger *debugger;
// DebuggerParser *parser;
};
#endif

View File

@ -13,30 +13,29 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DebuggerParser.cxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
// $Id: DebuggerParser.cxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#include "bspf.hxx"
#include "Debugger.hxx"
#include "DebuggerParser.hxx"
#include "DebuggerCommand.hxx"
#include "DCmdQuit.hxx"
#include "DCmdTrace.hxx"
#include "D6502.hxx"
DebuggerParser::DebuggerParser(OSystem *os)
// : quitCmd(NULL)
// Constants for argument processing
enum {
kIN_COMMAND,
kIN_SPACE,
kIN_ARG_START,
kIN_ARG_CONT
};
DebuggerParser::DebuggerParser(Debugger* d)
: debugger(d)
{
done = false;
quitCmd = new DCmdQuit(this);
// changeCmd = new DCmdChange(this);
// stepCmd = new DCmdStep(this);
traceCmd = new DCmdTrace(this);
myOSystem = os;
}
DebuggerParser::~DebuggerParser() {
delete quitCmd;
delete traceCmd;
}
string DebuggerParser::currentAddress() {
@ -47,10 +46,6 @@ void DebuggerParser::setDone() {
done = true;
}
OSystem *DebuggerParser::getOSystem() {
return myOSystem;
}
int DebuggerParser::conv_hex_digit(char d) {
if(d >= '0' && d <= '9')
return d - '0';
@ -61,13 +56,8 @@ int DebuggerParser::conv_hex_digit(char d) {
else return 0;
}
#define IN_COMMAND 0
#define IN_SPACE 1
#define IN_ARG_START 2
#define IN_ARG_CONT 3
void DebuggerParser::getArgs(const string& command) {
int state = IN_COMMAND;
int state = kIN_COMMAND;
int deref = 0;
int curArg = 0;
argCount = 0;
@ -78,21 +68,21 @@ void DebuggerParser::getArgs(const string& command) {
while(*c != '\0') {
// cerr << "State " << state << ", *c " << *c << endl;
switch(state) {
case IN_COMMAND:
if(*c == ' ') state = IN_SPACE;
case kIN_COMMAND:
if(*c == ' ') state = kIN_SPACE;
c++;
break;
case IN_SPACE:
case kIN_SPACE:
if(*c == ' ')
c++;
else
state = IN_ARG_START;
state = kIN_ARG_START;
break;
case IN_ARG_START:
case kIN_ARG_START:
curArg = 0;
state = IN_ARG_CONT;
state = kIN_ARG_CONT;
if(*c == '*') {
deref = 1;
c++;
@ -100,14 +90,14 @@ void DebuggerParser::getArgs(const string& command) {
deref = 0;
} // FALL THROUGH!
case IN_ARG_CONT:
case kIN_ARG_CONT:
if(isxdigit(*c)) {
int dig = conv_hex_digit(*c);
curArg = (curArg << 4) + dig;
*c++;
} else {
args[argCount++] = curArg;
state = IN_SPACE;
state = kIN_SPACE;
}
break;
}
@ -119,7 +109,7 @@ void DebuggerParser::getArgs(const string& command) {
}
// pick up last arg, if any:
if(state == IN_ARG_CONT || state == IN_ARG_START)
if(state == kIN_ARG_CONT || state == kIN_ARG_START)
args[argCount++] = curArg;
// for(int i=0; i<argCount; i++)
@ -128,49 +118,26 @@ void DebuggerParser::getArgs(const string& command) {
cerr << endl;
}
char *to_hex_8(int i) {
static char out[3];
sprintf(out, "%02x", i);
return out;
}
char *to_hex_16(int i) {
static char out[5];
sprintf(out, "%04x", i);
return out;
}
string DebuggerParser::run(const string& command) {
char disbuf[255];
string result;
// yuck!
D6502 *dcpu = new D6502(&(myOSystem->console().system()));
getArgs(command);
if(command == "quit") {
// TODO: use lookup table to determine which DebuggerCommand to run
result = quitCmd->execute(argCount, args);
// TODO: use lookup table to determine which command to run
debugger->quit();
return "";
} else if(command == "trace") {
result = traceCmd->execute(argCount, args);
debugger->trace();
result = "OK";
} else if(command == "ram") {
result = debugger->dumpRAM(kRamStart);
} else if(command == "tia") {
result = debugger->dumpTIA();
} else {
result = "unimplemented command";
}
result += "\nPC=";
result += to_hex_16(dcpu->pc());
result += " A=";
result += to_hex_8(dcpu->a());
result += " X=";
result += to_hex_8(dcpu->x());
result += " Y=";
result += to_hex_8(dcpu->y());
result += " S=";
result += to_hex_8(dcpu->sp());
result += " P=";
result += to_hex_8(dcpu->ps());
result += "\n ";
dcpu->disassemble(dcpu->pc(), disbuf);
result += disbuf;
delete dcpu;
result += debugger->state();
return result;
}

View File

@ -13,36 +13,39 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DebuggerParser.hxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
// $Id: DebuggerParser.hxx,v 1.1 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#ifndef DEBUGGER_PARSER_HXX
#define DEBUGGER_PARSER_HXX
class Debugger;
#include "bspf.hxx"
#include "DebuggerCommand.hxx"
#include "OSystem.hxx"
class DebuggerParser
{
public:
DebuggerParser(OSystem *os);
DebuggerParser(Debugger* debugger);
~DebuggerParser();
string currentAddress();
void setDone();
string run(const string& command);
void getArgs(const string& command);
OSystem *getOSystem();
private:
int DebuggerParser::conv_hex_digit(char d);
Debugger* debugger;
DebuggerCommand *changeCmd;
DebuggerCommand *traceCmd;
DebuggerCommand *stepCmd;
DebuggerCommand *quitCmd;
bool done;
OSystem *myOSystem;
int args[10]; // FIXME: should be dynamic
int argCount;
};

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: EventHandler.hxx,v 1.38 2005-06-11 01:52:49 markgrebe Exp $
// $Id: EventHandler.hxx,v 1.39 2005-06-12 18:18:00 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -74,7 +74,7 @@ struct Stella_Joystick {
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.38 2005-06-11 01:52:49 markgrebe Exp $
@version $Id: EventHandler.hxx,v 1.39 2005-06-12 18:18:00 stephena Exp $
*/
class EventHandler
{
@ -203,6 +203,11 @@ class EventHandler
return (mod & KMOD_SHIFT);
}
void enterMenuMode();
void leaveMenuMode();
void enterDebugMode();
void leaveDebugMode();
// Holds static strings for the remap menu
static ActionList ourActionList[61];
@ -277,11 +282,6 @@ class EventHandler
void loadState();
void takeSnapshot();
void enterMenuMode();
void leaveMenuMode();
void enterDebugMode();
void leaveDebugMode();
private:
// Global OSystem object
OSystem* myOSystem;

View File

@ -1,67 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// 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.4 2005-06-11 20:02:25 urchlay Exp $
//============================================================================
#include "bspf.hxx"
#include "Version.hxx"
#include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "DebuggerDialog.hxx"
#include "DebuggerParser.hxx"
#include "Debugger.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::Debugger(OSystem* osystem)
: DialogContainer(osystem),
myConsole(NULL),
myParser(NULL)
{
// Init parser
myParser = new DebuggerParser(myOSystem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::~Debugger()
{
delete myParser;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::initialize()
{
int x = 0,
y = myConsole->mediaSource().height(),
w = kDebuggerWidth,
h = kDebuggerHeight - y;
delete myBaseDialog;
myBaseDialog = new DebuggerDialog(myOSystem, this, x, y, w, h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::initializeVideo()
{
string title = string("Stella version ") + STELLA_VERSION + ": Debugger mode";
myOSystem->frameBuffer().initialize(title, kDebuggerWidth, kDebuggerHeight, false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::run(const string& command)
{
return myParser->run(command);
}