Implementing the stack viewer

This commit is contained in:
Anonymus Raccoon
2020-04-03 21:54:05 +02:00
parent 6bd920b65b
commit 4ac1169dc2
4 changed files with 94 additions and 4 deletions
+59 -3
View File
@@ -21,6 +21,7 @@ namespace ComSquare::Debugger
_ui(),
_model(*this),
_painter(*this),
_stackModel(*this->_bus, *this),
_snes(snes)
{
this->_window->setContextMenuPolicy(Qt::NoContextMenu);
@@ -31,12 +32,16 @@ namespace ComSquare::Debugger
this->_updateDisassembly(this->_cartridgeHeader.emulationInterrupts.reset, 0xFFFF - this->_cartridgeHeader.emulationInterrupts.reset); //Parse the first page of the ROM (the code can't reach the second page without a jump).
this->_ui.disassembly->setModel(&this->_model);
this->_ui.disassembly->horizontalHeader()->setStretchLastSection(true);
this->_ui.disassembly->resizeColumnsToContents();
this->_ui.disassembly->verticalHeader()->setSectionResizeMode (QHeaderView::Fixed);
this->_ui.disassembly->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
this->_ui.disassembly->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
this->_ui.disassembly->verticalHeader()->setHighlightSections(false);
this->_ui.disassembly->setItemDelegate(&this->_painter);
this->_ui.stackView->setModel(&this->_stackModel);
this->_ui.stackView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
this->_ui.stackView->verticalHeader()->setSectionResizeMode (QHeaderView::Fixed);
this->_ui.stackView->verticalHeader()->setHighlightSections(false);
QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
QMainWindow::connect(this->_ui.actionStep, &QAction::triggered, this, &CPUDebug::step);
QMainWindow::connect(this->_ui.actionNext, &QAction::triggered, this, &CPUDebug::next);
@@ -175,6 +180,9 @@ namespace ComSquare::Debugger
this->_ui.cCheckbox->setCheckState(this->_registers.p.c ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
this->_ui.zCheckbox->setCheckState(this->_registers.p.z ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
this->_ui.nCheckbox->setCheckState(this->_registers.p.n ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
auto index = this->_stackModel.index(this->_registers.s / 2, 0);
this->_ui.stackView->scrollTo(index, QAbstractItemView::PositionAtCenter);
}
std::string CPUDebug::_getFlagsString()
@@ -247,6 +255,11 @@ namespace ComSquare::Debugger
{
return this->_registers.pac;
}
uint16_t CPUDebug::getStackPointer()
{
return this->_registers.s;
}
}
DisassemblyModel::DisassemblyModel(ComSquare::Debugger::CPUDebug &cpu) : QAbstractTableModel(), _cpu(cpu){ }
@@ -321,3 +334,46 @@ QSize RowPainter::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) co
{
return QSize();
}
StackModel::StackModel(ComSquare::Memory::MemoryBus &bus, ComSquare::Debugger::CPUDebug &cpu) : _bus(bus), _cpu(cpu) { }
int StackModel::rowCount(const QModelIndex &) const
{
return 0x10000 / 2;
}
int StackModel::columnCount(const QModelIndex &) const
{
return 2;
}
QVariant StackModel::data(const QModelIndex &index, int role) const
{
if (role == Qt::BackgroundRole) {
if (index.row() * 2 + index.column() == this->_cpu.getStackPointer())
return QColor(Qt::darkBlue);
if (index.row() * 2 + index.column() == this->_cpu.initialStackPointer)
return QColor(Qt::darkCyan);
}
if (role == Qt::TextAlignmentRole)
return Qt::AlignCenter;
if (role != Qt::DisplayRole)
return QVariant();
uint16_t addr = index.row() * 2 + index.column();
try {
uint8_t value = this->_bus.read(addr);
return (ComSquare::Utility::to_hex(value, ComSquare::Utility::NoPrefix).c_str());
} catch (std::exception &) {
return "??";
}
}
QVariant StackModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal)
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
uint16_t addr = section * 2;
return QString(ComSquare::Utility::to_hex(addr, ComSquare::Utility::HexString::NoPrefix).c_str());
}
+29
View File
@@ -17,6 +17,29 @@ namespace ComSquare::Debugger
class CPUDebug;
}
//! @brief The qt model that show the stack.
class StackModel : public QAbstractTableModel
{
Q_OBJECT
private:
ComSquare::Memory::MemoryBus &_bus;
ComSquare::Debugger::CPUDebug &_cpu;
public:
explicit StackModel(ComSquare::Memory::MemoryBus &bus, ComSquare::Debugger::CPUDebug &cpu);
StackModel(const StackModel &) = delete;
const StackModel &operator=(const StackModel &) = delete;
~StackModel() override = default;
//! @brief The number of row the table has.
int rowCount(const QModelIndex &parent) const override;
//! @brief The number of column the table has.
int columnCount(const QModelIndex &parent) const override;
//! @brief Return a data representing the table cell.
QVariant data(const QModelIndex &index, int role) const override;
//! @brief Override the headers to use hex values.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
};
//! @brief The qt model that show the disassembly.
class DisassemblyModel : public QAbstractTableModel
{
@@ -114,6 +137,8 @@ namespace ComSquare::Debugger
DisassemblyModel _model;
//! @brief A custom painter that highlight breakpoints and the PC's position.
RowPainter _painter;
//! @brief The stack viewer's model.
StackModel _stackModel;
//! @brief If this is set to true, the execution of the CPU will be paused.
bool _isPaused = true;
//! @brief If this is set to true, the CPU will execute one instruction and pause itself.
@@ -197,6 +222,10 @@ namespace ComSquare::Debugger
std::vector<Breakpoint> breakpoints;
//! @brief Return the current program counter of this CPU.
uint24_t getPC();
//! @brief Return the current stack pointer.
uint16_t getStackPointer();
//! @brief The stack pointer before the execution of any instructions.
uint16_t initialStackPointer = this->_registers.s;
//! @brief Update the UI when resetting the CPU.
int RESB() override;
//! @brief Convert a basic CPU to a debugging CPU.
+5 -1
View File
@@ -56,7 +56,11 @@
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QTableView" name="stackView"/>
<widget class="QTableView" name="stackView">
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
+1
View File
@@ -133,6 +133,7 @@ public:
gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
stackView = new QTableView(centralwidget);
stackView->setObjectName(QString::fromUtf8("stackView"));
stackView->horizontalHeader()->setVisible(false);
gridLayout_2->addWidget(stackView, 1, 0, 1, 1);