From 09cd825bed0197c092cfdd1f021fee5337141622 Mon Sep 17 00:00:00 2001 From: Anonymus Raccoon Date: Mon, 23 Mar 2020 23:07:15 +0100 Subject: [PATCH] Cleaning up all debuggers --- sources/APU/APU.cpp | 5 ++ sources/APU/APU.hpp | 3 ++ sources/CPU/CPU.cpp | 5 ++ sources/CPU/CPU.hpp | 3 ++ sources/Debugger/APUDebug.cpp | 30 ++++++++---- sources/Debugger/APUDebug.hpp | 15 +++++- sources/Debugger/CPUDebug.cpp | 20 +++++--- sources/Debugger/CPUDebug.hpp | 9 +++- sources/Debugger/ClosableWindow.hpp | 6 +-- sources/Debugger/HeaderViewer.cpp | 74 +++++++++++++++++------------ sources/Debugger/HeaderViewer.hpp | 43 +++++++++++------ sources/Debugger/MemoryBusDebug.cpp | 32 ++++++++++--- sources/Debugger/MemoryBusDebug.hpp | 20 ++++++-- sources/Debugger/MemoryViewer.cpp | 23 ++++++--- sources/Debugger/MemoryViewer.hpp | 12 ++++- sources/Memory/MemoryBus.cpp | 5 ++ sources/Memory/MemoryBus.hpp | 3 ++ sources/SNES.cpp | 60 ++++++++++++++--------- sources/SNES.hpp | 3 +- 19 files changed, 266 insertions(+), 105 deletions(-) diff --git a/sources/APU/APU.cpp b/sources/APU/APU.cpp index 19a96d9..a4d9a7e 100644 --- a/sources/APU/APU.cpp +++ b/sources/APU/APU.cpp @@ -18,6 +18,11 @@ namespace ComSquare::APU this->reset(); } + bool APU::isDebugger() + { + return false; + } + uint8_t APU::_internalRead(uint24_t addr) { switch (addr) { case 0x0000 ... 0x00EF: diff --git a/sources/APU/APU.hpp b/sources/APU/APU.hpp index 5006316..f71afc0 100644 --- a/sources/APU/APU.hpp +++ b/sources/APU/APU.hpp @@ -273,6 +273,9 @@ namespace ComSquare::APU //! @brief This function is executed when the SNES is powered on or the reset button is pushed. void reset(); + + //! @brief Return true if the CPU is overloaded with debugging features. + virtual bool isDebugger(); }; } diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index 5a81b0f..e4efc02 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -18,6 +18,11 @@ namespace ComSquare::CPU this->RESB(); } + bool CPU::isDebugger() + { + return false; + } + void CPU::setMemoryBus(std::shared_ptr bus) { this->_bus = std::move(bus); diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index a856962..8efd3d8 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -573,6 +573,9 @@ namespace ComSquare::CPU //! @brief Reset interrupt - Called on boot and when the reset button is pressed. virtual void RESB(); + //! @brief Return true if the CPU is overloaded with debugging features. + virtual bool isDebugger(); + //! @brief Change the memory bus used by the CPU. void setMemoryBus(std::shared_ptr bus); }; diff --git a/sources/Debugger/APUDebug.cpp b/sources/Debugger/APUDebug.cpp index 443334e..6b34b5d 100644 --- a/sources/Debugger/APUDebug.cpp +++ b/sources/Debugger/APUDebug.cpp @@ -12,15 +12,16 @@ namespace ComSquare::Debugger { APUDebug::APUDebug(APU &apu, SNES &snes) : APU(apu), - QMainWindow(), + _window(new ClosableWindow(*this, &APUDebug::disableDebugger)), _ui(), _snes(snes) { - this->setContextMenuPolicy(Qt::NoContextMenu); - this->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setContextMenuPolicy(Qt::NoContextMenu); + this->_window->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setAttribute(Qt::WA_DeleteOnClose); - this->_ui.setupUi(this); - this->show(); + this->_ui.setupUi(this->_window); + this->_window->show(); this->_updatePanel(); } @@ -479,10 +480,21 @@ namespace ComSquare::Debugger void APUDebug::update(unsigned cycles) { - if (!this->isVisible()) { - this->_snes.disableAPUDebugging(); - return; - } return APU::update(cycles); } + + void APUDebug::disableDebugger() + { + this->_snes.disableAPUDebugging(); + } + + bool APUDebug::isDebugger() + { + return true; + } + + void APUDebug::focus() + { + this->_window->activateWindow(); + } } \ No newline at end of file diff --git a/sources/Debugger/APUDebug.hpp b/sources/Debugger/APUDebug.hpp index 41d66e1..68a2f30 100644 --- a/sources/Debugger/APUDebug.hpp +++ b/sources/Debugger/APUDebug.hpp @@ -11,8 +11,11 @@ namespace ComSquare::Debugger { - class APUDebug : public APU::APU, public QMainWindow { + class APUDebug : public APU::APU { private: + //! @brief The QT window for this debugger. + ClosableWindow *_window; + //! @brief A widget that contain the whole UI. Ui::APUView _ui; @@ -30,6 +33,10 @@ namespace ComSquare::Debugger //! @brief return the mnemonic of the current instruction done. std::string _getInstructionString(); + + public slots: + //! @brief Called when the window is closed. Turn off the debugger and revert to a basic APU. + void disableDebugger(); public: //! @brief Convert a basic APU to a debugging APU. explicit APUDebug(ComSquare::APU::APU &apu, SNES &snes); @@ -39,6 +46,12 @@ namespace ComSquare::Debugger //! @brief Override the apu's update to disable debugging. void update(unsigned cycles) override; + + //! @brief Return true if the CPU is overloaded with debugging features. + bool isDebugger() override; + + //! @brief Focus the debugger's window. + void focus(); }; } diff --git a/sources/Debugger/CPUDebug.cpp b/sources/Debugger/CPUDebug.cpp index 77ab9f1..30a86ad 100644 --- a/sources/Debugger/CPUDebug.cpp +++ b/sources/Debugger/CPUDebug.cpp @@ -13,7 +13,10 @@ using namespace ComSquare::CPU; namespace ComSquare::Debugger { CPUDebug::CPUDebug(CPU &basicCPU, SNES &snes) - : CPU(basicCPU), _window(new ClosableWindow(this, &CPUDebug::disableDebugger)), _ui(), _snes(snes) + : CPU(basicCPU), + _window(new ClosableWindow(*this, &CPUDebug::disableDebugger)), + _ui(), + _snes(snes) { this->_window->setContextMenuPolicy(Qt::NoContextMenu); this->_window->setAttribute(Qt::WA_QuitOnClose, false); @@ -27,16 +30,16 @@ namespace ComSquare::Debugger this->_updateRegistersPanel(); } + bool CPUDebug::isDebugger() + { + return true; + } + void CPUDebug::disableDebugger() { this->_snes.disableCPUDebugging(); } - CPUDebug::~CPUDebug() - { - std::cout << "Destructor" << std::endl; - } - unsigned CPUDebug::update() { try { @@ -390,4 +393,9 @@ namespace ComSquare::Debugger CPU::RESB(); this->_updateRegistersPanel(); } + + void CPUDebug::focus() + { + this->_window->activateWindow(); + } } \ No newline at end of file diff --git a/sources/Debugger/CPUDebug.hpp b/sources/Debugger/CPUDebug.hpp index a7219a8..15fbb7c 100644 --- a/sources/Debugger/CPUDebug.hpp +++ b/sources/Debugger/CPUDebug.hpp @@ -16,6 +16,7 @@ namespace ComSquare::Debugger //! @brief A custom CPU with a window that show it's registers and the disassembly. class CPUDebug : public CPU::CPU, public QObject { private: + //! @brief The QT window for this debugger. ClosableWindow *_window; //! @brief A widget that contain the whole UI. Ui::CPUView _ui; @@ -67,7 +68,13 @@ namespace ComSquare::Debugger explicit CPUDebug(ComSquare::CPU::CPU &cpu, SNES &snes); CPUDebug(const CPUDebug &) = delete; CPUDebug &operator=(const CPUDebug &) = delete; - ~CPUDebug() override; + ~CPUDebug() override = default; + + //! @brief Return true if the CPU is overloaded with debugging features. + bool isDebugger() override; + + //! @brief Focus the debugger's window. + void focus(); //! @brief Override the basic cpu's update to allow pausing of the CPU only. unsigned update() override; diff --git a/sources/Debugger/ClosableWindow.hpp b/sources/Debugger/ClosableWindow.hpp index f87df08..02f8bae 100644 --- a/sources/Debugger/ClosableWindow.hpp +++ b/sources/Debugger/ClosableWindow.hpp @@ -14,15 +14,15 @@ namespace ComSquare::Debugger protected: void closeEvent(QCloseEvent *) override { - (this->_obj->*this->_onClose)(); + (this->_obj.*this->_onClose)(); } private: - T *_obj; + T &_obj; void (T::*_onClose)(); public: - explicit ClosableWindow(T *obj, void (T::*onClose)()) + explicit ClosableWindow(T &obj, void (T::*onClose)()) : _obj(obj), _onClose(onClose) { } ClosableWindow(const ClosableWindow &) = delete; diff --git a/sources/Debugger/HeaderViewer.cpp b/sources/Debugger/HeaderViewer.cpp index 92b421b..2e77c88 100644 --- a/sources/Debugger/HeaderViewer.cpp +++ b/sources/Debugger/HeaderViewer.cpp @@ -4,50 +4,64 @@ #include "HeaderViewer.hpp" #include "../Utility/Utility.hpp" +#include "../SNES.hpp" namespace ComSquare::Debugger { - HeaderViewer::HeaderViewer(ComSquare::Cartridge::Cartridge &cartridge) : - _cartridge(cartridge), + HeaderViewer::HeaderViewer(ComSquare::SNES &snes) + : _window(new ClosableWindow(*this, &HeaderViewer::disableDebugger)), + _snes(snes), + _cartridge(*snes.cartridge), _ui() { - this->setContextMenuPolicy(Qt::NoContextMenu); - this->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setContextMenuPolicy(Qt::NoContextMenu); + this->_window->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setAttribute(Qt::WA_DeleteOnClose); - this->_ui.setupUi(this); - this->_ui.nameLineEdit->setText(cartridge.header.gameName.c_str()); + this->_ui.setupUi(this->_window); + this->_ui.nameLineEdit->setText(this->_cartridge.header.gameName.c_str()); std::string memType; - if (cartridge.header.mappingMode & Cartridge::LoRom) + if (this->_cartridge.header.mappingMode & Cartridge::LoRom) memType += "LoRom "; - if (cartridge.header.mappingMode & Cartridge::HiRom) + if (this->_cartridge.header.mappingMode & Cartridge::HiRom) memType += "HiRom "; - if (cartridge.header.mappingMode & Cartridge::SlowRom) + if (this->_cartridge.header.mappingMode & Cartridge::SlowRom) memType += "SlowRom "; - if (cartridge.header.mappingMode & Cartridge::FastRom) + if (this->_cartridge.header.mappingMode & Cartridge::FastRom) memType += "FastRom "; - if (cartridge.header.mappingMode & Cartridge::ExRom) + if (this->_cartridge.header.mappingMode & Cartridge::ExRom) memType += "ExRom "; this->_ui.mappingLineEdit->setText(memType.c_str()); - this->_ui.romSizeLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.romSize).c_str()); - this->_ui.sRamSizeLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.sramSize).c_str()); - this->_ui.versionLineEdit->setText(std::to_string(cartridge.header.version).c_str()); - this->_ui.creatorIDLineEdit->setText(std::to_string(cartridge.header.creatorID).c_str()); - this->_ui.checksumLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.checksum).c_str()); - this->_ui.checksumComplementLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.checksumComplement).c_str()); + this->_ui.romSizeLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.romSize).c_str()); + this->_ui.sRamSizeLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.sramSize).c_str()); + this->_ui.versionLineEdit->setText(std::to_string(this->_cartridge.header.version).c_str()); + this->_ui.creatorIDLineEdit->setText(std::to_string(this->_cartridge.header.creatorID).c_str()); + this->_ui.checksumLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.checksum).c_str()); + this->_ui.checksumComplementLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.checksumComplement).c_str()); - this->_ui.coProcessorLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.emulationInterrupts.cop).c_str()); - this->_ui.breakLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.emulationInterrupts.brk).c_str()); - this->_ui.abortLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.emulationInterrupts.abort).c_str()); - this->_ui.nMInteruptLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.emulationInterrupts.nmi).c_str()); - this->_ui.resetLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.emulationInterrupts.reset).c_str()); - this->_ui.interruptRequestLineEdit->setText(ComSquare::Utility::to_hex(cartridge.header.emulationInterrupts.irq).c_str()); + this->_ui.coProcessorLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.emulationInterrupts.cop).c_str()); + this->_ui.breakLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.emulationInterrupts.brk).c_str()); + this->_ui.abortLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.emulationInterrupts.abort).c_str()); + this->_ui.nMInteruptLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.emulationInterrupts.nmi).c_str()); + this->_ui.resetLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.emulationInterrupts.reset).c_str()); + this->_ui.interruptRequestLineEdit->setText(ComSquare::Utility::to_hex(this->_cartridge.header.emulationInterrupts.irq).c_str()); - this->_ui.coProcessorLineEditNat->setText(ComSquare::Utility::to_hex(cartridge.header.nativeInterrupts.cop).c_str()); - this->_ui.breakLineEditNat->setText(ComSquare::Utility::to_hex(cartridge.header.nativeInterrupts.brk).c_str()); - this->_ui.abortLineEditNat->setText(ComSquare::Utility::to_hex(cartridge.header.nativeInterrupts.abort).c_str()); - this->_ui.nMInteruptLineEditNat->setText(ComSquare::Utility::to_hex(cartridge.header.nativeInterrupts.nmi).c_str()); - this->_ui.resetLineEditNat->setText(ComSquare::Utility::to_hex(cartridge.header.nativeInterrupts.reset).c_str()); - this->_ui.interruptRequestLineEditNat->setText(ComSquare::Utility::to_hex(cartridge.header.nativeInterrupts.irq).c_str()); - this->show(); + this->_ui.coProcessorLineEditNat->setText(ComSquare::Utility::to_hex(this->_cartridge.header.nativeInterrupts.cop).c_str()); + this->_ui.breakLineEditNat->setText(ComSquare::Utility::to_hex(this->_cartridge.header.nativeInterrupts.brk).c_str()); + this->_ui.abortLineEditNat->setText(ComSquare::Utility::to_hex(this->_cartridge.header.nativeInterrupts.abort).c_str()); + this->_ui.nMInteruptLineEditNat->setText(ComSquare::Utility::to_hex(this->_cartridge.header.nativeInterrupts.nmi).c_str()); + this->_ui.resetLineEditNat->setText(ComSquare::Utility::to_hex(this->_cartridge.header.nativeInterrupts.reset).c_str()); + this->_ui.interruptRequestLineEditNat->setText(ComSquare::Utility::to_hex(this->_cartridge.header.nativeInterrupts.irq).c_str()); + this->_window->show(); + } + + void HeaderViewer::disableDebugger() + { + this->_snes.disableHeaderViewer(); + } + + void HeaderViewer::focus() + { + this->_window->activateWindow(); } } \ No newline at end of file diff --git a/sources/Debugger/HeaderViewer.hpp b/sources/Debugger/HeaderViewer.hpp index b8e1226..e0cf04e 100644 --- a/sources/Debugger/HeaderViewer.hpp +++ b/sources/Debugger/HeaderViewer.hpp @@ -8,22 +8,37 @@ #include #include "../Cartridge/Cartridge.hpp" #include "../../ui/ui_cartridgeView.h" +#include "ClosableWindow.hpp" -namespace ComSquare::Debugger +namespace ComSquare { - //! @brief Window that show the header of the currently running game. - class HeaderViewer : public QMainWindow { - private: - //! @brief The cartrdige containing the header. - Cartridge::Cartridge &_cartridge; - //! @brief The layout of the viewer. - Ui::CatridgeView _ui; - public: - explicit HeaderViewer(Cartridge::Cartridge &cartridge); - HeaderViewer(const HeaderViewer &) = delete; - HeaderViewer &operator=(const HeaderViewer &) = delete; - ~HeaderViewer() override = default; - }; + class SNES; + namespace Debugger + { + //! @brief Window that show the header of the currently running game. + class HeaderViewer { + private: + //! @brief The QT window for this debugger. + ClosableWindow *_window{}; + //! @brief A reference to the snes (to disable the debugger). + SNES &_snes; + //! @brief The cartridge containing the header. + Cartridge::Cartridge &_cartridge; + //! @brief The layout of the viewer. + Ui::CatridgeView _ui; + public slots: + //! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU. + void disableDebugger(); + public: + //! @brief Focus the debugger's window. + void focus(); + + explicit HeaderViewer(SNES &snes); + HeaderViewer(const HeaderViewer &) = delete; + HeaderViewer &operator=(const HeaderViewer &) = delete; + ~HeaderViewer() = default; + }; + } } #endif //COMSQUARE_HEADERVIEWER_HPP diff --git a/sources/Debugger/MemoryBusDebug.cpp b/sources/Debugger/MemoryBusDebug.cpp index 37168ad..725cdf8 100644 --- a/sources/Debugger/MemoryBusDebug.cpp +++ b/sources/Debugger/MemoryBusDebug.cpp @@ -3,17 +3,35 @@ // #include "MemoryBusDebug.hpp" +#include "../SNES.hpp" namespace ComSquare::Debugger { - MemoryBusDebug::MemoryBusDebug(const ComSquare::Memory::MemoryBus &bus) - : MemoryBus(bus), QMainWindow(), _ui() + MemoryBusDebug::MemoryBusDebug(SNES &snes, const Memory::MemoryBus &bus) + : MemoryBus(bus), + _window(new ClosableWindow(*this, &MemoryBusDebug::disableViewer)), + _snes(snes), + _ui() { - this->setContextMenuPolicy(Qt::NoContextMenu); - this->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setContextMenuPolicy(Qt::NoContextMenu); + this->_window->setAttribute(Qt::WA_QuitOnClose, false); - this->_ui.setupUi(this); -// QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause); - this->show(); + this->_ui.setupUi(this->_window); + this->_window->show(); + } + + void MemoryBusDebug::disableViewer() + { + this->_snes.disableMemoryBusDebugging(); + } + + void MemoryBusDebug::focus() + { + this->_window->activateWindow(); + } + + bool MemoryBusDebug::isDebugger() + { + return true; } } \ No newline at end of file diff --git a/sources/Debugger/MemoryBusDebug.hpp b/sources/Debugger/MemoryBusDebug.hpp index e93c6e0..6edd4f6 100644 --- a/sources/Debugger/MemoryBusDebug.hpp +++ b/sources/Debugger/MemoryBusDebug.hpp @@ -8,19 +8,33 @@ #include #include "../Memory/MemoryBus.hpp" #include "../../ui/ui_busView.h" +#include "ClosableWindow.hpp" namespace ComSquare::Debugger { //! @brief window that allow the user to view all data going through the memory bus. - class MemoryBusDebug : public Memory::MemoryBus, public QMainWindow { + class MemoryBusDebug : public Memory::MemoryBus { private: + //! @brief The QT window for this debugger. + ClosableWindow *_window; + //! @brief A reference to the snes (to disable the debugger). + SNES &_snes; //! @brief A widget that contain the whole UI. Ui::BusView _ui; + public slots: + //! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU. + void disableViewer(); public: - explicit MemoryBusDebug(const Memory::MemoryBus &bus); + explicit MemoryBusDebug(SNES &snes, const Memory::MemoryBus &bus); MemoryBusDebug(const MemoryBusDebug &) = delete; MemoryBusDebug &operator=(const MemoryBusDebug &) = delete; - ~MemoryBusDebug() override = default; + ~MemoryBusDebug() = default; + + //! @brief Focus the debugger's window. + void focus(); + + //! @brief Return true if the Bus is overloaded with debugging features. + bool isDebugger() override; }; } diff --git a/sources/Debugger/MemoryViewer.cpp b/sources/Debugger/MemoryViewer.cpp index 632f356..748b9b7 100644 --- a/sources/Debugger/MemoryViewer.cpp +++ b/sources/Debugger/MemoryViewer.cpp @@ -65,16 +65,17 @@ void MemoryViewerModel::setMemory(std::shared_ptr memory) namespace ComSquare::Debugger { MemoryViewer::MemoryViewer(ComSquare::SNES &snes, Memory::MemoryBus &bus) : - QMainWindow(), + _window(new ClosableWindow(*this, &MemoryViewer::disableViewer)), _snes(snes), _bus(bus), _ui(), _model(snes.wram) { - this->setContextMenuPolicy(Qt::NoContextMenu); - this->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setContextMenuPolicy(Qt::NoContextMenu); + this->_window->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setAttribute(Qt::WA_DeleteOnClose); - this->_ui.setupUi(this); + this->_ui.setupUi(this->_window); this->_ui.tableView->setModel(&this->_model); this->_ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); this->_ui.tabs->addTab("&WRam"); @@ -84,7 +85,12 @@ namespace ComSquare::Debugger QMainWindow::connect(this->_ui.actionGoto, &QAction::triggered, this, &MemoryViewer::gotoAddr); QMainWindow::connect(this->_ui.actionGoto_Absolute, &QAction::triggered, this, &MemoryViewer::gotoAbsoluteAddr); QObject::connect(this->_ui.tabs, &QTabBar::currentChanged, this, &MemoryViewer::changeRam); - this->show(); + this->_window->show(); + } + + void MemoryViewer::disableViewer() + { + this->_snes.disableRamViewer(); } void MemoryViewer::changeRam(int id) @@ -118,7 +124,7 @@ namespace ComSquare::Debugger void MemoryViewer::_internalGoto(bool isAbsolute) { - QDialog dialog(this); + QDialog dialog(this->_window); dialog.setWindowModality(Qt::WindowModal); Ui::GotoDialog dialogUI; dialogUI.setupUi(&dialog); @@ -162,4 +168,9 @@ namespace ComSquare::Debugger throw InvalidAddress("Memory viewer switch to address", addr); return addr - accessor->getStart(); } + + void MemoryViewer::focus() + { + this->_window->activateWindow(); + } } \ No newline at end of file diff --git a/sources/Debugger/MemoryViewer.hpp b/sources/Debugger/MemoryViewer.hpp index cd4c13f..3619866 100644 --- a/sources/Debugger/MemoryViewer.hpp +++ b/sources/Debugger/MemoryViewer.hpp @@ -10,6 +10,7 @@ #include "../../ui/ui_gotoDialog.h" #include "../Ram/Ram.hpp" #include "../Memory/MemoryBus.hpp" +#include "ClosableWindow.hpp" #include using ComSquare::Ram::Ram; @@ -49,8 +50,11 @@ namespace ComSquare namespace Debugger { //! @brief Class responsible of the Memory Viewer. - class MemoryViewer : public QMainWindow { + class MemoryViewer : public QObject { + Q_OBJECT private: + //! @brief The QT window for this debugger. + ClosableWindow *_window; //! @brief SNES containing all rams to view. SNES &_snes; //! @brief The memory bus used to get the view for a given address. @@ -61,6 +65,9 @@ namespace ComSquare MemoryViewerModel _model; //! @brief Helper function to create the goto dialog. void _internalGoto(bool isAbsolute); + public slots: + //! @brief Called when the window is closed. Turn off the debugger. + void disableViewer(); public: //! @brief Select the memory tab corresponding to a 24 bit address (map the address via the bus). //! @return The address converted to the new tab's locale space. @@ -73,6 +80,9 @@ namespace ComSquare //! @brief Create a popup asking you where you want to jump to with the absolute mode selected. void gotoAbsoluteAddr(); + //! @brief Focus the memory viewer's window. + void focus(); + explicit MemoryViewer(SNES &snes, Memory::MemoryBus &bus); MemoryViewer(const MemoryViewer &) = delete; MemoryViewer &operator=(const MemoryViewer &) = delete; diff --git a/sources/Memory/MemoryBus.cpp b/sources/Memory/MemoryBus.cpp index bb9229f..2e3177a 100644 --- a/sources/Memory/MemoryBus.cpp +++ b/sources/Memory/MemoryBus.cpp @@ -97,4 +97,9 @@ namespace ComSquare::Memory } // TODO should implement HiRom. } + + bool MemoryBus::isDebugger() + { + return false; + } } \ No newline at end of file diff --git a/sources/Memory/MemoryBus.hpp b/sources/Memory/MemoryBus.hpp index 3274807..bf67793 100644 --- a/sources/Memory/MemoryBus.hpp +++ b/sources/Memory/MemoryBus.hpp @@ -54,6 +54,9 @@ namespace ComSquare //! @param addr The address you want to look for. //! @return The components responsible for the address param or nullptr if none was found. std::shared_ptr getAccessor(uint24_t addr); + + //! @brief Return true if the Bus is overloaded with debugging features. + virtual bool isDebugger(); }; } } diff --git a/sources/SNES.cpp b/sources/SNES.cpp index aa5824c..e286c9e 100644 --- a/sources/SNES.cpp +++ b/sources/SNES.cpp @@ -27,10 +27,20 @@ namespace ComSquare this->_bus->mapComponents(*this); } + void SNES::update() + { + unsigned cycleCount = this->cpu->update(); + this->ppu->update(cycleCount); + this->apu->update(cycleCount); + } + void SNES::enableCPUDebugging() { #ifdef DEBUGGER_ENABLED - this->cpu = std::make_shared(*this->cpu, *this); + if (this->cpu->isDebugger()) + std::static_pointer_cast(this->cpu)->focus(); + else + this->cpu = std::make_shared(*this->cpu, *this); #else std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl; #endif @@ -38,14 +48,16 @@ namespace ComSquare void SNES::disableCPUDebugging() { - std::cout << "Disable the debugger of the CPU" << std::endl; this->cpu = std::make_shared(*this->cpu); } void SNES::enableRamViewer() { #ifdef DEBUGGER_ENABLED - this->_ramViewer = std::make_unique(*this, *this->_bus); + if (this->_ramViewer) + this->_ramViewer->focus(); + else + this->_ramViewer = std::make_unique(*this, *this->_bus); #endif } @@ -56,17 +68,13 @@ namespace ComSquare #endif } - void SNES::update() - { - unsigned cycleCount = this->cpu->update(); - this->ppu->update(cycleCount); - this->apu->update(cycleCount); - } - void SNES::enableHeaderViewer() { #ifdef DEBUGGER_ENABLED - this->_headerViewer = std::make_unique(*this->cartridge); + if (this->_headerViewer) + this->_headerViewer->focus(); + else + this->_headerViewer = std::make_unique(*this); #endif } @@ -80,7 +88,10 @@ namespace ComSquare void SNES::enableAPUDebugging() { #ifdef DEBUGGER_ENABLED - this->apu = std::make_shared(*this->apu, *this); + if (this->apu->isDebugger()) + std::static_pointer_cast(this->apu)->focus(); + else + this->apu = std::make_shared(*this->apu, *this); #else std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl; #endif @@ -91,6 +102,21 @@ namespace ComSquare this->apu = std::make_shared(*this->apu); } + void SNES::enableMemoryBusDebugging() + { + #ifdef DEBUGGER_ENABLED + if (this->_bus->isDebugger()) + std::static_pointer_cast(this->_bus)->focus(); + else + { + this->_bus = std::make_shared(*this, *this->_bus); + this->cpu->setMemoryBus(this->_bus); + } + #else + std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl; + #endif + } + void SNES::disableMemoryBusDebugging() { #ifdef DEBUGGER_ENABLED @@ -100,14 +126,4 @@ namespace ComSquare std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl; #endif } - - void SNES::enableMemoryBusDebugging() - { - #ifdef DEBUGGER_ENABLED - this->_bus = std::make_shared(*this->_bus); - this->cpu->setMemoryBus(this->_bus); - #else - std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl; - #endif - } } diff --git a/sources/SNES.hpp b/sources/SNES.hpp index b9a2025..25fb99e 100644 --- a/sources/SNES.hpp +++ b/sources/SNES.hpp @@ -28,7 +28,6 @@ namespace ComSquare std::unique_ptr _ramViewer; //! @brief The window that allow the user to view the cartridge's header. std::unique_ptr _headerViewer; -// std::unique_ptr _bus; @@ -74,7 +73,7 @@ namespace ComSquare //! @brief Create all the components using a common memory bus for all of them. SNES(const std::string &ramPath, Renderer::IRenderer &renderer); - SNES(const SNES &) = default; + SNES(const SNES &) = delete; SNES &operator=(const SNES &) = delete; ~SNES() = default; };