From 0119a5856b33147256889df60092ef817e232826 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Sat, 28 Mar 2020 00:54:11 +0100
Subject: [PATCH] Showing the current PC in the disassembly view
---
CMakeLists.txt | 4 +-
sources/Debugger/CPUDebug.cpp | 75 ++++++++++++++++++++++++-----------
sources/Debugger/CPUDebug.hpp | 23 ++++++++++-
sources/Utility/Utility.cpp | 37 +++++++++++------
sources/Utility/Utility.hpp | 12 ++++--
ui/cpu.ui | 23 ++++++++++-
6 files changed, 133 insertions(+), 41 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6533542..41f0df3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -93,7 +93,9 @@ add_executable(unit_tests
tests/CPU/TransferRegisters.cpp
sources/CPU/AddressingModes.cpp
sources/Models/Components.hpp
- sources/CPU/Instruction.hpp sources/Exceptions/DebuggableError.hpp)
+ sources/CPU/Instruction.hpp
+ sources/Exceptions/DebuggableError.hpp
+)
# include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov)
diff --git a/sources/Debugger/CPUDebug.cpp b/sources/Debugger/CPUDebug.cpp
index 50a7d01..1c48db8 100644
--- a/sources/Debugger/CPUDebug.cpp
+++ b/sources/Debugger/CPUDebug.cpp
@@ -7,6 +7,7 @@
#include "../Exceptions/InvalidOpcode.hpp"
#include "../CPU/CPU.hpp"
#include
+#include
#include
#include
@@ -19,6 +20,7 @@ namespace ComSquare::Debugger
_window(new ClosableWindow(*this, &CPUDebug::disableDebugger)),
_ui(),
_model(*this),
+ _painter(*this),
_snes(snes)
{
this->_window->setContextMenuPolicy(Qt::NoContextMenu);
@@ -27,12 +29,12 @@ namespace ComSquare::Debugger
this->_ui.setupUi(this->_window);
- this->disassembledInstructions = this->_disassemble(0x808000, 0x7FFF);
- this->_ui.disasembly->setModel(&this->_model);
- this->_ui.disasembly->setShowGrid(false);
- this->_ui.disasembly->verticalHeader()->hide();
- this->_ui.disasembly->horizontalHeader()->hide();
- this->_ui.disasembly->horizontalHeader()->setStretchLastSection(true);
+ this->disassembledInstructions = this->_disassemble(this->_registers.pac, 0x7FFF);
+ 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->setItemDelegate(&this->_painter);
QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
QMainWindow::connect(this->_ui.actionStep, &QAction::triggered, this, &CPUDebug::step);
@@ -56,8 +58,11 @@ namespace ComSquare::Debugger
try {
if (this->_isPaused)
return 0xFF;
- if (this->_isStepping)
- return this->_executeInstruction(this->readPC());
+ if (this->_isStepping) {
+ unsigned ret = this->_executeInstruction(this->readPC());
+ this->_ui.disassembly->viewport()->repaint();
+ return ret;
+ }
return CPU::update();
} catch (InvalidOpcode &e) {
if (!this->_isPaused)
@@ -91,6 +96,10 @@ namespace ComSquare::Debugger
this->_ui.actionPause->setText("Resume");
else
this->_ui.actionPause->setText("Pause");
+ // TODO reload the disassembly from this point to update items that may be false up to this point
+ // TODO highlight the current line.
+ //this->disassembledInstructions. //= this->_disassemble(0x808000, 0x7FFF);
+ this->_ui.disassembly->viewport()->repaint();
}
void CPUDebug::step()
@@ -236,16 +245,6 @@ namespace ComSquare::Debugger
return ss.str();
}
- std::string CPUDebug::_getImmediateValue16Bits(uint24_t pc)
- {
- unsigned value = this->_bus->read(pc, true);
- value += this->_bus->read(pc + 1, true) << 8u;
-
- std::stringstream ss;
- ss << "#$" << std::hex << value;
- return ss.str();
- }
-
std::string CPUDebug::_getDirectValue(uint24_t pc)
{
std::stringstream ss;
@@ -292,6 +291,11 @@ namespace ComSquare::Debugger
this->_window->activateWindow();
}
+ uint24_t CPUDebug::getPC()
+ {
+ return this->_registers.pac;
+ }
+
DisassembledInstruction::DisassembledInstruction(const CPU::Instruction &instruction, uint24_t addr, std::string arg, uint8_t op)
: CPU::Instruction(instruction), address(addr), argument(std::move(arg)), opcode(op) {}
@@ -305,7 +309,7 @@ DisassemblyModel::DisassemblyModel(ComSquare::Debugger::CPUDebug &cpu) : QAbstra
int DisassemblyModel::columnCount(const QModelIndex &) const
{
- return 4;
+ return 3;
}
int DisassemblyModel::rowCount(const QModelIndex &) const
@@ -320,12 +324,37 @@ QVariant DisassemblyModel::data(const QModelIndex &index, int role) const
ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembledInstructions[index.row()];
switch (index.column()) {
case 0:
- return QString(ComSquare::Utility::to_hex(instruction.address).c_str());
- case 1:
return QString(instruction.name.c_str());
- case 2:
+ case 1:
return QString(instruction.argument.c_str());
default:
return QVariant();
}
-}
\ No newline at end of file
+}
+
+QVariant DisassemblyModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Horizontal)
+ return QVariant();
+ if (role != Qt::DisplayRole)
+ return QVariant();
+ ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembledInstructions[section];
+ return QString(ComSquare::Utility::to_hex(instruction.address, ComSquare::Utility::HexString::NoPrefix).c_str());
+}
+
+RowPainter::RowPainter(ComSquare::Debugger::CPUDebug &cpu, QObject *parent) : QStyledItemDelegate(parent), _cpu(cpu) { }
+
+void RowPainter::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembledInstructions[index.row()];
+
+ if (instruction.address == this->_cpu.getPC())
+ painter->fillRect(option.rect,QColor(Qt::darkGreen));
+ // TODO display breakpoints with the Qt::darkRed color.
+ QStyledItemDelegate::paint(painter, option, index);
+}
+
+QSize RowPainter::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
+{
+ return QSize();
+}
diff --git a/sources/Debugger/CPUDebug.hpp b/sources/Debugger/CPUDebug.hpp
index d6f05c3..014680a 100644
--- a/sources/Debugger/CPUDebug.hpp
+++ b/sources/Debugger/CPUDebug.hpp
@@ -5,6 +5,7 @@
#ifndef COMSQUARE_CPUDEBUG_HPP
#define COMSQUARE_CPUDEBUG_HPP
+#include
#include "../CPU/CPU.hpp"
#include "../Renderer/SFRenderer.hpp"
#include "../SNES.hpp"
@@ -34,6 +35,22 @@ public:
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 class that highlight breakpoints and the PC's position
+class RowPainter : public QStyledItemDelegate {
+ Q_OBJECT
+private:
+ ComSquare::Debugger::CPUDebug &_cpu;
+public:
+ explicit RowPainter(ComSquare::Debugger::CPUDebug &cpu, QObject *parent = nullptr);
+ RowPainter &operator=(const RowPainter &) = delete;
+ ~RowPainter() override = default;
+protected:
+ QSize sizeHint(const QStyleOptionViewItem &options, const QModelIndex &index) const override;
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
namespace ComSquare::Debugger
@@ -75,6 +92,8 @@ namespace ComSquare::Debugger
Ui::CPUView _ui;
//! @brief The disassembly viewer's model.
DisassemblyModel _model;
+ //! @brief A custom painter that highlight breakpoints and the PC's position.
+ RowPainter _painter;
//! @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.
@@ -119,7 +138,9 @@ namespace ComSquare::Debugger
void disableDebugger();
//! @brief The list of disassembled instructions to show on the debugger.
std::vector disassembledInstructions;
- //! @brief Update the UI when reseting the CPU.
+ //! @brief Return the current program counter of this CPU.
+ uint24_t getPC();
+ //! @brief Update the UI when resetting the CPU.
int RESB(uint24_t) override;
//! @brief Convert a basic CPU to a debugging CPU.
explicit CPUDebug(ComSquare::CPU::CPU &cpu, SNES &snes);
diff --git a/sources/Utility/Utility.cpp b/sources/Utility/Utility.cpp
index c66efbc..66500b7 100644
--- a/sources/Utility/Utility.cpp
+++ b/sources/Utility/Utility.cpp
@@ -3,29 +3,42 @@
//
#include
+#include
#include "Utility.hpp"
namespace ComSquare::Utility
{
- std::string to_hex(uint8_t i)
+ std::string to_hex(uint8_t i, HexString prefix)
{
- char buf[5];
- sprintf(buf, "0x%02X", i);
- return buf;
+ std::stringstream ss;
+ if (prefix == AsmPrefix)
+ ss << "$";
+ else if (prefix == StandardPrefix)
+ ss << "0x";
+ ss << std::hex << std::setfill('0') << std::setw(2) << static_cast(i);
+ return ss.str();
}
- std::string to_hex(uint16_t i)
+ std::string to_hex(uint16_t i, HexString prefix)
{
- char buf[7];
- sprintf(buf, "0x%04X", i);
- return buf;
+ std::stringstream ss;
+ if (prefix == AsmPrefix)
+ ss << "$";
+ else if (prefix == StandardPrefix)
+ ss << "0x";
+ ss << std::hex << std::setfill('0') << std::setw(4) << i;
+ return ss.str();
}
- std::string to_hex(uint24_t i)
+ std::string to_hex(uint24_t i, HexString prefix)
{
- char buf[9];
- sprintf(buf, "0x%06X", i);
- return buf;
+ std::stringstream ss;
+ if (prefix == AsmPrefix)
+ ss << "$";
+ else if (prefix == StandardPrefix)
+ ss << "0x";
+ ss << std::hex << std::setfill('0') << std::setw(6) << i;
+ return ss.str();
}
std::string to_binary(uint8_t i)
diff --git a/sources/Utility/Utility.hpp b/sources/Utility/Utility.hpp
index 2fbc8bb..489afc3 100644
--- a/sources/Utility/Utility.hpp
+++ b/sources/Utility/Utility.hpp
@@ -12,11 +12,17 @@
namespace ComSquare::Utility
{
- std::string to_hex(uint8_t i);
+ enum HexString {
+ NoPrefix,
+ AsmPrefix,
+ StandardPrefix
+ };
- std::string to_hex(uint16_t i);
+ std::string to_hex(uint8_t i, HexString prefix = StandardPrefix);
- std::string to_hex(uint24_t i);
+ std::string to_hex(uint16_t i, HexString prefix = StandardPrefix);
+
+ std::string to_hex(uint24_t i, HexString prefix = StandardPrefix);
std::string to_binary(uint8_t i);
diff --git a/ui/cpu.ui b/ui/cpu.ui
index e3b719f..eada993 100644
--- a/ui/cpu.ui
+++ b/ui/cpu.ui
@@ -23,13 +23,34 @@
-
-
+
1
0
+
+
+
+
+ QAbstractItemView::ExtendedSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ Qt::NoPen
+
+
+ false
+
+
+ false
+
-