diff --git a/stella/src/debugger/Debugger.cxx b/stella/src/debugger/Debugger.cxx index 8fe321d63..2cc8d491f 100644 --- a/stella/src/debugger/Debugger.cxx +++ b/stella/src/debugger/Debugger.cxx @@ -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.16 2005-06-18 15:45:05 urchlay Exp $ +// $Id: Debugger.cxx,v 1.17 2005-06-18 17:28:18 urchlay Exp $ //============================================================================ #include "bspf.hxx" @@ -397,6 +397,31 @@ int Debugger::getPC() { return myDebugger->pc(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Debugger::getA() { + return myDebugger->a(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Debugger::getX() { + return myDebugger->x(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Debugger::getY() { + return myDebugger->y(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Debugger::getS() { + return myDebugger->sp(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Debugger::getP() { + return myDebugger->ps(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string Debugger::disassemble(int start, int lines) { char buf[255], bbuf[255]; @@ -438,3 +463,8 @@ void Debugger::clearAllBreakPoints() { breakPoints = new PackedBitArray(0x10000); mySystem->m6502().setBreakPoints(NULL); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int Debugger::peek(int addr) { + return mySystem->peek(addr); +} diff --git a/stella/src/debugger/Debugger.hxx b/stella/src/debugger/Debugger.hxx index 7b1d8e2e0..3b240058d 100644 --- a/stella/src/debugger/Debugger.hxx +++ b/stella/src/debugger/Debugger.hxx @@ -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.hxx,v 1.14 2005-06-18 15:45:05 urchlay Exp $ +// $Id: Debugger.hxx,v 1.15 2005-06-18 17:28:18 urchlay Exp $ //============================================================================ #ifndef DEBUGGER_HXX @@ -49,7 +49,7 @@ enum { for all debugging operations in Stella (parser, 6502 debugger, etc). @author Stephen Anthony - @version $Id: Debugger.hxx,v 1.14 2005-06-18 15:45:05 urchlay Exp $ + @version $Id: Debugger.hxx,v 1.15 2005-06-18 17:28:18 urchlay Exp $ */ class Debugger : public DialogContainer { @@ -105,6 +105,27 @@ class Debugger : public DialogContainer { return (int) strtoimax(h, NULL, 16); } + static char *to_bin(int dec, int places, char *buf) { + int bit = 1; + buf[places] = '\0'; + while(--places >= 0) { + if(dec & bit) + buf[places] = '1'; + else + buf[places] = '0'; + + bit <<= 1; + } + return buf; + } + static char *to_bin_8(int dec) { + static char buf[9]; + return to_bin(dec, 8, buf); + } + static char *to_bin_16(int dec) { + static char buf[17]; + return to_bin(dec, 16, buf); + } void toggleBreakPoint(int bp); bool breakPoint(int bp); @@ -146,6 +167,12 @@ class Debugger : public DialogContainer void setS(int sp); void setPC(int pc); int getPC(); + int getA(); + int getX(); + int getY(); + int getP(); + int getS(); + int peek(int addr); void toggleC(); void toggleZ(); void toggleN(); diff --git a/stella/src/debugger/DebuggerParser.cxx b/stella/src/debugger/DebuggerParser.cxx index f25ee7e88..872e8b0e2 100644 --- a/stella/src/debugger/DebuggerParser.cxx +++ b/stella/src/debugger/DebuggerParser.cxx @@ -13,12 +13,13 @@ // 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.12 2005-06-18 15:45:05 urchlay Exp $ +// $Id: DebuggerParser.cxx,v 1.13 2005-06-18 17:28:18 urchlay Exp $ //============================================================================ #include "bspf.hxx" #include "Debugger.hxx" #include "DebuggerParser.hxx" +#include "D6502.hxx" #include "EquateList.hxx" // Constants for argument processing @@ -57,31 +58,45 @@ int DebuggerParser::conv_hex_digit(char d) { else return -1; } -// Given a string argument that's either a label or a -// hex value, either dereference the label or convert +// Given a string argument that's either a label, +// hex value, or a register, either dereference the label or convert // the hex to an int. Returns -1 on error. -int DebuggerParser::decipher_arg(string &arg) { +int DebuggerParser::decipher_arg(string &arg, bool deref) { const char *a = arg.c_str(); - int address = debugger->equateList->getAddress(a); - // cerr << "decipher_arg: equateList->getAddress(" << a << ") == " << address << endl; - if(address >= 0) - return address; + int address; - address = 0; - while(*a != '\0') { - int hex = conv_hex_digit(*a++); - if(hex < 0) - return -1; + // Special cases (registers): + if(arg == "a") address = debugger->getA(); + else if(arg == "x") address = debugger->getX(); + else if(arg == "y") address = debugger->getY(); + else if(arg == "p") address = debugger->getP(); + else if(arg == "s") address = debugger->getS(); + else if(arg == "pc") address = debugger->getPC(); + else { // normal addresses: check for label first + address = debugger->equateList->getAddress(a); - address = (address << 4) + hex; + // if not label, must be hex. + if(address < 0) { + address = 0; + while(*a != '\0') { + int hex = conv_hex_digit(*a++); + if(hex < 0) + return -1; + + address = (address << 4) + hex; + } + } } + // dereference if we're supposed to: + if(deref) address = debugger->peek(address); + return address; } bool DebuggerParser::getArgs(const string& command) { int state = kIN_COMMAND; - int deref = 0; + bool deref = false; string curArg = ""; argCount = 0; verb = ""; @@ -112,30 +127,21 @@ bool DebuggerParser::getArgs(const string& command) { state = kIN_ARG_CONT; // FIXME: actually use this. if(*c == '*') { - deref = 1; + deref = true; c++; } else { - deref = 0; + deref = false; } // FALL THROUGH! case kIN_ARG_CONT: - /*if(isxdigit(*c)) { - int dig = conv_hex_digit(*c); - curArg = (curArg << 4) + dig; - *c++; - } else { - args[argCount++] = curArg; - state = kIN_SPACE; - } - break;*/ if(isalpha(*c) || isdigit(*c) || *c == '_') { curArg += *c++; // cerr << "curArg: " << curArg << endl; } else { - args[argCount] = decipher_arg(curArg); - if(args[argCount] < 0) + int a = decipher_arg(curArg, deref); + if(a < 0) return false; - argCount++; + args[argCount++] = a; curArg = ""; state = kIN_SPACE; } @@ -150,7 +156,7 @@ bool DebuggerParser::getArgs(const string& command) { // pick up last arg, if any: if(state == kIN_ARG_CONT || state == kIN_ARG_START) - if( (args[argCount++] = decipher_arg(curArg)) < 0) + if( (args[argCount++] = decipher_arg(curArg, deref)) < 0) return false; // for(int i=0; idisassemble(start, lines); } +string DebuggerParser::eval() { + char buf[10]; + string ret; + for(int i=0; iequates()->getLabel(args[i]); + if(label != NULL) { + ret += label; + ret += ": "; + } + if(args[i] < 0x100) { + ret += Debugger::to_hex_8(args[i]); + ret += " "; + ret += Debugger::to_bin_8(args[i]); + } else { + ret += Debugger::to_hex_16(args[i]); + ret += " "; + ret += Debugger::to_bin_16(args[i]); + } + sprintf(buf, " %d", args[i]); + ret += buf; + if(i != argCount - 1) ret += "\n"; + } + return ret; +} + string DebuggerParser::run(const string& command) { string result; @@ -319,15 +350,23 @@ string DebuggerParser::run(const string& command) { } else if(subStringMatch(verb, "disasm")) { return disasm(); } else if(subStringMatch(verb, "frame")) { + /* + // FIXME: make multiple frames work! int count = 0; if(argCount != 0) count = args[0]; - // FIXME: make multiple frames work! for(int i=0; inextFrame(); + */ + debugger->nextFrame(); return "OK"; } else if(subStringMatch(verb, "clearbreaks")) { debugger->clearAllBreakPoints(); return "cleared all breakpoints"; + } else if(subStringMatch(verb, "eval")) { + if(argCount < 1) + return "one or more arguments required"; + else + return eval(); } else if(subStringMatch(verb, "quit") || subStringMatch(verb, "run")) { debugger->quit(); return ""; @@ -336,6 +375,8 @@ string DebuggerParser::run(const string& command) { // easy to sort - bkw return "Commands are case-insensitive and may be abbreviated.\n" + "Arguments are either labels or hex constants, and may be\n" + "prefixed with a * to dereference.\n" "a xx - Set Accumulator to xx\n" "break - Set/clear breakpoint at current PC\n" "break xx - Set/clear breakpoint at address xx\n" @@ -344,19 +385,20 @@ string DebuggerParser::run(const string& command) { "d - Toggle Decimal Flag\n" "disasm - Disassemble (from current PC)\n" "disasm xx - Disassemble (from address xx)\n" + "eval xx - Evaluate expression xx\n" "frame - Advance to next TIA frame, then break\n" "listbreaks - List all breakpoints\n" "loadsym f - Load DASM symbols from file f\n" "n - Toggle Negative Flag\n" "pc xx - Set Program Counter to xx\n" "ram - Show RIOT RAM contents\n" - "ram xx yy - Set RAM location xx to value yy (multiple values may be given)\n" + "ram xx yy - Set RAM location xx to value yy (multiple values allowed)\n" "reset - Jump to 6502 init vector (does not reset TIA/RIOT)\n" "run - Exit debugger (back to emulator)\n" "s xx - Set Stack Pointer to xx\n" "step - Single-step\n" "tia - Show TIA register contents\n" - "trace - Single-step treating subroutine calls as one instruction\n" + "trace - Single-step treating subroutine calls as 1 instruction\n" "v - Toggle Overflow Flag\n" "x xx - Set X register to xx\n" "y xx - Set Y register to xx\n" diff --git a/stella/src/debugger/DebuggerParser.hxx b/stella/src/debugger/DebuggerParser.hxx index 11d836674..a489545d3 100644 --- a/stella/src/debugger/DebuggerParser.hxx +++ b/stella/src/debugger/DebuggerParser.hxx @@ -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: DebuggerParser.hxx,v 1.6 2005-06-17 21:59:53 urchlay Exp $ +// $Id: DebuggerParser.hxx,v 1.7 2005-06-18 17:28:18 urchlay Exp $ //============================================================================ #ifndef DEBUGGER_PARSER_HXX @@ -38,12 +38,12 @@ class DebuggerParser private: int DebuggerParser::conv_hex_digit(char d); bool DebuggerParser::subStringMatch(const string& needle, const string& haystack); - int decipher_arg(string &arg); + int decipher_arg(string &arg, bool deref); string disasm(); string listBreaks(); + string eval(); Debugger* debugger; - EquateList *equateList; bool done; diff --git a/stella/src/debugger/EquateList.cxx b/stella/src/debugger/EquateList.cxx index b16ef5ae9..7e69c2d62 100644 --- a/stella/src/debugger/EquateList.cxx +++ b/stella/src/debugger/EquateList.cxx @@ -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: EquateList.cxx,v 1.7 2005-06-16 02:16:26 urchlay Exp $ +// $Id: EquateList.cxx,v 1.8 2005-06-18 17:28:18 urchlay Exp $ //============================================================================ #include @@ -120,7 +120,7 @@ int EquateList::calcSize() { char *EquateList::getLabel(int addr) { // cerr << "getLabel(" << addr << ")" << endl; for(int i=0; ourVcsEquates[i].label != NULL; i++) { - // cerr << "Checking ourVcsEquates[" << i << "] (" << ourVcsEquates[i].label << endl; + // cerr << "Checking ourVcsEquates[" << i << "] (" << ourVcsEquates[i].label << ")" << endl; if(ourVcsEquates[i].address == addr) { // cerr << "Found label " << ourVcsEquates[i].label << endl; return ourVcsEquates[i].label;