Basic GB Camera support (Emulate only MBC, enough for the ROM to boot).
This commit is contained in:
parent
9b71454f07
commit
b3b041a151
@ -172,6 +172,7 @@ typedef struct {
|
|||||||
enum {
|
enum {
|
||||||
GB_STANDARD_MBC,
|
GB_STANDARD_MBC,
|
||||||
GB_HUC1, /* Todo: HUC1 features are not emulated. Should be unified with the CGB IR sensor API. */
|
GB_HUC1, /* Todo: HUC1 features are not emulated. Should be unified with the CGB IR sensor API. */
|
||||||
|
GB_CAMERA, /* Not emulated as well */
|
||||||
} mbc_subtype;
|
} mbc_subtype;
|
||||||
bool has_ram;
|
bool has_ram;
|
||||||
bool has_battery;
|
bool has_battery;
|
||||||
@ -282,6 +283,7 @@ typedef struct GB_gameboy_s {
|
|||||||
} mbc5;
|
} mbc5;
|
||||||
};
|
};
|
||||||
uint16_t mbc_rom0_bank; /* For some MBC1 wirings. */
|
uint16_t mbc_rom0_bank; /* For some MBC1 wirings. */
|
||||||
|
bool camera_registers_mapped;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ const GB_cartridge_t GB_cart_defs[256] = {
|
|||||||
{ GB_MBC5 , GB_STANDARD_MBC, true , true , false, true }, // 1Eh MBC5+RUMBLE+RAM+BATTERY
|
{ GB_MBC5 , GB_STANDARD_MBC, true , true , false, true }, // 1Eh MBC5+RUMBLE+RAM+BATTERY
|
||||||
[0xFC] =
|
[0xFC] =
|
||||||
// Todo: What are these?
|
// Todo: What are these?
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FCh POCKET CAMERA
|
{ GB_MBC5 , GB_CAMERA , true, true, false, false}, // FCh POCKET CAMERA
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FDh BANDAI TAMA5
|
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FDh BANDAI TAMA5
|
||||||
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FEh HuC3
|
{ GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FEh HuC3
|
||||||
{ GB_MBC1 , GB_HUC1 , true , true , false, false}, // FFh HuC1+RAM+BATTERY
|
{ GB_MBC1 , GB_HUC1 , true , true , false, false}, // FFh HuC1+RAM+BATTERY
|
||||||
|
@ -74,7 +74,7 @@ static uint8_t read_vram(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
|
|
||||||
static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
|
static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
|
||||||
{
|
{
|
||||||
if (!gb->mbc_ram_enable || !gb->mbc_ram_size) return 0xFF;
|
if ((!gb->mbc_ram_enable || !gb->mbc_ram_size) && gb->cartridge_type->mbc_subtype != GB_CAMERA) return 0xFF;
|
||||||
|
|
||||||
if (gb->cartridge_type->has_rtc && gb->mbc_ram_bank >= 8 && gb->mbc_ram_bank <= 0xC) {
|
if (gb->cartridge_type->has_rtc && gb->mbc_ram_bank >= 8 && gb->mbc_ram_bank <= 0xC) {
|
||||||
/* RTC read */
|
/* RTC read */
|
||||||
@ -82,6 +82,10 @@ static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
return gb->rtc_latched.data[gb->mbc_ram_bank - 8];
|
return gb->rtc_latched.data[gb->mbc_ram_bank - 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gb->camera_registers_mapped) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!gb->mbc_ram) {
|
if (!gb->mbc_ram) {
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
@ -282,7 +286,7 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
break;
|
break;
|
||||||
case GB_MBC2:
|
case GB_MBC2:
|
||||||
switch (addr & 0xF000) {
|
switch (addr & 0xF000) {
|
||||||
case 0x0000: case 0x1000: if (!(addr & 0x100)) gb->mbc_ram_enable = value == 10; break;
|
case 0x0000: case 0x1000: if (!(addr & 0x100)) gb->mbc_ram_enable = value == 0xA; break;
|
||||||
case 0x2000: case 0x3000: if ( addr & 0x100) gb->mbc2.rom_bank = value; break;
|
case 0x2000: case 0x3000: if ( addr & 0x100) gb->mbc2.rom_bank = value; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -292,7 +296,7 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
case 0x2000: case 0x3000: gb->mbc3.rom_bank = value; break;
|
case 0x2000: case 0x3000: gb->mbc3.rom_bank = value; break;
|
||||||
case 0x4000: case 0x5000: gb->mbc3.ram_bank = value; break;
|
case 0x4000: case 0x5000: gb->mbc3.ram_bank = value; break;
|
||||||
case 0x6000: case 0x7000:
|
case 0x6000: case 0x7000:
|
||||||
if (!gb->rtc_latch && (value & 1)) { /* Todo: verify condition is correct*/
|
if (!gb->rtc_latch && (value & 1)) { /* Todo: verify condition is correct */
|
||||||
memcpy(&gb->rtc_latched, &gb->rtc_real, sizeof(gb->rtc_real));
|
memcpy(&gb->rtc_latched, &gb->rtc_real, sizeof(gb->rtc_real));
|
||||||
}
|
}
|
||||||
gb->rtc_latch = value & 1;
|
gb->rtc_latch = value & 1;
|
||||||
@ -304,7 +308,10 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
case 0x0000: case 0x1000: gb->mbc_ram_enable = (value & 0xF) == 0xA; break;
|
case 0x0000: case 0x1000: gb->mbc_ram_enable = (value & 0xF) == 0xA; break;
|
||||||
case 0x2000: gb->mbc5.rom_bank_low = value; break;
|
case 0x2000: gb->mbc5.rom_bank_low = value; break;
|
||||||
case 0x3000: gb->mbc5.rom_bank_high = value; break;
|
case 0x3000: gb->mbc5.rom_bank_high = value; break;
|
||||||
case 0x4000: case 0x5000: gb->mbc5.ram_bank = value; break;
|
case 0x4000: case 0x5000:
|
||||||
|
gb->mbc5.ram_bank = value;
|
||||||
|
gb->camera_registers_mapped = (value & 0x10) && gb->cartridge_type->mbc_subtype == GB_CAMERA;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -333,6 +340,10 @@ static void write_mbc_ram(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gb->camera_registers_mapped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gb->mbc_ram[((addr & 0x1FFF) + gb->mbc_ram_bank * 0x2000) & (gb->mbc_ram_size - 1)] = value;
|
gb->mbc_ram[((addr & 0x1FFF) + gb->mbc_ram_bank * 0x2000) & (gb->mbc_ram_size - 1)] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user