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 +