trapifs implemented (and fixed mirrors)

wrong port display for swapped ports fixed
error due wrong argument number now with example display
label display in status line added
This commit is contained in:
thrust26 2017-10-09 23:15:40 +02:00
parent 07d2797c62
commit 3fddc03ff6
8 changed files with 181 additions and 123 deletions

View File

@ -603,6 +603,15 @@ bool Debugger::addFunction(const string& name, const string& definition,
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Debugger::isBuiltinFunction(const string& name)
{
for(int i = 0; builtin_functions[i][0] != 0; ++i)
if(name == builtin_functions[i][0])
return true;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Debugger::delFunction(const string& name) bool Debugger::delFunction(const string& name)
{ {
@ -611,8 +620,7 @@ bool Debugger::delFunction(const string& name)
return false; return false;
// We never want to delete built-in functions // We never want to delete built-in functions
for(int i = 0; builtin_functions[i][0] != 0; ++i) if (isBuiltinFunction(name))
if(name == builtin_functions[i][0])
return false; return false;
myFunctions.erase(name); myFunctions.erase(name);

View File

@ -99,6 +99,7 @@ class Debugger : public DialogContainer
bool addFunction(const string& name, const string& def, bool addFunction(const string& name, const string& def,
Expression* exp, bool builtin = false); Expression* exp, bool builtin = false);
bool isBuiltinFunction(const string& name);
bool delFunction(const string& name); bool delFunction(const string& name);
const Expression& getFunction(const string& name) const; const Expression& getFunction(const string& name) const;

View File

@ -110,7 +110,10 @@ string DebuggerParser::run(const string& command)
if(BSPF::equalsIgnoreCase(verb, commands[i].cmdString)) if(BSPF::equalsIgnoreCase(verb, commands[i].cmdString))
{ {
if(validateArgs(i)) if(validateArgs(i))
{
myCommand = i;
commands[i].executor(this); commands[i].executor(this);
}
if(commands[i].refreshRequired) if(commands[i].refreshRequired)
debugger.myBaseDialog->loadConfig(); debugger.myBaseDialog->loadConfig();
@ -151,6 +154,16 @@ string DebuggerParser::exec(const FilesystemNode& file)
return red("script file \'" + file.getShortPath() + "\' not found"); return red("script file \'" + file.getShortPath() + "\' not found");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::outputCommandError(const string& errorMsg, int command)
{
string example = commands[command].extendedDesc.substr(commands[command].extendedDesc.find("Example:"));
commandResult << red(errorMsg);
if(!example.empty())
commandResult << endl << example;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Completion-related stuff: // Completion-related stuff:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -396,7 +409,8 @@ bool DebuggerParser::validateArgs(int cmd)
{ {
if(required) if(required)
{ {
commandResult.str(red("missing required argument(s)")); commandResult.str();
outputCommandError("missing required argument(s)", cmd);
return false; // needed args. didn't get 'em. return false; // needed args. didn't get 'em.
} }
else else
@ -492,12 +506,14 @@ cerr << "curCount = " << curCount << endl
if(curCount < argRequiredCount) if(curCount < argRequiredCount)
{ {
commandResult.str(red("missing required argument(s)")); commandResult.str();
outputCommandError("missing required argument(s)", cmd);
return false; return false;
} }
else if(argCount > curCount) else if(argCount > curCount)
{ {
commandResult.str(red("too many arguments")); commandResult.str();
outputCommandError("too many arguments", cmd);
return false; return false;
} }
@ -542,6 +558,39 @@ string DebuggerParser::eval()
return buf.str(); return buf.str();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::listTraps(bool listCond)
{
StringList names = debugger.cpuDebug().m6502().getCondTrapNames();
commandResult << (listCond ? "trapifs:" : "traps:") << endl;
for(uInt32 i = 0; i < names.size(); i++)
{
bool hasCond = names[i] != "";
if(hasCond == listCond)
{
commandResult << Base::toString(i) << ": ";
if(myTraps[i]->read && myTraps[i]->write)
commandResult << "read|write";
else if(myTraps[i]->read)
commandResult << "read ";
else if(myTraps[i]->write)
commandResult << " write";
else
commandResult << "none";
if(hasCond)
commandResult << " " << names[i];
commandResult << " " << debugger.cartDebug().getLabel(myTraps[i]->begin, true, 4);
if(myTraps[i]->begin != myTraps[i]->end)
commandResult << " " << debugger.cartDebug().getLabel(myTraps[i]->end, true, 4);
commandResult << trapStatus(*myTraps[i]);
commandResult << " + mirrors";
if(i != (names.size() - 1)) commandResult << endl;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string DebuggerParser::trapStatus(const Trap& trap) string DebuggerParser::trapStatus(const Trap& trap)
{ {
@ -585,33 +634,41 @@ string DebuggerParser::saveScriptFile(string file)
FunctionDefMap funcs = debugger.getFunctionDefMap(); FunctionDefMap funcs = debugger.getFunctionDefMap();
for(const auto& f: funcs) for(const auto& f: funcs)
out << "function " << f.first << " { " << f.second << " }" << endl; if (!debugger.isBuiltinFunction(f.first))
out << "function " << f.first << " {" << f.second << "}" << endl;
for(const auto& w: myWatches) for(const auto& w: myWatches)
out << "watch " << w << endl; out << "watch " << w << endl;
for(uInt32 i = 0; i < 0x10000; ++i) for(uInt32 i = 0; i < 0x10000; ++i)
if(debugger.breakPoint(i)) if(debugger.breakPoint(i))
out << "break #" << i << endl; out << "break " << Base::toString(i) << endl;
// TODO: new trapif
for(uInt32 i = 0; i < 0x10000; ++i)
{
bool r = debugger.readTrap(i);
bool w = debugger.writeTrap(i);
if(r && w)
out << "trap #" << i << endl;
else if(r)
out << "trapread #" << i << endl;
else if(w)
out << "trapwrite #" << i << endl;
}
StringList conds = debugger.cpuDebug().m6502().getCondBreakNames(); StringList conds = debugger.cpuDebug().m6502().getCondBreakNames();
for(const auto& cond: conds) for(const auto& cond : conds)
out << "breakif {" << cond << "}" << endl; out << "breakif {" << cond << "}" << endl;
StringList names = debugger.cpuDebug().m6502().getCondTrapNames();
for(uInt32 i = 0; i < myTraps.size(); ++i)
{
bool read = myTraps[i]->read;
bool write = myTraps[i]->write;
bool hasCond = names[i] != "";
if(read && write)
out << "trap";
else if(read)
out << "trapread";
else if(write)
out << "trapwrite";
if(hasCond)
out << "if {" << names[i] << "}";
out << " " << Base::toString(myTraps[i]->begin);
if(myTraps[i]->begin != myTraps[i]->end)
out << " " << Base::toString(myTraps[i]->end);
out << endl;
}
return "saved " + node.getShortPath() + " OK"; return "saved " + node.getShortPath() + " OK";
} }
@ -710,7 +767,7 @@ void DebuggerParser::executeCheat()
#ifdef CHEATCODE_SUPPORT #ifdef CHEATCODE_SUPPORT
if(argCount == 0) if(argCount == 0)
{ {
commandResult << red("Missing cheat code"); outputCommandError("missing cheat code", myCommand);
return; return;
} }
@ -720,7 +777,7 @@ void DebuggerParser::executeCheat()
if(debugger.myOSystem.cheat().add("DBG", cheat)) if(debugger.myOSystem.cheat().add("DBG", cheat))
commandResult << "Cheat code " << cheat << " enabled" << endl; commandResult << "Cheat code " << cheat << " enabled" << endl;
else else
commandResult << red("Invalid cheat code ") << cheat << endl; commandResult << red("invalid cheat code ") << cheat << endl;
} }
#else #else
commandResult << red("Cheat support not enabled\n"); commandResult << red("Cheat support not enabled\n");
@ -778,12 +835,12 @@ void DebuggerParser::executeCode()
{ {
if(argCount != 2) if(argCount != 2)
{ {
commandResult << red("Specify start and end of range only"); outputCommandError("specify start and end of range only", myCommand);
return; return;
} }
else if(args[1] < args[0]) else if(args[1] < args[0])
{ {
commandResult << red("Start address must be <= end address"); commandResult << red("start address must be <= end address");
return; return;
} }
@ -819,12 +876,12 @@ void DebuggerParser::executeData()
{ {
if(argCount != 2) if(argCount != 2)
{ {
commandResult << red("Specify start and end of range only"); outputCommandError("specify start and end of range only", myCommand);
return; return;
} }
else if(args[1] < args[0]) else if(args[1] < args[0])
{ {
commandResult << red("Start address must be <= end address"); commandResult << red("start address must be <= end address");
return; return;
} }
@ -914,7 +971,7 @@ void DebuggerParser::executeDisasm()
start = args[0]; start = args[0];
lines = args[1]; lines = args[1];
} else { } else {
commandResult << "wrong number of arguments"; outputCommandError("wrong number of arguments", myCommand);
return; return;
} }
@ -944,7 +1001,7 @@ void DebuggerParser::executeDump()
// Error checking // Error checking
if(argCount > 1 && args[1] < args[0]) if(argCount > 1 && args[1] < args[0])
{ {
commandResult << red("Start address must be <= end address"); commandResult << red("start address must be <= end address");
return; return;
} }
@ -954,7 +1011,7 @@ void DebuggerParser::executeDump()
dump(args[0], args[1]); dump(args[0], args[1]);
else else
{ {
commandResult << "wrong number of arguments"; outputCommandError("wrong number of arguments", myCommand);
return; return;
} }
} }
@ -1015,12 +1072,12 @@ void DebuggerParser::executeGfx()
{ {
if(argCount != 2) if(argCount != 2)
{ {
commandResult << red("Specify start and end of range only"); outputCommandError("specify start and end of range only", myCommand);
return; return;
} }
else if(args[1] < args[0]) else if(args[1] < args[0])
{ {
commandResult << red("Start address must be <= end address"); commandResult << red("start address must be <= end address");
return; return;
} }
@ -1100,23 +1157,18 @@ void DebuggerParser::executeListbreaks()
if(debugger.breakPoints().isSet(i)) if(debugger.breakPoints().isSet(i))
{ {
buf << debugger.cartDebug().getLabel(i, true, 4) << " "; buf << debugger.cartDebug().getLabel(i, true, 4) << " ";
if(! (++count % 8) ) buf << "\n"; if(! (++count % 8) ) buf << endl;
} }
} }
/*
if(count) if(count)
return ret; commandResult << "breaks:" << endl << buf.str();
else
return "no breakpoints set";
*/
if(count)
commandResult << "breaks:\n" << buf.str();
StringList conds = debugger.cpuDebug().m6502().getCondBreakNames(); StringList conds = debugger.cpuDebug().m6502().getCondBreakNames();
if(conds.size() > 0) if(conds.size() > 0)
{ {
commandResult << "\nbreakifs:\n"; if(count)
commandResult << endl;
commandResult << "breakifs:" << endl;
for(uInt32 i = 0; i < conds.size(); i++) for(uInt32 i = 0; i < conds.size(); i++)
{ {
commandResult << Base::toString(i) << ": " << conds[i]; commandResult << Base::toString(i) << ": " << conds[i];
@ -1167,27 +1219,17 @@ void DebuggerParser::executeListtraps()
if (names.size() > 0) if (names.size() > 0)
{ {
bool trapFound = false, trapifFound = false;
for(uInt32 i = 0; i < names.size(); i++) for(uInt32 i = 0; i < names.size(); i++)
{ if(names[i] == "")
commandResult << Base::toString(i) << ": "; trapFound = true;
if(myTraps[i]->read && myTraps[i]->write)
commandResult << "read|write";
else if(myTraps[i]->read)
commandResult << "read ";
else if(myTraps[i]->write)
commandResult << " write";
else else
commandResult << "none"; trapifFound = true;
commandResult << " " << names[i]; if(trapFound)
commandResult << " " << Base::toString(myTraps[i]->begin); listTraps(false);
if (myTraps[i]->begin != myTraps[i]->end) if(trapifFound)
commandResult << " " << Base::toString(myTraps[i]->end); listTraps(true);
commandResult << trapStatus(*myTraps[i]);
commandResult << " + mirrors";
if(i != (names.size() - 1)) commandResult << endl;
}
} }
else else
commandResult << "no traps set"; commandResult << "no traps set";
@ -1240,12 +1282,12 @@ void DebuggerParser::executePGfx()
{ {
if(argCount != 2) if(argCount != 2)
{ {
commandResult << red("Specify start and end of range only"); outputCommandError("specify start and end of range only", myCommand);
return; return;
} }
else if(args[1] < args[0]) else if(args[1] < args[0])
{ {
commandResult << red("Start address must be <= end address"); commandResult << red("start address must be <= end address");
return; return;
} }
@ -1332,12 +1374,12 @@ void DebuggerParser::executeRow()
{ {
if(argCount != 2) if(argCount != 2)
{ {
commandResult << red("Specify start and end of range only"); outputCommandError("specify start and end of range only", myCommand);
return; return;
} }
else if(args[1] < args[0]) else if(args[1] < args[0])
{ {
commandResult << red("Start address must be <= end address"); commandResult << red("start address must be <= end address");
return; return;
} }
@ -1575,69 +1617,68 @@ void DebuggerParser::executeTrapwriteif()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Wrapper function for trap(if)s // Wrapper function for trap(if)s
void DebuggerParser::executeTraps(bool read, bool write, string command, bool hasCond) void DebuggerParser::executeTraps(bool read, bool write, const string& command, bool hasCond)
{ {
if(hasCond)
{
if(argCount < 1 || argCount > 3)
{
commandResult << red("Command takes one to three arguments");
return;
}
}
else
{
if(argCount > 2)
{
commandResult << red("Command takes one or two arguments");
return;
}
}
int ofs = hasCond ? 1 : 0; int ofs = hasCond ? 1 : 0;
uInt32 begin = args[ofs]; uInt32 begin = args[ofs];
uInt32 end = argCount == ofs + 2 ? args[ofs + 1] : begin; uInt32 end = argCount == 2 + ofs ? args[1 + ofs] : begin;
// mirrors
if(argCount < 1 + ofs)
{
outputCommandError("missing required argument(s)", myCommand);
return;
}
if(argCount > 2 + ofs)
{
outputCommandError("too many arguments", myCommand);
return;
}
if(begin > 0xFFFF || end > 0xFFFF)
{
commandResult << red("invalid word argument(s) (must be 0-$ffff)");
return;
}
if(begin > end)
{
commandResult << red("start address must be <= end address");
return;
}
// base addresses of mirrors
uInt32 beginRead = debugger.getBaseAddress(begin, true); uInt32 beginRead = debugger.getBaseAddress(begin, true);
uInt32 endRead = debugger.getBaseAddress(end, true); uInt32 endRead = debugger.getBaseAddress(end, true);
uInt32 beginWrite = debugger.getBaseAddress(begin, false); uInt32 beginWrite = debugger.getBaseAddress(begin, false);
uInt32 endWrite = debugger.getBaseAddress(end, false); uInt32 endWrite = debugger.getBaseAddress(end, false);
stringstream conditionBuf;
if(begin > 0xFFFF || end > 0xFFFF || begin > end)
{
commandResult << red("One or more addresses are invalid");
return;
}
// parenthesize provided and address range condition(s) (begin) // parenthesize provided and address range condition(s) (begin)
stringstream parserBuf, displayBuf;
if(hasCond) if(hasCond)
parserBuf << "(" << argStrings[0] << ")&&("; conditionBuf << "(" << argStrings[0] << ")&&(";
// add address range condition(s) to provided condition // add address range condition(s) to provided condition
if(read) if(read)
{ {
if(beginRead != endRead) if(beginRead != endRead)
parserBuf << "__lastread>=" << Base::toString(beginRead) << "&&__lastread<=" << Base::toString(endRead); conditionBuf << "__lastread>=" << Base::toString(beginRead) << "&&__lastread<=" << Base::toString(endRead);
else else
parserBuf << "__lastread==" << Base::toString(beginRead); conditionBuf << "__lastread==" << Base::toString(beginRead);
} }
if(read && write) if(read && write)
parserBuf << "||"; conditionBuf << "||";
if(write) if(write)
{ {
if(beginWrite != endWrite) if(beginWrite != endWrite)
parserBuf << "__lastwrite>=" << Base::toString(beginWrite) << "&&__lastwrite<=" << Base::toString(endWrite); conditionBuf << "__lastwrite>=" << Base::toString(beginWrite) << "&&__lastwrite<=" << Base::toString(endWrite);
else else
parserBuf << "__lastwrite==" << Base::toString(beginWrite); conditionBuf << "__lastwrite==" << Base::toString(beginWrite);
} }
// parenthesize provided condition (end) // parenthesize provided condition (end)
if(hasCond) if(hasCond)
parserBuf << ")"; conditionBuf << ")";
const string parserCondition = parserBuf.str(); const string condition = conditionBuf.str();
int res = YaccParser::parse(parserCondition.c_str()); int res = YaccParser::parse(condition.c_str());
if(res == 0) if(res == 0)
{ {
// duplicates will remove each other // duplicates will remove each other
@ -1646,7 +1687,7 @@ void DebuggerParser::executeTraps(bool read, bool write, string command, bool ha
{ {
if(myTraps[i]->begin == begin && myTraps[i]->end == end && if(myTraps[i]->begin == begin && myTraps[i]->end == end &&
myTraps[i]->read == read && myTraps[i]->write == write && myTraps[i]->read == read && myTraps[i]->write == write &&
myTraps[i]->condition == parserCondition) myTraps[i]->condition == condition)
{ {
if(debugger.cpuDebug().m6502().delCondTrap(i)) if(debugger.cpuDebug().m6502().delCondTrap(i))
{ {
@ -1663,11 +1704,11 @@ void DebuggerParser::executeTraps(bool read, bool write, string command, bool ha
if(add) if(add)
{ {
uInt32 ret = debugger.cpuDebug().m6502().addCondTrap( uInt32 ret = debugger.cpuDebug().m6502().addCondTrap(
YaccParser::getResult(), hasCond ? argStrings[0] : " "); YaccParser::getResult(), hasCond ? argStrings[0] : "");
commandResult << "Added trap " << Base::toString(ret); commandResult << "Added trap " << Base::toString(ret);
// @sa666666: please check this: // @sa666666: please check this:
myTraps.emplace_back(new Trap{ read, write, begin, end, parserCondition }); myTraps.emplace_back(new Trap{ read, write, begin, end, condition });
} }
for(uInt32 addr = begin; addr <= end; ++addr) for(uInt32 addr = begin; addr <= end; ++addr)
@ -2482,7 +2523,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
"trapif", "trapif",
"On <condition> trap R/W access to address(es) xx [yy]", "On <condition> trap R/W access to address(es) xx [yy]",
"Set a conditional R/W trap on the given address(es) and all mirrors\nCondition can include multiple items.\n" "Set a conditional R/W trap on the given address(es) and all mirrors\nCondition can include multiple items.\n"
"Example: trapif _scan>100 GRP0, trapif _bank==1 f000 f100", "Example: trapif _scan>#100 GRP0, trapif _bank==1 f000 f100",
true, true,
false, false,
{ kARG_WORD, kARG_MULTI_BYTE }, { kARG_WORD, kARG_MULTI_BYTE },
@ -2504,7 +2545,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
"trapreadif", "trapreadif",
"On <condition> trap read access to address(es) xx [yy]", "On <condition> trap read access to address(es) xx [yy]",
"Set a conditional read trap on the given address(es) and all mirrors\nCondition can include multiple items.\n" "Set a conditional read trap on the given address(es) and all mirrors\nCondition can include multiple items.\n"
"Example: trapreadif _scan>100 GRP0, trapreadif _bank==1 f000 f100", "Example: trapreadif _scan>#100 GRP0, trapreadif _bank==1 f000 f100",
true, true,
false, false,
{ kARG_WORD, kARG_MULTI_BYTE }, { kARG_WORD, kARG_MULTI_BYTE },
@ -2526,7 +2567,7 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = {
"trapwriteif", "trapwriteif",
"On <condition> trap write access to address(es) xx [yy]", "On <condition> trap write access to address(es) xx [yy]",
"Set a conditional write trap on the given address(es) and all mirrors\nCondition can include multiple items.\n" "Set a conditional write trap on the given address(es) and all mirrors\nCondition can include multiple items.\n"
"Example: trapwriteif _scan>100 GRP0, trapwriteif _bank==1 f000 f100", "Example: trapwriteif _scan>#100 GRP0, trapwriteif _bank==1 f000 f100",
true, true,
false, false,
{ kARG_WORD, kARG_MULTI_BYTE }, { kARG_WORD, kARG_MULTI_BYTE },

View File

@ -118,6 +118,8 @@ class DebuggerParser
// The results of the currently running command // The results of the currently running command
ostringstream commandResult; ostringstream commandResult;
// currently execute command id
int myCommand;
// Arguments in 'int' and 'string' format for the currently running command // Arguments in 'int' and 'string' format for the currently running command
IntArray args; IntArray args;
StringList argStrings; StringList argStrings;
@ -125,13 +127,14 @@ class DebuggerParser
StringList myWatches; StringList myWatches;
// Keep track of traps (read and/or write) // Keep track of traps (read and/or write)
vector<unique_ptr<Trap>> myTraps; vector<unique_ptr<Trap>> myTraps;
/*std::set<uInt32> myTraps; void listTraps(bool listCond);
std::vector<uInt32> myTrapIfs;*/
string trapStatus(const Trap& trap); string trapStatus(const Trap& trap);
// output the error with the example provided for the command
void outputCommandError(const string& errorMsg, int command);
// List of available command methods // List of available command methods
void executeA(); void executeA();
void executeBase(); void executeBase();
@ -201,7 +204,7 @@ class DebuggerParser
void executeTrapreadif(); void executeTrapreadif();
void executeTrapwrite(); void executeTrapwrite();
void executeTrapwriteif(); void executeTrapwriteif();
void executeTraps(bool read, bool write, string command, bool cond = false); void executeTraps(bool read, bool write, const string& command, bool cond = false);
void executeTrapRW(uInt32 addr, bool read, bool write, bool add = true); // not exposed by debugger void executeTrapRW(uInt32 addr, bool read, bool write, bool add = true); // not exposed by debugger
void executeType(); void executeType();
void executeUHex(); void executeUHex();

View File

@ -85,7 +85,7 @@ class AtariVox : public SaveKey
*/ */
void reset() override; void reset() override;
string about() const override { return Controller::about() + myAboutString; } string about(bool swappedPorts) const override { return Controller::about(swappedPorts) + myAboutString; }
private: private:
void clockDataIn(bool value); void clockDataIn(bool value);

View File

@ -199,8 +199,9 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
// Finally, add remaining info about the console // Finally, add remaining info about the console
myConsoleInfo.CartName = myProperties.get(Cartridge_Name); myConsoleInfo.CartName = myProperties.get(Cartridge_Name);
myConsoleInfo.CartMD5 = myProperties.get(Cartridge_MD5); myConsoleInfo.CartMD5 = myProperties.get(Cartridge_MD5);
myConsoleInfo.Control0 = myLeftControl->about(); bool swappedPorts = properties().get(Console_SwapPorts) == "YES";
myConsoleInfo.Control1 = myRightControl->about(); myConsoleInfo.Control0 = myLeftControl->about(swappedPorts);
myConsoleInfo.Control1 = myRightControl->about(swappedPorts);
myConsoleInfo.BankSwitch = myCart->about(); myConsoleInfo.BankSwitch = myCart->about();
myCart->setRomName(myConsoleInfo.CartName); myCart->setRomName(myConsoleInfo.CartName);

View File

@ -208,8 +208,10 @@ class Controller : public Serializable
/** /**
Returns more detailed information about this controller. Returns more detailed information about this controller.
*/ */
virtual string about() const virtual string about(bool swappedPorts) const
{ return name() + " in " + (myJack == Left ? "left port" : "right port"); } {
return name() + " in " + (myJack == Left ^ swappedPorts ? "left port" : "right port");
}
/** /**
The following two functions are used by the debugger to set The following two functions are used by the debugger to set

View File

@ -116,8 +116,10 @@ void RomInfoWidget::parseProperties()
myRomInfo.push_back("Model: " + myProperties.get(Cartridge_ModelNo)); myRomInfo.push_back("Model: " + myProperties.get(Cartridge_ModelNo));
myRomInfo.push_back("Rarity: " + myProperties.get(Cartridge_Rarity)); myRomInfo.push_back("Rarity: " + myProperties.get(Cartridge_Rarity));
myRomInfo.push_back("Note: " + myProperties.get(Cartridge_Note)); myRomInfo.push_back("Note: " + myProperties.get(Cartridge_Note));
myRomInfo.push_back("Controllers: " + myProperties.get(Controller_Left) + bool swappedPorts = myProperties.get(Console_SwapPorts) == "YES";
" (left), " + myProperties.get(Controller_Right) + " (right)"); myRomInfo.push_back("Controllers: " + (!swappedPorts
? myProperties.get(Controller_Left) + " (left), " + myProperties.get(Controller_Right) + " (right)"
: myProperties.get(Controller_Right) + " (left), " + myProperties.get(Controller_Left) + " (right)"));
#if 0 #if 0
myRomInfo.push_back("YStart/Height: " + myProperties.get(Display_YStart) + myRomInfo.push_back("YStart/Height: " + myProperties.get(Display_YStart) +
" " + myProperties.get(Display_Height)); " " + myProperties.get(Display_Height));