123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841 |
- #include "SymbolTable.h"
- #include "DebuggerData.h"
- #include <QFile>
- #include <QTextStream>
- #include <QStringList>
- #include <QRegExp>
- #include <QFileInfo>
- #include <QXmlStreamWriter>
- #include <QMap>
- // class SymbolTable
- SymbolTable::SymbolTable()
- {
- connect(&fileWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(const QString&)));
- }
- SymbolTable::~SymbolTable()
- {
- clear();
- }
- void SymbolTable::add(Symbol* symbol)
- {
- symbols.append(symbol);
- symbol->table = this;
- mapSymbol(symbol);
- }
- void SymbolTable::removeAt(int index)
- {
- Symbol* symbol = symbols.takeAt(index);
- unmapSymbol(symbol);
- delete symbol;
- }
- void SymbolTable::remove(Symbol* symbol)
- {
- symbols.removeAll(symbol);
- unmapSymbol(symbol);
- delete symbol;
- }
- void SymbolTable::clear()
- {
- addressSymbols.clear();
- valueSymbols.clear();
- qDeleteAll(symbols);
- symbols.clear();
- }
- int SymbolTable::size() const
- {
- return symbols.size();
- }
- void SymbolTable::mapSymbol(Symbol* symbol)
- {
- if (symbol->type() != Symbol::VALUE) {
- addressSymbols.insert(symbol->value(), symbol);
- }
- if (symbol->type() != Symbol::JUMPLABEL) {
- valueSymbols.insert(symbol->value(), symbol);
- }
- }
- void SymbolTable::unmapSymbol(Symbol* symbol)
- {
- QMutableMapIterator<int, Symbol*> i(addressSymbols);
- while (i.hasNext()) {
- i.next();
- if (i.value() == symbol) i.remove();
- }
- QMutableHashIterator<int, Symbol*> j(valueSymbols);
- while (j.hasNext()) {
- j.next();
- if (j.value() == symbol) j.remove();
- }
- }
- void SymbolTable::symbolTypeChanged(Symbol* symbol)
- {
- unmapSymbol(symbol);
- mapSymbol(symbol);
- }
- void SymbolTable::symbolValueChanged(Symbol* symbol)
- {
- unmapSymbol(symbol);
- mapSymbol(symbol);
- }
- Symbol* SymbolTable::findFirstAddressSymbol(int addr, MemoryLayout* ml)
- {
- for (currentAddress = addressSymbols.begin();
- currentAddress != addressSymbols.end(); ++currentAddress) {
- if ((*currentAddress)->value() >= addr) {
- if ((*currentAddress)->isSlotValid(ml)) {
- return *currentAddress;
- }
- }
- }
- return 0;
- }
- Symbol* SymbolTable::getCurrentAddressSymbol()
- {
- return currentAddress != addressSymbols.end() ? *currentAddress : 0;
- }
- Symbol* SymbolTable::findNextAddressSymbol(MemoryLayout* ml)
- {
- for (++currentAddress; currentAddress != addressSymbols.end();
- ++currentAddress) {
- if ((*currentAddress)->isSlotValid(ml)) {
- return *currentAddress;
- }
- }
- return 0;
- }
- Symbol* SymbolTable::getValueSymbol(int val, Symbol::Register reg, MemoryLayout* ml)
- {
- for (QMultiHash<int, Symbol*>::iterator it = valueSymbols.find(val);
- it != valueSymbols.end() && it.key() == val; ++it) {
- if ((it.value()->validRegisters() & reg) &&
- it.value()->isSlotValid(ml)) {
- return it.value();
- }
- }
- return 0;
- }
- Symbol* SymbolTable::getAddressSymbol(int addr, MemoryLayout* ml)
- {
- for (QMultiMap<int, Symbol*>::iterator it = addressSymbols.find(addr);
- it != addressSymbols.end() && it.key() == addr; ++it) {
- if (it.value()->isSlotValid(ml)) {
- return it.value();
- }
- }
- return 0;
- }
- Symbol* SymbolTable::getAddressSymbol(const QString& label, bool case_sensitive)
- {
- for (QMultiMap<int, Symbol*>::iterator it = addressSymbols.begin();
- it != addressSymbols.end(); ++it) {
- if (it.value()->text().compare(label, Qt::CaseSensitive)==0)
- return it.value();
- if (!case_sensitive && it.value()->text().compare(label, Qt::CaseInsensitive)==0)
- return it.value();
- }
- return 0;
- }
- QStringList SymbolTable::labelList(bool include_vars, const MemoryLayout* ml) const
- {
- QStringList labels;
- for (QMultiMap<int, Symbol*>::const_iterator it = addressSymbols.begin();
- it != addressSymbols.end(); ++it)
- {
- if (it.value()->type() == Symbol::JUMPLABEL || (include_vars && it.value()->type() == Symbol::VARIABLELABEL ) )
- if( ml == 0 || it.value()->isSlotValid(ml) )
- labels << it.value()->text();
- }
- return labels;
- }
- int SymbolTable::symbolFilesSize() const
- {
- return symbolFiles.size();
- }
- const QString& SymbolTable::symbolFile(int index) const
- {
- return symbolFiles.at(index).fileName;
- }
- const QDateTime& SymbolTable::symbolFileRefresh(int index) const
- {
- return symbolFiles.at(index).refreshTime;
- }
- bool SymbolTable::readFile(const QString& filename, FileType type)
- {
- if (type == DETECT_FILE) {
- if (filename.toLower().endsWith(".map")) {
- // HiTech link map file
- type = LINKMAP_FILE;
- } else if (filename.toLower().endsWith(".sym")) {
- // auto detect which sym file
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream in(&file);
- QString line = in.readLine();
- if (line[0] == ';') {
- type = ASMSX_FILE;
- } else if (line.contains("; last def. pass")) {
- type = TNIASM0_FILE;
- } else if (line.contains(": %equ ")) {
- type = TNIASM1_FILE;
- } else if (line.contains(": equ ")) {
- type = SJASM_FILE;
- } else {
- // this is a blunt conclusion but I
- // don't know a way to detect this file
- // type
- type = HTC_FILE;
- }
- }
- } else {
- QString ext = filename.toLower();
- /* They are the same type of file. For some reason the Debian
- * manpage uses the extension ".sys"
- * pasmo doc -> pasmo [options] file.asm file.bin [file.symbol [file.publics] ]
- * pasmo manpage in Debian -> pasmo [options] file.asm file.bin [file.sys]
- */
- if (ext.endsWith(".symbol") || ext.endsWith(".publics") || ext.endsWith(".sys") ) {
- type = PASMO_FILE;
- }
- }
- }
- switch (type) {
- case TNIASM0_FILE:
- return readTNIASM0File(filename);
- case TNIASM1_FILE:
- return readTNIASM1File(filename);
- case SJASM_FILE:
- return readSJASMFile(filename);
- case ASMSX_FILE:
- return readASMSXFile(filename);
- case HTC_FILE:
- return readHTCFile(filename);
- case LINKMAP_FILE:
- return readLinkMapFile(filename);
- case PASMO_FILE:
- return readPASMOFile(filename);
- default:
- return false;
- }
- }
- void SymbolTable::appendFile(const QString& file, FileType type)
- {
- SymbolFileRecord rec;
- rec.fileName = file;
- rec.fileType = type;
- rec.refreshTime = QDateTime::currentDateTime();
- symbolFiles.append(rec);
- fileWatcher.addPath(file);
- }
- // Universal value parsing routine. Accepts:
- // - 0123h, 1234h, 1234H (hex)
- // - 0x1234 (hex)
- // - 1234 (dec)
- // - 0123 (oct)
- // The string may (optionally) end with a '; comment' part (with or without
- // whitespace around the ';' character).
- static bool parseValue(const QString& str, int& result)
- {
- QStringList l = str.split(";"); // ignore stuff after ';'
- QString s = l.at(0).trimmed();
- bool success;
- if (s.endsWith('h', Qt::CaseInsensitive)) {
- s.chop(1);
- result = s.toInt(&success, 16);
- } else {
- result = s.toInt(&success, 0); // any base (e.g. 0x..)
- }
- return success;
- }
- bool SymbolTable::readSymbolFile(
- const QString& filename, FileType type, const QString& equ)
- {
- QFile file(filename);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return false;
- }
- appendFile(filename, type);
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
- QStringList l = line.split(equ);
- if (l.size() != 2) continue;
- int value;
- if (!parseValue(l.at(1), value)) continue;
- Symbol* sym = new Symbol(l.at(0), value);
- sym->setSource(&symbolFiles.back().fileName);
- add(sym);
- }
- return true;
- }
- bool SymbolTable::readTNIASM0File(const QString& filename)
- {
- return readSymbolFile(filename, TNIASM0_FILE, ": equ ");
- }
- bool SymbolTable::readTNIASM1File(const QString& filename)
- {
- return readSymbolFile(filename, TNIASM1_FILE, ": %equ ");
- }
- bool SymbolTable::readSJASMFile(const QString& filename)
- {
- return readSymbolFile(filename, SJASM_FILE, ": equ ");
- }
- bool SymbolTable::readASMSXFile(const QString& filename)
- {
- QFile file( filename );
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return false;
- }
- appendFile(filename, ASMSX_FILE);
- QTextStream in(&file);
- int filePart = 0;
- while (!in.atEnd()) {
- QString line = in.readLine();
- if (line[0] == ';') {
- if (line.startsWith("; global and local")) {
- filePart = 1;
- } else if (line.startsWith("; other")) {
- filePart = 2;
- }
- } else {
- if ((line[0] == '$') || (line[4] == 'h') ||
- (line[5] == 'h') || (line[8] == 'h')) {
- if (filePart == 1) {
- QStringList l = line.split(" ");
- Symbol* sym;
- if (line[0] == '$') {
- sym = new Symbol(l.at(1).trimmed(), l.at(0).right(4).toInt(0, 16));
- } else if ((line[4] == 'h') || (line[5] == 'h')) {
- sym = new Symbol(l.at(1).trimmed(), l.at(0).mid(l.at(0).indexOf('h') - 4, 4).toInt(0, 16));
- } else {
- QString m = l.at(0);
- QStringList n = m.split(":"); // n.at(0) = MegaROM page
- sym = new Symbol(l.at(1).trimmed(), n.at(1).left(4).toInt(0, 16));
- }
- sym->setSource(&symbolFiles.back().fileName);
- add(sym);
- } else if (filePart == 2) {
- //
- }
- }
- }
- }
- return true;
- }
- bool SymbolTable::readPASMOFile(const QString& filename)
- {
- QFile file( filename );
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return false;
- }
- appendFile(filename, PASMO_FILE);
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line;
- QStringList l;
- Symbol* sym;
- line = in.readLine();
- l = line.split(QRegExp("(\t+)|( +)"));
- if (l.size() == 3) {
- sym = new Symbol(l.at(0), l.at(2).left(5).toInt(0, 16));
- sym->setSource(&symbolFiles.back().fileName);
- add(sym);
- }
- }
- return true;
- }
- bool SymbolTable::readHTCFile(const QString& filename)
- {
- QFile file(filename);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return false;
- }
- appendFile(filename, HTC_FILE);
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
- QStringList l = line.split(' ');
- if (l.size() != 3) continue;
- int value;
- if (!parseValue("0x" + l.at(1), value)) continue;
- Symbol* sym = new Symbol(l.at(0), value);
- sym->setSource(&symbolFiles.back().fileName);
- add(sym);
- }
- return true;
- }
- bool SymbolTable::readLinkMapFile(const QString& filename)
- {
- const QString magic("Machine type");
- const QString tableStart("*\tSymbol Table");
- QRegExp rx(" [0-9A-Fa-f]{4} (?![ 0-9])");
- QRegExp rp("^([^ ]+) +[^ ]* +([0-9A-Fa-f]{4}) $");
- QFile file(filename);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- return false;
- }
- appendFile(filename, LINKMAP_FILE);
- QTextStream in(&file);
- if (in.atEnd()) return false;
- if (!in.readLine().startsWith(magic)) return false;
- while (true) {
- if (in.atEnd()) return false;
- if (in.readLine().startsWith(tableStart)) break;
- }
- while (!in.atEnd()) {
- QString line = in.readLine();
- Q_ASSERT(!line.endsWith("\r"));
- if (line.isEmpty()) continue;
- line += " ";
- int len = line.length();
- int l;
- int pos = 0;
- bool ok = false;
- // HiTech uses multiple columns of non-fixed width and
- // a column for psect may be blank so the address may in
- // the first or second match.
- for (int tries = 0; (tries < 2) && !ok; ++tries) {
- pos = rx.indexIn(line, pos);
- l = pos + rx.matchedLength();
- if ((l > 0) && (len % l) == 0) {
- ok = true;
- for (int posn = pos + l; (posn < len) && ok; posn += l) {
- ok = (posn == rx.indexIn(line, posn));
- }
- }
- pos = l - 1;
- }
- if (!ok) continue;
- for (pos = 0; pos < len; pos += l) {
- QString part = line.mid(pos, l);
- if (rp.indexIn(part) == 0) {
- QStringList l = rp.capturedTexts();
- Symbol* sym = new Symbol(l.at(1), l.last().toInt(0, 16));
- sym->setSource(&symbolFiles.back().fileName);
- add(sym);
- }
- }
- }
- return true;
- }
- void SymbolTable::fileChanged(const QString & /*path*/)
- {
- emit symbolFileChanged();
- }
- void SymbolTable::reloadFiles()
- {
- for (int i = 0; i < symbolFiles.size(); ++i) {
- // check if file is newer
- QFileInfo fi = QFileInfo(symbolFiles[i].fileName);
- if (fi.lastModified() <= symbolFiles[i].refreshTime) continue;
- // file info
- QString name = symbolFiles[i].fileName;
- FileType type = symbolFiles[i].fileType;
- // symbol file is newer
- QMap<QString, Symbol> symCopy;
- // copy all symbols originating from this file
- QMutableListIterator<Symbol*> si(symbols);
- while (si.hasNext()) {
- si.next();
- if (si.value()->source() == &symbolFiles[i].fileName) {
- symCopy.insert(si.value()->text(), Symbol(*si.value()));
- }
- }
- // remove existing file
- unloadFile(name);
- // read the new file
- readFile(name, type);
- // find old symbols in newly loaded file
- QMutableListIterator<Symbol*> ni(symbols);
- QString* newFile = &symbolFiles.back().fileName;
- while (ni.hasNext()) {
- ni.next();
- if (ni.value()->source() != newFile) continue;
- // find symbol in old list
- QMap<QString, Symbol>::iterator sit = symCopy.find(ni.value()->text());
- if (sit == symCopy.end()) continue;
- // symbol existed before, copy settings
- ni.value()->setValidSlots(sit->validSlots());
- ni.value()->setValidRegisters(sit->validRegisters());
- ni.value()->setType(sit->type());
- if (sit->status() == Symbol::LOST) {
- ni.value()->setStatus(Symbol::ACTIVE);
- } else {
- ni.value()->setStatus(sit->status());
- }
- symCopy.erase(sit);
- }
- // all symbols left in map are lost
- for (QMap<QString, Symbol>::iterator sit = symCopy.begin();
- sit != symCopy.end(); ++sit) {
- Symbol* sym = new Symbol(sit.value());
- sym->setStatus(Symbol::LOST);
- sym->setSource(newFile);
- add(sym);
- }
- }
- }
- void SymbolTable::unloadFile(const QString& file, bool keepSymbols)
- {
- int index = -1;
- for (int i = 0; i < symbolFiles.size(); ++i) {
- if (symbolFiles[i].fileName == file) {
- index = i;
- break;
- }
- }
- if (index >= 0) {
- QString* name = &symbolFiles[index].fileName;
- if (!keepSymbols) {
- // remove symbols from address map
- QMutableMapIterator<int, Symbol*> mi(addressSymbols);
- while (mi.hasNext()) {
- mi.next();
- if (mi.value()->source() == name) mi.remove();
- }
- // remove symbols from value hash
- QMutableHashIterator<int, Symbol*> hi(valueSymbols);
- while (hi.hasNext()) {
- hi.next();
- if (hi.value()->source() == name) hi.remove();
- }
- }
- // remove symbols from value hash
- QMutableListIterator<Symbol*> i(symbols);
- while (i.hasNext()) {
- i.next();
- Symbol* sym = i.value();
- if (sym->source() == name) {
- if (keepSymbols) {
- sym->setSource(0);
- } else {
- i.remove();
- delete sym;
- }
- }
- }
- // remove record
- fileWatcher.removePath(symbolFiles[index].fileName);
- symbolFiles.removeAt(index);
- }
- }
- /*
- * Session loading/saving
- */
- void SymbolTable::saveSymbols(QXmlStreamWriter& xml)
- {
- // write files
- QMap<const QString*, int> fileIds;
- for (int i = 0; i < symbolFiles.size(); ++i) {
- // add id mapping
- fileIds[&symbolFiles[i].fileName] = i;
- // write element
- xml.writeStartElement("SymbolFile");
- switch (symbolFiles[i].fileType) {
- case TNIASM0_FILE:
- xml.writeAttribute("type","tniasm0");
- break;
- case TNIASM1_FILE:
- xml.writeAttribute("type","tniasm1");
- break;
- case ASMSX_FILE:
- xml.writeAttribute("type","asmsx");
- break;
- case LINKMAP_FILE:
- xml.writeAttribute("type","linkmap");
- break;
- default:
- break;
- }
- xml.writeAttribute("refreshTime",
- QString::number(symbolFiles[i].refreshTime.toTime_t()));
- xml.writeCharacters(symbolFiles[i].fileName);
- xml.writeEndElement();
- }
- // write symbols
- for (QList<Symbol*>::iterator sit = symbols.begin();
- sit != symbols.end(); ++sit) {
- Symbol* sym = *sit;
- xml.writeStartElement("Symbol");
- // status
- if (sym->status() == Symbol::HIDDEN) {
- xml.writeAttribute("status", "hidden");
- } else if (sym->status() == Symbol::LOST) {
- xml.writeAttribute("status", "lost");
- }
- // type
- if (sym->type() == Symbol::JUMPLABEL) {
- xml.writeTextElement("type", "jump");
- } else if (sym->type() == Symbol::VARIABLELABEL) {
- xml.writeTextElement("type", "variable");
- } else {
- xml.writeTextElement("type", "value");
- }
- // text, value, slots and registers
- xml.writeTextElement("name", sym->text());
- xml.writeTextElement("value", QString::number(sym->value()));
- xml.writeTextElement("validSlots", QString::number(sym->validSlots()));
- xml.writeTextElement("validRegisters", QString::number(sym->validRegisters()));
- // write source filename
- if (sym->source()) {
- xml.writeTextElement("source", QString::number(fileIds[sym->source()]));
- }
- // complete
- xml.writeEndElement();
- }
- }
- void SymbolTable::loadSymbols(QXmlStreamReader& xml)
- {
- Symbol* sym;
- while (!xml.atEnd()) {
- xml.readNext();
- // exit if closing of main tag
- if (xml.isEndElement() && xml.name() == "Symbols") break;
- // begin tag
- if (xml.isStartElement()) {
- if (xml.name() == "SymbolFile") {
- // read attributes and text
- QString ftype = xml.attributes().value("type").toString().toLower();
- QString rtime = xml.attributes().value("refreshTime").toString();
- QString fname = xml.readElementText();
- // check type
- FileType type = TNIASM0_FILE;
- if (ftype == "tniasm1") {
- type = TNIASM1_FILE;
- } else if (ftype == "asmsx") {
- type = ASMSX_FILE;
- } else if (ftype == "linkmap") {
- type = LINKMAP_FILE;
- }
- // append file
- appendFile(fname, type);
- // change time
- symbolFiles.back().refreshTime.setTime_t(rtime.toUInt());
- } else if (xml.name() == "Symbol") {
- // add empty symbol
- sym = new Symbol("", 0);
- add(sym);
- // get status attribute
- QString stat = xml.attributes().value("status").toString().toLower();
- if (stat == "hidden") {
- sym->setStatus(Symbol::HIDDEN);
- } else if( stat == "lost" ) {
- sym->setStatus(Symbol::LOST);
- }
- } else if (xml.name() == "type") {
- // read symbol type element
- QString type = xml.readElementText().trimmed().toLower();
- if (type == "jump") {
- sym->setType(Symbol::JUMPLABEL);
- } else if( type == "variable" ) {
- sym->setType(Symbol::VARIABLELABEL);
- } else if( type == "value" ) {
- sym->setType(Symbol::VALUE);
- }
- } else if (xml.name() == "name") {
- // read symbol name
- sym->setText(xml.readElementText());
- } else if (xml.name() == "value") {
- // read symbol value
- sym->setValue(xml.readElementText().toInt());
- } else if (xml.name() == "validSlots") {
- // read numeric valid slot mask
- sym->setValidSlots(xml.readElementText().toInt());
- } else if (xml.name() == "validRegisters") {
- // read numeric valid registers mask
- sym->setValidRegisters(xml.readElementText().toInt());
- } else if (xml.name() == "source") {
- // read source file id
- int id = xml.readElementText().toInt();
- if (id >= 0 && id < symbolFiles.size()) {
- sym->setSource(&symbolFiles[id].fileName);
- }
- }
- }
- }
- }
- // class Symbol
- Symbol::Symbol(const QString& str, int addr, int val)
- : symText(str), symValue(addr), symSlots(val)
- {
- symStatus = ACTIVE;
- symType = JUMPLABEL;
- symSource = 0;
- if (addr & 0xFF00) {
- symRegisters = REG_ALL16;
- } else {
- symRegisters = REG_ALL;
- }
- table = 0;
- }
- Symbol::Symbol(const Symbol& symbol)
- {
- table = 0;
- symStatus = symbol.symStatus;
- symText = symbol.symText;
- symValue = symbol.symValue;
- symSlots = symbol.symSlots;
- symSegments = symbol.symSegments;
- symRegisters = symbol.symRegisters;
- symSource = symbol.symSource;
- symType = symbol.symType;
- }
- const QString& Symbol::text() const
- {
- return symText;
- }
- void Symbol::setText(const QString& str)
- {
- symText = str;
- }
- int Symbol::value() const
- {
- return symValue;
- }
- void Symbol::setValue(int addr)
- {
- if (addr == symValue) return;
- symValue = addr;
- if (table) table->symbolValueChanged(this);
- }
- int Symbol::validSlots() const
- {
- return symSlots;
- }
- void Symbol::setValidSlots(int val)
- {
- symSlots = val & 0xFFFF;
- }
- int Symbol::validRegisters() const
- {
- return symRegisters;
- }
- void Symbol::setValidRegisters(int regs)
- {
- symRegisters = regs;
- if (symValue & 0xFF00) {
- symRegisters &= REG_ALL16;
- }
- }
- const QString* Symbol::source() const
- {
- return symSource;
- }
- void Symbol::setSource(const QString* name)
- {
- symSource = name;
- }
- Symbol::SymbolStatus Symbol::status() const
- {
- return symStatus;
- }
- void Symbol::setStatus(SymbolStatus s)
- {
- symStatus = s;
- }
- Symbol::SymbolType Symbol::type() const
- {
- return symType;
- }
- void Symbol::setType(SymbolType t)
- {
- if (symType == t) return;
- symType = t;
- if (table) table->symbolTypeChanged(this);
- }
- bool Symbol::isSlotValid(const MemoryLayout* ml) const
- {
- if (!ml) return true;
- int page = symValue >> 14;
- int ps = ml->primarySlot[page] & 3;
- int ss = 0;
- if (ml->isSubslotted[page]) ss = ml->secondarySlot[page] & 3;
- if (symSlots & (1 << (4 * ps + ss))) {
- if (symSegments.empty()) return true;
- for (int i = 0; i < symSegments.size(); ++i) {
- if (ml->mapperSegment[page] == symSegments[i]) {
- return true;
- }
- }
- }
- return false;
- }
|