Enabling the memory bus debugger

This commit is contained in:
Zoe Roux
2021-07-05 00:23:48 +02:00
parent f16815c36f
commit cb6fb8a240
20 changed files with 475 additions and 418 deletions

View File

@@ -95,7 +95,7 @@ set(SOURCES
sources/PPU/TileRenderer.hpp sources/PPU/TileRenderer.hpp
sources/PPU/Tile.hpp sources/PPU/Tile.hpp
sources/CPU/Registers.hpp sources/CPU/Registers.hpp
) sources/Memory/IMemoryBus.hpp)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
@@ -129,8 +129,8 @@ add_executable(comsquare
sources/Debugger/HeaderViewer.hpp sources/Debugger/HeaderViewer.hpp
# sources/Debugger/APUDebug.hpp # sources/Debugger/APUDebug.hpp
# sources/Debugger/APUDebug.cpp # sources/Debugger/APUDebug.cpp
# sources/Debugger/MemoryBusDebug.cpp sources/Debugger/MemoryBusDebug.cpp
# sources/Debugger/MemoryBusDebug.hpp sources/Debugger/MemoryBusDebug.hpp
sources/Debugger/CGramDebug.cpp sources/Debugger/CGramDebug.cpp
sources/Debugger/CGramDebug.hpp sources/Debugger/CGramDebug.hpp
sources/Debugger/RegisterViewer.cpp sources/Debugger/RegisterViewer.cpp
@@ -148,7 +148,7 @@ add_executable(comsquare
ui/busView.ui ui/busView.ui
resources/appResources.qrc resources/appResources.qrc
) )
target_include_directories(comsquare PRIVATE ./) target_include_directories(comsquare PUBLIC ${PROJECT_BINARY_DIR})
target_compile_definitions(comsquare PUBLIC DEBUGGER_ENABLED) target_compile_definitions(comsquare PUBLIC DEBUGGER_ENABLED)
find_package(Qt5 COMPONENTS Widgets REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED)

View File

@@ -64,8 +64,8 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectIndexedYAddr() uint24_t CPU::_getDirectIndirectIndexedYAddr()
{ {
uint16_t dp = this->readPC() + this->_registers.d; uint16_t dp = this->readPC() + this->_registers.d;
uint24_t base = this->_bus.read(dp); uint24_t base = this->getBus().read(dp);
base += this->_bus.read(dp + 1) << 8u; base += this->getBus().read(dp + 1) << 8u;
base += this->_registers.dbr << 16u; base += this->_registers.dbr << 16u;
if ((base & 0x80000000u) == (((base + this->_registers.y) & 0x80000000u))) if ((base & 0x80000000u) == (((base + this->_registers.y) & 0x80000000u)))
this->_hasIndexCrossedPageBoundary = true; this->_hasIndexCrossedPageBoundary = true;
@@ -75,9 +75,9 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectIndexedYLongAddr() uint24_t CPU::_getDirectIndirectIndexedYLongAddr()
{ {
uint16_t dp = this->readPC() + this->_registers.d; uint16_t dp = this->readPC() + this->_registers.d;
uint24_t base = this->_bus.read(dp); uint24_t base = this->getBus().read(dp);
base += this->_bus.read(dp + 1) << 8u; base += this->getBus().read(dp + 1) << 8u;
base += this->_bus.read(dp + 2) << 16u; base += this->getBus().read(dp + 2) << 16u;
return base; return base;
} }
@@ -85,8 +85,8 @@ namespace ComSquare::CPU
{ {
uint16_t dp = this->readPC() + this->_registers.d; uint16_t dp = this->readPC() + this->_registers.d;
dp += this->_registers.x; dp += this->_registers.x;
uint24_t base = this->_bus.read(dp); uint24_t base = this->getBus().read(dp);
base += this->_bus.read(dp + 1) << 8u; base += this->getBus().read(dp + 1) << 8u;
base += this->_registers.dbr << 16u; base += this->_registers.dbr << 16u;
return base; return base;
} }
@@ -137,8 +137,8 @@ namespace ComSquare::CPU
{ {
uint16_t abs = this->readPC(); uint16_t abs = this->readPC();
abs += this->readPC() << 8u; abs += this->readPC() << 8u;
uint24_t effective = this->_bus.read(abs); uint24_t effective = this->getBus().read(abs);
effective += this->_bus.read(abs + 1) << 8u; effective += this->getBus().read(abs + 1) << 8u;
return effective; return effective;
} }
@@ -146,9 +146,9 @@ namespace ComSquare::CPU
{ {
uint16_t abs = this->readPC(); uint16_t abs = this->readPC();
abs += this->readPC() << 8u; abs += this->readPC() << 8u;
uint24_t effective = this->_bus.read(abs); uint24_t effective = this->getBus().read(abs);
effective += this->_bus.read(abs + 1) << 8u; effective += this->getBus().read(abs + 1) << 8u;
effective += this->_bus.read(abs + 2) << 16u; effective += this->getBus().read(abs + 2) << 16u;
return effective; return effective;
} }
@@ -157,16 +157,16 @@ namespace ComSquare::CPU
uint24_t abs = this->readPC(); uint24_t abs = this->readPC();
abs += this->readPC() << 8u; abs += this->readPC() << 8u;
abs += this->_registers.x; abs += this->_registers.x;
uint24_t effective = this->_bus.read(abs); uint24_t effective = this->getBus().read(abs);
effective += this->_bus.read(abs + 1) << 8u; effective += this->getBus().read(abs + 1) << 8u;
return effective; return effective;
} }
uint24_t CPU::_getDirectIndirectAddr() uint24_t CPU::_getDirectIndirectAddr()
{ {
uint16_t dp = this->readPC() + this->_registers.d; uint16_t dp = this->readPC() + this->_registers.d;
uint24_t effective = this->_bus.read(dp); uint24_t effective = this->getBus().read(dp);
effective += this->_bus.read(dp + 1) << 8u; effective += this->getBus().read(dp + 1) << 8u;
effective += this->_registers.dbr << 16u; effective += this->_registers.dbr << 16u;
return effective; return effective;
} }
@@ -174,9 +174,9 @@ namespace ComSquare::CPU
uint24_t CPU::_getDirectIndirectLongAddr() uint24_t CPU::_getDirectIndirectLongAddr()
{ {
uint16_t dp = this->readPC() + this->_registers.d; uint16_t dp = this->readPC() + this->_registers.d;
uint24_t effective = this->_bus.read(dp); uint24_t effective = this->getBus().read(dp);
effective += this->_bus.read(++dp) << 8u; effective += this->getBus().read(++dp) << 8u;
effective += this->_bus.read(++dp) << 16u; effective += this->getBus().read(++dp) << 16u;
return effective; return effective;
} }

View File

@@ -10,7 +10,7 @@
namespace ComSquare::CPU namespace ComSquare::CPU
{ {
CPU::CPU(Memory::MemoryBus &bus, Cartridge::Header &cartridgeHeader) CPU::CPU(Memory::IMemoryBus &bus, Cartridge::Header &cartridgeHeader)
: _bus(bus), : _bus(bus),
_cartridgeHeader(cartridgeHeader), _cartridgeHeader(cartridgeHeader),
_dmaChannels({DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus)}) _dmaChannels({DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus), DMA(bus)})
@@ -18,6 +18,12 @@ namespace ComSquare::CPU
this->RESB(); this->RESB();
} }
void CPU::setBus(Memory::IMemoryBus &bus)
{
this->_bus = bus;
for (auto &dma : this->_dmaChannels)
dma.setBus(bus);
}
//! @bref The CPU's internal registers starts at $4200 and finish at $421F. //! @bref The CPU's internal registers starts at $4200 and finish at $421F.
uint8_t CPU::read(uint24_t addr) uint8_t CPU::read(uint24_t addr)
@@ -203,7 +209,7 @@ namespace ComSquare::CPU
uint8_t CPU::readPC() uint8_t CPU::readPC()
{ {
uint8_t ret = this->_bus.read(this->_registers.pac); uint8_t ret = this->getBus().read(this->_registers.pac);
this->_registers.pc++; this->_registers.pc++;
return ret; return ret;
} }
@@ -322,24 +328,24 @@ namespace ComSquare::CPU
void CPU::_push(uint8_t data) void CPU::_push(uint8_t data)
{ {
this->_bus.write(this->_registers.s--, data); this->getBus().write(this->_registers.s--, data);
} }
void CPU::_push(uint16_t data) void CPU::_push(uint16_t data)
{ {
this->_bus.write(this->_registers.s--, data >> 8u); this->getBus().write(this->_registers.s--, data >> 8u);
this->_bus.write(this->_registers.s--, data); this->getBus().write(this->_registers.s--, data);
} }
uint8_t CPU::_pop() uint8_t CPU::_pop()
{ {
return this->_bus.read(++this->_registers.s); return this->getBus().read(++this->_registers.s);
} }
uint16_t CPU::_pop16() uint16_t CPU::_pop16()
{ {
uint16_t value = this->_bus.read(++this->_registers.s); uint16_t value = this->getBus().read(++this->_registers.s);
value += this->_bus.read(++this->_registers.s) << 8u; value += this->getBus().read(++this->_registers.s) << 8u;
return value; return value;
} }

View File

@@ -36,7 +36,8 @@ namespace ComSquare::CPU
bool _isWaitingForInterrupt = false; bool _isWaitingForInterrupt = false;
//! @brief The memory bus to use for read/write. //! @brief The memory bus to use for read/write.
Memory::MemoryBus &_bus; std::reference_wrapper<Memory::IMemoryBus> _bus;
private:
//! @brief The cartridge header (stored for interrupt vectors..) //! @brief The cartridge header (stored for interrupt vectors..)
Cartridge::Header &_cartridgeHeader; Cartridge::Header &_cartridgeHeader;
@@ -117,7 +118,6 @@ namespace ComSquare::CPU
//! @return The address of the data to read on the instruction. //! @return The address of the data to read on the instruction.
uint24_t _getValueAddr(Instruction &instruction); uint24_t _getValueAddr(Instruction &instruction);
public:
//! @brief Break instruction - Causes a software break. The PC is loaded from a vector table. //! @brief Break instruction - Causes a software break. The PC is loaded from a vector table.
int BRK(uint24_t, AddressingMode); int BRK(uint24_t, AddressingMode);
//! @brief Co-Processor Enable instruction - Causes a software break. The PC is loaded from a vector table. //! @brief Co-Processor Enable instruction - Causes a software break. The PC is loaded from a vector table.
@@ -309,6 +309,16 @@ namespace ComSquare::CPU
//! @param C_register (16 bits accumulator) Length -1 //! @param C_register (16 bits accumulator) Length -1
int MVP(uint24_t, AddressingMode); int MVP(uint24_t, AddressingMode);
public:
//! @brief Get the memory bus used by this CPU.
[[nodiscard]] inline Memory::IMemoryBus &getBus()
{
return this->_bus;
}
//! @brief Set the memory bus used by this CPU
//! @param bus The bus to use.
void setBus(Memory::IMemoryBus &bus);
//! @brief All the instructions of the CPU. //! @brief All the instructions of the CPU.
//! @info Instructions are indexed by their opcode //! @info Instructions are indexed by their opcode
const Instruction instructions[0x100] = { const Instruction instructions[0x100] = {
@@ -573,7 +583,7 @@ namespace ComSquare::CPU
//! @brief Construct a new generic CPU. //! @brief Construct a new generic CPU.
//! @param bus The memory bus to use to transfer data. //! @param bus The memory bus to use to transfer data.
//! @param cartridgeHeader The header used to know interrupts, main entry point etc... //! @param cartridgeHeader The header used to know interrupts, main entry point etc...
CPU(Memory::MemoryBus &bus, Cartridge::Header &cartridgeHeader); CPU(Memory::IMemoryBus &bus, Cartridge::Header &cartridgeHeader);
//! @brief A default copy constructor //! @brief A default copy constructor
CPU(const CPU &) = default; CPU(const CPU &) = default;
//! @brief A CPU is not assignable //! @brief A CPU is not assignable

View File

@@ -7,11 +7,16 @@
namespace ComSquare::CPU namespace ComSquare::CPU
{ {
DMA::DMA(Memory::MemoryBus &bus) DMA::DMA(Memory::IMemoryBus &bus)
: _bus(bus), : _bus(bus),
enabled(false) enabled(false)
{} {}
void DMA::setBus(Memory::IMemoryBus &bus)
{
this->_bus = bus;
}
uint8_t DMA::read(uint8_t addr) const uint8_t DMA::read(uint8_t addr) const
{ {
switch (addr) { switch (addr) {
@@ -68,22 +73,22 @@ namespace ComSquare::CPU
// Address $2180 refers to the WRam data register. // Address $2180 refers to the WRam data register.
// Write to/Read from this port when the a address is on the vram cause different behaviors. // Write to/Read from this port when the a address is on the vram cause different behaviors.
if (this->_port == 0x80) { if (this->_port == 0x80) {
auto accessor = this->_bus.getAccessor(aAddress); auto accessor = this->getBus().getAccessor(aAddress);
if (accessor && accessor->getComponent() == WRam) { if (accessor && accessor->getComponent() == WRam) {
// WRAM->$2180 The write is not performed but the time is consumed anyway. // WRAM->$2180 The write is not performed but the time is consumed anyway.
if (this->_controlRegister.direction == AtoB) if (this->_controlRegister.direction == AtoB)
return 8; return 8;
// $2180->WRAM No read is performed (so only 4 master cycles are needed) but the value written is invalid. // $2180->WRAM No read is performed (so only 4 master cycles are needed) but the value written is invalid.
this->_bus.write(aAddress, 0xFF); this->getBus().write(aAddress, 0xFF);
return 4; return 4;
} }
} }
if (this->_controlRegister.direction == AtoB) { if (this->_controlRegister.direction == AtoB) {
uint8_t data = this->_bus.read(aAddress); uint8_t data = this->getBus().read(aAddress);
this->_bus.write(bAddress, data); this->getBus().write(bAddress, data);
} else { } else {
uint8_t data = this->_bus.read(bAddress); uint8_t data = this->getBus().read(bAddress);
this->_bus.write(aAddress, data); this->getBus().write(aAddress, data);
} }
return 8; return 8;
} }

View File

@@ -93,9 +93,18 @@ namespace ComSquare::CPU
} _count {}; } _count {};
//! @brief The memory bus to use for read/write. //! @brief The memory bus to use for read/write.
Memory::MemoryBus &_bus; Memory::IMemoryBus &_bus;
public: public:
//! @brief Get the memory bus used by this CPU.
[[nodiscard]] inline Memory::IMemoryBus &getBus()
{
return this->_bus;
}
//! @brief Set the memory bus used by this CPU
//! @param bus The bus to use.
void setBus(Memory::IMemoryBus &bus);
//! @brief Is this channel set to run? //! @brief Is this channel set to run?
bool enabled; bool enabled;
@@ -116,7 +125,7 @@ namespace ComSquare::CPU
//! @brief Create a DMA channel with a given bus //! @brief Create a DMA channel with a given bus
//! @param bus The memory bus to use. //! @param bus The memory bus to use.
explicit DMA(Memory::MemoryBus &bus); explicit DMA(Memory::IMemoryBus &bus);
//! @brief A DMA is copy constructable. //! @brief A DMA is copy constructable.
DMA(const DMA &) = default; DMA(const DMA &) = default;
//! @brief A DMA is not assignable //! @brief A DMA is not assignable

View File

@@ -10,13 +10,13 @@ namespace ComSquare::CPU
{ {
int CPU::TSB(uint24_t valueAddr, AddressingMode mode) int CPU::TSB(uint24_t valueAddr, AddressingMode mode)
{ {
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
value |= this->_registers.a; value |= this->_registers.a;
this->_bus.write(valueAddr, value); this->getBus().write(valueAddr, value);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(valueAddr + 1, value >> 8u); this->getBus().write(valueAddr + 1, value >> 8u);
this->_registers.p.z = value == 0; this->_registers.p.z = value == 0;
@@ -30,14 +30,14 @@ namespace ComSquare::CPU
int CPU::TRB(uint24_t valueAddr, AddressingMode mode) int CPU::TRB(uint24_t valueAddr, AddressingMode mode)
{ {
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
uint16_t newValue = value & ~this->_registers.a; uint16_t newValue = value & ~this->_registers.a;
this->_bus.write(valueAddr, newValue); this->getBus().write(valueAddr, newValue);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(valueAddr + 1, newValue >> 8u); this->getBus().write(valueAddr + 1, newValue >> 8u);
this->_registers.p.z = (value & this->_registers.a) == 0; this->_registers.p.z = (value & this->_registers.a) == 0;
@@ -52,9 +52,9 @@ namespace ComSquare::CPU
int CPU::BIT(uint24_t valueAddr, AddressingMode mode) int CPU::BIT(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
if (mode != ImmediateForA) { if (mode != ImmediateForA) {
this->_registers.p.n = value & negativeMask; this->_registers.p.n = value & negativeMask;
@@ -89,18 +89,18 @@ namespace ComSquare::CPU
return 0; return 0;
} }
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.p.c = value & highByte; this->_registers.p.c = value & highByte;
value <<= 1u; value <<= 1u;
this->_registers.p.n = value & highByte; this->_registers.p.n = value & highByte;
this->_registers.p.z = value == 0; this->_registers.p.z = value == 0;
this->_bus.write(valueAddr, value); this->getBus().write(valueAddr, value);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(valueAddr + 1, value >> 8u); this->getBus().write(valueAddr + 1, value >> 8u);
int cycles = 2 * !this->_registers.p.m; int cycles = 2 * !this->_registers.p.m;
switch (mode) { switch (mode) {
@@ -128,17 +128,17 @@ namespace ComSquare::CPU
return 0; return 0;
} }
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.p.c = value & 1u; this->_registers.p.c = value & 1u;
value >>= 1u; value >>= 1u;
this->_registers.p.z = value == 0; this->_registers.p.z = value == 0;
this->_bus.write(valueAddr, value); this->getBus().write(valueAddr, value);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(valueAddr + 1, value >> 8u); this->getBus().write(valueAddr + 1, value >> 8u);
int cycles = 2 * !this->_registers.p.m; int cycles = 2 * !this->_registers.p.m;
switch (mode) { switch (mode) {
@@ -169,9 +169,9 @@ namespace ComSquare::CPU
return 0; return 0;
} }
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.p.c = value & highByte; this->_registers.p.c = value & highByte;
value <<= 1u; value <<= 1u;
@@ -179,9 +179,9 @@ namespace ComSquare::CPU
this->_registers.p.n = value & highByte; this->_registers.p.n = value & highByte;
this->_registers.p.z = value == 0; this->_registers.p.z = value == 0;
this->_bus.write(valueAddr, value); this->getBus().write(valueAddr, value);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(valueAddr + 1, value >> 8u); this->getBus().write(valueAddr + 1, value >> 8u);
int cycles = 2 * !this->_registers.p.m; int cycles = 2 * !this->_registers.p.m;
switch (mode) { switch (mode) {
@@ -212,18 +212,18 @@ namespace ComSquare::CPU
return 0; return 0;
} }
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.p.c = value & 1u; this->_registers.p.c = value & 1u;
value >>= 1u; value >>= 1u;
value |= oldCarry << highByteIndex; value |= oldCarry << highByteIndex;
this->_registers.p.z = value == 0; this->_registers.p.z = value == 0;
this->_bus.write(valueAddr, value); this->getBus().write(valueAddr, value);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(valueAddr + 1, value >> 8u); this->getBus().write(valueAddr + 1, value >> 8u);
int cycles = 2 * !this->_registers.p.m; int cycles = 2 * !this->_registers.p.m;
switch (mode) { switch (mode) {

View File

@@ -50,13 +50,13 @@ namespace ComSquare::CPU
int CPU::SEP(uint24_t valueAddr, AddressingMode) int CPU::SEP(uint24_t valueAddr, AddressingMode)
{ {
this->_registers.p.flags |= this->_bus.read(valueAddr); this->_registers.p.flags |= this->getBus().read(valueAddr);
return 0; return 0;
} }
int CPU::REP(uint24_t valueAddr, AddressingMode) int CPU::REP(uint24_t valueAddr, AddressingMode)
{ {
this->_registers.p.flags &= ~this->_bus.read(valueAddr); this->_registers.p.flags &= ~this->getBus().read(valueAddr);
if (this->_isEmulationMode) { if (this->_isEmulationMode) {
this->_registers.p.x_b = true; this->_registers.p.x_b = true;
this->_registers.p.m = true; this->_registers.p.m = true;
@@ -189,8 +189,8 @@ namespace ComSquare::CPU
int CPU::PER(uint24_t valueAddr, AddressingMode) int CPU::PER(uint24_t valueAddr, AddressingMode)
{ {
uint16_t value = this->_bus.read(valueAddr); uint16_t value = this->getBus().read(valueAddr);
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
value += this->_registers.pc; value += this->_registers.pc;
this->_push(value); this->_push(value);
return 0; return 0;
@@ -226,55 +226,55 @@ namespace ComSquare::CPU
int CPU::BCC(uint24_t valueAddr, AddressingMode) int CPU::BCC(uint24_t valueAddr, AddressingMode)
{ {
if (!this->_registers.p.c) if (!this->_registers.p.c)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return !this->_registers.p.c + this->_isEmulationMode; return !this->_registers.p.c + this->_isEmulationMode;
} }
int CPU::BCS(uint24_t valueAddr, AddressingMode) int CPU::BCS(uint24_t valueAddr, AddressingMode)
{ {
if (this->_registers.p.c) if (this->_registers.p.c)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return this->_registers.p.c + this->_isEmulationMode; return this->_registers.p.c + this->_isEmulationMode;
} }
int CPU::BEQ(uint24_t valueAddr, AddressingMode) int CPU::BEQ(uint24_t valueAddr, AddressingMode)
{ {
if (this->_registers.p.z) if (this->_registers.p.z)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return this->_registers.p.z + this->_isEmulationMode; return this->_registers.p.z + this->_isEmulationMode;
} }
int CPU::BNE(uint24_t valueAddr, AddressingMode) int CPU::BNE(uint24_t valueAddr, AddressingMode)
{ {
if (!this->_registers.p.z) if (!this->_registers.p.z)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return !this->_registers.p.z + this->_isEmulationMode; return !this->_registers.p.z + this->_isEmulationMode;
} }
int CPU::BMI(uint24_t valueAddr, AddressingMode) int CPU::BMI(uint24_t valueAddr, AddressingMode)
{ {
if (this->_registers.p.n) if (this->_registers.p.n)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return this->_registers.p.n + this->_isEmulationMode; return this->_registers.p.n + this->_isEmulationMode;
} }
int CPU::BPL(uint24_t valueAddr, AddressingMode) int CPU::BPL(uint24_t valueAddr, AddressingMode)
{ {
if (!this->_registers.p.n) if (!this->_registers.p.n)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return !this->_registers.p.n + this->_isEmulationMode; return !this->_registers.p.n + this->_isEmulationMode;
} }
int CPU::BRA(uint24_t valueAddr, AddressingMode) int CPU::BRA(uint24_t valueAddr, AddressingMode)
{ {
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return this->_isEmulationMode; return this->_isEmulationMode;
} }
int CPU::BRL(uint24_t valueAddr, AddressingMode) int CPU::BRL(uint24_t valueAddr, AddressingMode)
{ {
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.pc += static_cast<int16_t>(value); this->_registers.pc += static_cast<int16_t>(value);
return 0; return 0;
@@ -283,14 +283,14 @@ namespace ComSquare::CPU
int CPU::BVC(uint24_t valueAddr, AddressingMode) int CPU::BVC(uint24_t valueAddr, AddressingMode)
{ {
if (!this->_registers.p.v) if (!this->_registers.p.v)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return !this->_registers.p.v + this->_isEmulationMode; return !this->_registers.p.v + this->_isEmulationMode;
} }
int CPU::BVS(uint24_t valueAddr, AddressingMode) int CPU::BVS(uint24_t valueAddr, AddressingMode)
{ {
if (this->_registers.p.v) if (this->_registers.p.v)
this->_registers.pc += static_cast<int8_t>(this->_bus.read(valueAddr)); this->_registers.pc += static_cast<int8_t>(this->getBus().read(valueAddr));
return this->_registers.p.v + this->_isEmulationMode; return this->_registers.p.v + this->_isEmulationMode;
} }

View File

@@ -9,9 +9,9 @@ namespace ComSquare::CPU
{ {
int CPU::ADC(uint24_t valueAddr, AddressingMode mode) int CPU::ADC(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned value = this->_bus.read(valueAddr) + this->_registers.p.c; unsigned value = this->getBus().read(valueAddr) + this->_registers.p.c;
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned maxValue = this->_registers.p.m ? UINT8_MAX : UINT16_MAX; unsigned maxValue = this->_registers.p.m ? UINT8_MAX : UINT16_MAX;
@@ -52,9 +52,9 @@ namespace ComSquare::CPU
int CPU::SBC(uint24_t valueAddr, AddressingMode mode) int CPU::SBC(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
bool oldCarry = this->_registers.p.c; bool oldCarry = this->_registers.p.c;
this->_registers.p.c = this->_registers.a >= value; this->_registers.p.c = this->_registers.a >= value;
@@ -94,9 +94,9 @@ namespace ComSquare::CPU
int CPU::ORA(uint24_t valueAddr, AddressingMode mode) int CPU::ORA(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.a |= value; this->_registers.a |= value;
this->_registers.p.z = this->_registers.a == 0; this->_registers.p.z = this->_registers.a == 0;
this->_registers.p.n = this->_registers.a & negativeMask; this->_registers.p.n = this->_registers.a & negativeMask;
@@ -151,9 +151,9 @@ namespace ComSquare::CPU
int CPU::CMP(uint24_t valueAddr, AddressingMode mode) int CPU::CMP(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
unsigned result = this->_registers.a - value; unsigned result = this->_registers.a - value;
if (this->_registers.p.m) if (this->_registers.p.m)
result %= 0x100; result %= 0x100;
@@ -214,7 +214,7 @@ namespace ComSquare::CPU
int CPU::CPX(uint24_t valueAddr, AddressingMode mode) int CPU::CPX(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned value = this->_bus.read(valueAddr++); unsigned value = this->getBus().read(valueAddr++);
if (this->_registers.p.x_b) { if (this->_registers.p.x_b) {
uint8_t x = this->_registers.x; uint8_t x = this->_registers.x;
@@ -222,7 +222,7 @@ namespace ComSquare::CPU
this->_registers.p.z = x == 0; this->_registers.p.z = x == 0;
this->_registers.p.n = x & 0x80u; this->_registers.p.n = x & 0x80u;
} else { } else {
value += this->_bus.read(valueAddr) << 8u; value += this->getBus().read(valueAddr) << 8u;
uint16_t x = this->_registers.x; uint16_t x = this->_registers.x;
x -= value; x -= value;
this->_registers.p.z = x == 0; this->_registers.p.z = x == 0;
@@ -234,7 +234,7 @@ namespace ComSquare::CPU
int CPU::CPY(uint24_t valueAddr, AddressingMode mode) int CPU::CPY(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned value = this->_bus.read(valueAddr++); unsigned value = this->getBus().read(valueAddr++);
this->_registers.p.c = this->_registers.y >= value; this->_registers.p.c = this->_registers.y >= value;
if (this->_registers.p.x_b) { if (this->_registers.p.x_b) {
@@ -243,7 +243,7 @@ namespace ComSquare::CPU
this->_registers.p.z = y == 0; this->_registers.p.z = y == 0;
this->_registers.p.n = y & 0x80u; this->_registers.p.n = y & 0x80u;
} else { } else {
value += this->_bus.read(valueAddr) << 8u; value += this->getBus().read(valueAddr) << 8u;
uint16_t y = this->_registers.y; uint16_t y = this->_registers.y;
y -= value; y -= value;
this->_registers.p.z = y == 0; this->_registers.p.z = y == 0;
@@ -255,9 +255,9 @@ namespace ComSquare::CPU
int CPU::AND(uint24_t valueAddr, AddressingMode mode) int CPU::AND(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.a &= value; this->_registers.a &= value;
this->_registers.p.n = this->_registers.a & negativeMask; this->_registers.p.n = this->_registers.a & negativeMask;
@@ -297,15 +297,15 @@ namespace ComSquare::CPU
this->_registers.ah = 0; this->_registers.ah = 0;
result = this->_registers.a; result = this->_registers.a;
} else if (!this->_registers.p.m) { } else if (!this->_registers.p.m) {
result = this->_bus.read(valueAddr); result = this->getBus().read(valueAddr);
result += this->_bus.read(valueAddr + 1) << 8u; result += this->getBus().read(valueAddr + 1) << 8u;
result = (uint16_t)(result + 1); result = (uint16_t)(result + 1);
this->_bus.write(valueAddr, result); this->getBus().write(valueAddr, result);
this->_bus.write(valueAddr + 1, result << 8u); this->getBus().write(valueAddr + 1, result << 8u);
} else { } else {
result = this->_bus.read(valueAddr); result = this->getBus().read(valueAddr);
result = (uint8_t)(result + 1); result = (uint8_t)(result + 1);
this->_bus.write(valueAddr, result); this->getBus().write(valueAddr, result);
} }
this->_registers.p.z = result == 0; this->_registers.p.z = result == 0;
@@ -337,15 +337,15 @@ namespace ComSquare::CPU
this->_registers.ah = 0; this->_registers.ah = 0;
result = this->_registers.a; result = this->_registers.a;
} else if (!this->_registers.p.m) { } else if (!this->_registers.p.m) {
result = this->_bus.read(valueAddr); result = this->getBus().read(valueAddr);
result += this->_bus.read(valueAddr + 1) << 8u; result += this->getBus().read(valueAddr + 1) << 8u;
result = (uint16_t)(result - 1); result = (uint16_t)(result - 1);
this->_bus.write(valueAddr, result); this->getBus().write(valueAddr, result);
this->_bus.write(valueAddr + 1, result << 8u); this->getBus().write(valueAddr + 1, result << 8u);
} else { } else {
result = this->_bus.read(valueAddr); result = this->getBus().read(valueAddr);
result = (uint8_t)(result - 1); result = (uint8_t)(result - 1);
this->_bus.write(valueAddr, result); this->getBus().write(valueAddr, result);
} }
this->_registers.p.z = result == 0; this->_registers.p.z = result == 0;
@@ -369,9 +369,9 @@ namespace ComSquare::CPU
int CPU::EOR(uint24_t valueAddr, AddressingMode mode) int CPU::EOR(uint24_t valueAddr, AddressingMode mode)
{ {
unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u; unsigned negativeMask = this->_registers.p.m ? 0x80u : 0x8000u;
unsigned value = this->_bus.read(valueAddr); unsigned value = this->getBus().read(valueAddr);
if (!this->_registers.p.m) if (!this->_registers.p.m)
value += this->_bus.read(valueAddr + 1) << 8u; value += this->getBus().read(valueAddr + 1) << 8u;
this->_registers.a ^= value; this->_registers.a ^= value;
this->_registers.p.z = this->_registers.a == 0; this->_registers.p.z = this->_registers.a == 0;
this->_registers.p.n = this->_registers.a & negativeMask; this->_registers.p.n = this->_registers.a & negativeMask;

View File

@@ -9,10 +9,10 @@ namespace ComSquare::CPU
int CPU::STA(uint24_t addr, AddressingMode mode) int CPU::STA(uint24_t addr, AddressingMode mode)
{ {
if (this->_registers.p.m) if (this->_registers.p.m)
this->_bus.write(addr, this->_registers.al); this->getBus().write(addr, this->_registers.al);
else { else {
this->_bus.write(addr, this->_registers.al); this->getBus().write(addr, this->_registers.al);
this->_bus.write(addr + 1, this->_registers.ah); this->getBus().write(addr + 1, this->_registers.ah);
} }
int cycles = !this->_registers.p.m; int cycles = !this->_registers.p.m;
@@ -34,10 +34,10 @@ namespace ComSquare::CPU
int CPU::STX(uint24_t addr, AddressingMode mode) int CPU::STX(uint24_t addr, AddressingMode mode)
{ {
if (this->_registers.p.x_b) if (this->_registers.p.x_b)
this->_bus.write(addr, this->_registers.xl); this->getBus().write(addr, this->_registers.xl);
else { else {
this->_bus.write(addr, this->_registers.xl); this->getBus().write(addr, this->_registers.xl);
this->_bus.write(addr + 1, this->_registers.xh); this->getBus().write(addr + 1, this->_registers.xh);
} }
return !this->_registers.p.x_b + (mode != Absolute && this->_registers.dl != 0); return !this->_registers.p.x_b + (mode != Absolute && this->_registers.dl != 0);
} }
@@ -45,19 +45,19 @@ namespace ComSquare::CPU
int CPU::STY(uint24_t addr, AddressingMode mode) int CPU::STY(uint24_t addr, AddressingMode mode)
{ {
if (this->_registers.p.x_b) if (this->_registers.p.x_b)
this->_bus.write(addr, this->_registers.yl); this->getBus().write(addr, this->_registers.yl);
else { else {
this->_bus.write(addr, this->_registers.yl); this->getBus().write(addr, this->_registers.yl);
this->_bus.write(addr + 1, this->_registers.yh); this->getBus().write(addr + 1, this->_registers.yh);
} }
return !this->_registers.p.x_b + (mode != Absolute && this->_registers.dl != 0); return !this->_registers.p.x_b + (mode != Absolute && this->_registers.dl != 0);
} }
int CPU::STZ(uint24_t addr, AddressingMode mode) int CPU::STZ(uint24_t addr, AddressingMode mode)
{ {
this->_bus.write(addr, 0x00); this->getBus().write(addr, 0x00);
if (!this->_registers.p.m) if (!this->_registers.p.m)
this->_bus.write(addr + 1, 0x00); this->getBus().write(addr + 1, 0x00);
if (mode == Absolute || mode == AbsoluteIndexedByX) if (mode == Absolute || mode == AbsoluteIndexedByX)
return !this->_registers.p.m; return !this->_registers.p.m;
return !this->_registers.p.m + this->_registers.dl != 0; return !this->_registers.p.m + this->_registers.dl != 0;
@@ -66,11 +66,11 @@ namespace ComSquare::CPU
int CPU::LDA(uint24_t addr, AddressingMode mode) int CPU::LDA(uint24_t addr, AddressingMode mode)
{ {
if (this->_registers.p.m) { if (this->_registers.p.m) {
this->_registers.a = this->_bus.read(addr); this->_registers.a = this->getBus().read(addr);
this->_registers.p.n = this->_registers.al & 0xF0u; this->_registers.p.n = this->_registers.al & 0xF0u;
} else { } else {
this->_registers.al = this->_bus.read(addr); this->_registers.al = this->getBus().read(addr);
this->_registers.ah = this->_bus.read(addr + 1); this->_registers.ah = this->getBus().read(addr + 1);
this->_registers.p.n = this->_registers.a & 0xF000u; this->_registers.p.n = this->_registers.a & 0xF000u;
} }
this->_registers.p.z = this->_registers.a == 0x0; this->_registers.p.z = this->_registers.a == 0x0;
@@ -101,11 +101,11 @@ namespace ComSquare::CPU
int CPU::LDX(uint24_t addr, AddressingMode mode) int CPU::LDX(uint24_t addr, AddressingMode mode)
{ {
if (this->_registers.p.x_b) { if (this->_registers.p.x_b) {
this->_registers.x = this->_bus.read(addr); this->_registers.x = this->getBus().read(addr);
this->_registers.p.n = this->_registers.xl & 0xF0u; this->_registers.p.n = this->_registers.xl & 0xF0u;
} else { } else {
this->_registers.xl = this->_bus.read(addr); this->_registers.xl = this->getBus().read(addr);
this->_registers.xh = this->_bus.read(addr + 1); this->_registers.xh = this->getBus().read(addr + 1);
this->_registers.p.n = this->_registers.x & 0xF000u; this->_registers.p.n = this->_registers.x & 0xF000u;
} }
this->_registers.p.z = this->_registers.x == 0x0; this->_registers.p.z = this->_registers.x == 0x0;
@@ -128,11 +128,11 @@ namespace ComSquare::CPU
int CPU::LDY(uint24_t addr, AddressingMode mode) int CPU::LDY(uint24_t addr, AddressingMode mode)
{ {
if (this->_registers.p.x_b) { if (this->_registers.p.x_b) {
this->_registers.y = this->_bus.read(addr); this->_registers.y = this->getBus().read(addr);
this->_registers.p.n = this->_registers.yl & 0xF0u; this->_registers.p.n = this->_registers.yl & 0xF0u;
} else { } else {
this->_registers.yl = this->_bus.read(addr); this->_registers.yl = this->getBus().read(addr);
this->_registers.yh = this->_bus.read(addr + 1); this->_registers.yh = this->getBus().read(addr + 1);
this->_registers.p.n = this->_registers.y & 0xF000u; this->_registers.p.n = this->_registers.y & 0xF000u;
} }
this->_registers.p.z = this->_registers.y == 0x0; this->_registers.p.z = this->_registers.y == 0x0;

View File

@@ -160,8 +160,8 @@ namespace ComSquare::CPU
this->_registers.dbr = destBank; this->_registers.dbr = destBank;
while (this->_registers.a != 0xFFFF) { while (this->_registers.a != 0xFFFF) {
uint8_t data = this->_bus.read(srcBank << 24u | this->_registers.x); uint8_t data = this->getBus().read(srcBank << 24u | this->_registers.x);
this->_bus.write(destBank << 24u | this->_registers.y, data); this->getBus().write(destBank << 24u | this->_registers.y, data);
this->_registers.x++; this->_registers.x++;
this->_registers.y++; this->_registers.y++;
this->_registers.a--; this->_registers.a--;
@@ -177,8 +177,8 @@ namespace ComSquare::CPU
this->_registers.dbr = destBank; this->_registers.dbr = destBank;
while (this->_registers.a != 0xFFFF) { while (this->_registers.a != 0xFFFF) {
uint8_t data = this->_bus.read(srcBank << 24u | this->_registers.x); uint8_t data = this->getBus().read(srcBank << 24u | this->_registers.x);
this->_bus.write(destBank << 24u | this->_registers.y, data); this->getBus().write(destBank << 24u | this->_registers.y, data);
this->_registers.x--; this->_registers.x--;
this->_registers.y--; this->_registers.y--;
this->_registers.a--; this->_registers.a--;

View File

@@ -3,25 +3,19 @@
// //
#include "MemoryBusDebug.hpp" #include "MemoryBusDebug.hpp"
#include "../SNES.hpp" #include "SNES.hpp"
#include "../Utility/Utility.hpp" #include "Utility/Utility.hpp"
#include "../Exceptions/InvalidAction.hpp" #include "Exceptions/InvalidAction.hpp"
#include "../Exceptions/InvalidAddress.hpp"
namespace ComSquare::Debugger namespace ComSquare::Debugger
{ {
MemoryBusDebug::MemoryBusDebug(SNES &snes, const Memory::MemoryBus &bus) MemoryBusDebug::MemoryBusDebug(SNES &snes, Memory::IMemoryBus &bus)
: MemoryBus(bus), : _window(new ClosableWindow([&snes] { snes.disableMemoryBusDebugging(); })),
_window(new ClosableWindow<MemoryBusDebug>(*this, &MemoryBusDebug::disableViewer)), _bus(bus),
_snes(snes),
_ui(), _ui(),
_model(), _model(),
_proxy(this->_model) _proxy(this->_model)
{ {
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.setupUi(this->_window);
this->_proxy.setSourceModel(&this->_model); this->_proxy.setSourceModel(&this->_model);
this->_ui.log->setModel(&this->_proxy); this->_ui.log->setModel(&this->_proxy);
@@ -133,79 +127,63 @@ namespace ComSquare::Debugger
this->_window->show(); this->_window->show();
} }
void MemoryBusDebug::disableViewer()
{
this->_snes.disableMemoryBusDebugging();
}
void MemoryBusDebug::focus() void MemoryBusDebug::focus()
{ {
this->_window->activateWindow(); this->_window->activateWindow();
} }
bool MemoryBusDebug::isDebugger()
{
return true;
}
uint8_t MemoryBusDebug::read(uint24_t addr) uint8_t MemoryBusDebug::read(uint24_t addr)
{ {
if (this->forceSilence) uint8_t value = this->_bus.read(addr);
return MemoryBus::read(addr); this->_model.log(BusLog(false, addr, this->getAccessor(addr), value, value));
return this->read(addr, false); return value;
} }
uint8_t MemoryBusDebug::read(uint24_t addr, bool silence) std::optional<uint8_t> MemoryBusDebug::peek(uint24_t addr)
{ {
if (!silence && !this->forceSilence) { return this->_bus.peek(addr);
auto accessor = this->getAccessor(addr);
if (!accessor) {
this->_model.log(BusLog(true, addr, accessor, this->_openBus, this->_openBus));
} else {
uint8_t value = accessor->read(accessor->getRelativeAddress(addr));
this->_model.log(BusLog(false, addr, accessor, value, value));
}
}
return MemoryBus::read(addr, silence);
} }
void MemoryBusDebug::write(uint24_t addr, uint8_t data) void MemoryBusDebug::write(uint24_t addr, uint8_t data)
{ {
auto accessor = this->getAccessor(addr); std::optional<uint8_t> value = this->peek(addr);
std::optional<uint8_t> value = std::nullopt; this->_model.log(BusLog(true, addr, this->getAccessor(addr), value, data));
try { this->_bus.write(addr, data);
if (accessor)
value = accessor->read(accessor->getRelativeAddress(addr));
} catch (InvalidAddress &) {
value = std::nullopt;
}
if (!forceSilence)
this->_model.log(BusLog(true, addr, accessor, value, data));
MemoryBus::write(addr, data);
} }
BusLog::BusLog(bool _write, uint24_t _addr, std::shared_ptr<Memory::IMemory> &_accessor, std::optional<uint8_t> _oldData, uint8_t _newData) : Memory::IMemory *MemoryBusDebug::getAccessor(uint24_t addr)
write(_write), addr(_addr), accessor(std::move(_accessor)), oldData(_oldData), newData(_newData) {
return this->_bus.getAccessor(addr);
}
BusLog::BusLog(bool _write, uint24_t _addr,
Memory::IMemory *_accessor,
std::optional<uint8_t> _oldData,
uint8_t _newData)
: write(_write),
addr(_addr),
accessor(_accessor),
oldData(_oldData),
newData(_newData)
{} {}
}
int BusLogModel::rowCount(const QModelIndex &) const int BusLogModel::rowCount(const QModelIndex &) const
{ {
return this->_logs.size(); return static_cast<int>(this->_logs.size());
} }
int BusLogModel::columnCount(const QModelIndex &) const int BusLogModel::columnCount(const QModelIndex &) const
{ {
return this->column; return this->column;
} }
QVariant BusLogModel::data(const QModelIndex &index, int role) const QVariant BusLogModel::data(const QModelIndex &index, int role) const
{ {
if (role == Qt::TextAlignmentRole) if (role == Qt::TextAlignmentRole)
return Qt::AlignCenter; return Qt::AlignCenter;
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
ComSquare::Debugger::BusLog log = this->_logs[index.row()]; BusLog log = this->_logs[index.row()];
switch (index.column()) { switch (index.column()) {
case 0: case 0:
return QString(log.write ? "Write" : "Read"); return QString(log.write ? "Write" : "Read");
@@ -226,10 +204,10 @@ QVariant BusLogModel::data(const QModelIndex &index, int role) const
default: default:
return QVariant(); return QVariant();
} }
} }
QVariant BusLogModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant BusLogModel::headerData(int section, Qt::Orientation orientation, int role) const
{ {
if (role != Qt::DisplayRole || orientation == Qt::Vertical) if (role != Qt::DisplayRole || orientation == Qt::Vertical)
return QVariant(); return QVariant();
switch (section) { switch (section) {
@@ -248,63 +226,66 @@ QVariant BusLogModel::headerData(int section, Qt::Orientation orientation, int r
default: default:
return QString(""); return QString("");
} }
} }
void BusLogModel::log(const ComSquare::Debugger::BusLog& log) void BusLogModel::log(const BusLog &log)
{ {
int row = this->_logs.size(); int row = static_cast<int>(this->_logs.size());
this->beginInsertRows(QModelIndex(), row, row); this->beginInsertRows(QModelIndex(), row, row);
this->_logs.push_back(log); this->_logs.push_back(log);
this->insertRow(row); this->insertRow(row);
this->endInsertRows(); this->endInsertRows();
} }
ComSquare::Debugger::BusLog BusLogModel::getLogAt(int index) BusLog BusLogModel::getLogAt(int index)
{ {
return this->_logs[index]; return this->_logs[index];
} }
void BusLogModel::clearLogs() void BusLogModel::clearLogs()
{ {
this->beginResetModel(); this->beginResetModel();
this->_logs.clear(); this->_logs.clear();
this->endResetModel(); this->endResetModel();
} }
BusLoggerProxy::BusLoggerProxy(BusLogModel &parent) : QSortFilterProxyModel(), _parent(parent) {} BusLoggerProxy::BusLoggerProxy(BusLogModel &parent)
: QSortFilterProxyModel(), _parent(parent)
{}
bool BusLoggerProxy::filterAcceptsRow(int sourceRow, const QModelIndex &) const bool BusLoggerProxy::filterAcceptsRow(int sourceRow, const QModelIndex &) const
{ {
ComSquare::Debugger::BusLog log = this->_parent.getLogAt(sourceRow); BusLog log = this->_parent.getLogAt(sourceRow);
if (!log.accessor) if (!log.accessor)
return true; return true;
ComSquare::Component component = log.accessor->getComponent(); Component component = log.accessor->getComponent();
switch (component) { switch (component) {
case ComSquare::Component::Cpu: case Component::Cpu:
return this->filters[log.write].cpu; return this->filters[log.write].cpu;
case ComSquare::Component::Ppu: case Component::Ppu:
return this->filters[log.write].ppu; return this->filters[log.write].ppu;
case ComSquare::Component::Apu: case Component::Apu:
return this->filters[log.write].apu; return this->filters[log.write].apu;
case ComSquare::Component::Rom: case Component::Rom:
return this->filters[log.write].rom; return this->filters[log.write].rom;
case ComSquare::Component::WRam: case Component::WRam:
return this->filters[log.write].wram; return this->filters[log.write].wram;
case ComSquare::Component::VRam: case Component::VRam:
return this->filters[log.write].vram; return this->filters[log.write].vram;
case ComSquare::Component::CGRam: case Component::CGRam:
return this->filters[log.write].cgram; return this->filters[log.write].cgram;
case ComSquare::Component::OAMRam: case Component::OAMRam:
return this->filters[log.write].oamram; return this->filters[log.write].oamram;
case ComSquare::Component::SRam: case Component::SRam:
return this->filters[log.write].sram; return this->filters[log.write].sram;
default: default:
return true; return true;
} }
} }
void BusLoggerProxy::refresh() void BusLoggerProxy::refresh()
{ {
this->invalidateFilter(); this->invalidateFilter();
}
} }

View File

@@ -2,35 +2,37 @@
// Created by anonymus-raccoon on 3/20/20. // Created by anonymus-raccoon on 3/20/20.
// //
#ifndef COMSQUARE_MEMORYBUSDEBUG_HPP #pragma once
#define COMSQUARE_MEMORYBUSDEBUG_HPP
#include <QtWidgets/QMainWindow> #include <QtWidgets/QMainWindow>
#include <QtCore/QSortFilterProxyModel> #include <QtCore/QSortFilterProxyModel>
#include "../Memory/MemoryBus.hpp" #include "Memory/MemoryBus.hpp"
#include "../../ui/ui_busView.h" #include "Memory/IMemory.hpp"
#include "ui/ui_busView.h"
#include "ClosableWindow.hpp" #include "ClosableWindow.hpp"
#include <optional> #include <optional>
namespace ComSquare::Debugger namespace ComSquare::Debugger
{ {
//! @brief The struct used to represent memory bus logs. //! @brief The struct used to represent memory bus logs.
struct BusLog { struct BusLog
{
BusLog(bool write, BusLog(bool write,
uint24_t addr, uint24_t addr,
std::shared_ptr<Memory::IMemory> &accessor, Memory::IMemory *accessor,
std::optional<uint8_t> oldData, std::optional<uint8_t> oldData,
uint8_t newData); uint8_t newData);
bool write; bool write;
uint24_t addr; uint24_t addr;
std::shared_ptr<Memory::IMemory> accessor; Memory::IMemory *accessor;
std::optional<uint8_t> oldData; std::optional<uint8_t> oldData;
uint8_t newData; uint8_t newData;
}; };
//! @brief The struct representing filters of the memory bus's logger. //! @brief The struct representing filters of the memory bus's logger.
struct BusLoggerFilters { struct BusLoggerFilters
{
bool cpu = true; bool cpu = true;
bool apu = true; bool apu = true;
bool ppu = true; bool ppu = true;
@@ -41,17 +43,15 @@ namespace ComSquare::Debugger
bool oamram = true; bool oamram = true;
bool cgram = true; bool cgram = true;
}; };
}
//! @brief The qt model that bind the logs to the view.
//! @brief The qt model that bind the logs to the view. class BusLogModel : public QAbstractTableModel
class BusLogModel : public QAbstractTableModel {
{
Q_OBJECT Q_OBJECT
private: private:
//! @brief The logs to display. //! @brief The logs to display.
std::vector<ComSquare::Debugger::BusLog> _logs; std::vector<ComSquare::Debugger::BusLog> _logs;
public: public:
BusLogModel() = default; BusLogModel() = default;
BusLogModel(const BusLogModel &) = delete; BusLogModel(const BusLogModel &) = delete;
const BusLogModel &operator=(const BusLogModel &) = delete; const BusLogModel &operator=(const BusLogModel &) = delete;
@@ -61,7 +61,7 @@ public:
const int column = 6; const int column = 6;
//! @brief Add a log to the model //! @brief Add a log to the model
void log(const ComSquare::Debugger::BusLog& log); void log(const ComSquare::Debugger::BusLog &log);
//! @brief Get a log at an index. //! @brief Get a log at an index.
ComSquare::Debugger::BusLog getLogAt(int index); ComSquare::Debugger::BusLog getLogAt(int index);
@@ -69,27 +69,31 @@ public:
void clearLogs(); void clearLogs();
//! @brief The number of row the table has. //! @brief The number of row the table has.
int rowCount(const QModelIndex &parent) const override; [[nodiscard]] int rowCount(const QModelIndex &parent) const override;
//! @brief The number of column the table has. //! @brief The number of column the table has.
int columnCount(const QModelIndex &parent) const override; [[nodiscard]] int columnCount(const QModelIndex &parent) const override;
//! @brief Return a data representing the table cell. //! @brief Return a data representing the table cell.
QVariant data(const QModelIndex &index, int role) const override; [[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
//! @brief Override the headers to use hex values. //! @brief Override the headers to use hex values.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
}; };
//! @brief A class to filter logs from the memory bus's debugger. //! @brief A class to filter logs from the memory bus's debugger.
class BusLoggerProxy : public QSortFilterProxyModel { class BusLoggerProxy : public QSortFilterProxyModel
{
Q_OBJECT Q_OBJECT
private: private:
//! @brief The parent to get the original data for filters //! @brief The parent to get the original data for filters
BusLogModel &_parent; BusLogModel &_parent;
protected: protected:
//! @brief Function that filter logs. //! @brief Function that filter logs.
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; [[nodiscard]] bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
public: public:
//! @brief Currently enabled filters, index 0 is for reads, index 1 for writes. //! @brief Currently enabled filters, index 0 is for reads, index 1 for writes.
ComSquare::Debugger::BusLoggerFilters filters[2] = {ComSquare::Debugger::BusLoggerFilters(), ComSquare::Debugger::BusLoggerFilters()}; ComSquare::Debugger::BusLoggerFilters filters[2] = {
ComSquare::Debugger::BusLoggerFilters(),
ComSquare::Debugger::BusLoggerFilters()
};
//! @brief Refresh the view after a change of filters. //! @brief Refresh the view after a change of filters.
void refresh(); void refresh();
@@ -98,18 +102,16 @@ public:
BusLoggerProxy(const BusLoggerProxy &) = delete; BusLoggerProxy(const BusLoggerProxy &) = delete;
const BusLoggerProxy &operator=(const BusLoggerProxy &) = delete; const BusLoggerProxy &operator=(const BusLoggerProxy &) = delete;
~BusLoggerProxy() override = default; ~BusLoggerProxy() override = default;
}; };
namespace ComSquare::Debugger
{
//! @brief window that allow the user to view all data going through the memory bus. //! @brief window that allow the user to view all data going through the memory bus.
class MemoryBusDebug : public Memory::MemoryBus { class MemoryBusDebug : public Memory::IMemoryBus
{
private: private:
//! @brief The QT window for this debugger. //! @brief The QT window for this debugger.
ClosableWindow<MemoryBusDebug> *_window; ClosableWindow *_window;
//! @brief A reference to the snes (to disable the debugger). //! @brief A reference to the underlying bus..
SNES &_snes; Memory::IMemoryBus &_bus;
//! @brief A widget that contain the whole UI. //! @brief A widget that contain the whole UI.
Ui::BusView _ui; Ui::BusView _ui;
//! @brief The Log visualizer model for QT. //! @brief The Log visualizer model for QT.
@@ -117,35 +119,33 @@ namespace ComSquare::Debugger
//! @brief A QT proxy to filter the logs. //! @brief A QT proxy to filter the logs.
BusLoggerProxy _proxy; BusLoggerProxy _proxy;
public: public:
//! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU. explicit MemoryBusDebug(SNES &snes, Memory::IMemoryBus &bus);
void disableViewer();
public:
explicit MemoryBusDebug(SNES &snes, const Memory::MemoryBus &bus);
MemoryBusDebug(const MemoryBusDebug &) = delete; MemoryBusDebug(const MemoryBusDebug &) = delete;
MemoryBusDebug &operator=(const MemoryBusDebug &) = delete; MemoryBusDebug &operator=(const MemoryBusDebug &) = delete;
~MemoryBusDebug() = default; ~MemoryBusDebug() override = default;
//! @brief Read data at a global address and log it to the debugger. //! @brief Read data at a global address. This form allow read to be silenced.
//! @param addr The address to read from. //! @param addr The address to read from.
//! @throws InvalidAddress If the address is not mapped to the bus, this exception is thrown.
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register. //! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
uint8_t read(uint24_t addr) override; uint8_t read(uint24_t addr) override;
//! @brief Read data at a global address and log it to the debugger. //! @brief This as the same purpose as a read but it does not change the open bus and won't throw an exception.
//! @param addr The address to read from. //! @param addr The address to read from.
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register. //! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
uint8_t read(uint24_t addr, bool silence) override; std::optional<uint8_t> peek(uint24_t addr) override;
//! @brief Write a data to a global address and log it to the debugger. //! @brief Write a data to a global address.
//! @param addr The address to write to. //! @param addr The address to write to.
//! @param data The data to write. //! @param data The data to write.
void write(uint24_t addr, uint8_t data) override; void write(uint24_t addr, uint8_t data) override;
//! @brief Helper function to get the components that is responsible of read/write at an address.
//! @param addr The address you want to look for.
//! @return The components responsible for the address param or nullptr if none was found.
Memory::IMemory *getAccessor(uint24_t addr) override;
//! @brief Focus the debugger's window. //! @brief Focus the debugger's window.
void focus(); void focus();
//! @brief Return true if the Bus is overloaded with debugging features.
bool isDebugger() override;
}; };
} }
#endif //COMSQUARE_MEMORYBUSDEBUG_HPP

View File

@@ -8,13 +8,14 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <string> #include <string>
#include "../Models/Int24.hpp" #include "Models/Int24.hpp"
#include "../Models/Components.hpp" #include "Models/Components.hpp"
namespace ComSquare::Memory namespace ComSquare::Memory
{ {
//! @brief Common interface implemented by all components mapping memory. //! @brief Common interface implemented by all components mapping memory.
class IMemory { class IMemory
{
public: public:
//! @brief Read data from the component. //! @brief Read data from the component.
//! @param addr The local address to read from (0x0 should refer to the first byte of this component). //! @param addr The local address to read from (0x0 should refer to the first byte of this component).

View File

@@ -0,0 +1,47 @@
//
// Created by Zoe Roux on 2021-07-04.
//
#pragma once
#include <cinttypes>
#include <optional>
#include "IMemory.hpp"
namespace ComSquare
{
class SNES;
namespace Memory
{
//! @brief The memory bus is the component responsible of mapping addresses to components address and transmitting the data.
class IMemoryBus
{
public:
//! @brief A virtual default destructor.
virtual ~IMemoryBus() = default;
//! @brief Read data at a global address. This form allow read to be silenced.
//! @param addr The address to read from.
//! @throws InvalidAddress If the address is not mapped to the bus, this exception is thrown.
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
virtual uint8_t read(uint24_t addr) = 0;
//! @brief This as the same purpose as a read but it does not change the open bus and won't throw an exception.
//! @param addr The address to read from.
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
virtual std::optional<uint8_t> peek(uint24_t addr) = 0;
//! @brief Write a data to a global address.
//! @param addr The address to write to.
//! @param data The data to write.
virtual void write(uint24_t addr, uint8_t data) = 0;
//! @brief Helper function to get the components that is responsible of read/write at an address.
//! @param addr The address you want to look for.
//! @return The components responsible for the address param or nullptr if none was found.
virtual IMemory *getAccessor(uint24_t addr) = 0;
};
}
}

View File

@@ -2,7 +2,6 @@
// Created by anonymus-raccoon on 1/23/20. // Created by anonymus-raccoon on 1/23/20.
// //
#include <algorithm>
#include <iostream> #include <iostream>
#include "SNES.hpp" #include "SNES.hpp"
#include "Memory/MemoryBus.hpp" #include "Memory/MemoryBus.hpp"
@@ -36,7 +35,7 @@ namespace ComSquare::Memory
return data; return data;
} }
uint8_t MemoryBus::peek(uint24_t addr) std::optional<uint8_t> MemoryBus::peek(uint24_t addr)
{ {
IMemory *handler = this->getAccessor(addr); IMemory *handler = this->getAccessor(addr);
@@ -45,7 +44,7 @@ namespace ComSquare::Memory
try { try {
return handler->read(handler->getRelativeAddress(addr)); return handler->read(handler->getRelativeAddress(addr));
} catch (const InvalidAddress &) { } catch (const InvalidAddress &) {
return 0; return std::nullopt;
} }
} }

View File

@@ -7,6 +7,7 @@
#include "AMemory.hpp" #include "AMemory.hpp"
#include "RectangleShadow.hpp" #include "RectangleShadow.hpp"
#include "MemoryShadow.hpp" #include "MemoryShadow.hpp"
#include "IMemoryBus.hpp"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -18,7 +19,7 @@ namespace ComSquare
namespace Memory namespace Memory
{ {
//! @brief The memory bus is the component responsible of mapping addresses to components address and transmitting the data. //! @brief The memory bus is the component responsible of mapping addresses to components address and transmitting the data.
class MemoryBus class MemoryBus : public IMemoryBus
{ {
private: private:
//! @brief The list of components registered inside the bus. Every components that can read/write to a public address should be in this vector. //! @brief The list of components registered inside the bus. Every components that can read/write to a public address should be in this vector.
@@ -44,26 +45,23 @@ namespace ComSquare
//! @brief A memory bus is assignable. //! @brief A memory bus is assignable.
MemoryBus &operator=(const MemoryBus &) = default; MemoryBus &operator=(const MemoryBus &) = default;
//! @brief A default destructor //! @brief A default destructor
~MemoryBus() = default; ~MemoryBus() override = default;
//! @brief Force silencing read to the bus.
bool forceSilence = false;
//! @brief Read data at a global address. This form allow read to be silenced. //! @brief Read data at a global address. This form allow read to be silenced.
//! @param addr The address to read from. //! @param addr The address to read from.
//! @throws InvalidAddress If the address is not mapped to the bus, this exception is thrown. //! @throws InvalidAddress If the address is not mapped to the bus, this exception is thrown.
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register. //! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
uint8_t read(uint24_t addr); uint8_t read(uint24_t addr) override;
//! @brief This as the same purpose as a read but it does not change the open bus and won't throw an exception. //! @brief This as the same purpose as a read but it does not change the open bus and won't throw an exception.
//! @param addr The address to read from. //! @param addr The address to read from.
//! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register. //! @return The value that the component returned for this address. If the address was mapped to ram, it simply returned the value. If the address was mapped to a register the component returned the register.
uint8_t peek(uint24_t addr); std::optional<uint8_t> peek(uint24_t addr) override;
//! @brief Write a data to a global address. //! @brief Write a data to a global address.
//! @param addr The address to write to. //! @param addr The address to write to.
//! @param data The data to write. //! @param data The data to write.
void write(uint24_t addr, uint8_t data); void write(uint24_t addr, uint8_t data) override;
//! @brief Map components to the address space using the currently loaded cartridge to set the right mapping mode. //! @brief Map components to the address space using the currently loaded cartridge to set the right mapping mode.
//! @param console All the components. //! @param console All the components.
@@ -72,7 +70,7 @@ namespace ComSquare
//! @brief Helper function to get the components that is responsible of read/write at an address. //! @brief Helper function to get the components that is responsible of read/write at an address.
//! @param addr The address you want to look for. //! @param addr The address you want to look for.
//! @return The components responsible for the address param or nullptr if none was found. //! @return The components responsible for the address param or nullptr if none was found.
IMemory *getAccessor(uint24_t addr); IMemory *getAccessor(uint24_t addr) override;
}; };
} }
} }

View File

@@ -95,7 +95,7 @@ namespace ComSquare::Renderer
void QtFullSFML::enableDebugBus() void QtFullSFML::enableDebugBus()
{ {
// this->_snes.enableMemoryBusDebugging(); this->_snes.enableMemoryBusDebugging();
} }
void QtFullSFML::enableCgramViewer() void QtFullSFML::enableCgramViewer()

View File

@@ -116,22 +116,21 @@ namespace ComSquare
// this->apu = std::make_shared<APU::APU>(*this->apu); // this->apu = std::make_shared<APU::APU>(*this->apu);
// this->bus.mapComponents(*this); // this->bus.mapComponents(*this);
// } // }
//
// void SNES::enableMemoryBusDebugging() void SNES::enableMemoryBusDebugging()
// { {
// if (this->bus.isDebugger()) if (this->_busDebugger)
// std::static_pointer_cast<Debugger::MemoryBusDebug>(this->bus)->focus(); this->_busDebugger->focus();
// else { else
// this->bus = std::make_shared<Debugger::MemoryBusDebug>(*this, *this->bus); this->_busDebugger.emplace(*this, this->bus);
// this->cpu->setMemoryBus(this->bus); this->cpu.setBus(this->_busDebugger.value());
// } }
// }
// void SNES::disableMemoryBusDebugging()
// void SNES::disableMemoryBusDebugging() {
// { this->_busDebugger = std::nullopt;
// this->bus = std::make_shared<Memory::MemoryBus>(*this->bus); this->cpu.setBus(this->bus);
// this->cpu->setMemoryBus(this->bus); }
// }
void SNES::enableCgramViewer() void SNES::enableCgramViewer()
{ {

View File

@@ -18,7 +18,7 @@
//#include <Debugger/CPU/CPUDebug.hpp> //#include <Debugger/CPU/CPUDebug.hpp>
#include "Debugger/MemoryViewer.hpp" #include "Debugger/MemoryViewer.hpp"
#include "Debugger/HeaderViewer.hpp" #include "Debugger/HeaderViewer.hpp"
//#include "Debugger/MemoryBusDebug.hpp" #include "Debugger/MemoryBusDebug.hpp"
#include "Debugger/CGramDebug.hpp" #include "Debugger/CGramDebug.hpp"
#include "Debugger/RegisterViewer.hpp" #include "Debugger/RegisterViewer.hpp"
#include "Debugger/TileViewer/TileViewer.hpp" #include "Debugger/TileViewer/TileViewer.hpp"
@@ -33,6 +33,8 @@ namespace ComSquare
#ifdef DEBUGGER_ENABLED #ifdef DEBUGGER_ENABLED
//! @brief The CPU's debugger with disassembly, pause, step by step... //! @brief The CPU's debugger with disassembly, pause, step by step...
// std::optional<Debugger::CPUDebug> _cpuDebugger; // std::optional<Debugger::CPUDebug> _cpuDebugger;
//! @brief A debugger that shows every read and write made over the bus.
std::optional<Debugger::MemoryBusDebug> _busDebugger;
//! @brief The window that allow the user to view a memory. //! @brief The window that allow the user to view a memory.
std::optional<Debugger::MemoryViewer> _ramViewer; std::optional<Debugger::MemoryViewer> _ramViewer;
@@ -104,10 +106,10 @@ namespace ComSquare
// void disableAPUDebugging(); // void disableAPUDebugging();
// //! @brief Enable the APU's debugging window. // //! @brief Enable the APU's debugging window.
// void enableAPUDebugging(); // void enableAPUDebugging();
// //! @brief Disable the Memory Bus's debugging window. //! @brief Disable the Memory Bus's debugging window.
// void disableMemoryBusDebugging(); void disableMemoryBusDebugging();
// //! @brief Enable the Memory Bus's debugging window. //! @brief Enable the Memory Bus's debugging window.
// void enableMemoryBusDebugging(); void enableMemoryBusDebugging();
//! @brief Disable the CGRAM's debugging window. //! @brief Disable the CGRAM's debugging window.
void disableCgramViewer(); void disableCgramViewer();
//! @brief Enable the CGRAM's debugging window. //! @brief Enable the CGRAM's debugging window.