From ea19186269806cd20fa2e6ce715b1d109be1a914 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 20 Mar 2020 16:41:45 +0100
Subject: [PATCH] Splitting the debug window of the component to allow quick
change of a component
---
CMakeLists.txt | 15 +-
sources/CPU/AddressingModes.cpp | 184 ++++++++++++++++++++++
sources/CPU/CPU.cpp | 208 ++-----------------------
sources/CPU/CPU.hpp | 5 +-
sources/Debugger/CPUDebug.cpp | 28 ++--
sources/Debugger/CPUDebug.hpp | 8 +-
sources/Debugger/ClosableWindow.hpp | 34 ++++
sources/Debugger/MemoryBusDebug.cpp | 19 +++
sources/Debugger/MemoryBusDebug.hpp | 27 ++++
sources/PPU/PPU.cpp | 19 ++-
sources/PPU/PPU.hpp | 3 +-
sources/Renderer/QtRenderer/QtSFML.cpp | 9 ++
sources/Renderer/QtRenderer/QtSFML.hpp | 2 +
sources/SNES.cpp | 40 +++--
sources/SNES.hpp | 14 +-
main.cpp => sources/main.cpp | 30 ++--
tests/tests.cpp | 6 +-
ui/busView.ui | 4 +-
18 files changed, 407 insertions(+), 248 deletions(-)
create mode 100644 sources/CPU/AddressingModes.cpp
create mode 100644 sources/Debugger/ClosableWindow.hpp
create mode 100644 sources/Debugger/MemoryBusDebug.cpp
create mode 100644 sources/Debugger/MemoryBusDebug.hpp
rename main.cpp => sources/main.cpp (52%)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e12549a..bdf401a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,7 +77,11 @@ add_executable(unit_tests
sources/APU/Instructions/Stack.cpp
sources/APU/Instructions/Subroutine.cpp
sources/APU/Instructions/ProgramFlow.cpp
- tests/CPU/Math/testSBC.cpp sources/CPU/Instructions/TransferRegisters.cpp tests/CPU/TransferRegisters.cpp)
+ tests/CPU/Math/testSBC.cpp
+ sources/CPU/Instructions/TransferRegisters.cpp
+ tests/CPU/TransferRegisters.cpp
+ sources/CPU/AddressingModes.cpp
+)
# include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov)
@@ -95,7 +99,7 @@ set(CMAKE_AUTOUIC ON)
# make app
add_executable(ComSquare
- main.cpp
+ sources/main.cpp
sources/SNES.cpp
sources/SNES.hpp
sources/Memory/MemoryBus.cpp
@@ -166,7 +170,12 @@ add_executable(ComSquare
sources/APU/Instructions/Stack.cpp
sources/APU/Instructions/Subroutine.cpp
sources/APU/Instructions/ProgramFlow.cpp
- sources/CPU/Instructions/TransferRegisters.cpp)
+ sources/CPU/Instructions/TransferRegisters.cpp
+ sources/CPU/AddressingModes.cpp
+ sources/Debugger/MemoryBusDebug.cpp
+ sources/Debugger/MemoryBusDebug.hpp
+ sources/Debugger/ClosableWindow.hpp
+)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
diff --git a/sources/CPU/AddressingModes.cpp b/sources/CPU/AddressingModes.cpp
new file mode 100644
index 0000000..cbe52ff
--- /dev/null
+++ b/sources/CPU/AddressingModes.cpp
@@ -0,0 +1,184 @@
+//
+// Created by anonymus-raccoon on 3/20/20.
+//
+
+#include "../Models/Int24.hpp"$
+#include "CPU.hpp"
+
+namespace ComSquare::CPU
+{
+ uint24_t CPU::_getImmediateAddrForA()
+ {
+ uint24_t effective = this->_registers.pac++;
+ if (!this->_registers.p.m)
+ this->_registers.pac++;
+ return effective;
+ }
+
+ uint24_t CPU::_getImmediateAddrForX()
+ {
+ uint24_t effective = this->_registers.pac++;
+ if (!this->_registers.p.x_b)
+ this->_registers.pac++;
+ return effective;
+ }
+
+ uint24_t CPU::_getDirectAddr()
+ {
+ uint8_t addr = this->_bus->read(this->_registers.pac++);
+ return this->_registers.d + addr;
+ }
+
+ uint24_t CPU::_getAbsoluteAddr()
+ {
+ uint24_t addr = this->_registers.dbr << 16u;
+ addr += this->_bus->read(this->_registers.pac++);
+ addr += this->_bus->read(this->_registers.pac++) << 8u;
+ return addr;
+ }
+
+ uint24_t CPU::_getAbsoluteLongAddr()
+ {
+ uint24_t addr = this->_bus->read(this->_registers.pac++);
+ addr += this->_bus->read(this->_registers.pac++) << 8u;
+ addr += this->_bus->read(this->_registers.pac++) << 16u;
+ return addr;
+ }
+
+ uint24_t CPU::_getDirectIndirectIndexedYAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ uint24_t base = this->_bus->read(dp);
+ base += this->_bus->read(dp + 1) << 8u;
+ base += this->_registers.dbr << 16u;
+ if ((base & 0x80000000u) == (((base + this->_registers.y) & 0x80000000u)))
+ this->_hasIndexCrossedPageBoundary = true;
+ return base + this->_registers.y;
+ }
+
+ uint24_t CPU::_getDirectIndirectIndexedYLongAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ uint24_t base = this->_bus->read(dp);
+ base += this->_bus->read(dp + 1) << 8u;
+ base += this->_bus->read(dp + 2) << 16u;
+ return base;
+ }
+
+ uint24_t CPU::_getDirectIndirectIndexedXAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ dp += this->_registers.x;
+ uint24_t base = this->_bus->read(dp);
+ base += this->_bus->read(dp + 1) << 8u;
+ base += this->_registers.dbr << 16u;
+ return base;
+ }
+
+ uint24_t CPU::_getDirectIndexedByXAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ dp += this->_registers.x;
+ return dp;
+ }
+
+ uint24_t CPU::_getDirectIndexedByYAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ dp += this->_registers.y;
+ return dp;
+ }
+
+ uint24_t CPU::_getAbsoluteIndexedByXAddr()
+ {
+ uint16_t abs = this->_bus->read(this->_registers.pac++);
+ abs += this->_bus->read(this->_registers.pac++) << 8u;
+ uint24_t effective = abs + (this->_registers.dbr << 16u);
+ if ((effective & 0x80000000u) == (((effective + this->_registers.x) & 0x80000000u)))
+ this->_hasIndexCrossedPageBoundary = true;
+ return effective + this->_registers.x;
+ }
+
+ uint24_t CPU::_getAbsoluteIndexedByYAddr()
+ {
+ uint16_t abs = this->_bus->read(this->_registers.pac++);
+ abs += this->_bus->read(this->_registers.pac++) << 8u;
+ uint24_t effective = abs + (this->_registers.dbr << 16u);
+ if ((effective & 0x80000000u) == (((effective + this->_registers.y) & 0x80000000u)))
+ this->_hasIndexCrossedPageBoundary = true;
+ return effective + this->_registers.y;
+ }
+
+ uint24_t CPU::_getAbsoluteIndexedByXLongAddr()
+ {
+ uint24_t lng = this->_bus->read(this->_registers.pac++);
+ lng += this->_bus->read(this->_registers.pac++) << 8u;
+ lng += this->_bus->read(this->_registers.pac++) << 16u;
+ return lng + this->_registers.x;
+ }
+
+ uint24_t CPU::_getProgramCounterRelativeAddr()
+ {
+ uint24_t pc = this->_registers.pac;
+ int8_t mod = this->_bus->read(this->_registers.pac++);
+ return pc + mod;
+ }
+
+ uint24_t CPU::_getProgramCounterRelativeLongAddr()
+ {
+ uint24_t pc = this->_registers.pac;
+ uint8_t val1 = this->_bus->read(this->_registers.pac++);
+ uint8_t val2 = this->_bus->read(this->_registers.pac++);
+ int16_t mod = val2 > 0x7F ? (static_cast(val2) * 256 - val1) : (val1 | val2 << 8u);
+ return pc + mod;
+ }
+
+ uint24_t CPU::_getAbsoluteIndirectAddr()
+ {
+ uint16_t abs = this->_bus->read(this->_registers.pac++);
+ abs += this->_bus->read(this->_registers.pac++) << 8u;
+ uint24_t effective = this->_bus->read(abs);
+ effective += this->_bus->read(abs + 1) << 8u;
+ return effective;
+ }
+
+ uint24_t CPU::_getAbsoluteIndirectIndexedByXAddr()
+ {
+ uint24_t abs = this->_bus->read(this->_registers.pac++);
+ abs += this->_bus->read(this->_registers.pac++) << 8u;
+ abs += this->_registers.x;
+ uint24_t effective = this->_bus->read(abs);
+ effective += this->_bus->read(abs + 1) << 8u;
+ return effective;
+ }
+
+ uint24_t CPU::_getDirectIndirectAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ uint24_t effective = this->_bus->read(dp);
+ effective += this->_bus->read(dp + 1) << 8u;
+ effective += this->_registers.dbr << 16u;
+ return effective;
+ }
+
+ uint24_t CPU::_getDirectIndirectLongAddr()
+ {
+ uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
+ uint24_t effective = this->_bus->read(dp);
+ effective += this->_bus->read(++dp) << 8u;
+ effective += this->_bus->read(++dp) << 16u;
+ return effective;
+ }
+
+ uint24_t CPU::_getStackRelativeAddr()
+ {
+ return this->_bus->read(this->_registers.pac++) + this->_registers.s;
+ }
+
+ uint24_t CPU::_getStackRelativeIndirectIndexedYAddr()
+ {
+ uint24_t base = this->_bus->read(this->_registers.pac++) + this->_registers.s;
+ base += this->_registers.dbr << 16u;
+ return base + this->_registers.y;
+ }
+}
\ No newline at end of file
diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp
index ffc2647..5a81b0f 100644
--- a/sources/CPU/CPU.cpp
+++ b/sources/CPU/CPU.cpp
@@ -18,6 +18,11 @@ namespace ComSquare::CPU
this->RESB();
}
+ void CPU::setMemoryBus(std::shared_ptr bus)
+ {
+ this->_bus = std::move(bus);
+ }
+
//! @bref The CPU's internal registers starts at $4200 and finish at $421F.
uint8_t CPU::read(uint24_t addr)
{
@@ -204,9 +209,9 @@ namespace ComSquare::CPU
case Instructions::COP: this->COP(); return 7 + !this->_isEmulationMode;
- case Instructions::RTI: this->RTI(); return 6 + !this->_isEmulationMode;
+ case Instructions::RTI: this->RTI(); return 6 + !this->_isEmulationMode;
- case Instructions::ADC_IM: this->ADC(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
+ case Instructions::ADC_IM: this->ADC(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
case Instructions::ADC_ABS: this->ADC(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
case Instructions::ADC_ABSl: this->ADC(this->_getAbsoluteLongAddr()); return 5 + !this->_registers.p.m;
case Instructions::ADC_DP: this->ADC(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
@@ -250,7 +255,7 @@ namespace ComSquare::CPU
case Instructions::STZ_ABSX: this->STX(this->_getAbsoluteIndexedByXAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
case Instructions::STZ_DPX: this->STX(this->_getDirectIndexedByXAddr()); return 4 + !this->_registers.p.m + this->_registers.dl != 0;
- case Instructions::LDA_IM: this->LDA(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
+ case Instructions::LDA_IM: this->LDA(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
case Instructions::LDA_ABS: this->LDA(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
case Instructions::LDA_ABSl: this->LDA(this->_getAbsoluteLongAddr()); return 5 + !this->_registers.p.m;
case Instructions::LDA_DP: this->LDA(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
@@ -266,13 +271,13 @@ namespace ComSquare::CPU
case Instructions::LDA_SR: this->LDA(this->_getStackRelativeAddr()); return 4 + !this->_registers.p.m;
case Instructions::LDA_SRYi: this->LDA(this->_getStackRelativeIndirectIndexedYAddr()); return 7 + !this->_registers.p.m;
- case Instructions::LDX_IM: this->LDX(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
+ case Instructions::LDX_IM: this->LDX(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
case Instructions::LDX_ABS: this->LDX(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
case Instructions::LDX_DP: this->LDX(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
case Instructions::LDX_ABSY: this->LDX(this->_getAbsoluteIndexedByYAddr()); return 4 + !this->_registers.p.m + this->_hasIndexCrossedPageBoundary;
case Instructions::LDX_DPY: this->LDX(this->_getDirectIndexedByYAddr()); return 4 + !this->_registers.p.m + this->_registers.dl != 0;
- case Instructions::LDY_IM: this->LDY(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
+ case Instructions::LDY_IM: this->LDY(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
case Instructions::LDY_ABS: this->LDY(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
case Instructions::LDY_DP: this->LDY(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
case Instructions::LDY_ABSY: this->LDY(this->_getAbsoluteIndexedByYAddr()); return 4 + !this->_registers.p.m + this->_hasIndexCrossedPageBoundary;
@@ -311,7 +316,7 @@ namespace ComSquare::CPU
case Instructions::SED: this->SED(); return 2;
case Instructions::SEI: this->SEI(); return 2;
- case Instructions::AND_IM: this->AND(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
+ case Instructions::AND_IM: this->AND(this->_getImmediateAddrForA()); return 2 + !this->_registers.p.m;
case Instructions::AND_ABS: this->AND(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
case Instructions::AND_ABSl: this->AND(this->_getAbsoluteLongAddr()); return 5 + !this->_registers.p.m;
case Instructions::AND_DP: this->AND(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
@@ -352,13 +357,13 @@ namespace ComSquare::CPU
case Instructions::INX: this->INX(); return 2;
case Instructions::INY: this->INY(); return 2;
- case Instructions::CPX_IM: this->CPX(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
- case Instructions::CPX_ABS: this->CPX(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
- case Instructions::CPX_DP: this->CPX(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
+ case Instructions::CPX_IM: this->CPX(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
+ case Instructions::CPX_ABS: this->CPX(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
+ case Instructions::CPX_DP: this->CPX(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
- case Instructions::CPY_IM: this->CPY(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
- case Instructions::CPY_ABS: this->CPY(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
- case Instructions::CPY_DP: this->CPY(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
+ case Instructions::CPY_IM: this->CPY(this->_getImmediateAddrForX()); return 2 + !this->_registers.p.m;
+ case Instructions::CPY_ABS: this->CPY(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m;
+ case Instructions::CPY_DP: this->CPY(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0;
case Instructions::BCC: return this->BCC(this->_registers.pc++) + 2 + this->_isEmulationMode;
case Instructions::BCS: return this->BCS(this->_registers.pc++) + 2 + this->_isEmulationMode;
@@ -403,183 +408,4 @@ namespace ComSquare::CPU
{
return this->_bus->read(++this->_registers.s) + (this->_bus->read(++this->_registers.s) << 8u);
}
-
- ////////////////////////////////////////////////////////////////////
- /// Addressing modes
- ////////////////////////////////////////////////////////////////////
-
- uint24_t CPU::_getImmediateAddrForA()
- {
- uint24_t effective = this->_registers.pac++;
- if (!this->_registers.p.m)
- this->_registers.pac++;
- return effective;
- }
-
- uint24_t CPU::_getImmediateAddrForX()
- {
- uint24_t effective = this->_registers.pac++;
- if (!this->_registers.p.x_b)
- this->_registers.pac++;
- return effective;
- }
-
- uint24_t CPU::_getDirectAddr()
- {
- uint8_t addr = this->_bus->read(this->_registers.pac++);
- return this->_registers.d + addr;
- }
-
- uint24_t CPU::_getAbsoluteAddr()
- {
- uint24_t addr = this->_registers.dbr << 16u;
- addr += this->_bus->read(this->_registers.pac++);
- addr += this->_bus->read(this->_registers.pac++) << 8u;
- return addr;
- }
-
- uint24_t CPU::_getAbsoluteLongAddr()
- {
- uint24_t addr = this->_bus->read(this->_registers.pac++);
- addr += this->_bus->read(this->_registers.pac++) << 8u;
- addr += this->_bus->read(this->_registers.pac++) << 16u;
- return addr;
- }
-
- uint24_t CPU::_getDirectIndirectIndexedYAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- uint24_t base = this->_bus->read(dp);
- base += this->_bus->read(dp + 1) << 8u;
- base += this->_registers.dbr << 16u;
- if ((base & 0x80000000u) == (((base + this->_registers.y) & 0x80000000u)))
- this->_hasIndexCrossedPageBoundary = true;
- return base + this->_registers.y;
- }
-
- uint24_t CPU::_getDirectIndirectIndexedYLongAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- uint24_t base = this->_bus->read(dp);
- base += this->_bus->read(dp + 1) << 8u;
- base += this->_bus->read(dp + 2) << 16u;
- return base;
- }
-
- uint24_t CPU::_getDirectIndirectIndexedXAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- dp += this->_registers.x;
- uint24_t base = this->_bus->read(dp);
- base += this->_bus->read(dp + 1) << 8u;
- base += this->_registers.dbr << 16u;
- return base;
- }
-
- uint24_t CPU::_getDirectIndexedByXAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- dp += this->_registers.x;
- return dp;
- }
-
- uint24_t CPU::_getDirectIndexedByYAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- dp += this->_registers.y;
- return dp;
- }
-
- uint24_t CPU::_getAbsoluteIndexedByXAddr()
- {
- uint16_t abs = this->_bus->read(this->_registers.pac++);
- abs += this->_bus->read(this->_registers.pac++) << 8u;
- uint24_t effective = abs + (this->_registers.dbr << 16u);
- if ((effective & 0x80000000u) == (((effective + this->_registers.x) & 0x80000000u)))
- this->_hasIndexCrossedPageBoundary = true;
- return effective + this->_registers.x;
- }
-
- uint24_t CPU::_getAbsoluteIndexedByYAddr()
- {
- uint16_t abs = this->_bus->read(this->_registers.pac++);
- abs += this->_bus->read(this->_registers.pac++) << 8u;
- uint24_t effective = abs + (this->_registers.dbr << 16u);
- if ((effective & 0x80000000u) == (((effective + this->_registers.y) & 0x80000000u)))
- this->_hasIndexCrossedPageBoundary = true;
- return effective + this->_registers.y;
- }
-
- uint24_t CPU::_getAbsoluteIndexedByXLongAddr()
- {
- uint24_t lng = this->_bus->read(this->_registers.pac++);
- lng += this->_bus->read(this->_registers.pac++) << 8u;
- lng += this->_bus->read(this->_registers.pac++) << 16u;
- return lng + this->_registers.x;
- }
-
- uint24_t CPU::_getProgramCounterRelativeAddr()
- {
- uint24_t pc = this->_registers.pac;
- int8_t mod = this->_bus->read(this->_registers.pac++);
- return pc + mod;
- }
-
- uint24_t CPU::_getProgramCounterRelativeLongAddr()
- {
- uint24_t pc = this->_registers.pac;
- uint8_t val1 = this->_bus->read(this->_registers.pac++);
- uint8_t val2 = this->_bus->read(this->_registers.pac++);
- int16_t mod = val2 > 0x7F ? (static_cast(val2) * 256 - val1) : (val1 | val2 << 8u);
- return pc + mod;
- }
-
- uint24_t CPU::_getAbsoluteIndirectAddr()
- {
- uint16_t abs = this->_bus->read(this->_registers.pac++);
- abs += this->_bus->read(this->_registers.pac++) << 8u;
- uint24_t effective = this->_bus->read(abs);
- effective += this->_bus->read(abs + 1) << 8u;
- return effective;
- }
-
- uint24_t CPU::_getAbsoluteIndirectIndexedByXAddr()
- {
- uint24_t abs = this->_bus->read(this->_registers.pac++);
- abs += this->_bus->read(this->_registers.pac++) << 8u;
- abs += this->_registers.x;
- uint24_t effective = this->_bus->read(abs);
- effective += this->_bus->read(abs + 1) << 8u;
- return effective;
- }
-
- uint24_t CPU::_getDirectIndirectAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- uint24_t effective = this->_bus->read(dp);
- effective += this->_bus->read(dp + 1) << 8u;
- effective += this->_registers.dbr << 16u;
- return effective;
- }
-
- uint24_t CPU::_getDirectIndirectLongAddr()
- {
- uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
- uint24_t effective = this->_bus->read(dp);
- effective += this->_bus->read(++dp) << 8u;
- effective += this->_bus->read(++dp) << 16u;
- return effective;
- }
-
- uint24_t CPU::_getStackRelativeAddr()
- {
- return this->_bus->read(this->_registers.pac++) + this->_registers.s;
- }
-
- uint24_t CPU::_getStackRelativeIndirectIndexedYAddr()
- {
- uint24_t base = this->_bus->read(this->_registers.pac++) + this->_registers.s;
- base += this->_registers.dbr << 16u;
- return base + this->_registers.y;
- }
}
\ No newline at end of file
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index b3cc6cf..a856962 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -555,7 +555,7 @@ namespace ComSquare::CPU
explicit CPU(std::shared_ptr bus, Cartridge::Header &cartridgeHeader);
CPU(const CPU &) = default;
CPU &operator=(const CPU &) = delete;
- ~CPU() = default;
+ ~CPU() override = default;
//! @brief This function continue to execute the Cartridge code.
//! @return The number of CPU cycles that elapsed
virtual unsigned update();
@@ -572,6 +572,9 @@ namespace ComSquare::CPU
//! @brief Reset interrupt - Called on boot and when the reset button is pressed.
virtual void RESB();
+
+ //! @brief Change the memory bus used by the CPU.
+ void setMemoryBus(std::shared_ptr bus);
};
}
diff --git a/sources/Debugger/CPUDebug.cpp b/sources/Debugger/CPUDebug.cpp
index bb80fe6..77ab9f1 100644
--- a/sources/Debugger/CPUDebug.cpp
+++ b/sources/Debugger/CPUDebug.cpp
@@ -5,33 +5,41 @@
#include "CPUDebug.hpp"
#include "../Utility/Utility.hpp"
#include "../Exceptions/InvalidOpcode.hpp"
+#include
+#include
using namespace ComSquare::CPU;
namespace ComSquare::Debugger
{
CPUDebug::CPUDebug(CPU &basicCPU, SNES &snes)
- : CPU(basicCPU), QMainWindow(), _ui(), _snes(snes)
+ : CPU(basicCPU), _window(new ClosableWindow(this, &CPUDebug::disableDebugger)), _ui(), _snes(snes)
{
- this->setContextMenuPolicy(Qt::NoContextMenu);
- this->setAttribute(Qt::WA_QuitOnClose, false);
+ this->_window->setContextMenuPolicy(Qt::NoContextMenu);
+ this->_window->setAttribute(Qt::WA_QuitOnClose, false);
+ this->_window->setAttribute(Qt::WA_DeleteOnClose);
- this->_ui.setupUi(this);
+ this->_ui.setupUi(this->_window);
QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
QMainWindow::connect(this->_ui.actionStep, &QAction::triggered, this, &CPUDebug::step);
QMainWindow::connect(this->_ui.clear, &QPushButton::released, this, &CPUDebug::clearHistory);
- this->show();
+ this->_window->show();
this->_updateRegistersPanel();
}
+ void CPUDebug::disableDebugger()
+ {
+ this->_snes.disableCPUDebugging();
+ }
+
+ CPUDebug::~CPUDebug()
+ {
+ std::cout << "Destructor" << std::endl;
+ }
+
unsigned CPUDebug::update()
{
try {
- if (!this->isVisible()) {
- this->_snes.disableCPUDebugging();
- return 0;
- }
-
if (this->_isPaused)
return 0xFF;
return CPU::update();
diff --git a/sources/Debugger/CPUDebug.hpp b/sources/Debugger/CPUDebug.hpp
index e40f361..a7219a8 100644
--- a/sources/Debugger/CPUDebug.hpp
+++ b/sources/Debugger/CPUDebug.hpp
@@ -9,12 +9,14 @@
#include "../Renderer/SFRenderer.hpp"
#include "../SNES.hpp"
#include "../../ui/ui_cpu.h"
+#include "ClosableWindow.hpp"
namespace ComSquare::Debugger
{
//! @brief A custom CPU with a window that show it's registers and the disassembly.
- class CPUDebug : public CPU::CPU, public QMainWindow {
+ class CPUDebug : public CPU::CPU, public QObject {
private:
+ ClosableWindow *_window;
//! @brief A widget that contain the whole UI.
Ui::CPUView _ui;
//! @brief If this is set to true, the execution of the CPU will be paused.
@@ -56,6 +58,8 @@ namespace ComSquare::Debugger
void step();
//! @brief Clear the history panel.
void clearHistory();
+ //! @brief Called when the window is closed. Turn off the debugger and revert to a basic CPU.
+ void disableDebugger();
public:
//! @brief Update the UI when reseting the CPU.
void RESB() override;
@@ -63,7 +67,7 @@ namespace ComSquare::Debugger
explicit CPUDebug(ComSquare::CPU::CPU &cpu, SNES &snes);
CPUDebug(const CPUDebug &) = delete;
CPUDebug &operator=(const CPUDebug &) = delete;
- ~CPUDebug() override = default;
+ ~CPUDebug() override;
//! @brief Override the basic cpu's update to allow pausing of the CPU only.
unsigned update() override;
diff --git a/sources/Debugger/ClosableWindow.hpp b/sources/Debugger/ClosableWindow.hpp
new file mode 100644
index 0000000..f87df08
--- /dev/null
+++ b/sources/Debugger/ClosableWindow.hpp
@@ -0,0 +1,34 @@
+//
+// Created by anonymus-raccoon on 3/20/20.
+//
+
+#ifndef COMSQUARE_CLOSABLEWINDOW_HPP
+#define COMSQUARE_CLOSABLEWINDOW_HPP
+
+#include
+
+namespace ComSquare::Debugger
+{
+ template
+ class ClosableWindow : public QMainWindow {
+ protected:
+ void closeEvent(QCloseEvent *) override
+ {
+ (this->_obj->*this->_onClose)();
+ }
+
+ private:
+ T *_obj;
+ void (T::*_onClose)();
+
+ public:
+ explicit ClosableWindow(T *obj, void (T::*onClose)())
+ : _obj(obj), _onClose(onClose)
+ { }
+ ClosableWindow(const ClosableWindow &) = delete;
+ ClosableWindow &operator=(const ClosableWindow &) = delete;
+ ~ClosableWindow() override = default;
+ };
+}
+
+#endif //COMSQUARE_CLOSABLEWINDOW_HPP
diff --git a/sources/Debugger/MemoryBusDebug.cpp b/sources/Debugger/MemoryBusDebug.cpp
new file mode 100644
index 0000000..37168ad
--- /dev/null
+++ b/sources/Debugger/MemoryBusDebug.cpp
@@ -0,0 +1,19 @@
+//
+// Created by anonymus-raccoon on 3/20/20.
+//
+
+#include "MemoryBusDebug.hpp"
+
+namespace ComSquare::Debugger
+{
+ MemoryBusDebug::MemoryBusDebug(const ComSquare::Memory::MemoryBus &bus)
+ : MemoryBus(bus), QMainWindow(), _ui()
+ {
+ this->setContextMenuPolicy(Qt::NoContextMenu);
+ this->setAttribute(Qt::WA_QuitOnClose, false);
+
+ this->_ui.setupUi(this);
+// QMainWindow::connect(this->_ui.actionPause, &QAction::triggered, this, &CPUDebug::pause);
+ this->show();
+ }
+}
\ No newline at end of file
diff --git a/sources/Debugger/MemoryBusDebug.hpp b/sources/Debugger/MemoryBusDebug.hpp
new file mode 100644
index 0000000..e93c6e0
--- /dev/null
+++ b/sources/Debugger/MemoryBusDebug.hpp
@@ -0,0 +1,27 @@
+//
+// Created by anonymus-raccoon on 3/20/20.
+//
+
+#ifndef COMSQUARE_MEMORYBUSDEBUG_HPP
+#define COMSQUARE_MEMORYBUSDEBUG_HPP
+
+#include
+#include "../Memory/MemoryBus.hpp"
+#include "../../ui/ui_busView.h"
+
+namespace ComSquare::Debugger
+{
+ //! @brief window that allow the user to view all data going through the memory bus.
+ class MemoryBusDebug : public Memory::MemoryBus, public QMainWindow {
+ private:
+ //! @brief A widget that contain the whole UI.
+ Ui::BusView _ui;
+ public:
+ explicit MemoryBusDebug(const Memory::MemoryBus &bus);
+ MemoryBusDebug(const MemoryBusDebug &) = delete;
+ MemoryBusDebug &operator=(const MemoryBusDebug &) = delete;
+ ~MemoryBusDebug() override = default;
+ };
+}
+
+#endif //COMSQUARE_MEMORYBUSDEBUG_HPP
diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp
index d029ca0..92d40a6 100644
--- a/sources/PPU/PPU.cpp
+++ b/sources/PPU/PPU.cpp
@@ -10,6 +10,15 @@
namespace ComSquare::PPU
{
+ PPU::PPU(Renderer::IRenderer &renderer):
+ _renderer(renderer),
+ _vram(65536),
+ _oamram(544),
+ _cgram(512)
+ {
+ this->_isLowByte = true;
+ }
+
uint8_t PPU::read(uint24_t addr)
{
switch (addr) {
@@ -235,14 +244,4 @@ namespace ComSquare::PPU
}
this->_renderer.drawScreen();
}
-
- PPU::PPU(const std::shared_ptr &bus, Renderer::IRenderer &renderer):
- _renderer(renderer),
- _bus(std::move(bus)),
- _vram(65536),
- _oamram(544),
- _cgram(512)
- {
- this->_isLowByte = true;
- }
}
\ No newline at end of file
diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp
index 0836011..85ed2aa 100644
--- a/sources/PPU/PPU.hpp
+++ b/sources/PPU/PPU.hpp
@@ -545,12 +545,11 @@ namespace ComSquare::PPU
uint32_t mpy;
} mpy;
Renderer::IRenderer &_renderer;
- std::shared_ptr _bus;
Ram::ExtendedRam _vram;
Ram::ExtendedRam _oamram;
Ram::ExtendedRam _cgram;
public:
- PPU(const std::shared_ptr &bus, Renderer::IRenderer &renderer);
+ PPU(Renderer::IRenderer &renderer);
PPU(const PPU &) = default;
PPU &operator=(const PPU &) = delete;
~PPU() = default;
diff --git a/sources/Renderer/QtRenderer/QtSFML.cpp b/sources/Renderer/QtRenderer/QtSFML.cpp
index a2abe00..9020d62 100644
--- a/sources/Renderer/QtRenderer/QtSFML.cpp
+++ b/sources/Renderer/QtRenderer/QtSFML.cpp
@@ -55,6 +55,10 @@ namespace ComSquare::Renderer
apuDebugger->setShortcut(Qt::Key_F4);
QMainWindow::connect(apuDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableDebugAPU);
debugger->addAction(apuDebugger);
+ QAction *busDebugger = new QAction("Memory bus Viewer", &this->_window);
+ busDebugger->setShortcut(Qt::Key_F5);
+ QMainWindow::connect(busDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableDebugBus);
+ debugger->addAction(busDebugger);
this->_window.show();
}
@@ -110,4 +114,9 @@ namespace ComSquare::Renderer
{
this->_snes.enableAPUDebugging();
}
+
+ void QtFullSFML::enableDebugBus()
+ {
+ this->_snes.enableMemoryBusDebugging();
+ }
}
\ No newline at end of file
diff --git a/sources/Renderer/QtRenderer/QtSFML.hpp b/sources/Renderer/QtRenderer/QtSFML.hpp
index 66096b6..b971b82 100644
--- a/sources/Renderer/QtRenderer/QtSFML.hpp
+++ b/sources/Renderer/QtRenderer/QtSFML.hpp
@@ -31,6 +31,8 @@ namespace ComSquare::Renderer
void enableHeaderViewer();
//! @brief Action called when clicking on the enable APU debugger button.
void enableDebugAPU();
+ //! @brief Action called when clicking on the enable Memory Bus debugger button.
+ void enableDebugBus();
//! @brief Action called when clicking on the reset button.
void reset();
QtFullSFML(SNES &snes, QWidget* parent, const QPoint& position, const QSize& size, int frameRate = 0);
diff --git a/sources/SNES.cpp b/sources/SNES.cpp
index 73d4450..aa5824c 100644
--- a/sources/SNES.cpp
+++ b/sources/SNES.cpp
@@ -8,21 +8,23 @@
#ifdef DEBUGGER_ENABLED
#include "Debugger/CPUDebug.hpp"
#include "Debugger/APUDebug.hpp"
+#include "Debugger/MemoryBusDebug.hpp"
+
#endif
namespace ComSquare
{
- SNES::SNES(const std::shared_ptr &bus, const std::string &romPath, Renderer::IRenderer &renderer) :
- _bus(bus),
+ SNES::SNES(const std::string &romPath, Renderer::IRenderer &renderer) :
+ _bus(std::make_shared()),
cartridge(new Cartridge::Cartridge(romPath)),
wram(new Ram::Ram(16384)),
sram(new Ram::Ram(this->cartridge->header.sramSize)),
apuRam(new APU::MemoryMap()),
- cpu(new CPU::CPU(bus, cartridge->header)),
- ppu(new PPU::PPU(bus, renderer)),
+ cpu(new CPU::CPU(this->_bus, cartridge->header)),
+ ppu(new PPU::PPU(renderer)),
apu(new APU::APU(this->apuRam))
{
- bus->mapComponents(*this);
+ this->_bus->mapComponents(*this);
}
void SNES::enableCPUDebugging()
@@ -43,7 +45,7 @@ namespace ComSquare
void SNES::enableRamViewer()
{
#ifdef DEBUGGER_ENABLED
- this->_ramViewer = std::make_shared(*this, *this->_bus);
+ this->_ramViewer = std::make_unique(*this, *this->_bus);
#endif
}
@@ -64,7 +66,7 @@ namespace ComSquare
void SNES::enableHeaderViewer()
{
#ifdef DEBUGGER_ENABLED
- this->_headerViewer = std::make_shared(*this->cartridge);
+ this->_headerViewer = std::make_unique(*this->cartridge);
#endif
}
@@ -78,9 +80,9 @@ namespace ComSquare
void SNES::enableAPUDebugging()
{
#ifdef DEBUGGER_ENABLED
- this->apu = std::make_shared(*this->apu, *this);
+ this->apu = std::make_shared(*this->apu, *this);
#else
- std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl;
+ std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl;
#endif
}
@@ -88,4 +90,24 @@ namespace ComSquare
{
this->apu = std::make_shared(*this->apu);
}
+
+ void SNES::disableMemoryBusDebugging()
+ {
+ #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
+ }
+
+ void SNES::enableMemoryBusDebugging()
+ {
+ #ifdef DEBUGGER_ENABLED
+ this->_bus = std::make_shared(*this->_bus);
+ this->cpu->setMemoryBus(this->_bus);
+ #else
+ std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl;
+ #endif
+ }
}
diff --git a/sources/SNES.hpp b/sources/SNES.hpp
index 5fc5846..b9a2025 100644
--- a/sources/SNES.hpp
+++ b/sources/SNES.hpp
@@ -25,10 +25,12 @@ namespace ComSquare
private:
#ifdef DEBUGGER_ENABLED
//! @brief The window that allow the user to view a memory.
- std::shared_ptr _ramViewer;
+ std::unique_ptr _ramViewer;
//! @brief The window that allow the user to view the cartridge's header.
- std::shared_ptr _headerViewer;
+ std::unique_ptr _headerViewer;
+// std::unique_ptr _bus;
public:
//! @brief Cartridge containing instructions (ROM).
@@ -65,11 +67,15 @@ namespace ComSquare
void disableAPUDebugging();
//! @brief Enable the APU's debugging window.
void enableAPUDebugging();
+ //! @brief Disable the Memory Bus's debugging window.
+ void disableMemoryBusDebugging();
+ //! @brief Enable the Memory Bus's debugging window.
+ void enableMemoryBusDebugging();
//! @brief Create all the components using a common memory bus for all of them.
- SNES(const std::shared_ptr &bus, const std::string &ramPath, Renderer::IRenderer &renderer);
+ SNES(const std::string &ramPath, Renderer::IRenderer &renderer);
SNES(const SNES &) = default;
- SNES &operator=(const SNES &) = default;
+ SNES &operator=(const SNES &) = delete;
~SNES() = default;
};
}
diff --git a/main.cpp b/sources/main.cpp
similarity index 52%
rename from main.cpp
rename to sources/main.cpp
index a2bb748..ed678cd 100644
--- a/main.cpp
+++ b/sources/main.cpp
@@ -5,15 +5,21 @@
#include
#include
#include
-#include "sources/SNES.hpp"
-#include "sources/Renderer/SFRenderer.hpp"
-#include "sources/Renderer/QtRenderer/QtSFML.hpp"
+#include "SNES.hpp"
+#include "Renderer/SFRenderer.hpp"
+#include "Renderer/QtRenderer/QtSFML.hpp"
using namespace ComSquare;
void usage(char *bin)
{
- std::cout << "ComSquare:" << std::endl << "\tUsage: " << bin << " rom_path" << std::endl;
+ std::cout << "ComSquare:" << std::endl
+ << "\tUsage: " << bin << " rom_path [options]" << std::endl
+ << "Options:" << std::endl
+ << "\t-c, --cpu: \tEnable the debugger of the CPU." << std::endl
+ << "\t-m, --memory: \tEnable the memory viewer panel." << std::endl
+ << "\t-h, --header: \tShow the header of the cartridge." << std::endl
+ << "\t-b, --bus: \tShow the memory bus's log." << std::endl;
}
void parseArguments(int argc, char **argv, SNES &snes)
@@ -21,13 +27,14 @@ void parseArguments(int argc, char **argv, SNES &snes)
while (true) {
int option_index = 0;
static struct option long_options[] = {
- {"cpu", no_argument, 0, 'c' },
- {"memory", no_argument, 0, 'm' },
- {"header", no_argument, 0, 'h' },
- {0, 0, 0, 0 }
+ {"cpu", no_argument, 0, 'c'},
+ {"memory", no_argument, 0, 'm'},
+ {"header", no_argument, 0, 'h'},
+ {"bus", no_argument, 0, 'b'},
+ {0, 0, 0, 0}
};
- char c = getopt_long(argc, argv, "cmh", long_options, &option_index);
+ int c = getopt_long(argc, argv, "cmh", long_options, &option_index);
if (c == -1)
break;
switch (c) {
@@ -43,6 +50,9 @@ void parseArguments(int argc, char **argv, SNES &snes)
case 'h':
snes.enableHeaderViewer();
break;
+ case 'b':
+ snes.enableMemoryBusDebugging();
+ break;
default:
break;
}
@@ -58,7 +68,7 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
QApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
Renderer::QtSFML renderer(600, 800);
- SNES snes(std::make_shared(), argv[1], renderer);
+ SNES snes(argv[1], renderer);
renderer.createWindow(snes, 60);
parseArguments(argc, argv, snes);
return QApplication::exec();
diff --git a/tests/tests.cpp b/tests/tests.cpp
index c9a3bd7..5864663 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -13,14 +13,12 @@ using namespace ComSquare;
std::pair, SNES> Init()
{
- std::shared_ptr bus = std::make_shared();
Renderer::NoRenderer norenderer(0, 0, 0);
- SNES snes(bus, "../tests/my_cartridge", norenderer);
+ SNES snes("../tests/my_cartridge", norenderer);
snes.cartridge->_size = 100;
snes.cartridge->_data = new uint8_t[snes.cartridge->_size];
snes.cartridge->header.mappingMode = Cartridge::LoRom;
snes.sram->_size = 100;
snes.sram->_data = new uint8_t[snes.cartridge->_size];
-// bus->mapComponents(snes);
- return std::make_pair(bus, snes);
+ return std::make_pair(snes._bus, snes);
}
\ No newline at end of file
diff --git a/ui/busView.ui b/ui/busView.ui
index cddaee3..2b700d8 100644
--- a/ui/busView.ui
+++ b/ui/busView.ui
@@ -1,7 +1,7 @@
- MainWindow
-
+ BusView
+
0