aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_gui/memorydock.cpp10
-rw-r--r--qtmips_gui/memorymodel.cpp32
-rw-r--r--qtmips_gui/memorymodel.h18
-rw-r--r--qtmips_gui/memorytableview.cpp74
-rw-r--r--qtmips_gui/memorytableview.h9
5 files changed, 129 insertions, 14 deletions
diff --git a/qtmips_gui/memorydock.cpp b/qtmips_gui/memorydock.cpp
index 856dfa2..97226af 100644
--- a/qtmips_gui/memorydock.cpp
+++ b/qtmips_gui/memorydock.cpp
@@ -80,10 +80,12 @@ MemoryDock::MemoryDock(QWidget *parent, QSettings *settings) : QDockWidget(paren
setWidget(content);
connect(this, &MemoryDock::machine_setup, memory_model, &MemoryModel::setup);
- connect(cell_size, QOverload<int>::of(&QComboBox::currentIndexChanged),
- memory_model, &MemoryModel::set_cell_size);
- connect(memory_model, SIGNAL(cell_size_changed()),
- memory_content, SLOT(adap_to_cell_size()));
+ connect(cell_size, SIGNAL(currentIndexChanged(int)),
+ memory_content, SLOT(set_cell_size(int)));
+ connect(go_edit, SIGNAL(textEdited(QString)),
+ memory_content, SLOT(go_to_edit_text(QString)));
+ connect(memory_content, SIGNAL(set_go_edit_text(QString)),
+ go_edit, SLOT(setText(QString)));
}
void MemoryDock::setup(machine::QtMipsMachine *machine) {
diff --git a/qtmips_gui/memorymodel.cpp b/qtmips_gui/memorymodel.cpp
index 13ae1c7..69a412d 100644
--- a/qtmips_gui/memorymodel.cpp
+++ b/qtmips_gui/memorymodel.cpp
@@ -47,8 +47,8 @@ MemoryModel::MemoryModel(QObject *parent)
}
int MemoryModel::rowCount(const QModelIndex & /*parent*/) const {
- std::uint64_t rows = (0x2000 + cells_per_row - 1) / cells_per_row;
- return rows;
+ // std::uint64_t rows = (0x2000 + cells_per_row - 1) / cells_per_row;
+ return 2000;
}
int MemoryModel::columnCount(const QModelIndex & /*parent*/) const {
@@ -143,6 +143,10 @@ void MemoryModel::set_cell_size(int index) {
emit cell_size_changed();
}
+void MemoryModel::update_all() {
+ emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
+}
+
void MemoryModel::check_for_updates() {
bool need_update = false;
if (machine == nullptr)
@@ -158,5 +162,27 @@ void MemoryModel::check_for_updates() {
}
if (!need_update)
return;
- emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
+ update_all();
+}
+
+bool MemoryModel::adjustRowAndOffset(int &row, int optimal_row, std::uint32_t address) {
+ if (optimal_row < rowCount() / 8)
+ optimal_row = rowCount() / 8;
+ if (optimal_row >= rowCount() - rowCount() / 8)
+ optimal_row = rowCount() - rowCount() / 8;
+ row = rowCount() / 2;
+ address -= address % cellSizeBytes();
+ std::uint32_t row_bytes = cells_per_row * cellSizeBytes();
+ std::uint32_t diff = row * row_bytes;
+ if (diff > address) {
+ row = address / row_bytes;
+ if (row == 0) {
+ index0_offset = 0;
+ } else {
+ index0_offset = address - row * row_bytes;
+ }
+ } else {
+ index0_offset = address - diff;
+ }
+ return get_row_for_address(row, address);
}
diff --git a/qtmips_gui/memorymodel.h b/qtmips_gui/memorymodel.h
index e85d476..b06eff8 100644
--- a/qtmips_gui/memorymodel.h
+++ b/qtmips_gui/memorymodel.h
@@ -57,6 +57,8 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool adjustRowAndOffset(int &row, int optimal_row, std::uint32_t address);
+ void update_all();
void setCellsPerRow(unsigned int cells);
@@ -68,6 +70,10 @@ public:
return &data_font;
}
+ inline const std::uint32_t getIndex0Offset() const {
+ return index0_offset;
+ }
+
inline unsigned int cellSizeBytes() const {
switch (cell_size) {
case CELLSIZE_BYTE:
@@ -83,6 +89,18 @@ public:
address = index0_offset + (row * cells_per_row * cellSizeBytes());
return address >= index0_offset;
}
+ inline bool get_row_for_address(int &row, std::uint32_t address) const {
+ if (address < index0_offset) {
+ row = -1;
+ return false;
+ }
+ row = (address - index0_offset) / (cells_per_row * cellSizeBytes());
+ if ((address - index0_offset > 0x80000000) || row > rowCount()) {
+ row = rowCount();
+ return false;
+ }
+ return true;
+ }
public slots:
void setup(machine::QtMipsMachine *machine);
diff --git a/qtmips_gui/memorytableview.cpp b/qtmips_gui/memorytableview.cpp
index 9b5cddf..09accb0 100644
--- a/qtmips_gui/memorytableview.cpp
+++ b/qtmips_gui/memorytableview.cpp
@@ -35,11 +35,13 @@
#include <QHeaderView>
#include <QFontMetrics>
+#include <QScrollBar>
#include "memorytableview.h"
#include "memorymodel.h"
MemoryTableView::MemoryTableView(QWidget *parent) : Super(parent) {
-
+ connect(verticalScrollBar() , SIGNAL(valueChanged(int)),
+ this, SLOT(adjust_scroll_pos()));
}
void MemoryTableView::adjustColumnCount() {
@@ -58,7 +60,7 @@ void MemoryTableView::adjustColumnCount() {
horizontalHeader()->resizeSection(1, width1);
int w = verticalHeader()->width() + 8;
- int cells;
+ unsigned int cells;
width0 = columnWidth(0);
width1 = columnWidth(1);
w = width() - w - width0;
@@ -70,18 +72,82 @@ void MemoryTableView::adjustColumnCount() {
if (cells != m->cellsPerRow()) {
m->setCellsPerRow(cells);
}
- for (int i = 1; i < m->cellsPerRow() + 1; i++) {
+ for (unsigned int i = 1; i < m->cellsPerRow() + 1; i++) {
horizontalHeader()->setSectionResizeMode(i, QHeaderView::Fixed);
horizontalHeader()->resizeSection(i, width1);
}
}
}
-void MemoryTableView::adap_to_cell_size() {
+void MemoryTableView::set_cell_size(int index) {
+ std::uint32_t address;
+ int row;
+ bool keep_row0 = false;
+ MemoryModel *m = dynamic_cast<MemoryModel*>(model());
+ if (m != nullptr) {
+ keep_row0 = m->get_row_address(address, rowAt(0));
+ m->set_cell_size(index);
+ }
adjustColumnCount();
+ if (keep_row0) {
+ m->adjustRowAndOffset(row, m->rowCount() / 2, address);
+ scrollTo(m->index(row, 0),
+ QAbstractItemView::PositionAtTop);
+ }
+}
+
+void MemoryTableView:: adjust_scroll_pos() {
+ std::uint32_t address;
+ MemoryModel *m = dynamic_cast<MemoryModel*>(model());
+ if (m == nullptr)
+ return;
+ std::uint32_t row_bytes = m->cellSizeBytes() * m->cellsPerRow();
+ std::uint32_t index0_offset = m->getIndex0Offset();
+
+ do {
+ int row = rowAt(0);
+ if (row < m->rowCount() / 8) {
+ if ((row == 0) && (index0_offset < row_bytes) && (index0_offset != 0)) {
+ m->adjustRowAndOffset(row, 0, 0);
+ } else if (index0_offset > row_bytes) {
+ m->get_row_address(address, row);
+ m->adjustRowAndOffset(row, m->rowCount() / 7, address);
+ } else {
+ break;
+ }
+ } else if (row > m->rowCount() - m->rowCount() / 8) {
+ m->get_row_address(address, row);
+ m->adjustRowAndOffset(row, m->rowCount() - m->rowCount() / 7, address);
+ } else {
+ break;
+ }
+ scrollTo(m->index(row, 0),
+ QAbstractItemView::PositionAtTop);
+ emit m->update_all();
+ } while(0);
+ m->get_row_address(address, rowAt(0));
+ QString s, t;
+ s = QString::number(address, 16).toUpper();
+ t.fill('0', 8 - s.count());
+ emit set_go_edit_text("0x" + t + s);
}
void MemoryTableView::resizeEvent(QResizeEvent *event) {
Super::resizeEvent(event);
adjustColumnCount();
}
+
+void MemoryTableView::go_to_edit_text(QString text) {
+ MemoryModel *m = dynamic_cast<MemoryModel*>(model());
+ int row;
+ if (m == nullptr)
+ return;
+ bool convertOK = true;
+ std::int32_t address = text.toULong(&convertOK, 0);
+ if (!convertOK)
+ return;
+ m->adjustRowAndOffset(row, m->rowCount() / 2, address);
+ scrollTo(m->index(row, 0),
+ QAbstractItemView::PositionAtTop);
+ emit m->update_all();
+}
diff --git a/qtmips_gui/memorytableview.h b/qtmips_gui/memorytableview.h
index 73b1ea9..ba00539 100644
--- a/qtmips_gui/memorytableview.h
+++ b/qtmips_gui/memorytableview.h
@@ -50,10 +50,13 @@ public:
MemoryTableView(QWidget *parent);
void resizeEvent(QResizeEvent *event) override;
-
+signals:
+ void set_go_edit_text(QString text);
public slots:
- void adap_to_cell_size();
-
+ void set_cell_size(int index);
+ void go_to_edit_text(QString text);
+private slots:
+ void adjust_scroll_pos();
private:
void adjustColumnCount();