diff --git a/CMakeLists.txt b/CMakeLists.txt index 54faec4..c68f5eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,7 +129,8 @@ add_executable(ComSquare sources/Renderer/QtRenderer/QtSFML.hpp sources/Renderer/QtRenderer/QtWidgetSFML.cpp sources/Renderer/QtRenderer/QtWidgetSFML.hpp - Ui/cpu.ui + ui/cpu.ui + resources/appResources.qrc sources/Renderer/QtRenderer/QtWindow.cpp sources/Renderer/QtRenderer/QtWindow.hpp ) diff --git a/Ui/cpu.ui b/Ui/cpu.ui deleted file mode 100644 index 4efa2d9..0000000 --- a/Ui/cpu.ui +++ /dev/null @@ -1,45 +0,0 @@ - - - CPUView - - - - 0 - 0 - 600 - 400 - - - - CPU's Debugger - - - - - 0 - 25 - 200 - 375 - - - - - - - 0 - 0 - 200 - 25 - - - - Instructions History - - - Qt::AlignCenter - - - - - - diff --git a/resources/appResources.qrc b/resources/appResources.qrc new file mode 100644 index 0000000..d9b3d42 --- /dev/null +++ b/resources/appResources.qrc @@ -0,0 +1,6 @@ + + + Logo.png + icons/play.svg + + diff --git a/resources/icons/play.svg b/resources/icons/play.svg new file mode 100644 index 0000000..4de9b59 --- /dev/null +++ b/resources/icons/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index 1a07507..c35bd29 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -190,14 +190,12 @@ namespace ComSquare::CPU unsigned cycles = 0; for (int i = 0; i < 0xFF; i++) - cycles += this->_executeInstruction(); + cycles += this->_executeInstruction(this->_bus->read(this->_registers.pac++)); return cycles; } - unsigned CPU::_executeInstruction() + unsigned CPU::_executeInstruction(uint8_t opcode) { - uint8_t opcode = this->_bus->read(this->_registers.pc); - this->_hasIndexCrossedPageBoundary = false; switch (opcode) { diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index 3d42f1e..41a40b1 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -361,7 +361,7 @@ namespace ComSquare::CPU //! @brief Execute a single instruction. //! @return The number of CPU cycles that the instruction took. - unsigned _executeInstruction(); + virtual unsigned _executeInstruction(uint8_t opcode); //! @brief Reset interrupt - Called on boot and when the reset button is pressed. void RESB(); diff --git a/sources/Debugger/DebugCpu.cpp b/sources/Debugger/DebugCpu.cpp index d986fd2..b6a0245 100644 --- a/sources/Debugger/DebugCpu.cpp +++ b/sources/Debugger/DebugCpu.cpp @@ -7,22 +7,45 @@ namespace ComSquare::Debugger { CPUDebug::CPUDebug(ComSquare::CPU::CPU &basicCPU, SNES &snes) - : CPU::CPU(basicCPU), Ui::CPUView(), _snes(snes) + : CPU::CPU(basicCPU), QMainWindow(), _ui(), _snes(snes) { - this->setupUi(&this->_widget); - this->_widget.show(); + this->setContextMenuPolicy(Qt::NoContextMenu); + this->setAttribute(Qt::WA_QuitOnClose, false); + + this->_ui.setupUi(this); + QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause); + this->show(); } unsigned CPUDebug::update() { - if (!this->_widget.isVisible()) { + if (!this->isVisible()) { this->_snes.disableCPUDebugging(); return 0; } - this->logger->append("Update"); if (this->_isPaused) return 0xFF; return CPU::update(); } + + unsigned CPUDebug::_executeInstruction(uint8_t opcode) + { + this->_ui.logger->append(this->_getInstructionString(opcode).c_str()); + return CPU::_executeInstruction(opcode); + } + + std::string CPUDebug::_getInstructionString(uint8_t opcode) + { + return "Super"; + } + + void CPUDebug::pause() + { + this->_isPaused = !this->_isPaused; + if (this->_isPaused) + this->_ui.actionPause->setText("Resume"); + else + this->_ui.actionPause->setText("Pause"); + } } \ No newline at end of file diff --git a/sources/Debugger/DebugCpu.hpp b/sources/Debugger/DebugCpu.hpp index daca359..37e7677 100644 --- a/sources/Debugger/DebugCpu.hpp +++ b/sources/Debugger/DebugCpu.hpp @@ -9,19 +9,26 @@ #include "../Renderer/SFRenderer.hpp" #include "../SNES.hpp" #include "../Renderer/QtRenderer/QtWindow.hpp" -#include "../../Ui/ui_cpu.h" +#include "../../ui/ui_cpu.h" namespace ComSquare::Debugger { //! @brief A custom CPU with a window that show it's registers and the disassembly. - class CPUDebug : public CPU::CPU, Ui::CPUView { + class CPUDebug : public CPU::CPU, public QMainWindow { private: //! @brief A widget that contain the whole UI. - QWidget _widget; + Ui::CPUView _ui; //! @brief If this is set to true, the execution of the CPU will be paused. bool _isPaused = true; //! @brief A reference to the snes (to disable the debugger). SNES &_snes; + //! @brief Reimplement the basic instruction execution method to log instructions inside the logger view. + unsigned _executeInstruction(uint8_t opcode) override; + //! @brief Get a printable string representing an instruction. + std::string _getInstructionString(uint8_t opcode); + public slots: + //! @brief Pause/Resume the CPU. + void pause(); public: //! @brief Convert a basic CPU to a debugging CPU. explicit CPUDebug(ComSquare::CPU::CPU &cpu, SNES &snes); diff --git a/sources/Renderer/QtRenderer/QtWindow.cpp b/sources/Renderer/QtRenderer/QtWindow.cpp index 7268754..dcf0809 100644 --- a/sources/Renderer/QtRenderer/QtWindow.cpp +++ b/sources/Renderer/QtRenderer/QtWindow.cpp @@ -3,12 +3,14 @@ // #include "QtWindow.hpp" +#include namespace ComSquare::Renderer { QtWindow::QtWindow(unsigned int height, unsigned int width) : _frame(), _width(width), _height(height) { + this->_frame.setWindowIcon(QIcon(":/resources/Logo.png")); this->_frame.show(); } diff --git a/ui/cpu.ui b/ui/cpu.ui new file mode 100644 index 0000000..aea3729 --- /dev/null +++ b/ui/cpu.ui @@ -0,0 +1,108 @@ + + + CPUView + + + + 0 + 0 + 600 + 400 + + + + CPU's Debugger + + + + :/resources/Logo.png:/resources/Logo.png + + + false + + + + + + 0 + 25 + 200 + 375 + + + + + + + 0 + 0 + 200 + 25 + + + + Instructions History + + + Qt::AlignCenter + + + + + + + 0 + 0 + 600 + 30 + + + + + + + 0 + 0 + + + + toolBar + + + false + + + Qt::ToolButtonTextBesideIcon + + + true + + + TopToolBarArea + + + false + + + + + + + :/resources/icons/play.svg:/resources/icons/play.svg + + + Resume + + + Pause or Resume instruction execution. + + + P + + + + + + + +