mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-31 17:33:07 +00:00
Implementing the stack viewer
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user