mirror of
https://github.com/markdavidlong/AppleSAWS.git
synced 2026-04-20 05:16:40 +00:00
Modernized src/memory and reorganized src/relocatablefile
This commit is contained in:
@@ -1,30 +1,26 @@
|
||||
#include "IntBasicFile.h"
|
||||
#include <QDebug>
|
||||
|
||||
IntBasicFile::IntBasicFile(const QByteArray& data)
|
||||
IntBasicFile::IntBasicFile(const QByteArray& data) noexcept
|
||||
{
|
||||
setData(data);
|
||||
|
||||
qDebug()<<detokenize();
|
||||
qDebug() << detokenize();
|
||||
|
||||
setData(detokenize());
|
||||
}
|
||||
|
||||
QByteArray IntBasicFile::detokenize()
|
||||
{
|
||||
|
||||
// uint = unsigned int
|
||||
// quint8 = unsigned char
|
||||
// ==========================================================================
|
||||
return dumpBufferAsIntBasicFile(data());
|
||||
}
|
||||
|
||||
quint16 IntBasicFile::get16(quint8 v1, quint8 v2)
|
||||
constexpr quint16 IntBasicFile::get16(quint8 v1, quint8 v2) noexcept
|
||||
{
|
||||
return (quint16) v1 + ((quint16) v2 * 256);
|
||||
return static_cast<quint16>(v1) + (static_cast<quint16>(v2) * 256);
|
||||
}
|
||||
|
||||
QByteArray IntBasicFile::dumpBufferAsIntBasicFile(const QByteArray& origdata)
|
||||
QByteArray IntBasicFile::dumpBufferAsIntBasicFile(const QByteArray& origdata) const
|
||||
/*
|
||||
* THIS CODE IS MODIFIED FROM PAUL SCHYLTER'S SAMPLE CODE AVAILABLE AT:
|
||||
* https://macgui.com/usenet/?group=1&start=14720&id=184603
|
||||
|
||||
@@ -2,15 +2,22 @@
|
||||
|
||||
#include "GenericFile.h"
|
||||
|
||||
|
||||
class IntBasicFile : public GenericFile
|
||||
class IntBasicFile final : public GenericFile
|
||||
{
|
||||
public:
|
||||
explicit IntBasicFile(const QByteArray& data = QByteArray());
|
||||
explicit IntBasicFile(const QByteArray& data = {}) noexcept;
|
||||
|
||||
// Rule of Five
|
||||
~IntBasicFile() override = default;
|
||||
IntBasicFile(const IntBasicFile&) = delete;
|
||||
IntBasicFile& operator=(const IntBasicFile&) = delete;
|
||||
IntBasicFile(IntBasicFile&&) = default;
|
||||
IntBasicFile& operator=(IntBasicFile&&) = default;
|
||||
|
||||
[[nodiscard]] QByteArray detokenize();
|
||||
|
||||
private:
|
||||
[[nodiscard]] quint16 get16(quint8 v1, quint8 v2);
|
||||
[[nodiscard]] QByteArray dumpBufferAsIntBasicFile(const QByteArray& origdata);
|
||||
[[nodiscard]] static constexpr quint16 get16(quint8 v1, quint8 v2) noexcept;
|
||||
[[nodiscard]] QByteArray dumpBufferAsIntBasicFile(const QByteArray& origdata) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,67 +2,65 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
AttributedMemory::AttributedMemory(quint16 expectedBottom,
|
||||
quint16 expectedTop)
|
||||
AttributedMemory::AttributedMemory(quint16 expectedBottom, quint16 expectedTop)
|
||||
{
|
||||
setExpectedRange(expectedBottom, expectedTop);
|
||||
|
||||
for (int idx = 0; idx <= 0xffff; idx++)
|
||||
{
|
||||
m_cells.reserve(0x10000);
|
||||
for (int idx = 0; idx <= 0xffff; idx++) {
|
||||
MemoryCell cell;
|
||||
cell.setAddress(idx);
|
||||
cell.setAddress(static_cast<quint16>(idx));
|
||||
m_cells.append(cell);
|
||||
}
|
||||
}
|
||||
|
||||
void AttributedMemory::setExpectedRange(quint16 bottom, quint16 top)
|
||||
void AttributedMemory::setExpectedRange(quint16 bottom, quint16 top) noexcept
|
||||
{
|
||||
m_expected_top = qMax(bottom,top);
|
||||
m_expected_bottom = qMin(bottom,top);
|
||||
m_expected_top = qMax(bottom, top);
|
||||
m_expected_bottom = qMin(bottom, top);
|
||||
}
|
||||
|
||||
bool AttributedMemory::setValueAt(quint16 address,
|
||||
quint8 withValue,
|
||||
MemRole *andRole)
|
||||
quint16 AttributedMemory::getExpectedTop() const noexcept
|
||||
{
|
||||
return m_expected_top;
|
||||
}
|
||||
|
||||
bool AttributedMemory::setValueAt(quint16 address, quint8 withValue, MemRole* andRole)
|
||||
{
|
||||
m_cells[address].setValue(withValue);
|
||||
if (andRole)
|
||||
{
|
||||
if (andRole) {
|
||||
return setRoleAt(address, andRole);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AttributedMemory::setRoleAt(quint16 address,
|
||||
MemRole *withRole)
|
||||
bool AttributedMemory::setRoleAt(quint16 address, MemRole* withRole)
|
||||
{
|
||||
if (withRole)
|
||||
{
|
||||
if (withRole) {
|
||||
return m_cells[address].setRole(withRole);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AttributedMemory::replaceRoleAt(quint16 address,
|
||||
MemRole *withRole)
|
||||
bool AttributedMemory::replaceRoleAt(quint16 address, MemRole* withRole)
|
||||
{
|
||||
if (!withRole) return false;
|
||||
|
||||
removeRoleAt(address,withRole->id());
|
||||
return setRoleAt(address,withRole);
|
||||
removeRoleAt(address, withRole->id());
|
||||
return setRoleAt(address, withRole);
|
||||
}
|
||||
|
||||
bool AttributedMemory::hasRoleAt(quint16 address, int withId)
|
||||
bool AttributedMemory::hasRoleAt(quint16 address, int withId) const
|
||||
{
|
||||
return m_cells[address].hasRole(withId);
|
||||
}
|
||||
|
||||
MemRole *AttributedMemory::getRoleAt(quint16 address, int withId)
|
||||
MemRole* AttributedMemory::getRoleAt(quint16 address, int withId)
|
||||
{
|
||||
return m_cells[address].getRole(withId);
|
||||
}
|
||||
|
||||
QList<MemRole *> AttributedMemory::getAllRolesAt(quint16 address)
|
||||
QList<MemRole*> AttributedMemory::getAllRolesAt(quint16 address)
|
||||
{
|
||||
return m_cells[address].getAllRoles();
|
||||
}
|
||||
@@ -84,29 +82,29 @@ QByteArray AttributedMemory::getAllValuesInExpectedRange() const
|
||||
|
||||
QByteArray AttributedMemory::getAllValuesInRange(quint16 bottom, quint16 top) const
|
||||
{
|
||||
quint16 expbot = qMin(bottom,top);
|
||||
quint16 exptop = qMax(bottom,top);
|
||||
const quint16 expbot = qMin(bottom, top);
|
||||
const quint16 exptop = qMax(bottom, top);
|
||||
|
||||
QByteArray retval;
|
||||
for (int idx = expbot; idx <= exptop; idx++)
|
||||
{
|
||||
retval.reserve(exptop - expbot + 1);
|
||||
for (int idx = expbot; idx <= exptop; idx++) {
|
||||
retval.append(m_cells.at(idx).value());
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool AttributedMemory::addFile(QByteArray data, quint16 start)
|
||||
bool AttributedMemory::addFile(const QByteArray& data, quint16 start)
|
||||
{
|
||||
if (start+data.length() > 65536) {
|
||||
qWarning() << "Memory overflow adding data."; return false;
|
||||
}
|
||||
if (start + data.length() > 65536) {
|
||||
qWarning() << "Memory overflow adding data.";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < data.length(); idx++)
|
||||
{
|
||||
m_cells[start+idx].setValue(data[idx]);
|
||||
}
|
||||
for (int idx = 0; idx < data.length(); idx++) {
|
||||
m_cells[start + idx].setValue(static_cast<quint8>(data[idx]));
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,37 +6,35 @@
|
||||
class AttributedMemory
|
||||
{
|
||||
public:
|
||||
AttributedMemory(quint16 expectedBottom = 0x0000,
|
||||
quint16 expectedTop = 0xffff);
|
||||
explicit AttributedMemory(quint16 expectedBottom = 0x0000,
|
||||
quint16 expectedTop = 0xffff);
|
||||
|
||||
void setExpectedRange(quint16 bottom, quint16 top);
|
||||
void setExpectedRange(quint16 bottom, quint16 top) noexcept;
|
||||
|
||||
quint16 getExpectedBottom() const { return m_expected_bottom; }
|
||||
quint16 getExpectedTop() const;
|
||||
quint16 getExpectedSize() const { return m_expected_top-m_expected_bottom; }
|
||||
[[nodiscard]] constexpr quint16 getExpectedBottom() const noexcept { return m_expected_bottom; }
|
||||
[[nodiscard]] quint16 getExpectedTop() const noexcept;
|
||||
[[nodiscard]] constexpr quint16 getExpectedSize() const noexcept { return m_expected_top - m_expected_bottom; }
|
||||
|
||||
bool setValueAt(quint16 address, quint8 withValue, MemRole *andRole = nullptr);
|
||||
quint8 valueAt(quint16 address) const { return m_cells[address].value(); };
|
||||
bool setRoleAt(quint16 address, MemRole *withRole);
|
||||
bool hasRoleAt(quint16 address, int withId);
|
||||
MemRole *getRoleAt(quint16 address, int withId);
|
||||
QList<MemRole *> getAllRolesAt(quint16 address);
|
||||
bool setValueAt(quint16 address, quint8 withValue, MemRole* andRole = nullptr);
|
||||
[[nodiscard]] quint8 valueAt(quint16 address) const { return m_cells[address].value(); }
|
||||
bool setRoleAt(quint16 address, MemRole* withRole);
|
||||
[[nodiscard]] bool hasRoleAt(quint16 address, int withId) const;
|
||||
[[nodiscard]] MemRole* getRoleAt(quint16 address, int withId);
|
||||
[[nodiscard]] QList<MemRole*> getAllRolesAt(quint16 address);
|
||||
bool removeRoleAt(quint16 address, int withId);
|
||||
bool replaceRoleAt(quint16 address, MemRole *withRole);
|
||||
bool replaceRoleAt(quint16 address, MemRole* withRole);
|
||||
|
||||
QByteArray getAllValues() const;
|
||||
QByteArray getAllValuesInExpectedRange() const;
|
||||
QByteArray getAllValuesInRange(quint16 bottom, quint16 top) const;
|
||||
[[nodiscard]] QByteArray getAllValues() const;
|
||||
[[nodiscard]] QByteArray getAllValuesInExpectedRange() const;
|
||||
[[nodiscard]] QByteArray getAllValuesInRange(quint16 bottom, quint16 top) const;
|
||||
|
||||
quint8 at(quint16 address) const { return m_cells[address].value(); }
|
||||
[[nodiscard]] quint8 at(quint16 address) const { return m_cells[address].value(); }
|
||||
|
||||
bool addFile(QByteArray data, quint16 start); // From Memory.h. Should be replaced?
|
||||
bool addFile(const QByteArray& data, quint16 start); // From Memory.h. Should be replaced?
|
||||
|
||||
protected:
|
||||
|
||||
quint16 m_expected_bottom;
|
||||
quint16 m_expected_top;
|
||||
|
||||
quint16 m_expected_bottom{0x0000};
|
||||
quint16 m_expected_top{0xffff};
|
||||
QList<MemoryCell> m_cells;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
#include "MemRole.h"
|
||||
|
||||
MemRole::MemRole()
|
||||
{
|
||||
m_parent = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MemRole::setParent(MemoryCell *parent)
|
||||
void MemRole::setParent(MemoryCell* parent) noexcept
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
+10
-7
@@ -11,17 +11,20 @@ class MemoryCell;
|
||||
class MemRole
|
||||
{
|
||||
public:
|
||||
MemRole();
|
||||
virtual ~MemRole() { }
|
||||
MemRole() = default;
|
||||
virtual ~MemRole() noexcept = default;
|
||||
|
||||
virtual int id() const = 0;
|
||||
virtual QString name() const = 0;
|
||||
[[nodiscard]] virtual int id() const = 0;
|
||||
[[nodiscard]] virtual QString name() const = 0;
|
||||
|
||||
virtual void setParent(MemoryCell *parent);
|
||||
virtual MemoryCell *parent( ) const { return m_parent; }
|
||||
// Non-owning pointer to parent MemoryCell (lifetime managed elsewhere)
|
||||
virtual void setParent(MemoryCell* parent) noexcept;
|
||||
[[nodiscard]] virtual MemoryCell* parent() const noexcept { return m_parent; }
|
||||
[[nodiscard]] virtual bool hasParent() const noexcept { return m_parent != nullptr; }
|
||||
|
||||
protected:
|
||||
MemoryCell *m_parent;
|
||||
// Non-owning pointer - MemoryCell lifetime is managed by container/owner
|
||||
MemoryCell* m_parent{nullptr};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,42 +1,32 @@
|
||||
#include "MemoryCell.h"
|
||||
|
||||
MemoryCell::MemoryCell(quint8 val)
|
||||
{
|
||||
m_value = val;
|
||||
}
|
||||
|
||||
MemoryCell::~MemoryCell()
|
||||
{
|
||||
auto keys = m_roles.keys();
|
||||
|
||||
foreach (auto key, keys)
|
||||
{
|
||||
delete (m_roles.take(key));
|
||||
for (const auto& role : m_roles) {
|
||||
delete role;
|
||||
}
|
||||
}
|
||||
|
||||
bool MemoryCell::setRole(MemRole *role)
|
||||
bool MemoryCell::setRole(MemRole* role)
|
||||
{
|
||||
if (!role) {
|
||||
qWarning("No role given!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasRole(role->id()))
|
||||
{
|
||||
if (hasRole(role->id())) {
|
||||
qWarning("Address already has this role.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_roles.insert(role->id(),role);
|
||||
m_roles.insert(role->id(), role);
|
||||
role->setParent(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
MemRole *MemoryCell::getRole(int id)
|
||||
MemRole* MemoryCell::getRole(int id)
|
||||
{
|
||||
if (hasRole(id))
|
||||
{
|
||||
if (hasRole(id)) {
|
||||
return m_roles[id];
|
||||
}
|
||||
return nullptr;
|
||||
@@ -49,15 +39,14 @@ bool MemoryCell::hasRole(int id) const
|
||||
|
||||
bool MemoryCell::removeRole(int id)
|
||||
{
|
||||
if (hasRole(id))
|
||||
{
|
||||
if (hasRole(id)) {
|
||||
m_roles.remove(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<MemRole *> MemoryCell::getAllRoles()
|
||||
QList<MemRole*> MemoryCell::getAllRoles()
|
||||
{
|
||||
return m_roles.values();
|
||||
}
|
||||
|
||||
+14
-15
@@ -9,27 +9,26 @@
|
||||
class MemoryCell
|
||||
{
|
||||
public:
|
||||
MemoryCell(quint8 val = 0);
|
||||
virtual ~MemoryCell();
|
||||
explicit MemoryCell(quint8 val = 0) noexcept : m_value(val) {}
|
||||
~MemoryCell();
|
||||
|
||||
void setAddress(quint16 address) { m_address = address; }
|
||||
quint16 address() const { return m_address; }
|
||||
void setAddress(quint16 address) noexcept { m_address = address; }
|
||||
[[nodiscard]] constexpr quint16 address() const noexcept { return m_address; }
|
||||
|
||||
bool setRole(MemRole *role);
|
||||
MemRole *getRole(int id);
|
||||
bool hasRole(int id) const;
|
||||
bool setRole(MemRole* role);
|
||||
[[nodiscard]] MemRole* getRole(int id);
|
||||
[[nodiscard]] bool hasRole(int id) const;
|
||||
bool removeRole(int id);
|
||||
|
||||
void setValue(quint8 val) { m_value = val; }
|
||||
quint8 value() const { return m_value; }
|
||||
operator quint8() const { return m_value; }
|
||||
void setValue(quint8 val) noexcept { m_value = val; }
|
||||
[[nodiscard]] constexpr quint8 value() const noexcept { return m_value; }
|
||||
[[nodiscard]] constexpr operator quint8() const noexcept { return m_value; }
|
||||
|
||||
QList<MemRole *> getAllRoles();
|
||||
[[nodiscard]] QList<MemRole*> getAllRoles();
|
||||
|
||||
private:
|
||||
quint8 m_value;
|
||||
quint16 m_address;
|
||||
|
||||
QHash<int,MemRole *> m_roles;
|
||||
quint8 m_value{0};
|
||||
quint16 m_address{0};
|
||||
QHash<int, MemRole*> m_roles;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,20 +7,20 @@
|
||||
|
||||
class RoleAsmOpcode : public MemRole
|
||||
{
|
||||
|
||||
public:
|
||||
static const int RoleID = 1;
|
||||
RoleAsmOpcode() { m_am = AddressMode::AM_InvalidOp; }
|
||||
virtual ~RoleAsmOpcode() { }
|
||||
static constexpr int RoleID = 1;
|
||||
|
||||
RoleAsmOpcode() = default;
|
||||
~RoleAsmOpcode() noexcept override = default;
|
||||
|
||||
virtual int id() const override { return RoleID; }
|
||||
virtual QString name() const override { return "RoleAsmOpcode"; }
|
||||
[[nodiscard]] constexpr int id() const noexcept override { return RoleID; }
|
||||
[[nodiscard]] QString name() const override { return QStringLiteral("RoleAsmOpcode"); }
|
||||
|
||||
QString mnemonic() const;
|
||||
AddressMode addressMode() const;
|
||||
[[nodiscard]] QString mnemonic() const;
|
||||
[[nodiscard]] AddressMode addressMode() const;
|
||||
|
||||
protected:
|
||||
AddressMode m_am;
|
||||
AddressMode m_am{AddressMode::AM_InvalidOp};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "RoleAsmOperand.h"
|
||||
|
||||
RoleAsmOperand::RoleAsmOperand()
|
||||
{
|
||||
|
||||
}
|
||||
// Implementation file for RoleAsmOperand class
|
||||
// Constructor is defaulted in header for performance
|
||||
|
||||
@@ -6,27 +6,25 @@
|
||||
|
||||
class RoleAsmOperand : public MemRole
|
||||
{
|
||||
|
||||
public:
|
||||
static const int RoleID = 2;
|
||||
static constexpr int RoleID = 2;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
enum class Type {
|
||||
Byte,
|
||||
WordLo,
|
||||
WordHi,
|
||||
} Type;
|
||||
};
|
||||
|
||||
RoleAsmOperand();
|
||||
RoleAsmOperand() = default;
|
||||
|
||||
virtual int id() const override { return RoleID; }
|
||||
virtual QString name() const override { return "RoleAsmOperand"; }
|
||||
[[nodiscard]] constexpr int id() const noexcept override { return RoleID; }
|
||||
[[nodiscard]] QString name() const override { return QStringLiteral("RoleAsmOperand"); }
|
||||
|
||||
void setOperandType(Type type) { m_optype = type; }
|
||||
Type operandType() const { return m_optype; }
|
||||
void setOperandType(Type type) noexcept { m_optype = type; }
|
||||
[[nodiscard]] constexpr Type operandType() const noexcept { return m_optype; }
|
||||
|
||||
protected:
|
||||
Type m_optype;
|
||||
Type m_optype{Type::Byte};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "RelocatableDictItem.h"
|
||||
|
||||
// Implementation is header-only due to simple nature of the class
|
||||
// All methods are inline for performance
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
#include "RelocatableTypes.h"
|
||||
#include "Util.h"
|
||||
|
||||
class RelocatableDictItem final {
|
||||
public:
|
||||
RelocatableDictItem() noexcept { init(0, 0, 0, 0); }
|
||||
|
||||
explicit RelocatableDictItem(quint8 rld, quint8 fo_low, quint8 fo_hi, quint8 lbsym) noexcept {
|
||||
init(rld, fo_low, fo_hi, lbsym);
|
||||
}
|
||||
|
||||
explicit RelocatableDictItem(quint8 rld, quint16 fo, quint8 lbsym) noexcept {
|
||||
init(rld, fo, lbsym);
|
||||
}
|
||||
|
||||
void init(quint8 rld, quint8 fo_low, quint8 fo_hi, quint8 lbsym) noexcept {
|
||||
m_rld_flag = rld;
|
||||
m_halfword_or_sym_num = lbsym;
|
||||
m_field_offset = makeWord(fo_low, fo_hi);
|
||||
}
|
||||
|
||||
void init(quint8 rld, quint16 fo, quint8 lbsym) noexcept {
|
||||
m_rld_flag = rld;
|
||||
m_halfword_or_sym_num = lbsym;
|
||||
m_field_offset = fo;
|
||||
}
|
||||
|
||||
[[nodiscard]] RelocatableTypes::FieldSize getFieldSize() const noexcept {
|
||||
return (m_rld_flag & 0x80) ? RelocatableTypes::FieldSize::TwoByte : RelocatableTypes::FieldSize::OneByte;
|
||||
}
|
||||
|
||||
[[nodiscard]] RelocatableTypes::WordUpperLower getWordBytePos() const noexcept {
|
||||
return (m_rld_flag & 0x40) ? RelocatableTypes::WordUpperLower::HighByte : RelocatableTypes::WordUpperLower::LowByte;
|
||||
}
|
||||
|
||||
[[nodiscard]] RelocatableTypes::Endianness getEndianness() const noexcept {
|
||||
return (m_rld_flag & 0x20) ? RelocatableTypes::Endianness::HiLow : RelocatableTypes::Endianness::LowHi;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool isExtern() const noexcept { return (m_rld_flag & 0x10) != 0; }
|
||||
[[nodiscard]] constexpr bool isNotEndOfRLD() const noexcept { return (m_rld_flag & 0x01) != 0; }
|
||||
[[nodiscard]] constexpr bool isEndOfRLD() const noexcept { return (m_rld_flag & 0x01) == 0; }
|
||||
|
||||
[[nodiscard]] RelocatableTypes::Byte4ReturnType getByte4() const noexcept {
|
||||
RelocatableTypes::Byte4ReturnType retval;
|
||||
|
||||
if (isExtern()) {
|
||||
retval.first = RelocatableTypes::Byte4Type::ESDSymbol;
|
||||
} else if (getWordBytePos() == RelocatableTypes::WordUpperLower::HighByte) {
|
||||
retval.first = RelocatableTypes::Byte4Type::ByteHi;
|
||||
} else {
|
||||
retval.first = RelocatableTypes::Byte4Type::ByteLo;
|
||||
}
|
||||
|
||||
retval.second = m_halfword_or_sym_num;
|
||||
return retval;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr quint16 getFieldOffset() const noexcept { return m_field_offset; }
|
||||
[[nodiscard]] constexpr quint8 getRLDFlag() const noexcept { return m_rld_flag; }
|
||||
[[nodiscard]] constexpr quint8 getRawHalfWordOrSymNum() const noexcept { return m_halfword_or_sym_num; }
|
||||
|
||||
// Structured binding and comparison support
|
||||
[[nodiscard]] constexpr auto operator<=>(const RelocatableDictItem& other) const noexcept = default;
|
||||
|
||||
private:
|
||||
quint8 m_rld_flag{0};
|
||||
quint16 m_field_offset{0};
|
||||
quint8 m_halfword_or_sym_num{0};
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <QDebug>
|
||||
#include "RelocatableFile.h"
|
||||
#include <QDebug>
|
||||
|
||||
RelocatableFile::RelocatableFile(const QByteArray& data) : GenericFile(data)
|
||||
RelocatableFile::RelocatableFile(const QByteArray& data) noexcept
|
||||
: GenericFile(data)
|
||||
{
|
||||
// qDebug() << "Relocatable file ctor";
|
||||
if (!data.isEmpty()) {
|
||||
setData(data);
|
||||
}
|
||||
@@ -46,53 +46,53 @@ void RelocatableFile::setData(const QByteArray& data)
|
||||
void RelocatableFile::dump()
|
||||
{
|
||||
qDebug() << "\nTotalLength: " << length();
|
||||
qDebug() << "Starting Ram Address: " << (quint16) m_starting_ram_address << uint16ToHex(m_starting_ram_address);
|
||||
qDebug() << "Length of Ram Image: " << (quint16) m_ram_image_length << uint16ToHex(m_ram_image_length);
|
||||
qDebug() << "Length of Code Image: " << (quint16) m_code_image_length << uint16ToHex(m_code_image_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);
|
||||
|
||||
int itemIdx = 0;
|
||||
foreach (RelocatableDictItem item, m_relocatable_dict) {
|
||||
Byte4ReturnType b4rt = item.getByte4();
|
||||
for (const auto& item : m_relocatable_dict) {
|
||||
const auto b4rt = item.getByte4();
|
||||
QString typestr;
|
||||
if (b4rt.first == ESDSymbol) { typestr = "ESDSymbol"; }
|
||||
else if (b4rt.first == ByteHi) { typestr = "Hi Byte"; }
|
||||
else { typestr = "Lo Byte"; }
|
||||
quint16 fo = item.getFieldOffset();
|
||||
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()==RFS2Byte)?"2-Byte":"1-Byte")
|
||||
<< "FieldSize: " << ((item.getFieldSize() == RelocatableTypes::FieldSize::TwoByte) ? "2-Byte" : "1-Byte")
|
||||
<< typestr << uint8ToHex(b4rt.second)
|
||||
<< ((item.isNotEndOfRLD())?"NotEndOfRLD":"EndOfRLD")
|
||||
<< " " << ((item.isExtern())?"Extern":"Not Extern");
|
||||
<< ((item.isNotEndOfRLD()) ? "NotEndOfRLD" : "EndOfRLD")
|
||||
<< " " << ((item.isExtern()) ? "Extern" : "Not Extern");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
QStringList RelocatableFile::decodeRelocatableDict() const
|
||||
{
|
||||
QStringList retval;
|
||||
int idx = 0;
|
||||
foreach (RelocatableDictItem item, m_relocatable_dict) {
|
||||
Byte4ReturnType b4rt = item.getByte4();
|
||||
for (const auto& item : m_relocatable_dict) {
|
||||
const auto b4rt = item.getByte4();
|
||||
QString typestr;
|
||||
if (b4rt.first == ESDSymbol) { typestr = "ESDSymbol"; }
|
||||
else if (b4rt.first == ByteHi) { typestr = "Hi Byte"; }
|
||||
else { typestr = "Lo Byte"; }
|
||||
quint16 fo = item.getFieldOffset();
|
||||
// qDebug() << " Item #" << idx
|
||||
// << "Field Offset: " << uint16ToHex(fo)
|
||||
// << "FieldSize: " << ((item.getFieldSize()==RFS2Byte)?"2-Byte":"1-Byte")
|
||||
// << typestr << uint8ToHex(b4rt.second)
|
||||
// << ((item.isNotEndOfRLD())?"NotEndOfRLD":"EndOfRLD")
|
||||
// << " " << ((item.isExtern())?"Extern":"Not Extern");
|
||||
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();
|
||||
|
||||
retval.append(QString("Item %1, Offset %2, @ %3, %4 Field, %5")
|
||||
retval.append(QStringLiteral("Item %1, Offset %2, @ %3, %4 Field, %5")
|
||||
.arg(idx++)
|
||||
.arg(uint16ToHex(fo))
|
||||
.arg(uint16ToHex(fo+address()+6))
|
||||
.arg((item.getFieldSize()==RFS2Byte)?"2-Byte":"1-Byte")
|
||||
.arg((item.isExtern())?"Extern":"Not Extern"));
|
||||
.arg(uint16ToHex(fo + address() + 6))
|
||||
.arg((item.getFieldSize() == RelocatableTypes::FieldSize::TwoByte) ? "2-Byte" : "1-Byte")
|
||||
.arg((item.isExtern()) ? "Extern" : "Not Extern"));
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
@@ -2,106 +2,46 @@
|
||||
|
||||
#include "GenericFile.h"
|
||||
#include "Util.h"
|
||||
#include "RelocatableTypes.h"
|
||||
#include "RelocatableDictItem.h"
|
||||
|
||||
#include <QPair>
|
||||
#include <QByteArray>
|
||||
#include <memory>
|
||||
|
||||
|
||||
typedef enum { RFS1Byte, RFS2Byte } FieldSize;
|
||||
typedef enum { ULIsHighByte, ULIsLowByte } WordUpperLower;
|
||||
typedef enum { LowHi, HiLow } Endianness;
|
||||
typedef enum { ByteLo, ByteHi, ESDSymbol } Byte4Type;
|
||||
|
||||
typedef QPair<Byte4Type, quint8> Byte4ReturnType;
|
||||
|
||||
class RelocatableDictItem {
|
||||
public:
|
||||
RelocatableDictItem() {init(0,0,0,0); }
|
||||
RelocatableDictItem(quint8 rld, quint8 fo_low, quint8 fo_hi, quint8 lbsym) {
|
||||
init(rld,fo_low, fo_hi,lbsym);
|
||||
}
|
||||
RelocatableDictItem(quint8 rld, quint16 fo, quint8 lbsym) {
|
||||
init(rld,fo,lbsym);
|
||||
}
|
||||
|
||||
void init(quint8 rld, quint8 fo_low, quint8 fo_hi, quint8 lbsym) {
|
||||
m_rld_flag = rld;
|
||||
m_halfword_or_sym_num = lbsym;
|
||||
m_field_offset = makeWord(fo_low,fo_hi);
|
||||
}
|
||||
|
||||
void init(quint8 rld, quint16 fo, quint8 lbsym) {
|
||||
m_rld_flag = rld;
|
||||
m_halfword_or_sym_num = lbsym;
|
||||
m_field_offset = fo;
|
||||
}
|
||||
|
||||
FieldSize getFieldSize() { return (m_rld_flag & 0x80)?RFS2Byte:RFS1Byte; }
|
||||
WordUpperLower getWordBytePos() { return (m_rld_flag & 0x40)?ULIsHighByte:ULIsLowByte; }
|
||||
Endianness getEndianness() { return (m_rld_flag & 0x20)?HiLow:LowHi; }
|
||||
bool isExtern() { return (m_rld_flag & 0x10); }
|
||||
bool isNotEndOfRLD() { return (m_rld_flag & 0x01); }
|
||||
bool isEndOfRLD() { return !(m_rld_flag & 0x01); }
|
||||
|
||||
Byte4ReturnType getByte4() {
|
||||
Byte4ReturnType retval;
|
||||
|
||||
if (isExtern()) {
|
||||
retval.first = ESDSymbol;
|
||||
} else if (getWordBytePos() == ULIsHighByte) {
|
||||
retval.first = ByteHi;
|
||||
} else {
|
||||
retval.first = ByteLo;
|
||||
}
|
||||
|
||||
retval.second = m_halfword_or_sym_num;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
quint16 getFieldOffset() { return m_field_offset; }
|
||||
|
||||
quint8 getRLDFlag() { return m_rld_flag; }
|
||||
quint8 getRawHalfWordOrSymNum() { return m_halfword_or_sym_num; }
|
||||
|
||||
private:
|
||||
|
||||
quint8 m_rld_flag;
|
||||
quint16 m_field_offset;
|
||||
quint8 m_halfword_or_sym_num;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RelocatableFile : public GenericFile
|
||||
class RelocatableFile final : public GenericFile
|
||||
{
|
||||
public:
|
||||
explicit RelocatableFile(const QByteArray& data = {}) noexcept;
|
||||
|
||||
// Rule of Five - not needed since we use default destructor and no custom copy/move
|
||||
~RelocatableFile() override = default;
|
||||
RelocatableFile(const RelocatableFile&) = delete;
|
||||
RelocatableFile& operator=(const RelocatableFile&) = delete;
|
||||
RelocatableFile(RelocatableFile&&) = default;
|
||||
RelocatableFile& operator=(RelocatableFile&&) = default;
|
||||
|
||||
explicit RelocatableFile(const QByteArray& data = QByteArray());
|
||||
void setData(const QByteArray& data) override;
|
||||
|
||||
[[nodiscard]] virtual quint16 length() const noexcept override { return m_data.length(); }
|
||||
[[nodiscard]] quint16 length() const noexcept override { return static_cast<quint16>(m_data.length()); }
|
||||
|
||||
void dump();
|
||||
|
||||
[[nodiscard]] QByteArray getBinaryCodeImage() const noexcept { return m_binary_code_image; }
|
||||
[[nodiscard]] const QByteArray& getBinaryCodeImage() const noexcept { return m_binary_code_image; }
|
||||
[[nodiscard]] const QList<RelocatableDictItem>& getRelocatableDict() const noexcept { return m_relocatable_dict; }
|
||||
|
||||
[[nodiscard]] quint16 startingAddress() const noexcept { return m_starting_ram_address; }
|
||||
[[nodiscard]] quint16 codeImageLength() const noexcept { return m_code_image_length; }
|
||||
[[nodiscard]] constexpr quint16 startingAddress() const noexcept { return m_starting_ram_address; }
|
||||
[[nodiscard]] constexpr quint16 codeImageLength() const noexcept { return m_code_image_length; }
|
||||
[[nodiscard]] constexpr quint16 ramImageLength() const noexcept { return m_ram_image_length; }
|
||||
|
||||
[[nodiscard]] QStringList decodeRelocatableDict() const;
|
||||
|
||||
protected:
|
||||
quint16 m_starting_ram_address;
|
||||
quint16 m_ram_image_length;
|
||||
quint16 m_code_image_length;
|
||||
private:
|
||||
quint16 m_starting_ram_address{0};
|
||||
quint16 m_ram_image_length{0};
|
||||
quint16 m_code_image_length{0};
|
||||
|
||||
QByteArray m_binary_code_image;
|
||||
|
||||
QList<RelocatableDictItem> m_relocatable_dict;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <QPair>
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace RelocatableTypes {
|
||||
|
||||
// Modern scoped enums instead of global enums
|
||||
enum class FieldSize : quint8 {
|
||||
OneByte,
|
||||
TwoByte
|
||||
};
|
||||
|
||||
enum class WordUpperLower : quint8 {
|
||||
LowByte,
|
||||
HighByte
|
||||
};
|
||||
|
||||
enum class Endianness : quint8 {
|
||||
LowHi,
|
||||
HiLow
|
||||
};
|
||||
|
||||
enum class Byte4Type : quint8 {
|
||||
ByteLo,
|
||||
ByteHi,
|
||||
ESDSymbol
|
||||
};
|
||||
|
||||
// Modern type alias instead of typedef
|
||||
using Byte4ReturnType = QPair<Byte4Type, quint8>;
|
||||
|
||||
} // namespace RelocatableTypes
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <QDebug>
|
||||
#include "TextFile.h"
|
||||
#include <QDebug>
|
||||
|
||||
TextFile::TextFile(const QByteArray& data) : GenericFile(data)
|
||||
TextFile::TextFile(const QByteArray& data) noexcept
|
||||
: GenericFile(data)
|
||||
{
|
||||
if (!data.isEmpty()) {
|
||||
setData(data);
|
||||
@@ -15,4 +16,5 @@ void TextFile::setData(const QByteArray& data)
|
||||
|
||||
void TextFile::dump()
|
||||
{
|
||||
// TODO: Implement text file dumping functionality
|
||||
}
|
||||
|
||||
+10
-5
@@ -2,15 +2,20 @@
|
||||
|
||||
#include "GenericFile.h"
|
||||
|
||||
class TextFile : public GenericFile
|
||||
class TextFile final : public GenericFile
|
||||
{
|
||||
public:
|
||||
explicit TextFile(const QByteArray& data = QByteArray());
|
||||
explicit TextFile(const QByteArray& data = {}) noexcept;
|
||||
|
||||
// Rule of Five
|
||||
~TextFile() override = default;
|
||||
TextFile(const TextFile&) = delete;
|
||||
TextFile& operator=(const TextFile&) = delete;
|
||||
TextFile(TextFile&&) = default;
|
||||
TextFile& operator=(TextFile&&) = default;
|
||||
|
||||
void setData(const QByteArray& data) override;
|
||||
|
||||
void dump();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
+22
-15
@@ -7,31 +7,38 @@
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
|
||||
class AppleChar {
|
||||
class AppleChar final {
|
||||
public:
|
||||
AppleChar() { m_val = 0; }
|
||||
AppleChar(quint8 ch) { m_val = ch; }
|
||||
constexpr AppleChar() noexcept = default;
|
||||
explicit constexpr AppleChar(quint8 ch) noexcept : m_val(ch) {}
|
||||
|
||||
QChar printable() const { return printable(m_val); }
|
||||
[[nodiscard]] QChar printable() const { return printable(m_val); }
|
||||
|
||||
TextAttribute getAttribute() const { return getAttribute(m_val); }
|
||||
TextSet getTextSet() const { return getTextSet(m_val); }
|
||||
[[nodiscard]] TextAttribute getAttribute() const { return getAttribute(m_val); }
|
||||
[[nodiscard]] TextSet getTextSet() const { return getTextSet(m_val); }
|
||||
|
||||
static TextAttribute getAttribute(quint8 val) ;
|
||||
static TextSet getTextSet(quint8 val) ;
|
||||
static QChar printable(quint8 val) ;
|
||||
static QString getHtmlString(quint8 val);
|
||||
[[nodiscard]] static TextAttribute getAttribute(quint8 val);
|
||||
[[nodiscard]] static TextSet getTextSet(quint8 val);
|
||||
[[nodiscard]] static QChar printable(quint8 val);
|
||||
[[nodiscard]] static QString getHtmlString(quint8 val);
|
||||
|
||||
[[nodiscard]] constexpr quint8 value() const noexcept { return m_val; }
|
||||
|
||||
// Comparison operators
|
||||
[[nodiscard]] constexpr auto operator<=>(const AppleChar& other) const noexcept = default;
|
||||
|
||||
private:
|
||||
quint8 m_val;
|
||||
quint8 m_val{0};
|
||||
};
|
||||
|
||||
class AppleString : public QByteArray {
|
||||
class AppleString final : public QByteArray {
|
||||
public:
|
||||
void setData(const QByteArray &data) { insert(0,data); }
|
||||
QString printable() const;
|
||||
QList<TextAttribute> attributes() const;
|
||||
using QByteArray::QByteArray;
|
||||
|
||||
void setData(const QByteArray& data) { insert(0, data); }
|
||||
|
||||
[[nodiscard]] QString printable() const;
|
||||
[[nodiscard]] QList<TextAttribute> attributes() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user