From 7a51648ac95aeec7b4b587697e53315f4af1e0b2 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 6 Jul 2021 14:40:58 +0200 Subject: [PATCH] Reenabling APUs debugger --- CMakeLists.txt | 4 +- sources/APU/APU.cpp | 46 +- sources/APU/APU.hpp | 21 +- sources/APU/DSP/DSP.cpp | 36 +- sources/APU/DSP/DSP.hpp | 47 +- sources/APU/IPL/IPL.cpp | 10 + sources/APU/IPL/IPL.hpp | 9 + sources/CPU/CPU.hpp | 2 +- sources/Debugger/APUDebug.cpp | 237 ++++--- sources/Debugger/APUDebug.hpp | 675 ++++++++++--------- sources/Debugger/CPU/CPUDebug.cpp | 16 +- sources/Debugger/CPU/CPUDebug.hpp | 13 +- sources/Debugger/CPU/Disassembly.cpp | 10 +- sources/Debugger/CPU/SymbolLoaders/WlaDx.cpp | 2 +- sources/Debugger/CPU/SymbolLoaders/WlaDx.hpp | 2 +- sources/SNES.cpp | 14 +- sources/SNES.hpp | 5 +- 17 files changed, 596 insertions(+), 553 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe8bace..b32d227 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,8 +127,8 @@ add_executable(comsquare sources/Debugger/MemoryViewer.hpp sources/Debugger/HeaderViewer.cpp sources/Debugger/HeaderViewer.hpp -# sources/Debugger/APUDebug.hpp -# sources/Debugger/APUDebug.cpp + sources/Debugger/APUDebug.hpp + sources/Debugger/APUDebug.cpp sources/Debugger/MemoryBusDebug.cpp sources/Debugger/MemoryBusDebug.hpp sources/Debugger/CGramDebug.cpp diff --git a/sources/APU/APU.cpp b/sources/APU/APU.cpp index 38be765..3069934 100644 --- a/sources/APU/APU.cpp +++ b/sources/APU/APU.cpp @@ -3,18 +3,15 @@ // #include "APU.hpp" -#include "../Exceptions/InvalidAddress.hpp" -#include "../Exceptions/InvalidOpcode.hpp" -#include "../Exceptions/NotImplementedException.hpp" +#include "Exceptions/InvalidAddress.hpp" +#include "Exceptions/InvalidOpcode.hpp" #include #include namespace ComSquare::APU { - APU::APU(Renderer::IRenderer &renderer) : _renderer(renderer), - _map(new MemoryMap()), - _soundBuffer(), - _dsp(this->_soundBuffer, this->_soundBuffer.size() / 2, _map) + APU::APU(Renderer::IRenderer &renderer) + : _dsp(renderer, this->_map) { this->reset(); } @@ -33,7 +30,7 @@ namespace ComSquare::APU { switch (addr) { case 0x0000 ... 0x00EF: - return this->_map->Page0.read(addr); + return this->_map.Page0[addr]; case 0xF0: return this->_registers.unknown; case 0xF2: @@ -59,11 +56,11 @@ namespace ComSquare::APU case 0xFF: return this->_registers.counter2; case 0x0100 ... 0x01FF: - return this->_map->Page1.read(addr - 0x0100); + return this->_map.Page1[addr - 0x0100]; case 0x0200 ... 0xFFBF: - return this->_map->Memory.read(addr - 0x200); + return this->_map.Memory[addr - 0x200]; case 0xFFC0 ... 0xFFFF: - return this->_map->IPL.read(addr - 0xFFC0); + return this->_map.IPL[addr - 0xFFC0]; default: throw InvalidAddress("APU Registers read", addr); } @@ -73,7 +70,7 @@ namespace ComSquare::APU { switch (addr) { case 0x0000 ... 0x00EF: - this->_map->Page0.write(addr, data); + this->_map.Page0.write(addr, data); break; case 0xF0: this->_registers.unknown = data; @@ -115,13 +112,13 @@ namespace ComSquare::APU this->_registers.timer2 = data; break; case 0x0100 ... 0x01FF: - this->_map->Page1.write(addr - 0x0100, data); + this->_map.Page1.write(addr - 0x0100, data); break; case 0x0200 ... 0xFFBF: - this->_map->Memory.write(addr - 0x200, data); + this->_map.Memory.write(addr - 0x200, data); break; case 0xFFC0 ... 0xFFFF: - this->_map->IPL.write(addr - 0xFFC0, data); + this->_map.IPL.write(addr - 0xFFC0, data); break; default: throw InvalidAddress("APU Registers write", addr); @@ -801,7 +798,6 @@ namespace ComSquare::APU void APU::update(unsigned cycles) { unsigned total = 0; - int32_t samples = 0; if (this->_paddingCycles > cycles) { this->_paddingCycles -= cycles; @@ -814,9 +810,6 @@ namespace ComSquare::APU this->_paddingCycles = total - cycles; this->_dsp.update(); - samples = this->_dsp.getSamplesCount(); - if (samples > 0) - this->_renderer.playAudio(std::span(this->_soundBuffer.begin(), samples / 2)); } void APU::loadFromSPC(Cartridge::Cartridge &cartridge) @@ -841,9 +834,9 @@ namespace ComSquare::APU this->_internalRegisters.psw = cartridge.read(0x2A); this->_internalRegisters.sp = cartridge.read(0x2B); - std::memcpy(this->_map->Page0.getData(), data + 0x100, this->_map->Page0.getSize()); - std::memcpy(this->_map->Page1.getData(), data + 0x200, this->_map->Page1.getSize()); - std::memcpy(this->_map->Memory.getData(), data + 0x300, this->_map->Memory.getSize()); + std::memcpy(this->_map.Page0.getData(), data + 0x100, this->_map.Page0.getSize()); + std::memcpy(this->_map.Page1.getData(), data + 0x200, this->_map.Page1.getSize()); + std::memcpy(this->_map.Memory.getData(), data + 0x300, this->_map.Memory.getSize()); this->_registers.unknown = cartridge.read(0x100 + 0xF0); this->_registers.ctrlreg = cartridge.read(0x100 + 0xF1); @@ -896,9 +889,10 @@ namespace ComSquare::APU this->_internalRegisters.z = !value; } - MemoryMap::MemoryMap() : Page0(0x00F0, Apu, "APU's Page 0"), - Page1(0x0100, Apu, "APU's Page 1"), - Memory(0xFDC0, Apu, "APU's Ram"), - IPL(Apu, "IPL Rom") + MemoryMap::MemoryMap() + : Page0(0x00F0, Apu, "APU's Page 0"), + Page1(0x0100, Apu, "APU's Page 1"), + Memory(0xFDC0, Apu, "APU's Ram"), + IPL(Apu, "IPL Rom") {} }// namespace ComSquare::APU \ No newline at end of file diff --git a/sources/APU/APU.hpp b/sources/APU/APU.hpp index 66d7066..b9a3576 100644 --- a/sources/APU/APU.hpp +++ b/sources/APU/APU.hpp @@ -12,6 +12,10 @@ #include "Renderer/IRenderer.hpp" #include "Cartridge/Cartridge.hpp" +#ifdef DEBUGGER_ENABLED +#include "Debugger/APUDebug.hpp" +#endif + namespace ComSquare::APU { struct InternalRegisters { @@ -132,19 +136,14 @@ namespace ComSquare::APU }; class APU : public Memory::AMemory { - protected: + private: //! @brief All the registers of the APU CPU Registers _registers{}; //! @brief Internal registers of the CPU (accessible from the bus via addr $4200 to $421F). InternalRegisters _internalRegisters{}; - //! @brief Renderer used to play sounds - Renderer::IRenderer &_renderer; //! @brief Internal APU memory separated according to their utility - std::shared_ptr _map; - - //! @brief Buffer containing samples to be played - std::array _soundBuffer; + MemoryMap _map; //! @brief The DSP component used to produce sound DSP::DSP _dsp; @@ -199,7 +198,7 @@ namespace ComSquare::APU //! @brief Execute a single instruction. //! @return The number of cycles that the instruction took. - virtual int _executeInstruction(); + int _executeInstruction(); //! @brief No Operation instruction, do nothing than delay int NOP(); @@ -402,9 +401,13 @@ namespace ComSquare::APU //! @brief This function execute the instructions received until the maximum number of cycles is reached. //! @return The number of cycles that elapsed. - virtual void update(unsigned cycles); + void update(unsigned cycles); //! @brief This function is executed when the SNES is powered on or the reset button is pushed. void reset(); + +#ifdef DEBUGGER_ENABLED + friend Debugger::APU::APUDebug; +#endif }; } diff --git a/sources/APU/DSP/DSP.cpp b/sources/APU/DSP/DSP.cpp index fb933c9..63bfa2b 100644 --- a/sources/APU/DSP/DSP.cpp +++ b/sources/APU/DSP/DSP.cpp @@ -8,12 +8,12 @@ namespace ComSquare::APU::DSP { - DSP::DSP(std::array &buffer, uint32_t size, std::weak_ptr map) : - _state(buffer), _map(map) - { - this->_state.buffer = buffer; - this->_state.bufferSize = size; - } + DSP::DSP(Renderer::IRenderer &renderer, + MemoryMap &map) + : _state(this->_soundBuffer, this->_soundBuffer.size() / 2), + _map(map), + _renderer(renderer) + { } uint8_t DSP::read(uint24_t addr) const { @@ -570,17 +570,15 @@ namespace ComSquare::APU::DSP } uint8_t DSP::_readRAM(uint24_t addr) { - if (!this->_map.lock()) - throw std::runtime_error("DSP read : MemoryMap inaccessible"); switch (addr) { case 0x0000 ... 0x00EF: - return this->_map.lock()->Page0.read(addr); + return this->_map.Page0.read(addr); case 0x0100 ... 0x01FF: - return this->_map.lock()->Page1.read(addr - 0x0100); + return this->_map.Page1.read(addr - 0x0100); case 0x0200 ... 0xFFBF: - return this->_map.lock()->Memory.read(addr - 0x200); + return this->_map.Memory.read(addr - 0x200); case 0xFFC0 ... 0xFFFF: - return this->_map.lock()->IPL.read(addr - 0xFFC0); + return this->_map.IPL.read(addr - 0xFFC0); default: throw InvalidAddress("DSP read", addr); } @@ -588,20 +586,18 @@ namespace ComSquare::APU::DSP void DSP::_writeRAM(uint24_t addr, uint8_t data) { - if (!this->_map.lock()) - throw std::runtime_error("DSP write : MemoryMap inaccessible"); switch (addr) { case 0x0000 ... 0x00EF: - this->_map.lock()->Page0.write(addr, data); + this->_map.Page0.write(addr, data); break; case 0x0100 ... 0x01FF: - this->_map.lock()->Page1.write(addr - 0x0100, data); + this->_map.Page1.write(addr - 0x0100, data); break; case 0x0200 ... 0xFFBF: - this->_map.lock()->Memory.write(addr - 0x200, data); + this->_map.Memory.write(addr - 0x200, data); break; case 0xFFC0 ... 0xFFFF: - this->_map.lock()->IPL.write(addr - 0xFFC0, data); + this->_map.IPL.write(addr - 0xFFC0, data); break; default: throw InvalidAddress("DSP write", addr); @@ -764,7 +760,11 @@ namespace ComSquare::APU::DSP break; } this->_state.voice = (this->_state.voice + 1) % 32; + int32_t samples = this->getSamplesCount(); + if (samples > 0) + this->_renderer.playAudio(std::span(this->_soundBuffer.begin(), samples / 2)); } + uint24_t DSP::getSize() const { return 0x7F; diff --git a/sources/APU/DSP/DSP.hpp b/sources/APU/DSP/DSP.hpp index d8defa0..8e8e2e3 100644 --- a/sources/APU/DSP/DSP.hpp +++ b/sources/APU/DSP/DSP.hpp @@ -2,12 +2,12 @@ // Created by Melefo on 28/01/2020. // -#ifndef COMSQUARE_DSP_HPP -#define COMSQUARE_DSP_HPP +#pragma once #include #include -#include "../../Memory/AMemory.hpp" +#include "Renderer/IRenderer.hpp" +#include "Memory/AMemory.hpp" namespace ComSquare::APU { @@ -191,7 +191,9 @@ namespace ComSquare::APU::DSP //! @brief Current state of the DSP struct State { - State(std::array &array) : buffer(array) {}; + State(std::array &array, uint32_t size) + : buffer(array), bufferSize(size) + {}; //! @brief Current voice modification to do uint8_t voice = 0; @@ -324,31 +326,36 @@ namespace ComSquare::APU::DSP void decodeBRR(Voice &voice); //! @brief Whole APU RAM map - std::weak_ptr _map; + MemoryMap &_map; + + //! @brief Renderer used to play sounds + Renderer::IRenderer &_renderer; + //! @brief Buffer containing samples to be played + std::array _soundBuffer = {}; //! @brief Read inside APU RAM uint8_t _readRAM(uint24_t addr); //! @brief Write into APU RAM void _writeRAM(uint24_t addr, uint8_t data); public: - DSP(std::array &buffer, uint32_t size, std::weak_ptr map); + DSP(Renderer::IRenderer &renderer, MemoryMap &map); DSP(const DSP &) = default; - DSP &operator=(const DSP &) = default; + DSP &operator=(const DSP &) = delete; ~DSP() = default; //! @brief Return all 8 voices from DSP - const std::array &getVoices() const; - const Master &getMaster() const; - const Echo &getEcho() const; - const Noise &getNoise() const; - const BRR &getBrr() const; - const Latch &getLatch() const; + [[nodiscard]] const std::array &getVoices() const; + [[nodiscard]] const Master &getMaster() const; + [[nodiscard]] const Echo &getEcho() const; + [[nodiscard]] const Noise &getNoise() const; + [[nodiscard]] const BRR &getBrr() const; + [[nodiscard]] const Latch &getLatch() const; //! @brief Read from the internal DSP register. //! @param addr The address to read from. The address 0x0 should refer to the first byte of the register. //! @throw InvalidAddress will be thrown if the address is more than $7F (the number of register). //! @return Return the value of the register. - uint8_t read(uint24_t addr) const; + [[nodiscard]] uint8_t read(uint24_t addr) const; //! @brief Write data to the internal DSP register. //! @param addr The address to write to. The address 0x0 should refer to the first byte of register. //! @param data The new value of the register. @@ -356,19 +363,17 @@ namespace ComSquare::APU::DSP void write(uint24_t addr, uint8_t data); //! @brief Get the name of this accessor (used for debug purpose) - std::string getName() const; + [[nodiscard]] std::string getName() const; //! @brief Execute current voice transformation void update(); //! @brief Get the component of this accessor (used for debug purpose) - Component getComponent() const; + [[nodiscard]] Component getComponent() const; //! @brief Get the size of the data. This size can be lower than the mapped data. //! @return The number of bytes inside this memory. - uint24_t getSize() const; + [[nodiscard]] uint24_t getSize() const; //! @brief Return the number of samples written - int32_t getSamplesCount() const; + [[nodiscard]] int32_t getSamplesCount() const; }; -} - -#endif //COMSQUARE_DSP_HPP +} \ No newline at end of file diff --git a/sources/APU/IPL/IPL.cpp b/sources/APU/IPL/IPL.cpp index 0a50862..99fd05e 100644 --- a/sources/APU/IPL/IPL.cpp +++ b/sources/APU/IPL/IPL.cpp @@ -48,4 +48,14 @@ namespace ComSquare::APU::IPL // TODO implement this return "???"; } + + uint8_t &IPL::operator[](uint24_t addr) + { + return this->_data[addr]; + } + + const uint8_t &IPL::operator[](uint24_t addr) const + { + return this->_data[addr]; + } }// namespace ComSquare::APU::IPL \ No newline at end of file diff --git a/sources/APU/IPL/IPL.hpp b/sources/APU/IPL/IPL.hpp index 333f29f..fa81ab0 100644 --- a/sources/APU/IPL/IPL.hpp +++ b/sources/APU/IPL/IPL.hpp @@ -49,6 +49,15 @@ namespace ComSquare::APU::IPL //! @throw InvalidAddress if the address is not mapped to the component. void write(uint24_t addr, uint8_t data) override; + //! @brief Retrieve the data at the address given. This can be used instead of read or write. + //! @param addr The address of the data to retrieve. + //! @return The data at the address given as parameter. + uint8_t &operator[](uint24_t addr); + //! @brief Retrieve the data at the address given. This can be used instead of read or write. + //! @param addr The address of the data to retrieve. + //! @return The data at the address given as parameter. + const uint8_t &operator[](uint24_t addr) const; + //! @brief Get the size of the data. This size can be lower than the mapped data. //! @return The number of bytes inside this memory. [[nodiscard]] uint24_t getSize() const override; diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index bb96712..99bc554 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -648,7 +648,7 @@ namespace ComSquare::CPU bool IsAbortRequested = false; #ifdef DEBUGGER_ENABLED - friend Debugger::CPUDebug; + friend Debugger::CPU::CPUDebug; friend Debugger::RegisterViewer; #endif }; diff --git a/sources/Debugger/APUDebug.cpp b/sources/Debugger/APUDebug.cpp index 111deac..27f94bd 100644 --- a/sources/Debugger/APUDebug.cpp +++ b/sources/Debugger/APUDebug.cpp @@ -3,18 +3,17 @@ // #include "APUDebug.hpp" -#include "../Utility/Utility.hpp" -#include "../Exceptions/InvalidOpcode.hpp" +#include "SNES.hpp" +#include "APU/APU.hpp" +#include "Utility/Utility.hpp" +#include "Exceptions/InvalidOpcode.hpp" -using namespace ComSquare::APU; - -namespace ComSquare::Debugger +namespace ComSquare::Debugger::APU { - APUDebug::APUDebug(APU &apu, SNES &snes) - : APU(apu), - _window(new ClosableWindow([&snes] { snes.disableAPUDebugging(); })), + APUDebug::APUDebug(ComSquare::APU::APU &apu, SNES &snes) + : _window(new ClosableWindow([&snes] { snes.disableAPUDebugging(); })), _ui(), - _snes(snes) + _apu(apu) { this->_ui.setupUi(this->_window); QMainWindow::connect(this->_ui.resumeButton, &QPushButton::clicked, this, &APUDebug::pause); @@ -30,74 +29,74 @@ namespace ComSquare::Debugger void APUDebug::_updatePanel() { - this->_ui.port0hexaLineEdit->setText(Utility::to_hex(this->_registers.port0).c_str()); - this->_ui.port0LineEdit->setText(Utility::to_binary(this->_registers.port0).c_str()); + this->_ui.port0hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.port0).c_str()); + this->_ui.port0LineEdit->setText(Utility::to_binary(this->_apu._registers.port0).c_str()); - this->_ui.port1hexaLineEdit->setText(Utility::to_hex(this->_registers.port1).c_str()); - this->_ui.port1LineEdit->setText(Utility::to_binary(this->_registers.port1).c_str()); + this->_ui.port1hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.port1).c_str()); + this->_ui.port1LineEdit->setText(Utility::to_binary(this->_apu._registers.port1).c_str()); - this->_ui.port2hexaLineEdit->setText(Utility::to_hex(this->_registers.port2).c_str()); - this->_ui.port2LineEdit->setText(Utility::to_binary(this->_registers.port2).c_str()); + this->_ui.port2hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.port2).c_str()); + this->_ui.port2LineEdit->setText(Utility::to_binary(this->_apu._registers.port2).c_str()); - this->_ui.port3hexaLineEdit->setText(Utility::to_hex(this->_registers.port3).c_str()); - this->_ui.port3LineEdit->setText(Utility::to_binary(this->_registers.port3).c_str()); + this->_ui.port3hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.port3).c_str()); + this->_ui.port3LineEdit->setText(Utility::to_binary(this->_apu._registers.port3).c_str()); - this->_ui.controlhexaLineEdit->setText(Utility::to_hex(this->_registers.ctrlreg).c_str()); - this->_ui.controlLineEdit->setText(Utility::to_binary(this->_registers.ctrlreg).c_str()); + this->_ui.controlhexaLineEdit->setText(Utility::to_hex(this->_apu._registers.ctrlreg).c_str()); + this->_ui.controlLineEdit->setText(Utility::to_binary(this->_apu._registers.ctrlreg).c_str()); - this->_ui.dSPRegAddresshexaLineEdit->setText(Utility::to_hex(this->_registers.dspregAddr).c_str()); - this->_ui.dSPRegAddressLineEdit->setText(Utility::to_binary(this->_registers.dspregAddr).c_str()); + this->_ui.dSPRegAddresshexaLineEdit->setText(Utility::to_hex(this->_apu._registers.dspregAddr).c_str()); + this->_ui.dSPRegAddressLineEdit->setText(Utility::to_binary(this->_apu._registers.dspregAddr).c_str()); - this->_ui.dSPRegDatahexaLineEdit->setText(Utility::to_hex(this->_dsp.read(this->_registers.dspregAddr)).c_str()); - this->_ui.dSPRegDataLineEdit->setText(Utility::to_binary(this->_dsp.read(this->_registers.dspregAddr)).c_str()); + this->_ui.dSPRegDatahexaLineEdit->setText(Utility::to_hex(this->_apu._dsp.read(this->_apu._registers.dspregAddr)).c_str()); + this->_ui.dSPRegDataLineEdit->setText(Utility::to_binary(this->_apu._dsp.read(this->_apu._registers.dspregAddr)).c_str()); - this->_ui.timer0hexaLineEdit->setText(Utility::to_hex(this->_registers.timer0).c_str()); - this->_ui.timer0LineEdit->setText(Utility::to_binary(this->_registers.timer0).c_str()); + this->_ui.timer0hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.timer0).c_str()); + this->_ui.timer0LineEdit->setText(Utility::to_binary(this->_apu._registers.timer0).c_str()); - this->_ui.timer1hexaLineEdit->setText(Utility::to_hex(this->_registers.timer1).c_str()); - this->_ui.timer1LineEdit->setText(Utility::to_binary(this->_registers.timer1).c_str()); + this->_ui.timer1hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.timer1).c_str()); + this->_ui.timer1LineEdit->setText(Utility::to_binary(this->_apu._registers.timer1).c_str()); - this->_ui.timer2hexaLineEdit->setText(Utility::to_hex(this->_registers.timer2).c_str()); - this->_ui.timer2LineEdit->setText(Utility::to_binary(this->_registers.timer2).c_str()); + this->_ui.timer2hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.timer2).c_str()); + this->_ui.timer2LineEdit->setText(Utility::to_binary(this->_apu._registers.timer2).c_str()); - this->_ui.counter0hexaLineEdit->setText(Utility::to_hex(this->_registers.counter0).c_str()); - this->_ui.counter0LineEdit->setText(Utility::to_binary(this->_registers.counter0).c_str()); + this->_ui.counter0hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.counter0).c_str()); + this->_ui.counter0LineEdit->setText(Utility::to_binary(this->_apu._registers.counter0).c_str()); - this->_ui.counter1hexaLineEdit->setText(Utility::to_hex(this->_registers.counter1).c_str()); - this->_ui.counter1LineEdit->setText(Utility::to_binary(this->_registers.counter1).c_str()); + this->_ui.counter1hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.counter1).c_str()); + this->_ui.counter1LineEdit->setText(Utility::to_binary(this->_apu._registers.counter1).c_str()); - this->_ui.counter2hexaLineEdit->setText(Utility::to_hex(this->_registers.counter2).c_str()); - this->_ui.counter2LineEdit->setText(Utility::to_binary(this->_registers.counter2).c_str()); + this->_ui.counter2hexaLineEdit->setText(Utility::to_hex(this->_apu._registers.counter2).c_str()); + this->_ui.counter2LineEdit->setText(Utility::to_binary(this->_apu._registers.counter2).c_str()); - this->_ui.regMemhexaLineEdit->setText(Utility::to_hex(this->_registers.regmem1).c_str()); - this->_ui.regMemLineEdit->setText(Utility::to_binary(this->_registers.regmem1).c_str()); + this->_ui.regMemhexaLineEdit->setText(Utility::to_hex(this->_apu._registers.regmem1).c_str()); + this->_ui.regMemLineEdit->setText(Utility::to_binary(this->_apu._registers.regmem1).c_str()); - this->_ui.regMemhexaLineEdit_2->setText(Utility::to_hex(this->_registers.regmem2).c_str()); - this->_ui.regMemLineEdit_2->setText(Utility::to_binary(this->_registers.regmem2).c_str()); + this->_ui.regMemhexaLineEdit_2->setText(Utility::to_hex(this->_apu._registers.regmem2).c_str()); + this->_ui.regMemLineEdit_2->setText(Utility::to_binary(this->_apu._registers.regmem2).c_str()); - this->_ui.unknownhexaLineEdit->setText(Utility::to_hex(this->_registers.unknown).c_str()); - this->_ui.unknownLineEdit->setText(Utility::to_binary(this->_registers.unknown).c_str()); + this->_ui.unknownhexaLineEdit->setText(Utility::to_hex(this->_apu._registers.unknown).c_str()); + this->_ui.unknownLineEdit->setText(Utility::to_binary(this->_apu._registers.unknown).c_str()); - this->_ui.stackPointerLineEdit->setText(Utility::to_hex(this->_internalRegisters.sp).c_str()); - this->_ui.xIndexLineEdit->setText(Utility::to_hex(this->_internalRegisters.x).c_str()); - this->_ui.yIndexLineEdit->setText(Utility::to_hex(this->_internalRegisters.y).c_str()); - this->_ui.accumlatorLineEdit->setText(Utility::to_hex(this->_internalRegisters.a).c_str()); - this->_ui.programCounterLineEdit->setText(Utility::to_hex(this->_internalRegisters.pc).c_str()); - this->_ui.bFlagCheckBox->setChecked(this->_internalRegisters.b); - this->_ui.nFlagCheckBox->setChecked(this->_internalRegisters.n); - this->_ui.pFlagCheckBox->setChecked(this->_internalRegisters.p); - this->_ui.hFlagCheckBox->setChecked(this->_internalRegisters.h); - this->_ui.vFlagCheckBox->setChecked(this->_internalRegisters.v); - this->_ui.iFlagCheckBox->setChecked(this->_internalRegisters.i); - this->_ui.zFlagCheckBox->setChecked(this->_internalRegisters.z); - this->_ui.cFlagCheckBox->setChecked(this->_internalRegisters.c); + this->_ui.stackPointerLineEdit->setText(Utility::to_hex(this->_apu._internalRegisters.sp).c_str()); + this->_ui.xIndexLineEdit->setText(Utility::to_hex(this->_apu._internalRegisters.x).c_str()); + this->_ui.yIndexLineEdit->setText(Utility::to_hex(this->_apu._internalRegisters.y).c_str()); + this->_ui.accumlatorLineEdit->setText(Utility::to_hex(this->_apu._internalRegisters.a).c_str()); + this->_ui.programCounterLineEdit->setText(Utility::to_hex(this->_apu._internalRegisters.pc).c_str()); + this->_ui.bFlagCheckBox->setChecked(this->_apu._internalRegisters.b); + this->_ui.nFlagCheckBox->setChecked(this->_apu._internalRegisters.n); + this->_ui.pFlagCheckBox->setChecked(this->_apu._internalRegisters.p); + this->_ui.hFlagCheckBox->setChecked(this->_apu._internalRegisters.h); + this->_ui.vFlagCheckBox->setChecked(this->_apu._internalRegisters.v); + this->_ui.iFlagCheckBox->setChecked(this->_apu._internalRegisters.i); + this->_ui.zFlagCheckBox->setChecked(this->_apu._internalRegisters.z); + this->_ui.cFlagCheckBox->setChecked(this->_apu._internalRegisters.c); - auto voices = this->_dsp.getVoices(); - auto master = this->_dsp.getMaster(); - auto echo = this->_dsp.getEcho(); - auto noise = this->_dsp.getNoise(); - auto brr = this->_dsp.getBrr(); - auto latch = this->_dsp.getLatch(); + auto voices = this->_apu._dsp.getVoices(); + auto master = this->_apu._dsp.getMaster(); + auto echo = this->_apu._dsp.getEcho(); + auto noise = this->_apu._dsp.getNoise(); + auto brr = this->_apu._dsp.getBrr(); + auto latch = this->_apu._dsp.getLatch(); auto max = std::numeric_limits::max(); this->_ui.mvolLprogressBar->setValue(master.volume[0] * 100 / max); @@ -252,20 +251,19 @@ namespace ComSquare::Debugger QStringList labels = QStringList(); uint16_t offset = 0; - if (this->_pc != 0) + if (this->_apu._internalRegisters.pc != 0) { - auto pc = this->_internalRegisters.pc; + auto pc = this->_apu._internalRegisters.pc; - this->_internalRegisters.pc = this->_pc; this->_appendInstruction(0); - labels.append(Utility::to_hex(this->_pc).c_str()); - this->_internalRegisters.pc = pc; + labels.append(Utility::to_hex(pc).c_str()); + this->_apu._internalRegisters.pc = pc; } else labels.append("$0000"); for (uint16_t i = 1; i < 0x20; i++) { - auto pc = this->_internalRegisters.pc; + auto pc = this->_apu._internalRegisters.pc; offset += this->_appendInstruction(i); labels.append(Utility::to_hex(pc).c_str()); @@ -273,7 +271,7 @@ namespace ComSquare::Debugger this->_ui.logger->setVerticalHeaderLabels(labels); for (int i = 0; i < 3; i++) this->_ui.logger->item(1, i)->setData(Qt::BackgroundRole, QColor(200, 255, 148)); - this->_internalRegisters.pc -= offset; + this->_apu._internalRegisters.pc -= offset; } int APUDebug::_appendInstruction(int row) @@ -295,85 +293,104 @@ namespace ComSquare::Debugger return instruction.size; } - std::string APUDebug::_getOperand(Operand ope) + std::string APUDebug::_getOperand(Operand ope) const { + uint16_t pc = this->_apu._internalRegisters.pc; + std::string ret = "UNKNOWN"; + switch (ope) { case None: return ""; case A: - return Utility::to_hex(this->_internalRegisters.a); + ret = Utility::to_hex(this->_apu._internalRegisters.a); + break; case X: - return Utility::to_hex(this->_internalRegisters.x); + ret = Utility::to_hex(this->_apu._internalRegisters.x); + break; case Y: - return Utility::to_hex(this->_internalRegisters.y); + ret = Utility::to_hex(this->_apu._internalRegisters.y); + break; case SP: - return Utility::to_hex(this->_internalRegisters.sp); + ret = Utility::to_hex(this->_apu._internalRegisters.sp); + break; case PSW: - return Utility::to_hex(this->_internalRegisters.psw); + ret = Utility::to_hex(this->_apu._internalRegisters.psw); + break; case ImmediateData: - return Utility::to_hex(this->_getImmediateData()); + ret = Utility::to_hex(this->_apu._getImmediateData()); + break; case IndexXAddr: - return Utility::to_hex(this->_getIndexXAddr()); + ret = Utility::to_hex(this->_apu._getIndexXAddr()); + break; case IndexYAddr: - return Utility::to_hex(this->_getIndexYAddr()); + ret = Utility::to_hex(this->_apu._getIndexYAddr()); + break; case AbsoluteAddr: - return Utility::to_hex(this->_getAbsoluteAddr()); + ret = Utility::to_hex(this->_apu._getAbsoluteAddr()); + break; case AbsoluteBit: { - auto pair = this->_getAbsoluteBit(); - return Utility::to_hex(std::get<0>(pair)) + Utility::to_hex(std::get<1>(pair)); + auto pair = this->_apu._getAbsoluteBit(); + ret = Utility::to_hex(std::get<0>(pair)) + Utility::to_hex(std::get<1>(pair)); + break; } case AbsoluteAddrByX: - return Utility::to_hex(this->_getAbsoluteAddrByX()); + ret = Utility::to_hex(this->_apu._getAbsoluteAddrByX()); + break; case AbsoluteAddrByY: - return Utility::to_hex(this->_getAbsoluteAddrByY()); + ret = Utility::to_hex(this->_apu._getAbsoluteAddrByY()); + break; case AbsoluteByXAddr: - return Utility::to_hex(this->_getAbsoluteByXAddr()); + ret = Utility::to_hex(this->_apu._getAbsoluteByXAddr()); + break; case AbsoluteDirectByXAddr: - return Utility::to_hex(this->_getAbsoluteDirectByXAddr()); + ret = Utility::to_hex(this->_apu._getAbsoluteDirectByXAddr()); + break; case AbsoluteDirectAddrByY: - return Utility::to_hex(this->_getAbsoluteDirectAddrByY()); + ret = Utility::to_hex(this->_apu._getAbsoluteDirectAddrByY()); + break; case DirectAddr: - return Utility::to_hex(this->_getDirectAddr()); + ret = Utility::to_hex(this->_apu._getDirectAddr()); + break; case DirectAddrByX: - return Utility::to_hex(this->_getDirectAddrByX()); + ret = Utility::to_hex(this->_apu._getDirectAddrByX()); + break; case DirectAddrByY: - return Utility::to_hex(this->_getDirectAddrByY()); + ret = Utility::to_hex(this->_apu._getDirectAddrByY()); + break; } - return "UNKNOWN"; + this->_apu._internalRegisters.pc = pc; + return ret; } - Instruction &APUDebug::_getInstruction() + const Instruction &APUDebug::_getInstruction() const { - uint8_t opcode = this->_getImmediateData(); + uint8_t opcode = this->_apu._internalRead(this->_apu._internalRegisters.pc); return this->_instructions[opcode]; } - int APUDebug::_executeInstruction() + void APUDebug::update(unsigned maxCycles) { - int cycles = 0; + unsigned cycles = 0; - if (this->_isPaused) - return 0xFF; - if (this->_isStepping) { - this->_isStepping = false; - this->_isPaused = true; - } - cycles = APU::_executeInstruction(); - this->_updatePanel(); - return cycles; - } - - void APUDebug::update(unsigned cycles) - { - this->_pc = this->_internalRegisters.pc; try { - if (this->_isPaused) + if (this->_isPaused) { + this->_apu._dsp.update(); return; - APU::update(cycles); - } catch (InvalidOpcode &e) { + } + while (cycles < maxCycles) { + cycles += this->_apu._executeInstruction(); + this->_updatePanel(); + this->_updateLogger(); + if (this->_isStepping) { + this->_isStepping = false; + this->pause(); + return; + } + } + this->_apu._dsp.update(); + } catch (const InvalidOpcode &e) { this->pause(); - //this->_ui.logger->append(e.what()); } } diff --git a/sources/Debugger/APUDebug.hpp b/sources/Debugger/APUDebug.hpp index 838e176..8007af2 100644 --- a/sources/Debugger/APUDebug.hpp +++ b/sources/Debugger/APUDebug.hpp @@ -4,360 +4,361 @@ #pragma once -#include "APU/APU.hpp" -#include "SNES.hpp" +#include "ClosableWindow.hpp" #include "ui/ui_apuView.h" -namespace ComSquare::Debugger +namespace ComSquare { - //! @brief List of all types of operands used by the instructions - enum Operand + class SNES; + + namespace APU { - None, - A, - X, - Y, - SP, - PSW, - ImmediateData, - IndexXAddr, - IndexYAddr, - AbsoluteBit, - AbsoluteAddr, - AbsoluteAddrByX, - AbsoluteAddrByY, - AbsoluteByXAddr, - AbsoluteDirectByXAddr, - AbsoluteDirectAddrByY, - DirectAddr, - DirectAddrByX, - DirectAddrByY - }; + class APU; + } - //! @brief Small structure to store some values on the instructions - struct Instruction + namespace Debugger::APU { - std::string name; - int size; - std::tuple operands; - }; + //! @brief List of all types of operands used by the instructions + enum Operand + { + None, + A, + X, + Y, + SP, + PSW, + ImmediateData, + IndexXAddr, + IndexYAddr, + AbsoluteBit, + AbsoluteAddr, + AbsoluteAddrByX, + AbsoluteAddrByY, + AbsoluteByXAddr, + AbsoluteDirectByXAddr, + AbsoluteDirectAddrByY, + DirectAddr, + DirectAddrByX, + DirectAddrByY + }; - class APUDebug : public QObject - { - private: - //! @brief List of instructions and their information - const std::array _instructions {{ - {"NOP", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"OR", 2, {DirectAddr, None}}, - {"OR", 3, {AbsoluteAddr, None}}, - {"OR", 1, {IndexXAddr, None}}, - {"OR", 2, {AbsoluteDirectByXAddr, None}}, - {"OR", 2, {ImmediateData, None}}, - {"OR", 3, {DirectAddr, DirectAddr}}, - {"OR1", 3, {AbsoluteBit, None}}, - {"ASL", 2, {DirectAddr, None}}, - {"ASL", 3, {AbsoluteAddr, None}}, - {"PUSH", 1, {PSW, None}}, - {"TSET1", 3, {AbsoluteAddr, None}}, - {"BRK", 1, {None, None}}, - {"BPL", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"OR", 2, {DirectAddrByX, None}}, - {"OR", 3, {AbsoluteAddrByX, None}}, - {"OR", 3, {AbsoluteAddrByY, None}}, - {"OR", 2, {AbsoluteDirectAddrByY, None}}, - {"OR", 3, {DirectAddr, ImmediateData}}, - {"OR", 1, {IndexYAddr, IndexYAddr}}, - {"DECW", 2, {DirectAddr, None}}, - {"ASL", 2, {DirectAddrByX, None}}, - {"ASL", 1, {A, None}}, - {"DEC", 1, {X, None}}, - {"CMP", 3, {X, AbsoluteAddr}}, - {"JMP", 3, {AbsoluteByXAddr, None}}, - {"CLRP", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"AND", 2, {DirectAddr, None}}, - {"AND", 3, {AbsoluteAddr, None}}, - {"AND", 1, {IndexXAddr, None}}, - {"AND", 2, {AbsoluteDirectByXAddr, None}}, - {"AND", 2, {ImmediateData, None}}, - {"AND", 3, {DirectAddr, DirectAddr}}, - {"OR1", 3, {AbsoluteBit, None}}, - {"ROL", 2, {DirectAddr, None}}, - {"ROL", 3, {AbsoluteAddr, None}}, - {"PUSH", 1, {A, None}}, - {"CBNE", 3, {DirectAddrByX, ImmediateData}}, - {"BRA", 2, {ImmediateData, None}}, - {"BMI", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"AND", 2, {DirectAddrByX, None}}, - {"AND", 3, {AbsoluteAddrByX, None}}, - {"AND", 3, {AbsoluteAddrByY, None}}, - {"AND", 2, {AbsoluteDirectAddrByY, None}}, - {"AND", 3, {DirectAddr, ImmediateData}}, - {"AND", 1, {IndexXAddr, IndexYAddr}}, - {"INCW", 2, {DirectAddr, None}}, - {"ROL", 2, {AbsoluteAddrByX, None}}, - {"ROL", 1, {A, None}}, - {"INC", 1, {X, None}}, - {"CMP", 2, {X, DirectAddr}}, - {"CALL", 3, {AbsoluteAddr, None}}, - {"SETP", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"EOR", 2, {DirectAddr, None}}, - {"EOR", 3, {AbsoluteAddr, None}}, - {"EOR", 1, {IndexXAddr, None}}, - {"EOR", 2, {AbsoluteDirectByXAddr, None}}, - {"EOR", 2, {ImmediateData, None}}, - {"EOR", 3, {DirectAddr, DirectAddr}}, - {"AND1", 3, {AbsoluteBit, None}}, - {"LSR", 2, {DirectAddr, None}}, - {"LSR", 3, {AbsoluteAddr, None}}, - {"PUSH", 1, {X, None}}, - {"TCLR1", 3, {AbsoluteAddr, None}}, - {"PCALL", 3, {None, None}}, - {"BVC", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"EOR", 2, {DirectAddrByX, None}}, - {"EOR", 3, {AbsoluteAddrByX, None}}, - {"EOR", 3, {AbsoluteAddrByY, None}}, - {"EOR", 2, {AbsoluteDirectAddrByY, None}}, - {"EOR", 3, {DirectAddr, ImmediateData}}, - {"EOR", 1, {IndexXAddr, IndexYAddr}}, - {"CMPW", 2, {DirectAddr, None}}, - {"LSR", 2, {DirectAddrByX, None}}, - {"LSR", 1, {A, None}}, - {"MOV", 1, {A, X}}, - {"CMP", 3, {Y, AbsoluteAddr}}, - {"JMP", 3, {AbsoluteAddr, None}}, - {"CLRC", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"CMP", 2, {A, DirectAddr}}, - {"CMP", 3, {A, AbsoluteAddr}}, - {"CMP", 1, {A, IndexXAddr,}}, - {"CMP", 2, {A, AbsoluteDirectByXAddr}}, - {"CMP", 2, {A, ImmediateData}}, - {"CMP", 3, {DirectAddr, DirectAddr}}, - {"AND1", 3, {AbsoluteBit, None}}, - {"ROR", 2, {DirectAddr , None}}, - {"ROR", 3, {AbsoluteAddr, None}}, - {"PUSH", 1, {Y, None}}, - {"DBNZ", 3, {ImmediateData, None}}, - {"RET", 1, {None, None}}, - {"BVS", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"CMP", 2, {A, DirectAddrByX}}, - {"CMP", 3, {A, AbsoluteAddrByX}}, - {"CMP", 3, {A, AbsoluteAddrByY}}, - {"CMP", 2, {A, AbsoluteDirectAddrByY}}, - {"CMP", 3, {DirectAddr, ImmediateData}}, - {"CMP", 1, {IndexXAddr, IndexYAddr}}, - {"ADDW", 2, {DirectAddr, None}}, - {"ROR", 2, {DirectAddrByX, None}}, - {"ROR", 1, {A, None}}, - {"MOV", 1, {X, A}}, - {"CMP", 3, {Y, DirectAddr}}, - {"RETI", 1, {None, None}}, - {"SETC", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"ADC", 2, {DirectAddr, None}}, - {"ADC", 3, {AbsoluteAddr, None}}, - {"ADC", 1, {IndexXAddr, None}}, - {"ADC", 2, {AbsoluteDirectByXAddr, None}}, - {"ADC", 2, {ImmediateData, None}}, - {"ADC", 3, {DirectAddr, DirectAddr}}, - {"EOR1", 3, {AbsoluteBit, None}}, - {"DEC", 2, {DirectAddr, None}}, - {"DEC", 3, {AbsoluteAddr, None}}, - {"MOV", 2, {ImmediateData, Y}}, - {"POP", 1, {PSW, None}}, - {"MOV", 3, {DirectAddr, ImmediateData}}, - {"BCC", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"ADC", 2, {DirectAddrByX, None}}, - {"ADC", 3, {AbsoluteAddrByX, None}}, - {"ADC", 3, {AbsoluteAddrByY, None}}, - {"ADC", 2, {AbsoluteDirectAddrByY, None}}, - {"ADC", 3, {DirectAddr, ImmediateData}}, - {"ADC", 1, {IndexXAddr, IndexYAddr}}, - {"SUBW", 2, {DirectAddr, None}}, - {"DEC", 2, {DirectAddrByX, None}}, - {"DEC", 1, {A, None}}, - {"MOV", 1, {SP, X}}, - {"DIV", 1, {None, None}}, - {"XCN", 1, {None, None}}, - {"EI", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"SBC", 2, {DirectAddr, None}}, - {"SBC", 3, {AbsoluteAddr, None}}, - {"SBC", 1, {IndexXAddr, None}}, - {"SBC", 2, {AbsoluteDirectByXAddr, None}}, - {"SBC", 2, {ImmediateData, None}}, - {"SBC", 3, {DirectAddr, DirectAddr}}, - {"MOV1", 3, {AbsoluteBit, None}}, - {"INC", 2, {DirectAddr, None}}, - {"INC", 3, {AbsoluteAddr, None}}, - {"CMP", 2, {Y, ImmediateData}}, - {"POP", 1, {A, None}}, - {"MOV", 1, {A, IndexXAddr}}, - {"BCS", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"SBC", 2, {DirectAddrByX, None}}, - {"SBC", 3, {AbsoluteAddrByX, None}}, - {"SBC", 3, {AbsoluteAddrByY, None}}, - {"SBC", 2, {AbsoluteDirectAddrByY, None}}, - {"SBC", 2, {DirectAddr, ImmediateData}}, - {"SBC", 1, {IndexXAddr, IndexYAddr}}, - {"MOVW", 2, {DirectAddr, None}}, - {"INC", 2, {DirectAddrByX, None}}, - {"INC", 1, {A, None}}, - {"MOV", 1, {X, SP}}, - {"DAS", 1, {None, None}}, - {"MOV", 1, {IndexXAddr, A}}, - {"DI", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"MOV", 2, {A, DirectAddr}}, - {"MOV", 3, {A, AbsoluteAddr}}, - {"MOV", 1, {A, IndexXAddr}}, - {"MOV", 2, {A, AbsoluteDirectByXAddr}}, - {"CMP", 2, {X, ImmediateData}}, - {"MOV", 3, {X, AbsoluteAddr}}, - {"MOV1", 3, {AbsoluteBit, None}}, - {"MOV", 2, {Y, DirectAddr}}, - {"MOV", 3, {Y, AbsoluteAddr}}, - {"MOV", 2, {ImmediateData, X}}, - {"POP", 1, {X, None}}, - {"MUL", 1, {None, None}}, - {"BNE", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"MOV", 2, {A, DirectAddrByX}}, - {"MOV", 3, {A, AbsoluteAddrByX}}, - {"MOV", 3, {A, AbsoluteAddrByY}}, - {"MOV", 2, {A, AbsoluteDirectAddrByY}}, - {"MOV", 2, {X, DirectAddr}}, - {"MOV", 2, {X, DirectAddrByY}}, - {"MOVW", 2, {DirectAddr, None}}, - {"MOV", 2, {Y, DirectAddrByX}}, - {"DEC", 1, {Y, None}}, - {"MOV", 1, {Y, A}}, - {"CBNE", 3, {DirectAddrByX, ImmediateData}}, - {"DAA", 1, {None, None}}, - {"CLRV", 1, {None, None}}, - {"TCALL", 1, {None, None}}, - {"SET1", 2, {DirectAddr, None}}, - {"BBS", 3, {DirectAddr, ImmediateData}}, - {"MOV", 2, {DirectAddr, A}}, - {"MOV", 3, {AbsoluteAddrByX, A}}, - {"MOV", 1, {IndexXAddr, A}}, - {"MOV", 2, {AbsoluteDirectByXAddr, A}}, - {"MOV", 2, {ImmediateData, A}}, - {"MOV", 3, {AbsoluteAddr, X}}, - {"NOT1", 3, {AbsoluteBit, None}}, - {"MOV", 2, {DirectAddr, Y}}, - {"MOV", 3, {AbsoluteAddr, Y}}, - {"NOTC", 1, {None, None}}, - {"POP", 1, {Y, None}}, - {"SLEEP", 1, {None, None}}, - {"BEQ", 2, {ImmediateData, None}}, - {"TCALL", 1, {None, None}}, - {"CLR1", 2, {DirectAddr, None}}, - {"BBC", 3, {DirectAddr, ImmediateData}}, - {"MOV", 2, {DirectAddrByX, A}}, - {"MOV", 3, {AbsoluteAddrByX, A}}, - {"MOV", 3, {AbsoluteAddrByY, A}}, - {"MOV", 2, {AbsoluteDirectAddrByY, A}}, - {"MOV", 2, {DirectAddr, X}}, - {"MOV", 2, {DirectAddrByY, X}}, - {"MOV", 3, {DirectAddr, DirectAddr}}, - {"MOV", 2, {DirectAddrByX, Y}}, - {"INC", 1, {Y, None}}, - {"MOV", 1, {A, Y}}, - {"DBNZ", 3, {ImmediateData, None}}, - {"STOP", 1, {None, None}} - }}; + //! @brief Small structure to store some values on the instructions + struct Instruction + { + std::string name; + int size; + std::tuple operands; + }; - //! @brief Position of the last instruction executed - uint16_t _pc; + class APUDebug : public QObject + { + Q_OBJECT + private: + //! @brief List of instructions and their information + const std::array _instructions {{ + {"NOP", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"OR", 2, {DirectAddr, None}}, + {"OR", 3, {AbsoluteAddr, None}}, + {"OR", 1, {IndexXAddr, None}}, + {"OR", 2, {AbsoluteDirectByXAddr, None}}, + {"OR", 2, {ImmediateData, None}}, + {"OR", 3, {DirectAddr, DirectAddr}}, + {"OR1", 3, {AbsoluteBit, None}}, + {"ASL", 2, {DirectAddr, None}}, + {"ASL", 3, {AbsoluteAddr, None}}, + {"PUSH", 1, {PSW, None}}, + {"TSET1", 3, {AbsoluteAddr, None}}, + {"BRK", 1, {None, None}}, + {"BPL", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"OR", 2, {DirectAddrByX, None}}, + {"OR", 3, {AbsoluteAddrByX, None}}, + {"OR", 3, {AbsoluteAddrByY, None}}, + {"OR", 2, {AbsoluteDirectAddrByY, None}}, + {"OR", 3, {DirectAddr, ImmediateData}}, + {"OR", 1, {IndexYAddr, IndexYAddr}}, + {"DECW", 2, {DirectAddr, None}}, + {"ASL", 2, {DirectAddrByX, None}}, + {"ASL", 1, {A, None}}, + {"DEC", 1, {X, None}}, + {"CMP", 3, {X, AbsoluteAddr}}, + {"JMP", 3, {AbsoluteByXAddr, None}}, + {"CLRP", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"AND", 2, {DirectAddr, None}}, + {"AND", 3, {AbsoluteAddr, None}}, + {"AND", 1, {IndexXAddr, None}}, + {"AND", 2, {AbsoluteDirectByXAddr, None}}, + {"AND", 2, {ImmediateData, None}}, + {"AND", 3, {DirectAddr, DirectAddr}}, + {"OR1", 3, {AbsoluteBit, None}}, + {"ROL", 2, {DirectAddr, None}}, + {"ROL", 3, {AbsoluteAddr, None}}, + {"PUSH", 1, {A, None}}, + {"CBNE", 3, {DirectAddrByX, ImmediateData}}, + {"BRA", 2, {ImmediateData, None}}, + {"BMI", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"AND", 2, {DirectAddrByX, None}}, + {"AND", 3, {AbsoluteAddrByX, None}}, + {"AND", 3, {AbsoluteAddrByY, None}}, + {"AND", 2, {AbsoluteDirectAddrByY, None}}, + {"AND", 3, {DirectAddr, ImmediateData}}, + {"AND", 1, {IndexXAddr, IndexYAddr}}, + {"INCW", 2, {DirectAddr, None}}, + {"ROL", 2, {AbsoluteAddrByX, None}}, + {"ROL", 1, {A, None}}, + {"INC", 1, {X, None}}, + {"CMP", 2, {X, DirectAddr}}, + {"CALL", 3, {AbsoluteAddr, None}}, + {"SETP", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"EOR", 2, {DirectAddr, None}}, + {"EOR", 3, {AbsoluteAddr, None}}, + {"EOR", 1, {IndexXAddr, None}}, + {"EOR", 2, {AbsoluteDirectByXAddr, None}}, + {"EOR", 2, {ImmediateData, None}}, + {"EOR", 3, {DirectAddr, DirectAddr}}, + {"AND1", 3, {AbsoluteBit, None}}, + {"LSR", 2, {DirectAddr, None}}, + {"LSR", 3, {AbsoluteAddr, None}}, + {"PUSH", 1, {X, None}}, + {"TCLR1", 3, {AbsoluteAddr, None}}, + {"PCALL", 3, {None, None}}, + {"BVC", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"EOR", 2, {DirectAddrByX, None}}, + {"EOR", 3, {AbsoluteAddrByX, None}}, + {"EOR", 3, {AbsoluteAddrByY, None}}, + {"EOR", 2, {AbsoluteDirectAddrByY, None}}, + {"EOR", 3, {DirectAddr, ImmediateData}}, + {"EOR", 1, {IndexXAddr, IndexYAddr}}, + {"CMPW", 2, {DirectAddr, None}}, + {"LSR", 2, {DirectAddrByX, None}}, + {"LSR", 1, {A, None}}, + {"MOV", 1, {A, X}}, + {"CMP", 3, {Y, AbsoluteAddr}}, + {"JMP", 3, {AbsoluteAddr, None}}, + {"CLRC", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"CMP", 2, {A, DirectAddr}}, + {"CMP", 3, {A, AbsoluteAddr}}, + {"CMP", 1, {A, IndexXAddr,}}, + {"CMP", 2, {A, AbsoluteDirectByXAddr}}, + {"CMP", 2, {A, ImmediateData}}, + {"CMP", 3, {DirectAddr, DirectAddr}}, + {"AND1", 3, {AbsoluteBit, None}}, + {"ROR", 2, {DirectAddr, None}}, + {"ROR", 3, {AbsoluteAddr, None}}, + {"PUSH", 1, {Y, None}}, + {"DBNZ", 3, {ImmediateData, None}}, + {"RET", 1, {None, None}}, + {"BVS", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"CMP", 2, {A, DirectAddrByX}}, + {"CMP", 3, {A, AbsoluteAddrByX}}, + {"CMP", 3, {A, AbsoluteAddrByY}}, + {"CMP", 2, {A, AbsoluteDirectAddrByY}}, + {"CMP", 3, {DirectAddr, ImmediateData}}, + {"CMP", 1, {IndexXAddr, IndexYAddr}}, + {"ADDW", 2, {DirectAddr, None}}, + {"ROR", 2, {DirectAddrByX, None}}, + {"ROR", 1, {A, None}}, + {"MOV", 1, {X, A}}, + {"CMP", 3, {Y, DirectAddr}}, + {"RETI", 1, {None, None}}, + {"SETC", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"ADC", 2, {DirectAddr, None}}, + {"ADC", 3, {AbsoluteAddr, None}}, + {"ADC", 1, {IndexXAddr, None}}, + {"ADC", 2, {AbsoluteDirectByXAddr, None}}, + {"ADC", 2, {ImmediateData, None}}, + {"ADC", 3, {DirectAddr, DirectAddr}}, + {"EOR1", 3, {AbsoluteBit, None}}, + {"DEC", 2, {DirectAddr, None}}, + {"DEC", 3, {AbsoluteAddr, None}}, + {"MOV", 2, {ImmediateData, Y}}, + {"POP", 1, {PSW, None}}, + {"MOV", 3, {DirectAddr, ImmediateData}}, + {"BCC", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"ADC", 2, {DirectAddrByX, None}}, + {"ADC", 3, {AbsoluteAddrByX, None}}, + {"ADC", 3, {AbsoluteAddrByY, None}}, + {"ADC", 2, {AbsoluteDirectAddrByY, None}}, + {"ADC", 3, {DirectAddr, ImmediateData}}, + {"ADC", 1, {IndexXAddr, IndexYAddr}}, + {"SUBW", 2, {DirectAddr, None}}, + {"DEC", 2, {DirectAddrByX, None}}, + {"DEC", 1, {A, None}}, + {"MOV", 1, {SP, X}}, + {"DIV", 1, {None, None}}, + {"XCN", 1, {None, None}}, + {"EI", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"SBC", 2, {DirectAddr, None}}, + {"SBC", 3, {AbsoluteAddr, None}}, + {"SBC", 1, {IndexXAddr, None}}, + {"SBC", 2, {AbsoluteDirectByXAddr, None}}, + {"SBC", 2, {ImmediateData, None}}, + {"SBC", 3, {DirectAddr, DirectAddr}}, + {"MOV1", 3, {AbsoluteBit, None}}, + {"INC", 2, {DirectAddr, None}}, + {"INC", 3, {AbsoluteAddr, None}}, + {"CMP", 2, {Y, ImmediateData}}, + {"POP", 1, {A, None}}, + {"MOV", 1, {A, IndexXAddr}}, + {"BCS", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"SBC", 2, {DirectAddrByX, None}}, + {"SBC", 3, {AbsoluteAddrByX, None}}, + {"SBC", 3, {AbsoluteAddrByY, None}}, + {"SBC", 2, {AbsoluteDirectAddrByY, None}}, + {"SBC", 2, {DirectAddr, ImmediateData}}, + {"SBC", 1, {IndexXAddr, IndexYAddr}}, + {"MOVW", 2, {DirectAddr, None}}, + {"INC", 2, {DirectAddrByX, None}}, + {"INC", 1, {A, None}}, + {"MOV", 1, {X, SP}}, + {"DAS", 1, {None, None}}, + {"MOV", 1, {IndexXAddr, A}}, + {"DI", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"MOV", 2, {A, DirectAddr}}, + {"MOV", 3, {A, AbsoluteAddr}}, + {"MOV", 1, {A, IndexXAddr}}, + {"MOV", 2, {A, AbsoluteDirectByXAddr}}, + {"CMP", 2, {X, ImmediateData}}, + {"MOV", 3, {X, AbsoluteAddr}}, + {"MOV1", 3, {AbsoluteBit, None}}, + {"MOV", 2, {Y, DirectAddr}}, + {"MOV", 3, {Y, AbsoluteAddr}}, + {"MOV", 2, {ImmediateData, X}}, + {"POP", 1, {X, None}}, + {"MUL", 1, {None, None}}, + {"BNE", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"MOV", 2, {A, DirectAddrByX}}, + {"MOV", 3, {A, AbsoluteAddrByX}}, + {"MOV", 3, {A, AbsoluteAddrByY}}, + {"MOV", 2, {A, AbsoluteDirectAddrByY}}, + {"MOV", 2, {X, DirectAddr}}, + {"MOV", 2, {X, DirectAddrByY}}, + {"MOVW", 2, {DirectAddr, None}}, + {"MOV", 2, {Y, DirectAddrByX}}, + {"DEC", 1, {Y, None}}, + {"MOV", 1, {Y, A}}, + {"CBNE", 3, {DirectAddrByX, ImmediateData}}, + {"DAA", 1, {None, None}}, + {"CLRV", 1, {None, None}}, + {"TCALL", 1, {None, None}}, + {"SET1", 2, {DirectAddr, None}}, + {"BBS", 3, {DirectAddr, ImmediateData}}, + {"MOV", 2, {DirectAddr, A}}, + {"MOV", 3, {AbsoluteAddrByX, A}}, + {"MOV", 1, {IndexXAddr, A}}, + {"MOV", 2, {AbsoluteDirectByXAddr, A}}, + {"MOV", 2, {ImmediateData, A}}, + {"MOV", 3, {AbsoluteAddr, X}}, + {"NOT1", 3, {AbsoluteBit, None}}, + {"MOV", 2, {DirectAddr, Y}}, + {"MOV", 3, {AbsoluteAddr, Y}}, + {"NOTC", 1, {None, None}}, + {"POP", 1, {Y, None}}, + {"SLEEP", 1, {None, None}}, + {"BEQ", 2, {ImmediateData, None}}, + {"TCALL", 1, {None, None}}, + {"CLR1", 2, {DirectAddr, None}}, + {"BBC", 3, {DirectAddr, ImmediateData}}, + {"MOV", 2, {DirectAddrByX, A}}, + {"MOV", 3, {AbsoluteAddrByX, A}}, + {"MOV", 3, {AbsoluteAddrByY, A}}, + {"MOV", 2, {AbsoluteDirectAddrByY, A}}, + {"MOV", 2, {DirectAddr, X}}, + {"MOV", 2, {DirectAddrByY, X}}, + {"MOV", 3, {DirectAddr, DirectAddr}}, + {"MOV", 2, {DirectAddrByX, Y}}, + {"INC", 1, {Y, None}}, + {"MOV", 1, {A, Y}}, + {"DBNZ", 3, {ImmediateData, None}}, + {"STOP", 1, {None, None}} + }}; - //! @brief Add instruction to disassembly - int _appendInstruction(int row); + //! @brief Add instruction to disassembly + int _appendInstruction(int row); - //! @brief The QT window for this debugger. - ClosableWindow *_window; + //! @brief The QT window for this debugger. + ClosableWindow *_window; - //! @brief A widget that contain the whole UI. - Ui::APUView _ui; + //! @brief A widget that contain the whole UI. + Ui::APUView _ui; - //! @brief If this is set to true, the execution of the APU will be paused. - bool _isPaused = true; - //! @brief If this is set to true, the APU will execute one instruction and pause itself. - bool _isStepping = false; + //! @brief If this is set to true, the execution of the APU will be paused. + bool _isPaused = true; + //! @brief If this is set to true, the APU will execute one instruction and pause itself. + bool _isStepping = false; - //! @brief A reference to the snes (to disable the debugger). - SNES &_snes; + //! @brief The APU to debug. + ComSquare::APU::APU &_apu; - //! @brief Update the debugger panel values - void _updatePanel(); + //! @brief Update the debugger panel values + void _updatePanel(); - //! @brief Updates the object that serves as the disassembly - void _updateLogger(); + //! @brief Updates the object that serves as the disassembly + void _updateLogger(); - //! @brief Replace original _executeInstruction to write to the logger. - int _executeInstruction() override; + //! @brief Retrieves the instruction from the SP location + [[nodiscard]] const Instruction &_getInstruction() const; - //! @brief Retrieves the instruction from the SP location - Instruction &_getInstruction(); + //! @brief Returns an operand in text format + [[nodiscard]] std::string _getOperand(Operand ope) const; - //! @brief Returns an operand in text format - std::string _getOperand(Operand ope); + public slots: + //! @brief Pause/Resume the APU. + void pause(); + //! @brief Step - Execute a single instruction. + void step(); + //! @brief Override the apu's update to disable debugging. + void update(unsigned cycles); + public: + //! @brief Convert a basic APU to a debugging APU. + explicit APUDebug(ComSquare::APU::APU &apu, SNES &snes); + APUDebug(const APUDebug &) = delete; + APUDebug &operator=(const APUDebug &) = delete; + ~APUDebug() override = default; - public slots: - //! @brief Pause/Resume the APU. - void pause(); - //! @brief Step - Execute a single instruction. - void step(); - //! @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); - APUDebug(const APUDebug &) = delete; - APUDebug &operator=(const APUDebug &) = delete; - ~APUDebug() override = default; - - //! @brief Override the apu's update to disable debugging. - void update(unsigned cycles) override; - - //! @brief Focus the debugger's window. - void focus(); - }; + //! @brief Focus the debugger's window. + void focus(); + }; + } } \ No newline at end of file diff --git a/sources/Debugger/CPU/CPUDebug.cpp b/sources/Debugger/CPU/CPUDebug.cpp index a373c5b..018f814 100644 --- a/sources/Debugger/CPU/CPUDebug.cpp +++ b/sources/Debugger/CPU/CPUDebug.cpp @@ -14,9 +14,9 @@ using namespace ComSquare::CPU; -namespace ComSquare::Debugger +namespace ComSquare::Debugger::CPU { - CPUDebug::CPUDebug(CPU::CPU &basicCPU, SNES &snes) + CPUDebug::CPUDebug(ComSquare::CPU::CPU &basicCPU, SNES &snes) : _cpu(basicCPU), _window(new ClosableWindow([&snes] { snes.disableCPUDebugging(); })), _ui(), @@ -260,7 +260,7 @@ namespace ComSquare::Debugger std::string CPUDebug::getProceededParameters() const { uint24_t pac = this->_cpu._registers.pac; - Instruction instruction = this->_cpu.instructions[this->_cpu._readPC()]; + const Instruction &instruction = this->_cpu.instructions[this->_cpu._readPC()]; uint24_t valueAddr = this->_cpu._getValueAddr(instruction); this->_cpu._registers.pac = pac; if (instruction.size == 1) @@ -282,7 +282,7 @@ namespace ComSquare::Debugger //} } - DisassemblyModel::DisassemblyModel(ComSquare::Debugger::CPUDebug &cpu) + DisassemblyModel::DisassemblyModel(CPUDebug &cpu) : QAbstractTableModel(), _cpu(cpu) {} @@ -298,13 +298,13 @@ namespace ComSquare::Debugger QVariant DisassemblyModel::data(const QModelIndex &index, int role) const { - ComSquare::Debugger::DisassembledInstruction instruction = this->_cpu.disassembled[index.row()]; + DisassembledInstruction instruction = this->_cpu.disassembled[index.row()]; switch (role) { case Qt::DecorationRole: - if (index.column() == 2 && instruction.level == ComSquare::Debugger::TrustLevel::Unsafe) + if (index.column() == 2 && instruction.level == TrustLevel::Unsafe) return QColor(Qt::yellow); - if (index.column() == 2 && instruction.level == ComSquare::Debugger::TrustLevel::Compromised) + if (index.column() == 2 && instruction.level == TrustLevel::Compromised) return QColor(Qt::red); return QVariant(); case Qt::DisplayRole: @@ -347,7 +347,7 @@ namespace ComSquare::Debugger return QString(Utility::to_hex(instruction.address, Utility::HexString::NoPrefix).c_str()); } - RowPainter::RowPainter(ComSquare::Debugger::CPUDebug &cpu, QObject *parent) + RowPainter::RowPainter(CPUDebug &cpu, QObject *parent) : QStyledItemDelegate(parent), _cpu(cpu) {} diff --git a/sources/Debugger/CPU/CPUDebug.hpp b/sources/Debugger/CPU/CPUDebug.hpp index 1d2bd29..34f6623 100644 --- a/sources/Debugger/CPU/CPUDebug.hpp +++ b/sources/Debugger/CPU/CPUDebug.hpp @@ -24,7 +24,7 @@ namespace ComSquare class CPU; } - namespace Debugger + namespace Debugger::CPU { class CPUDebug; @@ -157,7 +157,7 @@ namespace ComSquare }; //! @brief Struct representing an instruction in an human readable way (created by disassembling the rom). - struct DisassembledInstruction : public CPU::Instruction + struct DisassembledInstruction : public ComSquare::CPU::Instruction { //! @brief The address of the instruction uint24_t address; @@ -168,7 +168,9 @@ namespace ComSquare //! @brief Are we sure that this instruction has been correctly disassembled? TrustLevel level; - DisassembledInstruction(const CPU::Instruction &instruction, uint24_t address, std::string argument, + DisassembledInstruction(const ComSquare::CPU::Instruction &instruction, + uint24_t address, + std::string argument, uint8_t opcode); DisassembledInstruction(const DisassembledInstruction &) = default; DisassembledInstruction &operator=(const DisassembledInstruction &) = default; @@ -201,7 +203,7 @@ namespace ComSquare Q_OBJECT private: //! @brief The basic CPU to debug. - CPU::CPU &_cpu; + ComSquare::CPU::CPU &_cpu; //! @brief The QT window for this debugger. ClosableWindow *_window; //! @brief Internal timer used for update intervals. @@ -242,7 +244,8 @@ namespace ComSquare //! @brief Parse the instruction at the program counter given to have human readable information. DisassembledInstruction _parseInstruction(uint24_t pc, DisassemblyContext &ctx) const; //! @brief Get the parameter of the instruction as an hexadecimal string. - std::string _getInstructionParameter(ComSquare::CPU::Instruction &instruction, uint24_t pc, + std::string _getInstructionParameter(const ComSquare::CPU::Instruction &instruction, + uint24_t pc, DisassemblyContext &ctx) const; //! @brief Update the register's panel (accumulator, stack pointer...) void _updateRegistersPanel(); diff --git a/sources/Debugger/CPU/Disassembly.cpp b/sources/Debugger/CPU/Disassembly.cpp index ad78177..bd96eba 100644 --- a/sources/Debugger/CPU/Disassembly.cpp +++ b/sources/Debugger/CPU/Disassembly.cpp @@ -9,13 +9,13 @@ using namespace ComSquare::CPU; -namespace ComSquare::Debugger +namespace ComSquare::Debugger::CPU { - DisassembledInstruction::DisassembledInstruction(const CPU::Instruction &instruction, + DisassembledInstruction::DisassembledInstruction(const ComSquare::CPU::Instruction &instruction, uint24_t addr, std::string arg, uint8_t op) - : CPU::Instruction(instruction), + : ComSquare::CPU::Instruction(instruction), address(addr), argument(std::move(arg)), opcode(op), @@ -76,12 +76,12 @@ namespace ComSquare::Debugger DisassembledInstruction CPUDebug::_parseInstruction(uint24_t pc, DisassemblyContext &ctx) const { uint24_t opcode = this->_snes.bus.peek_v(pc); - Instruction instruction = this->_cpu.instructions[opcode]; + const Instruction &instruction = this->_cpu.instructions[opcode]; std::string argument = this->_getInstructionParameter(instruction, pc + 1, ctx); return DisassembledInstruction(instruction, pc, argument, opcode); } - std::string CPUDebug::_getInstructionParameter(Instruction &instruction, uint24_t pc, DisassemblyContext &ctx) const + std::string CPUDebug::_getInstructionParameter(const Instruction &instruction, uint24_t pc, DisassemblyContext &ctx) const { switch (instruction.addressingMode) { case Implied: diff --git a/sources/Debugger/CPU/SymbolLoaders/WlaDx.cpp b/sources/Debugger/CPU/SymbolLoaders/WlaDx.cpp index f275da6..040b15d 100644 --- a/sources/Debugger/CPU/SymbolLoaders/WlaDx.cpp +++ b/sources/Debugger/CPU/SymbolLoaders/WlaDx.cpp @@ -6,7 +6,7 @@ #include "Utility/Utility.hpp" #include "WlaDx.hpp" -namespace ComSquare::Debugger +namespace ComSquare::Debugger::CPU { std::vector