From 44b2d2eada7f251357e19edbc3e7e46cc0e1cc95 Mon Sep 17 00:00:00 2001 From: Ignacio Sanchez Gines <863613+drhelius@users.noreply.github.com> Date: Sun, 28 Jul 2024 13:03:58 +0200 Subject: [PATCH] Fix rom mirroring --- .../shared/desktop/gui_debug_huc6270.cpp | 2 - src/cartridge.cpp | 94 ++++++++++++++++++- src/cartridge.h | 5 + src/game_db.h | 13 ++- src/memory_inline.h | 46 +++++---- 5 files changed, 132 insertions(+), 28 deletions(-) diff --git a/platforms/shared/desktop/gui_debug_huc6270.cpp b/platforms/shared/desktop/gui_debug_huc6270.cpp index ec7080f..0c9c447 100644 --- a/platforms/shared/desktop/gui_debug_huc6270.cpp +++ b/platforms/shared/desktop/gui_debug_huc6270.cpp @@ -180,7 +180,6 @@ void gui_debug_window_huc6270_background(void) GeargrafxCore* core = emu_get_core(); HuC6270* huc6270 = core->GetHuC6270(); - HuC6270::HuC6270_State* huc6270_state = huc6270->GetState(); ImGui::TextColored(magenta, "BACKGROUND"); @@ -203,7 +202,6 @@ void gui_debug_window_huc6270_sprites(void) GeargrafxCore* core = emu_get_core(); HuC6270* huc6270 = core->GetHuC6270(); - HuC6270::HuC6270_State* huc6270_state = huc6270->GetState(); ImGui::TextColored(magenta, "SPRITES"); diff --git a/src/cartridge.cpp b/src/cartridge.cpp index fa2a8b1..9bd06bf 100644 --- a/src/cartridge.cpp +++ b/src/cartridge.cpp @@ -34,11 +34,17 @@ Cartridge::Cartridge() m_file_extension[0] = 0; m_rom_bank_count = 0; m_crc = 0; + m_is_sgx = false; + + m_rom_map = new u8*[128]; + for (int i = 0; i < 128; i++) + InitPointer(m_rom_map[i]); } Cartridge::~Cartridge() { SafeDeleteArray(m_rom); + SafeDeleteArray(m_rom_map); } void Cartridge::Init() @@ -56,6 +62,10 @@ void Cartridge::Reset() m_file_extension[0] = 0; m_rom_bank_count = 0; m_crc = 0; + m_is_sgx = false; + + for (int i = 0; i < 128; i++) + InitPointer(m_rom_map[i]); } u32 Cartridge::GetCRC() @@ -93,6 +103,11 @@ u8* Cartridge::GetROM() return m_rom; } +u8** Cartridge::GetROMMap() +{ + return m_rom_map; +} + bool Cartridge::LoadFromFile(const char* path) { using namespace std; @@ -153,10 +168,21 @@ bool Cartridge::LoadFromBuffer(const u8* buffer, int size) { Debug("Loading ROM from buffer... Size: %d", size); + if(size & 512) + { + Debug("Removing 512 bytes header..."); + size &= ~512; + buffer += 512; + } + + if(!memcmp(buffer + 0x1FD0, "MCGENJIN", 8)) + { + Debug("MCGENJIN mapper detected."); + } + if ((size % 0x2000) != 0) { - Log("Invalid size found: %d bytes", size); - return false; + Log("Invalid size found: %d (0x%X) bytes", size, size); } m_rom_size = size; @@ -164,6 +190,15 @@ bool Cartridge::LoadFromBuffer(const u8* buffer, int size) memcpy(m_rom, buffer, m_rom_size); GatherROMInfo(); + + if (m_is_sgx) + { + Log("SuperGrafx (SGX) games are not supported yet."); + return false; + } + + InitRomMAP(); + m_ready = true; Debug("ROM loaded from buffer. Size: %d bytes", m_rom_size); @@ -239,8 +274,8 @@ void Cartridge::GatherROMInfo() m_rom_bank_count = (m_rom_size / 0x2000) + (m_rom_size % 0x2000 ? 1 : 0); m_crc = CalculateCRC32(0, m_rom, m_rom_size); - Debug("ROM Size: %d KB, %d bytes", m_rom_size / 1024, m_rom_size); - Debug("ROM Bank Count: %d", m_rom_bank_count); + Debug("ROM Size: %d KB, %d bytes (0x%0X)", m_rom_size / 1024, m_rom_size, m_rom_size); + Debug("ROM Bank Count: %d (0x%0X)", m_rom_bank_count, m_rom_bank_count); Debug("ROM CRC32: %08X", m_crc); GatherInfoFromDB(); @@ -259,6 +294,12 @@ void Cartridge::GatherInfoFromDB() { found = true; Log("ROM found in database: %s. CRC: %08X", k_game_database[i].title, m_crc); + + if (k_game_database[i].flags & GAMEDB_SGX) + { + m_is_sgx = true; + Log("ROM is a SuperGrafx (SGX) game."); + } } else i++; @@ -269,3 +310,48 @@ void Cartridge::GatherInfoFromDB() Debug("ROM not found in database. CRC: %08X", m_crc); } } + +void Cartridge::InitRomMAP() +{ + if(m_rom_size == 0x60000) + { + for(int x = 0; x < 64; x++) + { + int bank = x & 0x1F; + int bank_addess = bank * 0x2000; + m_rom_map[x] = &m_rom[bank_addess]; + } + + for(int x = 64; x < 128; x++) + { + int bank = (x & 0x0F) + 32; + int bank_addess = bank * 0x2000; + m_rom_map[x] = &m_rom[bank_addess]; + } + } + else if (m_rom_size == 0x80000) + { + for(int x = 0; x < 64; x++) + { + int bank = x & 0x3F; + int bank_addess = bank * 0x2000; + m_rom_map[x] = &m_rom[bank_addess]; + } + + for(int x = 64; x < 128; x++) + { + int bank = (x & 0x1F) + 32; + int bank_addess = bank * 0x2000; + m_rom_map[x] = &m_rom[bank_addess]; + } + } + else + { + for(int x = 0; x < 128; x++) + { + int bank = x % (m_rom_size / 0x2000); + int bank_addess = bank * 0x2000; + m_rom_map[x] = &m_rom[bank_addess]; + } + } +} diff --git a/src/cartridge.h b/src/cartridge.h index 9490544..a5f8b32 100644 --- a/src/cartridge.h +++ b/src/cartridge.h @@ -31,12 +31,14 @@ class Cartridge void Reset(); u32 GetCRC(); bool IsReady(); + bool IsSGX(); int GetROMSize(); int GetROMBankCount(); const char* GetFilePath(); const char* GetFileName(); const char* GetFileExtension(); u8* GetROM(); + u8** GetROMMap(); bool LoadFromFile(const char* path); bool LoadFromBuffer(const u8* buffer, int size); @@ -44,9 +46,11 @@ class Cartridge bool LoadFromZipFile(const u8* buffer, int size); void GatherROMInfo(); void GatherInfoFromDB(); + void InitRomMAP(); private: u8* m_rom; + u8** m_rom_map; int m_rom_size; int m_rom_bank_count; bool m_ready; @@ -54,6 +58,7 @@ class Cartridge char m_file_name[512]; char m_file_extension[512]; u32 m_crc; + bool m_is_sgx; }; #endif /* CARTRIDGE_H */ \ No newline at end of file diff --git a/src/game_db.h b/src/game_db.h index 8e4e2eb..b58a406 100644 --- a/src/game_db.h +++ b/src/game_db.h @@ -22,16 +22,25 @@ #include "common.h" +#define GAMEDB_NONE 0x00 +#define GAMEDB_SGX 0x01 + struct GG_Game_DB_Entry { u32 crc; const char* title; + u8 flags; }; const GG_Game_DB_Entry k_game_database[] = { - {0x00000000, "example"}, - {0, 0} + { 0xBEBFE042, "Darius Plus (J) (SGX)", GAMEDB_SGX}, + { 0x4C2126B0, "Aldynes (J) (SGX)", GAMEDB_SGX}, + { 0x8C4588E2, "1941 - Counter Attack (J) (SGX)", GAMEDB_SGX}, + { 0x1F041166, "Madouou Granzort (J) (SGX)", GAMEDB_SGX}, + { 0xB486A8ED, "Daimakaimura (J) (SGX)", GAMEDB_SGX}, + { 0x3B13AF61, "Battle Ace (J) (SGX)", GAMEDB_SGX}, + {0, 0, GAMEDB_NONE} }; const uint32_t kCRC32_tab[] = diff --git a/src/memory_inline.h b/src/memory_inline.h index aae6a3b..31323fc 100644 --- a/src/memory_inline.h +++ b/src/memory_inline.h @@ -36,25 +36,25 @@ inline u8 Memory::Read(u16 address, bool block_transfer) u8 mpr_value = m_mpr[mpr_index]; u32 physical_address = (mpr_value << 13) | (address & 0x1FFF); - // 0x00 - 0xF6 - if (mpr_value < 0xF7) + // 0x00 - 0x7F + if (mpr_value < 0x80) { // HuCard ROM - u8* rom = m_cartridge->GetROM(); - int rom_size = m_cartridge->GetROMSize(); - if ((int)physical_address >= rom_size) - { - Debug("Attempted read out of ROM bounds at %04X (%06X), MPR(%02X,%02X)", address, physical_address, mpr_index, mpr_value); - return rom[physical_address & (rom_size - 1)]; - } - else - return rom[physical_address]; + u8** rom_map = m_cartridge->GetROMMap(); + return rom_map[mpr_value][physical_address & 0x1FFF]; + } + // 0x80 - 0xF6 + else if (mpr_value < 0xF7) + { + // Unused + Debug("Unused read at %06X, bank=%02X", physical_address, mpr_value); + return 0xFF; } // 0xF7 else if (mpr_value < 0xF8) { // Backup RAM - Debug("Backup RAM read at %06X", physical_address); + Debug("Backup RAM read at %06X, bank=%02X", physical_address, mpr_value); return 0xFF; } // 0xF8 - 0xFB @@ -63,7 +63,7 @@ inline u8 Memory::Read(u16 address, bool block_transfer) // RAM if (mpr_value > 0xF8) { - Debug("SGX RAM read at %06X", physical_address); + Debug("SGX RAM read at %06X, bank=%02X", physical_address, mpr_value); } return m_wram[physical_address & 0x1FFF]; } @@ -71,7 +71,7 @@ inline u8 Memory::Read(u16 address, bool block_transfer) else if (mpr_value < 0xFF) { // Unused - Debug("Unused read at %06X", physical_address); + Debug("Unused read at %06X, bank=%02X", physical_address, mpr_value); return 0xFF; } // 0xFF @@ -149,17 +149,23 @@ inline void Memory::Write(u16 address, u8 value) u8 mpr_value = m_mpr[mpr_index]; u32 physical_address = (mpr_value << 13) | (address & 0x1FFF); - // 0x00 - 0xF6 - if (mpr_value < 0xF7) + // 0x00 - 0x7F + if (mpr_value < 0x7F) { // HuCard ROM - Debug("Attempted write to HuCard ROM at %06X, value=%02X", physical_address, value); + Debug("Attempted write to HuCard ROM at %06X, value=%02X, bank=%02X", physical_address, value, mpr_value); + } + // 0x80 - 0xF6 + else if (mpr_value < 0xF7) + { + // Unused + Debug("Unused write at %06X, value=%02X, bank=%02X", physical_address, value, mpr_value); } // 0xF7 else if (mpr_value < 0xF8) { // Savegame RAM - Debug("Savegame RAM write at %06X, value=%02X", physical_address, value); + Debug("Savegame RAM write at %06X, value=%02X, bank=%02X", physical_address, value, mpr_value); } // 0xF8 - 0xFB else if (mpr_value < 0xFC) @@ -167,7 +173,7 @@ inline void Memory::Write(u16 address, u8 value) // RAM if (mpr_value > 0xF8) { - Debug("SGX RAM write at %06X, value=%02X", physical_address, value); + Debug("SGX RAM write at %06X, value=%02X, bank=%02X", physical_address, value, mpr_value); } m_wram[physical_address & 0x1FFF] = value; } @@ -175,7 +181,7 @@ inline void Memory::Write(u16 address, u8 value) else if (mpr_value < 0xFF) { // Unused - Debug("Unused write at %06X, value=%02X", physical_address, value); + Debug("Unused write at %06X, value=%02X, bank=%02X", physical_address, value, mpr_value); } else {