More accurate Camera MBC emulation
This commit is contained in:
parent
24796acccf
commit
d41c188cfd
@ -1546,14 +1546,16 @@ static bool mbc(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugg
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
static const char *const mapper_names[] = {
|
static const char *const mapper_names[] = {
|
||||||
[GB_MBC1] = "MBC1",
|
[GB_MBC1] = "MBC1",
|
||||||
[GB_MBC2] = "MBC2",
|
[GB_MBC2] = "MBC2",
|
||||||
[GB_MBC3] = "MBC3",
|
[GB_MBC3] = "MBC3",
|
||||||
[GB_MBC5] = "MBC5",
|
[GB_MBC5] = "MBC5",
|
||||||
[GB_MBC7] = "MBC7",
|
[GB_MBC7] = "MBC7",
|
||||||
[GB_MMM01] = "MMM01",
|
[GB_MMM01] = "MMM01",
|
||||||
[GB_HUC1] = "HUC-1",
|
[GB_HUC1] = "HUC-1",
|
||||||
[GB_HUC3] = "HUC-3",
|
[GB_HUC3] = "HUC-3",
|
||||||
|
[GB_CAMERA] = "MAC-GBD",
|
||||||
|
|
||||||
};
|
};
|
||||||
GB_log(gb, "%s\n", mapper_names[cartridge->mbc_type]);
|
GB_log(gb, "%s\n", mapper_names[cartridge->mbc_type]);
|
||||||
}
|
}
|
||||||
|
@ -466,7 +466,7 @@ struct GB_gameboy_internal_s {
|
|||||||
uint8_t rom_bank_low;
|
uint8_t rom_bank_low;
|
||||||
uint8_t rom_bank_high:1;
|
uint8_t rom_bank_high:1;
|
||||||
uint8_t ram_bank:4;
|
uint8_t ram_bank:4;
|
||||||
} mbc5;
|
} mbc5; // Also used for GB_CAMERA
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t rom_bank;
|
uint8_t rom_bank;
|
||||||
|
62
Core/mbc.c
62
Core/mbc.c
@ -5,41 +5,41 @@
|
|||||||
|
|
||||||
const GB_cartridge_t GB_cart_defs[256] = {
|
const GB_cartridge_t GB_cart_defs[256] = {
|
||||||
// From http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header#0147_-_Cartridge_Type
|
// From http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header#0147_-_Cartridge_Type
|
||||||
/* MBC SUBTYPE RAM BAT. RTC RUMB. */
|
/* MBC RAM BAT. RTC RUMB. */
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // 00h ROM ONLY
|
{ GB_NO_MBC, false, false, false, false}, // 00h ROM ONLY
|
||||||
{ GB_MBC1 , GB_STANDARD_MBC, false, false, false, false}, // 01h MBC1
|
{ GB_MBC1 , false, false, false, false}, // 01h MBC1
|
||||||
{ GB_MBC1 , GB_STANDARD_MBC, true , false, false, false}, // 02h MBC1+RAM
|
{ GB_MBC1 , true , false, false, false}, // 02h MBC1+RAM
|
||||||
{ GB_MBC1 , GB_STANDARD_MBC, true , true , false, false}, // 03h MBC1+RAM+BATTERY
|
{ GB_MBC1 , true , true , false, false}, // 03h MBC1+RAM+BATTERY
|
||||||
[5] =
|
[5] =
|
||||||
{ GB_MBC2 , GB_STANDARD_MBC, true , false, false, false}, // 05h MBC2
|
{ GB_MBC2 , true , false, false, false}, // 05h MBC2
|
||||||
{ GB_MBC2 , GB_STANDARD_MBC, true , true , false, false}, // 06h MBC2+BATTERY
|
{ GB_MBC2 , true , true , false, false}, // 06h MBC2+BATTERY
|
||||||
[8] =
|
[8] =
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, true , false, false, false}, // 08h ROM+RAM
|
{ GB_NO_MBC, true , false, false, false}, // 08h ROM+RAM
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, true , true , false, false}, // 09h ROM+RAM+BATTERY
|
{ GB_NO_MBC, true , true , false, false}, // 09h ROM+RAM+BATTERY
|
||||||
[0xB] =
|
[0xB] =
|
||||||
{ GB_MMM01 , GB_STANDARD_MBC, false, false, false, false}, // 0Bh MMM01
|
{ GB_MMM01 , false, false, false, false}, // 0Bh MMM01
|
||||||
{ GB_MMM01 , GB_STANDARD_MBC, true , false, false, false}, // 0Ch MMM01+RAM
|
{ GB_MMM01 , true , false, false, false}, // 0Ch MMM01+RAM
|
||||||
{ GB_MMM01 , GB_STANDARD_MBC, true , true , false, false}, // 0Dh MMM01+RAM+BATTERY
|
{ GB_MMM01 , true , true , false, false}, // 0Dh MMM01+RAM+BATTERY
|
||||||
[0xF] =
|
[0xF] =
|
||||||
{ GB_MBC3 , GB_STANDARD_MBC, false, true, true , false}, // 0Fh MBC3+TIMER+BATTERY
|
{ GB_MBC3 , false, true, true , false}, // 0Fh MBC3+TIMER+BATTERY
|
||||||
{ GB_MBC3 , GB_STANDARD_MBC, true , true, true , false}, // 10h MBC3+TIMER+RAM+BATTERY
|
{ GB_MBC3 , true , true, true , false}, // 10h MBC3+TIMER+RAM+BATTERY
|
||||||
{ GB_MBC3 , GB_STANDARD_MBC, false, false, false, false}, // 11h MBC3
|
{ GB_MBC3 , false, false, false, false}, // 11h MBC3
|
||||||
{ GB_MBC3 , GB_STANDARD_MBC, true , false, false, false}, // 12h MBC3+RAM
|
{ GB_MBC3 , true , false, false, false}, // 12h MBC3+RAM
|
||||||
{ GB_MBC3 , GB_STANDARD_MBC, true , true , false, false}, // 13h MBC3+RAM+BATTERY
|
{ GB_MBC3 , true , true , false, false}, // 13h MBC3+RAM+BATTERY
|
||||||
[0x19] =
|
[0x19] =
|
||||||
{ GB_MBC5 , GB_STANDARD_MBC, false, false, false, false}, // 19h MBC5
|
{ GB_MBC5 , false, false, false, false}, // 19h MBC5
|
||||||
{ GB_MBC5 , GB_STANDARD_MBC, true , false, false, false}, // 1Ah MBC5+RAM
|
{ GB_MBC5 , true , false, false, false}, // 1Ah MBC5+RAM
|
||||||
{ GB_MBC5 , GB_STANDARD_MBC, true , true , false, false}, // 1Bh MBC5+RAM+BATTERY
|
{ GB_MBC5 , true , true , false, false}, // 1Bh MBC5+RAM+BATTERY
|
||||||
{ GB_MBC5 , GB_STANDARD_MBC, false, false, false, true }, // 1Ch MBC5+RUMBLE
|
{ GB_MBC5 , false, false, false, true }, // 1Ch MBC5+RUMBLE
|
||||||
{ GB_MBC5 , GB_STANDARD_MBC, true , false, false, true }, // 1Dh MBC5+RUMBLE+RAM
|
{ GB_MBC5 , true , false, false, true }, // 1Dh MBC5+RUMBLE+RAM
|
||||||
{ GB_MBC5 , GB_STANDARD_MBC, true , true , false, true }, // 1Eh MBC5+RUMBLE+RAM+BATTERY
|
{ GB_MBC5 , true , true , false, true }, // 1Eh MBC5+RUMBLE+RAM+BATTERY
|
||||||
[0x22] =
|
[0x22] =
|
||||||
{ GB_MBC7 , GB_STANDARD_MBC, true, true, false, false}, // 22h MBC7+ACCEL+EEPROM
|
{ GB_MBC7 , true, true, false, false}, // 22h MBC7+ACCEL+EEPROM
|
||||||
[0xFC] =
|
[0xFC] =
|
||||||
{ GB_MBC5 , GB_CAMERA , true , true , false, false}, // FCh POCKET CAMERA
|
{ GB_CAMERA, true , true , false, false}, // FCh POCKET CAMERA
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FDh BANDAI TAMA5 (Todo: Not supported)
|
{ GB_NO_MBC, false, false, false, false}, // FDh BANDAI TAMA5 (Todo: Not supported)
|
||||||
{ GB_HUC3 , GB_STANDARD_MBC, true , true , true, false}, // FEh HuC3
|
{ GB_HUC3 , true , true , true, false}, // FEh HuC3
|
||||||
{ GB_HUC1 , GB_STANDARD_MBC, true , true , false, false}, // FFh HuC1+RAM+BATTERY
|
{ GB_HUC1 , true , true , false, false}, // FFh HuC1+RAM+BATTERY
|
||||||
};
|
};
|
||||||
|
|
||||||
void GB_update_mbc_mappings(GB_gameboy_t *gb)
|
void GB_update_mbc_mappings(GB_gameboy_t *gb)
|
||||||
@ -96,6 +96,7 @@ void GB_update_mbc_mappings(GB_gameboy_t *gb)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GB_MBC5:
|
case GB_MBC5:
|
||||||
|
case GB_CAMERA:
|
||||||
gb->mbc_rom_bank = gb->mbc5.rom_bank_low | (gb->mbc5.rom_bank_high << 8);
|
gb->mbc_rom_bank = gb->mbc5.rom_bank_low | (gb->mbc5.rom_bank_high << 8);
|
||||||
gb->mbc_ram_bank = gb->mbc5.ram_bank;
|
gb->mbc_ram_bank = gb->mbc5.ram_bank;
|
||||||
break;
|
break;
|
||||||
@ -185,7 +186,7 @@ void GB_configure_cart(GB_gameboy_t *gb)
|
|||||||
if (gb->rom[0x147] == 0xBC &&
|
if (gb->rom[0x147] == 0xBC &&
|
||||||
gb->rom[0x149] == 0xC1 &&
|
gb->rom[0x149] == 0xC1 &&
|
||||||
gb->rom[0x14A] == 0x65) {
|
gb->rom[0x14A] == 0x65) {
|
||||||
static const GB_cartridge_t tpp1 = {GB_TPP1, GB_STANDARD_MBC, true, true, true, true};
|
static const GB_cartridge_t tpp1 = {GB_TPP1, true, true, true, true};
|
||||||
gb->cartridge_type = &tpp1;
|
gb->cartridge_type = &tpp1;
|
||||||
gb->tpp1.rom_bank = 1;
|
gb->tpp1.rom_bank = 1;
|
||||||
}
|
}
|
||||||
@ -255,7 +256,8 @@ void GB_reset_mbc(GB_gameboy_t *gb)
|
|||||||
gb->mbc_rom_bank = -1;
|
gb->mbc_rom_bank = -1;
|
||||||
gb->mbc_rom0_bank = -2;
|
gb->mbc_rom0_bank = -2;
|
||||||
}
|
}
|
||||||
else if (gb->cartridge_type->mbc_type == GB_MBC5) {
|
else if (gb->cartridge_type->mbc_type == GB_MBC5 ||
|
||||||
|
gb->cartridge_type->mbc_type == GB_CAMERA) {
|
||||||
gb->mbc5.rom_bank_low = 1;
|
gb->mbc5.rom_bank_low = 1;
|
||||||
gb->mbc_rom_bank = 1;
|
gb->mbc_rom_bank = 1;
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,8 @@ typedef struct {
|
|||||||
GB_HUC1,
|
GB_HUC1,
|
||||||
GB_HUC3,
|
GB_HUC3,
|
||||||
GB_TPP1,
|
GB_TPP1,
|
||||||
} mbc_type;
|
|
||||||
enum {
|
|
||||||
GB_STANDARD_MBC,
|
|
||||||
GB_CAMERA,
|
GB_CAMERA,
|
||||||
} mbc_subtype;
|
} mbc_type;
|
||||||
bool has_ram;
|
bool has_ram;
|
||||||
bool has_battery;
|
bool has_battery;
|
||||||
bool has_rtc;
|
bool has_rtc;
|
||||||
|
@ -383,7 +383,7 @@ static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((!gb->mbc_ram_enable) &&
|
else if ((!gb->mbc_ram_enable) &&
|
||||||
gb->cartridge_type->mbc_subtype != GB_CAMERA &&
|
gb->cartridge_type->mbc_type != GB_CAMERA &&
|
||||||
gb->cartridge_type->mbc_type != GB_HUC1 &&
|
gb->cartridge_type->mbc_type != GB_HUC1 &&
|
||||||
gb->cartridge_type->mbc_type != GB_HUC3) {
|
gb->cartridge_type->mbc_type != GB_HUC3) {
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
@ -414,7 +414,7 @@ static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gb->cartridge_type->mbc_subtype == GB_CAMERA && gb->mbc_ram_bank == 0 && addr >= 0xA100 && addr < 0xAF00) {
|
if (gb->cartridge_type->mbc_type == GB_CAMERA && gb->mbc_ram_bank == 0 && addr >= 0xA100 && addr < 0xAF00) {
|
||||||
return GB_camera_read_image(gb, addr - 0xA100);
|
return GB_camera_read_image(gb, addr - 0xA100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,7 +827,16 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
value &= 7;
|
value &= 7;
|
||||||
}
|
}
|
||||||
gb->mbc5.ram_bank = value;
|
gb->mbc5.ram_bank = value;
|
||||||
gb->camera_registers_mapped = (value & 0x10) && gb->cartridge_type->mbc_subtype == GB_CAMERA;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GB_CAMERA:
|
||||||
|
switch (addr & 0xF000) {
|
||||||
|
case 0x0000: case 0x1000: gb->mbc_ram_enable = (value & 0xF) == 0xA; break;
|
||||||
|
case 0x2000: case 0x3000: gb->mbc5.rom_bank_low = value; break;
|
||||||
|
case 0x4000: case 0x5000:
|
||||||
|
gb->mbc5.ram_bank = value;
|
||||||
|
gb->camera_registers_mapped = (value & 0x10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -254,6 +254,8 @@ static size_t bess_size_for_cartridge(const GB_cartridge_t *cart)
|
|||||||
return sizeof(BESS_block_t) + 3 * sizeof(BESS_MBC_pair_t) + (cart->has_rtc? sizeof(BESS_RTC_t) : 0);
|
return sizeof(BESS_block_t) + 3 * sizeof(BESS_MBC_pair_t) + (cart->has_rtc? sizeof(BESS_RTC_t) : 0);
|
||||||
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_CAMERA:
|
||||||
|
return sizeof(BESS_block_t) + 3 * sizeof(BESS_MBC_pair_t);
|
||||||
case GB_MBC7:
|
case GB_MBC7:
|
||||||
return sizeof(BESS_block_t) + 3 * sizeof(BESS_MBC_pair_t) + sizeof(BESS_MBC7_t);
|
return sizeof(BESS_block_t) + 3 * sizeof(BESS_MBC_pair_t) + sizeof(BESS_MBC7_t);
|
||||||
case GB_MMM01:
|
case GB_MMM01:
|
||||||
@ -459,6 +461,12 @@ static int save_bess_mbc_block(GB_gameboy_t *gb, virtual_file_t *file)
|
|||||||
pairs[3] = (BESS_MBC_pair_t){LE16(0x4000), gb->mbc5.ram_bank};
|
pairs[3] = (BESS_MBC_pair_t){LE16(0x4000), gb->mbc5.ram_bank};
|
||||||
mbc_block.size = 4 * sizeof(pairs[0]);
|
mbc_block.size = 4 * sizeof(pairs[0]);
|
||||||
break;
|
break;
|
||||||
|
case GB_CAMERA:
|
||||||
|
pairs[0] = (BESS_MBC_pair_t){LE16(0x0000), gb->mbc_ram_enable? 0xA : 0x0};
|
||||||
|
pairs[1] = (BESS_MBC_pair_t){LE16(0x2000), gb->mbc5.rom_bank_low};
|
||||||
|
pairs[2] = (BESS_MBC_pair_t){LE16(0x4000), gb->mbc5.ram_bank};
|
||||||
|
mbc_block.size = 3 * sizeof(pairs[0]);
|
||||||
|
break;
|
||||||
case GB_MBC7:
|
case GB_MBC7:
|
||||||
pairs[0] = (BESS_MBC_pair_t){LE16(0x0000), gb->mbc_ram_enable? 0xA : 0x0};
|
pairs[0] = (BESS_MBC_pair_t){LE16(0x0000), gb->mbc_ram_enable? 0xA : 0x0};
|
||||||
pairs[1] = (BESS_MBC_pair_t){LE16(0x2000), gb->mbc7.rom_bank};
|
pairs[1] = (BESS_MBC_pair_t){LE16(0x2000), gb->mbc7.rom_bank};
|
||||||
|
Loading…
Reference in New Issue
Block a user