From 1354c86a4ae507e0db31d0318ec33b340713c0df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?= Date: Fri, 27 Mar 2020 18:52:41 +0100 Subject: [PATCH] starting implementing cgram debugger --- CMakeLists.txt | 2 +- sources/Debugger/cgramDebug.cpp | 75 +++++++++++ sources/Debugger/cgramDebug.hpp | 89 ++++++++++++ sources/PPU/PPU.cpp | 19 +-- sources/PPU/PPU.hpp | 10 +- sources/SNES.cpp | 25 ++++ sources/SNES.hpp | 4 + ui/cgramView.ui | 231 ++++++++++++++++++++++++++++++++ 8 files changed, 443 insertions(+), 12 deletions(-) create mode 100644 sources/Debugger/cgramDebug.cpp create mode 100644 sources/Debugger/cgramDebug.hpp create mode 100644 ui/cgramView.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c2d8c4..9d5d68c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,7 +200,7 @@ add_executable(ComSquare sources/Debugger/MemoryBusDebug.cpp sources/Debugger/MemoryBusDebug.hpp sources/Debugger/ClosableWindow.hpp - sources/Models/Components.hpp) + sources/Models/Components.hpp sources/Debugger/cgramDebug.cpp sources/Debugger/cgramDebug.hpp) target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED) diff --git a/sources/Debugger/cgramDebug.cpp b/sources/Debugger/cgramDebug.cpp new file mode 100644 index 0000000..af897b3 --- /dev/null +++ b/sources/Debugger/cgramDebug.cpp @@ -0,0 +1,75 @@ +// +// Created by cbihan on 3/27/20. +// + +#include "cgramDebug.hpp" +#include "../SNES.hpp" +#include +#include "../Utility/Utility.hpp" +#include "../Exceptions/InvalidAction.hpp" +#include "../Exceptions/InvalidAddress.hpp" + +namespace ComSquare::cgramDebugger +{ + cgramDebug::cgramDebug(SNES &snes, ComSquare::PPU::PPU &ppu) + : _window(new ClosableWindow(*this, &cgramDebug::disableViewer)), + _snes(snes), + _ui(), + _model(), + _ppu(ppu), + { + this->_window->setContextMenuPolicy(Qt::NoContextMenu); + this->_window->setAttribute(Qt::WA_QuitOnClose, false); + this->_window->setAttribute(Qt::WA_DeleteOnClose); + + this->_ui.setupUi(this->_window); + this->_ui.log->setModel(&this->_model); + this->_ui.log->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + //this->_ui.log->horizontalHeader()->setStretchLastSection(true); + this->_ui.log->horizontalHeader()->setSectionsMovable(false); + for (int i = 0; i < this->_model.column; i++) + this->_ui.log->setColumnWidth(i, this->_ui.log->width()); + + this->_window->show(); + } + + void cgramDebug::disableViewer() + { + this->_snes.disableCgramDebugging(); + } + + void cgramDebug::focus() + { + this->_window->activateWindow(); + } + + bool cgramDebug::isDebugger() + { + return true; + } + + uint16_t cgramDebug::read(uint8_t addr) + { + return this->_ppu.cgramRead(addr); + } +} + +int cgramModel::rowCount(const QModelIndex &) const +{ + return this->rows; +} + +int cgramModel::columnCount(const QModelIndex &) const +{ + return this->column; +} + +QVariant cgramModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::TextAlignmentRole) + return Qt::AlignCenter; + if (role != Qt::DisplayRole) + return QVariant(); + if (role == Qt::BackgroundRole) + +} \ No newline at end of file diff --git a/sources/Debugger/cgramDebug.hpp b/sources/Debugger/cgramDebug.hpp new file mode 100644 index 0000000..1f23d1c --- /dev/null +++ b/sources/Debugger/cgramDebug.hpp @@ -0,0 +1,89 @@ +// +// Created by cbihan on 3/27/20. +// + +#ifndef COMSQUARE_CGRAMDEBUG_HPP +#define COMSQUARE_CGRAMDEBUG_HPP + +#include +#include "../PPU/PPU.hpp" +#include "../../ui/ui_cgramView.h" +#include +#include "ClosableWindow.hpp" + +/*namespace ComSquare::cgramDebugger +{ + //! @brief The struct used to represent memory bus logs. + struct BusLog { + BusLog(bool write, uint24_t addr, std::shared_ptr &accessor, uint8_t oldData, uint8_t newData); + + bool write; + uint24_t addr; + std::shared_ptr accessor; + uint8_t oldData; + uint8_t newData; + }; +}*/ + + +//! @brief The qt model that bind the logs to the view. +class cgramModel : public QAbstractTableModel +{ +Q_OBJECT +public: + //! @brief The number of columns + const int column = 16; + //! @brief The number of rows + const int rows = 16; + cgramModel() = default; + cgramModel(const cgramModel &) = delete; + const cgramModel &operator=(const cgramModel &) = delete; + ~cgramModel() override = default; + + //! @brief The number of row the table has. + int rowCount(const QModelIndex &parent) const override; + //! @brief The number of column the table has. + int columnCount(const QModelIndex &parent) const override; + //! @brief Return a data representing the table cell. + QVariant data(const QModelIndex &index, int role) const override; +}; + + +namespace ComSquare::cgramDebugger +{ + //! @brief window that allow the user to view all data going through the memory bus. + class cgramDebug { + 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::cgramView _ui; + //! @brief The Log visualizer model for QT. + cgramModel _model; + //! @brief A reference to the ppu + ComSquare::PPU::PPU &_ppu; + public: + //! @brief Called when the window is closed. Turn off the debugger. + void disableViewer(); + public: + explicit cgramDebug(SNES &snes, ComSquare::PPU::PPU &ppu); + cgramDebug(const cgramDebug &) = delete; + cgramDebug &operator=(const cgramDebug &) = delete; + ~cgramDebug() = default; + + //! @brief Read data at the CGRAM address send it to the debugger. + //! @param addr The address to read from. + //! @return The color value in BGR, looks like this xbbbbbgggggrrrrr. + uint16_t read(uint8_t addr) override; + + //! @brief Focus the debugger's window. + void focus(); + + //! @brief Return true if the Bus is overloaded with debugging features. + bool isDebugger() override; + }; +} + +#endif //COMSQUARE_CGRAMDEBUG_HPP diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp index 459f555..4390bc4 100644 --- a/sources/PPU/PPU.cpp +++ b/sources/PPU/PPU.cpp @@ -134,23 +134,16 @@ namespace ComSquare::PPU this->_registers._m7[addr - ppuRegisters::m7a].m7 = (this->_registers._m7[addr - ppuRegisters::m7a].m7 << 8) | data; break; case ppuRegisters::cgadd: - std::cout << "cgadd addr : " << std::bitset<8>(data) << std::endl; this->_registers._cgadd = data; this->_registers._isLowByte = true; break; case ppuRegisters::cgdata: - //throw InvalidAddress("cgdata", addr); if (this->_registers._isLowByte) { - std::cout << "cgadatal w data " << std::bitset<8>(data) << std::endl; this->_registers._cgdata.cgdatal = data; - //this->_registers._cgram.write(this->_registers._cgadd, this->_registers._cgdata.raw); - //this->_registers._cgadd++; } else { - std::cout << "cgdatah w data " << std::bitset<8>(data) << std::endl; this->_registers._cgdata.cgdatah = data; this->_cgram.write(this->_registers._cgadd, this->_registers._cgdata.raw); - std::cout << "cgadatah at addr: " << this->_registers._cgadd << " valeur : " << std::bitset<16>(this->_registers._cgdata.raw) << std::endl; this->_registers._cgadd++; } this->_registers._isLowByte = !this->_registers._isLowByte; @@ -385,7 +378,7 @@ namespace ComSquare::PPU case ppuRegisters::stat78: return "STAT78"; default: - return "PPU : ???"; + return "???"; } } @@ -393,4 +386,14 @@ namespace ComSquare::PPU { return Ppu; } + + bool PPU::isDebugger() + { + return false; + } + + uint16_t PPU::cgramRead(uint8_t addr) + { + return this->_cgram.read(addr); + } } \ No newline at end of file diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp index 28c9d03..272b6dd 100644 --- a/sources/PPU/PPU.hpp +++ b/sources/PPU/PPU.hpp @@ -494,7 +494,7 @@ namespace ComSquare::PPU } _mpy; }; - //! @brief The class containing all the registers the PPU + //! @brief The class containing all the registers of the PPU class PPU : public Memory::AMemory { private: //! @brief Init ppuRegisters @@ -526,11 +526,15 @@ namespace ComSquare::PPU //! @brief Update the PPU of n cycles. //! @param The number of cycles to update. - void update(unsigned cycles); + virtual void update(unsigned cycles); //! @brief Give the Vram Address with the right Address remapping uint8_t getVramAddress(); - //! @brief Give the name of the Address register + //! @brief Give the name of the Address register (used for debug) std::string getValueName(uint24_t addr); + //! @brief Return true if the CPU is overloaded with debugging features. + virtual bool isDebugger(); + //! @brief Allow others components to read the CGRAM (Debuggers) + uint16_t cgramRead(uint8_t addr); }; } #endif //COMSQUARE_PPU_HPP diff --git a/sources/SNES.cpp b/sources/SNES.cpp index 3dc9674..ffc3d67 100644 --- a/sources/SNES.cpp +++ b/sources/SNES.cpp @@ -126,4 +126,29 @@ namespace ComSquare std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl; #endif } + + void SNES::enableCgramDebugging() + { + #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::disableCgramDebugging() + { + #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 25fb99e..893ec3e 100644 --- a/sources/SNES.hpp +++ b/sources/SNES.hpp @@ -70,6 +70,10 @@ namespace ComSquare void disableMemoryBusDebugging(); //! @brief Enable the Memory Bus's debugging window. void enableMemoryBusDebugging(); + //! @brief Disable the Cgram's debugging window. + void disableCgramDebugging(); + //! @brief Enable the Cgram's debugging window. + void enableCgramDebugging(); //! @brief Create all the components using a common memory bus for all of them. SNES(const std::string &ramPath, Renderer::IRenderer &renderer); diff --git a/ui/cgramView.ui b/ui/cgramView.ui new file mode 100644 index 0000000..317cd78 --- /dev/null +++ b/ui/cgramView.ui @@ -0,0 +1,231 @@ + + + MainWindow + + + + 0 + 0 + 461 + 346 + + + + Palette Viewer + + + + :/resources/Logo.png:/resources/Logo.png + + + + + + + true + + + + 300 + 300 + + + + + 300 + 300 + + + + true + + + + 0 + 0 + 0 + + + + false + + + + + + + + + Index + + + + + + + + 70 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + + Value + + + + + + + + 70 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + + R + + + + + + + + 70 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + + G + + + + + + + + 70 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + + B + + + + + + + + 70 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + + Hex + + + + + + + + 70 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + false + + + + + + + + + + + 0 + 0 + 461 + 22 + + + + + + + + +