From 965e623637aa85c29eb3d2c274fca3991448ab8e Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Sun, 6 Mar 2022 15:53:33 +0200 Subject: [PATCH] Fix several BESS compatibility issues --- Core/save_state.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Core/save_state.c b/Core/save_state.c index d7429be..a257d82 100644 --- a/Core/save_state.c +++ b/Core/save_state.c @@ -233,7 +233,7 @@ static size_t bess_size_for_cartridge(const GB_cartridge_t *cart) case GB_MBC5: return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t); case GB_MMM01: - return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t); + return sizeof(BESS_block_t) + 8 * sizeof(BESS_MBC_pair_t); case GB_HUC1: return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t); case GB_HUC3: @@ -408,7 +408,7 @@ static int save_bess_mbc_block(GB_gameboy_t *gb, virtual_file_t *file) { BESS_block_t mbc_block = {BE32('MBC '), 0}; - BESS_MBC_pair_t pairs[4]; + BESS_MBC_pair_t pairs[8]; switch (gb->cartridge_type->mbc_type) { default: case GB_NO_MBC: return 0; @@ -438,11 +438,16 @@ static int save_bess_mbc_block(GB_gameboy_t *gb, virtual_file_t *file) mbc_block.size = 4 * sizeof(pairs[0]); break; case GB_MMM01: - pairs[0] = (BESS_MBC_pair_t){LE16(0x2000), gb->mmm01.rom_bank_low | (gb->mmm01.rom_bank_mid << 5)}; + pairs[0] = (BESS_MBC_pair_t){LE16(0x2000), (gb->mmm01.rom_bank_low & (gb->mmm01.rom_bank_mask << 1)) | (gb->mmm01.rom_bank_mid << 5)}; pairs[1] = (BESS_MBC_pair_t){LE16(0x6000), gb->mmm01.mbc1_mode | (gb->mmm01.rom_bank_mask << 2) | (gb->mmm01.multiplex_mode << 6)}; pairs[2] = (BESS_MBC_pair_t){LE16(0x4000), gb->mmm01.ram_bank_low | (gb->mmm01.ram_bank_high << 2) | (gb->mmm01.rom_bank_high << 4) | (gb->mmm01.mbc1_mode_disable << 6)}; pairs[3] = (BESS_MBC_pair_t){LE16(0x0000), (gb->mbc_ram_enable? 0xA : 0x0) | (gb->mmm01.ram_bank_mask << 4) | (gb->mmm01.locked << 6)}; - mbc_block.size = 4 * sizeof(pairs[0]); + /* For compatibility with emulators that inaccurately emulate MMM01, and also require two writes per register */ + pairs[4] = (BESS_MBC_pair_t){LE16(0x2000), (gb->mmm01.rom_bank_low & ~(gb->mmm01.rom_bank_mask << 1))}; + pairs[5] = pairs[1]; + pairs[6] = pairs[2]; + pairs[7] = pairs[3]; + mbc_block.size = 8 * sizeof(pairs[0]); break; case GB_HUC1: pairs[0] = (BESS_MBC_pair_t){LE16(0x0000), gb->huc1.ir_mode? 0xE : 0x0}; @@ -982,6 +987,11 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo // Interrupts GB_write_memory(&save, 0xFF00 + GB_IO_IF, core.io_registers[GB_IO_IF]); + /* Required to be compatible with both SameBoy 0.14.x AND BGB */ + if (GB_is_cgb(&save) && !save.cgb_mode && save.cgb_ram_bank == 7) { + save.cgb_ram_bank = 1; + } + break; case BE32('NAME'): if (LE32(block.size) > sizeof(emulator_name) - 1) { @@ -1017,7 +1027,12 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo case BE32('MBC '): if (!found_core) goto parse_error; if (LE32(block.size) % 3 != 0) goto parse_error; - if (LE32(block.size) > 0x1000) goto parse_error; + if (LE32(block.size) > 0x1000) goto parse_error; + /* Inject some default writes, as some emulators omit them */ + if (gb->cartridge_type->mbc_type == GB_MMM01) { + GB_write_memory(&save, 0x6000, 0x30); + GB_write_memory(&save, 0x4000, 0x70); + } for (unsigned i = LE32(block.size); i > 0; i -= 3) { BESS_MBC_pair_t pair; file->read(file, &pair, sizeof(pair));