diff --git a/Assets/dll/MSXHawk.dll b/Assets/dll/MSXHawk.dll index 3816ed97fb..d2fbb50341 100644 Binary files a/Assets/dll/MSXHawk.dll and b/Assets/dll/MSXHawk.dll differ diff --git a/libHawk/MSXHawk/MSXHawk/Core.h b/libHawk/MSXHawk/MSXHawk/Core.h index 8766175ad8..c907a69075 100644 --- a/libHawk/MSXHawk/MSXHawk/Core.h +++ b/libHawk/MSXHawk/MSXHawk/Core.h @@ -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) diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp index 34c6809a5b..53a5d9b1e8 100644 --- a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp +++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp @@ -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 diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj b/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj index 6176713181..ad03d7a570 100644 --- a/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj +++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.vcxproj @@ -85,6 +85,7 @@ MSXHawk false + ..\..\..\Assets\dll diff --git a/libHawk/MSXHawk/MSXHawk/Memory.cpp b/libHawk/MSXHawk/MSXHawk/Memory.cpp index 62b67c3dd2..310d20e5f1 100644 --- a/libHawk/MSXHawk/MSXHawk/Memory.cpp +++ b/libHawk/MSXHawk/MSXHawk/Memory.cpp @@ -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]; + } + } } \ No newline at end of file diff --git a/libHawk/MSXHawk/MSXHawk/Memory.h b/libHawk/MSXHawk/MSXHawk/Memory.h index c3d864b04e..6e2a97b344 100644 --- a/libHawk/MSXHawk/MSXHawk/Memory.h +++ b/libHawk/MSXHawk/MSXHawk/Memory.h @@ -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; diff --git a/libHawk/MSXHawk/MSXHawk/Z80A.cpp b/libHawk/MSXHawk/MSXHawk/Z80A.cpp index 2b4924bdd3..686747e2bc 100644 --- a/libHawk/MSXHawk/MSXHawk/Z80A.cpp +++ b/libHawk/MSXHawk/MSXHawk/Z80A.cpp @@ -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) diff --git a/libHawk/MSXHawk/MSXHawk/Z80A.h b/libHawk/MSXHawk/MSXHawk/Z80A.h index 9b772e82fe..798c0694e1 100644 --- a/libHawk/MSXHawk/MSXHawk/Z80A.h +++ b/libHawk/MSXHawk/MSXHawk/Z80A.h @@ -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); } diff --git a/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs b/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs index 313df5503b..9a9a3c5f85 100644 --- a/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs +++ b/src/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs @@ -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"); diff --git a/src/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs b/src/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs index ba3facfa4b..76aa01f1cf 100644 --- a/src/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs +++ b/src/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs @@ -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); + /// + /// get messages length + /// + /// opaque state pointer + [DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int MSX_getmessagelength(IntPtr core); + + /// + /// get messages from the core + /// + /// opaque state pointer + /// pointer to const char * + /// length of message to fetch + [DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void MSX_getmessage(IntPtr core, StringBuilder h, int l); + /// /// Save State /// diff --git a/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs b/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs index 7f7a15e715..ef62bbf862 100644 --- a/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs +++ b/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs @@ -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++; diff --git a/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.ISettable.cs b/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.ISettable.cs index f34c771bff..a0b27548d1 100644 --- a/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.ISettable.cs +++ b/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.ISettable.cs @@ -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() { diff --git a/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs b/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs index 6b8bab8804..14ec692691 100644 --- a/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs +++ b/src/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs @@ -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;