From 291426a3928a2ffe86176ec9fe6f23d177471fab Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Wed, 27 May 2020 18:52:11 +0200
Subject: [PATCH 01/30] Handling a basic DMA
---
sources/CPU/CPU.cpp | 20 ++++++++++++++------
sources/CPU/CPU.hpp | 3 ---
sources/CPU/DMA/DMA.cpp | 42 +++++++++++++++++++++++++++++++++++++++--
sources/CPU/DMA/DMA.hpp | 39 ++++++++++++++++++++++++++++++--------
4 files changed, 85 insertions(+), 19 deletions(-)
diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp
index e507265..5962413 100644
--- a/sources/CPU/CPU.cpp
+++ b/sources/CPU/CPU.cpp
@@ -12,9 +12,12 @@
namespace ComSquare::CPU
{
CPU::CPU(std::shared_ptr bus, Cartridge::Header &cartridgeHeader)
- : _bus(std::move(bus)), _cartridgeHeader(cartridgeHeader)
+ : _bus(std::move(bus)),
+ _cartridgeHeader(cartridgeHeader)
{
this->RESB();
+ for (DMA &channel : this->_dmaChannels)
+ channel.setBus(_bus);
}
bool CPU::isDebugger()
@@ -30,6 +33,8 @@ namespace ComSquare::CPU
//! @bref The CPU's internal registers starts at $4200 and finish at $421F.
uint8_t CPU::read(uint24_t addr)
{
+ uint8_t tmp = 0;
+
switch (addr) {
case 0x0:
return this->_internalRegisters.nmitimen;
@@ -54,7 +59,9 @@ namespace ComSquare::CPU
case 0xA:
return this->_internalRegisters.vtimeh;
case 0xB:
- return this->_internalRegisters.dmaEnableRegister;
+ for (int i = 0; i < 8; i++)
+ tmp |= this->_dmaChannels[i].enabled << i;
+ return tmp;
case 0xC:
return this->_internalRegisters.hdmaen;
case 0xD:
@@ -135,7 +142,8 @@ namespace ComSquare::CPU
this->_internalRegisters.vtimeh = data;
break;
case 0xB:
- this->_internalRegisters.dmaEnableRegister = data;
+ for (int i = 0; i < 8; i++)
+ this->_dmaChannels[i].enabled = data & (0b1 << i);
break;
case 0xC:
this->_internalRegisters.hdmaen = data;
@@ -211,10 +219,10 @@ namespace ComSquare::CPU
unsigned cycles = 0;
const unsigned maxCycles = 0x17;
- for (int i = 0; i < 8; i++) {
- if (!(this->_internalRegisters.dmaEnableRegister & (0xF << i)))
+ for (DMA &channel : this->_dmaChannels) {
+ if (!channel.enabled)
continue;
- cycles += this->_dmaChannels[i].run(maxCycles - cycles);
+ cycles += channel.run(maxCycles - cycles);
}
for (unsigned i = 0; i < maxCycles; i++) {
if (this->_isStopped) {
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index f4af358..8aec2fa 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -131,9 +131,6 @@ namespace ComSquare::CPU
//! @brief IRQ Timer Registers (Vertical - High)
uint8_t vtimeh;
- //! @brief DMA Enable Register
- uint8_t dmaEnableRegister;
-
//! @brief HDMA Enable Register
uint8_t hdmaen;
diff --git a/sources/CPU/DMA/DMA.cpp b/sources/CPU/DMA/DMA.cpp
index eda81d6..a9eee1d 100644
--- a/sources/CPU/DMA/DMA.cpp
+++ b/sources/CPU/DMA/DMA.cpp
@@ -7,6 +7,13 @@
namespace ComSquare::CPU
{
+ DMA::DMA(std::shared_ptr bus) : _bus(std::move(bus)) {}
+
+ void DMA::setBus(std::shared_ptr bus)
+ {
+ this->_bus = std::move(bus);
+ }
+
uint8_t DMA::read(uint8_t addr)
{
switch (addr) {
@@ -58,8 +65,39 @@ namespace ComSquare::CPU
}
}
- uint8_t DMA::run(unsigned int cycles)
+ unsigned DMA::_writeOneByte()
{
- return 0;
+ // 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.
+ if (this->port == 0x80) {
+ auto accessor = this->_bus->getAccessor(this->aAddress.raw);
+ if (accessor && accessor->getComponent() == WRam) {
+ if (this->controlRegister.direction == AToB)
+ return 8;
+ this->_bus->write(this->aAddress.raw, 0xFF);
+ return 4;
+ }
+ }
+ if (this->controlRegister.direction == AToB) {
+ uint8_t data = this->_bus->read(this->aAddress.raw);
+ this->_bus->write(0x2100 | this->port, data);
+ } else {
+ uint8_t data = this->_bus->read(0x2100 | this->port);
+ this->_bus->write(this->aAddress.raw, data);
+ }
+ return 8;
+ }
+
+ uint8_t DMA::run(unsigned int maxCycles)
+ {
+ unsigned cycles = 8;
+
+ do {
+ cycles += this->_writeOneByte();
+ if (!this->controlRegister.fixed)
+ this->aAddress.page += this->controlRegister.increment ? -1 : 1;
+ this->count.raw--;
+ } while (this->count.raw > 0 && cycles < maxCycles);
+ this->enabled = false;
+ return cycles;
}
}
\ No newline at end of file
diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp
index f152757..da9e8be 100644
--- a/sources/CPU/DMA/DMA.hpp
+++ b/sources/CPU/DMA/DMA.hpp
@@ -6,7 +6,9 @@
#define COMSQUARE_DMA_HPP
#include
+#include
#include "../../Models/Int24.hpp"
+#include "../../Memory/MemoryBus.hpp"
namespace ComSquare::CPU
{
@@ -24,22 +26,31 @@ namespace ComSquare::CPU
FourToFour = 0b100
};
+ enum Direction {
+ AToB,
+ BToA
+ };
+
//! @brief Class handling all DMA/HDMA transfers (Direct Memory Access or H-Blank Direct Memory Access)
class DMA {
+ private:
+ //! @brief Write one byte using the A address, the port and the direction. Handle special cases where no write occurs.
+ //! @return The number of cycles used.
+ unsigned _writeOneByte();
public:
//! @brief DMA Control register (various information about the transfer)
union {
struct {
- //! @brief The direction of the transfer (0: CPU to PPU aka A to B, 1: PPU to CPU aka B to A).
- bool direction: 1;
- //! @brief Two unused bites.
- bool _: 2;
- //! @brief if this flag is 0: increment. Else: decrement. (The A address)
- bool increment: 1;
+ //! @brief DMA's mode: how many bytes/registers there is, how many writes...
+ DMAMode mode: 3;
//! @brief If this flag is set, no increment/decrement will be done.
bool fixed: 1;
- //! @brief DMA's mode: how many bytes/registers there is, how many writes...
- enum DMAMode mode: 3;
+ //! @brief if this flag is 0: increment. Else: decrement. (The A address)
+ bool increment: 1;
+ //! @brief Two unused bites.
+ bool _: 2;
+ //! @brief The direction of the transfer.
+ Direction direction: 1;
};
uint8_t raw;
} controlRegister;
@@ -48,6 +59,10 @@ namespace ComSquare::CPU
//! @brief The absolute long address of the data from the A bus.
union {
uint8_t bytes[3];
+ struct {
+ uint16_t page;
+ uint8_t bank;
+ };
uint24_t raw: 24;
} aAddress;
//! @brief The number of bytes to be transferred.
@@ -55,6 +70,13 @@ namespace ComSquare::CPU
uint8_t bytes[2];
uint16_t raw;
} count;
+ //! @brief Is this channel set to run?
+ bool enabled;
+
+ //! @brief The memory bus to use for read/write.
+ std::shared_ptr _bus;
+ //! @brief Set the memory bus used by this dma channel.
+ void setBus(std::shared_ptr bus);
//! @brief Bus helper to read from this channel.
uint8_t read(uint8_t addr);
@@ -67,6 +89,7 @@ namespace ComSquare::CPU
uint8_t run(unsigned cycles);
DMA() = default;
+ DMA(std::shared_ptr bus);
DMA(const DMA &) = default;
DMA &operator=(const DMA &) = default;
~DMA() = default;
From 5ef1ba8d4fbfea0bd5ae1cd16437422f99b8ef2b Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 28 May 2020 01:17:45 +0200
Subject: [PATCH 02/30] Handling DMA's modes
---
sources/CPU/DMA/DMA.cpp | 35 +++++++++++++++++++++++++++--------
sources/CPU/DMA/DMA.hpp | 4 +++-
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/sources/CPU/DMA/DMA.cpp b/sources/CPU/DMA/DMA.cpp
index a9eee1d..3d21402 100644
--- a/sources/CPU/DMA/DMA.cpp
+++ b/sources/CPU/DMA/DMA.cpp
@@ -65,24 +65,24 @@ namespace ComSquare::CPU
}
}
- unsigned DMA::_writeOneByte()
+ unsigned DMA::_writeOneByte(uint24_t aAddress, uint24_t bAddress)
{
// 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.
if (this->port == 0x80) {
- auto accessor = this->_bus->getAccessor(this->aAddress.raw);
+ auto accessor = this->_bus->getAccessor(aAddress);
if (accessor && accessor->getComponent() == WRam) {
if (this->controlRegister.direction == AToB)
return 8;
- this->_bus->write(this->aAddress.raw, 0xFF);
+ this->_bus->write(aAddress, 0xFF);
return 4;
}
}
if (this->controlRegister.direction == AToB) {
- uint8_t data = this->_bus->read(this->aAddress.raw);
- this->_bus->write(0x2100 | this->port, data);
+ uint8_t data = this->_bus->read(aAddress);
+ this->_bus->write(bAddress, data);
} else {
- uint8_t data = this->_bus->read(0x2100 | this->port);
- this->_bus->write(this->aAddress.raw, data);
+ uint8_t data = this->_bus->read(bAddress);
+ this->_bus->write(aAddress, data);
}
return 8;
}
@@ -90,14 +90,33 @@ namespace ComSquare::CPU
uint8_t DMA::run(unsigned int maxCycles)
{
unsigned cycles = 8;
+ int i = 0;
do {
- cycles += this->_writeOneByte();
+ cycles += this->_writeOneByte(this->aAddress.raw, 0x2100 | this->port + this->getModeOffset(i));
if (!this->controlRegister.fixed)
this->aAddress.page += this->controlRegister.increment ? -1 : 1;
this->count.raw--;
+ i++;
} while (this->count.raw > 0 && cycles < maxCycles);
this->enabled = false;
return cycles;
}
+
+ int DMA::getModeOffset(int index)
+ {
+ switch (this->controlRegister.mode) {
+ case OneToOne:
+ return 0;
+ case TwoToTwo:
+ return index % 2;
+ case TwoToOne:
+ return 0;
+ case FourToTwo:
+ return (index & 0b11) > 1;
+ case FourToFour:
+ return (index & 0b11);
+ }
+ return 0;
+ }
}
\ No newline at end of file
diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp
index da9e8be..1daaf86 100644
--- a/sources/CPU/DMA/DMA.hpp
+++ b/sources/CPU/DMA/DMA.hpp
@@ -36,7 +36,9 @@ namespace ComSquare::CPU
private:
//! @brief Write one byte using the A address, the port and the direction. Handle special cases where no write occurs.
//! @return The number of cycles used.
- unsigned _writeOneByte();
+ unsigned _writeOneByte(uint24_t aAddress, uint24_t bAddress);
+ //! @brief Get an offset corresponding to the current DMAMode and the index of the currently transferred byte.
+ int getModeOffset(int index);
public:
//! @brief DMA Control register (various information about the transfer)
union {
From 627fac8f2df00e2a8478762e310e5943b674808e Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 28 May 2020 03:45:37 +0200
Subject: [PATCH 03/30] Fixing the PHA
---
sources/CPU/CPU.hpp | 2 +-
sources/CPU/Instructions/InternalInstruction.cpp | 5 ++++-
sources/PPU/PPU.cpp | 4 ++--
tests/CPU/testInternal.cpp | 12 ++++++++++++
4 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index 8aec2fa..f2afc1b 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -478,7 +478,7 @@ namespace ComSquare::CPU
{&CPU::ORA, 3, "ora", AddressingMode::DirectPage, 2}, // 05
{&CPU::ASL, 5, "asl", AddressingMode::DirectPage, 2}, // 06
{&CPU::ORA, 6, "ora", AddressingMode::DirectPageIndirectLong, 2}, // 07
- {&CPU::PHP, 3, "php", AddressingMode::Implied, 3}, // 08
+ {&CPU::PHP, 3, "php", AddressingMode::Implied, 1}, // 08
{&CPU::ORA, 2, "ora", AddressingMode::ImmediateForA, 2}, // 09
{&CPU::ASL, 2, "asl", AddressingMode::Implied, 1}, // 0A
{&CPU::PHD, 4, "phd", AddressingMode::Implied, 1}, // 0B
diff --git a/sources/CPU/Instructions/InternalInstruction.cpp b/sources/CPU/Instructions/InternalInstruction.cpp
index 8430522..03fb101 100644
--- a/sources/CPU/Instructions/InternalInstruction.cpp
+++ b/sources/CPU/Instructions/InternalInstruction.cpp
@@ -82,7 +82,10 @@ namespace ComSquare::CPU
int CPU::PHA(uint24_t, AddressingMode)
{
- this->_push(this->_registers.a);
+ if (this->_registers.p.m)
+ this->_push(this->_registers.al);
+ else
+ this->_push(this->_registers.a);
return !this->_registers.p.m;
}
diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp
index c0a5661..9075adc 100644
--- a/sources/PPU/PPU.cpp
+++ b/sources/PPU/PPU.cpp
@@ -45,7 +45,7 @@ namespace ComSquare::PPU
case ppuRegisters::stat78:
return 0;
default:
- throw InvalidAddress("PPU Internal Registers read ", addr);
+ throw InvalidAddress("PPU Internal Registers read ", addr + this->getStart());
}
}
@@ -215,7 +215,7 @@ namespace ComSquare::PPU
break;
//TODO adding the rest of the registers. oaf !
default:
- throw InvalidAddress("PPU Internal Registers write", addr);
+ throw InvalidAddress("PPU Internal Registers write", addr + this->getStart());
}
}
diff --git a/tests/CPU/testInternal.cpp b/tests/CPU/testInternal.cpp
index 63f6f5c..5b38be7 100644
--- a/tests/CPU/testInternal.cpp
+++ b/tests/CPU/testInternal.cpp
@@ -105,12 +105,24 @@ Test(PHA, basic)
Init()
snes.cpu->_registers.a = 0xABCD;
snes.cpu->_registers.s = 0x02;
+ snes.cpu->_registers.p.m = false;
snes.cpu->PHA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.wram->_data[1], 0xCD, "The second value pushed to the stack should be 0xCD but it was %x", snes.wram->_data[1]);
cr_assert_eq(snes.wram->_data[2], 0xAB, "The first value pushed to the stack should be 0xAB but it was %x", snes.wram->_data[2]);
cr_assert_eq(snes.cpu->_registers.s, 0x0, "The Stack pointer should be equal to 0x0 but it was %x", snes.cpu->_registers.s);
}
+Test(PHA, 8bits)
+{
+ Init()
+ snes.cpu->_registers.a = 0xCD;
+ snes.cpu->_registers.s = 0x02;
+ snes.cpu->_registers.p.m = false;
+ snes.cpu->PHA(0x0, ComSquare::CPU::AddressingMode::Implied);
+ cr_assert_eq(snes.wram->_data[1], 0xCD, "The second value pushed to the stack should be 0xCD but it was %x", snes.wram->_data[1]);
+ cr_assert_eq(snes.cpu->_registers.s, 0x0, "The Stack pointer should be equal to 0x0 but it was %x", snes.cpu->_registers.s);
+}
+
Test(PHB, basic)
{
Init()
From 29540ce9db81a11f0369f35a6029b9caadc6fd45 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 28 May 2020 04:53:16 +0200
Subject: [PATCH 04/30] Cleaning up
---
sources/CPU/DMA/DMA.cpp | 50 +++++++++++++++++++++--------------------
sources/CPU/DMA/DMA.hpp | 21 +++++++++--------
2 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/sources/CPU/DMA/DMA.cpp b/sources/CPU/DMA/DMA.cpp
index 3d21402..5815b67 100644
--- a/sources/CPU/DMA/DMA.cpp
+++ b/sources/CPU/DMA/DMA.cpp
@@ -2,6 +2,7 @@
// Created by anonymus-raccoon on 5/26/20.
//
+#include
#include "DMA.hpp"
#include "../../Exceptions/InvalidAddress.hpp"
@@ -18,19 +19,19 @@ namespace ComSquare::CPU
{
switch (addr) {
case 0x0:
- return this->controlRegister.raw;
+ return this->_controlRegister.raw;
case 0x1:
- return this->port;
+ return this->_port;
case 0x2:
- return this->aAddress.bytes[0];
+ return this->_aAddress.bytes[0];
case 0x3:
- return this->aAddress.bytes[1];
+ return this->_aAddress.bytes[1];
case 0x4:
- return this->aAddress.bytes[2];
+ return this->_aAddress.bytes[2];
case 0x5:
- return this->count.bytes[0];
+ return this->_count.bytes[0];
case 0x6:
- return this->count.bytes[1];
+ return this->_count.bytes[1];
default:
throw InvalidAddress("DMA read", addr);
}
@@ -40,25 +41,25 @@ namespace ComSquare::CPU
{
switch (addr) {
case 0x0:
- this->controlRegister.raw = data;
+ this->_controlRegister.raw = data;
break;
case 0x1:
- this->port = data;
+ this->_port = data;
break;
case 0x2:
- this->aAddress.bytes[0] = data;
+ this->_aAddress.bytes[0] = data;
break;
case 0x3:
- this->aAddress.bytes[1] = data;
+ this->_aAddress.bytes[1] = data;
break;
case 0x4:
- this->aAddress.bytes[2] = data;
+ this->_aAddress.bytes[2] = data;
break;
case 0x5:
- this->count.bytes[0] = data;
+ this->_count.bytes[0] = data;
break;
case 0x6:
- this->count.bytes[1] = data;
+ this->_count.bytes[1] = data;
break;
default:
throw InvalidAddress("DMA read", addr);
@@ -68,16 +69,16 @@ namespace ComSquare::CPU
unsigned DMA::_writeOneByte(uint24_t aAddress, uint24_t bAddress)
{
// 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.
- if (this->port == 0x80) {
+ if (this->_port == 0x80) {
auto accessor = this->_bus->getAccessor(aAddress);
if (accessor && accessor->getComponent() == WRam) {
- if (this->controlRegister.direction == AToB)
+ if (this->_controlRegister.direction == AToB)
return 8;
this->_bus->write(aAddress, 0xFF);
return 4;
}
}
- if (this->controlRegister.direction == AToB) {
+ if (this->_controlRegister.direction == AToB) {
uint8_t data = this->_bus->read(aAddress);
this->_bus->write(bAddress, data);
} else {
@@ -91,21 +92,22 @@ namespace ComSquare::CPU
{
unsigned cycles = 8;
int i = 0;
+ std::cout << "Starting a DMA transfer" << std::endl;
do {
- cycles += this->_writeOneByte(this->aAddress.raw, 0x2100 | this->port + this->getModeOffset(i));
- if (!this->controlRegister.fixed)
- this->aAddress.page += this->controlRegister.increment ? -1 : 1;
- this->count.raw--;
+ cycles += this->_writeOneByte(this->_aAddress.raw, 0x2100 | (this->_port + this->_getModeOffset(i)));
+ if (!this->_controlRegister.fixed)
+ this->_aAddress.page += this->_controlRegister.increment ? -1 : 1;
+ this->_count.raw--;
i++;
- } while (this->count.raw > 0 && cycles < maxCycles);
+ } while (this->_count.raw > 0);
this->enabled = false;
return cycles;
}
- int DMA::getModeOffset(int index)
+ int DMA::_getModeOffset(int index)
{
- switch (this->controlRegister.mode) {
+ switch (this->_controlRegister.mode) {
case OneToOne:
return 0;
case TwoToTwo:
diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp
index 1daaf86..caa2dcb 100644
--- a/sources/CPU/DMA/DMA.hpp
+++ b/sources/CPU/DMA/DMA.hpp
@@ -34,12 +34,12 @@ namespace ComSquare::CPU
//! @brief Class handling all DMA/HDMA transfers (Direct Memory Access or H-Blank Direct Memory Access)
class DMA {
private:
- //! @brief Write one byte using the A address, the port and the direction. Handle special cases where no write occurs.
+ //! @brief Write one byte using the A address, the port and the _direction. Handle special cases where no write occurs.
//! @return The number of cycles used.
unsigned _writeOneByte(uint24_t aAddress, uint24_t bAddress);
//! @brief Get an offset corresponding to the current DMAMode and the index of the currently transferred byte.
- int getModeOffset(int index);
- public:
+ int _getModeOffset(int index);
+
//! @brief DMA Control register (various information about the transfer)
union {
struct {
@@ -55,9 +55,9 @@ namespace ComSquare::CPU
Direction direction: 1;
};
uint8_t raw;
- } controlRegister;
+ } _controlRegister;
//! @brief If this is 'xx', the register accessed will be $21xx.
- uint8_t port;
+ uint8_t _port;
//! @brief The absolute long address of the data from the A bus.
union {
uint8_t bytes[3];
@@ -66,17 +66,20 @@ namespace ComSquare::CPU
uint8_t bank;
};
uint24_t raw: 24;
- } aAddress;
+ } _aAddress;
//! @brief The number of bytes to be transferred.
union {
uint8_t bytes[2];
uint16_t raw;
- } count;
- //! @brief Is this channel set to run?
- bool enabled;
+ } _count;
//! @brief The memory bus to use for read/write.
std::shared_ptr _bus;
+
+ public:
+ //! @brief Is this channel set to run?
+ bool enabled;
+
//! @brief Set the memory bus used by this dma channel.
void setBus(std::shared_ptr bus);
From 5e0f6104fe4851cf8ad2b302eba2a65489b173be Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 28 May 2020 14:13:12 +0200
Subject: [PATCH 05/30] Creating the layout of a DMA viewer
---
CMakeLists.txt | 17 +++-
sources/Debugger/CPU/CPUDebug.hpp | 2 +-
sources/Debugger/CPU/DMA/DMADebug.cpp | 32 +++++++
sources/Debugger/CPU/DMA/DMADebug.hpp | 43 +++++++++
sources/Renderer/QtRenderer/QtSFML.cpp | 17 ++++
sources/Renderer/QtRenderer/QtSFML.hpp | 4 +
sources/SNES.cpp | 17 ++++
sources/SNES.hpp | 7 ++
ui/{cpu.ui => cpuView.ui} | 0
ui/dmaView.ui | 125 +++++++++++++++++++++++++
ui/{ui_cpu.h => ui_cpuView.h} | 12 +--
11 files changed, 264 insertions(+), 12 deletions(-)
create mode 100644 sources/Debugger/CPU/DMA/DMADebug.cpp
create mode 100644 sources/Debugger/CPU/DMA/DMADebug.hpp
rename ui/{cpu.ui => cpuView.ui} (100%)
create mode 100644 ui/dmaView.ui
rename ui/{ui_cpu.h => ui_cpuView.h} (98%)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d2f7462..2a26978 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,7 +99,11 @@ add_executable(unit_tests
tests/testRectangleMemory.cpp
tests/CPU/Math/testCMP.cpp
sources/PPU/Backgrounds.cpp
- sources/PPU/Background.cpp sources/PPU/Background.hpp sources/CPU/DMA/DMA.cpp sources/CPU/DMA/DMA.hpp)
+ sources/PPU/Background.cpp
+ sources/PPU/Background.hpp
+ sources/CPU/DMA/DMA.cpp
+ sources/CPU/DMA/DMA.hpp
+)
# include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov)
@@ -169,7 +173,7 @@ add_executable(ComSquare
sources/Renderer/QtRenderer/QtSFML.hpp
sources/Renderer/QtRenderer/QtWidgetSFML.cpp
sources/Renderer/QtRenderer/QtWidgetSFML.hpp
- ui/cpu.ui
+ ui/cpuView.ui
ui/ramView.ui
ui/cartridgeView.ui
ui/apuView.ui
@@ -215,7 +219,14 @@ add_executable(ComSquare
sources/Debugger/CGramDebug.hpp
sources/Models/Vector2.hpp
sources/PPU/Backgrounds.cpp
- sources/PPU/Background.cpp sources/PPU/Background.hpp sources/CPU/DMA/DMA.cpp sources/CPU/DMA/DMA.hpp)
+ sources/PPU/Background.cpp
+ sources/PPU/Background.hpp
+ sources/CPU/DMA/DMA.cpp
+ sources/CPU/DMA/DMA.hpp
+ sources/Debugger/CPU/DMA/DMADebug.cpp
+ sources/Debugger/CPU/DMA/DMADebug.hpp
+ ui/dmaView.ui
+)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
diff --git a/sources/Debugger/CPU/CPUDebug.hpp b/sources/Debugger/CPU/CPUDebug.hpp
index db00d37..69d3e0e 100644
--- a/sources/Debugger/CPU/CPUDebug.hpp
+++ b/sources/Debugger/CPU/CPUDebug.hpp
@@ -9,7 +9,7 @@
#include "../../CPU/CPU.hpp"
#include "../../Renderer/SFRenderer.hpp"
#include "../../SNES.hpp"
-#include "../../../ui/ui_cpu.h"
+#include "../../../ui/ui_cpuView.h"
#include "../ClosableWindow.hpp"
namespace ComSquare::Debugger
diff --git a/sources/Debugger/CPU/DMA/DMADebug.cpp b/sources/Debugger/CPU/DMA/DMADebug.cpp
new file mode 100644
index 0000000..4222c97
--- /dev/null
+++ b/sources/Debugger/CPU/DMA/DMADebug.cpp
@@ -0,0 +1,32 @@
+//
+// Created by anonymus-raccoon on 5/28/20.
+//
+
+#include "DMADebug.hpp"
+#include "../../../SNES.hpp"
+
+namespace ComSquare::Debugger
+{
+ DMADebug::DMADebug(SNES &snes)
+ : _window(new ClosableWindow(*this, &DMADebug::disableDebugger)),
+ _ui(),
+ _snes(snes)
+ {
+ this->_window->setContextMenuPolicy(Qt::NoContextMenu);
+ this->_window->setAttribute(Qt::WA_QuitOnClose, false);
+ this->_window->setAttribute(Qt::WA_DeleteOnClose);
+
+ this->_ui.setupUi(this->_window);
+ this->_window->show();
+ }
+
+ void DMADebug::focus()
+ {
+ this->_window->activateWindow();
+ }
+
+ void DMADebug::disableDebugger()
+ {
+ this->_snes.disableDMADebugging();
+ }
+}
\ No newline at end of file
diff --git a/sources/Debugger/CPU/DMA/DMADebug.hpp b/sources/Debugger/CPU/DMA/DMADebug.hpp
new file mode 100644
index 0000000..6bf2aa0
--- /dev/null
+++ b/sources/Debugger/CPU/DMA/DMADebug.hpp
@@ -0,0 +1,43 @@
+//
+// Created by anonymus-raccoon on 5/28/20.
+//
+
+#ifndef COMSQUARE_DMADEBUG_HPP
+#define COMSQUARE_DMADEBUG_HPP
+
+#include
+#include "../../ClosableWindow.hpp"
+#include "../../../../ui/ui_dmaView.h"
+
+namespace ComSquare
+{
+ class SNES;
+
+ namespace Debugger
+ {
+ class DMADebug : public QObject {
+ private:
+ //! @brief The QT window for this debugger.
+ ClosableWindow *_window;
+ //! @brief A widget that contain the whole UI.
+ Ui::DMAView _ui;
+
+ //! @brief The snes instance to read/write to DMA channels.
+ SNES &_snes;
+ public:
+ //! @brief Called when the window is closed. Turn off the debugger.
+ void disableDebugger();
+
+ explicit DMADebug(SNES &snes);
+ DMADebug(
+ const DMADebug &) = delete;
+ DMADebug &operator=(const DMADebug &) = delete;
+ ~DMADebug() =default;
+
+ //! @brief Focus the debugger's window.
+ void focus();
+ };
+ };
+}
+
+#endif //COMSQUARE_DMADEBUG_HPP
diff --git a/sources/Renderer/QtRenderer/QtSFML.cpp b/sources/Renderer/QtRenderer/QtSFML.cpp
index 760bfd8..8c234a4 100644
--- a/sources/Renderer/QtRenderer/QtSFML.cpp
+++ b/sources/Renderer/QtRenderer/QtSFML.cpp
@@ -41,32 +41,44 @@ namespace ComSquare::Renderer
QMainWindow::connect(reset, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::reset);
game->addAction(reset);
+
+
QMenu *debugger = this->_window.menuBar()->addMenu("&Debugger");
QAction *cpuDebugger = new QAction("CPU's Debugger", &this->_window);
cpuDebugger->setShortcut(Qt::Key_F1);
QMainWindow::connect(cpuDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableDebugCPU);
debugger->addAction(cpuDebugger);
+
QAction *ramViewer = new QAction("Memory viewer", &this->_window);
ramViewer->setShortcut(Qt::Key_F2);
QMainWindow::connect(ramViewer, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableRamViewer);
debugger->addAction(ramViewer);
+
QAction *headerViewer = new QAction("Header viewer", &this->_window);
headerViewer->setShortcut(Qt::Key_F3);
QMainWindow::connect(headerViewer, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableHeaderViewer);
debugger->addAction(headerViewer);
+
QAction *apuDebugger = new QAction("APU's Debugger", &this->_window);
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);
+
QAction *cgramDebugger = new QAction("Palette Viewer", &this->_window);
cgramDebugger->setShortcut(Qt::Key_F6);
QMainWindow::connect(cgramDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableCgramViewer);
debugger->addAction(cgramDebugger);
+ QAction *dmaDebugger = new QAction("DMA Viewer", &this->_window);
+ dmaDebugger->setShortcut(Qt::Key_F7);
+ QMainWindow::connect(dmaDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableDMAViewer);
+ debugger->addAction(dmaDebugger);
+
this->_window.show();
}
@@ -134,4 +146,9 @@ namespace ComSquare::Renderer
{
this->_snes.enableCgramDebugging();
}
+
+ void QtFullSFML::enableDMAViewer()
+ {
+ this->_snes.enableDMADebugging();
+ }
}
\ No newline at end of file
diff --git a/sources/Renderer/QtRenderer/QtSFML.hpp b/sources/Renderer/QtRenderer/QtSFML.hpp
index 661422c..fc9d45a 100644
--- a/sources/Renderer/QtRenderer/QtSFML.hpp
+++ b/sources/Renderer/QtRenderer/QtSFML.hpp
@@ -35,8 +35,12 @@ namespace ComSquare::Renderer
void enableDebugBus();
//! @brief Action called when clicking on the enable Palette viewer button.
void enableCgramViewer();
+ //! @brief Action called when clicking on the enable DMA viewer button.
+ void enableDMAViewer();
+
//! @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);
QtFullSFML(const QtFullSFML &) = delete;
QtFullSFML &operator=(const QtFullSFML &) = delete;
diff --git a/sources/SNES.cpp b/sources/SNES.cpp
index 153c1e8..8ccbed3 100644
--- a/sources/SNES.cpp
+++ b/sources/SNES.cpp
@@ -153,4 +153,21 @@ namespace ComSquare
this->_cgramViewer = nullptr;
#endif
}
+
+ void SNES::disableDMADebugging()
+ {
+ #ifdef DEBUGGER_ENABLED
+ this->_dmaViewer = nullptr;
+ #endif
+ }
+
+ void SNES::enableDMADebugging()
+ {
+ #ifdef DEBUGGER_ENABLED
+ if (this->_dmaViewer)
+ this->_dmaViewer->focus();
+ else
+ this->_dmaViewer = std::make_unique(*this);
+ #endif
+ }
}
diff --git a/sources/SNES.hpp b/sources/SNES.hpp
index 5babc05..3755434 100644
--- a/sources/SNES.hpp
+++ b/sources/SNES.hpp
@@ -16,6 +16,7 @@
#include "Debugger/MemoryViewer.hpp"
#include "Debugger/HeaderViewer.hpp"
#include "Debugger/CGramDebug.hpp"
+#include "Debugger/CPU/DMA/DMADebug.hpp"
#endif
@@ -31,6 +32,8 @@ namespace ComSquare
std::unique_ptr _headerViewer;
//! @brief The window that allow the user to view the CGRAM.
std::unique_ptr _cgramViewer;
+ //! @brief The window that allow the user to view the DMA's properties.
+ std::unique_ptr _dmaViewer;
#endif
//! @brief The memory bus that map addresses to components.
std::shared_ptr _bus;
@@ -77,6 +80,10 @@ namespace ComSquare
void disableCgramDebugging();
//! @brief Enable the Cgram's debugging window.
void enableCgramDebugging();
+ //! @brief Disable the DMA's debugging window.
+ void disableDMADebugging();
+ //! @brief Enable the DMA's debugging window.
+ void enableDMADebugging();
//! @brief Create all the components using a common memory bus for all of them.
SNES(const std::string &ramPath, Renderer::IRenderer &renderer);
diff --git a/ui/cpu.ui b/ui/cpuView.ui
similarity index 100%
rename from ui/cpu.ui
rename to ui/cpuView.ui
diff --git a/ui/dmaView.ui b/ui/dmaView.ui
new file mode 100644
index 0000000..10f622e
--- /dev/null
+++ b/ui/dmaView.ui
@@ -0,0 +1,125 @@
+
+
+ DMAView
+
+
+
+ 0
+ 0
+ 795
+ 534
+
+
+
+ DMA's Debugger
+
+
+
+ :/resources/Logo.png:/resources/Logo.png
+
+
+
+ -
+
+
+ QAbstractScrollArea::AdjustIgnored
+
+
+ 28
+
+
+ 86
+
+
+ 61
+
+
+
+ Channel 1
+
+
+
+
+ Channel 2
+
+
+
+
+ Channel 3
+
+
+
+
+ Channel 4
+
+
+
+
+ Channel 5
+
+
+
+
+ Channel 6
+
+
+
+
+ Channel 7
+
+
+
+
+ Channel 8
+
+
+
+
+ Mode
+
+
+
+
+ Fixed
+
+
+
+
+ Increment
+
+
+
+
+ Direction
+
+
+
+
+ Port
+
+
+
+
+ A Address
+
+
+
+
+ Count
+
+
+
+
+ Enabled
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui/ui_cpu.h b/ui/ui_cpuView.h
similarity index 98%
rename from ui/ui_cpu.h
rename to ui/ui_cpuView.h
index 54b8db8..00998e3 100644
--- a/ui/ui_cpu.h
+++ b/ui/ui_cpuView.h
@@ -1,17 +1,13 @@
/********************************************************************************
-** Form generated from reading UI file 'cpu.ui'
+** Form generated from reading UI file 'cpuView.ui'
**
-<<<<<<< HEAD
-** Created by: Qt User Interface Compiler version 5.13.2
-=======
** Created by: Qt User Interface Compiler version 5.14.2
->>>>>>> 24bcafeea3896022704904815d263f69f22e5096
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
-#ifndef UI_CPU_H
-#define UI_CPU_H
+#ifndef UI_CPUVIEW_H
+#define UI_CPUVIEW_H
#include
#include
@@ -458,4 +454,4 @@ namespace Ui {
QT_END_NAMESPACE
-#endif // UI_CPU_H
+#endif // UI_CPUVIEW_H
From 3fb36e1be312acec8770ed29868291fd20a14936 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 28 May 2020 14:51:44 +0200
Subject: [PATCH 06/30] Remplacing the DMA viewer by a registers viewer
---
CMakeLists.txt | 6 +-
.../DMA/DMADebug.cpp => RegisterViewer.cpp} | 14 +-
.../DMA/DMADebug.hpp => RegisterViewer.hpp} | 26 ++--
sources/Renderer/QtRenderer/QtSFML.cpp | 15 +--
sources/Renderer/QtRenderer/QtSFML.hpp | 2 +-
sources/SNES.cpp | 12 +-
sources/SNES.hpp | 14 +-
ui/dmaView.ui | 125 ------------------
ui/registersView.ui | 75 +++++++++++
9 files changed, 119 insertions(+), 170 deletions(-)
rename sources/Debugger/{CPU/DMA/DMADebug.cpp => RegisterViewer.cpp} (56%)
rename sources/Debugger/{CPU/DMA/DMADebug.hpp => RegisterViewer.hpp} (51%)
delete mode 100644 ui/dmaView.ui
create mode 100644 ui/registersView.ui
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2a26978..72fa0bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -223,9 +223,9 @@ add_executable(ComSquare
sources/PPU/Background.hpp
sources/CPU/DMA/DMA.cpp
sources/CPU/DMA/DMA.hpp
- sources/Debugger/CPU/DMA/DMADebug.cpp
- sources/Debugger/CPU/DMA/DMADebug.hpp
- ui/dmaView.ui
+ ui/registersView.ui
+ sources/Debugger/RegisterViewer.cpp
+ sources/Debugger/RegisterViewer.hpp
)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
diff --git a/sources/Debugger/CPU/DMA/DMADebug.cpp b/sources/Debugger/RegisterViewer.cpp
similarity index 56%
rename from sources/Debugger/CPU/DMA/DMADebug.cpp
rename to sources/Debugger/RegisterViewer.cpp
index 4222c97..56178a9 100644
--- a/sources/Debugger/CPU/DMA/DMADebug.cpp
+++ b/sources/Debugger/RegisterViewer.cpp
@@ -2,13 +2,13 @@
// Created by anonymus-raccoon on 5/28/20.
//
-#include "DMADebug.hpp"
-#include "../../../SNES.hpp"
+#include "RegisterViewer.hpp"
+#include "../SNES.hpp"
namespace ComSquare::Debugger
{
- DMADebug::DMADebug(SNES &snes)
- : _window(new ClosableWindow(*this, &DMADebug::disableDebugger)),
+ RegisterViewer::RegisterViewer(SNES &snes)
+ : _window(new ClosableWindow(*this, &RegisterViewer::disableDebugger)),
_ui(),
_snes(snes)
{
@@ -20,13 +20,13 @@ namespace ComSquare::Debugger
this->_window->show();
}
- void DMADebug::focus()
+ void RegisterViewer::focus()
{
this->_window->activateWindow();
}
- void DMADebug::disableDebugger()
+ void RegisterViewer::disableDebugger()
{
- this->_snes.disableDMADebugging();
+ this->_snes.disableRegisterDebugging();
}
}
\ No newline at end of file
diff --git a/sources/Debugger/CPU/DMA/DMADebug.hpp b/sources/Debugger/RegisterViewer.hpp
similarity index 51%
rename from sources/Debugger/CPU/DMA/DMADebug.hpp
rename to sources/Debugger/RegisterViewer.hpp
index 6bf2aa0..e1853ab 100644
--- a/sources/Debugger/CPU/DMA/DMADebug.hpp
+++ b/sources/Debugger/RegisterViewer.hpp
@@ -2,12 +2,12 @@
// Created by anonymus-raccoon on 5/28/20.
//
-#ifndef COMSQUARE_DMADEBUG_HPP
-#define COMSQUARE_DMADEBUG_HPP
+#ifndef COMSQUARE_REGISTERVIEWER_HPP
+#define COMSQUARE_REGISTERVIEWER_HPP
#include
-#include "../../ClosableWindow.hpp"
-#include "../../../../ui/ui_dmaView.h"
+#include "ClosableWindow.hpp"
+#include "../../ui/ui_registersView.h"
namespace ComSquare
{
@@ -15,12 +15,12 @@ namespace ComSquare
namespace Debugger
{
- class DMADebug : public QObject {
+ class RegisterViewer : public QObject {
private:
//! @brief The QT window for this debugger.
- ClosableWindow *_window;
+ ClosableWindow *_window;
//! @brief A widget that contain the whole UI.
- Ui::DMAView _ui;
+ Ui::RegistersView _ui;
//! @brief The snes instance to read/write to DMA channels.
SNES &_snes;
@@ -28,11 +28,11 @@ namespace ComSquare
//! @brief Called when the window is closed. Turn off the debugger.
void disableDebugger();
- explicit DMADebug(SNES &snes);
- DMADebug(
- const DMADebug &) = delete;
- DMADebug &operator=(const DMADebug &) = delete;
- ~DMADebug() =default;
+ explicit RegisterViewer(SNES &snes);
+ RegisterViewer(
+ const RegisterViewer &) = delete;
+ RegisterViewer &operator=(const RegisterViewer &) = delete;
+ ~RegisterViewer() =default;
//! @brief Focus the debugger's window.
void focus();
@@ -40,4 +40,4 @@ namespace ComSquare
};
}
-#endif //COMSQUARE_DMADEBUG_HPP
+#endif //COMSQUARE_REGISTERVIEWER_HPP
diff --git a/sources/Renderer/QtRenderer/QtSFML.cpp b/sources/Renderer/QtRenderer/QtSFML.cpp
index 8c234a4..7cbdc5f 100644
--- a/sources/Renderer/QtRenderer/QtSFML.cpp
+++ b/sources/Renderer/QtRenderer/QtSFML.cpp
@@ -9,7 +9,6 @@
#include
#include "QtSFML.hpp"
#include "../../Exceptions/InvalidOpcode.hpp"
-#include "../../Exceptions/InvalidAddress.hpp"
#include "../../Exceptions/InvalidAction.hpp"
#ifdef Q_WS_X11
@@ -33,7 +32,7 @@ namespace ComSquare::Renderer
this->_window.setCentralWidget(this->_sfWidget.get());
QMenu *file = this->_window.menuBar()->addMenu("&File");
- //TODO implement rom openning from this menu.
+ //TODO implement rom opening from this menu.
(void)file;
QMenu *game = this->_window.menuBar()->addMenu("&Game");
@@ -74,10 +73,10 @@ namespace ComSquare::Renderer
QMainWindow::connect(cgramDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableCgramViewer);
debugger->addAction(cgramDebugger);
- QAction *dmaDebugger = new QAction("DMA Viewer", &this->_window);
- dmaDebugger->setShortcut(Qt::Key_F7);
- QMainWindow::connect(dmaDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableDMAViewer);
- debugger->addAction(dmaDebugger);
+ QAction *registerDebugger = new QAction("Registers Viewer", &this->_window);
+ registerDebugger->setShortcut(Qt::Key_F7);
+ QMainWindow::connect(registerDebugger, &QAction::triggered, this->_sfWidget.get(), &QtFullSFML::enableRegisterViewer);
+ debugger->addAction(registerDebugger);
this->_window.show();
}
@@ -147,8 +146,8 @@ namespace ComSquare::Renderer
this->_snes.enableCgramDebugging();
}
- void QtFullSFML::enableDMAViewer()
+ void QtFullSFML::enableRegisterViewer()
{
- this->_snes.enableDMADebugging();
+ this->_snes.enableRegisterDebugging();
}
}
\ No newline at end of file
diff --git a/sources/Renderer/QtRenderer/QtSFML.hpp b/sources/Renderer/QtRenderer/QtSFML.hpp
index fc9d45a..4d4e077 100644
--- a/sources/Renderer/QtRenderer/QtSFML.hpp
+++ b/sources/Renderer/QtRenderer/QtSFML.hpp
@@ -36,7 +36,7 @@ namespace ComSquare::Renderer
//! @brief Action called when clicking on the enable Palette viewer button.
void enableCgramViewer();
//! @brief Action called when clicking on the enable DMA viewer button.
- void enableDMAViewer();
+ void enableRegisterViewer();
//! @brief Action called when clicking on the reset button.
void reset();
diff --git a/sources/SNES.cpp b/sources/SNES.cpp
index 8ccbed3..a107aaf 100644
--- a/sources/SNES.cpp
+++ b/sources/SNES.cpp
@@ -154,20 +154,20 @@ namespace ComSquare
#endif
}
- void SNES::disableDMADebugging()
+ void SNES::disableRegisterDebugging()
{
#ifdef DEBUGGER_ENABLED
- this->_dmaViewer = nullptr;
+ this->_registerViewer = nullptr;
#endif
}
- void SNES::enableDMADebugging()
+ void SNES::enableRegisterDebugging()
{
#ifdef DEBUGGER_ENABLED
- if (this->_dmaViewer)
- this->_dmaViewer->focus();
+ if (this->_registerViewer)
+ this->_registerViewer->focus();
else
- this->_dmaViewer = std::make_unique(*this);
+ this->_registerViewer = std::make_unique(*this);
#endif
}
}
diff --git a/sources/SNES.hpp b/sources/SNES.hpp
index 3755434..146ffb5 100644
--- a/sources/SNES.hpp
+++ b/sources/SNES.hpp
@@ -16,7 +16,7 @@
#include "Debugger/MemoryViewer.hpp"
#include "Debugger/HeaderViewer.hpp"
#include "Debugger/CGramDebug.hpp"
-#include "Debugger/CPU/DMA/DMADebug.hpp"
+#include "Debugger/RegisterViewer.hpp"
#endif
@@ -32,8 +32,8 @@ namespace ComSquare
std::unique_ptr _headerViewer;
//! @brief The window that allow the user to view the CGRAM.
std::unique_ptr _cgramViewer;
- //! @brief The window that allow the user to view the DMA's properties.
- std::unique_ptr _dmaViewer;
+ //! @brief The window that allow the user to view registers.
+ std::unique_ptr _registerViewer;
#endif
//! @brief The memory bus that map addresses to components.
std::shared_ptr _bus;
@@ -80,10 +80,10 @@ namespace ComSquare
void disableCgramDebugging();
//! @brief Enable the Cgram's debugging window.
void enableCgramDebugging();
- //! @brief Disable the DMA's debugging window.
- void disableDMADebugging();
- //! @brief Enable the DMA's debugging window.
- void enableDMADebugging();
+ //! @brief Disable the Register's debugging window.
+ void disableRegisterDebugging();
+ //! @brief Enable the Register's debugging window.
+ void enableRegisterDebugging();
//! @brief Create all the components using a common memory bus for all of them.
SNES(const std::string &ramPath, Renderer::IRenderer &renderer);
diff --git a/ui/dmaView.ui b/ui/dmaView.ui
deleted file mode 100644
index 10f622e..0000000
--- a/ui/dmaView.ui
+++ /dev/null
@@ -1,125 +0,0 @@
-
-
- DMAView
-
-
-
- 0
- 0
- 795
- 534
-
-
-
- DMA's Debugger
-
-
-
- :/resources/Logo.png:/resources/Logo.png
-
-
-
- -
-
-
- QAbstractScrollArea::AdjustIgnored
-
-
- 28
-
-
- 86
-
-
- 61
-
-
-
- Channel 1
-
-
-
-
- Channel 2
-
-
-
-
- Channel 3
-
-
-
-
- Channel 4
-
-
-
-
- Channel 5
-
-
-
-
- Channel 6
-
-
-
-
- Channel 7
-
-
-
-
- Channel 8
-
-
-
-
- Mode
-
-
-
-
- Fixed
-
-
-
-
- Increment
-
-
-
-
- Direction
-
-
-
-
- Port
-
-
-
-
- A Address
-
-
-
-
- Count
-
-
-
-
- Enabled
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ui/registersView.ui b/ui/registersView.ui
new file mode 100644
index 0000000..44e26db
--- /dev/null
+++ b/ui/registersView.ui
@@ -0,0 +1,75 @@
+
+
+ RegistersView
+
+
+
+ 0
+ 0
+ 431
+ 646
+
+
+
+ Registers's Debugger
+
+
+
+ :/resources/Logo.png:/resources/Logo.png
+
+
+
+ -
+
+
+ 0
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+ CPU
+
+
+
-
+
+
+
+
+
+
+ PPU
+
+
+ -
+
+
+
+
+
+
+ DMA
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From c38b100c14c93fb126498e510384b35072bf8bd5 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 29 May 2020 18:52:58 +0200
Subject: [PATCH 07/30] Creating the structures of the register viewer
---
sources/CPU/CPU.hpp | 6 ++
sources/CPU/DMA/DMA.hpp | 5 ++
sources/Debugger/RegisterViewer.cpp | 104 ++++++++++++++++++++++++++++
sources/Debugger/RegisterViewer.hpp | 79 ++++++++++++++++++++-
sources/SNES.cpp | 28 ++++----
sources/SNES.hpp | 5 +-
sources/Utility/Utility.hpp | 6 +-
sources/main.cpp | 33 +++++----
tests/CPU/testAddressingMode.cpp | 2 +-
tests/PPU/testPpuWrite.cpp | 62 ++++++++---------
tests/PPU/testPpuWriteFromVmain.cpp | 68 +++++++++---------
tests/testMemoryBus.cpp | 98 +++++++++++++-------------
ui/registersView.ui | 86 ++++++++++++++++++++++-
13 files changed, 431 insertions(+), 151 deletions(-)
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index f2afc1b..761684f 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -12,6 +12,7 @@
#include "../Memory/AMemory.hpp"
#include "Instruction.hpp"
#include "DMA/DMA.hpp"
+#include "../Debugger/RegisterViewer.hpp"
namespace ComSquare::CPU
{
@@ -199,6 +200,7 @@ namespace ComSquare::CPU
//! @brief The cartridge header (stored for interrupt vectors..
Cartridge::Header &_cartridgeHeader;
+ //! @brief DMA channels witch are mapped to the bus.
std::array _dmaChannels;
//! @brief True if an addressing mode with an iterator (x, y) has crossed the page. (Used because crossing the page boundary take one more cycle to run certain instructions).
@@ -768,6 +770,10 @@ namespace ComSquare::CPU
//! @brief Change the memory bus used by the CPU.
virtual void setMemoryBus(std::shared_ptr bus);
+
+ #ifdef DEBUGGER_ENABLED
+ friend Debugger::RegisterViewer;
+ #endif
};
}
diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp
index caa2dcb..99fdbc3 100644
--- a/sources/CPU/DMA/DMA.hpp
+++ b/sources/CPU/DMA/DMA.hpp
@@ -9,6 +9,7 @@
#include
#include "../../Models/Int24.hpp"
#include "../../Memory/MemoryBus.hpp"
+#include "../../Debugger/RegisterViewer.hpp"
namespace ComSquare::CPU
{
@@ -98,6 +99,10 @@ namespace ComSquare::CPU
DMA(const DMA &) = default;
DMA &operator=(const DMA &) = default;
~DMA() = default;
+
+ #ifdef DEBUGGER_ENABLED
+ friend Debugger::RegisterViewer;
+ #endif
};
}
diff --git a/sources/Debugger/RegisterViewer.cpp b/sources/Debugger/RegisterViewer.cpp
index 56178a9..d6ae10f 100644
--- a/sources/Debugger/RegisterViewer.cpp
+++ b/sources/Debugger/RegisterViewer.cpp
@@ -4,6 +4,7 @@
#include "RegisterViewer.hpp"
#include "../SNES.hpp"
+#include "../Utility/Utility.hpp"
namespace ComSquare::Debugger
{
@@ -17,9 +18,22 @@ namespace ComSquare::Debugger
this->_window->setAttribute(Qt::WA_DeleteOnClose);
this->_ui.setupUi(this->_window);
+ this->_setupUi();
this->_window->show();
}
+ void RegisterViewer::_setupUi()
+ {
+ for (int i = 0; i < 8; i++) {
+ RegistersViewerModel *model = new RegistersViewerModel(this->_snes);
+ model->addRegister(Register(0x420B, "-0", "Enabled", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i].enabled;
+ }, nullptr, Boolean));
+ this->_ui.dmaChannel1->setModel(model);
+ this->_models.push_back(model);
+ }
+ }
+
void RegisterViewer::focus()
{
this->_window->activateWindow();
@@ -29,4 +43,94 @@ namespace ComSquare::Debugger
{
this->_snes.disableRegisterDebugging();
}
+
+ RegisterViewer::~RegisterViewer()
+ {
+ for (auto &model : this->_models)
+ delete model;
+ }
+
+ Register::Register(uint24_t addr,
+ const std::string &usedBits,
+ const std::string ®Name,
+ const std::function &getValue,
+ const std::function &setValue,
+ RegisterType regType)
+ : address(addr),
+ bits(usedBits),
+ name(regName),
+ get(getValue),
+ set(setValue),
+ type(regType) {}
+}
+
+using namespace ComSquare;
+using namespace ComSquare::Debugger;
+
+RegistersViewerModel::RegistersViewerModel(SNES &snes, QObject *parent) : QAbstractTableModel(parent), _snes(snes) { }
+
+
+void RegistersViewerModel::addRegister(Register reg)
+{
+ int row = this->_registers.size();
+ this->beginInsertRows(QModelIndex(), row, row);
+ this->_registers.push_back(reg);
+ this->insertRow(row);
+ this->endInsertRows();
+}
+
+int RegistersViewerModel::rowCount(const QModelIndex &) const
+{
+ return this->_registers.size();
+}
+
+int RegistersViewerModel::columnCount(const QModelIndex &) const
+{
+ return 3;
+}
+
+QVariant RegistersViewerModel::data(const QModelIndex &index, int role) const
+{
+ Register reg = this->_registers[index.row()];
+
+ if (role == Qt::CheckStateRole && reg.type == Boolean && index.column() == 2)
+ return reg.get(this->_snes) ? Qt::Checked : Qt::Unchecked;
+
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ switch (index.column()) {
+ case 0:
+ return QString((Utility::to_hex(reg.address) + reg.bits).c_str());
+ case 1:
+ return QString(reg.name.c_str());
+ case 2:
+ switch (reg.type) {
+ case Boolean:
+ return QString(reg.get(this->_snes) ? "True" : "False");
+ case EightBits:
+ return QString(Utility::to_hex(static_cast(reg.get(this->_snes))).c_str());
+ case SixteenBits:
+ return QString(Utility::to_hex(static_cast(reg.get(this->_snes))).c_str());
+ case TwentyFourBits:
+ return QString(Utility::to_hex(static_cast(reg.get(this->_snes))).c_str());
+ }
+ }
+ return QVariant();
+}
+
+QVariant RegistersViewerModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Vertical || role != Qt::DisplayRole)
+ return QVariant();
+ switch (section) {
+ case 0:
+ return QString("Address");
+ case 1:
+ return QString("Name");
+ case 2:
+ return QString("Value");
+ default:
+ return QVariant();
+ }
}
\ No newline at end of file
diff --git a/sources/Debugger/RegisterViewer.hpp b/sources/Debugger/RegisterViewer.hpp
index e1853ab..e98390e 100644
--- a/sources/Debugger/RegisterViewer.hpp
+++ b/sources/Debugger/RegisterViewer.hpp
@@ -8,6 +8,41 @@
#include
#include "ClosableWindow.hpp"
#include "../../ui/ui_registersView.h"
+#include "../Models/Int24.hpp"
+#include "../Memory/MemoryBus.hpp"
+
+namespace ComSquare::Debugger
+{
+ struct Register;
+}
+
+class RegistersViewerModel : public QAbstractTableModel
+{
+Q_OBJECT
+private:
+ //! @brief The list of registers to display / update.
+ std::vector _registers;
+ //! @brief Reference to the snes to get information from registers.
+ ComSquare::SNES &_snes;
+public:
+ //! @brief Add a register.
+ void addRegister(ComSquare::Debugger::Register reg);
+
+ RegistersViewerModel(ComSquare::SNES &snes, QObject *parent = nullptr);
+ RegistersViewerModel(const RegistersViewerModel &) = delete;
+ const RegistersViewerModel &operator=(const RegistersViewerModel &) = delete;
+ ~RegistersViewerModel() override = default;
+
+ //! @brief The number of row the table has.
+ int rowCount(const QModelIndex &parent) const override;
+ //! @brief The number of column the table has.
+ int columnCount(const QModelIndex &parent) const override;
+ //! @brief Return a data representing the table cell.
+ QVariant data(const QModelIndex &index, int role) const override;
+ //! @brief Override the headers to use hex values.
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+};
+
namespace ComSquare
{
@@ -21,9 +56,14 @@ namespace ComSquare
ClosableWindow *_window;
//! @brief A widget that contain the whole UI.
Ui::RegistersView _ui;
+ //! @brief The list of models used by different panels.
+ std::vector _models;
//! @brief The snes instance to read/write to DMA channels.
SNES &_snes;
+
+ //! @brief Set models to the different tables and initialize them.
+ void _setupUi();
public:
//! @brief Called when the window is closed. Turn off the debugger.
void disableDebugger();
@@ -32,12 +72,47 @@ namespace ComSquare
RegisterViewer(
const RegisterViewer &) = delete;
RegisterViewer &operator=(const RegisterViewer &) = delete;
- ~RegisterViewer() =default;
+ ~RegisterViewer();
//! @brief Focus the debugger's window.
void focus();
};
- };
+
+ //! @brief The types of registers
+ enum RegisterType {
+ //! @brief This type display a checkbox
+ Boolean,
+ //! @brief A 8 bits hexadecimal value.
+ EightBits,
+ //! @brief A 16 bits hexadecimal value.
+ SixteenBits,
+ //! @brief A 24 bits hexadecimal value.
+ TwentyFourBits
+ };
+
+ //! @brief Struct containing information about a register.
+ struct Register {
+ Register(uint24_t addr,
+ const std::string &usedBits,
+ const std::string ®Name,
+ const std::function &getValue,
+ const std::function &setValue,
+ RegisterType regType);
+
+ //! @brief Where this register is located on the bus.
+ uint24_t address;
+ //! @brief Specify witch bits are concerned if not all bytes are concerned.
+ std::string bits;
+ //! @brief The name of this register.
+ std::string name;
+ //! @brief How to get this value.
+ std::function get;
+ //! @brief How to set this value.
+ std::function set;
+ //! @brief How this value should be displayed/asked for input.
+ RegisterType type;
+ };
+ }
}
#endif //COMSQUARE_REGISTERVIEWER_HPP
diff --git a/sources/SNES.cpp b/sources/SNES.cpp
index a107aaf..d6d321b 100644
--- a/sources/SNES.cpp
+++ b/sources/SNES.cpp
@@ -15,16 +15,16 @@
namespace ComSquare
{
SNES::SNES(const std::string &romPath, Renderer::IRenderer &renderer) :
- _bus(std::make_shared()),
+ bus(std::make_shared()),
cartridge(new Cartridge::Cartridge(romPath)),
wram(new Ram::Ram(16384, WRam, "WRam")),
sram(new Ram::Ram(this->cartridge->header.sramSize, SRam, "SRam")),
apuRam(new APU::MemoryMap()),
- cpu(new CPU::CPU(this->_bus, cartridge->header)),
+ cpu(new CPU::CPU(this->bus, cartridge->header)),
ppu(new PPU::PPU(renderer)),
apu(new APU::APU(this->apuRam))
{
- this->_bus->mapComponents(*this);
+ this->bus->mapComponents(*this);
}
void SNES::update()
@@ -44,7 +44,7 @@ namespace ComSquare
cpuDebug->pause();
} else {
this->cpu = std::make_shared(*this->cpu, *this);
- this->_bus->mapComponents(*this);
+ this->bus->mapComponents(*this);
}
#else
std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl;
@@ -55,7 +55,7 @@ namespace ComSquare
void SNES::disableCPUDebugging()
{
this->cpu = std::make_shared(*this->cpu);
- this->_bus->mapComponents(*this);
+ this->bus->mapComponents(*this);
}
void SNES::enableRamViewer()
@@ -64,7 +64,7 @@ namespace ComSquare
if (this->_ramViewer)
this->_ramViewer->focus();
else
- this->_ramViewer = std::make_unique(*this, *this->_bus);
+ this->_ramViewer = std::make_unique(*this, *this->bus);
#endif
}
@@ -99,7 +99,7 @@ namespace ComSquare
std::static_pointer_cast(this->apu)->focus();
else {
this->apu = std::make_shared(*this->apu, *this);
- this->_bus->mapComponents(*this);
+ this->bus->mapComponents(*this);
}
#else
std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl;
@@ -109,18 +109,18 @@ namespace ComSquare
void SNES::disableAPUDebugging()
{
this->apu = std::make_shared(*this->apu);
- this->_bus->mapComponents(*this);
+ this->bus->mapComponents(*this);
}
void SNES::enableMemoryBusDebugging()
{
#ifdef DEBUGGER_ENABLED
- if (this->_bus->isDebugger())
- std::static_pointer_cast(this->_bus)->focus();
+ if (this->bus->isDebugger())
+ std::static_pointer_cast(this->bus)->focus();
else
{
- this->_bus = std::make_shared(*this, *this->_bus);
- this->cpu->setMemoryBus(this->_bus);
+ this->bus = std::make_shared(*this, *this->bus);
+ this->cpu->setMemoryBus(this->bus);
}
#else
std::cerr << "Debugging features are not enabled. You can't enable the debugger." << std::endl;
@@ -130,8 +130,8 @@ namespace ComSquare
void SNES::disableMemoryBusDebugging()
{
#ifdef DEBUGGER_ENABLED
- this->_bus = std::make_shared(*this->_bus);
- this->cpu->setMemoryBus(this->_bus);
+ 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 146ffb5..c3d3ed5 100644
--- a/sources/SNES.hpp
+++ b/sources/SNES.hpp
@@ -35,9 +35,10 @@ namespace ComSquare
//! @brief The window that allow the user to view registers.
std::unique_ptr _registerViewer;
#endif
- //! @brief The memory bus that map addresses to components.
- std::shared_ptr _bus;
public:
+ //! @brief The memory bus that map addresses to components.
+ std::shared_ptr bus;
+
//! @brief Cartridge containing instructions (ROM).
std::shared_ptr cartridge;
//! @brief Work Ram shared by all the components.
diff --git a/sources/Utility/Utility.hpp b/sources/Utility/Utility.hpp
index 489afc3..78b1ced 100644
--- a/sources/Utility/Utility.hpp
+++ b/sources/Utility/Utility.hpp
@@ -18,11 +18,11 @@ namespace ComSquare::Utility
StandardPrefix
};
- std::string to_hex(uint8_t i, HexString prefix = StandardPrefix);
+ std::string to_hex(uint8_t i, HexString prefix = AsmPrefix);
- std::string to_hex(uint16_t i, HexString prefix = StandardPrefix);
+ std::string to_hex(uint16_t i, HexString prefix = AsmPrefix);
- std::string to_hex(uint24_t i, HexString prefix = StandardPrefix);
+ std::string to_hex(uint24_t i, HexString prefix = AsmPrefix);
std::string to_binary(uint8_t i);
diff --git a/sources/main.cpp b/sources/main.cpp
index 99bbc08..a13903b 100644
--- a/sources/main.cpp
+++ b/sources/main.cpp
@@ -16,11 +16,12 @@ void usage(char *bin)
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
- << "\t-g, --cgram: \tShow the palette viewer." << 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
+ << "\t-g, --cgram: \tShow the palette viewer." << std::endl
+ << "\t-r, --registers: \tShow the registers viewer." << std::endl;
}
void parseArguments(int argc, char **argv, SNES &snes)
@@ -28,16 +29,17 @@ void parseArguments(int argc, char **argv, SNES &snes)
while (true) {
int option_index = 0;
static struct option long_options[] = {
- {"cpu", no_argument, 0, 'c'},
- {"apu", no_argument, 0, 'a'},
- {"memory", no_argument, 0, 'm'},
- {"header", no_argument, 0, 'h'},
- {"bus", no_argument, 0, 'b'},
- {"cgram", no_argument, 0, 'g'},
- {0, 0, 0, 0}
+ {"cpu", no_argument, 0, 'c'},
+ {"apu", no_argument, 0, 'a'},
+ {"memory", no_argument, 0, 'm'},
+ {"header", no_argument, 0, 'h'},
+ {"bus", no_argument, 0, 'b'},
+ {"cgram", no_argument, 0, 'g'},
+ {"registers", no_argument, 0, 'r'},
+ {0, 0, 0, 0}
};
- int c = getopt_long(argc, argv, "camhbg", long_options, &option_index);
+ int c = getopt_long(argc, argv, "camhbgr", long_options, &option_index);
if (c == -1)
break;
switch (c) {
@@ -62,6 +64,9 @@ void parseArguments(int argc, char **argv, SNES &snes)
case 'g':
snes.enableCgramDebugging();
break;
+ case 'r':
+ snes.enableRegisterDebugging();
+ break;
default:
break;
}
@@ -70,7 +75,7 @@ void parseArguments(int argc, char **argv, SNES &snes)
int main(int argc, char **argv)
{
- if (argc < 2) {
+ if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
usage(argv[0]);
return 1;
}
diff --git a/tests/CPU/testAddressingMode.cpp b/tests/CPU/testAddressingMode.cpp
index f4ed3e4..1fd8371 100644
--- a/tests/CPU/testAddressingMode.cpp
+++ b/tests/CPU/testAddressingMode.cpp
@@ -13,7 +13,7 @@ using namespace ComSquare;
Test(AddrModeInit, LegitBus)
{
Init()
- cr_assert_eq(snes._bus.get(), snes.cpu->_bus.get(), "Warning, the CPU's bus is not the same the SNES's bus. Next tests of the CPU may fail.");
+ cr_assert_eq(snes.bus.get(), snes.cpu->_bus.get(), "Warning, the CPU's bus is not the same the SNES's bus. Next tests of the CPU may fail.");
}
Test(AddrMode, Immediate)
diff --git a/tests/PPU/testPpuWrite.cpp b/tests/PPU/testPpuWrite.cpp
index 036d214..3e63c36 100644
--- a/tests/PPU/testPpuWrite.cpp
+++ b/tests/PPU/testPpuWrite.cpp
@@ -14,7 +14,7 @@ using namespace ComSquare;
Test(PPU_write, inidisp_data_full_ones)
{
Init()
- snes._bus->write(0x2100, 0b11111111);
+ snes.bus->write(0x2100, 0b11111111);
cr_assert_eq(snes.ppu->_registers._inidisp.fblank, true);
cr_assert_eq(snes.ppu->_registers._inidisp.brightness, 0xF);
}
@@ -22,7 +22,7 @@ Test(PPU_write, inidisp_data_full_ones)
Test(PPU_write, inidisp_data_full_zeros)
{
Init()
- snes._bus->write(0x2100, 0b00000000);
+ snes.bus->write(0x2100, 0b00000000);
cr_assert_eq(snes.ppu->_registers._inidisp.fblank, false);
cr_assert_eq(snes.ppu->_registers._inidisp.brightness, 0x0);
}
@@ -30,7 +30,7 @@ Test(PPU_write, inidisp_data_full_zeros)
Test(PPU_write, inidisp_data_fBlank_on_brghtness_off)
{
Init()
- snes._bus->write(0x2100, 0b10000000);
+ snes.bus->write(0x2100, 0b10000000);
cr_assert_eq(snes.ppu->_registers._inidisp.fblank, true);
cr_assert_eq(snes.ppu->_registers._inidisp.brightness, 0x0);
}
@@ -38,7 +38,7 @@ Test(PPU_write, inidisp_data_fBlank_on_brghtness_off)
Test(PPU_write, inidisp_data_fBlank_off_brghtness_max)
{
Init()
- snes._bus->write(0x2100, 0b00001111);
+ snes.bus->write(0x2100, 0b00001111);
cr_assert_eq(snes.ppu->_registers._inidisp.fblank, false);
cr_assert_eq(snes.ppu->_registers._inidisp.brightness, 0xF);
}
@@ -46,7 +46,7 @@ Test(PPU_write, inidisp_data_fBlank_off_brghtness_max)
Test(PPU_write, inidisp_data_fBlank_off_brghtness_half)
{
Init()
- snes._bus->write(0x2100, 0b00000101);
+ snes.bus->write(0x2100, 0b00000101);
cr_assert_eq(snes.ppu->_registers._inidisp.fblank, false);
cr_assert_eq(snes.ppu->_registers._inidisp.brightness, 0x5);
}
@@ -54,7 +54,7 @@ Test(PPU_write, inidisp_data_fBlank_off_brghtness_half)
Test(PPU_write, obsel_111_object_size_and_all_null)
{
Init()
- snes._bus->write(0x2101, 0b11100000);
+ snes.bus->write(0x2101, 0b11100000);
cr_assert_eq(snes.ppu->_registers._obsel.objectSize, 0b111);
cr_assert_eq(snes.ppu->_registers._obsel.nameSelect, 0b00);
cr_assert_eq(snes.ppu->_registers._obsel.nameBaseSelect, 0b000);
@@ -63,7 +63,7 @@ Test(PPU_write, obsel_111_object_size_and_all_null)
Test(PPU_write, obsel_data_full)
{
Init()
- snes._bus->write(0x2101, 0b11111111);
+ snes.bus->write(0x2101, 0b11111111);
cr_assert_eq(snes.ppu->_registers._obsel.objectSize, 0b111);
cr_assert_eq(snes.ppu->_registers._obsel.nameSelect, 0b11);
cr_assert_eq(snes.ppu->_registers._obsel.nameBaseSelect, 0b111);
@@ -72,7 +72,7 @@ Test(PPU_write, obsel_data_full)
Test(PPU_write, obsel_data_full_nameselect)
{
Init()
- snes._bus->write(0x2101, 0b00011000);
+ snes.bus->write(0x2101, 0b00011000);
cr_assert_eq(snes.ppu->_registers._obsel.objectSize, 0b000);
cr_assert_eq(snes.ppu->_registers._obsel.nameSelect, 0b11);
cr_assert_eq(snes.ppu->_registers._obsel.nameBaseSelect, 0b000);
@@ -81,7 +81,7 @@ Test(PPU_write, obsel_data_full_nameselect)
Test(PPU_write, obsel_data_full_baseselect)
{
Init()
- snes._bus->write(0x2101, 0b00000111);
+ snes.bus->write(0x2101, 0b00000111);
cr_assert_eq(snes.ppu->_registers._obsel.objectSize, 0b000);
cr_assert_eq(snes.ppu->_registers._obsel.nameSelect, 0b00);
cr_assert_eq(snes.ppu->_registers._obsel.nameBaseSelect, 0b111);
@@ -90,14 +90,14 @@ Test(PPU_write, obsel_data_full_baseselect)
Test(PPU_write, oamaddl_data_full)
{
Init()
- snes._bus->write(0x2102, 0b11111111);
+ snes.bus->write(0x2102, 0b11111111);
cr_assert_eq(snes.ppu->_registers._oamadd.oamAddress, 0b011111111);
}
Test(PPU_write, oamaddh_data_full)
{
Init()
- snes._bus->write(0x2103, 0b11111111);
+ snes.bus->write(0x2103, 0b11111111);
cr_assert_eq(snes.ppu->_registers._oamadd.objPriorityActivationBit, true);
cr_assert_eq(snes.ppu->_registers._oamadd.oamAddress, 0b100000000);
}
@@ -105,8 +105,8 @@ Test(PPU_write, oamaddh_data_full)
Test(PPU_write, oamaddlh_data_full)
{
Init()
- snes._bus->write(0x2102, 0b11111111);
- snes._bus->write(0x2103, 0b11111111);
+ snes.bus->write(0x2102, 0b11111111);
+ snes.bus->write(0x2103, 0b11111111);
cr_assert_eq(snes.ppu->_registers._oamadd.objPriorityActivationBit, true);
cr_assert_eq(snes.ppu->_registers._oamadd.oamAddress, 0b111111111);
}
@@ -114,8 +114,8 @@ Test(PPU_write, oamaddlh_data_full)
Test(PPU_write, oamaddlh_data_full_priorityBit_off)
{
Init()
- snes._bus->write(0x2102, 0b11111111);
- snes._bus->write(0x2103, 0b01111111);
+ snes.bus->write(0x2102, 0b11111111);
+ snes.bus->write(0x2103, 0b01111111);
cr_assert_eq(snes.ppu->_registers._oamadd.objPriorityActivationBit, false);
cr_assert_eq(snes.ppu->_registers._oamadd.oamAddress, 0b111111111);
}
@@ -123,8 +123,8 @@ Test(PPU_write, oamaddlh_data_full_priorityBit_off)
Test(PPU_write, oamaddlh_oamAdress_11_priorityBit_on)
{
Init()
- snes._bus->write(0x2102, 0b00001011);
- snes._bus->write(0x2103, 0b10011100);
+ snes.bus->write(0x2102, 0b00001011);
+ snes.bus->write(0x2103, 0b10011100);
cr_assert_eq(snes.ppu->_registers._oamadd.objPriorityActivationBit, true);
cr_assert_eq(snes.ppu->_registers._oamadd.oamAddress, 11);
}
@@ -132,7 +132,7 @@ Test(PPU_write, oamaddlh_oamAdress_11_priorityBit_on)
Test(PPU_write, bgmode_data_full)
{
Init()
- snes._bus->write(0x2105, 0b11111111);
+ snes.bus->write(0x2105, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgmode.bgMode, 7);
cr_assert_eq(snes.ppu->_registers._bgmode.characterSizeBg1, true);
cr_assert_eq(snes.ppu->_registers._bgmode.characterSizeBg2, true);
@@ -144,7 +144,7 @@ Test(PPU_write, bgmode_data_full)
Test(PPU_write, bgmode_bgmode_5_and_bg24_on)
{
Init()
- snes._bus->write(0x2105, 0b10100101);
+ snes.bus->write(0x2105, 0b10100101);
cr_assert_eq(snes.ppu->_registers._bgmode.bgMode, 5);
cr_assert_eq(snes.ppu->_registers._bgmode.characterSizeBg1, false);
cr_assert_eq(snes.ppu->_registers._bgmode.characterSizeBg2, true);
@@ -156,7 +156,7 @@ Test(PPU_write, bgmode_bgmode_5_and_bg24_on)
Test(PPU_write, mosaic_data_full)
{
Init()
- snes._bus->write(0x2106, 0b11111111);
+ snes.bus->write(0x2106, 0b11111111);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg1, true);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg2, true);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg3, true);
@@ -167,7 +167,7 @@ Test(PPU_write, mosaic_data_full)
Test(PPU_write, mosaic_affectbg23_w_1x1_size)
{
Init()
- snes._bus->write(0x2106, 0b00000110);
+ snes.bus->write(0x2106, 0b00000110);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg1, false);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg2, true);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg3, true);
@@ -178,7 +178,7 @@ Test(PPU_write, mosaic_affectbg23_w_1x1_size)
Test(PPU_write, mosaic_affectbg14_w_2x2_size)
{
Init()
- snes._bus->write(0x2106, 0b00101001);
+ snes.bus->write(0x2106, 0b00101001);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg1, true);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg2, false);
cr_assert_eq(snes.ppu->_registers._mosaic.affectBg3, false);
@@ -189,7 +189,7 @@ Test(PPU_write, mosaic_affectbg14_w_2x2_size)
Test(PPU_write, bg1sc_data_full)
{
Init()
- snes._bus->write(0x2107, 0b11111111);
+ snes.bus->write(0x2107, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgsc[0].tilemapAddress, 0b111111);
cr_assert_eq(snes.ppu->_registers._bgsc[0].tilemapHorizontalMirroring, true);
cr_assert_eq(snes.ppu->_registers._bgsc[0].tilemapVerticalMirroring, true);
@@ -198,7 +198,7 @@ Test(PPU_write, bg1sc_data_full)
Test(PPU_write, bg2sc_data_full)
{
Init()
- snes._bus->write(0x2108, 0b11111111);
+ snes.bus->write(0x2108, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgsc[1].tilemapAddress, 0b111111);
cr_assert_eq(snes.ppu->_registers._bgsc[1].tilemapHorizontalMirroring, true);
cr_assert_eq(snes.ppu->_registers._bgsc[1].tilemapVerticalMirroring, true);
@@ -207,7 +207,7 @@ Test(PPU_write, bg2sc_data_full)
Test(PPU_write, bg3sc_data_full)
{
Init()
- snes._bus->write(0x2109, 0b11111111);
+ snes.bus->write(0x2109, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgsc[2].tilemapAddress, 0b111111);
cr_assert_eq(snes.ppu->_registers._bgsc[2].tilemapHorizontalMirroring, true);
cr_assert_eq(snes.ppu->_registers._bgsc[2].tilemapVerticalMirroring, true);
@@ -216,7 +216,7 @@ Test(PPU_write, bg3sc_data_full)
Test(PPU_write, bg4sc_data_full)
{
Init()
- snes._bus->write(0x210A, 0b11111111);
+ snes.bus->write(0x210A, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapAddress, 0b111111);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapHorizontalMirroring, true);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapVerticalMirroring, true);
@@ -225,7 +225,7 @@ Test(PPU_write, bg4sc_data_full)
Test(PPU_write, bg4sc_data_null)
{
Init()
- snes._bus->write(0x210A, 0b00000000);
+ snes.bus->write(0x210A, 0b00000000);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapAddress, 0);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapHorizontalMirroring, false);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapVerticalMirroring, false);
@@ -234,7 +234,7 @@ Test(PPU_write, bg4sc_data_null)
Test(PPU_write, bg4sc_horizontal_off_vertical_on_random_tilemapAdress)
{
Init()
- snes._bus->write(0x210A, 0b11000110);
+ snes.bus->write(0x210A, 0b11000110);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapAddress, 0b110001);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapHorizontalMirroring, false);
cr_assert_eq(snes.ppu->_registers._bgsc[3].tilemapVerticalMirroring, true);
@@ -243,7 +243,7 @@ Test(PPU_write, bg4sc_horizontal_off_vertical_on_random_tilemapAdress)
Test(PPU_write, bg12nba_data_full)
{
Init()
- snes._bus->write(0x210B, 0b11111111);
+ snes.bus->write(0x210B, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgnba[0].baseAddressBg1a3, 0b1111);
cr_assert_eq(snes.ppu->_registers._bgnba[0].baseAddressBg2a4, 0b1111);
}
@@ -251,7 +251,7 @@ Test(PPU_write, bg12nba_data_full)
Test(PPU_write, bg34nba_data_full)
{
Init()
- snes._bus->write(0x210C, 0b11111111);
+ snes.bus->write(0x210C, 0b11111111);
cr_assert_eq(snes.ppu->_registers._bgnba[1].baseAddressBg1a3, 0b1111);
cr_assert_eq(snes.ppu->_registers._bgnba[1].baseAddressBg2a4, 0b1111);
}
@@ -259,7 +259,7 @@ Test(PPU_write, bg34nba_data_full)
Test(PPU_write, bg12nba_data_random_data)
{
Init()
- snes._bus->write(0x210B, 0b10101010);
+ snes.bus->write(0x210B, 0b10101010);
cr_assert_eq(snes.ppu->_registers._bgnba[0].baseAddressBg1a3, 0b1010);
cr_assert_eq(snes.ppu->_registers._bgnba[0].baseAddressBg2a4, 0b1010);
}
\ No newline at end of file
diff --git a/tests/PPU/testPpuWriteFromVmain.cpp b/tests/PPU/testPpuWriteFromVmain.cpp
index df4f295..197aed0 100644
--- a/tests/PPU/testPpuWriteFromVmain.cpp
+++ b/tests/PPU/testPpuWriteFromVmain.cpp
@@ -14,7 +14,7 @@ using namespace ComSquare;
Test(PPU_write_2, vmain_data_full)
{
Init()
- snes._bus->write(0x2115, 0b11111111);
+ snes.bus->write(0x2115, 0b11111111);
cr_assert_eq(snes.ppu->_registers._vmain.incrementMode, true);
cr_assert_eq(snes.ppu->_registers._vmain.addressRemapping, 0b11);
cr_assert_eq(snes.ppu->_registers._vmain.incrementAmount, 0b11);
@@ -23,7 +23,7 @@ Test(PPU_write_2, vmain_data_full)
Test(PPU_write_2, vmain_incrementmode_off_false_else_full)
{
Init()
- snes._bus->write(0x2115, 0b01111111);
+ snes.bus->write(0x2115, 0b01111111);
cr_assert_eq(snes.ppu->_registers._vmain.incrementMode, false);
cr_assert_eq(snes.ppu->_registers._vmain.addressRemapping, 0b11);
cr_assert_eq(snes.ppu->_registers._vmain.incrementAmount, 0b11);
@@ -32,7 +32,7 @@ Test(PPU_write_2, vmain_incrementmode_off_false_else_full)
Test(PPU_write_2, vmain_addressremaping_null_else_full)
{
Init()
- snes._bus->write(0x2115, 0b11110011);
+ snes.bus->write(0x2115, 0b11110011);
cr_assert_eq(snes.ppu->_registers._vmain.incrementMode, true);
cr_assert_eq(snes.ppu->_registers._vmain.addressRemapping, 0b00);
cr_assert_eq(snes.ppu->_registers._vmain.incrementAmount, 0b11);
@@ -41,7 +41,7 @@ Test(PPU_write_2, vmain_addressremaping_null_else_full)
Test(PPU_write_2, vmain_incrementamount_null_else_full)
{
Init()
- snes._bus->write(0x2115, 0b11111100);
+ snes.bus->write(0x2115, 0b11111100);
cr_assert_eq(snes.ppu->_registers._vmain.incrementMode, true);
cr_assert_eq(snes.ppu->_registers._vmain.addressRemapping, 0b11);
cr_assert_eq(snes.ppu->_registers._vmain.incrementAmount, 0b00);
@@ -50,39 +50,39 @@ Test(PPU_write_2, vmain_incrementamount_null_else_full)
Test(PPU_write_2, vmadd_full_data)
{
Init()
- snes._bus->write(0x2116, 0b11111111);
- snes._bus->write(0x2117, 0b11111111);
+ snes.bus->write(0x2116, 0b11111111);
+ snes.bus->write(0x2117, 0b11111111);
cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0b1111111111111111);
}
Test(PPU_write_2, vmadd_full_high_byte_null)
{
Init()
- snes._bus->write(0x2116, 0b11111111);
- snes._bus->write(0x2117, 0b00000000);
+ snes.bus->write(0x2116, 0b11111111);
+ snes.bus->write(0x2117, 0b00000000);
cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0b0000000011111111);
}
Test(PPU_write_2, vmdata_full_data)
{
Init()
- snes._bus->write(0x2118, 0b11111111);
- snes._bus->write(0x2119, 0b11111111);
+ snes.bus->write(0x2118, 0b11111111);
+ snes.bus->write(0x2119, 0b11111111);
cr_assert_eq(snes.ppu->_registers._vmdata.vmdata, 0b1111111111111111);
}
Test(PPU_write_2, vmdata_full_high_byte_null)
{
Init()
- snes._bus->write(0x2118, 0b11111111);
- snes._bus->write(0x2119, 0b00000000);
+ snes.bus->write(0x2118, 0b11111111);
+ snes.bus->write(0x2119, 0b00000000);
cr_assert_eq(snes.ppu->_registers._vmdata.vmdata, 0b0000000011111111);
}
Test(PPU_write_2, cgadd_full_high_byte_null)
{
Init()
- snes._bus->write(0x2121, 0b11111111);
+ snes.bus->write(0x2121, 0b11111111);
cr_assert_eq(snes.ppu->_registers._cgadd, 0b11111111);
cr_assert_eq(snes.ppu->_registers._isLowByte, true);
}
@@ -90,12 +90,12 @@ Test(PPU_write_2, cgadd_full_high_byte_null)
Test(PPU_write_2, cgdata_data_full)
{
Init()
- snes._bus->write(0x2121, 0x0);
- snes._bus->write(0x2122, 0b11111111);
+ snes.bus->write(0x2121, 0x0);
+ snes.bus->write(0x2122, 0b11111111);
cr_assert_eq(snes.ppu->_registers._cgdata.cgdatal, 0b11111111);
cr_assert_eq(snes.ppu->_registers._isLowByte, false);
int address = snes.ppu->_registers._cgadd;
- snes._bus->write(0x2122, 0b11111000);
+ snes.bus->write(0x2122, 0b11111000);
cr_assert_eq(snes.ppu->_registers._cgdata.cgdatah, 0b11111000);
cr_assert_eq(snes.ppu->_registers._isLowByte, true);
cr_assert_eq(snes.ppu->_registers._cgadd, address + 2);
@@ -104,7 +104,7 @@ Test(PPU_write_2, cgdata_data_full)
Test(PPU_write_2, m7sel_data_full)
{
Init()
- snes._bus->write(0x211A, 0b11111111);
+ snes.bus->write(0x211A, 0b11111111);
cr_assert_eq(snes.ppu->_registers._m7sel.playingFieldSize, true);
cr_assert_eq(snes.ppu->_registers._m7sel.emptySpaceFill, true);
cr_assert_eq(snes.ppu->_registers._m7sel.horizontalMirroring, true);
@@ -114,7 +114,7 @@ Test(PPU_write_2, m7sel_data_full)
Test(PPU_write_2, m7sel_data_actual)
{
Init()
- snes._bus->write(0x211A, 0b01111101);
+ snes.bus->write(0x211A, 0b01111101);
cr_assert_eq(snes.ppu->_registers._m7sel.playingFieldSize, false);
cr_assert_eq(snes.ppu->_registers._m7sel.emptySpaceFill, true);
cr_assert_eq(snes.ppu->_registers._m7sel.horizontalMirroring, true);
@@ -124,7 +124,7 @@ Test(PPU_write_2, m7sel_data_actual)
Test(PPU_write_2, w12sel_data_full)
{
Init()
- snes._bus->write(0x2123, 0b11111111);
+ snes.bus->write(0x2123, 0b11111111);
cr_assert_eq(snes.ppu->_registers._wsel[0].window1InversionForBg1Bg2Obj, true);
cr_assert_eq(snes.ppu->_registers._wsel[0].enableWindow1ForBg1Bg2Obj, true);
cr_assert_eq(snes.ppu->_registers._wsel[0].window2InversionForBg1Bg3Obj, true);
@@ -138,7 +138,7 @@ Test(PPU_write_2, w12sel_data_full)
Test(PPU_write_2, w34sel_data_full)
{
Init()
- snes._bus->write(0x2124, 0b10101010);
+ snes.bus->write(0x2124, 0b10101010);
cr_assert_eq(snes.ppu->_registers._wsel[1].window1InversionForBg1Bg2Obj, true);
cr_assert_eq(snes.ppu->_registers._wsel[1].enableWindow1ForBg1Bg2Obj, false);
cr_assert_eq(snes.ppu->_registers._wsel[1].window2InversionForBg1Bg3Obj, true);
@@ -152,7 +152,7 @@ Test(PPU_write_2, w34sel_data_full)
Test(PPU_write_2, wobjsel_data_full)
{
Init()
- snes._bus->write(0x2125, 0b10110001);
+ snes.bus->write(0x2125, 0b10110001);
cr_assert_eq(snes.ppu->_registers._wsel[2].window1InversionForBg1Bg2Obj, true);
cr_assert_eq(snes.ppu->_registers._wsel[2].enableWindow1ForBg1Bg2Obj, false);
cr_assert_eq(snes.ppu->_registers._wsel[2].window2InversionForBg1Bg3Obj, true);
@@ -166,7 +166,7 @@ Test(PPU_write_2, wobjsel_data_full)
Test(PPU_write_2, wbglog_data_full)
{
Init()
- snes._bus->write(0x212A, 0b10110001);
+ snes.bus->write(0x212A, 0b10110001);
cr_assert_eq(snes.ppu->_registers._wbglog.maskLogicBg1, 0b10);
cr_assert_eq(snes.ppu->_registers._wbglog.maskLogicBg2, 0b11);
cr_assert_eq(snes.ppu->_registers._wbglog.maskLogicBg3, 0b00);
@@ -176,7 +176,7 @@ Test(PPU_write_2, wbglog_data_full)
Test(PPU_write_2, wobjlog_data_full)
{
Init()
- snes._bus->write(0x212B, 0b10110001);
+ snes.bus->write(0x212B, 0b10110001);
cr_assert_eq(snes.ppu->_registers._wobjlog.maskLogicObj, 0b01);
cr_assert_eq(snes.ppu->_registers._wobjlog.maskLogicColor, 0b00);
}
@@ -184,7 +184,7 @@ Test(PPU_write_2, wobjlog_data_full)
Test(PPU_write_2, tm_data_full)
{
Init()
- snes._bus->write(0x212C, 0b10110001);
+ snes.bus->write(0x212C, 0b10110001);
cr_assert_eq(snes.ppu->_registers._t[0].enableWindowDisplayBg1, true);
cr_assert_eq(snes.ppu->_registers._t[0].enableWindowDisplayBg2, false);
cr_assert_eq(snes.ppu->_registers._t[0].enableWindowDisplayBg3, false);
@@ -195,7 +195,7 @@ Test(PPU_write_2, tm_data_full)
Test(PPU_write_2, ts_data_full)
{
Init()
- snes._bus->write(0x212D, 0b10101110);
+ snes.bus->write(0x212D, 0b10101110);
cr_assert_eq(snes.ppu->_registers._t[1].enableWindowDisplayBg1, false);
cr_assert_eq(snes.ppu->_registers._t[1].enableWindowDisplayBg2, true);
cr_assert_eq(snes.ppu->_registers._t[1].enableWindowDisplayBg3, true);
@@ -206,7 +206,7 @@ Test(PPU_write_2, ts_data_full)
Test(PPU_write_2, tmw_data_full)
{
Init()
- snes._bus->write(0x212E, 0b10101110);
+ snes.bus->write(0x212E, 0b10101110);
cr_assert_eq(snes.ppu->_registers._tw[0].enableWindowMaskingBg1, false);
cr_assert_eq(snes.ppu->_registers._tw[0].enableWindowMaskingBg2, true);
cr_assert_eq(snes.ppu->_registers._tw[0].enableWindowMaskingBg3, true);
@@ -217,7 +217,7 @@ Test(PPU_write_2, tmw_data_full)
Test(PPU_write_2, tsw_data_full)
{
Init()
- snes._bus->write(0x212F, 0b10100011);
+ snes.bus->write(0x212F, 0b10100011);
cr_assert_eq(snes.ppu->_registers._tw[1].enableWindowMaskingBg1, true);
cr_assert_eq(snes.ppu->_registers._tw[1].enableWindowMaskingBg2, true);
cr_assert_eq(snes.ppu->_registers._tw[1].enableWindowMaskingBg3, false);
@@ -228,7 +228,7 @@ Test(PPU_write_2, tsw_data_full)
Test(PPU_write_2, cgwsel_data_full)
{
Init()
- snes._bus->write(0x2130, 0b10111001);
+ snes.bus->write(0x2130, 0b10111001);
cr_assert_eq(snes.ppu->_registers._cgwsel.clipColorToBlackBeforeMath, 0b10);
cr_assert_eq(snes.ppu->_registers._cgwsel.preventColorMath, 0b11);
cr_assert_eq(snes.ppu->_registers._cgwsel.addSubscreen, false);
@@ -238,7 +238,7 @@ Test(PPU_write_2, cgwsel_data_full)
Test(PPU_write_2, cgadsub_data_full)
{
Init()
- snes._bus->write(0x2131, 0b10111001);
+ snes.bus->write(0x2131, 0b10111001);
cr_assert_eq(snes.ppu->_registers._cgadsub.addSubtractSelect, true);
cr_assert_eq(snes.ppu->_registers._cgadsub.halfColorMath, false);
cr_assert_eq(snes.ppu->_registers._cgadsub.enableColorMathBackdrop, true);
@@ -252,7 +252,7 @@ Test(PPU_write_2, cgadsub_data_full)
Test(PPU_write_2, coldata_data_full)
{
Init()
- snes._bus->write(0x2132, 0b10111001);
+ snes.bus->write(0x2132, 0b10111001);
cr_assert_eq(snes.ppu->_registers._coldata.blue, true);
cr_assert_eq(snes.ppu->_registers._coldata.green, false);
cr_assert_eq(snes.ppu->_registers._coldata.red, true);
@@ -262,7 +262,7 @@ Test(PPU_write_2, coldata_data_full)
Test(PPU_write_2, setini_data_full)
{
Init()
- snes._bus->write(0x2133, 0b10111001);
+ snes.bus->write(0x2133, 0b10111001);
cr_assert_eq(snes.ppu->_registers._setini.externalSync, true);
cr_assert_eq(snes.ppu->_registers._setini.mode7ExtBg, false);
cr_assert_eq(snes.ppu->_registers._setini.enablePseudoHiresMode, true);
@@ -274,14 +274,14 @@ Test(PPU_write_2, setini_data_full)
Test(PPU_write_2, m7a_data_full)
{
Init()
- snes._bus->write(0x211B, 0b10111001);
+ snes.bus->write(0x211B, 0b10111001);
cr_assert_eq(snes.ppu->_registers._m7[0].m7l, 0b10111001);
}
Test(PPU_write_2, m7c_data_low_and_high_byte)
{
Init()
- snes._bus->write(0x211D, 0b10111001);
- snes._bus->write(0x211D, 0b11111111);
+ snes.bus->write(0x211D, 0b10111001);
+ snes.bus->write(0x211D, 0b11111111);
cr_assert_eq(snes.ppu->_registers._m7[2].m7, 0b1011100111111111);
}
\ No newline at end of file
diff --git a/tests/testMemoryBus.cpp b/tests/testMemoryBus.cpp
index 81600be..d41788a 100644
--- a/tests/testMemoryBus.cpp
+++ b/tests/testMemoryBus.cpp
@@ -29,7 +29,7 @@ Test(BusAccessor, GetWramStart)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x7E0000);
+ accessor = snes.bus->getAccessor(0x7E0000);
cr_assert_eq(accessor.get(), snes.wram.get());
}
@@ -38,7 +38,7 @@ Test(BusAccessor, GetWramEnd)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x7FFFFF);
+ accessor = snes.bus->getAccessor(0x7FFFFF);
cr_assert_eq(accessor.get(), snes.wram.get());
}
@@ -47,7 +47,7 @@ Test(BusAccessor, GetWramMirror)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x2F11FF));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x2F11FF));
cr_assert_neq(accessor, nullptr);
cr_assert_eq(accessor->_initial.get(), snes.wram.get());
}
@@ -57,7 +57,7 @@ Test(BusAccessor, GetWramMirror2)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x100000));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x100000));
cr_assert_neq(accessor, nullptr);
cr_assert_eq(accessor->_initial.get(), snes.wram.get());
}
@@ -67,7 +67,7 @@ Test(BusAccessor, GetWramMirror3)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x1010));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x1010));
cr_assert_neq(accessor, nullptr);
cr_assert_eq(accessor->_initial.get(), snes.wram.get());
}
@@ -75,7 +75,7 @@ Test(BusAccessor, GetWramMirror3)
Test(BusAccessor, GetOpenBus)
{
Init()
- std::shared_ptr accessor = snes._bus->getAccessor(0x897654);
+ std::shared_ptr accessor = snes.bus->getAccessor(0x897654);
cr_assert_eq(accessor.get(), nullptr);
}
@@ -84,7 +84,7 @@ Test(BusAccessor, GetSramStart)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x700000));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x700000));
cr_assert_eq(accessor->_initial.get(), snes.sram.get());
}
@@ -93,7 +93,7 @@ Test(BusAccessor, GetSramEnd)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x7D7FFF));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x7D7FFF));
cr_assert_eq(accessor->_initial.get(), snes.sram.get());
}
@@ -102,7 +102,7 @@ Test(BusAccessor, GetSramMirror)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0xF00123));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0xF00123));
cr_assert_eq(accessor.get(), snes.sram.get());
}
@@ -111,7 +111,7 @@ Test(BusAccessor, GetAPUStart)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x002140);
+ accessor = snes.bus->getAccessor(0x002140);
cr_assert_eq(accessor.get(), snes.apu.get());
}
@@ -120,7 +120,7 @@ Test(BusAccessor, GetAPUEnd)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x002143);
+ accessor = snes.bus->getAccessor(0x002143);
cr_assert_eq(accessor.get(), snes.apu.get());
}
@@ -129,7 +129,7 @@ Test(BusAccessor, GetAPUMirror)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0xAB2143));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0xAB2143));
cr_assert_eq(accessor->_initial.get(), snes.apu.get());
}
@@ -138,7 +138,7 @@ Test(BusAccessor, GetAPUMirrorFirstHalf)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x052143));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x052143));
cr_assert_eq(accessor->_initial.get(), snes.apu.get());
}
@@ -147,7 +147,7 @@ Test(BusAccessor, GetCPUStart)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x004200);
+ accessor = snes.bus->getAccessor(0x004200);
cr_assert_eq(accessor.get(), snes.cpu.get());
}
@@ -156,7 +156,7 @@ Test(BusAccessor, GetCPUEnd)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x00421F);
+ accessor = snes.bus->getAccessor(0x00421F);
cr_assert_eq(accessor.get(), snes.cpu.get());
}
@@ -165,7 +165,7 @@ Test(BusAccessor, GetPPU1Start)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x00213E);
+ accessor = snes.bus->getAccessor(0x00213E);
cr_assert_eq(accessor.get(), snes.ppu.get());
}
@@ -174,7 +174,7 @@ Test(BusAccessor, GetPPU1End)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x00213F);
+ accessor = snes.bus->getAccessor(0x00213F);
cr_assert_eq(accessor.get(), snes.ppu.get());
}
@@ -183,7 +183,7 @@ Test(BusAccessor, GetCPU)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x004212);
+ accessor = snes.bus->getAccessor(0x004212);
cr_assert_eq(accessor.get(), snes.cpu.get());
}
@@ -192,7 +192,7 @@ Test(BusAccessor, GetPPU1Mirror)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x80213F));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x80213F));
cr_assert_eq(accessor->_initial.get(), snes.ppu.get());
}
@@ -201,7 +201,7 @@ Test(BusAccessor, GetCPU2Mirror)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x804212));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x804212));
cr_assert_eq(accessor->_initial.get(), snes.cpu.get());
}
@@ -210,7 +210,7 @@ Test(BusAccessor, GetRomStart)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0x808000);
+ accessor = snes.bus->getAccessor(0x808000);
cr_assert_eq(accessor.get(), snes.cartridge.get());
}
@@ -219,7 +219,7 @@ Test(BusAccessor, GetRomEnd)
Init()
std::shared_ptr accessor = nullptr;
- accessor = snes._bus->getAccessor(0xFFFFFF);
+ accessor = snes.bus->getAccessor(0xFFFFFF);
cr_assert_eq(accessor.get(), snes.cartridge.get());
}
@@ -228,7 +228,7 @@ Test(BusAccessor, GetRomMirror)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x694200));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x694200));
cr_assert_eq(accessor->_initial.get(), snes.cartridge.get());
}
@@ -237,7 +237,7 @@ Test(BusAccessor, GetRomMirror2)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x01FEDC));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x01FEDC));
cr_assert_eq(accessor->_initial.get(), snes.cartridge.get());
}
@@ -246,7 +246,7 @@ Test(BusAccessor, GetRomMirror3)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0xDE1248));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0xDE1248));
cr_assert_eq(accessor->_initial.get(), snes.cartridge.get());
}
@@ -255,7 +255,7 @@ Test(BusAccessor, Get0x0)
Init()
std::shared_ptr accessor = nullptr;
- accessor = std::static_pointer_cast(snes._bus->getAccessor(0x0));
+ accessor = std::static_pointer_cast(snes.bus->getAccessor(0x0));
cr_assert_eq(accessor->_initial.get(), snes.wram.get());
}
@@ -271,7 +271,7 @@ Test(BusRead, Read0x0)
uint8_t data;
snes.wram->_data[0] = 123;
- data = snes._bus->read(0x0);
+ data = snes.bus->read(0x0);
cr_assert_eq(data, 123);
}
@@ -280,8 +280,8 @@ Test(BusRead, ReadOutside, .init = cr_redirect_stdout)
Init()
uint8_t data;
- snes._bus->_openBus = 123;
- data = snes._bus->read(0x002000);
+ snes.bus->_openBus = 123;
+ data = snes.bus->read(0x002000);
cr_assert_eq(data, 123);
}
@@ -290,8 +290,8 @@ Test(BusRead, ReadOutside2, .init = cr_redirect_stdout)
Init()
uint8_t data;
- snes._bus->_openBus = 123;
- data = snes._bus->read(0xBF2FFF);
+ snes.bus->_openBus = 123;
+ data = snes.bus->read(0xBF2FFF);
cr_assert_eq(data, 123);
}
@@ -300,8 +300,8 @@ Test(BusRead, ReadOutside3, .init = cr_redirect_stdout)
Init()
uint8_t data;
- snes._bus->_openBus = 123;
- data = snes._bus->read(0x127654);
+ snes.bus->_openBus = 123;
+ data = snes.bus->read(0x127654);
cr_assert_eq(data, 123);
}
@@ -311,7 +311,7 @@ Test(BusRead, ReadAPU)
uint8_t data;
snes.apu->_registers.port0 = 123;
- data = snes._bus->read(0x002140);
+ data = snes.bus->read(0x002140);
cr_assert_eq(data, 123);
}
@@ -321,7 +321,7 @@ Test(BusRead, ReadROM)
uint8_t data;
snes.cartridge->_data[5] = 123;
- data = snes._bus->read(0x808005);
+ data = snes.bus->read(0x808005);
cr_assert_eq(data, 123);
}
@@ -331,7 +331,7 @@ Test(BusRead, ReadROMStart)
uint8_t data;
snes.cartridge->_data[0] = 123;
- data = snes._bus->read(0x808000);
+ data = snes.bus->read(0x808000);
cr_assert_eq(data, 123);
}
@@ -341,7 +341,7 @@ Test(BusRead, ReadCPU)
uint8_t data;
snes.cpu->_internalRegisters.wrio = 123;
- data = snes._bus->read(0x004201);
+ data = snes.bus->read(0x004201);
cr_assert_eq(data, 123);
}
@@ -351,7 +351,7 @@ Test(BusRead, ReadPPU)
uint8_t data;
snes.ppu->_registers._mpy.mpyl = 123;
- data = snes._bus->read(0x002134);
+ data = snes.bus->read(0x002134);
cr_assert_eq(data, 123);
}
@@ -361,7 +361,7 @@ Test(BusRead, ReadSRAM)
uint8_t data;
snes.sram->_data[7] = 123;
- data = snes._bus->read(0x700007);
+ data = snes.bus->read(0x700007);
cr_assert_eq(data, 123);
}
@@ -371,7 +371,7 @@ Test(BusRead, ReadWRAM)
uint8_t data;
snes.wram->_data[3] = 123;
- data = snes._bus->read(0x7E0003);
+ data = snes.bus->read(0x7E0003);
cr_assert_eq(data, 123);
}
@@ -381,7 +381,7 @@ Test(BusRead, ReadWRAM2)
uint8_t data;
snes.wram->_data[0x1010] = 123;
- data = snes._bus->read(0x7E1010);
+ data = snes.bus->read(0x7E1010);
cr_assert_eq(data, 123);
}
@@ -392,7 +392,7 @@ Test(BusRead, ReadWRAMMirror)
uint8_t data;
snes.wram->_data[0x1010] = 123;
- data = snes._bus->read(0x1010);
+ data = snes.bus->read(0x1010);
cr_assert_eq(data, 123);
}
@@ -407,7 +407,7 @@ Test(BusWrite, Write0x0)
Init()
try {
- snes._bus->write(0x0, 123);
+ snes.bus->write(0x0, 123);
} catch (std::exception &ex) {
std::cout << ex.what() << std::endl;
}
@@ -419,7 +419,7 @@ Test(BusWrite, WriteAPU)
{
Init()
- snes._bus->write(0x002143, 123);
+ snes.bus->write(0x002143, 123);
cr_assert_eq(snes.apu->_registers.port3, 123);
}
@@ -427,7 +427,7 @@ Test(BusWrite, WritePPU)
{
Init()
- snes._bus->write(0x002106, 123);
+ snes.bus->write(0x002106, 123);
cr_assert_eq(snes.ppu->_registers._mosaic.raw, 123);
}
@@ -435,7 +435,7 @@ Test(BusWrite, WriteCPU)
{
Init()
- snes._bus->write(0x00420D, 123);
+ snes.bus->write(0x00420D, 123);
cr_assert_eq(snes.cpu->_internalRegisters.memsel, 123);
}
@@ -443,14 +443,14 @@ Test(BusWrite, WriteROM)
{
Init()
- cr_assert_throw(snes._bus->write(0x808005, 123), InvalidAction);
+ cr_assert_throw(snes.bus->write(0x808005, 123), InvalidAction);
}
Test(BusWrite, WriteWRAM)
{
Init()
- snes._bus->write(0x7E0002, 123);
+ snes.bus->write(0x7E0002, 123);
cr_assert_eq(snes.wram->_data[2], 123);
}
@@ -458,6 +458,6 @@ Test(BusWrite, WriteSRAM)
{
Init()
- snes._bus->write(0x700009, 123);
+ snes.bus->write(0x700009, 123);
cr_assert_eq(snes.sram->_data[9], 123);
}
\ No newline at end of file
diff --git a/ui/registersView.ui b/ui/registersView.ui
index 44e26db..4f467e3 100644
--- a/ui/registersView.ui
+++ b/ui/registersView.ui
@@ -59,7 +59,91 @@
-
-
+
+
+ 0
+
+
+
+ 1
+
+
+
-
+
+
+
+
+
+
+ 2
+
+
+ -
+
+
+
+
+
+
+ 3
+
+
+ -
+
+
+
+
+
+
+ 4
+
+
+ -
+
+
+
+
+
+
+ 5
+
+
+ -
+
+
+
+
+
+
+ 6
+
+
+ -
+
+
+
+
+
+
+ 7
+
+
+ -
+
+
+
+
+
+
+ 8
+
+
+ -
+
+
+
+
+
From fdfa0fc0d67a9e8232a881b46789e2ef17aa04d9 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 29 May 2020 21:32:50 +0200
Subject: [PATCH 08/30] Adding the first dma channel to the register viewer
---
sources/Debugger/RegisterViewer.cpp | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/sources/Debugger/RegisterViewer.cpp b/sources/Debugger/RegisterViewer.cpp
index d6ae10f..9f49c4c 100644
--- a/sources/Debugger/RegisterViewer.cpp
+++ b/sources/Debugger/RegisterViewer.cpp
@@ -26,9 +26,30 @@ namespace ComSquare::Debugger
{
for (int i = 0; i < 8; i++) {
RegistersViewerModel *model = new RegistersViewerModel(this->_snes);
- model->addRegister(Register(0x420B, "-0", "Enabled", [i](SNES &snes) {
+ model->addRegister(Register(0x420B, ":0", "Enabled", [i](SNES &snes) {
return snes.cpu->_dmaChannels[i].enabled;
}, nullptr, Boolean));
+ model->addRegister(Register(0x4302, "-4", "A address", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i]._aAddress.raw;
+ }, nullptr, TwentyFourBits));
+ model->addRegister(Register(0x4301, "", "B address", [i](SNES &snes) {
+ return 0x2100 | snes.cpu->_dmaChannels[i]._port;
+ }, nullptr, SixteenBits));
+ model->addRegister(Register(0x4305, "-6", "Count", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i]._count.raw;
+ }, nullptr, SixteenBits));
+ model->addRegister(Register(0x4300, ":7", "B To A", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i]._controlRegister.direction;
+ }, nullptr, Boolean));
+ model->addRegister(Register(0x4300, ":3", "Fixed", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i]._controlRegister.fixed;
+ }, nullptr, Boolean));
+ model->addRegister(Register(0x4300, ":4", "Increment", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i]._controlRegister.increment;
+ }, nullptr, Boolean));
+ model->addRegister(Register(0x4300, ":0-2", "Mode", [i](SNES &snes) {
+ return snes.cpu->_dmaChannels[i]._controlRegister.increment;
+ }, nullptr, EightBits));
this->_ui.dmaChannel1->setModel(model);
this->_models.push_back(model);
}
From ced42a3bf99edec14b21a3a985eed07defcdd6f4 Mon Sep 17 00:00:00 2001
From: Zoe Roux
Date: Mon, 1 Feb 2021 19:21:18 +0100
Subject: [PATCH 09/30] Fixing bugs with the DMA
---
CMakeLists.txt | 2 +-
Doxyfile | 2 +-
sources/CPU/CPU.hpp | 1 -
sources/CPU/DMA/DMA.cpp | 9 ++--
sources/CPU/DMA/DMA.hpp | 45 ++++++++++---------
sources/Debugger/RegisterViewer.cpp | 5 ++-
sources/PPU/PPU.cpp | 4 +-
sources/SNES.hpp | 10 ++---
tests/CPU/testDMA.cpp | 70 +++++++++++++++++++++++++++++
tests/CPU/testInternal.cpp | 65 +++++++++++++--------------
ui/ui_cpuView.h | 2 +-
11 files changed, 141 insertions(+), 74 deletions(-)
create mode 100644 tests/CPU/testDMA.cpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 72fa0bd..d5e1027 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,7 +103,7 @@ add_executable(unit_tests
sources/PPU/Background.hpp
sources/CPU/DMA/DMA.cpp
sources/CPU/DMA/DMA.hpp
-)
+ tests/CPU/testDMA.cpp)
# include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov)
diff --git a/Doxyfile b/Doxyfile
index fe9687f..962fcf8 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -2431,7 +2431,7 @@ DIRECTORY_GRAPH = YES
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
-DOT_IMAGE_FORMAT = png
+DOT_IMAGE_FORMAT = svg
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index 761684f..9db4b3f 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -12,7 +12,6 @@
#include "../Memory/AMemory.hpp"
#include "Instruction.hpp"
#include "DMA/DMA.hpp"
-#include "../Debugger/RegisterViewer.hpp"
namespace ComSquare::CPU
{
diff --git a/sources/CPU/DMA/DMA.cpp b/sources/CPU/DMA/DMA.cpp
index 5815b67..e6491cf 100644
--- a/sources/CPU/DMA/DMA.cpp
+++ b/sources/CPU/DMA/DMA.cpp
@@ -72,13 +72,13 @@ namespace ComSquare::CPU
if (this->_port == 0x80) {
auto accessor = this->_bus->getAccessor(aAddress);
if (accessor && accessor->getComponent() == WRam) {
- if (this->_controlRegister.direction == AToB)
+ if (this->_controlRegister.direction == AtoB)
return 8;
this->_bus->write(aAddress, 0xFF);
return 4;
}
}
- if (this->_controlRegister.direction == AToB) {
+ if (this->_controlRegister.direction == AtoB) {
uint8_t data = this->_bus->read(aAddress);
this->_bus->write(bAddress, data);
} else {
@@ -88,11 +88,10 @@ namespace ComSquare::CPU
return 8;
}
- uint8_t DMA::run(unsigned int maxCycles)
+ unsigned DMA::run(unsigned int maxCycles)
{
unsigned cycles = 8;
int i = 0;
- std::cout << "Starting a DMA transfer" << std::endl;
do {
cycles += this->_writeOneByte(this->_aAddress.raw, 0x2100 | (this->_port + this->_getModeOffset(i)));
@@ -100,7 +99,7 @@ namespace ComSquare::CPU
this->_aAddress.page += this->_controlRegister.increment ? -1 : 1;
this->_count.raw--;
i++;
- } while (this->_count.raw > 0);
+ } while (this->_count.raw > 0 && this->enabled);
this->enabled = false;
return cycles;
}
diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp
index 99fdbc3..3027dd5 100644
--- a/sources/CPU/DMA/DMA.hpp
+++ b/sources/CPU/DMA/DMA.hpp
@@ -9,31 +9,34 @@
#include
#include "../../Models/Int24.hpp"
#include "../../Memory/MemoryBus.hpp"
-#include "../../Debugger/RegisterViewer.hpp"
+
+#ifdef DEBUGGER_ENABLED
+ #include "../../Debugger/RegisterViewer.hpp"
+#endif
namespace ComSquare::CPU
{
- //! @brief The first three bytes of the DMA's control register. Used to tell how many bytes/registers there is.
- enum DMAMode {
- //! @brief 1 byte is transferred to 1 register (write once)
- OneToOne = 0b000,
- //! @brief 2 byte is transferred to 2 register (write once)
- TwoToTwo = 0b001,
- //! @brief 2 byte is transferred to 1 register (write twice)
- TwoToOne = 0b010,
- //! @brief 4 byte is transferred to 2 register (write twice)
- FourToTwo = 0b011,
- //! @brief 4 byte is transferred to 4 register (write once)
- FourToFour = 0b100
- };
-
- enum Direction {
- AToB,
- BToA
- };
-
//! @brief Class handling all DMA/HDMA transfers (Direct Memory Access or H-Blank Direct Memory Access)
class DMA {
+ public:
+ //! @brief The first three bytes of the DMA's control register. Used to tell how many bytes/registers there is.
+ enum DMAMode {
+ //! @brief 1 byte is transferred to 1 register (write once)
+ OneToOne = 0b000,
+ //! @brief 2 byte is transferred to 2 register (write once)
+ TwoToTwo = 0b001,
+ //! @brief 2 byte is transferred to 1 register (write twice)
+ TwoToOne = 0b010,
+ //! @brief 4 byte is transferred to 2 register (write twice)
+ FourToTwo = 0b011,
+ //! @brief 4 byte is transferred to 4 register (write once)
+ FourToFour = 0b100
+ };
+
+ enum Direction {
+ AtoB,
+ BtoA
+ };
private:
//! @brief Write one byte using the A address, the port and the _direction. Handle special cases where no write occurs.
//! @return The number of cycles used.
@@ -92,7 +95,7 @@ namespace ComSquare::CPU
//! @brief Run the DMA for x cycles
//! @param cycles The maximum number of cycles this DMA should run.
//! @return the number of cycles taken
- uint8_t run(unsigned cycles);
+ unsigned run(unsigned cycles);
DMA() = default;
DMA(std::shared_ptr bus);
diff --git a/sources/Debugger/RegisterViewer.cpp b/sources/Debugger/RegisterViewer.cpp
index 9f49c4c..1dfcc90 100644
--- a/sources/Debugger/RegisterViewer.cpp
+++ b/sources/Debugger/RegisterViewer.cpp
@@ -24,7 +24,8 @@ namespace ComSquare::Debugger
void RegisterViewer::_setupUi()
{
- for (int i = 0; i < 8; i++) {
+ int i = 0;
+ // for (int i = 0; i < 8; i++) {
RegistersViewerModel *model = new RegistersViewerModel(this->_snes);
model->addRegister(Register(0x420B, ":0", "Enabled", [i](SNES &snes) {
return snes.cpu->_dmaChannels[i].enabled;
@@ -52,7 +53,7 @@ namespace ComSquare::Debugger
}, nullptr, EightBits));
this->_ui.dmaChannel1->setModel(model);
this->_models.push_back(model);
- }
+// }
}
void RegisterViewer::focus()
diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp
index 9075adc..0c5b98f 100644
--- a/sources/PPU/PPU.cpp
+++ b/sources/PPU/PPU.cpp
@@ -126,7 +126,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatal" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatal = data;
- this->vram->write_internal(getVramAddress(), this->_registers._vmdata.vmdatal);
+ this->vram->write_internal(getVramAddress(), data);
}
if (!this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -135,7 +135,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatah" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatah = data;
- this->vram->write_internal(getVramAddress(), this->_registers._vmdata.vmdatah);
+ this->vram->write_internal(getVramAddress(), data);
}
if (this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
diff --git a/sources/SNES.hpp b/sources/SNES.hpp
index c3d3ed5..7aa41ae 100644
--- a/sources/SNES.hpp
+++ b/sources/SNES.hpp
@@ -12,12 +12,12 @@
#include "PPU/PPU.hpp"
#include "APU/APU.hpp"
#include "Renderer/IRenderer.hpp"
-#ifdef DEBUGGER_ENABLED
-#include "Debugger/MemoryViewer.hpp"
-#include "Debugger/HeaderViewer.hpp"
-#include "Debugger/CGramDebug.hpp"
-#include "Debugger/RegisterViewer.hpp"
+#ifdef DEBUGGER_ENABLED
+ #include "Debugger/MemoryViewer.hpp"
+ #include "Debugger/HeaderViewer.hpp"
+ #include "Debugger/CGramDebug.hpp"
+ #include "Debugger/RegisterViewer.hpp"
#endif
namespace ComSquare
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
new file mode 100644
index 0000000..ce757e5
--- /dev/null
+++ b/tests/CPU/testDMA.cpp
@@ -0,0 +1,70 @@
+//
+// Created by anonymus-raccoon on 2/1/21.
+//
+
+#include
+#include
+#include "../tests.hpp"
+using namespace ComSquare;
+
+//Test(DMA, RomToVRAM)
+//{
+// Init()
+// snes.cartridge->_size = 4000000;
+// snes.cartridge->_data = new uint8_t[snes.cartridge->_size];
+// for(unsigned i = 0xBE00, j = 0; i < 0xBE00 + 0x800; i++, j++)
+// snes.cartridge->_data[i] = j;
+//
+// // Transferring $800 bytes from ROM ($13BE00) to VRam ($2000) via DMA channel 0
+//
+// // Setting VRam address (since this is an indirect write)
+// snes.bus->write(0x2117, 0x20);
+// snes.bus->write(0x2116, 0);
+//
+// snes.bus->write(0x4301, 0x18);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma's b port was $%x but it should have been $18.", snes.cpu->_dmaChannels[0]._port);
+// snes.bus->write(0x4304, 0x13);
+// snes.bus->write(0x4303, 0xBE);
+// snes.bus->write(0x4302, 0x00);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x13BE00, "The dma's a address was $%x but it should have been $13BE00.", snes.cpu->_dmaChannels[0]._aAddress.raw);
+// snes.bus->write(0x4306, 0x08);
+// snes.bus->write(0x4305, 0);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0x0800, "The dma's count was $%x but it should have been $0800.", snes.cpu->_dmaChannels[0]._count.raw);
+// snes.bus->write(0x4300, 1);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.direction, CPU::DMA::AtoB, "Direction should have been 0 (A to B) but it was %x.", snes.cpu->_dmaChannels[0]._controlRegister.direction);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister._, 0, "The unused byte should be 0.");
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.increment, 0, "The increment byte should be set to 0.");
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.fixed, 0, "The increment byte should be set to 0.");
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.mode, CPU::DMA::TwoToTwo, "The DMA mode should have been TwoToTwo (%%001) but it was) $%x", snes.cpu->_dmaChannels[0]._controlRegister.mode);
+// cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, false, "The DMA channel should be disabled.");
+// // Enabling DMA's channel 0
+// snes.bus->write(0x420B, 1);
+// cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, true, "The DMA channel should be enabled.");
+// // TODO There is an overhead of 12-24 cycles for the whole transfer. How should I know how many cycles there is?
+// auto cycles = snes.cpu->_dmaChannels[0].run(1000000);
+// cr_assert_eq(cycles, 8 + 8 * 0x800, "The dma should take $4008 cycles but it took $%x.", cycles);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0, "The dma count should be 0 but it was $%x.", snes.cpu->_dmaChannels[0]._count.raw);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x13C600, "The dma count should be $13C600 but it was $%x.", snes.cpu->_dmaChannels[0]._aAddress.raw);
+// cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma count should be $18 but it was $%x.", snes.cpu->_dmaChannels[0]._port);
+// cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2400, "The vram address should be $2400 but it was %x.", snes.ppu->_registers._vmadd.vmadd);
+// for(unsigned i = 0x2000, j = 0; i < 0x2000 + 0x800; i++, j++)
+// std::cout << std::hex << i << ": " << (unsigned)snes.ppu->vram->_data[i] << std::endl;
+//// cr_assert_eq(snes.ppu->vram->_data[i], j, "The memory at %x should be %x but it was %x", i, (uint16_t)j, snes.ppu->vram->_data[i]);
+//}
+
+Test(DMA, VramWrite)
+{
+ Init()
+ snes.bus->write(0x2117, 0x20);
+ snes.bus->write(0x2116, 0x0);
+ for (unsigned i = 0; i < 0x400; i++) {
+ snes.bus->write(0x2119, i >> 8);
+ snes.bus->write(0x2118, i);
+ cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2001 + i, "The vram address was %x but it should have been %x", snes.ppu->_registers._vmadd.vmadd, 0x2001 + i);
+ }
+ for(unsigned i = 0; i < 0x400; i++) {
+ uint16_t value = snes.ppu->vram->_data[0x2000 + i * 2] | (snes.ppu->vram->_data[0x2000 + i * 2 + 1] << 8);
+ std::cout << std::hex << 0x2000 + i << ": " << value << std::endl;
+// cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
+ }
+}
\ No newline at end of file
diff --git a/tests/CPU/testInternal.cpp b/tests/CPU/testInternal.cpp
index 5b38be7..a85efbd 100644
--- a/tests/CPU/testInternal.cpp
+++ b/tests/CPU/testInternal.cpp
@@ -3,13 +3,8 @@
//
#include
-#include
#include
#include "../tests.hpp"
-#include "../../sources/SNES.hpp"
-#include "../../sources/Memory/MemoryBus.hpp"
-#include "../../sources/CPU/CPU.hpp"
-
using namespace ComSquare;
Test(SEP, setall)
@@ -196,8 +191,8 @@ Test(PLA, basic)
snes.cpu->PLA(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.a;
cr_assert_eq(data, 0x7BCD, "The accumulator should be 0x7BCD but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -211,8 +206,8 @@ Test(PLA, zero)
snes.cpu->PLA(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.a;
cr_assert_eq(data, 0x0000, "The accumulator should be 0x0000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -226,8 +221,8 @@ Test(PLA, negative)
snes.cpu->PLA(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.a;
cr_assert_eq(data, 0xA000, "The accumulator should be 0xA000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -241,8 +236,8 @@ Test(PLX, basic)
snes.cpu->PLX(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.x;
cr_assert_eq(data, 0x7BCD, "The X register should be 0x7BCD but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -256,8 +251,8 @@ Test(PLX, zero)
snes.cpu->PLX(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.x;
cr_assert_eq(data, 0x0000, "The x register should be 0x0000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -271,8 +266,8 @@ Test(PLX, negative)
snes.cpu->PLX(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.x;
cr_assert_eq(data, 0xA000, "The x register should be 0xA000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -286,8 +281,8 @@ Test(PLY, basic)
snes.cpu->PLY(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.y;
cr_assert_eq(data, 0x7BCD, "The Y register should be 0x7BCD but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -301,8 +296,8 @@ Test(PLY, zero)
snes.cpu->PLY(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.y;
cr_assert_eq(data, 0x0000, "The y register should be 0x0000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -316,8 +311,8 @@ Test(PLY, negative)
snes.cpu->PLY(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.y;
cr_assert_eq(data, 0xA000, "The y register should be 0xA000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -330,8 +325,8 @@ Test(PLD, basic)
snes.cpu->PLD(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.d;
cr_assert_eq(data, 0x7BCD, "The D register should be 0x7BCD but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -344,8 +339,8 @@ Test(PLD, zero)
snes.cpu->PLD(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.d;
cr_assert_eq(data, 0x0000, "The d register should be 0x0000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -358,8 +353,8 @@ Test(PLD, negative)
snes.cpu->PLD(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.d;
cr_assert_eq(data, 0xA000, "The D register should be 0xA000 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x2, "The Stack pointer should be equal to 0x2 but it was %x", snes.cpu->_registers.s);
}
@@ -371,8 +366,8 @@ Test(PLB, basic)
snes.cpu->PLB(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.dbr;
cr_assert_eq(data, 0x7D, "The DBR should be 0x7D but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should not be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", snes.cpu->_registers.s);
}
@@ -384,8 +379,8 @@ Test(PLB, zero)
snes.cpu->PLB(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.dbr;
cr_assert_eq(data, 0x00, "The dbr should be 0x00 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", snes.cpu->_registers.s);
}
@@ -397,8 +392,8 @@ Test(PLB, negative)
snes.cpu->PLB(0x0, ComSquare::CPU::AddressingMode::Implied);
auto data = snes.cpu->_registers.dbr;
cr_assert_eq(data, 0xA0, "The D register should be 0xA0 but it was %x", data);
- cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.", snes.cpu->_registers.p.z);
- cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.", snes.cpu->_registers.p.n);
+ cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag not should be set.");
+ cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.s, 0x1, "The Stack pointer should be equal to 0x1 but it was %x", snes.cpu->_registers.s);
}
diff --git a/ui/ui_cpuView.h b/ui/ui_cpuView.h
index 00998e3..70433d5 100644
--- a/ui/ui_cpuView.h
+++ b/ui/ui_cpuView.h
@@ -1,7 +1,7 @@
/********************************************************************************
** Form generated from reading UI file 'cpuView.ui'
**
-** Created by: Qt User Interface Compiler version 5.14.2
+** Created by: Qt User Interface Compiler version 5.15.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
From 58f7fe6a2cf0588a04f4529e635e5265bf6715f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Bihan?=
Date: Tue, 2 Feb 2021 00:20:22 +0100
Subject: [PATCH 10/30] fixing ppu vram write
---
sources/PPU/PPU.cpp | 6 +++---
tests/CPU/testDMA.cpp | 7 ++++---
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp
index 0c5b98f..a8389ba 100644
--- a/sources/PPU/PPU.cpp
+++ b/sources/PPU/PPU.cpp
@@ -126,7 +126,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatal" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatal = data;
- this->vram->write_internal(getVramAddress(), data);
+ this->vram->write_internal(this->getVramAddress(), data);
}
if (!this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -135,7 +135,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatah" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatah = data;
- this->vram->write_internal(getVramAddress(), data);
+ this->vram->write_internal(this->getVramAddress() + 1, data);
}
if (this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -221,7 +221,7 @@ namespace ComSquare::PPU
uint16_t PPU::getVramAddress()
{
- uint16_t vanillaAddress = this->_registers._vmadd.vmadd;
+ uint16_t vanillaAddress = this->_registers._vmadd.vmadd * 2;
switch (this->_registers._vmain.addressRemapping) {
case 0b00:
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
index ce757e5..bc86cde 100644
--- a/tests/CPU/testDMA.cpp
+++ b/tests/CPU/testDMA.cpp
@@ -55,6 +55,7 @@ using namespace ComSquare;
Test(DMA, VramWrite)
{
Init()
+ //snes.bus->write(0x2115, 0b10000000);
snes.bus->write(0x2117, 0x20);
snes.bus->write(0x2116, 0x0);
for (unsigned i = 0; i < 0x400; i++) {
@@ -63,8 +64,8 @@ Test(DMA, VramWrite)
cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2001 + i, "The vram address was %x but it should have been %x", snes.ppu->_registers._vmadd.vmadd, 0x2001 + i);
}
for(unsigned i = 0; i < 0x400; i++) {
- uint16_t value = snes.ppu->vram->_data[0x2000 + i * 2] | (snes.ppu->vram->_data[0x2000 + i * 2 + 1] << 8);
- std::cout << std::hex << 0x2000 + i << ": " << value << std::endl;
-// cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
+ uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
+ //std::cout << std::hex << 0x2000 + i << ": " << value << std::endl;
+ cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
}
}
\ No newline at end of file
From 71096ded7c40271991d0066b24550b7b79164703 Mon Sep 17 00:00:00 2001
From: Zoe Roux
Date: Wed, 3 Feb 2021 00:32:06 +0100
Subject: [PATCH 11/30] Adding missings mode in the DMA & adding notes for
weird behaviors
---
sources/CPU/DMA/DMA.cpp | 13 ++++--
sources/CPU/DMA/DMA.hpp | 8 +++-
tests/CPU/testDMA.cpp | 97 ++++++++++++++++++++++-------------------
3 files changed, 68 insertions(+), 50 deletions(-)
diff --git a/sources/CPU/DMA/DMA.cpp b/sources/CPU/DMA/DMA.cpp
index e6491cf..306ed9b 100644
--- a/sources/CPU/DMA/DMA.cpp
+++ b/sources/CPU/DMA/DMA.cpp
@@ -72,8 +72,10 @@ namespace ComSquare::CPU
if (this->_port == 0x80) {
auto accessor = this->_bus->getAccessor(aAddress);
if (accessor && accessor->getComponent() == WRam) {
+ // WRAM->$2180 The write is not performed but the time is consumed anyway.
if (this->_controlRegister.direction == AtoB)
return 8;
+ // $2180->WRAM No read is performed (so only 4 master cycles are needed) but the value written is invalid.
this->_bus->write(aAddress, 0xFF);
return 4;
}
@@ -108,13 +110,18 @@ namespace ComSquare::CPU
{
switch (this->_controlRegister.mode) {
case OneToOne:
- return 0;
- case TwoToTwo:
- return index % 2;
case TwoToOne:
+ case TwoToOneBis:
return 0;
+
+ case TwoToTwo:
+ case TwoToTwoBis:
+ return index % 2;
+
case FourToTwo:
+ case FourToTwoBis:
return (index & 0b11) > 1;
+
case FourToFour:
return (index & 0b11);
}
diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp
index 3027dd5..de6d232 100644
--- a/sources/CPU/DMA/DMA.hpp
+++ b/sources/CPU/DMA/DMA.hpp
@@ -30,7 +30,13 @@ namespace ComSquare::CPU
//! @brief 4 byte is transferred to 2 register (write twice)
FourToTwo = 0b011,
//! @brief 4 byte is transferred to 4 register (write once)
- FourToFour = 0b100
+ FourToFour = 0b100,
+ //! @brief Exactly the same as TwoToTwo (not implemented on the SNES so this fallbacks)
+ TwoToTwoBis = 0b101,
+ //! @brief Exactly the same as TwoToOne (not implemented on the SNES so this fallbacks)
+ TwoToOneBis = 0b110,
+ //! @brief Exactly the same as FourToTwo (not implemented on the SNES so this fallbacks)
+ FourToTwoBis = 0b111
};
enum Direction {
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
index bc86cde..8f1baf9 100644
--- a/tests/CPU/testDMA.cpp
+++ b/tests/CPU/testDMA.cpp
@@ -7,55 +7,61 @@
#include "../tests.hpp"
using namespace ComSquare;
-//Test(DMA, RomToVRAM)
-//{
-// Init()
-// snes.cartridge->_size = 4000000;
-// snes.cartridge->_data = new uint8_t[snes.cartridge->_size];
-// for(unsigned i = 0xBE00, j = 0; i < 0xBE00 + 0x800; i++, j++)
-// snes.cartridge->_data[i] = j;
-//
-// // Transferring $800 bytes from ROM ($13BE00) to VRam ($2000) via DMA channel 0
-//
-// // Setting VRam address (since this is an indirect write)
-// snes.bus->write(0x2117, 0x20);
-// snes.bus->write(0x2116, 0);
-//
-// snes.bus->write(0x4301, 0x18);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma's b port was $%x but it should have been $18.", snes.cpu->_dmaChannels[0]._port);
-// snes.bus->write(0x4304, 0x13);
-// snes.bus->write(0x4303, 0xBE);
-// snes.bus->write(0x4302, 0x00);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x13BE00, "The dma's a address was $%x but it should have been $13BE00.", snes.cpu->_dmaChannels[0]._aAddress.raw);
-// snes.bus->write(0x4306, 0x08);
-// snes.bus->write(0x4305, 0);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0x0800, "The dma's count was $%x but it should have been $0800.", snes.cpu->_dmaChannels[0]._count.raw);
-// snes.bus->write(0x4300, 1);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.direction, CPU::DMA::AtoB, "Direction should have been 0 (A to B) but it was %x.", snes.cpu->_dmaChannels[0]._controlRegister.direction);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister._, 0, "The unused byte should be 0.");
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.increment, 0, "The increment byte should be set to 0.");
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.fixed, 0, "The increment byte should be set to 0.");
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.mode, CPU::DMA::TwoToTwo, "The DMA mode should have been TwoToTwo (%%001) but it was) $%x", snes.cpu->_dmaChannels[0]._controlRegister.mode);
-// cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, false, "The DMA channel should be disabled.");
-// // Enabling DMA's channel 0
-// snes.bus->write(0x420B, 1);
-// cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, true, "The DMA channel should be enabled.");
-// // TODO There is an overhead of 12-24 cycles for the whole transfer. How should I know how many cycles there is?
-// auto cycles = snes.cpu->_dmaChannels[0].run(1000000);
-// cr_assert_eq(cycles, 8 + 8 * 0x800, "The dma should take $4008 cycles but it took $%x.", cycles);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0, "The dma count should be 0 but it was $%x.", snes.cpu->_dmaChannels[0]._count.raw);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x13C600, "The dma count should be $13C600 but it was $%x.", snes.cpu->_dmaChannels[0]._aAddress.raw);
-// cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma count should be $18 but it was $%x.", snes.cpu->_dmaChannels[0]._port);
-// cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2400, "The vram address should be $2400 but it was %x.", snes.ppu->_registers._vmadd.vmadd);
-// for(unsigned i = 0x2000, j = 0; i < 0x2000 + 0x800; i++, j++)
-// std::cout << std::hex << i << ": " << (unsigned)snes.ppu->vram->_data[i] << std::endl;
-//// cr_assert_eq(snes.ppu->vram->_data[i], j, "The memory at %x should be %x but it was %x", i, (uint16_t)j, snes.ppu->vram->_data[i]);
-//}
+Test(DMA, RomToVRAM)
+{
+ Init()
+ snes.cartridge->_size = 4000000;
+ snes.cartridge->_data = new uint8_t[snes.cartridge->_size];
+ for(unsigned i = 0; i < 0x400; i++) {
+ snes.cartridge->_data[0xBE00 + i * 2] = i >> 8;
+ snes.cartridge->_data[0xBE00 + i * 2 + 1] = i;
+ uint16_t value = snes.cartridge->_data[0xBE00 + i * 2] | (snes.cartridge->_data[0xBE00 + i * 2 + 1] << 8);
+ std::cout << std::hex << 0xBE00 + i << ": " << value << std::endl;
+ }
+
+ // Transferring $800 bytes from ROM ($13BE00) to VRam ($2000) via DMA channel 0
+
+ // Setting VRam address (since this is an indirect write)
+ snes.bus->write(0x2117, 0x20);
+ snes.bus->write(0x2116, 0);
+
+ snes.bus->write(0x4301, 0x18);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma's b port was $%x but it should have been $18.", snes.cpu->_dmaChannels[0]._port);
+ snes.bus->write(0x4304, 0x13);
+ snes.bus->write(0x4303, 0xBE);
+ snes.bus->write(0x4302, 0x00);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x13BE00, "The dma's a address was $%x but it should have been $13BE00.", snes.cpu->_dmaChannels[0]._aAddress.raw);
+ snes.bus->write(0x4306, 0x08);
+ snes.bus->write(0x4305, 0);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0x0800, "The dma's count was $%x but it should have been $0800.", snes.cpu->_dmaChannels[0]._count.raw);
+ snes.bus->write(0x4300, 1);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.direction, CPU::DMA::AtoB, "Direction should have been 0 (A to B) but it was %x.", snes.cpu->_dmaChannels[0]._controlRegister.direction);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister._, 0, "The unused byte should be 0.");
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.increment, 0, "The increment byte should be set to 0.");
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.fixed, 0, "The increment byte should be set to 0.");
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.mode, CPU::DMA::TwoToTwo, "The DMA mode should have been TwoToTwo (%%001) but it was) $%x", snes.cpu->_dmaChannels[0]._controlRegister.mode);
+ cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, false, "The DMA channel should be disabled.");
+ // Enabling DMA's channel 0
+ snes.bus->write(0x420B, 1);
+ cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, true, "The DMA channel should be enabled.");
+ // TODO There is an overhead of 12-24 cycles for the whole transfer. How should I know how many cycles there is?
+ auto cycles = snes.cpu->_dmaChannels[0].run(1000000);
+ cr_assert_eq(cycles, 8 + 8 * 0x800, "The dma should take $4008 cycles but it took $%x.", cycles);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0, "The dma count should be 0 but it was $%x.", snes.cpu->_dmaChannels[0]._count.raw);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x13C600, "The dma count should be $13C600 but it was $%x.", snes.cpu->_dmaChannels[0]._aAddress.raw);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma count should be $18 but it was $%x.", snes.cpu->_dmaChannels[0]._port);
+ cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2400, "The vram address should be $2400 but it was %x.", snes.ppu->_registers._vmadd.vmadd);
+ for(unsigned i = 0; i < 0x400; i++) {
+ // TODO check endianess
+ uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
+ std::cout << std::hex << 0x2000 + i << ": " << value << std::endl;
+// cr_assert_eq(value, i, "The memory at %x should be %x but it was %x", 0x2000 + i, i, snes.ppu->vram->_data[i]);
+ }
+}
Test(DMA, VramWrite)
{
Init()
- //snes.bus->write(0x2115, 0b10000000);
snes.bus->write(0x2117, 0x20);
snes.bus->write(0x2116, 0x0);
for (unsigned i = 0; i < 0x400; i++) {
@@ -65,7 +71,6 @@ Test(DMA, VramWrite)
}
for(unsigned i = 0; i < 0x400; i++) {
uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
- //std::cout << std::hex << 0x2000 + i << ": " << value << std::endl;
cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
}
}
\ No newline at end of file
From 2d83137b40a729a64ccebc57bd882e2ca4be98d8 Mon Sep 17 00:00:00 2001
From: Zoe Roux
Date: Wed, 3 Feb 2021 17:44:02 +0100
Subject: [PATCH 12/30] Fixing the DMA test
---
tests/CPU/testDMA.cpp | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
index 8f1baf9..828f30a 100644
--- a/tests/CPU/testDMA.cpp
+++ b/tests/CPU/testDMA.cpp
@@ -12,16 +12,15 @@ Test(DMA, RomToVRAM)
Init()
snes.cartridge->_size = 4000000;
snes.cartridge->_data = new uint8_t[snes.cartridge->_size];
- for(unsigned i = 0; i < 0x400; i++) {
- snes.cartridge->_data[0xBE00 + i * 2] = i >> 8;
- snes.cartridge->_data[0xBE00 + i * 2 + 1] = i;
- uint16_t value = snes.cartridge->_data[0xBE00 + i * 2] | (snes.cartridge->_data[0xBE00 + i * 2 + 1] << 8);
- std::cout << std::hex << 0xBE00 + i << ": " << value << std::endl;
+ for (unsigned i = 0; i < 0x400; i++) {
+ snes.cartridge->_data[0xBDED + i * 2] = i;
+ snes.cartridge->_data[0xBDED + i * 2 + 1] = i >> 8;
}
// Transferring $800 bytes from ROM ($13BE00) to VRam ($2000) via DMA channel 0
// Setting VRam address (since this is an indirect write)
+ snes.bus->write(0x2115, 0b10000000);
snes.bus->write(0x2117, 0x20);
snes.bus->write(0x2116, 0);
@@ -52,10 +51,8 @@ Test(DMA, RomToVRAM)
cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma count should be $18 but it was $%x.", snes.cpu->_dmaChannels[0]._port);
cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2400, "The vram address should be $2400 but it was %x.", snes.ppu->_registers._vmadd.vmadd);
for(unsigned i = 0; i < 0x400; i++) {
- // TODO check endianess
uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
- std::cout << std::hex << 0x2000 + i << ": " << value << std::endl;
-// cr_assert_eq(value, i, "The memory at %x should be %x but it was %x", 0x2000 + i, i, snes.ppu->vram->_data[i]);
+ cr_assert_eq(value, i, "The memory at %x should be %x but it was %x", 0x2000 + i, i, snes.ppu->vram->_data[i]);
}
}
@@ -73,4 +70,21 @@ Test(DMA, VramWrite)
uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
}
+}
+
+Test(DMA, VramWriteInvertedOrder)
+{
+ Init()
+ snes.bus->write(0x2115, 0b10000000);
+ snes.bus->write(0x2117, 0x20);
+ snes.bus->write(0x2116, 0x0);
+ for (unsigned i = 0; i < 0x400; i++) {
+ snes.bus->write(0x2118, i);
+ snes.bus->write(0x2119, i >> 8);
+ cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x2001 + i, "The vram address was %x but it should have been %x", snes.ppu->_registers._vmadd.vmadd, 0x2001 + i);
+ }
+ for(unsigned i = 0; i < 0x400; i++) {
+ uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
+ cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
+ }
}
\ No newline at end of file
From 8ec3cad58bcd114ecd5faa9d308437eff529253f Mon Sep 17 00:00:00 2001
From: Zoe Roux
Date: Wed, 3 Feb 2021 18:18:49 +0100
Subject: [PATCH 13/30] Running dma inside the CPU's debugger
---
sources/Debugger/CPU/CPUDebug.cpp | 4 ++++
tests/CPU/testDMA.cpp | 1 +
2 files changed, 5 insertions(+)
diff --git a/sources/Debugger/CPU/CPUDebug.cpp b/sources/Debugger/CPU/CPUDebug.cpp
index d677158..ce5118d 100644
--- a/sources/Debugger/CPU/CPUDebug.cpp
+++ b/sources/Debugger/CPU/CPUDebug.cpp
@@ -79,6 +79,10 @@ namespace ComSquare::Debugger
try {
unsigned cycles = 0;
+ for (auto &channel : this->_dmaChannels)
+ if (channel.enabled)
+ cycles += channel.run(INT_MAX);
+
if (this->_isPaused)
return 0xFF;
if (this->_isStepping) {
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
index 828f30a..412c295 100644
--- a/tests/CPU/testDMA.cpp
+++ b/tests/CPU/testDMA.cpp
@@ -54,6 +54,7 @@ Test(DMA, RomToVRAM)
uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
cr_assert_eq(value, i, "The memory at %x should be %x but it was %x", 0x2000 + i, i, snes.ppu->vram->_data[i]);
}
+ cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, false, "The DMA channel should be disabled.");
}
Test(DMA, VramWrite)
From 0b28719f41bd149de5b17e341606fa018ffc8a79 Mon Sep 17 00:00:00 2001
From: Zoe Roux
Date: Wed, 3 Feb 2021 18:37:07 +0100
Subject: [PATCH 14/30] Adding more dma tests
---
sources/Debugger/CPU/CPUDebug.cpp | 2 +-
tests/CPU/testDMA.cpp | 48 +++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/sources/Debugger/CPU/CPUDebug.cpp b/sources/Debugger/CPU/CPUDebug.cpp
index ce5118d..c38be29 100644
--- a/sources/Debugger/CPU/CPUDebug.cpp
+++ b/sources/Debugger/CPU/CPUDebug.cpp
@@ -137,7 +137,7 @@ namespace ComSquare::Debugger
{
this->_isPaused = !this->_isPaused;
if (this->_isPaused)
- this->_ui.actionPause->setText("Resume");
+ this->_ui.actionPause->setText("Continue");
else
this->_ui.actionPause->setText("Pause");
this->_updateDisassembly(this->_registers.pac);
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
index 412c295..25b87d3 100644
--- a/tests/CPU/testDMA.cpp
+++ b/tests/CPU/testDMA.cpp
@@ -88,4 +88,52 @@ Test(DMA, VramWriteInvertedOrder)
uint16_t value = snes.ppu->vram->_data[0x2000 * 2 + i * 2] | (snes.ppu->vram->_data[0x2000 * 2 + i * 2 + 1] << 8);
cr_assert_eq(value, (uint16_t)i, "The memory at %x should be %x but it was %x", 0x2000 + i, (uint16_t)i, value);
}
+}
+
+Test(DMA, WRamToVRAM)
+{
+ Init()
+ for (unsigned i = 0; i < 0x400; i++) {
+ snes.wram->_data[i * 2] = i;
+ snes.wram->_data[i * 2 + 1] = i >> 8;
+ }
+
+ // Transferring $800 bytes from WRAM ($00) to VRam ($2000) via DMA channel 0
+
+ // Setting VRam address (since this is an indirect write)
+ snes.bus->write(0x2115, 0b10000000);
+ snes.bus->write(0x2117, 0);
+ snes.bus->write(0x2116, 0);
+
+ snes.bus->write(0x4301, 0x18);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma's b port was $%x but it should have been $18.", snes.cpu->_dmaChannels[0]._port);
+ snes.bus->write(0x4304, 0x7E);
+ snes.bus->write(0x4303, 0x00);
+ snes.bus->write(0x4302, 0x00);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x7E0000, "The dma's a address was $%x but it should have been $7E0000.", snes.cpu->_dmaChannels[0]._aAddress.raw);
+ snes.bus->write(0x4306, 0x08);
+ snes.bus->write(0x4305, 0);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0x0800, "The dma's count was $%x but it should have been $0800.", snes.cpu->_dmaChannels[0]._count.raw);
+ snes.bus->write(0x4300, 1);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.direction, CPU::DMA::AtoB, "Direction should have been 0 (A to B) but it was %x.", snes.cpu->_dmaChannels[0]._controlRegister.direction);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister._, 0, "The unused byte should be 0.");
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.increment, 0, "The increment byte should be set to 0.");
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.fixed, 0, "The increment byte should be set to 0.");
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._controlRegister.mode, CPU::DMA::TwoToTwo, "The DMA mode should have been TwoToTwo (%%001) but it was) $%x", snes.cpu->_dmaChannels[0]._controlRegister.mode);
+ cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, false, "The DMA channel should be disabled.");
+ // Enabling DMA's channel 0
+ snes.bus->write(0x420B, 1);
+ cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, true, "The DMA channel should be enabled.");
+ // TODO There is an overhead of 12-24 cycles for the whole transfer. How should I know how many cycles there is?
+ auto cycles = snes.cpu->_dmaChannels[0].run(1000000);
+ cr_assert_eq(cycles, 8 + 8 * 0x800, "The dma should take $4008 cycles but it took $%x.", cycles);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._count.raw, 0, "The dma count should be 0 but it was $%x.", snes.cpu->_dmaChannels[0]._count.raw);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._aAddress.raw, 0x7E0800, "The dma count should be $7E0800 but it was $%x.", snes.cpu->_dmaChannels[0]._aAddress.raw);
+ cr_assert_eq(snes.cpu->_dmaChannels[0]._port, 0x18, "The dma count should be $18 but it was $%x.", snes.cpu->_dmaChannels[0]._port);
+ cr_assert_eq(snes.ppu->_registers._vmadd.vmadd, 0x0400, "The vram address should be $400 but it was %x.", snes.ppu->_registers._vmadd.vmadd);
+ for(unsigned i = 0; i < 0x400; i++) {
+ uint16_t value = snes.ppu->vram->_data[i * 2] | (snes.ppu->vram->_data[i * 2 + 1] << 8);
+ cr_assert_eq(value, i, "The memory at %x should be %x but it was %x", i, i, snes.ppu->vram->_data[i]);
+ }
+ cr_assert_eq(snes.cpu->_dmaChannels[0].enabled, false, "The DMA channel should be disabled.");
}
\ No newline at end of file
From 874c21b0fd85b6ee192cd97e79a52808c4d4e3a2 Mon Sep 17 00:00:00 2001
From: Zoe Roux
Date: Wed, 3 Feb 2021 23:43:07 +0100
Subject: [PATCH 15/30] Reworking the memory management & fixing a bug in the
memory viewer goto
---
CMakeLists.txt | 4 +-
sources/APU/APU.cpp | 13 +++----
sources/APU/IPL/IPL.hpp | 2 +-
sources/CPU/CPU.cpp | 4 +-
sources/Cartridge/Cartridge.cpp | 14 +++----
sources/Cartridge/Cartridge.hpp | 11 ++----
sources/Debugger/MemoryBusDebug.cpp | 12 +++---
sources/Debugger/MemoryBusDebug.hpp | 4 +-
sources/Debugger/MemoryViewer.cpp | 26 ++++++-------
sources/Debugger/RegisterViewer.cpp | 2 +-
sources/Memory/AMemory.cpp | 13 +++----
sources/Memory/AMemory.hpp | 48 ++++++++----------------
sources/Memory/ARectangleMemory.cpp | 47 ++++++++++--------------
sources/Memory/ARectangleMemory.hpp | 52 ++++++++++----------------
sources/Memory/IMemory.hpp | 53 +++++++++++++++++++++++++++
sources/Memory/MemoryBus.cpp | 13 +++----
sources/Memory/MemoryBus.hpp | 4 +-
sources/Memory/MemoryShadow.cpp | 4 +-
sources/Memory/MemoryShadow.hpp | 13 +++----
sources/Memory/RectangleShadow.cpp | 26 ++++++++-----
sources/Memory/RectangleShadow.hpp | 38 ++++++++++---------
sources/PPU/Backgrounds.cpp | 17 +++------
sources/PPU/PPU.cpp | 50 ++++++++++++-------------
sources/PPU/PPU.hpp | 3 +-
sources/Ram/Ram.cpp | 17 ++-------
sources/Ram/Ram.hpp | 26 ++++++-------
tests/CPU/testDMA.cpp | 3 +-
tests/testMemoryBus.cpp | 57 +++++++++++++----------------
tests/testRectangleMemory.cpp | 26 ++++++-------
29 files changed, 295 insertions(+), 307 deletions(-)
create mode 100644 sources/Memory/IMemory.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5e1027..22d3311 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,7 +103,7 @@ add_executable(unit_tests
sources/PPU/Background.hpp
sources/CPU/DMA/DMA.cpp
sources/CPU/DMA/DMA.hpp
- tests/CPU/testDMA.cpp)
+ tests/CPU/testDMA.cpp sources/Memory/IMemory.hpp)
# include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov)
@@ -226,7 +226,7 @@ add_executable(ComSquare
ui/registersView.ui
sources/Debugger/RegisterViewer.cpp
sources/Debugger/RegisterViewer.hpp
-)
+ sources/Memory/IMemory.hpp)
target_compile_definitions(ComSquare PUBLIC DEBUGGER_ENABLED)
diff --git a/sources/APU/APU.cpp b/sources/APU/APU.cpp
index dacb563..effc58d 100644
--- a/sources/APU/APU.cpp
+++ b/sources/APU/APU.cpp
@@ -7,7 +7,6 @@
#include "../Exceptions/NotImplementedException.hpp"
#include "../Exceptions/InvalidAddress.hpp"
#include "../Exceptions/InvalidOpcode.hpp"
-#include "../Utility/Utility.hpp"
namespace ComSquare::APU
{
@@ -36,7 +35,7 @@ namespace ComSquare::APU
uint8_t APU::_internalRead(uint24_t addr) {
switch (addr) {
case 0x0000 ... 0x00EF:
- return this->_map->Page0.read_internal(addr);
+ return this->_map->Page0.read(addr);
case 0xF0:
return this->_registers.unknown;
case 0xF2:
@@ -62,9 +61,9 @@ namespace ComSquare::APU
case 0xFF:
return this->_registers.counter2;
case 0x0100 ... 0x01FF:
- return this->_map->Page1.read_internal(addr - 0x0100);
+ return this->_map->Page1.read(addr - 0x0100);
case 0x0200 ... 0xFFBF:
- return this->_map->Memory.read_internal(addr - 0x200);
+ return this->_map->Memory.read(addr - 0x200);
case 0xFFC0 ... 0xFFFF:
return this->_map->IPL.read(addr - 0xFFC0);
default:
@@ -75,7 +74,7 @@ namespace ComSquare::APU
void APU::_internalWrite(uint24_t addr, uint8_t data) {
switch (addr) {
case 0x0000 ... 0x00EF:
- this->_map->Page0.write_internal(addr, data);
+ this->_map->Page0.write(addr, data);
break;
case 0xF0:
this->_registers.unknown = data;
@@ -117,10 +116,10 @@ namespace ComSquare::APU
this->_registers.timer2 = data;
break;
case 0x0100 ... 0x01FF:
- this->_map->Page1.write_internal(addr - 0x0100, data);
+ this->_map->Page1.write(addr - 0x0100, data);
break;
case 0x0200 ... 0xFFBF:
- this->_map->Memory.write_internal(addr - 0x200, data);
+ this->_map->Memory.write(addr - 0x200, data);
break;
case 0xFFC0 ... 0xFFFF:
this->_map->IPL.write(addr - 0xFFC0, data);
diff --git a/sources/APU/IPL/IPL.hpp b/sources/APU/IPL/IPL.hpp
index 38c3437..54ba95d 100644
--- a/sources/APU/IPL/IPL.hpp
+++ b/sources/APU/IPL/IPL.hpp
@@ -5,7 +5,7 @@
#ifndef COMSQUARE_IPL_HPP
#define COMSQUARE_IPL_HPP
-#include "../../Memory/ARectangleMemory.hpp"
+#include "../../Memory/AMemory.hpp"
namespace ComSquare::APU::IPL
{
diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp
index 5962413..107a6a9 100644
--- a/sources/CPU/CPU.cpp
+++ b/sources/CPU/CPU.cpp
@@ -101,7 +101,7 @@ namespace ComSquare::CPU
case 0x100 ... 0x180:
return this->_dmaChannels[(addr - 0x100) >> 8u].read(addr & 0xF);
default:
- throw InvalidAddress("CPU Internal Registers read", addr + this->getStart());
+ throw InvalidAddress("CPU Internal Registers read", addr + this->_start);
}
}
@@ -203,7 +203,7 @@ namespace ComSquare::CPU
this->_dmaChannels[(addr - 0x100) >> 8u].write(addr & 0xF, data);
break;
default:
- throw InvalidAddress("CPU Internal Registers write", addr + this->getStart());
+ throw InvalidAddress("CPU Internal Registers write", addr + this->_start);
}
}
diff --git a/sources/Cartridge/Cartridge.cpp b/sources/Cartridge/Cartridge.cpp
index 91a8036..8156c54 100644
--- a/sources/Cartridge/Cartridge.cpp
+++ b/sources/Cartridge/Cartridge.cpp
@@ -3,7 +3,6 @@
//
#include
-#include
#include
#include "Cartridge.hpp"
#include "../Exceptions/InvalidAddress.hpp"
@@ -39,17 +38,13 @@ namespace ComSquare::Cartridge
}
- uint8_t Cartridge::read_internal(uint24_t addr)
+ uint8_t Cartridge::read(uint24_t addr)
{
- if (addr >= this->_size)
- throw InvalidAddress("Cartridge read", addr);
- return this->_data[addr + this->_romStart];
+ return Ram::read(addr + this->_romStart);
}
- void Cartridge::write_internal(uint24_t addr, uint8_t data)
+ void Cartridge::write(uint24_t, uint8_t)
{
- (void)addr;
- (void)data;
throw InvalidAction("Witting to the ROM is not allowed.");
}
@@ -123,7 +118,8 @@ namespace ComSquare::Cartridge
if (info.checksum + info.checksumComplement == 0xFFFF && info.checksum != 0 && info.checksumComplement != 0)
score += 8;
- if (info.emulationInterrupts.reset < 0x8000u) // The reset vector is the first thing called by the SNES so It must execute the code inside the ROM (the rom starts at 0x8000).
+ // The reset vector is the first thing called by the SNES so It must execute the code inside the ROM (the rom starts at 0x8000).
+ if (info.emulationInterrupts.reset < 0x8000u)
continue;
uint8_t resetOpCode = this->_data[info.emulationInterrupts.reset - 0x8000u];
switch (resetOpCode) {
diff --git a/sources/Cartridge/Cartridge.hpp b/sources/Cartridge/Cartridge.hpp
index 9dc7c73..4b4ea0a 100644
--- a/sources/Cartridge/Cartridge.hpp
+++ b/sources/Cartridge/Cartridge.hpp
@@ -2,8 +2,7 @@
// Created by anonymus-raccoon on 1/27/20.
//
-#ifndef COMSQUARE_CARTRIDGE_HPP
-#define COMSQUARE_CARTRIDGE_HPP
+#pragma once
#include
#include "../Memory/AMemory.hpp"
@@ -99,13 +98,11 @@ namespace ComSquare::Cartridge
//! @param addr The address to read from. The address 0x0 should refer to the first byte of the rom's memory.
//! @throw InvalidAddress will be thrown if the address is more than the size of the rom's memory.
//! @return Return the data at the address.
- uint8_t read_internal(uint24_t addr) override;
+ uint8_t read(uint24_t addr) override;
//! @brief Write data to the rom.
//! @param addr The address to write to. The address 0x0 should refer to the first byte of the rom's memory.
//! @param data The data to write.
//! @throw InvalidAddress will be thrown if the address is more than the size of the rom's memory.
- void write_internal(uint24_t addr, uint8_t data) override;
+ void write(uint24_t addr, uint8_t data) override;
};
-}
-
-#endif //COMSQUARE_CARTRIDGE_HPP
+}
\ No newline at end of file
diff --git a/sources/Debugger/MemoryBusDebug.cpp b/sources/Debugger/MemoryBusDebug.cpp
index 17d77fc..8ebe6c2 100644
--- a/sources/Debugger/MemoryBusDebug.cpp
+++ b/sources/Debugger/MemoryBusDebug.cpp
@@ -155,7 +155,7 @@ namespace ComSquare::Debugger
if (!accessor) {
this->_model.log(BusLog(true, addr, accessor, this->_openBus, this->_openBus));
} else {
- uint8_t value = accessor->read(addr - accessor->getStart());
+ uint8_t value = accessor->read(accessor->getRelativeAddress(addr));
this->_model.log(BusLog(false, addr, accessor, value, value));
}
}
@@ -168,7 +168,7 @@ namespace ComSquare::Debugger
std::optional value = std::nullopt;
try {
if (accessor)
- value = accessor->read(addr - accessor->getStart());
+ value = accessor->read(accessor->getRelativeAddress(addr));
} catch (InvalidAddress &) {
value = std::nullopt;
}
@@ -177,7 +177,7 @@ namespace ComSquare::Debugger
MemoryBus::write(addr, data);
}
- BusLog::BusLog(bool _write, uint24_t _addr, std::shared_ptr &_accessor, std::optional _oldData, uint8_t _newData) :
+ BusLog::BusLog(bool _write, uint24_t _addr, std::shared_ptr &_accessor, std::optional _oldData, uint8_t _newData) :
write(_write), addr(_addr), accessor(std::move(_accessor)), oldData(_oldData), newData(_newData)
{}
}
@@ -206,8 +206,10 @@ QVariant BusLogModel::data(const QModelIndex &index, int role) const
return QString(ComSquare::Utility::to_hex(log.addr).c_str());
case 2:
return QString(log.accessor ? log.accessor->getName().c_str() : "Bus");
- case 3:
- return QString(log.accessor ? log.accessor->getValueName(log.addr - log.accessor->getStart()).c_str() : "Open bus");
+ case 3: {
+ uint24_t addr = log.accessor->getRelativeAddress(log.addr);
+ return QString(log.accessor ? log.accessor->getValueName(addr).c_str() : "Open bus");
+ }
case 4:
if (!log.oldData)
return QString("???");
diff --git a/sources/Debugger/MemoryBusDebug.hpp b/sources/Debugger/MemoryBusDebug.hpp
index c477d2d..1f19be1 100644
--- a/sources/Debugger/MemoryBusDebug.hpp
+++ b/sources/Debugger/MemoryBusDebug.hpp
@@ -17,13 +17,13 @@ namespace ComSquare::Debugger
struct BusLog {
BusLog(bool write,
uint24_t addr,
- std::shared_ptr &accessor,
+ std::shared_ptr &accessor,
std::optional oldData,
uint8_t newData);
bool write;
uint24_t addr;
- std::shared_ptr accessor;
+ std::shared_ptr accessor;
std::optional oldData;
uint8_t newData;
};
diff --git a/sources/Debugger/MemoryViewer.cpp b/sources/Debugger/MemoryViewer.cpp
index 2e1b6b4..01b29ff 100644
--- a/sources/Debugger/MemoryViewer.cpp
+++ b/sources/Debugger/MemoryViewer.cpp
@@ -35,7 +35,7 @@ QVariant MemoryViewerModel::data(const QModelIndex &index, int role) const
if (role != Qt::DisplayRole)
return QVariant();
char buf[3];
- snprintf(buf, 3, "%02X", this->_memory->read_internal((index.row() << 4u) + index.column()));
+ snprintf(buf, 3, "%02X", this->_memory->read((index.row() << 4u) + index.column()));
return QString(buf);
}
@@ -149,31 +149,31 @@ namespace ComSquare::Debugger
value = this->switchToAddrTab(value);
} catch (InvalidAddress &) {}
}
- QModelIndex index = this->_ui.tableView->model()->index(value >> 4, value & 0x0000000F);
+ QModelIndex index = this->_ui.tableView->model()->index(value >> 4, value & 0x0F);
this->_ui.tableView->scrollTo(index);
this->_ui.tableView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
}
unsigned MemoryViewer::switchToAddrTab(uint24_t addr)
{
- std::shared_ptr accessor = this->_bus.getAccessor(addr);
+ std::shared_ptr accessor = this->_bus.getAccessor(addr);
if (!accessor)
throw InvalidAddress("Memory viewer switch to address", addr);
- Memory::AMemory *ptr;
- if (accessor->isMirror())
- ptr = accessor->getMirrored().get();
- else
- ptr = accessor.get();
- if (ptr == this->_snes.wram.get())
+ switch (accessor->getComponent()) {
+ case WRam:
this->_ui.tabs->setCurrentIndex(0);
- else if (ptr == this->_snes.sram.get())
+ break;
+ case SRam:
this->_ui.tabs->setCurrentIndex(1);
- else if (ptr == this->_snes.cartridge.get())
+ break;
+ case Rom:
this->_ui.tabs->setCurrentIndex(2);
- else
+ break;
+ default:
throw InvalidAddress("Memory viewer switch to address", addr);
- return addr - accessor->getStart();
+ }
+ return accessor->getRelativeAddress(addr);
}
void MemoryViewer::focus()
diff --git a/sources/Debugger/RegisterViewer.cpp b/sources/Debugger/RegisterViewer.cpp
index 1dfcc90..dba6ee3 100644
--- a/sources/Debugger/RegisterViewer.cpp
+++ b/sources/Debugger/RegisterViewer.cpp
@@ -45,7 +45,7 @@ namespace ComSquare::Debugger
model->addRegister(Register(0x4300, ":3", "Fixed", [i](SNES &snes) {
return snes.cpu->_dmaChannels[i]._controlRegister.fixed;
}, nullptr, Boolean));
- model->addRegister(Register(0x4300, ":4", "Increment", [i](SNES &snes) {
+ model->addRegister(Register(0x4300, ":4", "Decrement", [i](SNES &snes) {
return snes.cpu->_dmaChannels[i]._controlRegister.increment;
}, nullptr, Boolean));
model->addRegister(Register(0x4300, ":0-2", "Mode", [i](SNES &snes) {
diff --git a/sources/Memory/AMemory.cpp b/sources/Memory/AMemory.cpp
index ce51b16..3132424 100644
--- a/sources/Memory/AMemory.cpp
+++ b/sources/Memory/AMemory.cpp
@@ -3,10 +3,14 @@
//
#include "AMemory.hpp"
-#include
namespace ComSquare::Memory
{
+ uint24_t AMemory::getRelativeAddress(uint24_t addr)
+ {
+ return addr - this->_start;
+ }
+
void AMemory::setMemoryRegion(uint24_t start, uint24_t end)
{
this->_start = start;
@@ -18,17 +22,12 @@ namespace ComSquare::Memory
return this->_start <= addr && addr <= this->_end;
}
- uint32_t AMemory::getStart()
- {
- return this->_start;
- }
-
bool AMemory::isMirror()
{
return false;
}
- std::shared_ptr AMemory::getMirrored()
+ std::shared_ptr AMemory::getMirrored()
{
return nullptr;
}
diff --git a/sources/Memory/AMemory.hpp b/sources/Memory/AMemory.hpp
index 1450261..210aa49 100644
--- a/sources/Memory/AMemory.hpp
+++ b/sources/Memory/AMemory.hpp
@@ -2,9 +2,7 @@
// Created by anonymus-raccoon on 1/23/20.
//
-#ifndef COMSQUARE_AMEMORY_HPP
-#define COMSQUARE_AMEMORY_HPP
-
+#pragma once
#include
#include
@@ -12,27 +10,23 @@
#include
#include "../Models/Int24.hpp"
#include "../Models/Components.hpp"
+#include "IMemory.hpp"
namespace ComSquare::Memory
{
- //! @brief Common interface implemented by all components mapping memory.
- class AMemory {
- private:
+ //! @brief Abstract class representing a continuous block of memory.
+ class AMemory : public IMemory {
+ protected:
//! @brief The starting address mapped to this component.
uint24_t _start = 0;
//! @brief The last continuous address mapped to this components. For shadows, see the MemoryShadow class.
uint24_t _end = 0;
public:
- //! @brief Read data from the component.
- //! @param addr The local address to read from (0x0 should refer to the first byte of this component).
- //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
- //! @return Return the data at the address given as parameter.
- virtual uint8_t read(uint24_t addr) = 0;
- //! @brief Write data to this component.
- //! @param addr The local address to write data (0x0 should refer to the first byte of this component).
- //! @param data The new data to write.
- //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
- virtual void write(uint24_t addr, uint8_t data) = 0;
+ //! @brief Translate an absolute address to a relative address
+ //! @param addr The absolute address (in the 24 bit bus)
+ //! @return The local address (0 refers to the first byte of this component).
+ //! @throw InvalidAddress is thrown if the address is not mapped by this component.
+ virtual uint24_t getRelativeAddress(uint24_t addr) override;
//! @brief Change starting and ending points of this mapped memory.
//! @param start The first address mapped to this component.
//! @param end The last address mapped to this component.
@@ -41,26 +35,16 @@ namespace ComSquare::Memory
//! @brief Return true if this component has mapped the address.
//! @param addr The address to check.
//! @return True if this address is mapped to the component. False otherwise.
- virtual bool hasMemoryAt(uint24_t addr);
- //! @brief Get the first address mapped to this component.
- //! @return the _start value.
- virtual uint24_t getStart();
+ virtual bool hasMemoryAt(uint24_t addr) override;
//! @brief Check if this memory is a mirror or not.
//! @return True if this memory is a mirror. False otherwise.
- virtual bool isMirror();
- //! @brief Get the name of this accessor (used for debug purpose)
- virtual std::string getName() = 0;
- //! @brief Get the component of this accessor (used for debug purpose)
- virtual Component getComponent() = 0;
+ virtual bool isMirror() override;
//! @brief Get the name of the data at the address
//! @param addr The address (in local space)
- virtual std::string getValueName(uint24_t addr);
+ virtual std::string getValueName(uint24_t addr) override;
//! @brief Return the memory accessor this accessor mirror if any
//! @return nullptr if isMirror is false, the source otherwise.
- virtual std::shared_ptr getMirrored();
- virtual ~AMemory() = default;
+ virtual std::shared_ptr getMirrored() override;
+ virtual ~AMemory() override = default;
};
-};
-
-
-#endif //COMSQUARE_AMEMORY_HPP
+}
\ No newline at end of file
diff --git a/sources/Memory/ARectangleMemory.cpp b/sources/Memory/ARectangleMemory.cpp
index e7e9ff4..5c6b392 100644
--- a/sources/Memory/ARectangleMemory.cpp
+++ b/sources/Memory/ARectangleMemory.cpp
@@ -9,38 +9,19 @@
namespace ComSquare::Memory
{
- uint8_t ARectangleMemory::read(uint24_t addr)
+ uint24_t ARectangleMemory::getRelativeAddress(uint24_t addr)
{
- addr += this->getStart();
uint8_t bank = addr >> 16u;
uint16_t page = addr;
unsigned bankCount = bank - this->_startBank;
unsigned pageCount = this->_endPage - this->_startPage;
if (bank < this->_startBank || bank > this->_endBank)
- throw InvalidAddress("Rectangle memory read Invalid Bank", addr);
+ throw InvalidAddress("Rectangle memory: Invalid Bank", addr);
if (page < this->_startPage || page > this->_endPage)
- throw InvalidAddress("Rectangle memory read Invalid Page", addr);
+ throw InvalidAddress("Rectangle memory: Invalid Page", addr);
page -= this->_startPage;
- page += pageCount * bankCount;
- return this->read_internal(page);
- }
-
- void ARectangleMemory::write(uint24_t addr, uint8_t data)
- {
- addr += this->getStart();
- uint8_t bank = addr >> 16u;
- uint16_t page = addr;
- unsigned bankCount = bank - this->_startBank;
- unsigned pageCount = this->_endPage - this->_startPage;
-
- if (bank < this->_startBank || bank > this->_endBank)
- throw InvalidRectangleAddress("Rectangle memory write Invalid Bank", addr, bank, this->_startBank, this->_endBank);
- if (page < this->_startPage || page > this->_endPage)
- throw InvalidRectangleAddress("Rectangle memory write Invalid Page", addr, page, this->_startPage, this->_endPage);
- page -= this->_startPage;
- page += pageCount * bankCount;
- this->write_internal(page, data);
+ return pageCount * bankCount + page;
}
bool ARectangleMemory::hasMemoryAt(uint24_t addr)
@@ -54,11 +35,6 @@ namespace ComSquare::Memory
return false;
}
- uint24_t ARectangleMemory::getStart()
- {
- return (this->_startBank << 16u) + this->_startPage;
- }
-
void ARectangleMemory::setMemoryRegion(uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage)
{
this->_startBank = startBank;
@@ -66,4 +42,19 @@ namespace ComSquare::Memory
this->_startPage = startPage;
this->_endPage = endPage;
}
+
+ bool ARectangleMemory::isMirror()
+ {
+ return false;
+ }
+
+ std::shared_ptr ARectangleMemory::getMirrored()
+ {
+ return nullptr;
+ }
+
+ std::string ARectangleMemory::getValueName(uint24_t)
+ {
+ return "???";
+ }
}
\ No newline at end of file
diff --git a/sources/Memory/ARectangleMemory.hpp b/sources/Memory/ARectangleMemory.hpp
index 0a8f028..e923bb3 100644
--- a/sources/Memory/ARectangleMemory.hpp
+++ b/sources/Memory/ARectangleMemory.hpp
@@ -2,16 +2,14 @@
// Created by anonymus-raccoon on 1/29/20.
//
-#ifndef COMSQUARE_ARECTANGLEMEMORY_HPP
-#define COMSQUARE_ARECTANGLEMEMORY_HPP
+#pragma once
-
-#include "AMemory.hpp"
+#include "IMemory.hpp"
namespace ComSquare::Memory
{
- //! @brief Superset of the AMemory to map non continuous rectangle to the memory. (A rectangle that spam across more than one bank but that does not start at 0000 or end at FFFF).
- class ARectangleMemory : public AMemory {
+ //! @brief Base memory class to map non continuous rectangle to the memory. (A rectangle that spam across more than one bank but that does not start at $0000 or end at $FFFF).
+ class ARectangleMemory : public IMemory {
protected:
//! @brief The first bank to map to.
uint8_t _startBank = 0;
@@ -22,33 +20,15 @@ namespace ComSquare::Memory
//! @brief The last address of each bank to map.
uint16_t _endPage = 0;
public:
- //! @brief Read data from the component using the same method as the basic AMemory.
- //! @param addr The global 24 bits address. This method is responsible of mapping to the component's read.
- //! @throw InvalidAddress if the address is not mapped to the component.
- //! @return Return the data at the address given as parameter.
- uint8_t read(uint24_t addr) override;
- //! @brief Write data to this component using the same method as the basic AMemory.
- //! @param addr The global 24 bits address. This method is responsible of mapping to the component's write.
- //! @param data The new data to write.
- //! @throw InvalidAddress if the address is not mapped to the component.
- void write(uint24_t addr, uint8_t data) override;
- //! @brief Internal component read. Implement this as you would implement a basic AMemory's read.
- //! @param addr The local address to read from. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous
- //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
- //! @return Return the data at the address given as parameter.
- virtual uint8_t read_internal(uint24_t addr) = 0;
- //! @brief Internal component write. Implement this as you would implement a basic AMemory's write.
- //! @param addr The local address to write to. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous
- //! @param data The new data to write.
- //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
- virtual void write_internal(uint24_t addr, uint8_t data) = 0;
+ //! @brief Translate an absolute address to a relative address
+ //! @param addr The absolute address (in the 24 bit bus)
+ //! @return The local address (0 refers to the first byte of this component).
+ //! @throw InvalidAddress is thrown if the address is not mapped by this component.
+ virtual uint24_t getRelativeAddress(uint24_t addr) override;
//! @brief Return true if this component has mapped the address.
//! @param addr The address to check.
//! @return True if this address is mapped to the component. False otherwise.
bool hasMemoryAt(uint24_t addr) override;
- //! @brief Get the first address mapped to this component.
- //! @return the _start value.
- uint24_t getStart() override;
//! @brief Change starting and ending points of this mapped memory.
//! @param startBank The first bank mapped to this component.
//! @param endBank The last bank mapped to this component.
@@ -56,7 +36,15 @@ namespace ComSquare::Memory
//! @param endPage The end page mapped to this component (every mapped banks will have this pages lower than this mapped)
//! @warning The start/end address should be a rectangle. To mirror memory, use the MemoryShadow class and not this one.
void setMemoryRegion(uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage);
+ //! @brief Check if this memory is a mirror or not.
+ //! @return True if this memory is a mirror. False otherwise.
+ virtual bool isMirror() override;
+ //! @brief Get the name of the data at the address
+ //! @param addr The address (in local space)
+ virtual std::string getValueName(uint24_t addr) override;
+ //! @brief Return the memory accessor this accessor mirror if any
+ //! @return nullptr if isMirror is false, the source otherwise.
+ virtual std::shared_ptr getMirrored() override;
+ virtual ~ARectangleMemory() override = default;
};
-}
-
-#endif //COMSQUARE_ARECTANGLEMEMORY_HPP
+}
\ No newline at end of file
diff --git a/sources/Memory/IMemory.hpp b/sources/Memory/IMemory.hpp
new file mode 100644
index 0000000..14370af
--- /dev/null
+++ b/sources/Memory/IMemory.hpp
@@ -0,0 +1,53 @@
+//
+// Created by anonymus-raccoon on 1/23/20.
+//
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include "../Models/Int24.hpp"
+#include "../Models/Components.hpp"
+
+namespace ComSquare::Memory
+{
+ //! @brief Common interface implemented by all components mapping memory.
+ class IMemory {
+ public:
+ //! @brief Read data from the component.
+ //! @param addr The local address to read from (0x0 should refer to the first byte of this component).
+ //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
+ //! @return Return the data at the address given as parameter.
+ virtual uint8_t read(uint24_t addr) = 0;
+ //! @brief Write data to this component.
+ //! @param addr The local address to write data (0x0 should refer to the first byte of this component).
+ //! @param data The new data to write.
+ //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
+ virtual void write(uint24_t addr, uint8_t data) = 0;
+ //! @brief Return true if this component has mapped the address.
+ //! @param addr The address to check.
+ //! @return True if this address is mapped to the component. False otherwise.
+ virtual bool hasMemoryAt(uint24_t addr) = 0;
+ //! @brief Translate an absolute address to a relative address
+ //! @param addr The absolute address (in the 24 bit bus)
+ //! @return The local address (0 refers to the first byte of this component).
+ //! @throw InvalidAddress is thrown if the address is not mapped by this component.
+ virtual uint24_t getRelativeAddress(uint24_t addr) = 0;
+ //! @brief Check if this memory is a mirror or not.
+ //! @return True if this memory is a mirror. False otherwise.
+ virtual bool isMirror() = 0;
+ //! @brief Get the name of this accessor (used for debug purpose)
+ virtual std::string getName() = 0;
+ //! @brief Get the component of this accessor (used for debug purpose)
+ virtual Component getComponent() = 0;
+ //! @brief Get the name of the data at the address
+ //! @param addr The address (in local space)
+ virtual std::string getValueName(uint24_t addr) = 0;
+ //! @brief Return the memory accessor this accessor mirror if any
+ //! @return nullptr if isMirror is false, the source otherwise.
+ virtual std::shared_ptr getMirrored() = 0;
+ virtual ~IMemory() = default;
+ };
+};
\ No newline at end of file
diff --git a/sources/Memory/MemoryBus.cpp b/sources/Memory/MemoryBus.cpp
index dca92ed..38d3ccc 100644
--- a/sources/Memory/MemoryBus.cpp
+++ b/sources/Memory/MemoryBus.cpp
@@ -11,9 +11,9 @@
namespace ComSquare::Memory
{
- std::shared_ptr MemoryBus::getAccessor(uint24_t addr)
+ std::shared_ptr MemoryBus::getAccessor(uint24_t addr)
{
- auto it = std::find_if(this->_memoryAccessors.begin(), this->_memoryAccessors.end(), [addr](std::shared_ptr &accessor)
+ auto it = std::find_if(this->_memoryAccessors.begin(), this->_memoryAccessors.end(), [addr](std::shared_ptr &accessor)
{
return accessor->hasMemoryAt(addr);
});
@@ -24,27 +24,27 @@ namespace ComSquare::Memory
uint8_t MemoryBus::read(uint24_t addr, bool silence)
{
- std::shared_ptr handler = this->getAccessor(addr);
+ std::shared_ptr handler = this->getAccessor(addr);
if (!handler) {
if (!silence)
std::cout << "Unknown memory accessor for address $" << std::hex << addr << ". Using open bus." << std::endl;
return this->_openBus;
}
- uint8_t data = handler->read(addr - handler->getStart());
+ uint8_t data = handler->read(handler->getRelativeAddress(addr));
this->_openBus = data;
return data;
}
void MemoryBus::write(uint24_t addr, uint8_t data)
{
- std::shared_ptr handler = this->getAccessor(addr);
+ std::shared_ptr handler = this->getAccessor(addr);
if (!handler) {
std::cout << "Unknown memory accessor for address " << std::hex << addr << ". Warning, it was a write." << std::endl;
return;
}
- handler->write(addr - handler->getStart(), data);
+ handler->write(handler->getRelativeAddress(addr), data);
}
void MemoryBus::_mirrorComponents(SNES &console, unsigned i)
@@ -72,7 +72,6 @@ namespace ComSquare::Memory
console.cpu->setMemoryRegion(0x4200, 0x44FF);
this->_memoryAccessors.push_back(console.cpu);
- // TODO implement DMA & HDMA (4220 to 4300)
// TODO implement Joys.
// Mirror to the quarter 1.
diff --git a/sources/Memory/MemoryBus.hpp b/sources/Memory/MemoryBus.hpp
index 044462d..301dcd4 100644
--- a/sources/Memory/MemoryBus.hpp
+++ b/sources/Memory/MemoryBus.hpp
@@ -20,7 +20,7 @@ namespace ComSquare
class MemoryBus {
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.
- std::vector> _memoryAccessors;
+ std::vector> _memoryAccessors;
//! @brief WRam, CPU, PPU & APU registers are mirrored to all banks of Q1 & Q3. This function is used for the mirroring.
//! @param console All the components.
@@ -56,7 +56,7 @@ namespace ComSquare
//! @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.
- std::shared_ptr getAccessor(uint24_t addr);
+ std::shared_ptr getAccessor(uint24_t addr);
//! @brief Return true if the Bus is overloaded with debugging features.
virtual bool isDebugger();
diff --git a/sources/Memory/MemoryShadow.cpp b/sources/Memory/MemoryShadow.cpp
index ecc4b4f..4912fc5 100644
--- a/sources/Memory/MemoryShadow.cpp
+++ b/sources/Memory/MemoryShadow.cpp
@@ -8,7 +8,7 @@
namespace ComSquare::Memory
{
- MemoryShadow::MemoryShadow(std::shared_ptr initial, uint24_t start, uint24_t end)
+ MemoryShadow::MemoryShadow(std::shared_ptr initial, uint24_t start, uint24_t end)
: _initial(std::move(initial))
{
this->setMemoryRegion(start, end);
@@ -29,7 +29,7 @@ namespace ComSquare::Memory
return true;
}
- std::shared_ptr MemoryShadow::getMirrored()
+ std::shared_ptr MemoryShadow::getMirrored()
{
return this->_initial;
}
diff --git a/sources/Memory/MemoryShadow.hpp b/sources/Memory/MemoryShadow.hpp
index 7c33c43..519a4c6 100644
--- a/sources/Memory/MemoryShadow.hpp
+++ b/sources/Memory/MemoryShadow.hpp
@@ -2,8 +2,7 @@
// Created by anonymus-raccoon on 1/28/20.
//
-#ifndef COMSQUARE_MEMORYSHADOW_HPP
-#define COMSQUARE_MEMORYSHADOW_HPP
+#pragma once
#include
#include "AMemory.hpp"
@@ -13,10 +12,10 @@ namespace ComSquare::Memory
class MemoryShadow : public AMemory {
private:
//! @brief Memory to shadow from.
- std::shared_ptr _initial;
+ std::shared_ptr _initial;
public:
//! @brief Create a shadow for the memory given as parameter.
- explicit MemoryShadow(std::shared_ptr initial, uint24_t start, uint24_t end);
+ MemoryShadow(std::shared_ptr initial, uint24_t start, uint24_t end);
MemoryShadow(const MemoryShadow &) = default;
MemoryShadow &operator=(const MemoryShadow &) = default;
~MemoryShadow() = default;
@@ -40,8 +39,6 @@ namespace ComSquare::Memory
Component getComponent() override;
//! @brief Return the memory accessor this accessor mirror if any
//! @return nullptr if isMirror is false, the source otherwise.
- std::shared_ptr getMirrored() override;
+ std::shared_ptr getMirrored() override;
};
-}
-
-#endif //COMSQUARE_MEMORYSHADOW_HPP
+}
\ No newline at end of file
diff --git a/sources/Memory/RectangleShadow.cpp b/sources/Memory/RectangleShadow.cpp
index 424724a..182a4fc 100644
--- a/sources/Memory/RectangleShadow.cpp
+++ b/sources/Memory/RectangleShadow.cpp
@@ -3,29 +3,35 @@
//
#include "RectangleShadow.hpp"
-#include "../Utility/Utility.hpp"
-
#include
#include
namespace ComSquare::Memory
{
- RectangleShadow::RectangleShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage)
+ RectangleShadow::RectangleShadow(std::shared_ptr initial,
+ uint8_t startBank,
+ uint8_t endBank,
+ uint16_t startPage,
+ uint16_t endPage)
: _initial(std::move(initial))
{
this->setMemoryRegion(startBank, endBank, startPage, endPage);
}
- uint8_t RectangleShadow::read_internal(uint24_t addr)
+ uint24_t RectangleShadow::getRelativeAddress(uint24_t addr)
{
- addr += this->_bankOffset * (this->_endPage - this->_startPage);
- return this->_initial->read_internal(addr);
+ uint24_t base = ARectangleMemory::getRelativeAddress(addr);
+ return base + this->_bankOffset * (this->_endPage - this->_startPage);
}
- void RectangleShadow::write_internal(uint24_t addr, uint8_t data)
+ uint8_t RectangleShadow::read(uint24_t addr)
{
- addr += this->_bankOffset * (this->_endPage - this->_startPage);
- this->_initial->write_internal(addr, data);
+ return this->_initial->read(addr);
+ }
+
+ void RectangleShadow::write(uint24_t addr, uint8_t data)
+ {
+ return this->_initial->write(addr, data);
}
RectangleShadow *RectangleShadow::setBankOffset(uint8_t bankOffset)
@@ -39,7 +45,7 @@ namespace ComSquare::Memory
return true;
}
- std::shared_ptr RectangleShadow::getMirrored()
+ std::shared_ptr RectangleShadow::getMirrored()
{
return this->_initial;
}
diff --git a/sources/Memory/RectangleShadow.hpp b/sources/Memory/RectangleShadow.hpp
index 365c85f..2c6cb24 100644
--- a/sources/Memory/RectangleShadow.hpp
+++ b/sources/Memory/RectangleShadow.hpp
@@ -2,8 +2,7 @@
// Created by anonymus-raccoon on 2/4/20.
//
-#ifndef COMSQUARE_RECTANGLESHADOW_HPP
-#define COMSQUARE_RECTANGLESHADOW_HPP
+#pragma once
#include
#include "ARectangleMemory.hpp"
@@ -14,26 +13,31 @@ namespace ComSquare::Memory
class RectangleShadow : public ARectangleMemory {
private:
//! @brief Memory to shadow from.
- std::shared_ptr _initial;
+ std::shared_ptr _initial;
//! @brief The number of banks to add to the memory before accessing it from the initial data.
uint8_t _bankOffset = 0;
public:
//! @brief Create a shadow for the memory given as parameter.
- explicit RectangleShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage);
+ explicit RectangleShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage);
RectangleShadow(const RectangleShadow &) = default;
RectangleShadow &operator=(const RectangleShadow &) = default;
~RectangleShadow() override = default;
- //! @brief Internal component read. Implement this as you would implement a basic AMemory's read.
- //! @param addr The local address to read from. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous
- //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
- //! @return Return the data at the address given as parameter.
- uint8_t read_internal(uint24_t addr) override;
- //! @brief Internal component write. Implement this as you would implement a basic AMemory's write.
- //! @param addr The local address to write to. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous
- //! @param data The new data to write.
- //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
- void write_internal(uint24_t addr, uint8_t data) override;
+ //! @brief Read from the initial AMemory given.
+ //! @param addr The address to read from. The address 0x0 should refer to the first byte of the initial AMemory.
+ //! @throw InvalidAddress will be thrown if the address is more than the size of the initial AMemory.
+ //! @return Return the data at the address.
+ uint8_t read(uint24_t addr) override;
+ //! @brief Write data to the ram.
+ //! @param addr The address to write to. The address 0x0 should refer to the first byte of the initial AMemory.
+ //! @param data The data to write.
+ //! @throw InvalidAddress will be thrown if the address is more than the size of the initial AMemory.
+ void write(uint24_t addr, uint8_t data) override;
+ //! @brief Translate an absolute address to a relative address
+ //! @param addr The absolute address (in the 24 bit bus)
+ //! @return The local address (0 refers to the first byte of this component).
+ //! @throw InvalidAddress is thrown if the address is not mapped by this component.
+ uint24_t getRelativeAddress(uint24_t addr) override;
//! @brief Check if this memory is a mirror or not.
//! @return True if this memory is a mirror. False otherwise.
bool isMirror() override;
@@ -43,10 +47,8 @@ namespace ComSquare::Memory
Component getComponent() override;
//! @brief Return the memory accessor this accessor mirror if any
//! @return nullptr if isMirror is false, the source otherwise.
- std::shared_ptr getMirrored() override;
+ std::shared_ptr getMirrored() override;
RectangleShadow *setBankOffset(uint8_t bankOffset);
};
-}
-
-#endif //COMSQUARE_RECTANGLESHADOW_HPP
+}
\ No newline at end of file
diff --git a/sources/PPU/Backgrounds.cpp b/sources/PPU/Backgrounds.cpp
index c7d01dc..5919990 100644
--- a/sources/PPU/Backgrounds.cpp
+++ b/sources/PPU/Backgrounds.cpp
@@ -2,14 +2,9 @@
// Created by cbihan on 5/14/20.
//
-#include
#include
#include "PPU.hpp"
#include "PPUUtils.hpp"
-#include "../Exceptions/NotImplementedException.hpp"
-#include "../Exceptions/InvalidAddress.hpp"
-#include "../Ram/Ram.hpp"
-#include "../Models/Vector2.hpp"
namespace ComSquare::PPU
{
@@ -50,8 +45,8 @@ namespace ComSquare::PPU
union TileMapData tileData;
std::vector palette;
int index = 0;
- uint8_t reference = 0;
- uint32_t color = 0;
+ uint8_t reference;
+ uint32_t color;
tileData.raw = data;
graphicAddress = this->getGraphicVramAddress(tileData.posX, tileData.posY, bg, bpp);
@@ -106,7 +101,7 @@ namespace ComSquare::PPU
uint8_t PPU::getTilePixelReference(uint16_t addr, int bpp, int nb)
{
- uint8_t reference = this->vram->read_internal(addr);
+ uint8_t reference = this->vram->read(addr);
switch (bpp) {
case 8:
@@ -123,13 +118,13 @@ namespace ComSquare::PPU
void PPU::drawBasicTileMap(uint16_t baseAddress, int bgNumber, int bpp, Vector2 characterSize, Vector2 offset)
{
- uint16_t tileMapValue = 0;
+ uint16_t tileMapValue;
Vector2 pos(0,0);
uint16_t vramAddress = baseAddress;
while (vramAddress < 0x800 + baseAddress) {
- tileMapValue = this->vram->read_internal(vramAddress);
- tileMapValue += this->vram->read_internal(vramAddress + 1) << 8U;
+ tileMapValue = this->vram->read(vramAddress);
+ tileMapValue += this->vram->read(vramAddress + 1) << 8U;
vramAddress += 2;
drawBgTile(tileMapValue, {(pos.x * characterSize.x) + offset.x, (pos.y * characterSize.y) + offset.y}, bgNumber, bpp, characterSize);
if (pos.x % 31 == 0 && pos.x) {
diff --git a/sources/PPU/PPU.cpp b/sources/PPU/PPU.cpp
index a8389ba..f931a8e 100644
--- a/sources/PPU/PPU.cpp
+++ b/sources/PPU/PPU.cpp
@@ -5,11 +5,8 @@
#include
#include
#include "PPU.hpp"
-#include "PPUUtils.hpp"
#include "../Exceptions/NotImplementedException.hpp"
#include "../Exceptions/InvalidAddress.hpp"
-#include "../Ram/Ram.hpp"
-#include "../Models/Vector2.hpp"
namespace ComSquare::PPU
{
@@ -21,7 +18,7 @@ namespace ComSquare::PPU
{
this->_registers._isLowByte = true;
for (int i = 0; i < 512; i++) {
- this->cgram->write_internal(i, random() % 255);
+ this->cgram->write(i, random() % 255);
}
}
@@ -45,7 +42,7 @@ namespace ComSquare::PPU
case ppuRegisters::stat78:
return 0;
default:
- throw InvalidAddress("PPU Internal Registers read ", addr + this->getStart());
+ throw InvalidAddress("PPU Internal Registers read ", addr + this->_start);
}
}
@@ -69,7 +66,7 @@ namespace ComSquare::PPU
//throw InvalidAddress("oamdata", addr);
std::cout << "oamdata" << std::endl;
// the oamAddress have to be calculated if fblank or not (not implemented)
- oamram->write_internal(this->_registers._oamadd.oamAddress, this->_registers._oamdata);
+ oamram->write(this->_registers._oamadd.oamAddress, this->_registers._oamdata);
this->_registers._oamadd.oamAddress++;
break;
case ppuRegisters::bgmode:
@@ -126,7 +123,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatal" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatal = data;
- this->vram->write_internal(this->getVramAddress(), data);
+ this->vram->write(this->getVramAddress(), data);
}
if (!this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -135,7 +132,7 @@ namespace ComSquare::PPU
//std::cout << "vmdatah" << std::endl;
if (!this->_registers._inidisp.fblank) {
this->_registers._vmdata.vmdatah = data;
- this->vram->write_internal(this->getVramAddress() + 1, data);
+ this->vram->write(this->getVramAddress() + 1, data);
}
if (this->_registers._vmain.incrementMode)
this->_registers._vmadd.vmadd += this->_registers._incrementAmount;
@@ -163,9 +160,9 @@ namespace ComSquare::PPU
}
else {
this->_registers._cgdata.cgdatah = data;
- this->cgram->write_internal(this->_registers._cgadd, this->_registers._cgdata.cgdatal);
+ this->cgram->write(this->_registers._cgadd, this->_registers._cgdata.cgdatal);
this->_registers._cgadd++;
- this->cgram->write_internal(this->_registers._cgadd, this->_registers._cgdata.cgdatah);
+ this->cgram->write(this->_registers._cgadd, this->_registers._cgdata.cgdatah);
this->_registers._cgadd++;
}
this->_registers._isLowByte = !this->_registers._isLowByte;
@@ -215,7 +212,7 @@ namespace ComSquare::PPU
break;
//TODO adding the rest of the registers. oaf !
default:
- throw InvalidAddress("PPU Internal Registers write", addr + this->getStart());
+ throw InvalidAddress("PPU Internal Registers write", addr + this->_start);
}
}
@@ -233,6 +230,7 @@ namespace ComSquare::PPU
case 0b11:
return (vanillaAddress & 0xFC00U) | (vanillaAddress & 0x0380U) >> 7U | (vanillaAddress & 0x7FU) << 3U;
}
+ throw InvalidAddress("Invalid vram address", vanillaAddress);
}
void PPU::update(unsigned cycles)
@@ -242,23 +240,23 @@ namespace ComSquare::PPU
uint8_t red;
uint8_t green;
uint8_t blue;
- uint32_t pixelTmp = 0x0;
+ uint32_t pixelTmp;
if (!this->_registers._inidisp.fblank) {
- for (int y = 0; y <= 255; y += 2) {
- tmp = this->cgram->read_internal(y);
- tmp += this->cgram->read_internal(y + 1) << 8;
- blue = (tmp & 0x7D00U) >> 10U;
- green = (tmp & 0x03E0U) >> 5U;
- red = (tmp & 0x001FU);
+ for (int y = 0; y <= 255; y += 2) {
+ tmp = this->cgram->read(y);
+ tmp += this->cgram->read(y + 1) << 8;
+ blue = (tmp & 0x7D00U) >> 10U;
+ green = (tmp & 0x03E0U) >> 5U;
+ red = (tmp & 0x001FU);
- pixelTmp = this->_registers._inidisp.brightness * 255U / 15U;
- pixelTmp += (red * 255U / 31U) << 24U;
- pixelTmp += (green * 255U / 31U) << 16U;
- pixelTmp += (blue * 255U / 31U) << 8U;
+ pixelTmp = this->_registers._inidisp.brightness * 255U / 15U;
+ pixelTmp += (red * 255U / 31U) << 24U;
+ pixelTmp += (green * 255U / 31U) << 16U;
+ pixelTmp += (blue * 255U / 31U) << 8U;
- for (int x = 0; x < 100; x++)
- this->_renderer.putPixel(x, y, pixelTmp);
- }
+ for (int x = 0; x < 100; x++)
+ this->_renderer.putPixel(x, y, pixelTmp);
+ }
}
this->renderBackground(1, {8, 8}, 4, false);
this->_renderer.drawScreen();
@@ -417,6 +415,6 @@ namespace ComSquare::PPU
uint16_t PPU::cgramRead(uint16_t addr)
{
- return this->cgram->read_internal(addr);
+ return this->cgram->read(addr);
}
}
\ No newline at end of file
diff --git a/sources/PPU/PPU.hpp b/sources/PPU/PPU.hpp
index 38aceaf..c8cdf30 100644
--- a/sources/PPU/PPU.hpp
+++ b/sources/PPU/PPU.hpp
@@ -5,11 +5,10 @@
#ifndef COMSQUARE_PPU_HPP
#define COMSQUARE_PPU_HPP
-#include
+#include
#include "../Memory/AMemory.hpp"
#include "../Memory/MemoryBus.hpp"
#include "../Renderer/IRenderer.hpp"
-//#include "../Ram/ExtendedRam.hpp"
#include "../Ram/Ram.hpp"
#include "../Models/Vector2.hpp"
diff --git a/sources/Ram/Ram.cpp b/sources/Ram/Ram.cpp
index 100901d..da6ab26 100644
--- a/sources/Ram/Ram.cpp
+++ b/sources/Ram/Ram.cpp
@@ -27,29 +27,20 @@ namespace ComSquare::Ram
delete[] this->_data;
}
- uint8_t Ram::read_internal(uint24_t addr)
+ uint8_t Ram::read(uint24_t addr)
{
if (addr >= this->_size)
- throw InvalidAddress("Ram read", addr);
+ throw InvalidAddress(this->getName() + " read", addr);
return this->_data[addr];
}
- void Ram::write_internal(uint24_t addr, uint8_t data)
+ void Ram::write(uint24_t addr, uint8_t data)
{
if (addr >= this->_size)
- throw InvalidAddress("Ram write", addr);
+ throw InvalidAddress(this->getName() + " write", addr);
this->_data[addr] = data;
}
- void Ram::memset(uint24_t start, uint24_t end, uint8_t value)
- {
- if (end >= this->_size)
- throw InvalidAddress("Ram memset end", end);
- if (start >= end)
- throw InvalidAddress("Ram memset start", start);
- std::memset(&this->_data[start], value, sizeof(uint8_t) * (end - start));
- }
-
size_t Ram::getSize()
{
return this->_size;
diff --git a/sources/Ram/Ram.hpp b/sources/Ram/Ram.hpp
index 2a68e36..4fe2a41 100644
--- a/sources/Ram/Ram.hpp
+++ b/sources/Ram/Ram.hpp
@@ -29,22 +29,18 @@ namespace ComSquare::Ram
Ram &operator=(Ram &) = delete;
//! @brief Destructor that free the ram.
~Ram() override;
- //! @brief Read from the ram.
- //! @param addr The address to read from. The address 0x0 should refer to the first byte of this ram.
- //! @throw InvalidAddress will be thrown if the address is more than the size of the ram.
- //! @return Return the data at the address.
- uint8_t read_internal(uint24_t addr) override;
- //! @brief Write data to the ram.
- //! @param addr The address to write to. The address 0x0 should refer to the first byte of this ram.
- //! @param data The data to write.
- //! @throw InvalidAddress will be thrown if the address is more than the size of the ram.
- void write_internal(uint24_t addr, uint8_t data) override;
- //! @brief replace values between two addresses with a value
- //! @param start start address to replace
- //! @param end end address to replace
- //! @param value replace value
- void memset(uint24_t start, uint24_t end, uint8_t value);
+ //! @brief Read data from the component.
+ //! @param addr The local address to read from (0x0 should refer to the first byte of this component).
+ //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
+ //! @return Return the data at the address given as parameter.
+ uint8_t read(uint24_t addr) override;
+ //! @brief Write data to this component.
+ //! @param addr The local address to write data (0x0 should refer to the first byte of this component).
+ //! @param data The new data to write.
+ //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component.
+ void write(uint24_t addr, uint8_t data) override;
+
//! @brief Get the name of this accessor (used for debug purpose)
std::string getName() override;
diff --git a/tests/CPU/testDMA.cpp b/tests/CPU/testDMA.cpp
index 25b87d3..d35b02f 100644
--- a/tests/CPU/testDMA.cpp
+++ b/tests/CPU/testDMA.cpp
@@ -7,7 +7,8 @@
#include "../tests.hpp"
using namespace ComSquare;
-Test(DMA, RomToVRAM)
+//Test(DMA, RomToVRAM)
+int main()
{
Init()
snes.cartridge->_size = 4000000;
diff --git a/tests/testMemoryBus.cpp b/tests/testMemoryBus.cpp
index d41788a..cb8c9dc 100644
--- a/tests/testMemoryBus.cpp
+++ b/tests/testMemoryBus.cpp
@@ -6,13 +6,8 @@
#include
#include
#include "tests.hpp"
-#include "../sources/Memory/MemoryBus.hpp"
-#include "../sources/Memory/AMemory.hpp"
-#include "../sources/SNES.hpp"
-#include "../sources/Renderer/NoRenderer.hpp"
#include "../sources/Memory/MemoryShadow.hpp"
#include "../sources/Memory/RectangleShadow.hpp"
-#include "../sources/PPU/PPU.hpp"
#include "../sources/Exceptions/InvalidAction.hpp"
@@ -27,7 +22,7 @@ using namespace ComSquare;
Test(BusAccessor, GetWramStart)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = snes.bus->getAccessor(0x7E0000);
cr_assert_eq(accessor.get(), snes.wram.get());
@@ -36,7 +31,7 @@ Test(BusAccessor, GetWramStart)
Test(BusAccessor, GetWramEnd)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = snes.bus->getAccessor(0x7FFFFF);
cr_assert_eq(accessor.get(), snes.wram.get());
@@ -45,7 +40,7 @@ Test(BusAccessor, GetWramEnd)
Test(BusAccessor, GetWramMirror)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = std::static_pointer_cast(snes.bus->getAccessor(0x2F11FF));
cr_assert_neq(accessor, nullptr);
@@ -55,7 +50,7 @@ Test(BusAccessor, GetWramMirror)
Test(BusAccessor, GetWramMirror2)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = std::static_pointer_cast(snes.bus->getAccessor(0x100000));
cr_assert_neq(accessor, nullptr);
@@ -65,7 +60,7 @@ Test(BusAccessor, GetWramMirror2)
Test(BusAccessor, GetWramMirror3)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = std::static_pointer_cast(snes.bus->getAccessor(0x1010));
cr_assert_neq(accessor, nullptr);
@@ -75,14 +70,14 @@ Test(BusAccessor, GetWramMirror3)
Test(BusAccessor, GetOpenBus)
{
Init()
- std::shared_ptr accessor = snes.bus->getAccessor(0x897654);
+ std::shared_ptr accessor = snes.bus->getAccessor(0x897654);
cr_assert_eq(accessor.get(), nullptr);
}
Test(BusAccessor, GetSramStart)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = std::static_pointer_cast(snes.bus->getAccessor(0x700000));
cr_assert_eq(accessor->_initial.get(), snes.sram.get());
@@ -91,7 +86,7 @@ Test(BusAccessor, GetSramStart)
Test(BusAccessor, GetSramEnd)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = std::static_pointer_cast(snes.bus->getAccessor(0x7D7FFF));
cr_assert_eq(accessor->_initial.get(), snes.sram.get());
@@ -100,7 +95,7 @@ Test(BusAccessor, GetSramEnd)
Test(BusAccessor, GetSramMirror)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = std::static_pointer_cast(snes.bus->getAccessor(0xF00123));
cr_assert_eq(accessor.get(), snes.sram.get());
@@ -109,7 +104,7 @@ Test(BusAccessor, GetSramMirror)
Test(BusAccessor, GetAPUStart)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr accessor;
accessor = snes.bus->getAccessor(0x002140);
cr_assert_eq(accessor.get(), snes.apu.get());
@@ -118,7 +113,7 @@ Test(BusAccessor, GetAPUStart)
Test(BusAccessor, GetAPUEnd)
{
Init()
- std::shared_ptr accessor = nullptr;
+ std::shared_ptr