MSX: do some work on mappers

This commit is contained in:
alyosha-tas 2021-11-17 15:27:54 -05:00
parent abd6324ca4
commit de1a312262
13 changed files with 349 additions and 44 deletions

Binary file not shown.

View File

@ -44,6 +44,9 @@ namespace MSXHawk
bool FrameAdvance(uint8_t controller_1, uint8_t controller_2, uint8_t* kb_rows_ptr, bool render, bool rendersound)
{
//MemMap.Mem_text_1.resize(2);
//MemMap.Mem_text_1 = " ";
if ((MemMap.psg_pntr->Register[0xF] & 0x40) > 0)
{
MemMap.psg_pntr->Register[0xE] = controller_2;
@ -161,6 +164,17 @@ namespace MSXHawk
return psg.sampleclock;
}
int GetMessageLength()
{
return (int)(MemMap.Mem_text_1.length() + 1);
}
// the copy length l must be supplied ahead of time from GetMessageLength
void GetMessage(char* h, int l)
{
memcpy(h, MemMap.Mem_text_1.c_str(), l);
}
#pragma region State Save / Load
void SaveState(uint8_t* saver)

View File

@ -58,6 +58,18 @@ MSXHawk_EXPORT uint32_t MSX_get_audio(MSXCore* p, int32_t* dest, int32_t* n_samp
return p->GetAudio(dest, n_samp);
}
// length of messages to send
MSXHawk_EXPORT int MSX_getmessagelength(MSXCore* p)
{
return p->GetMessageLength();
}
// send messages to be printed
MSXHawk_EXPORT void MSX_getmessage(MSXCore* p, char* h, int l)
{
p->GetMessage(h, l);
}
#pragma region State Save / Load
// save state

View File

@ -85,6 +85,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>MSXHawk</TargetName>
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\..\Assets\dll</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>

View File

@ -96,6 +96,7 @@ namespace MSXHawk
{
if ((PortA8 & 3) == 0)
{
slot_0_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &bios_rom[(0x400 * i)];
@ -104,22 +105,25 @@ namespace MSXHawk
}
else if ((PortA8 & 3) == 1)
{
slot_0_has_rom = 1;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &rom_1[(0x400 * i)];
cpu_pntr->MemoryMapMask[i] = 0;
cpu_pntr->MemoryMap[i] = remap_rom1(0, i);
cpu_pntr->MemoryMapMask[i] = 0;
}
}
else if ((PortA8 & 3) == 2)
{
slot_0_has_rom = 2;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &rom_2[(0x400 * i)];
cpu_pntr->MemoryMap[i] = remap_rom2(0, i);
cpu_pntr->MemoryMapMask[i] = 0;
}
}
else if ((PortA8 & 3) == 3)
{
slot_0_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &ram[(0x400 * i)];
@ -129,6 +133,7 @@ namespace MSXHawk
if (((PortA8 >> 2) & 3) == 0)
{
slot_1_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &basic_rom[(0x400 * i)];
@ -137,22 +142,25 @@ namespace MSXHawk
}
else if (((PortA8 >> 2) & 3) == 1)
{
slot_1_has_rom = 1;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &rom_1[0x4000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 16] = 0;
cpu_pntr->MemoryMap[i + 16] = remap_rom1(0x4000, i);
cpu_pntr->MemoryMapMask[i + 16] = 0;
}
}
else if (((PortA8 >> 2) & 3) == 2)
{
slot_1_has_rom = 2;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &rom_2[0x4000 + (0x400 * i)];
cpu_pntr->MemoryMap[i + 16] = remap_rom2(0x4000, i);
cpu_pntr->MemoryMapMask[i + 16] = 0;
}
}
else if (((PortA8 >> 2) & 3) == 3)
{
slot_1_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &ram[0x4000 + (0x400 * i)];
@ -162,6 +170,7 @@ namespace MSXHawk
if (((PortA8 >> 4) & 3) == 0)
{
slot_2_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &unmapped[0];
@ -170,22 +179,25 @@ namespace MSXHawk
}
else if (((PortA8 >> 4) & 3) == 1)
{
slot_2_has_rom = 1;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &rom_1[0x8000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 32] = 0;
cpu_pntr->MemoryMap[i + 32] = remap_rom1(0x8000, i);
cpu_pntr->MemoryMapMask[i + 32] = 0;
}
}
else if (((PortA8 >> 4) & 3) == 2)
{
slot_2_has_rom = 2;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &rom_2[0x8000 + (0x400 * i)];
cpu_pntr->MemoryMap[i + 32] = remap_rom2(0x8000, i);
cpu_pntr->MemoryMapMask[i + 32] = 0;
}
}
else if (((PortA8 >> 4) & 3) == 3)
{
slot_2_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &ram[0x8000 + (0x400 * i)];
@ -195,6 +207,7 @@ namespace MSXHawk
if (((PortA8 >> 6) & 3) == 0)
{
slot_3_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &unmapped[0];
@ -203,22 +216,25 @@ namespace MSXHawk
}
else if (((PortA8 >> 6) & 3) == 1)
{
slot_3_has_rom = 1;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &rom_1[0xC000 + (0x400 * i)];
cpu_pntr->MemoryMap[i + 48] = remap_rom1(0xC000, i);
cpu_pntr->MemoryMapMask[i + 48] = 0;
}
}
else if (((PortA8 >> 6) & 3) == 2)
{
slot_3_has_rom = 2;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &rom_2[0xC000 + (0x400 * i)];
cpu_pntr->MemoryMap[i + 48] = remap_rom2(0xC000, i);
cpu_pntr->MemoryMapMask[i + 48] = 0;
}
}
else if (((PortA8 >> 6) & 3) == 3)
{
slot_3_has_rom = 0;
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &ram[0xC000 + (0x400 * i)];
@ -226,4 +242,130 @@ namespace MSXHawk
}
}
}
uint8_t* MemoryManager::remap_rom1(uint32_t base_addr, uint32_t segment)
{
if (rom_mapper_1 == 0)
{
return &rom_1[base_addr + (0x400 * segment)];
}
else if (rom_mapper_1 == 1) // basic konami mapper
{
if (base_addr == 0)
{
if (segment < 8)
{
return &rom_1[rom1_konami_page_2 * 0x2000 + (0x400 * segment)];
}
else
{
segment -= 8;
return &rom_1[rom1_konami_page_3 * 0x2000 + (0x400 * segment)];
}
}
else if (base_addr == 0x4000)
{
if (segment < 8)
{
return &rom_1[(0x400 * segment)];
}
else
{
segment -= 8;
return &rom_1[rom1_konami_page_1 * 0x2000 + (0x400 * segment)];
}
}
else if (base_addr == 0x8000)
{
if (segment < 8)
{
return &rom_1[rom1_konami_page_2 * 0x2000 + (0x400 * segment)];
}
else
{
segment -= 8;
return &rom_1[rom1_konami_page_3 * 0x2000 + (0x400 * segment)];
}
}
else
{
if (segment < 8)
{
return &rom_1[(0x400 * segment)];
}
else
{
segment -= 8;
return &rom_1[rom1_konami_page_1 * 0x2000 + (0x400 * segment)];
}
}
}
else
{
return &unmapped[0];
}
}
uint8_t* MemoryManager::remap_rom2(uint32_t base_addr, uint32_t segment)
{
if (rom_mapper_2 == 0)
{
return &rom_2[base_addr + (0x400 * segment)];
}
else if (rom_mapper_2 == 1) // basic konami mapper
{
if (base_addr == 0)
{
if (segment < 8)
{
return &rom_2[rom2_konami_page_2 * 0x2000 + (0x400 * segment)];
}
else
{
segment -= 8;
return &rom_2[rom2_konami_page_3 * 0x2000 + (0x400 * segment)];
}
}
else if (base_addr == 0x4000)
{
if (segment < 8)
{
return &rom_2[(0x400 * segment)];
}
else
{
segment -= 8;
return &rom_2[rom2_konami_page_1 * 0x2000 + (0x400 * segment)];
}
}
else if (base_addr == 0x8000)
{
if (segment < 8)
{
return &rom_2[rom2_konami_page_2 * 0x2000 + (0x400 * segment)];
}
else
{
segment -= 8;
return &rom_2[rom2_konami_page_3 * 0x2000 + (0x400 * segment)];
}
}
else
{
if (segment < 8)
{
return &rom_2[(0x400 * segment)];
}
else
{
segment -= 8;
return &rom_2[rom2_konami_page_1 * 0x2000 + (0x400 * segment)];
}
}
}
else
{
return &unmapped[0];
}
}
}

View File

@ -50,12 +50,21 @@ namespace MSXHawk
};
char msg[1000] = {};
int msg_len = 0;
string Mem_text_1 = " ";
uint8_t HardwareRead(uint32_t value);
void HardwareWrite(uint32_t addr, uint8_t value);
void remap();
uint8_t* remap_rom1(uint32_t, uint32_t);
uint8_t* remap_rom2(uint32_t, uint32_t);
// NOTE: only called from source when both are available and of correct size (0x4000)
void Load_BIOS(uint8_t* bios, uint8_t* basic)
{
@ -74,21 +83,51 @@ namespace MSXHawk
memcpy(rom_1, ext_rom_1, ext_rom_size_1);
memcpy(rom_2, ext_rom_2, ext_rom_size_2);
rom_size_1 = ext_rom_size_1 / 0x4000;
rom_size_1 = ext_rom_size_1 / 0x400 - 1;
rom_mapper_1 = ext_rom_mapper_1;
rom_size_2 = ext_rom_size_2 / 0x4000;
rom_size_2 = ext_rom_size_2 / 0x400 - 1;
rom_mapper_2 = ext_rom_mapper_2;
if (rom_mapper_1 == 1)
{
rom1_konami_page_1 = 1;
rom1_konami_page_2 = 2;
rom1_konami_page_3 = 3;
}
if (rom_mapper_2 == 1)
{
rom2_konami_page_1 = 1;
rom2_konami_page_2 = 2;
rom2_konami_page_3 = 3;
}
// default memory map setup
PortA8 = 0;
remap();
}
// mapper support and variables
uint8_t slot_0_has_rom, slot_1_has_rom, slot_2_has_rom, slot_3_has_rom;
uint8_t rom1_konami_page_1, rom1_konami_page_2, rom1_konami_page_3;
uint8_t rom2_konami_page_1, rom2_konami_page_2, rom2_konami_page_3;
void MemoryWrite(uint32_t addr, uint8_t value)
{
if (rom_mapper_1 == 1)
{
if (addr >= 0x6000 && addr < 0x8000 && slot_1_has_rom == 1) { rom1_konami_page_1 = (uint8_t)(value & rom_size_1); remap(); }
if (addr >= 0x8000 && addr < 0xA000 && slot_2_has_rom == 1) { rom1_konami_page_2 = (uint8_t)(value & rom_size_1); remap(); }
if (addr >= 0xA000 && addr < 0xC000 && slot_2_has_rom == 1) { rom1_konami_page_3 = (uint8_t)(value & rom_size_1); remap(); }
}
if (rom_mapper_2 == 1)
{
if (addr >= 0x6000 && addr < 0x8000 && slot_1_has_rom == 2) { rom2_konami_page_1 = (uint8_t)(value & rom_size_2); remap(); }
if (addr >= 0x8000 && addr < 0xA000 && slot_2_has_rom == 2) { rom2_konami_page_2 = (uint8_t)(value & rom_size_2); remap(); }
if (addr >= 0xA000 && addr < 0xC000 && slot_2_has_rom == 2) { rom2_konami_page_3 = (uint8_t)(value & rom_size_2); remap(); }
}
}
#pragma region State Save / Load
@ -106,6 +145,18 @@ namespace MSXHawk
*saver = reg_FFFE; saver++;
*saver = reg_FFFF; saver++;
*saver = slot_0_has_rom; saver++;
*saver = slot_1_has_rom; saver++;
*saver = slot_2_has_rom; saver++;
*saver = slot_3_has_rom; saver++;
*saver = rom1_konami_page_1; saver++;
*saver = rom1_konami_page_2; saver++;
*saver = rom1_konami_page_3; saver++;
*saver = rom2_konami_page_1; saver++;
*saver = rom2_konami_page_2; saver++;
*saver = rom2_konami_page_3; saver++;
std::memcpy(saver, &ram, 0x10000); saver += 0x10000;
std::memcpy(saver, &cart_ram, 0x8000); saver += 0x8000;
@ -125,6 +176,18 @@ namespace MSXHawk
reg_FFFE = *loader; loader++;
reg_FFFF = *loader; loader++;
slot_0_has_rom = *loader; loader++;
slot_1_has_rom = *loader; loader++;
slot_2_has_rom = *loader; loader++;
slot_3_has_rom = *loader; loader++;
rom1_konami_page_1 = *loader; loader++;
rom1_konami_page_2 = *loader; loader++;
rom1_konami_page_3 = *loader; loader++;
rom2_konami_page_1 = *loader; loader++;
rom2_konami_page_2 = *loader; loader++;
rom2_konami_page_3 = *loader; loader++;
std::memcpy(&ram, loader, 0x10000); loader += 0x10000;
std::memcpy(&cart_ram, loader, 0x8000); loader += 0x8000;

View File

@ -11,10 +11,7 @@ namespace MSXHawk
{
void Z80A::Memory_Write(uint32_t addr, uint8_t value)
{
if ((addr & 0xFFFF) >= 0xFFFC)
{
mem_ctrl->MemoryWrite(addr, value);
}
mem_ctrl->MemoryWrite(addr, value);
}
void Z80A::HW_Write(uint32_t addr, uint8_t value)

View File

@ -3843,7 +3843,7 @@ namespace MSXHawk
void Read_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
{
bank_num = bank_offset = (uint32_t)(Regs[src_l] | (Regs[src_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[src_l] | (Regs[src_h] << 8));
bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask;
Regs[dest] = MemoryMap[bank_num][bank_offset];
@ -3853,7 +3853,7 @@ namespace MSXHawk
void Read_INC_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
{
bank_num = bank_offset = (uint32_t)(Regs[src_l] | (Regs[src_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[src_l] | (Regs[src_h] << 8));
bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask;
Regs[dest] = MemoryMap[bank_num][bank_offset];
@ -3864,7 +3864,7 @@ namespace MSXHawk
void Read_INC_TR_PC_Func(uint32_t dest_l, uint32_t dest_h, uint32_t src_l, uint32_t src_h)
{
bank_num = bank_offset = (uint32_t)(Regs[src_l] | (Regs[src_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[src_l] | (Regs[src_h] << 8));
bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask;
Regs[dest_h] = MemoryMap[bank_num][bank_offset];
@ -3880,9 +3880,9 @@ namespace MSXHawk
{
Regs[DB] = Regs[src];
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8));
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)) | ((~MemoryMapMask[bank_num]) & MemoryMap[bank_num][bank_offset]);
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
@ -3892,9 +3892,9 @@ namespace MSXHawk
{
Regs[DB] = Regs[src];
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8));
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)) | ((~MemoryMapMask[bank_num]) & MemoryMap[bank_num][bank_offset]);
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
@ -3906,9 +3906,9 @@ namespace MSXHawk
{
Regs[DB] = Regs[src];
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8));
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)) | ((~MemoryMapMask[bank_num]) & MemoryMap[bank_num][bank_offset]);
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
@ -3920,9 +3920,9 @@ namespace MSXHawk
{
Regs[DB] = Regs[src];
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h]) << 8);
bank_num = bank_offset = (uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8));
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)) | ((~MemoryMapMask[bank_num]) & MemoryMap[bank_num][bank_offset]);
Memory_Write((uint32_t)(Regs[dest_l] | (Regs[dest_h] << 8)), (uint8_t)(Regs[src] & 0xFF));
@ -3946,7 +3946,7 @@ namespace MSXHawk
void IN_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
{
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];
FlagZset(Regs[dest] == 0);
@ -3960,7 +3960,7 @@ namespace MSXHawk
void IN_INC_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
{
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];
FlagZset(Regs[dest] == 0);
@ -3976,7 +3976,7 @@ namespace MSXHawk
void IN_A_N_INC_Func(uint32_t dest, uint32_t src_l, uint32_t src_h)
{
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];
INC16_Func(src_l, src_h);
}

View File

@ -145,11 +145,12 @@ namespace BizHawk.Emulation.Common
FirmwareAndOption("282EB7BC819AAD2A12FD954E76F7838A4E1A7929", 16384, "ZXSpectrum", "TRDOSROM", "ZX_trdos.rom", "TRDOS ROM");
// MSX
FirmwareAndOption("B398CFCB94C9F7E808E0FECE54813CFDFB96F8D0", 16384, "MSX", "bios_test", "MSX_bios.rom", "MSX BIOS");
FirmwareAndOption("18559FA9C2D9E99A319550D809009ECDBA6D396E", 16384, "MSX", "basic_test", "MSX_cbios_basic.rom", "MSX BASIC (C-BIOS v0.29a)");
FirmwareAndOption("2F997E8A57528518C82AB3693FDAE243DBBCC508", 32768, "MSX", "bios_test_ext", "MSX_cbios_main_msx1.rom", "MSX BIOS (C-BIOS v0.29a)");
FirmwareAndOption("E998F0C441F4F1800EF44E42CD1659150206CF79", 16384, "MSX", "bios_pal", "MSX_8020-20bios.rom", "MSX BIOS (Philips VG-8020)");
FirmwareAndOption("DF48902F5F12AF8867AE1A87F255145F0E5E0774", 16384, "MSX", "bios_jp", "MSX_4000bios.rom", "MSX BIOS (FS-4000)");
//FirmwareAndOption("E998F0C441F4F1800EF44E42CD1659150206CF79", 16384, "MSX", "bios_pal", "MSX_8020-20bios.rom", "MSX BIOS (Philips VG-8020)");
//FirmwareAndOption("DF48902F5F12AF8867AE1A87F255145F0E5E0774", 16384, "MSX", "bios_jp", "MSX_4000bios.rom", "MSX BIOS (FS-4000)");
FirmwareAndOption("409E82ADAC40F6BDD18EB6C84E8B2FBDC7FB5498", 32768, "MSX", "bios_basic_usa", "MSX.rom", "MSX BIOS and BASIC");
FirmwareAndOption("3656BB3BBC17D280D2016FE4F6FF3CDED3082A41", 32768, "MSX", "bios_basic_usa", "MSX.rom", "MSX 1.0 BIOS and BASIC");
FirmwareAndOption("302AFB5D8BE26C758309CA3DF611AE69CCED2821", 32768, "MSX", "bios_basic_jpn", "MSX_jpn.rom", "MSX 1.0 JPN BIOS and BASIC");
// Channel F
FirmwareAndOption("81193965A374D77B99B4743D317824B53C3E3C78", 1024, "ChannelF", "ChannelF_sl131253", "ChannelF_SL31253.rom", "Channel F Rom0");

View File

@ -70,6 +70,22 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint MSX_get_audio(IntPtr core, int[] aud_buf, ref uint n_samp);
/// <summary>
/// get messages length
/// </summary>
/// <param name="core">opaque state pointer</param>
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int MSX_getmessagelength(IntPtr core);
/// <summary>
/// get messages from the core
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="h">pointer to const char *</param>
/// <param name="l">length of message to fetch</param>
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MSX_getmessage(IntPtr core, StringBuilder h, int l);
/// <summary>
/// Save State
/// </summary>

View File

@ -1,5 +1,6 @@
using BizHawk.Emulation.Common;
using System;
using System.Text;
namespace BizHawk.Emulation.Cores.Computers.MSX
{
@ -43,6 +44,13 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
LibMSX.MSX_settracecallback(MSX_Pntr, tracecb);
LibMSX.MSX_frame_advance(MSX_Pntr, ctrl1_byte, ctrl2_byte, kb_rows, true, true);
/*
int msg_l = LibMSX.MSX_getmessagelength(MSX_Pntr);
StringBuilder new_msg = new StringBuilder(msg_l);
LibMSX.MSX_getmessage(MSX_Pntr, new_msg, msg_l - 1);
Console.WriteLine(new_msg);
*/
_frame++;

View File

@ -70,11 +70,22 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
Keyboard
}
public enum RegionType
{
USA,
JPN
}
[DisplayName("Controller Configuration")]
[Description("Pick Between Controller Types")]
[DefaultValue(ContrType.Joystick)]
public ContrType Contr_Setting { get; set; }
[DisplayName("Region Configuration")]
[Description("Select Console Region")]
[DefaultValue(RegionType.USA)]
public RegionType Region_Setting { get; set; }
public MSXSyncSettings Clone()
{

View File

@ -15,19 +15,32 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
Settings = (MSXSettings)settings ?? new MSXSettings();
SyncSettings = (MSXSyncSettings)syncSettings ?? new MSXSyncSettings();
RomData = rom;
RomData = new byte[rom.Length];
for (int i = 0; i < rom.Length; i++)
{
RomData[i] = rom[i];
}
int size = RomData.Length;
int mapper_1 = 0;
if (RomData.Length % BankSize != 0)
{
Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
}
// we want all ROMS to be multiples of 64K for easy memory mapping later
if (RomData.Length != 0x10000)
if (RomData.Length < 0x10000)
{
Array.Resize(ref RomData, 0x10000);
}
else
{
mapper_1 = 1;
Console.WriteLine("Konami Mapper");
}
// if the original was not 64 or 48 k, move it (may need to do this case by case)
@ -53,18 +66,44 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
}
}
Bios = comm.CoreFileProvider.GetFirmware(new("MSX", "bios_jp"), "BIOS Not Found, Cannot Load")
?? comm.CoreFileProvider.GetFirmwareOrThrow(new("MSX", "bios_test_ext"), "BIOS Not Found, Cannot Load");
//Basic = comm.CoreFileProvider.GetFirmware("MSX", "basic_test", true, "BIOS Not Found, Cannot Load");
// loook for combination BIOS + BASIC files first
byte[] loc_bios = null;
if (SyncSettings.Region_Setting == MSXSyncSettings.RegionType.USA)
{
loc_bios = comm.CoreFileProvider.GetFirmware(new("MSX", "bios_basic_usa"));
}
else
{
loc_bios = comm.CoreFileProvider.GetFirmwareOrThrow(new("MSX", "bios_basic_jpn"));
}
// look for individual files (not implemented yet)
if (loc_bios == null)
{
throw new Exception("Cannot load, no BIOS files found for selected region.");
}
Basic = new byte[0x4000];
if (loc_bios.Length == 32768)
{
Bios = new byte[0x4000];
Basic = new byte[0x4000];
for (int i = 0; i < 0x4000; i++)
{
Bios[i] = loc_bios[i];
Basic[i] = loc_bios[i + 0x4000];
}
}
//only use one rom cart for now
RomData2 = new byte[0x10000];
for (int i = 0; i < 0x10000; i++) { RomData2[i] = 0; }
MSX_Pntr = LibMSX.MSX_create();
LibMSX.MSX_load_bios(MSX_Pntr, Bios, Basic);
LibMSX.MSX_load(MSX_Pntr, RomData, (uint)RomData.Length, 0, RomData, (uint)RomData.Length, 0);
LibMSX.MSX_load(MSX_Pntr, RomData, (uint)RomData.Length, mapper_1, RomData2, (uint)RomData2.Length, 0);
blip.SetRates(3579545, 44100);
@ -104,7 +143,8 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
private const int BankSize = 16384;
// ROM
public byte[] RomData;
public static byte[] RomData;
public static byte[] RomData2;
// Machine resources
private IController _controller = NullController.Instance;