From b78161192595cda002e649a1352276bf947524ac Mon Sep 17 00:00:00 2001 From: stephena Date: Sat, 10 Apr 2010 00:52:47 +0000 Subject: [PATCH] Some updates to the PromptWidget and DebuggerParser. The descriptions for the debugger commands are more streamlined and better explained, and are neater when output. Added 'cls' debugger command, which actually isn't for the debugger at all, but for the prompt. This erases all showing text and history. Removed 'bank' debugger command, since it was already removed from the RomWidget UI. Removed 'listwatches' debugger command, since it wasn't implemented anyway. Besides, any watches are printed on every command access, so it was pointless to have another function to do it. Removed 'poke' debugger command; 'ram' and 'rom' do the same thing. Fixed bugs in 'function' debugger command; it now correctly adds functions without crashing. Related to this, added 'listfunctions' and 'delfunction' debugger commands for user-defined commands. Fixed bug in completions for functions; it was including user-defined functions twice. Some general code cleanups in DebuggerParser (use ostringstream instead of constantly creating new strings) and Expression classes (make some methods const, for safety). git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1998 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- Changes.txt | 10 + docs/debugger.html | 84 +++-- src/debugger/Debugger.cxx | 39 +- src/debugger/Debugger.hxx | 10 +- src/debugger/DebuggerExpressions.hxx | 108 ++++-- src/debugger/DebuggerParser.cxx | 524 +++++++++++++-------------- src/debugger/DebuggerParser.hxx | 11 +- src/debugger/Expression.hxx | 2 +- src/debugger/gui/PromptWidget.cxx | 35 +- src/debugger/gui/PromptWidget.hxx | 3 + 10 files changed, 428 insertions(+), 398 deletions(-) diff --git a/Changes.txt b/Changes.txt index b0ab9dae8..837a35138 100644 --- a/Changes.txt +++ b/Changes.txt @@ -69,6 +69,16 @@ given program counter. This is also available in the ROM disassembly UI. + * Added 'listfunctions' and 'delfunction' debugger commands to + access/remove user-defined functions. Related to this, fixed a bug + in 'function' command that could cause a program crash. + + * Added 'cls' debugger command, used to erase the text and history + from the debugger prompt. + + * Removed the 'listwatches' and 'poke' debugger commands, as they + were redundant. + * Removed the 'loadlst' debugger command and the ability to use a DASM .lst file. With the recent disassembler improvements, this support is no longer feasible. diff --git a/docs/debugger.html b/docs/debugger.html index b1356653a..bf48c3001 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -571,63 +571,61 @@ can also get rid of all traps at once with the "cleartraps" command.

             a - Set Accumulator to value xx
-         bank - Show # of banks (with no args), Switch to bank (with 1 arg)
          base - Set default base (hex, dec, or bin)
-        break - Set/clear breakpoint at address (default: current pc)
-      breakif - Set breakpoint on condition
-            c - Carry Flag: set (to 0 or 1), or toggle (no arg)
-        cheat - Use a cheat code (see Stella manual for cheat types)
+        break - Set/clear breakpoint at address xx (default=PC)
+      breakif - Set breakpoint on condition xx
+            c - Carry Flag: set (0 or 1), or toggle (no arg)
+        cheat - Use a cheat code (see manual for cheat types)
   clearbreaks - Clear all breakpoints
    cleartraps - Clear all traps
  clearwatches - Clear all watches
-    colortest - Color Test
-            d - Decimal Flag: set (to 0 or 1), or toggle (no arg)
-       define - Define label
-   delbreakif - Delete conditional break created with breakif
-     delwatch - Delete watch
-       disasm - Disassemble from address (default=pc)
-         dump - Dump 128 bytes of memory at address
-         exec - Execute script file
+          cls - Clear prompt area of text and erase history
+    colortest - Show value xx as TIA color
+            d - Decimal Flag: set (0 or 1), or toggle (no arg)
+       define - Define label xx for address yy
+   delbreakif - Delete conditional breakif xx
+  delfunction - Delete function with label xx
+     delwatch - Delete watch xx
+       disasm - Disassemble address xx [yy lines] (default=PC)
+         dump - Dump 128 bytes of memory at address xx
+         exec - Execute script file xx
         frame - Advance emulation by xx frames (default=1)
-     function - Define expression as a function for later use
+     function - Define function name xx for expression yy
          help - This cruft
-+        list - List source (if loaded with loadlist)
    listbreaks - List breakpoints
+listfunctions - List user-defined functions
     listtraps - List traps
-  listwatches - List watches
-+    loadlist - Load DASM listing file
-    loadstate - Load emulator state (0-9)
-      loadsym - Load symbol file
-            n - Negative Flag: set (to 0 or 1), or toggle (no arg)
-           pc - Set Program Counter to address
-         poke - Set address to value. Can give multiple values (for address+1, etc)
-        print - Evaluate and print expression in hex/dec/binary
-          ram - Show RAM contents (no args), or set address xx to value yy
-        reset - Reset 6507 to init vector (does not reset TIA, RIOT)
-       rewind - Rewind state to last step/trace/scanline/frame advance
+    loadstate - Load emulator state xx (0-9)
+      loadsym - Load symbol file named xx
+            n - Negative Flag: set (0 or 1), or toggle (no arg)
+           pc - Set Program Counter to address xx
+        print - Evaluate/print expression xx in hex/dec/binary
+          ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
+        reset - Reset 6507 to init vector (excluding TIA/RIOT)
+       rewind - Rewind state to last step/trace/scanline/frame
          riot - Show RIOT timer/input status
-          rom - Change ROM contents
+          rom - Set ROM address xx to yy1 [yy2 ...]
           run - Exit debugger, return to emulator
-+       runto - Run until first occurrence of string in disassembly
+        runto - Run until string xx in disassembly
+      runtopc - Run until PC is set to value xx
             s - Set Stack Pointer to value xx
-         save - Save breaks, watches, traps as a .stella script file
-      saverom - Save (possibly patched) ROM to file
-      saveses - Save console session to file
-    savestate - Save emulator state (valid args 0-9)
-      savesym - Save symbols to file
+         save - Save breaks, watches, traps to file xx
+      saverom - Save (possibly patched) ROM to file xx
+      saveses - Save console session to file xx
+    savestate - Save emulator state xx (valid args 0-9)
      scanline - Advance emulation by xx scanlines (default=1)
-         step - Single step CPU (optionally, with count)
-+         tia - Show TIA state (NOT FINISHED YET)
-        trace - Single step CPU (optionally, with count), subroutines count as one instruction
-         trap - Trap read and write accesses to address
-     trapread - Trap read accesses to address
-    trapwrite - Trap write accesses to address
-        undef - Undefine label (if defined)
-            v - Overflow Flag: set (to 0 or 1), or toggle (no arg)
-        watch - Print contents of address before every prompt
+         step - Single step CPU [with count xx]
+          tia - Show TIA state (NOT FINISHED YET)
+        trace - Single step CPU over subroutines [with count xx]
+         trap - Trap read and write accesses to address xx
+     trapread - Trap read accesses to address xx
+    trapwrite - Trap write accesses to address xx
+        undef - Undefine label xx (if defined)
+            v - Overflow Flag: set (0 or 1), or toggle (no arg)
+        watch - Print contents of address xx before every prompt
             x - Set X Register to value xx
             y - Set Y Register to value xx
-            z - Zero Flag: set (to 0 or 1), or toggle (no arg)
+            z - Zero Flag: set (0 or 1), or toggle (no arg)
 
diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index ad46c0848..3b4bc1a1a 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -670,35 +670,38 @@ GUI::Rect Debugger::getTabBounds() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Debugger::addFunction(const string& name, const string& definition, +bool Debugger::addFunction(const string& name, const string& definition, Expression* exp, bool builtin) { functions.insert(make_pair(name, exp)); if(!builtin) functionDefs.insert(make_pair(name, definition)); + + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Debugger::delFunction(const string& name) +bool Debugger::delFunction(const string& name) { FunctionMap::iterator iter = functions.find(name); if(iter == functions.end()) - return; + return false; functions.erase(name); delete iter->second; FunctionDefMap::iterator def_iter = functionDefs.find(name); if(def_iter == functionDefs.end()) - return; + return false; functionDefs.erase(name); + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Expression* Debugger::getFunction(const string& name) +const Expression* Debugger::getFunction(const string& name) const { - FunctionMap::iterator iter = functions.find(name); + FunctionMap::const_iterator iter = functions.find(name); if(iter == functions.end()) return 0; else @@ -706,11 +709,11 @@ Expression* Debugger::getFunction(const string& name) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Debugger::getFunctionDef(const string& name) +const string& Debugger::getFunctionDef(const string& name) const { - FunctionDefMap::iterator iter = functionDefs.find(name); + FunctionDefMap::const_iterator iter = functionDefs.find(name); if(iter == functionDefs.end()) - return ""; + return EmptyString; else return iter->second; } @@ -722,7 +725,7 @@ const FunctionDefMap Debugger::getFunctionDefMap() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const string Debugger::builtinHelp() const +string Debugger::builtinHelp() const { ostringstream buf; uInt16 len, c_maxlen = 0, i_maxlen = 0; @@ -751,20 +754,10 @@ const string Debugger::builtinHelp() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::getCompletions(const char* in, StringList& list) const { - // First check built-in functions - FunctionMap::const_iterator iter1; - for(iter1 = functions.begin(); iter1 != functions.end(); ++iter1) + FunctionMap::const_iterator iter; + for(iter = functions.begin(); iter != functions.end(); ++iter) { - const char* l = iter1->first.c_str(); - if(BSPF_strncasecmp(l, in, strlen(in)) == 0) - list.push_back(l); - } - - // Now consider user-defined functions - FunctionDefMap::const_iterator iter2; - for(iter2 = functionDefs.begin(); iter2 != functionDefs.end(); ++iter2) - { - const char* l = iter2->first.c_str(); + const char* l = iter->first.c_str(); if(BSPF_strncasecmp(l, in, strlen(in)) == 0) list.push_back(l); } diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 96e2cc432..c2f044485 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -120,14 +120,14 @@ class Debugger : public DialogContainer */ void quit(); - void addFunction(const string& name, const string& def, + bool addFunction(const string& name, const string& def, Expression* exp, bool builtin = false); - void delFunction(const string& name); - Expression* getFunction(const string& name); + bool delFunction(const string& name); + const Expression* getFunction(const string& name) const; - string getFunctionDef(const string& name); + const string& getFunctionDef(const string& name) const; const FunctionDefMap getFunctionDefMap() const; - const string builtinHelp() const; + string builtinHelp() const; /** Methods used by the command parser for tab-completion diff --git a/src/debugger/DebuggerExpressions.hxx b/src/debugger/DebuggerExpressions.hxx index 3eba0e01b..e71eee882 100644 --- a/src/debugger/DebuggerExpressions.hxx +++ b/src/debugger/DebuggerExpressions.hxx @@ -36,7 +36,8 @@ class BinAndExpression : public Expression { public: BinAndExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() & myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() & myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -44,7 +45,8 @@ class BinNotExpression : public Expression { public: BinNotExpression(Expression* left) : Expression(left, 0) {} - uInt16 evaluate() { return ~(myLHS->evaluate()); } + uInt16 evaluate() const + { return ~(myLHS->evaluate()); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -52,7 +54,8 @@ class BinOrExpression : public Expression { public: BinOrExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() | myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() | myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,7 +63,8 @@ class BinXorExpression : public Expression { public: BinXorExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() ^ myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() ^ myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -68,7 +72,8 @@ class ByteDerefExpression : public Expression { public: ByteDerefExpression(Expression* left): Expression(left, 0) {} - uInt16 evaluate() { return Debugger::debugger().peek(myLHS->evaluate()); } + uInt16 evaluate() const + { return Debugger::debugger().peek(myLHS->evaluate()); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -76,7 +81,8 @@ class ByteDerefOffsetExpression : public Expression { public: ByteDerefOffsetExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return Debugger::debugger().peek(myLHS->evaluate() + myRHS->evaluate()); } + uInt16 evaluate() const + { return Debugger::debugger().peek(myLHS->evaluate() + myRHS->evaluate()); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -84,7 +90,8 @@ class ConstExpression : public Expression { public: ConstExpression(const int value) : Expression(0, 0), myValue(value) {} - uInt16 evaluate() { return myValue; } + uInt16 evaluate() const + { return myValue; } private: int myValue; @@ -95,7 +102,8 @@ class CpuMethodExpression : public Expression { public: CpuMethodExpression(CPUDEBUG_INT_METHOD method) : Expression(0, 0), myMethod(method) {} - uInt16 evaluate() { return CALL_CPUDEBUG_METHOD(myMethod); } + uInt16 evaluate() const + { return CALL_CPUDEBUG_METHOD(myMethod); } private: CPUDEBUG_INT_METHOD myMethod; @@ -106,9 +114,9 @@ class DivExpression : public Expression { public: DivExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { int denom = myRHS->evaluate(); - return denom == 0 ? 0 : myLHS->evaluate() / denom; - } + uInt16 evaluate() const + { int denom = myRHS->evaluate(); + return denom == 0 ? 0 : myLHS->evaluate() / denom; } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -116,7 +124,8 @@ class EqualsExpression : public Expression { public: EqualsExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() == myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() == myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -124,7 +133,8 @@ class EquateExpression : public Expression { public: EquateExpression(const string& label) : Expression(0, 0), myLabel(label) {} - uInt16 evaluate() { return Debugger::debugger().cartDebug().getAddress(myLabel); } + uInt16 evaluate() const + { return Debugger::debugger().cartDebug().getAddress(myLabel); } private: string myLabel; @@ -135,10 +145,11 @@ class FunctionExpression : public Expression { public: FunctionExpression(const string& label) : Expression(0, 0), myLabel(label) {} - uInt16 evaluate() { - Expression* exp = Debugger::debugger().getFunction(myLabel); - if(exp) return exp->evaluate(); - else return 0; + uInt16 evaluate() const + { + const Expression* exp = Debugger::debugger().getFunction(myLabel); + if(exp) return exp->evaluate(); + else return 0; } private: @@ -150,7 +161,8 @@ class GreaterEqualsExpression : public Expression { public: GreaterEqualsExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() >= myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() >= myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -158,7 +170,8 @@ class GreaterExpression : public Expression { public: GreaterExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() > myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() > myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -166,7 +179,8 @@ class HiByteExpression : public Expression { public: HiByteExpression(Expression* left) : Expression(left, 0) {} - uInt16 evaluate() { return 0xff & (myLHS->evaluate() >> 8); } + uInt16 evaluate() const + { return 0xff & (myLHS->evaluate() >> 8); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -174,7 +188,8 @@ class LessEqualsExpression : public Expression { public: LessEqualsExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() <= myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() <= myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -182,7 +197,8 @@ class LessExpression : public Expression { public: LessExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() < myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() < myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -190,7 +206,8 @@ class LoByteExpression : public Expression { public: LoByteExpression(Expression* left) : Expression(left, 0) {} - uInt16 evaluate() { return 0xff & myLHS->evaluate(); } + uInt16 evaluate() const + { return 0xff & myLHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -198,7 +215,8 @@ class LogAndExpression : public Expression { public: LogAndExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() && myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() && myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -206,7 +224,8 @@ class LogNotExpression : public Expression { public: LogNotExpression(Expression* left) : Expression(left, 0) {} - uInt16 evaluate() { return !(myLHS->evaluate()); } + uInt16 evaluate() const + { return !(myLHS->evaluate()); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -214,7 +233,8 @@ class LogOrExpression : public Expression { public: LogOrExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() || myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() || myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -222,7 +242,8 @@ class MinusExpression : public Expression { public: MinusExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() - myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() - myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -230,9 +251,9 @@ class ModExpression : public Expression { public: ModExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { int rhs = myRHS->evaluate(); - return rhs == 0 ? 0 : myLHS->evaluate() % rhs; - } + uInt16 evaluate() const + { int rhs = myRHS->evaluate(); + return rhs == 0 ? 0 : myLHS->evaluate() % rhs; } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -240,7 +261,8 @@ class MultExpression : public Expression { public: MultExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() * myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() * myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -248,7 +270,8 @@ class NotEqualsExpression : public Expression { public: NotEqualsExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() != myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() != myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -256,7 +279,8 @@ class PlusExpression : public Expression { public: PlusExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() + myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() + myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -264,7 +288,8 @@ class CartMethodExpression : public Expression { public: CartMethodExpression(CARTDEBUG_INT_METHOD method) : Expression(0, 0), myMethod(method) {} - uInt16 evaluate() { return CALL_CARTDEBUG_METHOD(myMethod); } + uInt16 evaluate() const + { return CALL_CARTDEBUG_METHOD(myMethod); } private: CARTDEBUG_INT_METHOD myMethod; @@ -275,7 +300,8 @@ class ShiftLeftExpression : public Expression { public: ShiftLeftExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() << myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() << myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -283,7 +309,8 @@ class ShiftRightExpression : public Expression { public: ShiftRightExpression(Expression* left, Expression* right) : Expression(left, right) {} - uInt16 evaluate() { return myLHS->evaluate() >> myRHS->evaluate(); } + uInt16 evaluate() const + { return myLHS->evaluate() >> myRHS->evaluate(); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -291,7 +318,8 @@ class TiaMethodExpression : public Expression { public: TiaMethodExpression(TIADEBUG_INT_METHOD method) : Expression(0, 0), myMethod(method) {} - uInt16 evaluate() { return CALL_TIADEBUG_METHOD(myMethod); } + uInt16 evaluate() const + { return CALL_TIADEBUG_METHOD(myMethod); } private: TIADEBUG_INT_METHOD myMethod; @@ -302,7 +330,8 @@ class UnaryMinusExpression : public Expression { public: UnaryMinusExpression(Expression* left) : Expression(left, 0) {} - uInt16 evaluate() { return -(myLHS->evaluate()); } + uInt16 evaluate() const + { return -(myLHS->evaluate()); } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -310,7 +339,8 @@ class WordDerefExpression : public Expression { public: WordDerefExpression(Expression* left) : Expression(left, 0) {} - uInt16 evaluate() { return Debugger::debugger().dpeek(myLHS->evaluate()); } + uInt16 evaluate() const + { return Debugger::debugger().dpeek(myLHS->evaluate()); } }; #endif diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 965ea3091..f739625b5 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -17,7 +17,6 @@ //============================================================================ #include -#include #include "bspf.hxx" #include "Dialog.hxx" @@ -103,7 +102,7 @@ string DebuggerParser::run(const string& command) extern int refCount; cerr << "Expression count: " << refCount << endl; #endif - commandResult = ""; + commandResult.str(""); for(int i = 0; i < kNumCommands; ++i) { @@ -115,12 +114,11 @@ string DebuggerParser::run(const string& command) if(commands[i].refreshRequired) debugger->myBaseDialog->loadConfig(); - return commandResult; + return commandResult.str(); } } - commandResult = "No such command (try \"help\")"; - return commandResult; + return "No such command (try \"help\")"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -422,7 +420,7 @@ bool DebuggerParser::validateArgs(int cmd) { if(required) { - commandResult = red("missing required argument(s)"); + commandResult.str(red("missing required argument(s)")); return false; // needed args. didn't get 'em. } else @@ -456,7 +454,7 @@ bool DebuggerParser::validateArgs(int cmd) case kARG_WORD: if(curArgInt < 0 || curArgInt > 0xffff) { - commandResult = red("invalid word argument (must be 0-$ffff)"); + commandResult.str(red("invalid word argument (must be 0-$ffff)")); return false; } break; @@ -464,7 +462,7 @@ bool DebuggerParser::validateArgs(int cmd) case kARG_BYTE: if(curArgInt < 0 || curArgInt > 0xff) { - commandResult = red("invalid byte argument (must be 0-$ff)"); + commandResult.str(red("invalid byte argument (must be 0-$ff)")); return false; } break; @@ -472,7 +470,7 @@ bool DebuggerParser::validateArgs(int cmd) case kARG_BOOL: if(curArgInt != 0 && curArgInt != 1) { - commandResult = red("invalid boolean argument (must be 0 or 1)"); + commandResult.str(red("invalid boolean argument (must be 0 or 1)")); return false; } break; @@ -481,7 +479,7 @@ bool DebuggerParser::validateArgs(int cmd) if(curArgInt != 2 && curArgInt != 10 && curArgInt != 16 && curArgStr != "hex" && curArgStr != "dec" && curArgStr != "bin") { - commandResult = red("invalid base (must be #2, #10, #16, \"bin\", \"dec\", or \"hex\")"); + commandResult.str(red("invalid base (must be #2, #10, #16, \"bin\", \"dec\", or \"hex\")")); return false; } break; @@ -510,12 +508,12 @@ cerr << "curCount = " << curCount << endl if(curCount < argRequiredCount) { - commandResult = red("missing required argument(s)"); + commandResult.str(red("missing required argument(s)")); return false; } else if(argCount > curCount) { - commandResult = red("too many arguments"); + commandResult.str(red("too many arguments")); return false; } @@ -631,34 +629,6 @@ void DebuggerParser::executeA() debugger->cpuDebug().setA((uInt8)args[0]); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// "bank" -void DebuggerParser::executeBank() -{ - int banks = debugger->cartDebug().bankCount(); - if(argCount == 0) { - commandResult += debugger->cartDebug().getCartType(); - commandResult += ": "; - if(banks < 2) - commandResult += red("bankswitching not supported by this cartridge"); - else { - commandResult += debugger->valueToString(debugger->cartDebug().getBank()); - commandResult += "/"; - commandResult += debugger->valueToString(banks); - } - } else { - if(args[0] >= banks) { - commandResult += red("invalid bank number (must be 0 to "); - commandResult += debugger->valueToString(banks - 1); - commandResult += ")"; - } else if(debugger->setBank(args[0])) { - commandResult += "switched bank OK"; - } else { - commandResult += red("unknown error switching banks"); - } - } -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "base" void DebuggerParser::executeBase() @@ -670,22 +640,22 @@ void DebuggerParser::executeBase() else if(args[0] == 16 || argStrings[0] == "hex") setBase(kBASE_16); - commandResult = "default base set to "; + commandResult << "default base set to "; switch(defaultBase) { case kBASE_2: - commandResult += "#2/bin"; + commandResult << "#2/bin"; break; case kBASE_10: - commandResult += "#10/dec"; + commandResult << "#10/dec"; break; case kBASE_16: - commandResult += "#16/hex"; + commandResult << "#16/hex"; break; default: - commandResult += red("UNKNOWN"); + commandResult << red("UNKNOWN"); break; } } @@ -703,12 +673,11 @@ void DebuggerParser::executeBreak() debugger->myRom->invalidate(); if(debugger->breakPoint(bp)) - commandResult = "Set"; + commandResult << "Set"; else - commandResult = "Cleared"; + commandResult << "Cleared"; - commandResult += " breakpoint at "; - commandResult += debugger->valueToString(bp); + commandResult << " breakpoint at " << debugger->valueToString(bp); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -716,15 +685,14 @@ void DebuggerParser::executeBreak() void DebuggerParser::executeBreakif() { int res = YaccParser::parse(argStrings[0].c_str()); - if(res == 0) { - // I hate this().method().chaining().crap() - unsigned int ret = debugger->cpuDebug().m6502().addCondBreak( - YaccParser::getResult(), argStrings[0] ); - commandResult = "Added breakif "; - commandResult += debugger->valueToString(ret); - } else { - commandResult = red("invalid expression"); + if(res == 0) + { + uInt32 ret = debugger->cpuDebug().m6502().addCondBreak( + YaccParser::getResult(), argStrings[0] ); + commandResult << "Added breakif " << debugger->valueToString(ret); } + else + commandResult << red("invalid expression"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -743,22 +711,23 @@ void DebuggerParser::executeC() void DebuggerParser::executeCheat() { #ifdef CHEATCODE_SUPPORT - if(argCount == 0) { - commandResult = red("Missing cheat code"); + if(argCount == 0) + { + commandResult << red("Missing cheat code"); return; } - for(int arg = 0; arg < argCount; arg++) { - string& cheat = argStrings[arg]; + for(int arg = 0; arg < argCount; arg++) + { + const string& cheat = argStrings[arg]; const Cheat* c = debugger->getOSystem()->cheat().add("DBG", cheat); - if(c && c->enabled()) { - commandResult = "Cheat code " + cheat + " enabled\n"; - } else { - commandResult = red("Invalid cheat code " + cheat + "\n"); - } + if(c && c->enabled()) + commandResult << "Cheat code " << cheat << " enabled" << endl; + else + commandResult << red("Invalid cheat code ") << cheat << endl; } #else - commandResult = red("Cheat support not enabled\n"); + commandResult << red("Cheat support not enabled\n"); #endif } @@ -768,7 +737,7 @@ void DebuggerParser::executeClearbreaks() { debugger->clearAllBreakPoints(); debugger->cpuDebug().m6502().clearCondBreaks(); - commandResult = "all breakpoints cleared"; + commandResult << "all breakpoints cleared"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -776,7 +745,7 @@ void DebuggerParser::executeClearbreaks() void DebuggerParser::executeCleartraps() { debugger->clearAllTraps(); - commandResult = "all traps cleared"; + commandResult << "all traps cleared"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -784,16 +753,24 @@ void DebuggerParser::executeCleartraps() void DebuggerParser::executeClearwatches() { watches.clear(); - commandResult = "all watches cleared"; + commandResult << "all watches cleared"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// "cls" +void DebuggerParser::executeCls() +{ + debugger->prompt()->clearScreen(); + commandResult << ""; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "colortest" void DebuggerParser::executeColortest() { - commandResult = "test color: "; - commandResult += char((args[0]>>1) | 0x80); - commandResult += inverse(" "); + commandResult << "test color: " + << char((args[0]>>1) | 0x80) + << inverse(" "); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -813,7 +790,6 @@ void DebuggerParser::executeDefine() // TODO: check if label already defined? debugger->cartDebug().addLabel(argStrings[0], args[1]); debugger->myRom->invalidate(); - commandResult = "label " + argStrings[0] + " defined as " + debugger->valueToString(args[1]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -823,6 +799,16 @@ void DebuggerParser::executeDelbreakif() debugger->cpuDebug().m6502().delCondBreak(args[0]); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// "delfunction" +void DebuggerParser::executeDelfunction() +{ + if(debugger->delFunction(argStrings[0])) + commandResult << "removed function " << argStrings[0]; + else + commandResult << "function " << argStrings[0] << " not found"; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "delwatch" void DebuggerParser::executeDelwatch() @@ -831,10 +817,10 @@ void DebuggerParser::executeDelwatch() if(which >= 0 && which < (int)watches.size()) { watches.remove_at(which); - commandResult = "removed watch"; + commandResult << "removed watch"; } else - commandResult = "no such watch"; + commandResult << "no such watch"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -851,27 +837,27 @@ void DebuggerParser::executeDisasm() start = args[0]; lines = args[1]; } else { - commandResult = "wrong number of arguments"; + commandResult << "wrong number of arguments"; return; } - commandResult = debugger->cartDebug().disassemble(start, lines); + commandResult << debugger->cartDebug().disassemble(start, lines); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "dump" void DebuggerParser::executeDump() { - for(int i=0; i<8; i++) { + for(int i=0; i<8; i++) + { int start = args[0] + i*16; - commandResult += debugger->valueToString(start); - commandResult += ": "; - for(int j=0; j<16; j++) { - commandResult += debugger->valueToString( debugger->peek(start+j) ); - commandResult += " "; - if(j == 7) commandResult += "- "; + commandResult << debugger->valueToString(start) << ": "; + for(int j=0; j<16; j++) + { + commandResult << debugger->valueToString(debugger->peek(start+j)) << " "; + if(j == 7) commandResult << "- "; } - if(i != 7) commandResult += "\n"; + if(i != 7) commandResult << endl; } } @@ -879,15 +865,13 @@ void DebuggerParser::executeDump() // "exec" void DebuggerParser::executeExec() { - commandResult = exec(argStrings[0]); + commandResult << exec(argStrings[0]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "help" void DebuggerParser::executeHelp() { - ostringstream buf; - // Find length of longest command uInt16 clen = 0; for(int i = 0; i < kNumCommands; ++i) @@ -898,22 +882,21 @@ void DebuggerParser::executeHelp() // TODO - add wraparound for text longer than the output area bounds for(int i = 0; i < kNumCommands; ++i) - buf << setw(clen) << right << commands[i].cmdString << " - " << commands[i].description << endl; + commandResult << setw(clen) << right << commands[i].cmdString + << " - " << commands[i].description << endl; - buf << endl - << "\nPseudo-registers:" << endl - << "_bank Currently selected bank" << endl - << "_rwport Address at which a read from a write port occurred" << endl - << "_scan Current scanline count" << endl - << "_fcount Number of frames since emulation started" << endl - << "_cclocks Color clocks on current scanline" << endl - << "_vsync Whether vertical sync is enabled (1 or 0)" << endl - << "_vblank Whether vertical blank is enabled (1 or 0)" << endl - << endl - << "Built-in functions:" << endl - << debugger->builtinHelp(); - - commandResult = buf.str(); + commandResult + << "\nPseudo-registers:" << endl + << "_bank Currently selected bank" << endl + << "_rwport Address at which a read from a write port occurred" << endl + << "_scan Current scanline count" << endl + << "_fcount Number of frames since emulation started" << endl + << "_cclocks Color clocks on current scanline" << endl + << "_vsync Whether vertical sync is enabled (1 or 0)" << endl + << "_vblank Whether vertical blank is enabled (1 or 0)" << endl + << endl + << "Built-in functions:" << endl + << debugger->builtinHelp(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -923,28 +906,28 @@ void DebuggerParser::executeFrame() int count = 1; if(argCount != 0) count = args[0]; debugger->nextFrame(count); - commandResult = "advanced "; - commandResult += debugger->valueToString(count); - commandResult += " frame"; - if(count != 1) commandResult += "s"; + commandResult << "advanced " << debugger->valueToString(count) << " frame"; + if(count != 1) commandResult << "s"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "function" void DebuggerParser::executeFunction() { - if(args[0] >= 0) { - commandResult = red("name already in use"); + if(args[0] >= 0) + { + commandResult << red("name already in use"); return; } int res = YaccParser::parse(argStrings[1].c_str()); - if(res == 0) { + if(res == 0) + { debugger->addFunction(argStrings[0], argStrings[1], YaccParser::getResult()); - commandResult = "Added function " + argStrings[0]; - } else { - commandResult = red("invalid expression"); + commandResult << "Added function " << argStrings[0] << " -> " << argStrings[1]; } + else + commandResult << red("invalid expression"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -962,7 +945,6 @@ void DebuggerParser::executeListbreaks() if(! (++count % 8) ) buf << "\n"; } } - commandResult += buf.str(); /* if(count) @@ -971,21 +953,37 @@ void DebuggerParser::executeListbreaks() return "no breakpoints set"; */ if(count) - commandResult = "breaks:\n" + commandResult; + commandResult << "breaks:\n" << buf.str(); StringList conds = debugger->cpuDebug().m6502().getCondBreakNames(); - if(conds.size() > 0) { - commandResult += "\nbreakifs:\n"; - for(unsigned int i=0; ivalueToString(i); - commandResult += ": "; - commandResult += conds[i]; - if(i != (conds.size() - 1)) commandResult += "\n"; + if(conds.size() > 0) + { + commandResult << "\nbreakifs:\n"; + for(unsigned int i=0; ivalueToString(i) << ": " << conds[i]; + if(i != (conds.size() - 1)) commandResult << endl; } } - if(commandResult == "") - commandResult = "no breakpoints set"; + if(commandResult.str() == "") + commandResult << "no breakpoints set"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// "listfunctions" +void DebuggerParser::executeListfunctions() +{ + const FunctionDefMap& functions = debugger->getFunctionDefMap(); + + if(functions.size() > 0) + { + FunctionDefMap::const_iterator iter; + for(iter = functions.begin(); iter != functions.end(); ++iter) + commandResult << iter->first << " -> " << iter->second << endl; + } + else + commandResult << "no user-defined functions"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -994,43 +992,37 @@ void DebuggerParser::executeListtraps() { int count = 0; - for(unsigned int i=0; i<0x10000; i++) { - if(debugger->readTrap(i) || debugger->writeTrap(i)) { - commandResult += trapStatus(i); - commandResult += "\n"; + for(unsigned int i=0; i<0x10000; i++) + { + if(debugger->readTrap(i) || debugger->writeTrap(i)) + { + commandResult << trapStatus(i) << endl; count++; } } if(!count) - commandResult = "no traps set"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// "listwatches" -void DebuggerParser::executeListwatches() -{ - // commandResult = listWatches(); - commandResult = red("command not yet implemented (sorry)"); + commandResult << "no traps set"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "loadstate" void DebuggerParser::executeLoadstate() { - if(args[0] >= 0 && args[0] <= 9) { + if(args[0] >= 0 && args[0] <= 9) + { debugger->loadState(args[0]); - commandResult = "state loaded"; - } else { - commandResult = red("invalid slot (must be 0-9)"); + commandResult << "state loaded"; } + else + commandResult << red("invalid slot (must be 0-9)"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "loadsym" void DebuggerParser::executeLoadsym() { - commandResult = debugger->cartDebug().loadSymbolFile(argStrings[0]); + commandResult << debugger->cartDebug().loadSymbolFile(argStrings[0]); debugger->myRom->invalidate(); } @@ -1055,7 +1047,7 @@ void DebuggerParser::executePc() // "print" void DebuggerParser::executePrint() { - commandResult = eval(); + commandResult << eval(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1063,9 +1055,9 @@ void DebuggerParser::executePrint() void DebuggerParser::executeRam() { if(argCount == 0) - commandResult = debugger->cartDebug().toString(); + commandResult << debugger->cartDebug().toString(); else - commandResult = debugger->setRAM(args); + commandResult << debugger->setRAM(args); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1074,7 +1066,7 @@ void DebuggerParser::executeReset() { debugger->reset(); debugger->myRom->invalidate(); - commandResult = "reset CPU"; + commandResult << "reset CPU"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1084,17 +1076,17 @@ void DebuggerParser::executeRewind() if(debugger->rewindState()) { debugger->myRom->invalidate(); - commandResult = "rewind by one level"; + commandResult << "rewind by one level"; } else - commandResult = "no states left to rewind"; + commandResult << "no states left to rewind"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "riot" void DebuggerParser::executeRiot() { - commandResult = debugger->riotDebug().toString(); + commandResult << debugger->riotDebug().toString(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1102,9 +1094,11 @@ void DebuggerParser::executeRiot() void DebuggerParser::executeRom() { int addr = args[0]; - for(int i=1; ipatchROM(addr++, args[i])) ) { - commandResult = red("patching ROM unsupported for this cart type"); + for(int i=1; ipatchROM(addr++, args[i])) ) + { + commandResult << red("patching ROM unsupported for this cart type"); return; } } @@ -1116,9 +1110,8 @@ void DebuggerParser::executeRom() // method ... debugger->myRom->invalidate(); - commandResult = "changed "; - commandResult += debugger->valueToString( args.size() - 1 ); - commandResult += " location(s)"; + commandResult << "changed " << debugger->valueToString( args.size() - 1 ) + << " location(s)"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1127,14 +1120,13 @@ void DebuggerParser::executeRun() { debugger->saveOldState(); debugger->quit(); - commandResult = "_EXIT_DEBUGGER"; // See PromptWidget for more info + commandResult << "_EXIT_DEBUGGER"; // See PromptWidget for more info } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "runto" void DebuggerParser::executeRunTo() { - ostringstream buf; const CartDebug& cartdbg = debugger->cartDebug(); const CartDebug::DisassemblyList& list = cartdbg.disassemblyList(); @@ -1154,22 +1146,21 @@ void DebuggerParser::executeRunTo() } while(!done && count < list.size()); if(done) - buf << "found " << argStrings[0] << " in " - << debugger->valueToString(count, kBASE_10) - << " disassembled instructions"; + commandResult + << "found " << argStrings[0] << " in " + << debugger->valueToString(count, kBASE_10) + << " disassembled instructions"; else - buf << argStrings[0] << " not found in " - << debugger->valueToString(count, kBASE_10) - << " disassembled instructions"; - - commandResult = buf.str(); + commandResult + << argStrings[0] << " not found in " + << debugger->valueToString(count, kBASE_10) + << " disassembled instructions"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "runtopc" void DebuggerParser::executeRunToPc() { - ostringstream buf; const CartDebug& cartdbg = debugger->cartDebug(); const CartDebug::DisassemblyList& list = cartdbg.disassemblyList(); @@ -1185,15 +1176,15 @@ void DebuggerParser::executeRunToPc() } while(!done && count < list.size()); if(done) - buf << "set PC to " << hex << args[0] << " in " - << debugger->valueToString(count, kBASE_10) - << " disassembled instructions"; + commandResult + << "set PC to " << hex << args[0] << " in " + << debugger->valueToString(count, kBASE_10) + << " disassembled instructions"; else - buf << "PC " << hex << args[0] << " not reached or found in " - << debugger->valueToString(count, kBASE_10) - << " disassembled instructions"; - - commandResult = buf.str(); + commandResult + << "PC " << hex << args[0] << " not reached or found in " + << debugger->valueToString(count, kBASE_10) + << " disassembled instructions"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1208,9 +1199,9 @@ void DebuggerParser::executeS() void DebuggerParser::executeSave() { if(saveScriptFile(argStrings[0])) - commandResult = "saved script to file " + argStrings[0]; + commandResult << "saved script to file " << argStrings[0]; else - commandResult = red("I/O error"); + commandResult << red("I/O error"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1218,9 +1209,9 @@ void DebuggerParser::executeSave() void DebuggerParser::executeSaverom() { if(debugger->saveROM(argStrings[0])) - commandResult = "saved ROM as " + argStrings[0]; + commandResult << "saved ROM as " << argStrings[0]; else - commandResult = red("failed to save ROM"); + commandResult << red("failed to save ROM"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1228,21 +1219,22 @@ void DebuggerParser::executeSaverom() void DebuggerParser::executeSaveses() { if(debugger->prompt()->saveBuffer(argStrings[0])) - commandResult = "saved session to file " + argStrings[0]; + commandResult << "saved session to file " << argStrings[0]; else - commandResult = red("I/O error"); + commandResult << red("I/O error"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "savestate" void DebuggerParser::executeSavestate() { - if(args[0] >= 0 && args[0] <= 9) { + if(args[0] >= 0 && args[0] <= 9) + { debugger->saveState(args[0]); - commandResult = "state saved"; - } else { - commandResult = red("invalid slot (must be 0-9)"); + commandResult << "state saved"; } + else + commandResult << red("invalid slot (must be 0-9)"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1252,37 +1244,31 @@ void DebuggerParser::executeScanline() int count = 1; if(argCount != 0) count = args[0]; debugger->nextScanline(count); - commandResult = "advanced "; - commandResult += debugger->valueToString(count); - commandResult += " scanline"; - if(count != 1) commandResult += "s"; + commandResult << "advanced " << debugger->valueToString(count) << " scanline"; + if(count != 1) commandResult << "s"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "step" void DebuggerParser::executeStep() { - int cycles = debugger->step(); - commandResult = "executed "; - commandResult += debugger->valueToString(cycles); - commandResult += " cycles"; + commandResult + << "executed " << debugger->valueToString(debugger->step()) << " cycles"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "tia" void DebuggerParser::executeTia() { - commandResult = debugger->tiaDebug().toString(); + commandResult << debugger->tiaDebug().toString(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "trace" void DebuggerParser::executeTrace() { - int cycles = debugger->trace(); - commandResult = "executed "; - commandResult += debugger->valueToString(cycles); - commandResult += " cycles"; + commandResult + << "executed " << debugger->valueToString(debugger->trace()) << " cycles"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1291,7 +1277,7 @@ void DebuggerParser::executeTrap() { debugger->toggleReadTrap(args[0]); debugger->toggleWriteTrap(args[0]); - commandResult = trapStatus(args[0]); + commandResult << trapStatus(args[0]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1299,7 +1285,7 @@ void DebuggerParser::executeTrap() void DebuggerParser::executeTrapread() { debugger->toggleReadTrap(args[0]); - commandResult = trapStatus(args[0]); + commandResult << trapStatus(args[0]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1307,7 +1293,7 @@ void DebuggerParser::executeTrapread() void DebuggerParser::executeTrapwrite() { debugger->toggleWriteTrap(args[0]); - commandResult = trapStatus(args[0]); + commandResult << trapStatus(args[0]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1317,10 +1303,10 @@ void DebuggerParser::executeUndef() if(debugger->cartDebug().removeLabel(argStrings[0])) { debugger->myRom->invalidate(); - commandResult = argStrings[0] + " now undefined"; + commandResult << argStrings[0] + " now undefined"; } else - commandResult = red("no such label"); + commandResult << red("no such label"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1338,7 +1324,7 @@ void DebuggerParser::executeV() void DebuggerParser::executeWatch() { watches.push_back(argStrings[0]); - commandResult = "added watch \"" + argStrings[0] + "\""; + commandResult << "added watch \"" << argStrings[0] << "\""; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1378,15 +1364,6 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { &DebuggerParser::executeA }, - { - "bank", - "Show # of banks (with no args), Switch to bank (with 1 arg)", - false, - true, - { kARG_WORD, kARG_END_ARGS }, - &DebuggerParser::executeBank - }, - { "base", "Set default base (hex, dec, or bin)", @@ -1398,7 +1375,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "break", - "Set/clear breakpoint at address (default: current pc)", + "Set/clear breakpoint at address xx (default=PC)", false, true, { kARG_WORD, kARG_END_ARGS }, @@ -1407,7 +1384,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "breakif", - "Set breakpoint on condition", + "Set breakpoint on condition xx", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1416,7 +1393,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "c", - "Carry Flag: set (to 0 or 1), or toggle (no arg)", + "Carry Flag: set (0 or 1), or toggle (no arg)", false, true, { kARG_BOOL, kARG_END_ARGS }, @@ -1425,7 +1402,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "cheat", - "Use a cheat code (see Stella manual for cheat types)", + "Use a cheat code (see manual for cheat types)", false, false, { kARG_LABEL, kARG_END_ARGS }, @@ -1459,9 +1436,18 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { &DebuggerParser::executeClearwatches }, + { + "cls", + "Clear prompt area of text and erase history", + false, + false, + { kARG_END_ARGS }, + &DebuggerParser::executeCls + }, + { "colortest", - "Color Test", + "Show value xx as TIA color", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1470,7 +1456,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "d", - "Decimal Flag: set (to 0 or 1), or toggle (no arg)", + "Decimal Flag: set (0 or 1), or toggle (no arg)", false, true, { kARG_BOOL, kARG_END_ARGS }, @@ -1479,7 +1465,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "define", - "Define label", + "Define label xx for address yy", true, true, { kARG_LABEL, kARG_WORD, kARG_END_ARGS }, @@ -1488,16 +1474,25 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "delbreakif", - "Delete conditional break created with breakif", + "Delete conditional breakif xx", true, false, { kARG_WORD, kARG_END_ARGS }, &DebuggerParser::executeDelbreakif }, + { + "delfunction", + "Delete function with label xx", + true, + false, + { kARG_LABEL, kARG_END_ARGS }, + &DebuggerParser::executeDelfunction + }, + { "delwatch", - "Delete watch", + "Delete watch xx", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1506,7 +1501,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "disasm", - "Disassemble from address (default=pc)", + "Disassemble address xx [yy lines] (default=PC)", false, false, { kARG_WORD, kARG_MULTI_BYTE }, @@ -1515,7 +1510,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "dump", - "Dump 128 bytes of memory at address", + "Dump 128 bytes of memory at address xx", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1524,7 +1519,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "exec", - "Execute script file", + "Execute script file xx", true, true, { kARG_FILE, kARG_END_ARGS }, @@ -1542,8 +1537,8 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "function", - "Define expression as a function for later use", - false, + "Define function name xx for expression yy", + true, false, { kARG_LABEL, kARG_WORD, kARG_END_ARGS }, &DebuggerParser::executeFunction @@ -1567,6 +1562,15 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { &DebuggerParser::executeListbreaks }, + { + "listfunctions", + "List user-defined functions", + false, + false, + { kARG_END_ARGS }, + &DebuggerParser::executeListfunctions + }, + { "listtraps", "List traps", @@ -1576,18 +1580,9 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { &DebuggerParser::executeListtraps }, - { - "listwatches", - "List watches", - false, - false, - { kARG_END_ARGS }, - &DebuggerParser::executeListwatches - }, - { "loadstate", - "Load emulator state (0-9)", + "Load emulator state xx (0-9)", true, true, { kARG_WORD, kARG_END_ARGS }, @@ -1596,7 +1591,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "loadsym", - "Load symbol file", + "Load symbol file named xx", true, true, { kARG_FILE, kARG_END_ARGS }, @@ -1605,7 +1600,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "n", - "Negative Flag: set (to 0 or 1), or toggle (no arg)", + "Negative Flag: set (0 or 1), or toggle (no arg)", false, true, { kARG_BOOL, kARG_END_ARGS }, @@ -1614,25 +1609,16 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "pc", - "Set Program Counter to address", + "Set Program Counter to address xx", true, true, { kARG_WORD, kARG_END_ARGS }, &DebuggerParser::executePc }, - { - "poke", - "Set address to value. Can give multiple values (for address+1, etc)", - true, - true, - { kARG_WORD, kARG_MULTI_BYTE }, - &DebuggerParser::executeRam - }, - { "print", - "Evaluate and print expression in hex/dec/binary", + "Evaluate/print expression xx in hex/dec/binary", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1641,7 +1627,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "ram", - "Show RAM contents (no args), or set address xx to value yy", + "Show ZP RAM, or set address xx to yy1 [yy2 ...]", false, true, { kARG_WORD, kARG_MULTI_BYTE }, @@ -1650,7 +1636,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "reset", - "Reset 6507 to init vector (does not reset TIA, RIOT)", + "Reset 6507 to init vector (excluding TIA/RIOT)", false, true, { kARG_END_ARGS }, @@ -1659,7 +1645,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "rewind", - "Rewind state to last step/trace/scanline/frame advance", + "Rewind state to last step/trace/scanline/frame", false, true, { kARG_END_ARGS }, @@ -1677,7 +1663,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "rom", - "Change ROM contents", + "Set ROM address xx to yy1 [yy2 ...]", true, true, { kARG_WORD, kARG_MULTI_BYTE }, @@ -1695,7 +1681,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "runto", - "Run until first occurrence of string in disassembly", + "Run until string xx in disassembly", true, true, { kARG_LABEL, kARG_END_ARGS }, @@ -1704,7 +1690,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "runtopc", - "Run until PC is set to this value", + "Run until PC is set to value xx", true, true, { kARG_WORD, kARG_END_ARGS }, @@ -1722,7 +1708,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "save", - "Save breaks, watches, traps as a .stella script file", + "Save breaks, watches, traps to file xx", true, false, { kARG_FILE, kARG_END_ARGS }, @@ -1731,7 +1717,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "saverom", - "Save (possibly patched) ROM to file", + "Save (possibly patched) ROM to file xx", true, false, { kARG_FILE, kARG_END_ARGS }, @@ -1740,7 +1726,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "saveses", - "Save console session to file", + "Save console session to file xx", true, false, { kARG_FILE, kARG_END_ARGS }, @@ -1749,7 +1735,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "savestate", - "Save emulator state (valid args 0-9)", + "Save emulator state xx (valid args 0-9)", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1767,7 +1753,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "step", - "Single step CPU (optionally, with count)", + "Single step CPU [with count xx]", false, true, { kARG_WORD, kARG_END_ARGS }, @@ -1785,7 +1771,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "trace", - "Single step CPU (optionally, with count), subroutines count as one instruction", + "Single step CPU over subroutines [with count xx]", false, true, { kARG_WORD, kARG_END_ARGS }, @@ -1794,7 +1780,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "trap", - "Trap read and write accesses to address", + "Trap read and write accesses to address xx", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1803,7 +1789,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "trapread", - "Trap read accesses to address", + "Trap read accesses to address xx", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1812,7 +1798,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "trapwrite", - "Trap write accesses to address", + "Trap write accesses to address xx", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1821,7 +1807,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "undef", - "Undefine label (if defined)", + "Undefine label xx (if defined)", true, true, { kARG_LABEL, kARG_END_ARGS }, @@ -1830,7 +1816,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "v", - "Overflow Flag: set (to 0 or 1), or toggle (no arg)", + "Overflow Flag: set (0 or 1), or toggle (no arg)", false, true, { kARG_BOOL, kARG_END_ARGS }, @@ -1839,7 +1825,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "watch", - "Print contents of address before every prompt", + "Print contents of address xx before every prompt", true, false, { kARG_WORD, kARG_END_ARGS }, @@ -1866,7 +1852,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "z", - "Zero Flag: set (to 0 or 1), or toggle (no arg)", + "Zero Flag: set (0 or 1), or toggle (no arg)", false, true, { kARG_BOOL, kARG_END_ARGS }, diff --git a/src/debugger/DebuggerParser.hxx b/src/debugger/DebuggerParser.hxx index 5e329188c..fa8c90c1b 100644 --- a/src/debugger/DebuggerParser.hxx +++ b/src/debugger/DebuggerParser.hxx @@ -19,6 +19,8 @@ #ifndef DEBUGGER_PARSER_HXX #define DEBUGGER_PARSER_HXX +#include + class Debugger; struct Command; @@ -119,7 +121,7 @@ class DebuggerParser Debugger* debugger; // The results of the currently running command - string commandResult; + ostringstream commandResult; // Arguments in 'int' and 'string' format for the currently running command IntArray args; @@ -131,7 +133,6 @@ class DebuggerParser // List of available command methods void executeA(); - void executeBank(); void executeBase(); void executeBreak(); void executeBreakif(); @@ -140,10 +141,12 @@ class DebuggerParser void executeClearbreaks(); void executeCleartraps(); void executeClearwatches(); + void executeCls(); void executeColortest(); void executeD(); void executeDefine(); void executeDelbreakif(); + void executeDelfunction(); void executeDelwatch(); void executeDisasm(); void executeDump(); @@ -152,14 +155,14 @@ class DebuggerParser void executeFunction(); void executeHelp(); void executeListbreaks(); + void executeListfunctions(); void executeListtraps(); - void executeListwatches(); void executeLoadstate(); void executeLoadsym(); void executeN(); void executePc(); void executePrint(); - void executeRam(); // also implements 'poke' command + void executeRam(); void executeReset(); void executeRewind(); void executeRiot(); diff --git a/src/debugger/Expression.hxx b/src/debugger/Expression.hxx index 0dfad7607..cd536a3d5 100644 --- a/src/debugger/Expression.hxx +++ b/src/debugger/Expression.hxx @@ -40,7 +40,7 @@ class Expression Expression(Expression* lhs, Expression* rhs); virtual ~Expression(); - virtual uInt16 evaluate() = 0; + virtual uInt16 evaluate() const = 0; protected: Expression* myLHS; diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 74a1f5768..4b55be1a0 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -59,14 +59,8 @@ PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, // Calculate depending values _lineWidth = (_w - kScrollBarWidth - 2) / _kConsoleCharWidth; _linesPerPage = (_h - 2) / _kConsoleLineHeight; - - memset(_buffer, 0, kBufferSize * sizeof(int)); _linesInBuffer = kBufferSize / _lineWidth; - _currentPos = 0; - _scrollLine = _linesPerPage - 1; - _firstLineInBuffer = 0; - // Add scrollbar _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, kScrollBarWidth, _h); _scrollBar->setTarget(this); @@ -74,14 +68,7 @@ PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, // Init colors _inverse = false; - // Init History - _historyIndex = 0; - _historyLine = 0; - _historySize = 0; - for (int i = 0; i < kHistorySize; i++) - _history[i][0] = '\0'; - - _promptStartPos = _promptEndPos = -1; + clearScreen(); addFocusWidget(this); } @@ -908,3 +895,23 @@ string PromptWidget::getCompletionPrefix(const StringList& completions, string p return prefix; } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PromptWidget::clearScreen() +{ + // Initialize start position and history + _currentPos = 0; + _scrollLine = _linesPerPage - 1; + _firstLineInBuffer = 0; + _promptStartPos = _promptEndPos = -1; + memset(_buffer, 0, kBufferSize * sizeof(int)); + + _historyIndex = 0; + _historyLine = 0; + _historySize = 0; + for (int i = 0; i < kHistorySize; i++) + _history[i][0] = '\0'; + + if(!_firstTime) + updateScrollBuffer(); +} diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx index 8639ebedd..09873cffc 100644 --- a/src/debugger/gui/PromptWidget.hxx +++ b/src/debugger/gui/PromptWidget.hxx @@ -46,6 +46,9 @@ class PromptWidget : public Widget, public CommandSender void printPrompt(); bool saveBuffer(string& filename); + // Clear screen and erase all history + void clearScreen(); + protected: inline int &buffer(int idx) { return _buffer[idx % kBufferSize]; }