mirror of https://github.com/stella-emu/stella.git
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:
parent
5378b2c971
commit
cb6232cc25
|
@ -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++)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue