mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-22 09:30:32 +00:00
Add an "UnusedMemory" class to better allow "gaps" in the memory map.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
984626a331
commit
9132f2028f
@ -7,6 +7,7 @@
|
||||
#include <Ram.h>
|
||||
#include <Bus.h>
|
||||
#include <Register.h>
|
||||
#include <UnusedMemory.h>
|
||||
|
||||
#include "LR35902.h"
|
||||
#include "IoRegisters.h"
|
||||
@ -59,16 +60,16 @@ namespace EightBit {
|
||||
private:
|
||||
LR35902 m_cpu;
|
||||
|
||||
Rom m_bootRom = 0x100; // 0x0000 - 0x00ff
|
||||
std::vector<Rom> m_gameRomBanks; // 0x0000 - 0x3fff, 0x4000 - 0x7fff (switchable)
|
||||
Ram m_videoRam = 0x2000; // 0x8000 - 0x9fff
|
||||
std::vector<Ram> 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<Rom> m_gameRomBanks; // 0x0000 - 0x3fff, 0x4000 - 0x7fff (switchable)
|
||||
Ram m_videoRam = 0x2000; // 0x8000 - 0x9fff
|
||||
std::vector<Ram> 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;
|
||||
|
||||
|
@ -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<uint8_t> content(m_unmapped2000.size());
|
||||
std::fill(content.begin(), content.end(), 0xff);
|
||||
m_unmapped2000.load(content);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<uint8_t> content(m_unmapped60.size());
|
||||
std::fill(content.begin(), content.end(), 0xff);
|
||||
m_unmapped60.load(content);
|
||||
}
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::Bus::reset() {
|
||||
|
@ -5,9 +5,6 @@ Board::Board(const Configuration& configuration)
|
||||
: m_configuration(configuration),
|
||||
m_cpu(EightBit::mc6809(*this)),
|
||||
m_disassembler(*this, m_cpu) {
|
||||
std::vector<uint8_t> content(m_unused2000.size());
|
||||
std::fill(content.begin(), content.end(), 0xff);
|
||||
m_unused2000.load(content);
|
||||
}
|
||||
|
||||
void Board::initialise() {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <mc6809.h>
|
||||
#include <Disassembly.h>
|
||||
#include <MC6850.h>
|
||||
#include <UnusedMemory.h>
|
||||
|
||||
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;
|
||||
|
||||
|
26
inc/MemoryInterface.h
Normal file
26
inc/MemoryInterface.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<uint8_t>& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0;
|
||||
|
||||
protected:
|
||||
virtual void poke(uint16_t address, uint8_t value) = 0;
|
||||
};
|
||||
}
|
40
inc/UnusedMemory.h
Normal file
40
inc/UnusedMemory.h
Normal file
@ -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<uint8_t>& 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;
|
||||
};
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -156,6 +156,7 @@
|
||||
<ClInclude Include="..\inc\Register.h" />
|
||||
<ClInclude Include="..\inc\Signal.h" />
|
||||
<ClInclude Include="..\inc\TestHarness.h" />
|
||||
<ClInclude Include="..\inc\UnusedMemory.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -62,6 +62,9 @@
|
||||
<ClInclude Include="..\inc\MemoryInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\UnusedMemory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
Loading…
Reference in New Issue
Block a user