From 235f14710905afc06653b8749e5ab0b58d31cf61 Mon Sep 17 00:00:00 2001
From: AnonymusRaccoon
Date: Tue, 28 Jan 2020 17:29:41 +0100
Subject: [PATCH] Adding shadows
---
CMakeLists.txt | 14 ++++++++++---
main.cpp | 1 +
sources/APU/APU.cpp | 6 +++---
sources/APU/APU.hpp | 4 ++--
sources/CPU/CPU.hpp | 4 ++--
sources/Memory/MemoryBus.cpp | 35 +++++++++++++++++++++++++++++++++
sources/Memory/MemoryBus.hpp | 7 +++++++
sources/Memory/MemoryShadow.cpp | 11 +++++++++--
sources/Memory/MemoryShadow.hpp | 6 ++++--
sources/Ram/Ram.hpp | 2 +-
sources/SNES.cpp | 8 ++++++--
sources/SNES.hpp | 13 ++++++++----
12 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d63be30..3a19583 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,8 @@ target_compile_options(unit_tests PUBLIC -fprofile-arcs -ftest-coverage)
# make app
add_executable(ComSquare
main.cpp
+ sources/SNES.cpp
+ sources/SNES.hpp
sources/Memory/MemoryBus.cpp
sources/Memory/MemoryBus.hpp
sources/Memory/IMemory.hpp
@@ -29,11 +31,17 @@ add_executable(ComSquare
sources/PPU/PPU.hpp
sources/CPU/CPU.cpp
sources/CPU/CPU.hpp
- sources/SNES.cpp
- sources/SNES.hpp
sources/Cartridge/Cartridge.cpp
sources/Cartridge/Cartridge.hpp
sources/Exceptions/NotImplementedException.hpp
sources/APU/APU.hpp
sources/APU/APU.cpp
- sources/Exceptions/InvalidAddress.hpp sources/Exceptions/InvalidRom.hpp sources/Models/Ints.hpp sources/Models/Ints.hpp sources/Ram/Ram.cpp sources/Ram/Ram.hpp sources/Memory/MemoryShadow.cpp sources/Memory/MemoryShadow.hpp)
+ sources/Exceptions/InvalidAddress.hpp
+ sources/Exceptions/InvalidRom.hpp
+ sources/Models/Ints.hpp
+ sources/Models/Ints.hpp
+ sources/Ram/Ram.cpp
+ sources/Ram/Ram.hpp
+ sources/Memory/MemoryShadow.cpp
+ sources/Memory/MemoryShadow.hpp
+)
diff --git a/main.cpp b/main.cpp
index 7544138..b93334c 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,5 +14,6 @@ int main(int argc, char **argv)
}
ComSquare::MemoryBus bus;
ComSquare::SNES snes(std::make_shared(bus), argv[1]);
+ bus.mapComponents(snes);
return 0;
}
\ No newline at end of file
diff --git a/sources/APU/APU.cpp b/sources/APU/APU.cpp
index 50b8750..3a2066e 100644
--- a/sources/APU/APU.cpp
+++ b/sources/APU/APU.cpp
@@ -8,9 +8,9 @@
namespace ComSquare::APU
{
- APU::APU(std::shared_ptr dsp)
- : _dsp(std::move(dsp))
- { }
+ APU::APU()
+ {
+ }
uint8_t APU::read(uint24_t addr)
{
diff --git a/sources/APU/APU.hpp b/sources/APU/APU.hpp
index 0fa7f48..8088257 100644
--- a/sources/APU/APU.hpp
+++ b/sources/APU/APU.hpp
@@ -105,12 +105,12 @@ namespace ComSquare::APU
class DSP {
};
- class APU : IMemory {
+ class APU : public IMemory {
private:
Registers _registers;
InternalRegisters _internalRegisters{};
public:
- explicit APU(std::shared_ptr dsp);
+ explicit APU();
//! @brief The DSP component used to produce sound
std::shared_ptr _dsp;
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index 51b9b53..f399295 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -174,12 +174,12 @@ namespace ComSquare::CPU
};
//! @brief The main CPU
- class CPU : IMemory {
+ class CPU : public IMemory {
private:
//! @brief All the registers of the CPU
Registers _registers{};
//! @brief Is the CPU running in emulation mode (in 8bits)
- bool _isEmulationMode{};
+ bool _isEmulationMode = true;
//! @brief Internal registers of the CPU (accessible from the bus via addr $4200 to $421F).
InternalRegisters _internalRegisters{};
//! @brief The memory bus to use for read/write.
diff --git a/sources/Memory/MemoryBus.cpp b/sources/Memory/MemoryBus.cpp
index bf9f1dc..837146d 100644
--- a/sources/Memory/MemoryBus.cpp
+++ b/sources/Memory/MemoryBus.cpp
@@ -5,6 +5,8 @@
#include
#include
#include "MemoryBus.hpp"
+#include "../SNES.hpp"
+#include "MemoryShadow.hpp"
namespace ComSquare
{
@@ -42,4 +44,37 @@ namespace ComSquare
}
handler->write(addr - handler->getStart(), data);
}
+
+ void MemoryBus::_mirrorComponents(SNES &console, int i)
+ {
+ this->_memoryAccessors.push_back(Memory::MemoryShadow::createShadow(console.wram, i, i + 0x2000));
+ this->_memoryAccessors.push_back(Memory::MemoryShadow::createShadow(console.cpu, i + 0x4200, i + 0x4220));
+ }
+
+ void MemoryBus::mapComponents(SNES &console)
+ {
+ // The WRam is always mapped in the bank 7E and 7F, no matter the memory mapping mode.
+ console.wram->setMemoryRegion(0x7E0000, 0x7FFFFF);
+ this->_memoryAccessors.push_back(console.wram);
+
+ console.ppu->setMemoryRegion(0x2100, 0x2140);
+ this->_memoryAccessors.push_back(console.ppu);
+
+ console.apu->setMemoryRegion(0x2140, 0x2144);
+ this->_memoryAccessors.push_back(console.apu);
+
+ console.cpu->setMemoryRegion(0x4200, 0x4220);
+ this->_memoryAccessors.push_back(console.cpu);
+
+ // TODO implement DMA & HDMA (4220 to 4300)
+
+ //Mirror the first $2000 bits of the WRam to all banks of the Q1 & Q3.
+ for (uint24_t i = 0; i < 0x400000; i += 0x10000) {
+ this->_mirrorComponents(console, i);
+ }
+ for (uint24_t i = 0x800000; i < 0xC00000; i += 0x10000) {
+ this->_memoryAccessors.push_back(Memory::MemoryShadow::createShadow(console.wram, i, i + 0x2000));
+ this->_memoryAccessors.push_back(Memory::MemoryShadow::createShadow(console.cpu, i + 0x4200, i + 0x4220));
+ }
+ }
}
\ No newline at end of file
diff --git a/sources/Memory/MemoryBus.hpp b/sources/Memory/MemoryBus.hpp
index fa5b097..3ad6c01 100644
--- a/sources/Memory/MemoryBus.hpp
+++ b/sources/Memory/MemoryBus.hpp
@@ -23,6 +23,10 @@ namespace ComSquare
std::shared_ptr getAccessor(uint24_t addr);
//! @brief The last value read via the memory bus.
uint8_t _openbus = 0;
+ //! @brief Mirror components to other banks. (Used by the mapComponents method).
+ //! @param console All the components.
+ //! @param i Base address for the mirrors.
+ inline void _mirrorComponents(struct SNES &console, int i);
public:
//! @brief Read data at a global address.
//! @param addr The address to read from.
@@ -32,6 +36,9 @@ namespace ComSquare
//! @param addr The address to write to.
//! @param data The data to write.
void write(uint24_t addr, uint8_t data);
+ //! @brief Map components to the address space using the currently loaded cartridge to set the right mapping mode.
+ //! @param console All the components.
+ void mapComponents(struct SNES &console);
};
}
diff --git a/sources/Memory/MemoryShadow.cpp b/sources/Memory/MemoryShadow.cpp
index b98e513..c9c14d0 100644
--- a/sources/Memory/MemoryShadow.cpp
+++ b/sources/Memory/MemoryShadow.cpp
@@ -8,9 +8,16 @@
namespace ComSquare::Memory
{
- MemoryShadow::MemoryShadow(std::shared_ptr initial)
+ MemoryShadow::MemoryShadow(std::shared_ptr initial, uint24_t start, uint24_t end)
: _initial(std::move(initial))
- { }
+ {
+ this->setMemoryRegion(start, end);
+ }
+
+ std::shared_ptr MemoryShadow::createShadow(std::shared_ptr initial, uint24_t start, uint24_t end)
+ {
+ return static_cast>(new MemoryShadow(std::move(initial), start, end));
+ }
uint8_t MemoryShadow::read(uint24_t addr)
{
diff --git a/sources/Memory/MemoryShadow.hpp b/sources/Memory/MemoryShadow.hpp
index 8bfb284..e848a3e 100644
--- a/sources/Memory/MemoryShadow.hpp
+++ b/sources/Memory/MemoryShadow.hpp
@@ -10,13 +10,15 @@
namespace ComSquare::Memory
{
- class MemoryShadow : IMemory {
+ class MemoryShadow : public IMemory {
private:
//! @brief Memory to shadow from.
std::shared_ptr _initial;
public:
//! @brief Create a shadow for the memory given as parameter.
- explicit MemoryShadow(std::shared_ptr initial);
+ explicit MemoryShadow(std::shared_ptr initial, uint24_t start, uint24_t end);
+
+ static std::shared_ptr createShadow(std::shared_ptr initial, uint24_t start, uint24_t end);
//! @brief Read from the initial IMemory given.
//! @param addr The address to read from. The address 0x0 should refer to the first byte of the initial IMemory.
//! @throw InvalidAddress will be thrown if the address is more than the size of the initial IMemory.
diff --git a/sources/Ram/Ram.hpp b/sources/Ram/Ram.hpp
index 93b2b43..98b73cf 100644
--- a/sources/Ram/Ram.hpp
+++ b/sources/Ram/Ram.hpp
@@ -9,7 +9,7 @@
namespace ComSquare::Ram
{
- class Ram : IMemory {
+ class Ram : public IMemory {
private:
//! @brief The ram. (Can be used for WRam, SRam, VRam etc)
uint8_t *_data;
diff --git a/sources/SNES.cpp b/sources/SNES.cpp
index 9f15064..022a1aa 100644
--- a/sources/SNES.cpp
+++ b/sources/SNES.cpp
@@ -6,7 +6,11 @@
namespace ComSquare
{
- SNES::SNES(const std::shared_ptr &bus, const std::string &romPath)
- : _cpu(bus), _cartridge(romPath)
+ SNES::SNES(const std::shared_ptr &bus, const std::string &romPath) :
+ cpu(new CPU::CPU(bus)),
+ ppu(new PPU::PPU()),
+ apu(new APU::APU()),
+ cartridge(new Cartridge::Cartridge(romPath)),
+ wram(new Ram::Ram(16384))
{ }
}
diff --git a/sources/SNES.hpp b/sources/SNES.hpp
index 946b604..8adc2f1 100644
--- a/sources/SNES.hpp
+++ b/sources/SNES.hpp
@@ -8,15 +8,20 @@
#include "Memory/MemoryBus.hpp"
#include "CPU/CPU.hpp"
#include "Cartridge/Cartridge.hpp"
+#include "Ram/Ram.hpp"
+#include "PPU/PPU.hpp"
+#include "APU/APU.hpp"
namespace ComSquare
{
//! @brief Container of all the components of the SNES.
- class SNES {
- private:
- CPU::CPU _cpu;
- Cartridge::Cartridge _cartridge;
+ struct SNES {
public:
+ std::shared_ptr cpu;
+ std::shared_ptr ppu;
+ std::shared_ptr apu;
+ std::shared_ptr cartridge;
+ std::shared_ptr wram;
//! @brief Create all the components using a common memory bus for all of them.
SNES(const std::shared_ptr &bus, const std::string &ramPath);
};