Implemented prefix operators < and > (low byte and high byte) in CLI.

They work just like the ones in DASM: "<1234" is "34" and ">1234" is "12".
They can of course be used with labels, and they can be prefixed with "*"
for dereference.

Implemented binary input in CLI. Like DASM: prefix with "%" to treat
your argument as binary. "%10101010" means hex "ff". Can be stacked with
other prefixes.

Stacking order of prefixes is important. "*" must come first, if present.
Then ">" or "<" if present (but not both!). Then "%" if present. Currently
there's no real error checking for this.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@528 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-06-18 19:00:44 +00:00
parent 5378b2c971
commit cb6232cc25
2 changed files with 67 additions and 23 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: DebuggerParser.cxx,v 1.13 2005-06-18 17:28:18 urchlay Exp $ // $Id: DebuggerParser.cxx,v 1.14 2005-06-18 19:00:44 urchlay Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -61,10 +61,13 @@ int DebuggerParser::conv_hex_digit(char d) {
// Given a string argument that's either a label, // Given a string argument that's either a label,
// hex value, or a register, either dereference the label or convert // hex value, or a register, either dereference the label or convert
// the hex to an int. Returns -1 on error. // the hex to an int. Returns -1 on error.
int DebuggerParser::decipher_arg(string &arg, bool deref) { int DebuggerParser::decipher_arg(string &arg, bool deref, bool lobyte, bool hibyte, bool bin)
{
const char *a = arg.c_str(); const char *a = arg.c_str();
int address; int address;
// cerr << "decipher_arg: arg==" << arg << ", deref==" << deref << ", lobyte==" << lobyte << ", hibyte==" << hibyte << ", bin==" << bin << endl;
// Special cases (registers): // Special cases (registers):
if(arg == "a") address = debugger->getA(); if(arg == "a") address = debugger->getA();
else if(arg == "x") address = debugger->getX(); else if(arg == "x") address = debugger->getX();
@ -75,19 +78,40 @@ int DebuggerParser::decipher_arg(string &arg, bool deref) {
else { // normal addresses: check for label first else { // normal addresses: check for label first
address = debugger->equateList->getAddress(a); address = debugger->equateList->getAddress(a);
// if not label, must be hex. if(address < 0) { // if not label, must be a number
if(address < 0) { if(bin) { // treat as binary
address = 0; address = 0;
while(*a != '\0') { while(*a != '\0') {
int hex = conv_hex_digit(*a++); address <<= 1;
if(hex < 0) switch(*a++) {
return -1; case '1':
address++;
break;
address = (address << 4) + hex; case '0':
break;
default:
return -1;
}
}
} else { // not binary, must be hex.
address = 0;
while(*a != '\0') {
int hex = conv_hex_digit(*a++);
if(hex < 0)
return -1;
address = (address << 4) + hex;
}
} }
} }
} }
if(lobyte && hibyte) return -1;
else if(lobyte) address &= 0xff;
else if(hibyte) address = (address >> 8) & 0xff;
// dereference if we're supposed to: // dereference if we're supposed to:
if(deref) address = debugger->peek(address); if(deref) address = debugger->peek(address);
@ -96,7 +120,7 @@ int DebuggerParser::decipher_arg(string &arg, bool deref) {
bool DebuggerParser::getArgs(const string& command) { bool DebuggerParser::getArgs(const string& command) {
int state = kIN_COMMAND; int state = kIN_COMMAND;
bool deref = false; bool deref = false, lobyte = false, hibyte = false, bin = false;
string curArg = ""; string curArg = "";
argCount = 0; argCount = 0;
verb = ""; verb = "";
@ -123,24 +147,42 @@ bool DebuggerParser::getArgs(const string& command) {
break; break;
case kIN_ARG_START: case kIN_ARG_START:
deref = lobyte = hibyte = false;
curArg = ""; curArg = "";
state = kIN_ARG_CONT; state = kIN_ARG_CONT;
// FIXME: actually use this.
if(*c == '*') { if(*c == '*') {
deref = true; deref = true;
c++; c++;
} else { }
deref = false;
} // FALL THROUGH! if(*c == '<') {
lobyte = true;
c++;
}
if(*c == '>') {
hibyte = true;
c++;
}
if(*c == '%') {
bin = true;
c++;
}
// FALL THROUGH!
case kIN_ARG_CONT: case kIN_ARG_CONT:
if(isalpha(*c) || isdigit(*c) || *c == '_') { if(isalpha(*c) || isdigit(*c) || *c == '_') {
// cerr << (*c) << ", " << "curArg: " << curArg << endl;
curArg += *c++; curArg += *c++;
// cerr << "curArg: " << curArg << endl;
} else { } else {
int a = decipher_arg(curArg, deref); // cerr << "end-of-arg: " << (*c) << ", " << "curArg: " << curArg << endl;
int a = decipher_arg(curArg, deref, lobyte, hibyte, bin);
if(a < 0) if(a < 0)
return false; return false;
args[argCount++] = a; args[argCount++] = a;
curArg = ""; curArg = "";
state = kIN_SPACE; state = kIN_SPACE;
@ -148,15 +190,15 @@ bool DebuggerParser::getArgs(const string& command) {
} }
if(argCount == 10) { if(argCount == kMAX_ARGS) {
cerr << "reached max 10 args" << endl; cerr << "reached max " << kMAX_ARGS << " args" << endl;
return true; return true;
} }
} }
// pick up last arg, if any: // pick up last arg, if any:
if(state == kIN_ARG_CONT || state == kIN_ARG_START) if(state == kIN_ARG_CONT || state == kIN_ARG_START)
if( (args[argCount++] = decipher_arg(curArg, deref)) < 0) if( (args[argCount++] = decipher_arg(curArg, deref, lobyte, hibyte, bin)) < 0)
return false; return false;
// for(int i=0; i<argCount; i++) // for(int i=0; i<argCount; i++)

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.7 2005-06-18 17:28:18 urchlay Exp $ // $Id: DebuggerParser.hxx,v 1.8 2005-06-18 19:00:44 urchlay Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_PARSER_HXX #ifndef DEBUGGER_PARSER_HXX
@ -24,6 +24,8 @@ class Debugger;
#include "bspf.hxx" #include "bspf.hxx"
#include "EquateList.hxx" #include "EquateList.hxx"
#define kMAX_ARGS 100
class DebuggerParser class DebuggerParser
{ {
public: public:
@ -38,7 +40,7 @@ class DebuggerParser
private: private:
int DebuggerParser::conv_hex_digit(char d); int DebuggerParser::conv_hex_digit(char d);
bool DebuggerParser::subStringMatch(const string& needle, const string& haystack); bool DebuggerParser::subStringMatch(const string& needle, const string& haystack);
int decipher_arg(string &arg, bool deref); int decipher_arg(string &arg, bool deref, bool lobyte, bool hibyte, bool bin);
string disasm(); string disasm();
string listBreaks(); string listBreaks();
string eval(); string eval();
@ -48,7 +50,7 @@ class DebuggerParser
bool done; bool done;
string verb; string verb;
int args[10]; // FIXME: should be dynamic int args[kMAX_ARGS+1]; // FIXME: should be dynamic
int argCount; int argCount;
}; };