Finally, the console does something!

The "trace" command is now implemented (though it doesn't skip over
JSR's like it's supposed to yet, so it does what "step" will do).

After each command, we now emit the values of all the CPU regs and a
disassembly of the next instruction, like gdb and good old DEBUG.COM do.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@483 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-06-11 20:02:25 +00:00
parent 3bc9a165bc
commit 47b471bc1a
10 changed files with 241 additions and 18 deletions

View File

@ -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: makefile,v 1.90 2005-06-10 17:46:05 stephena Exp $ ## $Id: makefile,v 1.91 2005-06-11 20:02:24 urchlay Exp $
##============================================================================ ##============================================================================
##============================================================================ ##============================================================================
@ -170,7 +170,7 @@ CORE_OBJS = Booster.o Cart.o Cart2K.o Cart3F.o Cart4K.o CartAR.o CartDPC.o \
Props.o PropsSet.o Random.o SoundNull.o Switches.o Settings.o TIA.o \ Props.o PropsSet.o Random.o SoundNull.o Switches.o Settings.o TIA.o \
Serializer.o Deserializer.o EventHandler.o FrameBuffer.o \ Serializer.o Deserializer.o EventHandler.o FrameBuffer.o \
OSystem.o FSNode.o unzip.o \ OSystem.o FSNode.o unzip.o \
DebuggerParser.o DebuggerCommand.o DCmdQuit.o \ DebuggerParser.o DebuggerCommand.o DCmdQuit.o DCmdTrace.o \
$(M6502_OBJS) $(GUI_OBJS) $(M6502_OBJS) $(GUI_OBJS)
stella: $(CORE_OBJS) $(OBJS) stella: $(CORE_OBJS) $(OBJS)
@ -465,3 +465,6 @@ DebuggerCommand.o: $(COMMON)/DebuggerCommand.cxx $(COMMON)/DebuggerCommand.hxx
DCmdQuit.o: $(COMMON)/DCmdQuit.cxx $(COMMON)/DCmdQuit.hxx DCmdQuit.o: $(COMMON)/DCmdQuit.cxx $(COMMON)/DCmdQuit.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(COMMON)/DCmdQuit.cxx $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(COMMON)/DCmdQuit.cxx
DCmdTrace.o: $(COMMON)/DCmdTrace.cxx $(COMMON)/DCmdTrace.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(COMMON)/DCmdTrace.cxx

View File

@ -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: DCmdQuit.cxx,v 1.2 2005-06-09 15:08:21 stephena Exp $ // $Id: DCmdQuit.cxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -34,7 +34,7 @@ int DCmdQuit::getArgCount() {
return 0; return 0;
} }
string DCmdQuit::execute() { string DCmdQuit::execute(int c, int *args) {
parser->setDone(); parser->setDone();
return "If you quit the debugger, I'll summon Satan all over your hard drive!"; return "If you quit the debugger, I'll summon Satan all over your hard drive!";
} }

View File

@ -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: DCmdQuit.hxx,v 1.2 2005-06-09 15:08:21 stephena Exp $ // $Id: DCmdQuit.hxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#ifndef DCMDQUIT_HXX #ifndef DCMDQUIT_HXX
@ -30,7 +30,7 @@ class DCmdQuit: public DebuggerCommand
string getName(); string getName();
int getArgCount(); int getArgCount();
string execute(); string execute(int c, int *args);
}; };
#endif #endif

View File

@ -0,0 +1,45 @@
//============================================================================
//
// 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 and the Stella team
//
// 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 $
//============================================================================
#include "bspf.hxx"
#include "DCmdTrace.hxx"
#include "DebuggerParser.hxx"
#include "Console.hxx"
#include "System.hxx"
#include "M6502.hxx"
DCmdTrace::DCmdTrace(DebuggerParser* p) {
parser = p;
}
string DCmdTrace::getName() {
return "Trace";
}
int DCmdTrace::getArgCount() {
return 0;
}
string DCmdTrace::execute(int c, int *args) {
parser->getOSystem()->console().system().m6502().execute(1);
return "OK";
}

View File

@ -0,0 +1,37 @@
//============================================================================
//
// 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 and the Stella team
//
// 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 $
//============================================================================
#ifndef DCMDTRACE_HXX
#define DCMDTRACE_HXX
#include "bspf.hxx"
#include "DebuggerParser.hxx"
#include "DebuggerCommand.hxx"
class DCmdTrace: public DebuggerCommand
{
public:
DCmdTrace(DebuggerParser* p);
string getName();
int getArgCount();
string execute(int c, int *args);
};
#endif

View File

@ -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: DebuggerCommand.cxx,v 1.2 2005-06-09 15:08:22 stephena Exp $ // $Id: DebuggerCommand.cxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -26,3 +26,4 @@ DebuggerCommand::DebuggerCommand() {
DebuggerCommand::DebuggerCommand(DebuggerParser* p) { DebuggerCommand::DebuggerCommand(DebuggerParser* p) {
parser = p; parser = p;
} }

View File

@ -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: DebuggerCommand.hxx,v 1.2 2005-06-09 15:08:22 stephena Exp $ // $Id: DebuggerCommand.hxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_COMMAND_HXX #ifndef DEBUGGER_COMMAND_HXX
@ -31,9 +31,10 @@ class DebuggerCommand
virtual string getName() = 0; virtual string getName() = 0;
virtual int getArgCount() = 0; virtual int getArgCount() = 0;
virtual string execute() = 0; virtual string execute(int c, int *a) = 0;
protected: protected:
int *args;
DebuggerParser *parser; DebuggerParser *parser;
}; };

View File

@ -13,23 +13,30 @@
// 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: DebuggerParser.cxx,v 1.2 2005-06-09 15:08:22 stephena Exp $ // $Id: DebuggerParser.cxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
#include "DebuggerCommand.hxx" #include "DebuggerCommand.hxx"
#include "DCmdQuit.hxx" #include "DCmdQuit.hxx"
#include "DCmdTrace.hxx"
#include "D6502.hxx"
DebuggerParser::DebuggerParser() DebuggerParser::DebuggerParser(OSystem *os)
: quitCmd(NULL) // : quitCmd(NULL)
{ {
done = false; done = false;
quitCmd = new DCmdQuit(this); quitCmd = new DCmdQuit(this);
// changeCmd = new DCmdChange(this);
// stepCmd = new DCmdStep(this);
traceCmd = new DCmdTrace(this);
myOSystem = os;
} }
DebuggerParser::~DebuggerParser() { DebuggerParser::~DebuggerParser() {
delete quitCmd; delete quitCmd;
delete traceCmd;
} }
string DebuggerParser::currentAddress() { string DebuggerParser::currentAddress() {
@ -40,11 +47,130 @@ void DebuggerParser::setDone() {
done = true; done = true;
} }
OSystem *DebuggerParser::getOSystem() {
return myOSystem;
}
int DebuggerParser::conv_hex_digit(char d) {
if(d >= '0' && d <= '9')
return d - '0';
else if(d >= 'a' && d <= 'f')
return d - 'a' + 10;
else if(d >= 'A' && d <= 'F')
return d - 'A' + 10;
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 deref = 0;
int curArg = 0;
argCount = 0;
const char *c = command.c_str();
cerr << "Parsing \"" << command << "\"" << endl;
while(*c != '\0') {
// cerr << "State " << state << ", *c " << *c << endl;
switch(state) {
case IN_COMMAND:
if(*c == ' ') state = IN_SPACE;
c++;
break;
case IN_SPACE:
if(*c == ' ')
c++;
else
state = IN_ARG_START;
break;
case IN_ARG_START:
curArg = 0;
state = IN_ARG_CONT;
if(*c == '*') {
deref = 1;
c++;
} else {
deref = 0;
} // FALL THROUGH!
case IN_ARG_CONT:
if(isxdigit(*c)) {
int dig = conv_hex_digit(*c);
curArg = (curArg << 4) + dig;
*c++;
} else {
args[argCount++] = curArg;
state = IN_SPACE;
}
break;
}
if(argCount == 10) {
cerr << "reached max 10 args" << endl;
return;
}
}
// pick up last arg, if any:
if(state == IN_ARG_CONT || state == IN_ARG_START)
args[argCount++] = curArg;
// for(int i=0; i<argCount; i++)
// cerr << "args[" << i << "] == " << args[i] << endl;
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) { string DebuggerParser::run(const string& command) {
char disbuf[255];
string result;
// yuck!
D6502 *dcpu = new D6502(&(myOSystem->console().system()));
getArgs(command);
if(command == "quit") { if(command == "quit") {
// TODO: use lookup table to determine which DebuggerCommand to run // TODO: use lookup table to determine which DebuggerCommand to run
return quitCmd->execute(); result = quitCmd->execute(argCount, args);
} else if(command == "trace") {
result = traceCmd->execute(argCount, args);
} else { } else {
return "unimplemented command"; 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;
return result;
} }

View File

@ -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: DebuggerParser.hxx,v 1.2 2005-06-09 15:08:22 stephena Exp $ // $Id: DebuggerParser.hxx,v 1.3 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_PARSER_HXX #ifndef DEBUGGER_PARSER_HXX
@ -21,20 +21,30 @@
#include "bspf.hxx" #include "bspf.hxx"
#include "DebuggerCommand.hxx" #include "DebuggerCommand.hxx"
#include "OSystem.hxx"
class DebuggerParser class DebuggerParser
{ {
public: public:
DebuggerParser(); DebuggerParser(OSystem *os);
~DebuggerParser(); ~DebuggerParser();
string currentAddress(); string currentAddress();
void setDone(); void setDone();
string run(const string& command); string run(const string& command);
void getArgs(const string& command);
OSystem *getOSystem();
private: private:
int DebuggerParser::conv_hex_digit(char d);
DebuggerCommand *changeCmd;
DebuggerCommand *traceCmd;
DebuggerCommand *stepCmd;
DebuggerCommand *quitCmd; DebuggerCommand *quitCmd;
bool done; bool done;
OSystem *myOSystem;
int args[10]; // FIXME: should be dynamic
int argCount;
}; };
#endif #endif

View File

@ -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.3 2005-06-09 15:08:23 stephena Exp $ // $Id: Debugger.cxx,v 1.4 2005-06-11 20:02:25 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -32,7 +32,7 @@ Debugger::Debugger(OSystem* osystem)
myParser(NULL) myParser(NULL)
{ {
// Init parser // Init parser
myParser = new DebuggerParser(); myParser = new DebuggerParser(myOSystem);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -