Rework MemoryModel to interface with the VSRTL processor
MODIFY
external/VSRTL
external/VSRTL
-Subproject commit f9b5156807fd8c7191652898878d3c819356aad8
+Subproject commit f622086c52d630e9b94b5c79d20e834c0f1f1920

MODIFY
src/memorymodel.cpp
src/memorymodel.cpp
#include "memorymodel.h"
+NewMemoryModel::NewMemoryModel(ProcessorHandler& handler, QObject* parent)
+ : QAbstractTableModel(parent), m_handler(handler) {}
+
+int NewMemoryModel::columnCount(const QModelIndex&) const {
+ return 1 /* address column */ + m_handler.getProcessor()->implementsISA().bytes() /* byte columns */;
+}
+
+int NewMemoryModel::rowCount(const QModelIndex&) const {
+ return m_rowsVisible;
+}
+
+void NewMemoryModel::processorWasClocked() {
+ // Reload model
+ beginResetModel();
+ endResetModel();
+}
+
+void NewMemoryModel::offsetCentralAddress(int rowOffset) {
+ const int byteOffset = rowOffset * m_handler.getProcessor()->implementsISA().bytes();
+ const long long newCenterAddress = static_cast<long long>(m_centralAddress) + byteOffset;
+ m_centralAddress = newCenterAddress < 0 ? m_centralAddress : newCenterAddress;
+ processorWasClocked();
+}
+
+QVariant NewMemoryModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ if (section == Column::Address) {
+ return "Address";
+ } else {
+ return "+" + QString::number(section);
+ }
+ }
+ return QVariant();
+}
+
+void NewMemoryModel::setRowsVisible(unsigned rows) {
+ m_rowsVisible = rows;
+ processorWasClocked();
+}
+
+QVariant NewMemoryModel::data(const QModelIndex& index, int role) const {
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (role == Qt::TextAlignmentRole)
+ return Qt::AlignCenter;
+
+ const auto bytes = m_handler.getProcessor()->implementsISA().bytes();
+ const long long alignedAddress = static_cast<long long>(m_centralAddress) +
+ ((((m_rowsVisible * bytes) / 2) / bytes) * bytes) - (index.row() * bytes);
+ const unsigned byteOffset = index.column() - 1;
+
+ if (index.column() == Column::Address) {
+ if (role == Qt::DisplayRole) {
+ return addrData(alignedAddress);
+ }
+ } else {
+ switch (role) {
+ case Qt::FontRole:
+ return QFont("monospace");
+ case Qt::ForegroundRole:
+ return fgColorData(alignedAddress, byteOffset);
+ case Qt::DisplayRole:
+ return byteData(alignedAddress, byteOffset);
+ default:
+ break;
+ }
+ }
+
+ return QVariant();
+}
+
+void NewMemoryModel::setRadix(Radix r) {
+ m_radix = r;
+ processorWasClocked();
+}
+
+QVariant NewMemoryModel::addrData(long long address) const {
+ if (address < 0) {
+ return "-";
+ }
+ return encodeRadixValue(address, Radix::Hex);
+}
+
+QVariant NewMemoryModel::fgColorData(long long address, unsigned byteOffset) const {
+ if (address < 0 || !m_handler.getProcessor()->getMemory().contains(address + byteOffset)) {
+ return QBrush(Qt::lightGray);
+ } else {
+ return QVariant(); // default
+ }
+}
+
+QVariant NewMemoryModel::byteData(long long address, unsigned byteOffset) const {
+ if (address < 0) {
+ return "-";
+ } else if (!m_handler.getProcessor()->getMemory().contains(address + byteOffset)) {
+ // Dont read the memory (this will create an entry in the memory if done so). Instead, create a "fake" entry in
+ // the memory model, containing X's.
+ return "X";
+ } else {
+ uint32_t value = m_handler.getProcessor()->getMemory().readMem(address);
+ value = value >> (byteOffset * 8);
+ return encodeRadixValue(value & 0xFF, m_radix, 8);
+ }
+}
+
+Qt::ItemFlags NewMemoryModel::flags(const QModelIndex& index) const {
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
MemoryModel::MemoryModel(MainMemory* memoryPtr, QObject* parent) : QStandardItemModel(parent) {
m_memoryPtr = memoryPtr;

MODIFY
src/memorymodel.h
src/memorymodel.h
#include "mainmemory.h"
+#include <QAbstractTableModel>
#include <QStandardItemModel>
#include <unordered_map>
+#include "processorhandler.h"
+#include "radix.h"
+
+class NewMemoryModel : public QAbstractTableModel {
+ Q_OBJECT
+public:
+ enum Column { Address = 0 };
+ NewMemoryModel(ProcessorHandler& handler, QObject* parent = nullptr);
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex& parent = QModelIndex()) const override;
+
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+
+ Qt::ItemFlags flags(const QModelIndex& index) const override;
+
+ void setRadix(Radix r);
+ Radix getRadix() const { return m_radix; }
+
+public slots:
+ void processorWasClocked();
+ void setRowsVisible(unsigned rows);
+ void offsetCentralAddress(int rowOffset);
+
+private:
+ QVariant addrData(long long address) const;
+ QVariant byteData(long long address, unsigned byteOffset) const;
+ QVariant fgColorData(long long address, unsigned byteOffset) const;
+ ProcessorHandler& m_handler;
+
+ Radix m_radix = Radix::Unsigned;
+
+ long long m_centralAddress = 4; // Address at the center of the model
+ unsigned m_rowsVisible = 0; // Number of rows currently visible in the view associated with the model
+};
+
class MemoryModel : public QStandardItemModel {
Q_OBJECT

Rework MemoryModel to interface with the VSRTL processor