MSXHawk: clean up memory structure

This commit is contained in:
alyosha-tas 2020-01-15 08:39:50 -05:00
parent fe0ff1d983
commit 2035fb5ccd
9 changed files with 243 additions and 165 deletions

View File

@ -1,5 +1,3 @@
#pragma once
#include <iostream> #include <iostream>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>
@ -8,145 +6,37 @@
#include "Z80A.h" #include "Z80A.h"
#include "PSG.h" #include "PSG.h"
#include "VDP.h" #include "VDP.h"
#include "Memory.h"
namespace MSXHawk namespace MSXHawk
{ {
//class Z80A;
//class VDP;
//class SN76489sms;
//class MemoryManager;
class MSXCore class MSXCore
{ {
public: public:
MSXCore() MSXCore()
{ {
cpu.HW_Read = &HardwareRead; MemMap.cpu_pntr = &cpu;
cpu.HW_Write = &HardwareWrite; 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) Z80A* aaa;
{
rom = ext_rom;
rom_size = ext_rom_size / 0x4000;
rom_mapper = ext_rom_mapper;
// default memory map setup void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
reg_FFFC = 0; {
reg_FFFD = 0; MemMap.Load_ROM(ext_rom, ext_rom_size, ext_rom_mapper);
reg_FFFE = 0;
reg_FFFF = 0;
remap_ROM_0();
remap_ROM_1();
remap_ROM_2();
remap_RAM();
} }
static VDP vdp; VDP vdp;
static Z80A cpu; Z80A cpu;
static SN76489sms psg; SN76489sms psg;
MemoryManager MemMap;
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;
}
}
}
}; };
} }

View File

@ -9,28 +9,8 @@
#include <iomanip> #include <iomanip>
#include <string> #include <string>
#include "Z80A.h"
#include "PSG.h"
#include "VDP.h"
using namespace MSXHawk; 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 // Create pointer to a core instance
MSXHAWK_EXPORT MSXCore* MSX_create() MSXHAWK_EXPORT MSXCore* MSX_create()
{ {

View File

@ -159,6 +159,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Core.h" /> <ClInclude Include="Core.h" />
<ClInclude Include="Memory.h" />
<ClInclude Include="VDP.h" /> <ClInclude Include="VDP.h" />
<ClInclude Include="PSG.h" /> <ClInclude Include="PSG.h" />
<ClInclude Include="Z80A.h" /> <ClInclude Include="Z80A.h" />
@ -166,6 +167,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="MSXHawk.cpp" /> <ClCompile Include="MSXHawk.cpp" />
<ClCompile Include="Memory.cpp" />
<ClCompile Include="Z80A.cpp" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -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;
}
}
}
}

View File

@ -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();
};
}

View File

@ -1,5 +1,3 @@
#pragma once
#include <iostream> #include <iostream>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>

View File

@ -1,5 +1,3 @@
#pragma once
#include <iostream> #include <iostream>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>

View File

@ -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);
}
}

View File

@ -1,5 +1,3 @@
#pragma once
#include <iostream> #include <iostream>
#include <cstdint> #include <cstdint>
#include <iomanip> #include <iomanip>
@ -9,12 +7,18 @@ using namespace std;
namespace MSXHawk namespace MSXHawk
{ {
class MemoryManager;
class Z80A class Z80A
{ {
public: public:
#pragma region Variable Declarations #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 // 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. // the size of the pointer matrix and masks is system dependent.
// This also assumes a simple relationship between bank and write mask // 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 // Port action is highly variable based on application, typically this will not suitable for a static mapping
// uint8_t* HWMemoryMap; // uint8_t* HWMemoryMap;
// uint8_t* HWMemoryMapMask; // uint8_t* HWMemoryMapMask;
void (*HW_Write)(uint32_t, uint8_t); void HW_Write(uint32_t, uint8_t);
uint8_t (*HW_Read)(uint32_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 // 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; uint32_t ExternalDB;
@ -258,8 +263,8 @@ namespace MSXHawk
Z80A() Z80A()
{ {
Reset(); //Reset();
InitTableParity(); //InitTableParity();
} }
void Reset() void Reset()
@ -3696,6 +3701,8 @@ namespace MSXHawk
bank_offset &= low_mask; bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF); 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) 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; bank_num = (bank_num >> bank_shift)& high_mask;
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF); 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); INC16_Func(dest_l, dest_h);
} }
@ -3719,6 +3728,8 @@ namespace MSXHawk
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF); 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); DEC16_Func(dest_l, dest_h);
} }
@ -3731,27 +3742,26 @@ namespace MSXHawk
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
MemoryMap[bank_num][bank_offset] = MemoryMapMask[bank_num] & (Regs[src] & 0xFF); 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); TR16_Func(PCl, PCh, Z, W);
} }
void OUT_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src) void OUT_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src)
{ {
Regs[DB] = Regs[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)); 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) void OUT_INC_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src)
{ {
Regs[DB] = Regs[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)); HW_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
INC16_Func(dest_l, dest_h); INC16_Func(dest_l, dest_h);
} }
void IN_Func(uint32_t dest, uint32_t src_l, uint32_t src_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[dest] = HW_Read((uint32_t)(Regs[src_l] | (Regs[src_h]) << 8));
Regs[DB] = Regs[dest]; 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) 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[dest] = HW_Read((uint32_t)(Regs[src_l] | (Regs[src_h]) << 8));
Regs[DB] = Regs[dest]; 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) 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[dest] = HW_Read((uint32_t)(Regs[src_l] | (Regs[src_h]) << 8));
Regs[DB] = Regs[dest]; Regs[DB] = Regs[dest];
INC16_Func(src_l, src_h); INC16_Func(src_l, src_h);