MSXHawk: clean up memory structure
This commit is contained in:
parent
fe0ff1d983
commit
2035fb5ccd
|
@ -1,5 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
|
@ -8,145 +6,37 @@
|
|||
#include "Z80A.h"
|
||||
#include "PSG.h"
|
||||
#include "VDP.h"
|
||||
#include "Memory.h"
|
||||
|
||||
namespace MSXHawk
|
||||
{
|
||||
//class Z80A;
|
||||
//class VDP;
|
||||
//class SN76489sms;
|
||||
//class MemoryManager;
|
||||
|
||||
class MSXCore
|
||||
{
|
||||
public:
|
||||
MSXCore()
|
||||
{
|
||||
cpu.HW_Read = &HardwareRead;
|
||||
cpu.HW_Write = &HardwareWrite;
|
||||
MemMap.cpu_pntr = &cpu;
|
||||
MemMap.vdp_pntr = &vdp;
|
||||
MemMap.psg_pntr = &psg;
|
||||
cpu.mem_ctrl = &MemMap;
|
||||
};
|
||||
|
||||
static void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
|
||||
{
|
||||
rom = ext_rom;
|
||||
rom_size = ext_rom_size / 0x4000;
|
||||
rom_mapper = ext_rom_mapper;
|
||||
Z80A* aaa;
|
||||
|
||||
// default memory map setup
|
||||
reg_FFFC = 0;
|
||||
reg_FFFD = 0;
|
||||
reg_FFFE = 0;
|
||||
reg_FFFF = 0;
|
||||
remap_ROM_0();
|
||||
remap_ROM_1();
|
||||
remap_ROM_2();
|
||||
remap_RAM();
|
||||
void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
|
||||
{
|
||||
MemMap.Load_ROM(ext_rom, ext_rom_size, ext_rom_mapper);
|
||||
}
|
||||
|
||||
static VDP vdp;
|
||||
static Z80A cpu;
|
||||
static SN76489sms psg;
|
||||
|
||||
static uint8_t* rom;
|
||||
static uint32_t rom_size;
|
||||
static uint32_t rom_mapper;
|
||||
static uint8_t ram[0x2000];
|
||||
|
||||
static uint8_t cart_ram[0x8000];
|
||||
|
||||
static uint8_t HardwareRead(uint32_t value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void HardwareWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void MemoryWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0xFFFC:
|
||||
reg_FFFC = value;
|
||||
remap_ROM_2();
|
||||
remap_RAM();
|
||||
break;
|
||||
case 0xFFFD:
|
||||
reg_FFFD = value;
|
||||
remap_ROM_0();
|
||||
break;
|
||||
case 0xFFFE:
|
||||
reg_FFFE = value;
|
||||
remap_ROM_1();
|
||||
break;
|
||||
case 0xFFFF:
|
||||
reg_FFFF = value;
|
||||
remap_ROM_2();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
|
||||
|
||||
static inline void remap_ROM_0()
|
||||
{
|
||||
// 0x0000 - 0x03FF always maps to start of ROM
|
||||
cpu.MemoryMap[0] = &rom[0];
|
||||
cpu.MemoryMapMask[0] = 0;
|
||||
|
||||
for (uint32_t i = 1; i < 16; i++)
|
||||
{
|
||||
cpu.MemoryMap[i] = &rom[(reg_FFFD % rom_size) * 0x4000 + (0x400 * i)];
|
||||
cpu.MemoryMapMask[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void remap_ROM_1()
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
{
|
||||
cpu.MemoryMap[i + 16] = &rom[(reg_FFFE % rom_size) * 0x4000 + (0x400 * i)];
|
||||
cpu.MemoryMapMask[i + 16] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void remap_ROM_2()
|
||||
{
|
||||
if ((reg_FFFC & 0x8) > 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
{
|
||||
cpu.MemoryMap[i + 32] = &cart_ram[((reg_FFFC >> 2) & 0x1) * 0x4000 + (0x400 * i)];
|
||||
cpu.MemoryMapMask[i + 32] = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
cpu.MemoryMap[i + 32] = &rom[(reg_FFFF % rom_size) * 0x4000 + (0x400 * i)];
|
||||
cpu.MemoryMapMask[i + 32] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void remap_RAM()
|
||||
{
|
||||
if ((reg_FFFC & 0x10) > 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
{
|
||||
cpu.MemoryMap[i + 48] = &cart_ram[(0x400 * i)];
|
||||
cpu.MemoryMapMask[i + 48] = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
{
|
||||
cpu.MemoryMap[i + 48] = &ram[(0x400 * i)];
|
||||
cpu.MemoryMap[i + 48 + 8] = &ram[(0x400 * i)];
|
||||
cpu.MemoryMapMask[i + 48] = 0xFF;
|
||||
cpu.MemoryMapMask[i + 48 + 8] = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
VDP vdp;
|
||||
Z80A cpu;
|
||||
SN76489sms psg;
|
||||
MemoryManager MemMap;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,28 +9,8 @@
|
|||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
#include "Z80A.h"
|
||||
#include "PSG.h"
|
||||
#include "VDP.h"
|
||||
|
||||
using namespace MSXHawk;
|
||||
|
||||
// initialize static members
|
||||
uint8_t MSXCore::reg_FFFC = 0;
|
||||
uint8_t MSXCore::reg_FFFD = 0;
|
||||
uint8_t MSXCore::reg_FFFE = 0;
|
||||
uint8_t MSXCore::reg_FFFF = 0;
|
||||
|
||||
uint8_t* MSXCore::rom = nullptr;
|
||||
uint32_t MSXCore::rom_size = 0;
|
||||
uint32_t MSXCore::rom_mapper = 0;
|
||||
uint8_t MSXCore::ram[0x2000] = {};
|
||||
uint8_t MSXCore::cart_ram[0x8000] = {};
|
||||
|
||||
Z80A MSXCore::cpu;
|
||||
SN76489sms MSXCore::psg;
|
||||
VDP MSXCore::vdp;
|
||||
|
||||
// Create pointer to a core instance
|
||||
MSXHAWK_EXPORT MSXCore* MSX_create()
|
||||
{
|
||||
|
|
|
@ -159,6 +159,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Core.h" />
|
||||
<ClInclude Include="Memory.h" />
|
||||
<ClInclude Include="VDP.h" />
|
||||
<ClInclude Include="PSG.h" />
|
||||
<ClInclude Include="Z80A.h" />
|
||||
|
@ -166,6 +167,8 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MSXHawk.cpp" />
|
||||
<ClCompile Include="Memory.cpp" />
|
||||
<ClCompile Include="Z80A.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Z80A.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MSXHawk
|
||||
{
|
||||
void MemoryManager::remap_ROM_0()
|
||||
{
|
||||
// 0x0000 - 0x03FF always maps to start of ROM
|
||||
cpu_pntr->MemoryMap[0] = &rom[0];
|
||||
cpu_pntr->MemoryMapMask[0] = 0;
|
||||
|
||||
for (uint32_t i = 1; i < 16; i++)
|
||||
{
|
||||
cpu_pntr->MemoryMap[i] = &rom[(reg_FFFD % rom_size) * 0x4000 + (0x400 * i)];
|
||||
cpu_pntr->MemoryMapMask[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::remap_ROM_1()
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
{
|
||||
cpu_pntr->MemoryMap[i + 16] = &rom[(reg_FFFE % rom_size) * 0x4000 + (0x400 * i)];
|
||||
cpu_pntr->MemoryMapMask[i + 16] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::remap_ROM_2()
|
||||
{
|
||||
if ((reg_FFFC & 0x8) > 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
{
|
||||
cpu_pntr->MemoryMap[i + 32] = &cart_ram[((reg_FFFC >> 2) & 0x1) * 0x4000 + (0x400 * i)];
|
||||
cpu_pntr->MemoryMapMask[i + 32] = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
cpu_pntr->MemoryMap[i + 32] = &rom[(reg_FFFF % rom_size) * 0x4000 + (0x400 * i)];
|
||||
cpu_pntr->MemoryMapMask[i + 32] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::remap_RAM()
|
||||
{
|
||||
if ((reg_FFFC & 0x10) > 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
{
|
||||
cpu_pntr->MemoryMap[i + 48] = &cart_ram[(0x400 * i)];
|
||||
cpu_pntr->MemoryMapMask[i + 48] = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
{
|
||||
cpu_pntr->MemoryMap[i + 48] = &ram[(0x400 * i)];
|
||||
cpu_pntr->MemoryMap[i + 48 + 8] = &ram[(0x400 * i)];
|
||||
cpu_pntr->MemoryMapMask[i + 48] = 0xFF;
|
||||
cpu_pntr->MemoryMapMask[i + 48 + 8] = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MSXHawk
|
||||
{
|
||||
class Z80A;
|
||||
class VDP;
|
||||
class SN76489sms;
|
||||
|
||||
class MemoryManager
|
||||
{
|
||||
public:
|
||||
MemoryManager()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
VDP* vdp_pntr;
|
||||
SN76489sms* psg_pntr;
|
||||
Z80A* cpu_pntr;
|
||||
|
||||
uint8_t* rom;
|
||||
uint32_t rom_size;
|
||||
uint32_t rom_mapper;
|
||||
uint8_t ram[0x2000];
|
||||
|
||||
uint8_t cart_ram[0x8000];
|
||||
|
||||
void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
|
||||
{
|
||||
rom = ext_rom;
|
||||
rom_size = ext_rom_size / 0x4000;
|
||||
rom_mapper = ext_rom_mapper;
|
||||
|
||||
// default memory map setup
|
||||
reg_FFFC = 0;
|
||||
reg_FFFD = 0;
|
||||
reg_FFFE = 0;
|
||||
reg_FFFF = 0;
|
||||
remap_ROM_0();
|
||||
remap_ROM_1();
|
||||
remap_ROM_2();
|
||||
remap_RAM();
|
||||
}
|
||||
|
||||
uint8_t HardwareRead(uint32_t value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HardwareWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MemoryWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0xFFFC:
|
||||
reg_FFFC = value;
|
||||
remap_ROM_2();
|
||||
remap_RAM();
|
||||
break;
|
||||
case 0xFFFD:
|
||||
reg_FFFD = value;
|
||||
remap_ROM_0();
|
||||
break;
|
||||
case 0xFFFE:
|
||||
reg_FFFE = value;
|
||||
remap_ROM_1();
|
||||
break;
|
||||
case 0xFFFF:
|
||||
reg_FFFF = value;
|
||||
remap_ROM_2();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
|
||||
|
||||
void remap_ROM_0();
|
||||
|
||||
void remap_ROM_1();
|
||||
|
||||
void remap_ROM_2();
|
||||
|
||||
void remap_RAM();
|
||||
};
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Z80A.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MSXHawk
|
||||
{
|
||||
void Z80A::Memory_Write(uint32_t addr, uint8_t value)
|
||||
{
|
||||
mem_ctrl->MemoryWrite(addr, value);
|
||||
}
|
||||
|
||||
void Z80A::HW_Write(uint32_t addr, uint8_t value)
|
||||
{
|
||||
mem_ctrl->HardwareWrite(addr, value);
|
||||
}
|
||||
|
||||
uint8_t Z80A::HW_Read(uint32_t addr)
|
||||
{
|
||||
return mem_ctrl->HardwareRead(addr);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
|
@ -9,12 +7,18 @@ using namespace std;
|
|||
|
||||
namespace MSXHawk
|
||||
{
|
||||
class MemoryManager;
|
||||
|
||||
class Z80A
|
||||
{
|
||||
public:
|
||||
|
||||
#pragma region Variable Declarations
|
||||
|
||||
// pointer to controlling memory manager goes here
|
||||
// this will be iplementation dependent
|
||||
MemoryManager* mem_ctrl;
|
||||
|
||||
// Memory is usually mostly static, so it is efficient to access it with a pointer and write mask
|
||||
// the size of the pointer matrix and masks is system dependent.
|
||||
// This also assumes a simple relationship between bank and write mask
|
||||
|
@ -31,8 +35,9 @@ namespace MSXHawk
|
|||
// Port action is highly variable based on application, typically this will not suitable for a static mapping
|
||||
// uint8_t* HWMemoryMap;
|
||||
// uint8_t* HWMemoryMapMask;
|
||||
void (*HW_Write)(uint32_t, uint8_t);
|
||||
uint8_t (*HW_Read)(uint32_t);
|
||||
void HW_Write(uint32_t, uint8_t);
|
||||
uint8_t HW_Read(uint32_t);
|
||||
void Memory_Write(uint32_t, uint8_t);
|
||||
|
||||
// when connected devices do not output a value on the BUS, they are responsible for determining open bus behaviour and returning it
|
||||
uint32_t ExternalDB;
|
||||
|
@ -258,8 +263,8 @@ namespace MSXHawk
|
|||
|
||||
Z80A()
|
||||
{
|
||||
Reset();
|
||||
InitTableParity();
|
||||
//Reset();
|
||||
//InitTableParity();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
|
@ -3696,6 +3701,8 @@ namespace MSXHawk
|
|||
bank_offset &= low_mask;
|
||||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF);
|
||||
|
||||
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
|
||||
}
|
||||
|
||||
void Write_INC_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src)
|
||||
|
@ -3707,6 +3714,8 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF);
|
||||
|
||||
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
|
||||
|
||||
INC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
|
@ -3719,6 +3728,8 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF);
|
||||
|
||||
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
|
||||
|
||||
DEC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
|
@ -3731,27 +3742,26 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF);
|
||||
|
||||
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
|
||||
|
||||
TR16_Func(PCl, PCh, Z, W);
|
||||
}
|
||||
|
||||
void OUT_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
//HWMemoryMap[(uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8))] = (Regs[src] & 0xFF);
|
||||
HW_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
|
||||
}
|
||||
|
||||
void OUT_INC_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
//HWMemoryMap[(uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8))] = (Regs[src] & 0xFF);
|
||||
HW_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
|
||||
INC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
void IN_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
|
||||
{
|
||||
// Regs[dest] = HWMemoryMap[(uint32_t)(Regs[src_l] | (Regs[src_h]) << 8)];
|
||||
Regs[dest] = HW_Read((uint32_t)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
|
||||
|
@ -3766,7 +3776,6 @@ namespace MSXHawk
|
|||
|
||||
void IN_INC_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
|
||||
{
|
||||
// Regs[dest] = HWMemoryMap[(uint32_t)(Regs[src_l] | (Regs[src_h]) << 8)];
|
||||
Regs[dest] = HW_Read((uint32_t)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
|
||||
|
@ -3783,7 +3792,6 @@ namespace MSXHawk
|
|||
|
||||
void IN_A_N_INC_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
|
||||
{
|
||||
// Regs[dest] = HWMemoryMap[(uint32_t)(Regs[src_l] | (Regs[src_h]) << 8)];
|
||||
Regs[dest] = HW_Read((uint32_t)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
INC16_Func(src_l, src_h);
|
||||
|
|
Loading…
Reference in New Issue