Add MemoryMapModel
MODIFY
src/io/iomanager.cpp
src/io/iomanager.cpp
@@ -10,6 +10,8 @@ namespace Ripes {
IOManager::IOManager() : QObject(nullptr) {
// Always re-register the currently active peripherals when the processor changes
connect(ProcessorHandler::get(), &ProcessorHandler::processorChanged, this, &IOManager::setProcessorPeripherals);
+ connect(ProcessorHandler::get(), &ProcessorHandler::reqProcessorReset, this, &IOManager::refreshMemoryMap);
+ refreshMemoryMap();
}
IOBase* IOManager::createPeripheral(IOType type) {
@@ -17,10 +19,10 @@ IOBase* IOManager::createPeripheral(IOType type) {
// Assign base address to peripheral
uint32_t base;
- if (m_memoryMap.empty()) {
+ if (m_peripherals.empty()) {
base = RipesSettings::value(RIPES_SETTING_PERIPHERALS_START).toUInt();
} else {
- auto lastPeriph = m_memoryMap.rbegin();
+ auto lastPeriph = m_peripherals.rbegin();
base = lastPeriph->first + lastPeriph->second.size;
}
@@ -30,11 +32,26 @@ IOBase* IOManager::createPeripheral(IOType type) {
[peripheral](uint32_t offset, uint32_t value, uint32_t size) { peripheral->ioWrite(offset, value, size); },
[peripheral](uint32_t offset, uint32_t size) { return peripheral->ioRead(offset, size); }});
- m_memoryMap[base] = {peripheral->size(), peripheral->name()};
+ m_peripherals[base] = {peripheral->size(), peripheral->name()};
+ refreshMemoryMap();
return peripheral;
}
void IOManager::setProcessorPeripherals() {}
+void IOManager::refreshMemoryMap() {
+ m_memoryMap = m_peripherals;
+
+ const auto& program = ProcessorHandler::get()->getProgram();
+ if (program) {
+ for (const auto& section : program.get()->sections) {
+ m_memoryMap[section.second.address] =
+ MemoryMapEntry{static_cast<unsigned>(section.second.data.size()), section.second.name};
+ }
+ }
+
+ emit memoryMapChanged();
+}
+
} // namespace Ripes

MODIFY
src/io/iomanager.h
src/io/iomanager.h
@@ -20,9 +20,14 @@ public:
IOBase* createPeripheral(IOType type);
const MemoryMap& memoryMap() const { return m_memoryMap; }
+signals:
+ void memoryMapChanged();
+
private:
+ void refreshMemoryMap();
void setProcessorPeripherals();
MemoryMap m_memoryMap;
+ MemoryMap m_peripherals;
};
} // namespace Ripes

ADD
src/io/memorymapmodel.cpp
+#include "memorymapmodel.h"
+
+#include <QHeaderView>
+
+#include "iobase.h"
+#include "iomanager.h"
+#include "processorhandler.h"
+#include "radix.h"
+
+namespace Ripes {
+
+MemoryMapModel::MemoryMapModel(const IOManager* ioManager, QObject* parent)
+ : QAbstractTableModel(parent), m_ioManager(ioManager) {
+ connect(m_ioManager, &IOManager::memoryMapChanged, this, &MemoryMapModel::memoryMapChanged);
+}
+
+void MemoryMapModel::memoryMapChanged() {
+ // Let's assume that this is not a hot function, and just update the whole view.
+ emit dataChanged(index(0, 0), index(rowCount(), columnCount()));
+ emit layoutChanged();
+}
+
+int MemoryMapModel::columnCount(const QModelIndex&) const {
+ return NColumns;
+}
+
+int MemoryMapModel::rowCount(const QModelIndex&) const {
+ return m_ioManager->memoryMap().size();
+}
+
+QVariant MemoryMapModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ switch (section) {
+ case Column::Name:
+ return "Name";
+ case Column::AddressRange:
+ return "Range";
+ case Column::Size:
+ return "Size";
+ default:
+ return QVariant();
+ }
+ }
+ return QVariant();
+}
+
+QVariant MemoryMapModel::data(const QModelIndex& index, int role) const {
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ const unsigned idx = index.row();
+ auto memoryMapEntry = std::next(m_ioManager->memoryMap().begin(), idx);
+ switch (index.column()) {
+ case Column::Name: {
+ if (role == Qt::DisplayRole) {
+ return memoryMapEntry->second.name;
+ }
+ break;
+ }
+ case Column::AddressRange: {
+ switch (role) {
+ case Qt::DisplayRole:
+ return encodeRadixValue(memoryMapEntry->first, Radix::Hex) + " - " +
+ encodeRadixValue(memoryMapEntry->first + memoryMapEntry->second.size, Radix::Hex);
+ case Qt::FontRole:
+ return QFont("Inconsolata", 11);
+ case Qt::TextAlignmentRole:
+ return Qt::AlignCenter;
+ }
+ break;
+ }
+ case Column::Size: {
+ switch (role) {
+ case Qt::DisplayRole: {
+ return QString::number(memoryMapEntry->second.size);
+ }
+ case Qt::TextAlignmentRole:
+ return Qt::AlignCenter;
+ }
+ break;
+ }
+
+ default:
+ return QVariant();
+ }
+ return QVariant();
+}
+
+Qt::ItemFlags MemoryMapModel::flags(const QModelIndex&) const {
+ return Qt::ItemIsEnabled;
+}
+} // namespace Ripes

ADD
src/io/memorymapmodel.h
+#pragma once
+
+#include <QColor>
+#include <set>
+#include "defines.h"
+#include "mainmemory.h"
+
+#include "isa/isainfo.h"
+#include "radix.h"
+
+#include <QAbstractTableModel>
+
+namespace Ripes {
+class IOBase;
+class IOManager;
+
+/**
+ * @brief The MemoryMapModel class
+ * A model for Qt's MVC framework, responsible for representing the current state of the memory system of the simulator.
+ */
+class MemoryMapModel : public QAbstractTableModel {
+ Q_OBJECT
+public:
+ enum Column { Name, Size, AddressRange, NColumns };
+ MemoryMapModel(const IOManager* iomanager, 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;
+
+public slots:
+ void memoryMapChanged();
+
+private:
+ IOManager const* m_ioManager = nullptr;
+};
+} // namespace Ripes

MODIFY
src/iotab.cpp
src/iotab.cpp
#include <QMdiSubWindow>
#include <QToolBar>
+#include "io/memorymapmodel.h"
#include "processorhandler.h"
#include "ioperipheraltab.h"
@@ -61,6 +62,11 @@ IOTab::IOTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent), m_
});
connect(m_ui->peripheralsTab, &QTabWidget::currentChanged, this, &IOTab::setPeripheralMDIWindowActive);
+ m_ui->memoryMapView->setModel(new MemoryMapModel(&m_iomanager, this));
+ m_ui->memoryMapView->horizontalHeader()->setSectionResizeMode(MemoryMapModel::Name, QHeaderView::ResizeToContents);
+ m_ui->memoryMapView->horizontalHeader()->setSectionResizeMode(MemoryMapModel::AddressRange,
+ QHeaderView::ResizeToContents);
+ m_ui->memoryMapView->horizontalHeader()->setSectionResizeMode(MemoryMapModel::Size, QHeaderView::ResizeToContents);
}
/**

MODIFY
src/iotab.ui
src/iotab.ui
</size>
</property>
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="peripherals">
<attribute name="title">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>TODO: Config</string>
- </property>
+ <widget class="QTableView" name="memoryMapView">
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
</widget>
</item>
- <item>
- <widget class="QTableView" name="tableView"/>
- </item>
</layout>
</item>
</layout>

MODIFY
src/ripessettings.h
src/ripessettings.h
@@ -49,7 +49,7 @@ const static std::map<QString, QVariant> s_defaultSettings = {
{RIPES_SETTING_ASSEMBLER_TEXTSTART, 0x0},
{RIPES_SETTING_ASSEMBLER_DATASTART, 0x10000000},
{RIPES_SETTING_ASSEMBLER_BSSSTART, 0x11000000},
- {RIPES_SETTING_PERIPHERALS_START, 0xF0000000},
+ {RIPES_SETTING_PERIPHERALS_START, static_cast<unsigned>(0xF0000000)},
// Program state preserving settings
{RIPES_SETTING_SETTING_TAB, 0},

Add MemoryMapModel