Fix several BESS compatibility issues

This commit is contained in:
Lior Halphon 2022-03-06 15:53:33 +02:00
parent 7350843cca
commit 965e623637

View File

@ -233,7 +233,7 @@ static size_t bess_size_for_cartridge(const GB_cartridge_t *cart)
case GB_MBC5: case GB_MBC5:
return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t); return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t);
case GB_MMM01: 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: case GB_HUC1:
return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t); return sizeof(BESS_block_t) + 4 * sizeof(BESS_MBC_pair_t);
case GB_HUC3: 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_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) { switch (gb->cartridge_type->mbc_type) {
default: default:
case GB_NO_MBC: return 0; 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]); mbc_block.size = 4 * sizeof(pairs[0]);
break; break;
case GB_MMM01: 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[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[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)}; 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; break;
case GB_HUC1: case GB_HUC1:
pairs[0] = (BESS_MBC_pair_t){LE16(0x0000), gb->huc1.ir_mode? 0xE : 0x0}; 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 // Interrupts
GB_write_memory(&save, 0xFF00 + GB_IO_IF, core.io_registers[GB_IO_IF]); 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; break;
case BE32('NAME'): case BE32('NAME'):
if (LE32(block.size) > sizeof(emulator_name) - 1) { if (LE32(block.size) > sizeof(emulator_name) - 1) {
@ -1018,6 +1028,11 @@ static int load_bess_save(GB_gameboy_t *gb, virtual_file_t *file, bool is_samebo
if (!found_core) goto parse_error; if (!found_core) goto parse_error;
if (LE32(block.size) % 3 != 0) 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) { for (unsigned i = LE32(block.size); i > 0; i -= 3) {
BESS_MBC_pair_t pair; BESS_MBC_pair_t pair;
file->read(file, &pair, sizeof(pair)); file->read(file, &pair, sizeof(pair));