Modernized src/memory and reorganized src/relocatablefile

This commit is contained in:
Mark Long
2025-09-30 15:08:23 -05:00
parent 2bfb0b375e
commit 46a021ecba
19 changed files with 326 additions and 283 deletions
+5 -9
View File
@@ -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
+12 -5
View File
@@ -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;
};
+35 -37
View File
@@ -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;
}
+20 -22
View File
@@ -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 -8
View File
@@ -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
View File
@@ -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};
};
+9 -20
View File
@@ -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
View File
@@ -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;
};
+9 -9
View File
@@ -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};
};
+2 -4
View File
@@ -1,6 +1,4 @@
#include "RoleAsmOperand.h"
RoleAsmOperand::RoleAsmOperand()
{
}
// Implementation file for RoleAsmOperand class
// Constructor is defaulted in header for performance
+9 -11
View File
@@ -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
+73
View File
@@ -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};
};
+33 -33
View File
@@ -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;
+21 -81
View File
@@ -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;
};
+33
View File
@@ -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
+4 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
};