From 9132f2028f40a7bfa5b6ce1ebec21359697c8567 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sat, 3 Nov 2018 23:11:48 +0000 Subject: [PATCH] Add an "UnusedMemory" class to better allow "gaps" in the memory map. Signed-off-by: Adrian Conlon --- LR35902/inc/GameBoyBus.h | 21 ++++++++++--------- LR35902/src/GameBoyBus.cpp | 12 ----------- MC6809/test/Board.cpp | 3 --- MC6809/test/Board.h | 9 ++++---- inc/MemoryInterface.h | 26 +++++++++++++++++++++++ inc/UnusedMemory.h | 40 ++++++++++++++++++++++++++++++++++++ src/Bus.cpp | 3 +-- src/EightBit.vcxproj | 1 + src/EightBit.vcxproj.filters | 3 +++ 9 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 inc/MemoryInterface.h create mode 100644 inc/UnusedMemory.h diff --git a/LR35902/inc/GameBoyBus.h b/LR35902/inc/GameBoyBus.h index 6f9acd2..89e3672 100644 --- a/LR35902/inc/GameBoyBus.h +++ b/LR35902/inc/GameBoyBus.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "LR35902.h" #include "IoRegisters.h" @@ -59,16 +60,16 @@ namespace EightBit { private: LR35902 m_cpu; - Rom m_bootRom = 0x100; // 0x0000 - 0x00ff - std::vector m_gameRomBanks; // 0x0000 - 0x3fff, 0x4000 - 0x7fff (switchable) - Ram m_videoRam = 0x2000; // 0x8000 - 0x9fff - std::vector m_ramBanks; // 0xa000 - 0xbfff (switchable) - Rom m_unmapped2000 = 0x2000; // 0xa000 - 0xbfff - Ram m_lowInternalRam = 0x2000; // 0xc000 - 0xdfff (mirrored at 0xe000) - Ram m_oamRam = 0xa0; // 0xfe00 - 0xfe9f - Rom m_unmapped60 = 0x60; // 0xfea0 - 0xfeff - IoRegisters m_ioPorts; // 0xff00 - 0xff7f - Ram m_highInternalRam = 0x80; // 0xff80 - 0xffff + Rom m_bootRom = 0x100; // 0x0000 - 0x00ff + std::vector m_gameRomBanks; // 0x0000 - 0x3fff, 0x4000 - 0x7fff (switchable) + Ram m_videoRam = 0x2000; // 0x8000 - 0x9fff + std::vector m_ramBanks; // 0xa000 - 0xbfff (switchable) + UnusedMemory m_unmapped2000 = { 0x2000, 0xff }; // 0xa000 - 0xbfff + Ram m_lowInternalRam = 0x2000; // 0xc000 - 0xdfff (mirrored at 0xe000) + Ram m_oamRam = 0xa0; // 0xfe00 - 0xfe9f + UnusedMemory m_unmapped60 = { 0x60, 0xff }; // 0xfea0 - 0xfeff + IoRegisters m_ioPorts; // 0xff00 - 0xff7f + Ram m_highInternalRam = 0x80; // 0xff80 - 0xffff bool m_enabledLCD = false; diff --git a/LR35902/src/GameBoyBus.cpp b/LR35902/src/GameBoyBus.cpp index d2e424e..abdfc61 100644 --- a/LR35902/src/GameBoyBus.cpp +++ b/LR35902/src/GameBoyBus.cpp @@ -6,18 +6,6 @@ EightBit::GameBoy::Bus::Bus() noexcept : m_cpu(*this), m_ioPorts(*this) { WrittenByte.connect(std::bind(&GameBoy::Bus::Bus_WrittenByte, this, std::placeholders::_1)); - - { - std::vector content(m_unmapped2000.size()); - std::fill(content.begin(), content.end(), 0xff); - m_unmapped2000.load(content); - } - - { - std::vector content(m_unmapped60.size()); - std::fill(content.begin(), content.end(), 0xff); - m_unmapped60.load(content); - } } void EightBit::GameBoy::Bus::reset() { diff --git a/MC6809/test/Board.cpp b/MC6809/test/Board.cpp index 56856fa..df1c62e 100644 --- a/MC6809/test/Board.cpp +++ b/MC6809/test/Board.cpp @@ -5,9 +5,6 @@ Board::Board(const Configuration& configuration) : m_configuration(configuration), m_cpu(EightBit::mc6809(*this)), m_disassembler(*this, m_cpu) { - std::vector content(m_unused2000.size()); - std::fill(content.begin(), content.end(), 0xff); - m_unused2000.load(content); } void Board::initialise() { diff --git a/MC6809/test/Board.h b/MC6809/test/Board.h index bece7aa..3163877 100644 --- a/MC6809/test/Board.h +++ b/MC6809/test/Board.h @@ -9,6 +9,7 @@ #include #include #include +#include class Board : public EightBit::Bus { public: @@ -24,10 +25,10 @@ protected: private: const Configuration& m_configuration; - EightBit::Ram m_ram = 0x8000; // 0000 - 7FFF, 32K RAM - EightBit::Rom m_unused2000 = 0x2000; // 8000 - 9FFF, 8K unused - EightBit::Ram m_io = 0x2000; // A000 - BFFF, 8K serial interface, minimally decoded - EightBit::Rom m_rom = 0x4000; // C000 - FFFF, 16K ROM + EightBit::Ram m_ram = 0x8000; // 0000 - 7FFF, 32K RAM + EightBit::UnusedMemory m_unused2000 = { 0x2000, 0xff }; // 8000 - 9FFF, 8K unused + EightBit::Ram m_io = 0x2000; // A000 - BFFF, 8K serial interface, minimally decoded + EightBit::Rom m_rom = 0x4000; // C000 - FFFF, 16K ROM EightBit::mc6850 m_acia; diff --git a/inc/MemoryInterface.h b/inc/MemoryInterface.h new file mode 100644 index 0000000..d5a6ab6 --- /dev/null +++ b/inc/MemoryInterface.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace EightBit { + class MemoryInterface { + public: + virtual size_t size() const = 0; + virtual uint8_t peek(uint16_t address) const = 0; + + virtual uint8_t& reference(uint16_t) { + throw new std::logic_error("Reference operation not allowed."); + } + + virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0; + virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0; + virtual int load(const std::vector& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0; + + protected: + virtual void poke(uint16_t address, uint8_t value) = 0; + }; +} diff --git a/inc/UnusedMemory.h b/inc/UnusedMemory.h new file mode 100644 index 0000000..d81c5d6 --- /dev/null +++ b/inc/UnusedMemory.h @@ -0,0 +1,40 @@ +#pragma once + +#include "MemoryInterface.h" + +namespace EightBit { + class UnusedMemory final : public MemoryInterface { + public: + UnusedMemory(const size_t size, const uint8_t value) + : m_size(size), m_value(value) {} + virtual ~UnusedMemory() = default; + + virtual size_t size() const final { return m_size; } + virtual uint8_t peek(uint16_t address) const final { return m_value; } + + virtual uint8_t& reference(uint16_t) { + throw new std::logic_error("Reference operation not allowed."); + } + + virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) final { + throw new std::logic_error("load operation not allowed."); + } + + virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) final { + throw new std::logic_error("load operation not allowed."); + } + + virtual int load(const std::vector& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) final { + throw new std::logic_error("load operation not allowed."); + } + + protected: + virtual void poke(uint16_t address, uint8_t value) { + throw new std::logic_error("Poke operation not allowed."); + } + + private: + size_t m_size; + uint8_t m_value; + }; +} \ No newline at end of file diff --git a/src/Bus.cpp b/src/Bus.cpp index f9c8be5..03b080d 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -93,6 +93,5 @@ uint8_t& EightBit::Bus::reference(const uint16_t address) { const uint16_t offset = (address - mapped.begin) & mapped.mask; if (mapped.access == MemoryMapping::ReadOnly) return DATA() = mapped.memory.peek(offset); - Ram& ram = (Ram&)(mapped.memory); - return ram.reference(offset); + return mapped.memory.reference(offset); } diff --git a/src/EightBit.vcxproj b/src/EightBit.vcxproj index 30a7df3..51c5fdc 100644 --- a/src/EightBit.vcxproj +++ b/src/EightBit.vcxproj @@ -156,6 +156,7 @@ + diff --git a/src/EightBit.vcxproj.filters b/src/EightBit.vcxproj.filters index a7a5407..a16718d 100644 --- a/src/EightBit.vcxproj.filters +++ b/src/EightBit.vcxproj.filters @@ -62,6 +62,9 @@ Header Files + + Header Files +