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 <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;
};
Z80A* aaa;
static void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
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();
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;
};
}

View File

@ -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()
{

View File

@ -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">

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 <cstdint>
#include <iomanip>

View File

@ -1,5 +1,3 @@
#pragma once
#include <iostream>
#include <cstdint>
#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 <cstdint>
#include <iomanip>
@ -9,11 +7,17 @@ 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.
@ -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;
@ -255,13 +260,13 @@ namespace MSXHawk
#pragma endregion
#pragma region Z80 functions
Z80A()
{
Reset();
InitTableParity();
//Reset();
//InitTableParity();
}
void Reset()
{
ResetRegisters();
@ -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);