diff --git a/Core/gb.h b/Core/gb.h index ca810ba..f5061bb 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -88,8 +88,11 @@ enum { GB_IO_OBP1 = 0x49, // Object Palette 1 Data (R/W) - Non CGB Mode Only GB_IO_WY = 0x4a, // Window Y Position (R/W) GB_IO_WX = 0x4b, // Window X Position minus 7 (R/W) - - /* Missing */ + // Has some undocumented compatibility flags written at boot. + // Unfortunately it is not readable or writable after boot has finished, so research of this + // register is quite limited. The value written to this register, however, can be controlled + // in some cases. + GB_IO_DMG_EMULATION = 0x4c, /* General CGB features */ GB_IO_KEY1 = 0x4d, // CGB Mode Only - Prepare Speed Switch @@ -117,7 +120,8 @@ enum { GB_IO_OBPI = 0x6a, // CGB Mode Only - Sprite Palette Index GB_IO_OBPD = 0x6b, // CGB Mode Only - Sprite Palette Data - GB_IO_DMG_EMULATION = 0x6c, // (FEh) Bit 0 (Read/Write) - CGB Mode Only + // 1 is written for DMG ROMs on a CGB. Does not appear to have an effect. + GB_IO_DMG_EMULATION_INDICATION = 0x6c, // (FEh) Bit 0 (Read/Write) /* Missing */ diff --git a/Core/memory.c b/Core/memory.c index 3e8c154..9ac5a1f 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -100,6 +100,8 @@ static unsigned char read_high_memory(GB_gameboy_t *gb, unsigned short addr) return gb->io_registers[GB_IO_TAC] | 0xF8; case GB_IO_STAT: return gb->io_registers[GB_IO_STAT] | 0x80; + case GB_IO_DMG_EMULATION_INDICATION: + return gb->io_registers[GB_IO_DMG_EMULATION_INDICATION] | 0xFE; case GB_IO_JOYP: case GB_IO_DIV: case GB_IO_TIMA: @@ -155,7 +157,7 @@ static unsigned char read_high_memory(GB_gameboy_t *gb, unsigned short addr) } case GB_IO_KEY1: - if (!gb->is_cgb) { + if (!gb->cgb_mode) { return 0xFF; } return (gb->io_registers[GB_IO_KEY1] & 0x7F) | (gb->cgb_double_speed? 0xFE : 0x7E); @@ -349,6 +351,7 @@ static void write_high_memory(GB_gameboy_t *gb, unsigned short addr, unsigned ch case GB_IO_HDMA3: case GB_IO_HDMA4: case GB_IO_SB: + case GB_IO_DMG_EMULATION_INDICATION: gb->io_registers[addr & 0xFF] = value; return; @@ -382,8 +385,9 @@ static void write_high_memory(GB_gameboy_t *gb, unsigned short addr, unsigned ch return; case GB_IO_DMG_EMULATION: - // Todo: Can it be disabled? What about values other than 1? - gb->cgb_mode = false; + if (gb->is_cgb && !gb->bios_finished) { + gb->cgb_mode = value != 4; /* The real "contents" of this register aren't quite known yet. */ + } return; case GB_IO_DMA: