mirror of
https://github.com/markdavidlong/AppleSAWS.git
synced 2026-03-10 23:25:02 +00:00
More cleanup of binaryfile/intbasicfile/textfile
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
#include "AssemblerSymbols.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
AssemblerSymbols::AssemblerSymbols(QObject *parent) : QObject(parent)
|
||||
AssemblerSymbols::AssemblerSymbols(QObject* parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -17,7 +19,9 @@ int AssemblerSymbols::locationOfSymbolAtAddress(quint16 address) const
|
||||
return symbol.address == address;
|
||||
});
|
||||
|
||||
return (it != m_assemblerSymbols.cend()) ? std::distance(m_assemblerSymbols.cbegin(), it) : -1;
|
||||
return (it != m_assemblerSymbols.cend())
|
||||
? static_cast<int>(std::distance(m_assemblerSymbols.cbegin(), it))
|
||||
: -1;
|
||||
}
|
||||
|
||||
QString AssemblerSymbols::getSymbolAtAddress(quint16 address) const
|
||||
@@ -26,7 +30,7 @@ QString AssemblerSymbols::getSymbolAtAddress(quint16 address) const
|
||||
return (loc >= 0) ? m_assemblerSymbols.at(loc).name : QString{};
|
||||
}
|
||||
|
||||
bool AssemblerSymbols::hasAssemSymbolAtAddress(quint16 address) const
|
||||
bool AssemblerSymbols::hasAssemSymbolAtAddress(quint16 address) const noexcept
|
||||
{
|
||||
// Use modern algorithm for better performance and clarity
|
||||
return std::any_of(m_assemblerSymbols.cbegin(), m_assemblerSymbols.cend(),
|
||||
@@ -35,7 +39,7 @@ bool AssemblerSymbols::hasAssemSymbolAtAddress(quint16 address) const
|
||||
});
|
||||
}
|
||||
|
||||
void AssemblerSymbols::editSymbol(int location, Symbol newSymbol)
|
||||
void AssemblerSymbols::editSymbol(int location, const Symbol& newSymbol)
|
||||
{
|
||||
|
||||
if (m_assemblerSymbols.at(location).address == newSymbol.address)
|
||||
@@ -50,19 +54,22 @@ void AssemblerSymbols::editSymbol(int location, Symbol newSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblerSymbols::addSymbol(Symbol ep)
|
||||
void AssemblerSymbols::addSymbol(const Symbol& ep)
|
||||
{
|
||||
if (hasAssemSymbolAtAddress(ep.address)) return;
|
||||
|
||||
const int totalSymbols = m_assemblerSymbols.count();
|
||||
int idx = 0;
|
||||
for (; idx < m_assemblerSymbols.count(); idx++)
|
||||
for (; idx < totalSymbols; ++idx)
|
||||
{
|
||||
if (ep.address < m_assemblerSymbols[idx].address)
|
||||
if (ep.address < m_assemblerSymbols.at(idx).address)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_assemblerSymbols.insert(idx,ep);
|
||||
m_assemblerSymbols.insert(idx, ep);
|
||||
emit symbolAddedAt(idx);
|
||||
emit symbolAdded(ep,idx);
|
||||
emit symbolAdded(m_assemblerSymbols.at(idx), idx);
|
||||
}
|
||||
|
||||
void AssemblerSymbols::removeSymbolAt(int location)
|
||||
@@ -73,7 +80,7 @@ void AssemblerSymbols::removeSymbolAt(int location)
|
||||
//---------------------------------------------------------------------------
|
||||
// STREAMING OPERATORS
|
||||
|
||||
QDataStream &AssemblerSymbols::read(QDataStream &dataStream)
|
||||
QDataStream& AssemblerSymbols::read(QDataStream& dataStream)
|
||||
{
|
||||
quint8 version;
|
||||
dataStream >> version;
|
||||
@@ -81,30 +88,33 @@ QDataStream &AssemblerSymbols::read(QDataStream &dataStream)
|
||||
{
|
||||
dataStream >> m_assemblerSymbols;
|
||||
}
|
||||
else qWarning("Unhandled version of AssemSymbolModel (%d) found in QDataStream",version);
|
||||
else
|
||||
{
|
||||
qWarning().noquote() << QStringLiteral("Unhandled version of AssemSymbolModel (%1) found in QDataStream").arg(version);
|
||||
}
|
||||
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
QDataStream &AssemblerSymbols::write(QDataStream &dataStream) const
|
||||
QDataStream& AssemblerSymbols::write(QDataStream& dataStream) const
|
||||
{
|
||||
quint8 version = 0; // Increment this and update read() if new items are added
|
||||
constexpr quint8 version = 0; // Increment this and update read() if new items are added
|
||||
dataStream << version;
|
||||
dataStream << m_assemblerSymbols;
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const AssemblerSymbols &model)
|
||||
QDataStream& operator<<(QDataStream& out, const AssemblerSymbols& model)
|
||||
{
|
||||
return model.write(out);
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, AssemblerSymbols&model)
|
||||
QDataStream& operator>>(QDataStream& in, AssemblerSymbols& model)
|
||||
{
|
||||
return model.read(in);
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const AssemblerSymbols::Symbol &model)
|
||||
QDataStream& operator<<(QDataStream& out, const AssemblerSymbols::Symbol& model)
|
||||
{
|
||||
out << model.address;
|
||||
out << model.name;
|
||||
@@ -112,7 +122,7 @@ QDataStream &operator<<(QDataStream &out, const AssemblerSymbols::Symbol &model)
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, AssemblerSymbols::Symbol &model)
|
||||
QDataStream& operator>>(QDataStream& in, AssemblerSymbols::Symbol& model)
|
||||
{
|
||||
in >> model.address;
|
||||
in >> model.name;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QDataStream>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class AssemblerSymbols : public QObject
|
||||
{
|
||||
@@ -12,24 +14,24 @@ public:
|
||||
Word = 2
|
||||
};
|
||||
|
||||
struct Symbol {
|
||||
struct Symbol final {
|
||||
quint16 address{0};
|
||||
QString name{};
|
||||
SymbolSize symbolsize{SymbolSize::Byte};
|
||||
};
|
||||
|
||||
explicit AssemblerSymbols(QObject *parent = nullptr);
|
||||
explicit AssemblerSymbols(QObject* parent = nullptr);
|
||||
|
||||
[[nodiscard]] bool hasAssemSymbolAtAddress(quint16 address) const;
|
||||
[[nodiscard]] bool hasAssemSymbolAtAddress(quint16 address) const noexcept;
|
||||
|
||||
[[nodiscard]] const Symbol &at(int location) const { return m_assemblerSymbols.at(location); }
|
||||
[[nodiscard]] Symbol &symbolRefAt(int location) { return m_assemblerSymbols[location]; }
|
||||
[[nodiscard]] Symbol &operator[](int location) { return m_assemblerSymbols[location]; }
|
||||
[[nodiscard]] const Symbol& at(int location) const { return m_assemblerSymbols.at(location); }
|
||||
[[nodiscard]] Symbol& symbolRefAt(int location) { return m_assemblerSymbols[location]; }
|
||||
[[nodiscard]] Symbol& operator[](int location) { return m_assemblerSymbols[location]; }
|
||||
|
||||
void editSymbol(int at, Symbol newSymbol);
|
||||
void editSymbol(int at, const Symbol& newSymbol);
|
||||
|
||||
[[nodiscard]] QDataStream &read(QDataStream &dataStream);
|
||||
[[nodiscard]] QDataStream &write(QDataStream &dataStream) const;
|
||||
[[nodiscard]] QDataStream& read(QDataStream& dataStream);
|
||||
[[nodiscard]] QDataStream& write(QDataStream& dataStream) const;
|
||||
|
||||
[[nodiscard]] int numAssemblerSymbols() const noexcept { return m_assemblerSymbols.count(); }
|
||||
|
||||
@@ -39,23 +41,23 @@ public:
|
||||
[[nodiscard]] QString getSymbolAtAddress(quint16 address) const;
|
||||
|
||||
signals:
|
||||
void symbolAdded(Symbol &symbol, int location);
|
||||
void symbolAdded(const Symbol& symbol, int location);
|
||||
void symbolAddedAt(int location);
|
||||
void symbolRemovedAt(int location);
|
||||
void symbolChangedAt(int location);
|
||||
|
||||
public slots:
|
||||
void addSymbol(Symbol ep);
|
||||
void addSymbol(const Symbol& ep);
|
||||
void removeSymbolAt(int location);
|
||||
|
||||
protected:
|
||||
QList<Symbol> m_assemblerSymbols;
|
||||
};
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const AssemblerSymbols &model);
|
||||
QDataStream &operator>>(QDataStream &in, AssemblerSymbols &model);
|
||||
QDataStream& operator<<(QDataStream& out, const AssemblerSymbols& model);
|
||||
QDataStream& operator>>(QDataStream& in, AssemblerSymbols& model);
|
||||
|
||||
// Serialization operators for Symbol struct
|
||||
QDataStream &operator<<(QDataStream &out, const AssemblerSymbols::Symbol &symbol);
|
||||
QDataStream &operator>>(QDataStream &in, AssemblerSymbols::Symbol &symbol);
|
||||
QDataStream& operator<<(QDataStream& out, const AssemblerSymbols::Symbol& symbol);
|
||||
QDataStream& operator>>(QDataStream& in, AssemblerSymbols::Symbol& symbol);
|
||||
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
#include "BinaryFile.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QLatin1Char>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr qsizetype MetadataSize{4};
|
||||
}
|
||||
|
||||
BinaryFile::BinaryFile(const QByteArray& data) : GenericFile(data)
|
||||
{
|
||||
@@ -15,19 +22,28 @@ BinaryFile::BinaryFile(const QByteArray& data) : GenericFile(data)
|
||||
|
||||
void BinaryFile::setData(const QByteArray& data)
|
||||
{
|
||||
if (data.length() >= 4) {
|
||||
QByteArray metadata = data.left(4);
|
||||
m_data = data.mid(4);
|
||||
setAddress(makeWord(metadata[0],metadata[1]));
|
||||
m_length = makeWord(metadata[2],metadata[3]);
|
||||
}
|
||||
GenericFile::setData(data);
|
||||
|
||||
if (data.size() < MetadataSize) {
|
||||
m_data.clear();
|
||||
m_length = 0;
|
||||
setAddress(0U);
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray metadata = data.first(MetadataSize);
|
||||
m_data = data.mid(MetadataSize);
|
||||
setAddress(makeWord(static_cast<quint8>(metadata[0]), static_cast<quint8>(metadata[1])));
|
||||
m_length = makeWord(static_cast<quint8>(metadata[2]), static_cast<quint8>(metadata[3]));
|
||||
}
|
||||
|
||||
void BinaryFile::dump()
|
||||
void BinaryFile::dump() const
|
||||
{
|
||||
qDebug() << QString("Address: %1 Length: %2")
|
||||
.arg((quint16) address(),4,16,QChar('0'))
|
||||
.arg(m_length,4,16,QChar('0')).toUpper();
|
||||
qDebug() << QString("Data Length Recorded: %1")
|
||||
.arg(m_data.length(),4,16,QChar('0')).toUpper();
|
||||
const QString addressHex = uint16ToHex(address());
|
||||
const QString lengthHex = uint16ToHex(m_length);
|
||||
const QString recordedLengthHex = QStringLiteral("%1").arg(m_data.size(), 4, 16, QLatin1Char('0')).toUpper();
|
||||
|
||||
qDebug().noquote() << QStringLiteral("Address: %1 Length: %2")
|
||||
.arg(addressHex, lengthHex);
|
||||
qDebug().noquote() << QStringLiteral("Data Length Recorded: %1").arg(recordedLengthHex);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ public:
|
||||
explicit BinaryFile(const QByteArray& data = QByteArray());
|
||||
void setData(const QByteArray& data) override;
|
||||
|
||||
[[nodiscard]] virtual quint16 length() const noexcept override { return m_length; }
|
||||
[[nodiscard]] quint16 length() const noexcept override { return m_length; }
|
||||
|
||||
void dump();
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,63 +1,87 @@
|
||||
#include "BinaryFileMetadata.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
||||
BinaryFileMetadata::BinaryFileMetadata(GenericFile &file, quint16 defaultAddress, QObject *parent)
|
||||
: QObject(parent), m_file(file), m_defaultAddress(defaultAddress)
|
||||
{
|
||||
EntryPoint p {defaultAddress, "Start"};
|
||||
EntryPoint p {defaultAddress, QStringLiteral("Start")};
|
||||
m_eps.addPoint(p);
|
||||
//load();
|
||||
}
|
||||
|
||||
QString BinaryFileMetadata::filename() const
|
||||
{
|
||||
return m_file.filename();
|
||||
}
|
||||
|
||||
QString BinaryFileMetadata::metadataFilePath() const
|
||||
{
|
||||
const DiskFile* const disk = m_file.diskFile();
|
||||
if (disk == nullptr)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const QString basePath = disk->getMetaDataPath();
|
||||
QDir dir(basePath);
|
||||
if (!dir.exists())
|
||||
{
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
|
||||
return dir.filePath(QStringLiteral("%1.bfm").arg(m_file.filename()));
|
||||
}
|
||||
|
||||
void BinaryFileMetadata::load()
|
||||
{
|
||||
QFile infile(QString("%1%2%3")
|
||||
.arg(m_file.diskFile()->getMetaDataPath())
|
||||
.arg(m_file.filename())
|
||||
.arg(".bfm"));
|
||||
const QString metadataPath = metadataFilePath();
|
||||
if (metadataPath.isEmpty())
|
||||
{
|
||||
qWarning().noquote() << QStringLiteral("Cannot load BinaryFile metadata: disk file is not associated");
|
||||
return;
|
||||
}
|
||||
|
||||
QFile infile(metadataPath);
|
||||
if (infile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
qDebug() << "Loading binary file metadata from" << QString("%1%2%3")
|
||||
.arg(m_file.diskFile()->getMetaDataPath())
|
||||
.arg(m_file.filename())
|
||||
.arg(".bfm");
|
||||
qDebug().noquote() << QStringLiteral("Loading binary file metadata from %1").arg(QDir::toNativeSeparators(metadataPath));
|
||||
QDataStream ds(&infile);
|
||||
ds >> m_eps;
|
||||
ds >> m_as;
|
||||
infile.close();
|
||||
}
|
||||
else qDebug() << "Cannot open " << QString("%1%2%3")
|
||||
.arg(m_file.diskFile()->getMetaDataPath())
|
||||
.arg(m_file.filename())
|
||||
.arg(".bfm") << "for reading";
|
||||
|
||||
else
|
||||
{
|
||||
qWarning().noquote() << QStringLiteral("Cannot open %1 for reading")
|
||||
.arg(QDir::toNativeSeparators(metadataPath));
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryFileMetadata::save()
|
||||
{
|
||||
QFile outfile(QString("%1%2%3")
|
||||
.arg(m_file.diskFile()->getMetaDataPath())
|
||||
.arg(m_file.filename())
|
||||
.arg(".bfm"));
|
||||
const QString metadataPath = metadataFilePath();
|
||||
if (metadataPath.isEmpty())
|
||||
{
|
||||
qWarning().noquote() << QStringLiteral("Cannot save BinaryFile metadata: disk file is not associated");
|
||||
return;
|
||||
}
|
||||
|
||||
QFile outfile(metadataPath);
|
||||
if (outfile.open(QIODevice::WriteOnly))
|
||||
{
|
||||
qDebug() << "Saving binary file metadata to" << QString("%1%2%3")
|
||||
.arg(m_file.diskFile()->getMetaDataPath())
|
||||
.arg(m_file.filename())
|
||||
.arg(".bfm");
|
||||
qDebug().noquote() << QStringLiteral("Saving binary file metadata to %1").arg(QDir::toNativeSeparators(metadataPath));
|
||||
QDataStream ds(&outfile);
|
||||
ds << m_eps;
|
||||
ds << m_as;
|
||||
outfile.close();
|
||||
}
|
||||
else qDebug() << "Cannot open " << QString("%1%2%3")
|
||||
.arg(m_file.diskFile()->getMetaDataPath())
|
||||
.arg(m_file.filename())
|
||||
.arg(".bfm") << "for writing";
|
||||
|
||||
else
|
||||
{
|
||||
qWarning().noquote() << QStringLiteral("Cannot open %1 for writing")
|
||||
.arg(QDir::toNativeSeparators(metadataPath));
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryFileMetadata::requestDisassembly()
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "EntryPoints.h"
|
||||
#include "AssemblerSymbols.h"
|
||||
#include "EntryPoints.h"
|
||||
#include "GenericFile.h"
|
||||
|
||||
#include <Qt>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
|
||||
|
||||
|
||||
class BinaryFileMetadata : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BinaryFileMetadata(GenericFile &file, quint16 defaultAddress, QObject *parent = nullptr);
|
||||
explicit BinaryFileMetadata(GenericFile& file, quint16 defaultAddress, QObject* parent = nullptr);
|
||||
~BinaryFileMetadata() override = default;
|
||||
|
||||
[[nodiscard]] QString filename() const { return m_file.filename(); }
|
||||
BinaryFileMetadata(const BinaryFileMetadata&) = delete;
|
||||
BinaryFileMetadata& operator=(const BinaryFileMetadata&) = delete;
|
||||
BinaryFileMetadata(BinaryFileMetadata&&) = delete;
|
||||
BinaryFileMetadata& operator=(BinaryFileMetadata&&) = delete;
|
||||
|
||||
[[nodiscard]] EntryPoints &entryPoints() noexcept { return m_eps; }
|
||||
[[nodiscard]] AssemblerSymbols &assemblerSymbols() noexcept { return m_as; }
|
||||
[[nodiscard]] QString filename() const;
|
||||
|
||||
[[nodiscard]] EntryPoints& entryPoints() noexcept { return m_eps; }
|
||||
[[nodiscard]] const EntryPoints& entryPoints() const noexcept { return m_eps; }
|
||||
|
||||
[[nodiscard]] AssemblerSymbols& assemblerSymbols() noexcept { return m_as; }
|
||||
[[nodiscard]] const AssemblerSymbols& assemblerSymbols() const noexcept { return m_as; }
|
||||
|
||||
signals:
|
||||
void doDisassemble(QList<quint16>);
|
||||
@@ -33,10 +36,12 @@ public slots:
|
||||
void requestDisassembly();
|
||||
|
||||
private:
|
||||
[[nodiscard]] QString metadataFilePath() const;
|
||||
|
||||
AssemblerSymbols m_as;
|
||||
EntryPoints m_eps;
|
||||
|
||||
GenericFile &m_file;
|
||||
GenericFile& m_file;
|
||||
|
||||
quint16 m_defaultAddress{0};
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <iterator>
|
||||
|
||||
|
||||
EntryPoints::EntryPoints(QObject *parent) : QObject(parent)
|
||||
EntryPoints::EntryPoints(QObject* parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -15,13 +15,13 @@ bool EntryPoints::hasEntryPointAtAddress(quint16 address) const noexcept
|
||||
{
|
||||
// Use binary search since list is sorted by address - O(log n)
|
||||
return std::binary_search(m_entryPoints.begin(), m_entryPoints.end(),
|
||||
EntryPoint{address, QString()},
|
||||
EntryPoint{address, {}},
|
||||
[](const EntryPoint& a, const EntryPoint& b) {
|
||||
return a.address < b.address;
|
||||
});
|
||||
}
|
||||
|
||||
void EntryPoints::editPoint(int location, EntryPoint newPoint)
|
||||
void EntryPoints::editPoint(int location, const EntryPoint& newPoint)
|
||||
{
|
||||
|
||||
if (m_entryPoints.at(location).address == newPoint.address)
|
||||
@@ -36,7 +36,7 @@ void EntryPoints::editPoint(int location, EntryPoint newPoint)
|
||||
}
|
||||
}
|
||||
|
||||
void EntryPoints::addPoint(EntryPoint ep)
|
||||
void EntryPoints::addPoint(const EntryPoint& ep)
|
||||
{
|
||||
if (hasEntryPointAtAddress(ep.address)) return;
|
||||
|
||||
@@ -46,10 +46,10 @@ void EntryPoints::addPoint(EntryPoint ep)
|
||||
return a.address < b.address;
|
||||
});
|
||||
|
||||
int idx = std::distance(m_entryPoints.begin(), it);
|
||||
const int idx = static_cast<int>(std::distance(m_entryPoints.begin(), it));
|
||||
m_entryPoints.insert(it, ep);
|
||||
emit pointAddedAt(idx);
|
||||
emit pointAdded(ep, idx);
|
||||
emit pointAdded(m_entryPoints.at(idx), idx);
|
||||
}
|
||||
|
||||
void EntryPoints::removePointAt(int location)
|
||||
@@ -60,7 +60,7 @@ void EntryPoints::removePointAt(int location)
|
||||
//---------------------------------------------------------------------------
|
||||
// STREAMING OPERATORS
|
||||
|
||||
QDataStream &EntryPoints::read(QDataStream &dataStream)
|
||||
QDataStream& EntryPoints::read(QDataStream& dataStream)
|
||||
{
|
||||
quint8 version;
|
||||
dataStream >> version;
|
||||
@@ -68,14 +68,17 @@ QDataStream &EntryPoints::read(QDataStream &dataStream)
|
||||
{
|
||||
dataStream >> m_entryPoints;
|
||||
}
|
||||
else qWarning("Unhandled version of EntryPointModel (%d) found in QDataStream",version);
|
||||
else
|
||||
{
|
||||
qWarning().noquote() << QStringLiteral("Unhandled version of EntryPointModel (%1) found in QDataStream").arg(version);
|
||||
}
|
||||
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
QDataStream &EntryPoints::write(QDataStream &dataStream) const
|
||||
QDataStream& EntryPoints::write(QDataStream& dataStream) const
|
||||
{
|
||||
quint8 version = 0; // Increment this and update read() if new items are added
|
||||
constexpr quint8 version = 0; // Increment this and update read() if new items are added
|
||||
dataStream << version;
|
||||
dataStream << m_entryPoints;
|
||||
return dataStream;
|
||||
@@ -93,24 +96,24 @@ QList<quint16> EntryPoints::getEntryPointAddresses() const
|
||||
return retval;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const EntryPoints &model)
|
||||
QDataStream& operator<<(QDataStream& out, const EntryPoints& model)
|
||||
{
|
||||
return model.write(out);
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, EntryPoints&model)
|
||||
QDataStream& operator>>(QDataStream& in, EntryPoints& model)
|
||||
{
|
||||
return model.read(in);
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const EntryPoint &model)
|
||||
QDataStream& operator<<(QDataStream& out, const EntryPoint& model)
|
||||
{
|
||||
out << model.address;
|
||||
out << model.note;
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, EntryPoint &model)
|
||||
QDataStream& operator>>(QDataStream& in, EntryPoint& model)
|
||||
{
|
||||
in >> model.address;
|
||||
in >> model.note;
|
||||
@@ -123,16 +126,9 @@ QDataStream &operator>>(QDataStream &in, EntryPoint &model)
|
||||
|
||||
void EntryPoints::doTestData()
|
||||
{
|
||||
EntryPoint ep;
|
||||
ep.address = 0x0010;
|
||||
ep.note = "Test Entry Point 1";
|
||||
addPoint(ep);
|
||||
ep.address = 0x0020;
|
||||
ep.note = "Test Entry Point 2";
|
||||
addPoint(ep);
|
||||
ep.address = 0x0030;
|
||||
ep.note = "Test Entry Point 3";
|
||||
addPoint(ep);
|
||||
addPoint(EntryPoint{0x0010, QStringLiteral("Test Entry Point 1")});
|
||||
addPoint(EntryPoint{0x0020, QStringLiteral("Test Entry Point 2")});
|
||||
addPoint(EntryPoint{0x0030, QStringLiteral("Test Entry Point 3")});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QListIterator>
|
||||
#include <QDataStream>
|
||||
|
||||
struct EntryPoint {
|
||||
struct EntryPoint final {
|
||||
quint16 address{0};
|
||||
QString note;
|
||||
};
|
||||
@@ -19,18 +18,18 @@ class EntryPoints : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EntryPoints(QObject *parent = nullptr);
|
||||
explicit EntryPoints(QObject* parent = nullptr);
|
||||
|
||||
[[nodiscard]] bool hasEntryPointAtAddress(quint16 address) const noexcept;
|
||||
|
||||
[[nodiscard]] const EntryPoint &at(int location) const { return m_entryPoints.at(location); }
|
||||
[[nodiscard]] EntryPoint &pointRefAt(int location) { return m_entryPoints[location]; }
|
||||
[[nodiscard]] EntryPoint &operator[](int location) { return m_entryPoints[location]; }
|
||||
[[nodiscard]] const EntryPoint& at(int location) const { return m_entryPoints.at(location); }
|
||||
[[nodiscard]] EntryPoint& pointRefAt(int location) { return m_entryPoints[location]; }
|
||||
[[nodiscard]] EntryPoint& operator[](int location) { return m_entryPoints[location]; }
|
||||
|
||||
void editPoint(int at, EntryPoint newPoint);
|
||||
void editPoint(int at, const EntryPoint& newPoint);
|
||||
|
||||
QDataStream &read(QDataStream &dataStream);
|
||||
[[nodiscard]] QDataStream &write(QDataStream &dataStream) const;
|
||||
QDataStream& read(QDataStream& dataStream);
|
||||
[[nodiscard]] QDataStream& write(QDataStream& dataStream) const;
|
||||
|
||||
[[nodiscard]] int numEntryPoints() const noexcept { return m_entryPoints.count(); }
|
||||
|
||||
@@ -39,19 +38,19 @@ public:
|
||||
void doTestData();
|
||||
|
||||
signals:
|
||||
void pointAdded(EntryPoint &entryPoint, int location);
|
||||
void pointAdded(const EntryPoint& entryPoint, int location);
|
||||
void pointAddedAt(int location);
|
||||
void pointRemovedAt(int location);
|
||||
void pointChangedAt(int location);
|
||||
|
||||
public slots:
|
||||
void addPoint(EntryPoint ep);
|
||||
void addPoint(const EntryPoint& ep);
|
||||
void removePointAt(int location);
|
||||
|
||||
protected:
|
||||
QList<EntryPoint> m_entryPoints;
|
||||
};
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const EntryPoints &model);
|
||||
QDataStream &operator>>(QDataStream &in, EntryPoints &model);
|
||||
QDataStream& operator<<(QDataStream& out, const EntryPoints& model);
|
||||
QDataStream& operator>>(QDataStream& in, EntryPoints& model);
|
||||
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
#include <QDebug>
|
||||
|
||||
IntBasicFile::IntBasicFile(const QByteArray& data) noexcept
|
||||
: GenericFile(data)
|
||||
{
|
||||
setData(data);
|
||||
if (data.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << detokenize();
|
||||
|
||||
setData(detokenize());
|
||||
const QByteArray detokenized = detokenize();
|
||||
qDebug().noquote() << detokenized;
|
||||
setData(detokenized);
|
||||
}
|
||||
|
||||
QByteArray IntBasicFile::detokenize()
|
||||
QByteArray IntBasicFile::detokenize() const
|
||||
{
|
||||
return dumpBufferAsIntBasicFile(data());
|
||||
}
|
||||
@@ -135,14 +139,17 @@ QByteArray IntBasicFile::dumpBufferAsIntBasicFile(const QByteArray& origdata) co
|
||||
QByteArray retval;
|
||||
|
||||
QList<quint8> data;
|
||||
QByteArray data0 = origdata;
|
||||
data.reserve(static_cast<int>(origdata.size()));
|
||||
|
||||
|
||||
foreach (quint8 value, origdata)
|
||||
for (const auto byte : origdata)
|
||||
{
|
||||
data.append(value);
|
||||
data.append(static_cast<quint8>(static_cast<unsigned char>(byte)));
|
||||
}
|
||||
|
||||
if (!data.isEmpty())
|
||||
{
|
||||
data.removeFirst();
|
||||
}
|
||||
data.removeFirst();
|
||||
|
||||
// int alen = get16(data[0],data[1]);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
IntBasicFile(IntBasicFile&&) = default;
|
||||
IntBasicFile& operator=(IntBasicFile&&) = default;
|
||||
|
||||
[[nodiscard]] QByteArray detokenize();
|
||||
[[nodiscard]] QByteArray detokenize() const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] static constexpr quint16 get16(quint8 v1, quint8 v2) noexcept;
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#include "RelocatableFile.h"
|
||||
#include <QDebug>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr qsizetype HeaderSize{6};
|
||||
}
|
||||
|
||||
// This file format is documented in the "Apple 6502 Assembler/Editor" manual.
|
||||
|
||||
RelocatableFile::RelocatableFile(const QByteArray &data) noexcept
|
||||
RelocatableFile::RelocatableFile(const QByteArray& data) noexcept
|
||||
: GenericFile(data)
|
||||
{
|
||||
if (!data.isEmpty())
|
||||
@@ -12,78 +17,82 @@ RelocatableFile::RelocatableFile(const QByteArray &data) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
void RelocatableFile::setData(const QByteArray &data)
|
||||
void RelocatableFile::setData(const QByteArray& data)
|
||||
{
|
||||
if (data.length() >= 6)
|
||||
GenericFile::setData(data);
|
||||
if (data.size() < HeaderSize)
|
||||
{
|
||||
m_starting_ram_address = makeWord(m_data[0], m_data[1]);
|
||||
m_address = m_starting_ram_address;
|
||||
m_ram_image_length = makeWord(m_data[2], m_data[3]);
|
||||
m_code_image_length = makeWord(m_data[4], m_data[5]);
|
||||
m_starting_ram_address = 0;
|
||||
m_ram_image_length = 0;
|
||||
m_code_image_length = 0;
|
||||
m_binary_code_image.clear();
|
||||
m_relocatable_dict.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
m_data = m_data.mid(6);
|
||||
int offset = 0;
|
||||
m_starting_ram_address = makeWord(static_cast<quint8>(data[0]), static_cast<quint8>(data[1]));
|
||||
setAddress(m_starting_ram_address);
|
||||
m_ram_image_length = makeWord(static_cast<quint8>(data[2]), static_cast<quint8>(data[3]));
|
||||
m_code_image_length = makeWord(static_cast<quint8>(data[4]), static_cast<quint8>(data[5]));
|
||||
|
||||
for (int idx = 0; idx < m_code_image_length; idx++)
|
||||
m_binary_code_image.clear();
|
||||
m_relocatable_dict.clear();
|
||||
|
||||
m_data = data.mid(HeaderSize);
|
||||
m_binary_code_image = m_data.left(m_code_image_length);
|
||||
|
||||
const qsizetype dictionaryStart = m_code_image_length;
|
||||
const qsizetype dictionaryLength = m_data.size() - dictionaryStart;
|
||||
|
||||
for (qsizetype offset = 0; offset + 3 < dictionaryLength; offset += 4)
|
||||
{
|
||||
const qsizetype index = dictionaryStart + offset;
|
||||
const RelocatableDictItem rdi{static_cast<quint8>(m_data[index]),
|
||||
static_cast<quint8>(m_data[index + 1]),
|
||||
static_cast<quint8>(m_data[index + 2]),
|
||||
static_cast<quint8>(m_data[index + 3])};
|
||||
if (rdi.isEndOfRLD())
|
||||
{
|
||||
quint8 val = m_data[idx];
|
||||
m_binary_code_image.append(val);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int N = 0; N < (m_code_image_length); N += 4)
|
||||
{
|
||||
|
||||
offset = m_code_image_length + N;
|
||||
|
||||
// qDebug() << "N: " << N << uint8ToHex(m_data[offset])
|
||||
// << uint8ToHex(m_data[offset+1])
|
||||
// << uint8ToHex(m_data[offset+2])
|
||||
// << uint8ToHex(m_data[offset+3]);
|
||||
|
||||
RelocatableDictItem rdi = RelocatableDictItem(m_data[offset], m_data[offset + 1],
|
||||
m_data[offset + 2], m_data[offset + 3]);
|
||||
if (rdi.isEndOfRLD())
|
||||
{
|
||||
break;
|
||||
}
|
||||
m_relocatable_dict.append(rdi);
|
||||
}
|
||||
|
||||
// m_data = m_binary_code_image;
|
||||
m_relocatable_dict.append(rdi);
|
||||
}
|
||||
}
|
||||
|
||||
void RelocatableFile::dump()
|
||||
{
|
||||
qDebug() << "\nTotalLength: " << length();
|
||||
qDebug() << "Starting Ram Address: " << m_starting_ram_address << uint16ToHex(m_starting_ram_address);
|
||||
qDebug() << "Length of Ram Image: " << m_ram_image_length << uint16ToHex(m_ram_image_length);
|
||||
qDebug() << "Length of Code Image: " << m_code_image_length << uint16ToHex(m_code_image_length);
|
||||
qDebug().noquote() << QStringLiteral("\nTotalLength: %1").arg(length());
|
||||
qDebug().noquote() << QStringLiteral("Starting RAM Address: %1 (%2)")
|
||||
.arg(QString::number(m_starting_ram_address), uint16ToHex(m_starting_ram_address));
|
||||
qDebug().noquote() << QStringLiteral("Length of RAM Image: %1 (%2)")
|
||||
.arg(QString::number(m_ram_image_length), uint16ToHex(m_ram_image_length));
|
||||
qDebug().noquote() << QStringLiteral("Length of Code Image: %1 (%2)")
|
||||
.arg(QString::number(m_code_image_length), uint16ToHex(m_code_image_length));
|
||||
|
||||
int itemIdx = 0;
|
||||
for (const auto &item : m_relocatable_dict)
|
||||
for (const auto& item : m_relocatable_dict)
|
||||
{
|
||||
const auto b4rt = item.getByte4();
|
||||
QString typestr;
|
||||
if (b4rt.first == RelocatableTypes::Byte4Type::ESDSymbol)
|
||||
{
|
||||
typestr = QStringLiteral("ESDSymbol");
|
||||
}
|
||||
else if (b4rt.first == RelocatableTypes::Byte4Type::ByteHi)
|
||||
{
|
||||
typestr = QStringLiteral("Hi Byte");
|
||||
}
|
||||
else
|
||||
{
|
||||
typestr = QStringLiteral("Lo Byte");
|
||||
}
|
||||
const quint16 fo = item.getFieldOffset();
|
||||
qDebug() << " Item #" << itemIdx++
|
||||
<< "Field Offset: " << uint16ToHex(fo)
|
||||
<< "FieldSize: " << ((item.getFieldSize() == RelocatableTypes::FieldSize::TwoByte) ? "2-Byte" : "1-Byte")
|
||||
<< typestr << uint8ToHex(b4rt.second)
|
||||
<< ((item.isNotEndOfRLD()) ? "NotEndOfRLD" : "EndOfRLD")
|
||||
<< " " << ((item.isExtern()) ? "Extern" : "Not Extern");
|
||||
const QString typeString = (b4rt.first == RelocatableTypes::Byte4Type::ESDSymbol)
|
||||
? QStringLiteral("ESDSymbol")
|
||||
: (b4rt.first == RelocatableTypes::Byte4Type::ByteHi)
|
||||
? QStringLiteral("Hi Byte")
|
||||
: QStringLiteral("Lo Byte");
|
||||
const quint16 fieldOffset = item.getFieldOffset();
|
||||
const QString fieldSize = (item.getFieldSize() == RelocatableTypes::FieldSize::TwoByte)
|
||||
? QStringLiteral("2-Byte")
|
||||
: QStringLiteral("1-Byte");
|
||||
const QString rldState = item.isNotEndOfRLD() ? QStringLiteral("NotEndOfRLD") : QStringLiteral("EndOfRLD");
|
||||
const QString externState = item.isExtern() ? QStringLiteral("Extern") : QStringLiteral("Not Extern");
|
||||
|
||||
qDebug().noquote() << QStringLiteral(" Item #%1 Field Offset: %2 FieldSize: %3 %4 %5 %6 %7")
|
||||
.arg(itemIdx++)
|
||||
.arg(uint16ToHex(fieldOffset))
|
||||
.arg(fieldSize)
|
||||
.arg(typeString)
|
||||
.arg(uint8ToHex(b4rt.second))
|
||||
.arg(rldState)
|
||||
.arg(externState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,30 +100,28 @@ QStringList RelocatableFile::decodeRelocatableDict() const
|
||||
{
|
||||
QStringList retval;
|
||||
int idx = 0;
|
||||
for (const auto &item : m_relocatable_dict)
|
||||
for (const auto& item : m_relocatable_dict)
|
||||
{
|
||||
const auto b4rt = item.getByte4();
|
||||
QString typestr;
|
||||
if (b4rt.first == RelocatableTypes::Byte4Type::ESDSymbol)
|
||||
{
|
||||
typestr = QStringLiteral("ESDSymbol");
|
||||
}
|
||||
else if (b4rt.first == RelocatableTypes::Byte4Type::ByteHi)
|
||||
{
|
||||
typestr = QStringLiteral("Hi Byte");
|
||||
}
|
||||
else
|
||||
{
|
||||
typestr = QStringLiteral("Lo Byte");
|
||||
}
|
||||
const quint16 fo = item.getFieldOffset();
|
||||
const QString typeString = (b4rt.first == RelocatableTypes::Byte4Type::ESDSymbol)
|
||||
? QStringLiteral("ESDSymbol")
|
||||
: (b4rt.first == RelocatableTypes::Byte4Type::ByteHi)
|
||||
? QStringLiteral("Hi Byte")
|
||||
: QStringLiteral("Lo Byte");
|
||||
const quint16 fieldOffset = item.getFieldOffset();
|
||||
const QString fieldSize = (item.getFieldSize() == RelocatableTypes::FieldSize::TwoByte)
|
||||
? QStringLiteral("2-Byte")
|
||||
: QStringLiteral("1-Byte");
|
||||
const QString externState = item.isExtern() ? QStringLiteral("Extern") : QStringLiteral("Not Extern");
|
||||
|
||||
retval.append(QStringLiteral("Item %1, Offset %2, @ %3, %4 Field, %5")
|
||||
const quint16 absoluteAddress = static_cast<quint16>(fieldOffset + address() + static_cast<quint16>(HeaderSize));
|
||||
|
||||
retval.append(QStringLiteral("Item %1, Offset %2, @ %3, %4 Field, %5")
|
||||
.arg(idx++)
|
||||
.arg(uint16ToHex(fo))
|
||||
.arg(uint16ToHex(fo + address() + 6))
|
||||
.arg((item.getFieldSize() == RelocatableTypes::FieldSize::TwoByte) ? "2-Byte" : "1-Byte")
|
||||
.arg((item.isExtern()) ? "Extern" : "Not Extern"));
|
||||
.arg(uint16ToHex(fieldOffset))
|
||||
.arg(uint16ToHex(absoluteAddress))
|
||||
.arg(fieldSize)
|
||||
.arg(externState));
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "TextFile.h"
|
||||
#include <QDebug>
|
||||
|
||||
TextFile::TextFile(const QByteArray& data) noexcept
|
||||
TextFile::TextFile(const QByteArray& data) noexcept
|
||||
: GenericFile(data)
|
||||
{
|
||||
if (!data.isEmpty()) {
|
||||
@@ -11,12 +11,12 @@ TextFile::TextFile(const QByteArray& data) noexcept
|
||||
|
||||
void TextFile::setData(const QByteArray& data)
|
||||
{
|
||||
m_data = data;
|
||||
GenericFile::setData(data);
|
||||
}
|
||||
|
||||
void TextFile::dump() const
|
||||
{
|
||||
qDebug() << "Text File:" << filename();
|
||||
qDebug() << " Size:" << m_data.size() << "bytes";
|
||||
qDebug().noquote() << QStringLiteral("Text File: %1").arg(filename());
|
||||
qDebug().noquote() << QStringLiteral(" Size: %1 bytes").arg(m_data.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <QPair>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QColor>
|
||||
#include <QDebug>
|
||||
#include <QFont>
|
||||
#include <QLatin1Char>
|
||||
#include <QPair>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -40,40 +42,36 @@ typedef enum
|
||||
SetNormLC = 0xE0
|
||||
} TextSet;
|
||||
|
||||
inline QString uint8ToHex(quint8 val)
|
||||
[[nodiscard]] inline QString uint8ToHex(quint8 val)
|
||||
{
|
||||
QString retval = QString("%1").arg(val, 2, 16, QChar('0')).toUpper();
|
||||
return retval;
|
||||
return QStringLiteral("%1").arg(val, 2, 16, QLatin1Char('0')).toUpper();
|
||||
}
|
||||
|
||||
inline QString uint16ToHex(quint16 val)
|
||||
[[nodiscard]] inline QString uint16ToHex(quint16 val)
|
||||
{
|
||||
QString retval = QString("%1").arg(val, 4, 16, QChar('0')).toUpper();
|
||||
return retval;
|
||||
return QStringLiteral("%1").arg(val, 4, 16, QLatin1Char('0')).toUpper();
|
||||
}
|
||||
|
||||
inline QString uint32ToHex(quint32 val)
|
||||
[[nodiscard]] inline QString uint32ToHex(quint32 val)
|
||||
{
|
||||
QString retval = QString("%1").arg(val, 8, 16, QChar('0')).toUpper();
|
||||
return retval;
|
||||
return QStringLiteral("%1").arg(val, 8, 16, QLatin1Char('0')).toUpper();
|
||||
}
|
||||
|
||||
inline quint16 makeWord(quint8 lo, quint8 hi)
|
||||
[[nodiscard]] constexpr quint16 makeWord(quint8 lo, quint8 hi) noexcept
|
||||
{
|
||||
return hi * 256 + lo;
|
||||
return static_cast<quint16>((static_cast<quint16>(hi) << 8) | lo);
|
||||
}
|
||||
|
||||
|
||||
inline QFont fontFromSettings(QString key, QFont &defaultfont)
|
||||
[[nodiscard]] inline QFont fontFromSettings(const QString& key, const QFont& defaultfont)
|
||||
{
|
||||
QSettings settings;
|
||||
QString result = settings.value(key, defaultfont.toString()).toString();
|
||||
const QString result = settings.value(key, defaultfont.toString()).toString();
|
||||
QFont retval;
|
||||
retval.fromString(result);
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline void fontToSettings(const QString &key, const QFont &font)
|
||||
inline void fontToSettings(const QString& key, const QFont& font)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue(key, font.toString());
|
||||
|
||||
Reference in New Issue
Block a user