Converted CartDebug to use new FSNode I/O. This means we can load from sym/list files stored in a ZIP file.

This commit is contained in:
Stephen Anthony 2020-07-18 15:26:42 -02:30
parent 25913b791e
commit f9194bbfb4
3 changed files with 102 additions and 94 deletions

View File

@ -734,19 +734,20 @@ string CartDebug::loadListFile()
// The default naming/location for list files is the ROM dir based on the // The default naming/location for list files is the ROM dir based on the
// actual ROM filename // actual ROM filename
if(myListFile == "")
{
FilesystemNode lst(myOSystem.romFile().getPathWithExt(".lst")); FilesystemNode lst(myOSystem.romFile().getPathWithExt(".lst"));
if(lst.isFile() && lst.isReadable()) if(!lst.isReadable())
myListFile = lst.getPath();
else
return DebuggerParser::red("list file \'" + lst.getShortPath() + "\' not found"); return DebuggerParser::red("list file \'" + lst.getShortPath() + "\' not found");
}
FilesystemNode node(myListFile); stringstream in;
ifstream in(node.getPath()); try
if(!in.is_open()) {
return DebuggerParser::red("list file '" + node.getShortPath() + "' not readable"); if(lst.read(in) == 0)
return DebuggerParser::red("list file '" + lst.getShortPath() + "' not readable");
}
catch(...)
{
return DebuggerParser::red("list file '" + lst.getShortPath() + "' not readable");
}
while(!in.eof()) while(!in.eof())
{ {
@ -785,7 +786,7 @@ string CartDebug::loadListFile()
} }
myDebugger.rom().invalidate(); myDebugger.rom().invalidate();
return "list file '" + node.getShortPath() + "' loaded OK"; return "list file '" + lst.getShortPath() + "' loaded OK";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -794,23 +795,24 @@ string CartDebug::loadSymbolFile()
// The default naming/location for symbol files is the ROM dir based on the // The default naming/location for symbol files is the ROM dir based on the
// actual ROM filename // actual ROM filename
if(mySymbolFile == "")
{
FilesystemNode sym(myOSystem.romFile().getPathWithExt(".sym")); FilesystemNode sym(myOSystem.romFile().getPathWithExt(".sym"));
if(sym.isFile() && sym.isReadable()) if(!sym.isReadable())
mySymbolFile = sym.getPath();
else
return DebuggerParser::red("symbol file \'" + sym.getShortPath() + "\' not found"); return DebuggerParser::red("symbol file \'" + sym.getShortPath() + "\' not found");
}
FilesystemNode node(mySymbolFile);
ifstream in(node.getPath());
if(!in.is_open())
return DebuggerParser::red("symbol file '" + node.getShortPath() + "' not readable");
myUserAddresses.clear(); myUserAddresses.clear();
myUserLabels.clear(); myUserLabels.clear();
stringstream in;
try
{
if(sym.read(in) == 0)
return DebuggerParser::red("symbol file '" + sym.getShortPath() + "' not readable");
}
catch(...)
{
return DebuggerParser::red("symbol file '" + sym.getShortPath() + "' not readable");
}
while(!in.eof()) while(!in.eof())
{ {
string label; string label;
@ -845,7 +847,7 @@ string CartDebug::loadSymbolFile()
} }
myDebugger.rom().invalidate(); myDebugger.rom().invalidate();
return "symbol file '" + node.getShortPath() + "' loaded OK"; return "symbol file '" + sym.getShortPath() + "' loaded OK";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -854,20 +856,21 @@ string CartDebug::loadConfigFile()
// The default naming/location for config files is the CFG dir and based // The default naming/location for config files is the CFG dir and based
// on the actual ROM filename // on the actual ROM filename
if(myCfgFile == "")
{
FilesystemNode romNode(myOSystem.romFile().getPathWithExt(".cfg")); FilesystemNode romNode(myOSystem.romFile().getPathWithExt(".cfg"));
FilesystemNode cfg(myOSystem.cfgDir() + romNode.getName()); FilesystemNode cfg(myOSystem.cfgDir() + romNode.getName());
if(cfg.isFile() && cfg.isReadable()) if(!cfg.isReadable())
myCfgFile = cfg.getPath();
else
return DebuggerParser::red("config file \'" + cfg.getShortPath() + "\' not found"); return DebuggerParser::red("config file \'" + cfg.getShortPath() + "\' not found");
}
FilesystemNode node(myCfgFile); stringstream in;
ifstream in(node.getPath()); try
if(!in.is_open()) {
return "Unable to load directives from " + node.getPath(); if(cfg.read(in) == 0)
return "Unable to load directives from " + cfg.getPath();
}
catch(...)
{
return "Unable to load directives from " + cfg.getPath();
}
// Erase all previous directives // Erase all previous directives
for(auto& bi: myBankInfo) for(auto& bi: myBankInfo)
@ -965,7 +968,7 @@ string CartDebug::loadConfigFile()
stringstream retVal; stringstream retVal;
if(myConsole.cartridge().romBankCount() > 1) if(myConsole.cartridge().romBankCount() > 1)
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n"); retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
retVal << "config file '" << node.getShortPath() << "' loaded OK"; retVal << "config file '" << cfg.getShortPath() << "' loaded OK";
return retVal.str(); return retVal.str();
} }
@ -976,25 +979,11 @@ string CartDebug::saveConfigFile()
// The default naming/location for config files is the CFG dir and based // The default naming/location for config files is the CFG dir and based
// on the actual ROM filename // on the actual ROM filename
if(myCfgFile == "")
{
FilesystemNode romNode(myOSystem.romFile().getPathWithExt(".cfg"));
FilesystemNode cfg(myOSystem.cfgDir() + romNode.getName());
if(cfg.getParent().isWritable())
myCfgFile = cfg.getPath();
else
return DebuggerParser::red("config file \'" + cfg.getShortPath() + "\' not writable");
}
const string& name = myConsole.properties().get(PropType::Cart_Name); const string& name = myConsole.properties().get(PropType::Cart_Name);
const string& md5 = myConsole.properties().get(PropType::Cart_MD5); const string& md5 = myConsole.properties().get(PropType::Cart_MD5);
FilesystemNode cfg(myCfgFile);
ofstream out(cfg.getPath());
if(!out.is_open())
return "Unable to save directives to " + cfg.getShortPath();
// Store all bank information // Store all bank information
stringstream out;
out << "// Stella.pro: \"" << name << "\"" << endl out << "// Stella.pro: \"" << name << "\"" << endl
<< "// MD5: " << md5 << endl << "// MD5: " << md5 << endl
<< endl; << endl;
@ -1005,9 +994,25 @@ string CartDebug::saveConfigFile()
} }
stringstream retVal; stringstream retVal;
try
{
FilesystemNode romNode(myOSystem.romFile().getPathWithExt(".cfg"));
FilesystemNode cfg(myOSystem.cfgDir() + romNode.getName());
if(!cfg.getParent().isWritable())
return DebuggerParser::red("config file \'" + cfg.getShortPath() + "\' not writable");
size_t size = cfg.write(out);
if(size == 0)
return "Unable to save directives to " + cfg.getShortPath();
if(myConsole.cartridge().romBankCount() > 1) if(myConsole.cartridge().romBankCount() > 1)
retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n"); retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n");
retVal << "config file '" << cfg.getShortPath() << "' saved OK"; retVal << "config file '" << cfg.getShortPath() << "' saved OK";
}
catch(const runtime_error& e)
{
retVal << e.what();
}
return retVal.str(); return retVal.str();
} }
@ -1033,19 +1038,6 @@ string CartDebug::saveDisassembly()
bool isNTSC = myConsole.timing() == ConsoleTiming::ntsc; bool isNTSC = myConsole.timing() == ConsoleTiming::ntsc;
bool isPAL = myConsole.timing() == ConsoleTiming::pal; bool isPAL = myConsole.timing() == ConsoleTiming::pal;
if(myDisasmFile == "")
{
const string& propsname =
myConsole.properties().get(PropType::Cart_Name) + ".asm";
myDisasmFile = FilesystemNode(myOSystem.defaultSaveDir() + propsname).getPath();
}
FilesystemNode node(myDisasmFile);
ofstream out(node.getPath());
if(!out.is_open())
return "Unable to save disassembly to " + node.getShortPath();
#define ALIGN(x) setfill(' ') << left << setw(x) #define ALIGN(x) setfill(' ') << left << setw(x)
// We can't print the header to the disassembly until it's actually // We can't print the header to the disassembly until it's actually
@ -1094,7 +1086,6 @@ string CartDebug::saveDisassembly()
buf << " / 0.." << romBankCount - 1; buf << " / 0.." << romBankCount - 1;
buf << "\n;***********************************************************\n\n"; buf << "\n;***********************************************************\n\n";
// Disassemble bank // Disassemble bank
disasm.list.clear(); disasm.list.clear();
DiStella distella(*this, disasm.list, info, settings, DiStella distella(*this, disasm.list, info, settings,
@ -1183,6 +1174,7 @@ string CartDebug::saveDisassembly()
// Some boilerplate, similar to what DiStella adds // Some boilerplate, similar to what DiStella adds
auto timeinfo = BSPF::localTime(); auto timeinfo = BSPF::localTime();
stringstream out;
out << "; Disassembly of " << myOSystem.romFile().getShortPath() << "\n" out << "; Disassembly of " << myOSystem.romFile().getShortPath() << "\n"
<< "; Disassembled " << std::put_time(&timeinfo, "%c\n") << "; Disassembled " << std::put_time(&timeinfo, "%c\n")
<< "; Using Stella " << STELLA_VERSION << "\n;\n" << "; Using Stella " << STELLA_VERSION << "\n;\n"
@ -1335,9 +1327,24 @@ string CartDebug::saveDisassembly()
out << buf.str(); out << buf.str();
stringstream retVal; stringstream retVal;
try
{
const string& propsname =
myConsole.properties().get(PropType::Cart_Name) + ".asm";
FilesystemNode node(myOSystem.defaultSaveDir() + propsname);
size_t size = node.write(out);
if(size == 0)
return "Unable to save disassembly to " + node.getShortPath();
if(myConsole.cartridge().romBankCount() > 1) if(myConsole.cartridge().romBankCount() > 1)
retVal << DebuggerParser::red("disassembly for multi-bank ROM not fully supported\n"); retVal << DebuggerParser::red("disassembly for multi-bank ROM not fully supported\n");
retVal << "saved " << node.getShortPath() << " OK"; retVal << "saved " << node.getShortPath() << " OK";
}
catch(const runtime_error& e)
{
retVal << e.what();
}
return retVal.str(); return retVal.str();
} }
@ -1356,18 +1363,24 @@ string CartDebug::saveRom()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::saveAccessFile() string CartDebug::saveAccessFile()
{ {
const string& rom = myConsole.properties().get(PropType::Cart_Name) + ".csv"; stringstream out;
FilesystemNode node(myOSystem.defaultSaveDir() + rom);
ofstream out(node.getPath());
if(out)
{
out << myConsole.tia().getAccessCounters(); out << myConsole.tia().getAccessCounters();
out << myConsole.riot().getAccessCounters(); out << myConsole.riot().getAccessCounters();
out << myConsole.cartridge().getAccessCounters(); out << myConsole.cartridge().getAccessCounters();
try
{
const string& rom = myConsole.properties().get(PropType::Cart_Name) + ".csv";
FilesystemNode node(myOSystem.defaultSaveDir() + rom);
size_t size = node.write(out);
if(size > 0)
return "saved access counters as " + node.getShortPath(); return "saved access counters as " + node.getShortPath();
} }
else catch(const runtime_error& e)
{
return e.what();
}
return DebuggerParser::red("failed to save access counters file"); return DebuggerParser::red("failed to save access counters file");
} }

View File

@ -342,9 +342,6 @@ class CartDebug : public DebuggerSystem
// The maximum length of all labels currently defined // The maximum length of all labels currently defined
uInt16 myLabelLength{8}; // longest pre-defined label uInt16 myLabelLength{8}; // longest pre-defined label
// Filenames to use for various I/O (currently these are hardcoded)
string myListFile, mySymbolFile, myCfgFile, myDisasmFile;
/// Table of instruction mnemonics /// Table of instruction mnemonics
static std::array<const char*, 16> ourTIAMnemonicR; // read mode static std::array<const char*, 16> ourTIAMnemonicR; // read mode
static std::array<const char*, 64> ourTIAMnemonicW; // write mode static std::array<const char*, 64> ourTIAMnemonicW; // write mode

View File

@ -909,10 +909,7 @@ void PromptWidget::scrollToCurrent()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PromptWidget::saveBuffer(const FilesystemNode& file) bool PromptWidget::saveBuffer(const FilesystemNode& file)
{ {
ofstream out(file.getPath()); stringstream out;
if(!out.is_open())
return false;
for(int start = 0; start < _promptStartPos; start += _lineWidth) for(int start = 0; start < _promptStartPos; start += _lineWidth)
{ {
int end = start + _lineWidth - 1; int end = start + _lineWidth - 1;
@ -930,7 +927,8 @@ bool PromptWidget::saveBuffer(const FilesystemNode& file)
out << endl; out << endl;
} }
return true; try { return file.write(out) > 0; }
catch(...) { return false; }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -