From 2fdc9e0e64c234832e13735a9e6972a699ed9bed Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Sun, 10 Feb 2019 01:16:12 +0100 Subject: Next steps to implement QTableView based memory view. Signed-off-by: Pavel Pisa --- qtmips_gui/memorydock.cpp | 14 +++++--- qtmips_gui/memorydock.h | 3 ++ qtmips_gui/memorymodel.cpp | 70 ++++++++++++++++++++++++++++++++++--- qtmips_gui/memorymodel.h | 20 ++++++++++- qtmips_gui/memorytableview.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++ qtmips_gui/memorytableview.h | 58 +++++++++++++++++++++++++++++++ qtmips_gui/qtmips_gui.pro | 6 ++-- 7 files changed, 238 insertions(+), 12 deletions(-) create mode 100644 qtmips_gui/memorytableview.cpp create mode 100644 qtmips_gui/memorytableview.h diff --git a/qtmips_gui/memorydock.cpp b/qtmips_gui/memorydock.cpp index eea7122..53cc2e0 100644 --- a/qtmips_gui/memorydock.cpp +++ b/qtmips_gui/memorydock.cpp @@ -41,6 +41,7 @@ #include #include #include "memorydock.h" +#include "memorytableview.h" @@ -51,11 +52,12 @@ MemoryDock::MemoryDock(QWidget *parent, QSettings *settings) : QDockWidget(paren QWidget *content = new QWidget(); QComboBox *cell_size = new QComboBox(); - cell_size->addItem("Word", MemoryModel::CELLSIZE_WORD); - cell_size->addItem("Half-word", MemoryModel::CELLSIZE_HWORD); cell_size->addItem("Byte", MemoryModel::CELLSIZE_BYTE); + cell_size->addItem("Half-word", MemoryModel::CELLSIZE_HWORD); + cell_size->addItem("Word", MemoryModel::CELLSIZE_WORD); + cell_size->setCurrentIndex(MemoryModel::CELLSIZE_WORD); - QTableView *memory_content = new QTableView(); + QTableView *memory_content = new MemoryTableView(0); // memory_content->setSizePolicy(); MemoryModel *memory_model = new MemoryModel(0); memory_content->setModel(memory_model); @@ -75,8 +77,12 @@ MemoryDock::MemoryDock(QWidget *parent, QSettings *settings) : QDockWidget(paren content->setLayout(layout); setWidget(content); + + connect(this, &MemoryDock::machine_setup, memory_model, &MemoryModel::setup); + connect(cell_size, QOverload::of(&QComboBox::currentIndexChanged), + memory_model, &MemoryModel::set_cell_size); } void MemoryDock::setup(machine::QtMipsMachine *machine) { - + emit machine_setup(machine); } diff --git a/qtmips_gui/memorydock.h b/qtmips_gui/memorydock.h index 8971457..2b34b8c 100644 --- a/qtmips_gui/memorydock.h +++ b/qtmips_gui/memorydock.h @@ -50,6 +50,9 @@ public: void setup(machine::QtMipsMachine *machine); +signals: + void machine_setup(machine::QtMipsMachine *machine); + private: }; diff --git a/qtmips_gui/memorymodel.cpp b/qtmips_gui/memorymodel.cpp index 71df4ce..65ee586 100644 --- a/qtmips_gui/memorymodel.cpp +++ b/qtmips_gui/memorymodel.cpp @@ -36,10 +36,12 @@ #include "memorymodel.h" MemoryModel::MemoryModel(QObject *parent) - :QAbstractTableModel(parent) { + :QAbstractTableModel(parent), data_font("Monospace") { cell_size = CELLSIZE_WORD; cells_per_row = 1; index0_offset = 0; + data_font.setStyleHint(QFont::TypeWriter); + machine = nullptr; } int MemoryModel::rowCount(const QModelIndex & /*parent*/) const { @@ -48,7 +50,7 @@ int MemoryModel::rowCount(const QModelIndex & /*parent*/) const { } int MemoryModel::columnCount(const QModelIndex & /*parent*/) const { - return 2; + return cells_per_row + 1; } QVariant MemoryModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -71,9 +73,67 @@ QVariant MemoryModel::headerData(int section, Qt::Orientation orientation, int r QVariant MemoryModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { - return QString("Row%1, Column%2") - .arg(index.row() + 1) - .arg(index.column() +1); + QString s, t; + std::uint32_t address; + std::uint32_t data; + address = index0_offset + (index.row() * cells_per_row * cellSizeBytes()); + if (address < index0_offset) + return QString(""); + if (index.column() == 0) { + t = QString::number(address, 16); + s.fill('0', 8 - t.count()); + return "0x" + s + t.toUpper(); + } + if (machine == nullptr) + return QString(""); + if (machine->memory() == nullptr) + return QString(""); + address += cellSizeBytes() * (index.column() - 1); + if (address < index0_offset) + return QString(""); + switch (cell_size) { + case CELLSIZE_BYTE: + data = machine->memory()->read_byte(address); + break; + case CELLSIZE_HWORD: + data = machine->memory()->read_hword(address); + break; + case CELLSIZE_WORD: + data = machine->memory()->read_word(address); + break; + } + + t = QString::number(data, 16); + s.fill('0', cellSizeBytes() * 2 - t.count()); + t = s + t; + + machine::LocationStatus loc_stat = machine::LOCSTAT_NONE; + if (machine->cache_data() != nullptr) { + loc_stat = machine->cache_data()->location_status(address); + if (loc_stat & machine::LOCSTAT_DIRTY) + t += " D"; + else if (loc_stat & machine::LOCSTAT_CACHED) + t += " C"; + } + return t; } + if (role==Qt::FontRole) + return data_font; return QVariant(); } + +void MemoryModel::setup(machine::QtMipsMachine *machine) { + this->machine = machine; +} + +void MemoryModel::setCellsPerRow(unsigned int cells) { + beginResetModel(); + cells_per_row = cells; + endResetModel(); +} + +void MemoryModel::set_cell_size(int index) { + beginResetModel(); + cell_size = (enum MemoryCellSize)index; + endResetModel(); +} diff --git a/qtmips_gui/memorymodel.h b/qtmips_gui/memorymodel.h index 8a01531..bbe51c5 100644 --- a/qtmips_gui/memorymodel.h +++ b/qtmips_gui/memorymodel.h @@ -37,6 +37,8 @@ #define MEMORYMODEL_H #include +#include +#include "qtmipsmachine.h" class MemoryModel : public QAbstractTableModel { @@ -55,7 +57,17 @@ 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; -private: + + void setCellsPerRow(unsigned int cells); + + inline unsigned int cellsPerRow() { + return cells_per_row; + } + + inline const QFont *getFont() const { + return &data_font; + } + inline unsigned int cellSizeBytes() const { switch (cell_size) { case CELLSIZE_BYTE: @@ -67,10 +79,16 @@ private: } return 0; } +public slots: + void setup(machine::QtMipsMachine *machine); + void set_cell_size(int index); +private: enum MemoryCellSize cell_size; unsigned int cells_per_row; std::uint32_t index0_offset; + QFont data_font; + machine::QtMipsMachine *machine; }; diff --git a/qtmips_gui/memorytableview.cpp b/qtmips_gui/memorytableview.cpp new file mode 100644 index 0000000..8435e35 --- /dev/null +++ b/qtmips_gui/memorytableview.cpp @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci + * Copyright (c) 2019 Pavel Pisa + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#include +#include +#include "memorytableview.h" +#include "memorymodel.h" + +MemoryTableView::MemoryTableView(QWidget *parent) : Super(parent) { + +} + +void MemoryTableView::resizeEvent(QResizeEvent *event) { + Super::resizeEvent(event); + MemoryModel *m = dynamic_cast(model()); + + if (horizontalHeader()->count() >= 2 && m != nullptr) { + QFontMetrics fm(*m->getFont()); + int width0 = fm.width("0x00000000"); + horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + horizontalHeader()->resizeSection(0, width0); + + QString t = ""; + t.fill(QChar('0'), m->cellSizeBytes() * 2); + int width1 = fm.width(t + " C"); + horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); + horizontalHeader()->resizeSection(1, width1); + + int w = verticalHeader()->width() + 8; + int cells; + width0 = columnWidth(0); + width1 = columnWidth(1); + w = width() - w - width0; + if (w < width1) { + cells = 1; + } else { + cells = w / width1; + } + if (cells != m->cellsPerRow()) { + m->setCellsPerRow(cells); + } + for (int i = 1; i < m->cellsPerRow() + 1; i++) { + horizontalHeader()->setSectionResizeMode(i, QHeaderView::Fixed); + horizontalHeader()->resizeSection(i, width1); + } + } +} diff --git a/qtmips_gui/memorytableview.h b/qtmips_gui/memorytableview.h new file mode 100644 index 0000000..2017b78 --- /dev/null +++ b/qtmips_gui/memorytableview.h @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci + * Copyright (c) 2019 Pavel Pisa + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#ifndef MEMORYTABLEVIEW_H +#define MEMORYTABLEVIEW_H + +#include +#include +#include + +class MemoryTableView : public QTableView +{ + Q_OBJECT + + using Super = QTableView; + +public: + MemoryTableView(QWidget *parent); + + void resizeEvent(QResizeEvent *event) override; + +private: + +}; + +#endif // MEMORYTABLEVIEW_H diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro index 4f40454..39d3cc6 100644 --- a/qtmips_gui/qtmips_gui.pro +++ b/qtmips_gui/qtmips_gui.pro @@ -47,7 +47,8 @@ SOURCES += \ cachedock.cpp \ graphicsview.cpp \ coreview/value.cpp \ - memorymodel.cpp + memorymodel.cpp \ + memorytableview.cpp HEADERS += \ mainwindow.h \ @@ -75,7 +76,8 @@ HEADERS += \ cachedock.h \ graphicsview.h \ coreview/value.h \ - memorymodel.h + memorymodel.h \ + memorytableview.h FORMS += \ NewDialog.ui \ -- cgit v1.2.3