started working on multi bank support for labels

This commit is contained in:
thrust26 2021-01-21 23:01:00 +01:00
parent b08bbd7f79
commit 3fbaff31c9
8 changed files with 236 additions and 112 deletions

View File

@ -61,6 +61,15 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
}; };
mySystemAddresses = LabelToAddr(sysCmp); mySystemAddresses = LabelToAddr(sysCmp);
// Add compare for system addresses (incl. banks)
const auto lblCmp = [](const BankAddress& a, const BankAddress& b)
{
if(a.bank == b.bank)
return a.addr < b.addr;
return a.bank < b.bank;
};
myUserLabels = AddrToLabel(lblCmp);
// Add Zero-page RAM addresses // Add Zero-page RAM addresses
for(uInt16 i = 0x80; i <= 0xFF; ++i) for(uInt16 i = 0x80; i <= 0xFF; ++i)
{ {
@ -80,18 +89,27 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
BankInfo info; BankInfo info;
info.size = std::min<size_t>(romSize, 4_KB); info.size = std::min<size_t>(romSize, 4_KB);
for(uInt32 i = 0; i < myConsole.cartridge().romBankCount(); ++i) for(uInt32 i = 0; i < myConsole.cartridge().romBankCount(); ++i)
{
info.bank = i;
myBankInfo.push_back(info); myBankInfo.push_back(info);
}
for(uInt32 i = 0; i < myConsole.cartridge().ramBankCount(); ++i) for(uInt32 i = 0; i < myConsole.cartridge().ramBankCount(); ++i)
{
info.bank = i;
myBankInfo.push_back(info); myBankInfo.push_back(info);
}
info.bank = 0;
info.size = 128; // ZP RAM info.size = 128; // ZP RAM
myBankInfo.push_back(info); myBankInfo.push_back(info);
// We know the address for the startup bank right now // We know the address for the startup bank right now
myBankInfo[myConsole.cartridge().startBank()].addressList.push_front( myBankInfo[myConsole.cartridge().startBank()].addressList.push_front(
myDebugger.dpeek(0xfffc)); myDebugger.dpeek(0xfffc));
addLabel("Start", myDebugger.dpeek(0xfffc, Device::DATA)); // TOOD: ::CODE??? addLabel("Start",
BankAddress(myConsole.cartridge().startBank(),
myDebugger.dpeek(0xfffc, Device::DATA))); // TOOD: ::CODE???
// Add system equates // Add system equates
for(uInt16 addr = 0x00; addr <= 0x0F; ++addr) for(uInt16 addr = 0x00; addr <= 0x0F; ++addr)
@ -339,7 +357,8 @@ bool CartDebug::fillDisassemblyList(BankInfo& info, uInt16 search)
myDisassembly.list.clear(); myDisassembly.list.clear();
myDisassembly.fieldwidth = 24 + myLabelLength; myDisassembly.fieldwidth = 24 + myLabelLength;
DiStella distella(*this, myDisassembly.list, info, DiStella::settings, DiStella distella(*this, myDisassembly.list, info, DiStella::settings,
myDisLabels, myDisDirectives, myReserved); myDisLabels, myDisDirectives, myReserved,
myConsole.cartridge().romBankCount());
// Parts of the disassembly will be accessed later in different ways // Parts of the disassembly will be accessed later in different ways
// We place those parts in separate maps, to speed up access // We place those parts in separate maps, to speed up access
@ -569,20 +588,20 @@ int CartDebug::romBankCount() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDebug::addLabel(const string& label, uInt16 address) bool CartDebug::addLabel(const string& label, BankAddress bankAddr)
{ {
// Only user-defined labels can be added or redefined // Only user-defined labels can be added or redefined
switch(addressType(address)) switch(addressType(bankAddr.addr))
{ {
case AddrType::TIA: case AddrType::TIA:
case AddrType::IO: case AddrType::IO:
return false; return false;
default: default:
removeLabel(label); removeLabel(label);
myUserAddresses.emplace(label, address); myUserAddresses.emplace(label, bankAddr);
myUserLabels.emplace(address, label); myUserLabels.emplace(bankAddr, label);
myLabelLength = std::max(myLabelLength, uInt16(label.size())); myLabelLength = std::max(myLabelLength, uInt16(label.size()));
mySystem.setDirtyPage(address); mySystem.setDirtyPage(bankAddr.addr);
return true; return true;
} }
} }
@ -600,7 +619,7 @@ bool CartDebug::removeLabel(const string& label)
myUserLabels.erase(iter2); myUserLabels.erase(iter2);
// Erase the label itself // Erase the label itself
mySystem.setDirtyPage(iter->second); mySystem.setDirtyPage(iter->second.addr);
myUserAddresses.erase(iter); myUserAddresses.erase(iter);
return true; return true;
@ -609,16 +628,16 @@ bool CartDebug::removeLabel(const string& label)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, bool CartDebug::getLabel(ostream& buf, BankAddress bankAddr, bool isRead,
int places, bool isRam) const int places, bool isRam) const
{ {
switch(addressType(addr)) switch(addressType(bankAddr.addr))
{ {
case AddrType::TIA: case AddrType::TIA:
{ {
if(isRead) if(isRead)
{ {
uInt16 a = addr & 0x0F, offset = addr & 0xFFF0; uInt16 a = bankAddr.addr & 0x0F, offset = bankAddr.addr & 0xFFF0;
if(ourTIAMnemonicR[a]) if(ourTIAMnemonicR[a])
{ {
buf << ourTIAMnemonicR[a]; buf << ourTIAMnemonicR[a];
@ -626,11 +645,11 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
buf << "|$" << Base::HEX2 << offset; buf << "|$" << Base::HEX2 << offset;
} }
else else
buf << "$" << Base::HEX2 << addr; buf << "$" << Base::HEX2 << bankAddr.addr;
} }
else else
{ {
uInt16 a = addr & 0x3F, offset = addr & 0xFFC0; uInt16 a = bankAddr.addr & 0x3F, offset = bankAddr.addr & 0xFFC0;
if(ourTIAMnemonicW[a]) if(ourTIAMnemonicW[a])
{ {
buf << ourTIAMnemonicW[a]; buf << ourTIAMnemonicW[a];
@ -638,14 +657,14 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
buf << "|$" << Base::HEX2 << offset; buf << "|$" << Base::HEX2 << offset;
} }
else else
buf << "$" << Base::HEX2 << addr; buf << "$" << Base::HEX2 << bankAddr.addr;
} }
return true; return true;
} }
case AddrType::IO: case AddrType::IO:
{ {
uInt16 a = addr & 0xFF, offset = addr & 0xFD00; uInt16 a = bankAddr.addr & 0xFF, offset = bankAddr.addr & 0xFD00;
if(a <= 0x97) if(a <= 0x97)
{ {
if(ourIOMnemonic[a - 0x80]) if(ourIOMnemonic[a - 0x80])
@ -655,10 +674,10 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
buf << "|$" << Base::HEX2 << offset; buf << "|$" << Base::HEX2 << offset;
} }
else else
buf << "$" << Base::HEX2 << addr; buf << "$" << Base::HEX2 << bankAddr.addr;
} }
else else
buf << "$" << Base::HEX2 << addr; buf << "$" << Base::HEX2 << bankAddr.addr;
return true; return true;
} }
@ -668,12 +687,12 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
// RAM can use user-defined labels; otherwise we default to // RAM can use user-defined labels; otherwise we default to
// standard mnemonics // standard mnemonics
AddrToLabel::const_iterator iter; AddrToLabel::const_iterator iter;
uInt16 a = addr & 0xFF, offset = addr & 0xFF00; uInt16 a = bankAddr.addr & 0xFF, offset = bankAddr.addr & 0xFF00;
bool found = false; bool found = false;
// Search for nearest label // Search for nearest label
for(uInt16 i = a; i >= 0x80; --i) for(uInt16 i = a; i >= 0x80; --i)
if((iter = myUserLabels.find(i)) != myUserLabels.end()) if((iter = myUserLabels.find(BankAddress(i))) != myUserLabels.end())
{ {
buf << iter->second; buf << iter->second;
if(a != i) if(a != i)
@ -697,18 +716,18 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
AddrToLabel::const_iterator iter; AddrToLabel::const_iterator iter;
// Search for nearest label // Search for nearest label
for(uInt16 i = addr; i >= (addr & 0xf000); --i) for(uInt16 i = bankAddr.addr; i >= (bankAddr.addr & 0xf000); --i)
if((iter = myUserLabels.find(i)) != myUserLabels.end()) if((iter = myUserLabels.find(BankAddress(bankAddr.bank, i))) != myUserLabels.end())
{ {
buf << iter->second; buf << iter->second;
if(addr != i) if(bankAddr.addr != i)
buf << "+$" << Base::HEX1 << (addr - i); buf << "+$" << Base::HEX1 << (bankAddr.addr - i);
return true; return true;
} }
} }
else else
{ {
const auto& iter = myUserLabels.find(addr); const auto& iter = myUserLabels.find(bankAddr);
if(iter != myUserLabels.end()) if(iter != myUserLabels.end())
{ {
// TODO: detect and add SUBROUTINE in saved disassembly // TODO: detect and add SUBROUTINE in saved disassembly
@ -723,13 +742,13 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
switch(places) switch(places)
{ {
case 2: case 2:
buf << "$" << Base::HEX2 << addr; buf << "$" << Base::HEX2 << bankAddr.addr;
return true; return true;
case 4: case 4:
buf << "$" << Base::HEX4 << addr; buf << "$" << Base::HEX4 << bankAddr.addr;
return true; return true;
case 8: case 8:
buf << "$" << Base::HEX8 << addr; buf << "$" << Base::HEX8 << bankAddr.addr;
return true; return true;
default: default:
break; break;
@ -739,15 +758,41 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::getLabel(uInt16 addr, bool isRead, int places, bool isRam) const bool CartDebug::getLabel(ostream& buf, int bank, int addr, bool isRead,
int places, bool isRam) const
{
return getLabel(buf, BankAddress(bank, addr), isRead, places, isRam);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDebug::getLabel(ostream& buf, int addr, bool isRead,
int places, bool isRam) const
{
return getLabel(buf, BankAddress(addr), isRead, places, isRam);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::getLabel(BankAddress bankAddr, bool isRead, int places, bool isRam) const
{ {
ostringstream buf; ostringstream buf;
getLabel(buf, addr, isRead, places, isRam); getLabel(buf, bankAddr, isRead, places, isRam);
return buf.str(); return buf.str();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CartDebug::getAddress(const string& label) const string CartDebug::getLabel(int bank, int addr, bool isRead, int places, bool isRam) const
{
return getLabel(BankAddress(bank, addr), isRead, places, isRam);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::getLabel(int addr, bool isRead, int places, bool isRam) const
{
return getLabel(BankAddress(addr), isRead, places, isRam);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartDebug::BankAddress CartDebug::getAddress(const string& label) const
{ {
LabelToAddr::const_iterator iter; LabelToAddr::const_iterator iter;
@ -756,7 +801,7 @@ int CartDebug::getAddress(const string& label) const
else if((iter = myUserAddresses.find(label)) != myUserAddresses.end()) else if((iter = myUserAddresses.find(label)) != myUserAddresses.end())
return iter->second; return iter->second;
else else
return -1; return BankAddress(-1, 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -811,7 +856,7 @@ string CartDebug::loadListFile()
buf >> hex >> xx >> hex >> yy >> line >> eq; buf >> hex >> xx >> hex >> yy >> line >> eq;
if(xx >= 0 && yy >= 0 && eq == '=') if(xx >= 0 && yy >= 0 && eq == '=')
//myUserCLabels.emplace(xx*256+yy, line); //myUserCLabels.emplace(xx*256+yy, line);
addLabel(line, xx * 256 + yy); addLabel(line, BankAddress(xx * 256 + yy));
} }
} }
} }
@ -860,7 +905,7 @@ string CartDebug::loadSymbolFile()
// For now, we simply ignore constants completely // For now, we simply ignore constants completely
//const auto& iter = myUserCLabels.find(value); //const auto& iter = myUserCLabels.find(value);
//if(iter == myUserCLabels.end() || !BSPF::equalsIgnoreCase(label, iter->second)) //if(iter == myUserCLabels.end() || !BSPF::equalsIgnoreCase(label, iter->second))
const auto& iter = myUserLabels.find(value); const auto& iter = myUserLabels.find(BankAddress(value));
if(iter == myUserLabels.end() || !BSPF::equalsIgnoreCase(label, iter->second)) if(iter == myUserLabels.end() || !BSPF::equalsIgnoreCase(label, iter->second))
{ {
// Check for period, and strip leading number // Check for period, and strip leading number
@ -872,16 +917,16 @@ string CartDebug::loadSymbolFile()
if(iterA != myUserAddresses.end()) if(iterA != myUserAddresses.end())
// if short label already exists, move prefix to suffix and add long local label name // if short label already exists, move prefix to suffix and add long local label name
addLabel(shortLabel + "." + label.substr(0, pos), value); addLabel(shortLabel + "." + label.substr(0, pos), BankAddress(value));
else else
addLabel(shortLabel, value); addLabel(shortLabel, BankAddress(value));
} }
else else
{ {
// skip local macro labels // skip local macro labels
pos = label.find_last_of('$'); pos = label.find_last_of('$');
if(pos == string::npos || pos != label.length() - 1) if(pos == string::npos || pos != label.length() - 1)
addLabel(label, value); addLabel(label, BankAddress(value));
} }
} }
} }
@ -1128,10 +1173,11 @@ string CartDebug::saveDisassembly(string path)
// Disassemble bank // Disassemble bank
disasm.list.clear(); disasm.list.clear();
DiStella distella(*this, disasm.list, info, settings, DiStella distella(*this, disasm.list, info, settings,
myDisLabels, myDisDirectives, myReserved); myDisLabels, myDisDirectives, myReserved,
myConsole.cartridge().romBankCount());
if (myReserved.breakFound) if (myReserved.breakFound)
addLabel("Break", myDebugger.dpeek(0xfffe)); addLabel("Break", BankAddress(bank, myDebugger.dpeek(0xfffe)));
buf << " SEG CODE\n"; buf << " SEG CODE\n";
@ -1308,7 +1354,7 @@ string CartDebug::saveDisassembly(string path)
bool stackUsed = (mySystem.getAccessFlags(addr|0x100) & (Device::DATA | Device::WRITE)); bool stackUsed = (mySystem.getAccessFlags(addr|0x100) & (Device::DATA | Device::WRITE));
if (myReserved.ZPRAM[addr - 0x80] && if (myReserved.ZPRAM[addr - 0x80] &&
myUserLabels.find(addr) == myUserLabels.end()) { myUserLabels.find(BankAddress(addr)) == myUserLabels.end()) {
if (addLine) if (addLine)
out << "\n"; out << "\n";
out << ALIGN(16) << ourZPMnemonic[addr - 0x80] << "= $" out << ALIGN(16) << ourZPMnemonic[addr - 0x80] << "= $"
@ -1341,7 +1387,7 @@ string CartDebug::saveDisassembly(string path)
<< "; Non Locatable Labels\n" << "; Non Locatable Labels\n"
<< ";-----------------------------------------------------------\n\n"; << ";-----------------------------------------------------------\n\n";
for(const auto& iter: myReserved.Label) for(const auto& iter: myReserved.Label)
out << ALIGN(16) << iter.second << "= $" << iter.first << "\n"; out << ALIGN(16) << iter.second << "= $" << iter.first.addr << "\n";
} }
if(myUserLabels.size() > 0) if(myUserLabels.size() > 0)
@ -1353,7 +1399,7 @@ string CartDebug::saveDisassembly(string path)
for(const auto& iter: myUserLabels) for(const auto& iter: myUserLabels)
max_len = std::max(max_len, int(iter.second.size())); max_len = std::max(max_len, int(iter.second.size()));
for(const auto& iter: myUserLabels) for(const auto& iter: myUserLabels)
out << ALIGN(max_len) << iter.second << "= $" << iter.first << "\n"; out << ALIGN(max_len) << iter.second << "= $" << iter.first.addr << "\n";
} }
// And finally, output the disassembly // And finally, output the disassembly

View File

@ -68,6 +68,20 @@ class CartDebug : public DebuggerSystem
enum class AddrType { TIA, IO, ZPRAM, ROM }; enum class AddrType { TIA, IO, ZPRAM, ROM };
AddrType addressType(uInt16 addr) const; AddrType addressType(uInt16 addr) const;
struct BankAddress {
Int16 bank{0}; // -1 means undefined
uInt16 addr{0};
explicit BankAddress(Int16 _bank, uInt16 _addr)
: bank{_bank}, addr{_addr} { }
explicit BankAddress(uInt16 _addr)
: bank{0}, addr{_addr} { }
BankAddress(const BankAddress&) = default;
BankAddress& operator=(const BankAddress&) = default;
BankAddress(BankAddress&&) = default;
BankAddress& operator=(BankAddress&&) = default;
};
public: public:
CartDebug(Debugger& dbg, Console& console, const OSystem& osystem); CartDebug(Debugger& dbg, Console& console, const OSystem& osystem);
~CartDebug() override = default; ~CartDebug() override = default;
@ -193,7 +207,7 @@ class CartDebug : public DebuggerSystem
Add a label and associated address. Add a label and associated address.
Labels that reference either TIA or RIOT spaces will not be processed. Labels that reference either TIA or RIOT spaces will not be processed.
*/ */
bool addLabel(const string& label, uInt16 address); bool addLabel(const string& label, BankAddress bankAddr);
/** /**
Remove the given label and its associated address. Remove the given label and its associated address.
@ -211,11 +225,20 @@ class CartDebug : public DebuggerSystem
If places is not -1 and a label hasn't been defined, return a If places is not -1 and a label hasn't been defined, return a
formatted hexidecimal address formatted hexidecimal address
*/ */
bool getLabel(ostream& buf, uInt16 addr, bool isRead, bool getLabel(ostream& buf, BankAddress bankAddr, bool isRead,
int places = -1, bool isRam = false) const; int places = -1, bool isRam = false) const;
string getLabel(uInt16 addr, bool isRead, bool getLabel(ostream& buf, int bank, int addr, bool isRead,
int places = -1, bool isRam = false) const;
bool getLabel(ostream& buf, int addr, bool isRead,
int places = -1, bool isRam = false) const;
string getLabel(BankAddress bankAddr, bool isRead,
int places = -1, bool isRam = false) const; int places = -1, bool isRam = false) const;
int getAddress(const string& label) const; string getLabel(int bank, int addr, bool isRead,
int places = -1, bool isRam = false) const;
string getLabel(int addr, bool isRead,
int places = -1, bool isRam = false) const;
BankAddress getAddress(const string& label) const;
/** /**
Load constants from list file (as generated by DASM). Load constants from list file (as generated by DASM).
@ -269,8 +292,9 @@ class CartDebug : public DebuggerSystem
void AccessTypeAsString(ostream& buf, Device::AccessType type) const; void AccessTypeAsString(ostream& buf, Device::AccessType type) const;
private: private:
using AddrToLabel = std::map<uInt16, string>; using AddrToLabel = std::map<BankAddress, string,
using LabelToAddr = std::map<string, uInt16, std::function<bool(const BankAddress&, const BankAddress&)>>;
using LabelToAddr = std::map<string, BankAddress,
std::function<bool(const string&, const string&)>>; std::function<bool(const string&, const string&)>>;
using AddrTypeArray = std::array<uInt16, 0x1000>; using AddrTypeArray = std::array<uInt16, 0x1000>;
@ -284,6 +308,7 @@ class CartDebug : public DebuggerSystem
using DirectiveList = std::list<DirectiveTag>; using DirectiveList = std::list<DirectiveTag>;
struct BankInfo { struct BankInfo {
Int16 bank; // bank number
uInt16 start{0}; // start of address space uInt16 start{0}; // start of address space
uInt16 end{0}; // end of address space uInt16 end{0}; // end of address space
uInt16 offset{0}; // ORG value uInt16 offset{0}; // ORG value

View File

@ -122,7 +122,7 @@ bool Debugger::start(const string& message, int address, bool read,
ostringstream buf; ostringstream buf;
buf << message; buf << message;
if(address > -1) if(address > -1)
buf << cartDebug().getLabel(address, read, 4); buf << cartDebug().getLabel(CartDebug::BankAddress(address), read, 4);
dialog().message().setText(buf.str()); dialog().message().setText(buf.str());
dialog().message().setToolTip(toolTip); dialog().message().setToolTip(toolTip);
return true; return true;

View File

@ -136,7 +136,7 @@ class EquateExpression : public Expression
public: public:
EquateExpression(const string& label) : Expression(), myLabel{label} { } EquateExpression(const string& label) : Expression(), myLabel{label} { }
Int32 evaluate() const override Int32 evaluate() const override
{ return Debugger::debugger().cartDebug().getAddress(myLabel); } { return Debugger::debugger().cartDebug().getAddress(myLabel).addr; }
private: private:
string myLabel; string myLabel;

View File

@ -244,9 +244,10 @@ int DebuggerParser::decipher_arg(const string& str)
else if(arg == "pc" || arg == ".") result = state.PC; else if(arg == "pc" || arg == ".") result = state.PC;
else { // Not a special, must be a regular arg: check for label first else { // Not a special, must be a regular arg: check for label first
const char* a = arg.c_str(); const char* a = arg.c_str();
result = debugger.cartDebug().getAddress(arg); CartDebug::BankAddress bankAddr = debugger.cartDebug().getAddress(arg);
result = bankAddr.addr;
if(result < 0) { // if not label, must be a number if(bankAddr.bank < 0) { // if not label, must be a number
if(bin) { // treat as binary if(bin) { // treat as binary
result = 0; result = 0;
while(*a != '\0') { while(*a != '\0') {
@ -595,9 +596,11 @@ void DebuggerParser::listTraps(bool listCond)
if(hasCond) if(hasCond)
commandResult << " " << names[i]; commandResult << " " << names[i];
commandResult << " " << debugger.cartDebug().getLabel(myTraps[i]->begin, true, 4); commandResult << " "
<< debugger.cartDebug().getLabel(myTraps[i]->begin, true, 4);
if(myTraps[i]->begin != myTraps[i]->end) if(myTraps[i]->begin != myTraps[i]->end)
commandResult << " " << debugger.cartDebug().getLabel(myTraps[i]->end, true, 4); commandResult << " "
<< debugger.cartDebug().getLabel(myTraps[i]->end, true, 4);
commandResult << trapStatus(*myTraps[i]); commandResult << trapStatus(*myTraps[i]);
commandResult << " + mirrors"; commandResult << " + mirrors";
if(i != (names.size() - 1)) commandResult << endl; if(i != (names.size() - 1)) commandResult << endl;
@ -1034,7 +1037,7 @@ void DebuggerParser::executeDebugColors()
void DebuggerParser::executeDefine() void DebuggerParser::executeDefine()
{ {
// TODO: check if label already defined? // TODO: check if label already defined?
debugger.cartDebug().addLabel(argStrings[0], args[1]); debugger.cartDebug().addLabel(argStrings[0], CartDebug::BankAddress(args[1]));
debugger.rom().invalidate(); debugger.rom().invalidate();
} }
@ -1530,14 +1533,14 @@ void DebuggerParser::executeListbreaks()
{ {
if(romBankCount == 1) if(romBankCount == 1)
{ {
buf << debugger.cartDebug().getLabel(bp.addr, true, 4) << " "; buf << debugger.cartDebug().getLabel(bp.bank, bp.addr, true, 4) << " ";
if(!(++count % 8)) buf << endl; if(!(++count % 8)) buf << endl;
} }
else else
{ {
if(count % 6) if(count % 6)
buf << ", "; buf << ", ";
buf << debugger.cartDebug().getLabel(bp.addr, true, 4); buf << debugger.cartDebug().getLabel(bp.bank, bp.addr, true, 4);
if(bp.bank != 255) if(bp.bank != 255)
buf << " #" << int(bp.bank); buf << " #" << int(bp.bank);
else else

View File

@ -26,13 +26,16 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
CartDebug::BankInfo& info, const DiStella::Settings& s, CartDebug::BankInfo& info, const DiStella::Settings& s,
CartDebug::AddrTypeArray& labels, CartDebug::AddrTypeArray& labels,
CartDebug::AddrTypeArray& directives, CartDebug::AddrTypeArray& directives,
CartDebug::ReservedEquates& reserved) CartDebug::ReservedEquates& reserved,
int numBanks)
: myDbg{dbg}, : myDbg{dbg},
myList{list}, myList{list},
mySettings{s}, mySettings{s},
myReserved{reserved}, myReserved{reserved},
myLabels{labels}, myLabels{labels},
myDirectives{directives} myDirectives{directives},
myBank(info.bank),
myNumBanks(numBanks)
{ {
bool resolve_code = mySettings.resolveCode; bool resolve_code = mySettings.resolveCode;
CartDebug::AddressList& debuggerAddresses = info.addressList; CartDebug::AddressList& debuggerAddresses = info.addressList;
@ -72,7 +75,7 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
disasm(myOffset, 2); disasm(myOffset, 2);
// Add reserved line equates // Add reserved line equates
ostringstream reservedLabel; stringstream reservedLabel;
for (int k = 0; k <= myAppData.end; k++) { for (int k = 0; k <= myAppData.end; k++) {
if ((myLabels[k] & (Device::REFERENCED | Device::VALID_ENTRY)) == Device::REFERENCED) { if ((myLabels[k] & (Device::REFERENCED | Device::VALID_ENTRY)) == Device::REFERENCED) {
// If we have a piece of code referenced somewhere else, but cannot // If we have a piece of code referenced somewhere else, but cannot
@ -82,7 +85,7 @@ DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
// However, we only do this for labels pointing to ROM (above $1000) // However, we only do this for labels pointing to ROM (above $1000)
if (myDbg.addressType(k + myOffset) == CartDebug::AddrType::ROM) { if (myDbg.addressType(k + myOffset) == CartDebug::AddrType::ROM) {
reservedLabel.str(""); reservedLabel.str("");
reservedLabel << "L" << Base::HEX4 << (k + myOffset); labelHigh(reservedLabel, k + myOffset);
myReserved.Label.emplace(k + myOffset, reservedLabel.str()); myReserved.Label.emplace(k + myOffset, reservedLabel.str());
} }
} }
@ -101,8 +104,8 @@ void DiStella::disasm(uInt32 distart, int pass)
- pass 3 generates output - pass 3 generates output
*/ */
{ {
#define LABEL_A12_HIGH(address) labelA12High(nextLine, opcode, address, labelFound) #define LABEL_HIGH(addr) labelHigh(nextLine, addr)
#define LABEL_A12_LOW(address) labelA12Low(nextLine, opcode, address, labelFound) #define LABEL_LOW(addr) labelLow(nextLine, opcode, addr, labelFound)
uInt8 opcode, d1; uInt8 opcode, d1;
uInt16 ad; uInt16 ad;
@ -184,7 +187,7 @@ void DiStella::disasm(uInt32 distart, int pass)
// add extra spacing line when switching from non-code to code // add extra spacing line when switching from non-code to code
if(pass == 3 && mySegType != Device::CODE && mySegType != Device::NONE) { if(pass == 3 && mySegType != Device::CODE && mySegType != Device::NONE) {
myDisasmBuf << " ' ' "; myDisasmBuf << EMPTY_LINE;
addEntry(Device::NONE); addEntry(Device::NONE);
mark(myPC + myOffset, Device::REFERENCED); // add label when switching mark(myPC + myOffset, Device::REFERENCED); // add label when switching
} }
@ -201,9 +204,12 @@ void DiStella::disasm(uInt32 distart, int pass)
if(pass == 3) { if(pass == 3) {
if(checkBit(myPC, Device::REFERENCED)) if(checkBit(myPC, Device::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'"; {
myDisasmBuf << Base::HEX4 << myPC + myOffset;
lineLabelHigh(myDisasmBuf, myPC + myOffset);
}
else else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '"; myDisasmBuf << Base::HEX4 << myPC + myOffset << NO_LABEL;
} }
++myPC; ++myPC;
@ -276,10 +282,14 @@ void DiStella::disasm(uInt32 distart, int pass)
addEntry(Device::DATA); addEntry(Device::DATA);
if(myPC == myAppData.end) { if(myPC == myAppData.end) {
if(checkBit(myPC, Device::REFERENCED)) if(checkBit(myPC, Device::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'"; {
myDisasmBuf << Base::HEX4 << myPC + myOffset;
lineLabelHigh(myDisasmBuf, myPC + myOffset);
}
else else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '"; myDisasmBuf << Base::HEX4 << myPC + myOffset << NO_LABEL;
opcode = Debugger::debugger().peek(myPC + myOffset); ++myPC; opcode = Debugger::debugger().peek(myPC + myOffset); ++myPC;
myDisasmBuf << ".byte $" << Base::HEX2 << int(opcode) << " $" myDisasmBuf << ".byte $" << Base::HEX2 << int(opcode) << " $"
@ -338,13 +348,13 @@ void DiStella::disasm(uInt32 distart, int pass)
nextLine << " "; nextLine << " ";
if(labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
LABEL_A12_HIGH(ad); LABEL_HIGH(ad);
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
else if(labelFound == AddressType::ROM_MIRROR) { else if(labelFound == AddressType::ROM_MIRROR) {
if(mySettings.rFlag) { if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_HIGH(tmp);
nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8); nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8);
} }
else { else {
@ -353,7 +363,7 @@ void DiStella::disasm(uInt32 distart, int pass)
} }
} }
else { else {
LABEL_A12_LOW(ad); LABEL_LOW(ad);
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
} }
@ -366,7 +376,7 @@ void DiStella::disasm(uInt32 distart, int pass)
labelFound = mark(d1, Device::REFERENCED); labelFound = mark(d1, Device::REFERENCED);
if(pass == 3) { if(pass == 3) {
nextLine << " "; nextLine << " ";
LABEL_A12_LOW(int(d1)); LABEL_LOW(int(d1));
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
} }
break; break;
@ -400,14 +410,14 @@ void DiStella::disasm(uInt32 distart, int pass)
nextLine << " "; nextLine << " ";
if(labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
LABEL_A12_HIGH(ad); LABEL_HIGH(ad);
nextLine << ",x"; nextLine << ",x";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
else if(labelFound == AddressType::ROM_MIRROR) { else if(labelFound == AddressType::ROM_MIRROR) {
if(mySettings.rFlag) { if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_HIGH(tmp);
nextLine << ",x"; nextLine << ",x";
nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8); nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8);
} }
@ -417,7 +427,7 @@ void DiStella::disasm(uInt32 distart, int pass)
} }
} }
else { else {
LABEL_A12_LOW(ad); LABEL_LOW(ad);
nextLine << ",x"; nextLine << ",x";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
@ -443,14 +453,14 @@ void DiStella::disasm(uInt32 distart, int pass)
nextLine << " "; nextLine << " ";
if(labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
LABEL_A12_HIGH(ad); LABEL_HIGH(ad);
nextLine << ",y"; nextLine << ",y";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
else if(labelFound == AddressType::ROM_MIRROR) { else if(labelFound == AddressType::ROM_MIRROR) {
if(mySettings.rFlag) { if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_HIGH(tmp);
nextLine << ",y"; nextLine << ",y";
nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8); nextLineBytes << Base::HEX2 << int(tmp & 0xff) << " " << Base::HEX2 << int(tmp >> 8);
} }
@ -460,7 +470,7 @@ void DiStella::disasm(uInt32 distart, int pass)
} }
} }
else { else {
LABEL_A12_LOW(ad); LABEL_LOW(ad);
nextLine << ",y"; nextLine << ",y";
nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8); nextLineBytes << Base::HEX2 << int(ad & 0xff) << " " << Base::HEX2 << int(ad >> 8);
} }
@ -474,7 +484,7 @@ void DiStella::disasm(uInt32 distart, int pass)
if(pass == 3) { if(pass == 3) {
labelFound = mark(d1, 0); // dummy call to get address type labelFound = mark(d1, 0); // dummy call to get address type
nextLine << " ("; nextLine << " (";
LABEL_A12_LOW(d1); LABEL_LOW(d1);
nextLine << ",x)"; nextLine << ",x)";
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
} }
@ -487,7 +497,7 @@ void DiStella::disasm(uInt32 distart, int pass)
if(pass == 3) { if(pass == 3) {
labelFound = mark(d1, 0); // dummy call to get address type labelFound = mark(d1, 0); // dummy call to get address type
nextLine << " ("; nextLine << " (";
LABEL_A12_LOW(d1); LABEL_LOW(d1);
nextLine << "),y"; nextLine << "),y";
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
} }
@ -500,7 +510,7 @@ void DiStella::disasm(uInt32 distart, int pass)
labelFound = mark(d1, Device::REFERENCED); labelFound = mark(d1, Device::REFERENCED);
if(pass == 3) { if(pass == 3) {
nextLine << " "; nextLine << " ";
LABEL_A12_LOW(d1); LABEL_LOW(d1);
nextLine << ",x"; nextLine << ",x";
} }
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
@ -513,7 +523,7 @@ void DiStella::disasm(uInt32 distart, int pass)
labelFound = mark(d1, Device::REFERENCED); labelFound = mark(d1, Device::REFERENCED);
if(pass == 3) { if(pass == 3) {
nextLine << " "; nextLine << " ";
LABEL_A12_LOW(d1); LABEL_LOW(d1);
nextLine << ",y"; nextLine << ",y";
} }
nextLineBytes << Base::HEX2 << int(d1); nextLineBytes << Base::HEX2 << int(d1);
@ -532,7 +542,7 @@ void DiStella::disasm(uInt32 distart, int pass)
if(pass == 3) { if(pass == 3) {
if(labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
nextLine << " "; nextLine << " ";
LABEL_A12_HIGH(ad); LABEL_HIGH(ad);
} }
else else
nextLine << " $" << Base::HEX4 << ad; nextLine << " $" << Base::HEX4 << ad;
@ -561,23 +571,23 @@ void DiStella::disasm(uInt32 distart, int pass)
} }
if(labelFound == AddressType::ROM) { if(labelFound == AddressType::ROM) {
nextLine << "("; nextLine << "(";
LABEL_A12_HIGH(ad); LABEL_HIGH(ad);
nextLine << ")"; nextLine << ")";
} }
else if(labelFound == AddressType::ROM_MIRROR) { else if(labelFound == AddressType::ROM_MIRROR) {
nextLine << "("; nextLine << "(";
if(mySettings.rFlag) { if(mySettings.rFlag) {
int tmp = (ad & myAppData.end) + myOffset; int tmp = (ad & myAppData.end) + myOffset;
LABEL_A12_HIGH(tmp); LABEL_HIGH(tmp);
} }
else { else {
LABEL_A12_LOW(ad); LABEL_LOW(ad);
} }
nextLine << ")"; nextLine << ")";
} }
else { else {
nextLine << "("; nextLine << "(";
LABEL_A12_LOW(ad); LABEL_LOW(ad);
nextLine << ")"; nextLine << ")";
} }
@ -594,23 +604,27 @@ void DiStella::disasm(uInt32 distart, int pass)
// A complete line of disassembly (text, cycle count, and bytes) // A complete line of disassembly (text, cycle count, and bytes)
myDisasmBuf << nextLine.str() << "'" myDisasmBuf << nextLine.str() << "'"
<< ";" << std::dec << int(ourLookup[opcode].cycles) << ";" << std::dec << int(ourLookup[opcode].cycles)
<< (addrMode == AddressingMode::RELATIVE ? (ad & 0xf00) != ((myPC + myOffset) & 0xf00) ? "/3!" : "/3 " : " "); << (addrMode == AddressingMode::RELATIVE
? (ad & 0xf00) != ((myPC + myOffset) & 0xf00)
? "/3!" : "/3 "
: " ");
if((opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00 // code block end if((opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00 // code block end
|| checkBit(myPC, Device::REFERENCED) // referenced address || checkBit(myPC, Device::REFERENCED) // referenced address
|| (ourLookup[opcode].rw_mode == RWMode::WRITE && d1 == WSYNC)) // strobe WSYNC || (ourLookup[opcode].rw_mode == RWMode::WRITE && d1 == WSYNC)) // strobe WSYNC
&& cycles > 0) { && cycles > 0) {
// output cycles for previous code block // output cycles for previous code block
myDisasmBuf << "'= " << std::setw(3) << std::setfill(' ') << std::dec << cycles; myDisasmBuf << "'= "
<< std::right << std::setw(3) << std::setfill(' ') << std::dec << cycles << "'";
cycles = 0; cycles = 0;
} }
else { else {
myDisasmBuf << "' "; myDisasmBuf << "' '";
} }
myDisasmBuf << "'" << nextLineBytes.str(); myDisasmBuf << nextLineBytes.str();
addEntry(Device::CODE); addEntry(Device::CODE);
if(opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00) { if(opcode == 0x40 || opcode == 0x60 || opcode == 0x4c || opcode == 0x00) {
myDisasmBuf << " ' ' "; myDisasmBuf << EMPTY_LINE;
addEntry(Device::NONE); addEntry(Device::NONE);
mySegType = Device::NONE; // prevent extra lines if data follows mySegType = Device::NONE; // prevent extra lines if data follows
} }
@ -1031,7 +1045,7 @@ void DiStella::addEntry(Device::AccessType type)
// Label (a user-defined label always overrides any auto-generated one) // Label (a user-defined label always overrides any auto-generated one)
myDisasmBuf.seekg(5, std::ios::beg); myDisasmBuf.seekg(5, std::ios::beg);
if (tag.address) { if (tag.address) {
tag.label = myDbg.getLabel(tag.address, true); tag.label = myDbg.getLabel(myBank, tag.address, true);
tag.hllabel = true; tag.hllabel = true;
if (tag.label == EmptyString) { if (tag.label == EmptyString) {
if (myDisasmBuf.peek() != ' ') if (myDisasmBuf.peek() != ' ')
@ -1047,7 +1061,7 @@ void DiStella::addEntry(Device::AccessType type)
// Disassembly // Disassembly
// Up to this point the field sizes are fixed, until we get to // Up to this point the field sizes are fixed, until we get to
// variable length labels, cycle counts, etc // variable length labels, cycle counts, etc
myDisasmBuf.seekg(11, std::ios::beg); myDisasmBuf.seekg(11+3, std::ios::beg);
switch (tag.type) { switch (tag.type) {
case Device::CODE: case Device::CODE:
getline(myDisasmBuf, tag.disasm, '\''); getline(myDisasmBuf, tag.disasm, '\'');
@ -1103,15 +1117,18 @@ void DiStella::outputGraphics()
// add extra spacing line when switching from non-graphics to graphics // add extra spacing line when switching from non-graphics to graphics
if (mySegType != Device::GFX && mySegType != Device::NONE) { if (mySegType != Device::GFX && mySegType != Device::NONE) {
myDisasmBuf << " ' ' "; myDisasmBuf << EMPTY_LINE;
addEntry(Device::NONE); addEntry(Device::NONE);
} }
mySegType = Device::GFX; mySegType = Device::GFX;
if (checkBit(myPC, Device::REFERENCED)) if (checkBit(myPC, Device::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'"; {
myDisasmBuf << Base::HEX4 << myPC + myOffset;
lineLabelHigh(myDisasmBuf, myPC + myOffset);
}
else else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '"; myDisasmBuf << Base::HEX4 << myPC + myOffset << NO_LABEL;
myDisasmBuf << ".byte $" << Base::HEX2 << int(byte) << " |"; myDisasmBuf << ".byte $" << Base::HEX2 << int(byte) << " |";
for (uInt8 i = 0, c = byte; i < 8; ++i, c <<= 1) for (uInt8 i = 0, c = byte; i < 8; ++i, c <<= 1)
myDisasmBuf << ((c > 127) ? bitString : " "); myDisasmBuf << ((c > 127) ? bitString : " ");
@ -1149,16 +1166,19 @@ void DiStella::outputColors()
// add extra spacing line when switching from non-colors to colors // add extra spacing line when switching from non-colors to colors
if(mySegType != Device::COL && mySegType != Device::NONE) if(mySegType != Device::COL && mySegType != Device::NONE)
{ {
myDisasmBuf << " ' ' "; myDisasmBuf << EMPTY_LINE;
addEntry(Device::NONE); addEntry(Device::NONE);
} }
mySegType = Device::COL; mySegType = Device::COL;
// output label/address // output label/address
if(checkBit(myPC, Device::REFERENCED)) if(checkBit(myPC, Device::REFERENCED))
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 << myPC + myOffset << "'"; {
myDisasmBuf << Base::HEX4 << myPC + myOffset;
lineLabelHigh(myDisasmBuf, myPC + myOffset);
}
else else
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '"; myDisasmBuf << Base::HEX4 << myPC + myOffset << NO_LABEL;
// output color // output color
string color; string color;
@ -1202,7 +1222,7 @@ void DiStella::outputBytes(Device::AccessType type)
// add extra spacing line when switching from non-data to data // add extra spacing line when switching from non-data to data
if (mySegType != Device::DATA && mySegType != Device::NONE) { if (mySegType != Device::DATA && mySegType != Device::NONE) {
myDisasmBuf << " ' ' "; myDisasmBuf << EMPTY_LINE;
addEntry(Device::NONE); addEntry(Device::NONE);
} }
mySegType = Device::DATA; mySegType = Device::DATA;
@ -1213,15 +1233,16 @@ void DiStella::outputBytes(Device::AccessType type)
if (!lineEmpty) if (!lineEmpty)
addEntry(type); addEntry(type);
myDisasmBuf << Base::HEX4 << myPC + myOffset << "'L" << Base::HEX4 myDisasmBuf << Base::HEX4 << myPC + myOffset;
<< myPC + myOffset << "'.byte " << "$" << Base::HEX2 lineLabelHigh(myDisasmBuf, myPC + myOffset);
myDisasmBuf << ".byte " << "$" << Base::HEX2
<< int(Debugger::debugger().peek(myPC + myOffset)); << int(Debugger::debugger().peek(myPC + myOffset));
++myPC; ++myPC;
numBytes = 1; numBytes = 1;
lineEmpty = false; lineEmpty = false;
} else if (lineEmpty) { } else if (lineEmpty) {
// start a new line without a label // start a new line without a label
myDisasmBuf << Base::HEX4 << myPC + myOffset << "' '" myDisasmBuf << Base::HEX4 << myPC + myOffset << NO_LABEL
<< ".byte $" << Base::HEX2 << int(Debugger::debugger().peek(myPC + myOffset)); << ".byte $" << Base::HEX2 << int(Debugger::debugger().peek(myPC + myOffset));
++myPC; ++myPC;
numBytes = 1; numBytes = 1;
@ -1243,7 +1264,7 @@ void DiStella::outputBytes(Device::AccessType type)
} }
if (!lineEmpty) if (!lineEmpty)
addEntry(type); addEntry(type);
/*myDisasmBuf << " ' ' "; /*myDisasmBuf << EMPTY_LINE;
addEntry(Device::NONE);*/ addEntry(Device::NONE);*/
} }
@ -1588,3 +1609,7 @@ const std::array<DiStella::Instruction_tag, 256> DiStella::ourLookup = { {
/* fe */{"inc", AddressingMode::ABSOLUTE_X, AccessMode::ABSX, RWMode::WRITE, 7, 3}, /* Absolute,X */ /* fe */{"inc", AddressingMode::ABSOLUTE_X, AccessMode::ABSX, RWMode::WRITE, 7, 3}, /* Absolute,X */
/* ff */{"ISB", AddressingMode::ABSOLUTE_X, AccessMode::ABSX, RWMode::WRITE, 7, 3} /* ff */{"ISB", AddressingMode::ABSOLUTE_X, AccessMode::ABSX, RWMode::WRITE, 7, 3}
} }; } };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string DiStella::NO_LABEL = "' '"; // 8 chars per address (was 5)
const string DiStella::EMPTY_LINE = " " + NO_LABEL + " ";

View File

@ -65,12 +65,14 @@ class DiStella
@param labels Array storing label info determined by Distella @param labels Array storing label info determined by Distella
@param directives Array storing directive info determined by Distella @param directives Array storing directive info determined by Distella
@param reserved The TIA/RIOT addresses referenced in the disassembled code @param reserved The TIA/RIOT addresses referenced in the disassembled code
@param numBank The total number of ROM banks
*/ */
DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list, DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
CartDebug::BankInfo& info, const DiStella::Settings& settings, CartDebug::BankInfo& info, const DiStella::Settings& settings,
CartDebug::AddrTypeArray& labels, CartDebug::AddrTypeArray& labels,
CartDebug::AddrTypeArray& directives, CartDebug::AddrTypeArray& directives,
CartDebug::ReservedEquates& reserved); CartDebug::ReservedEquates& reserved,
int numBanks);
private: private:
/** /**
@ -86,6 +88,8 @@ class DiStella
ZP_RAM ZP_RAM
}; };
static const string NO_LABEL;
static const string EMPTY_LINE;
private: private:
// Indicate that a new line of disassembly has been completed // Indicate that a new line of disassembly has been completed
@ -111,12 +115,29 @@ class DiStella
void outputBytes(Device::AccessType type); void outputBytes(Device::AccessType type);
// Convenience methods to generate appropriate labels // Convenience methods to generate appropriate labels
inline void labelA12High(stringstream& buf, uInt8 op, uInt16 addr, AddressType labfound) inline void lineLabelHigh(stringstream& buf, uInt16 addr)
{ {
if(!myDbg.getLabel(buf, addr, true)) stringstream buf8;
buf << "L" << Common::Base::HEX4 << addr;
buf8 << "'L";
if(myNumBanks > 1)
buf8 << Common::Base::HEX1 << myBank << "_";
buf8 << Common::Base::HEX4 << addr;
buf << std::left << std::setw(9) << std::setfill(' ') << buf8.str() << "'";
} }
inline void labelA12Low(stringstream& buf, uInt8 op, uInt16 addr, AddressType labfound)
inline void labelHigh(stringstream& buf, uInt16 addr)
{
if(!myDbg.getLabel(buf, myBank, addr, true))
{
buf << "L";
if(myNumBanks > 1)
buf << Common::Base::HEX1 << myBank << "_";
buf << Common::Base::HEX4 << addr;
}
}
inline void labelLow(stringstream& buf, uInt8 op, uInt16 addr, AddressType labfound)
{ {
myDbg.getLabel(buf, addr, ourLookup[op].rw_mode == RWMode::READ, 2); myDbg.getLabel(buf, addr, ourLookup[op].rw_mode == RWMode::READ, 2);
if (labfound == AddressType::TIA) if (labfound == AddressType::TIA)
@ -139,6 +160,8 @@ class DiStella
CartDebug::ReservedEquates& myReserved; CartDebug::ReservedEquates& myReserved;
stringstream myDisasmBuf; stringstream myDisasmBuf;
std::queue<uInt16> myAddressQueue; std::queue<uInt16> myAddressQueue;
Int16 myBank{-1};
Int16 myNumBanks{1};
uInt16 myOffset{0}, myPC{0}, myPCEnd{0}; uInt16 myOffset{0}, myPC{0}, myPCEnd{0};
uInt16 mySegType{0}; uInt16 mySegType{0};

View File

@ -317,7 +317,9 @@ int yylex() {
// happen if the user defines a label that matches one of // happen if the user defines a label that matches one of
// the specials. Who would do that, though? // the specials. Who would do that, though?
if(Debugger::debugger().cartDebug().getAddress(idbuf) > -1) { CartDebug::BankAddress bankAddr = Debugger::debugger().cartDebug().getAddress(idbuf);
if(bankAddr.bank > -1) {
yylval.Equate = idbuf; yylval.Equate = idbuf;
return EQUATE; return EQUATE;
} else if( (cpuMeth = getCpuSpecial(idbuf)) ) { } else if( (cpuMeth = getCpuSpecial(idbuf)) ) {