More accurate emulation of the LYC register and interrupt. (Still not perfect on a CGB)

This commit is contained in:
Lior Halphon 2018-04-27 13:40:39 +03:00
parent 0f8385a798
commit af3554c1d1
3 changed files with 10 additions and 4 deletions

View File

@ -247,9 +247,13 @@ void GB_STAT_update(GB_gameboy_t *gb)
gb->stat_interrupt_line = gb->oam_interrupt_line; gb->stat_interrupt_line = gb->oam_interrupt_line;
/* Set LY=LYC bit */ /* Set LY=LYC bit */
if (gb->ly_for_comparison == gb->io_registers[GB_IO_LYC]) { if (gb->ly_for_comparison == gb->io_registers[GB_IO_LYC]) {
gb->lyc_interrupt_line = true;
gb->io_registers[GB_IO_STAT] |= 4; gb->io_registers[GB_IO_STAT] |= 4;
} }
else { else {
if (gb->ly_for_comparison != (uint16_t)-1) {
gb->lyc_interrupt_line = false;
}
gb->io_registers[GB_IO_STAT] &= ~4; gb->io_registers[GB_IO_STAT] &= ~4;
} }
@ -262,7 +266,7 @@ void GB_STAT_update(GB_gameboy_t *gb)
} }
/* User requested a LY=LYC interrupt and the LY=LYC bit is on */ /* User requested a LY=LYC interrupt and the LY=LYC bit is on */
if ((gb->io_registers[GB_IO_STAT] & 0x44) == 0x44) { if ((gb->io_registers[GB_IO_STAT] & 0x40) && gb->lyc_interrupt_line) {
gb->stat_interrupt_line = true; gb->stat_interrupt_line = true;
} }

View File

@ -423,6 +423,7 @@ struct GB_gameboy_internal_s {
uint8_t extra_penalty_for_sprite_at_0; uint8_t extra_penalty_for_sprite_at_0;
bool is_first_line_mode2; bool is_first_line_mode2;
bool oam_interrupt_line; bool oam_interrupt_line;
bool lyc_interrupt_line;
); );
/* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */ /* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */

View File

@ -13,18 +13,20 @@ typedef enum {
GB_CONFLICT_READ_NEW, GB_CONFLICT_READ_NEW,
/* If the CPU writes while another component reads, it reads a bitwise OR between the new and old values */ /* If the CPU writes while another component reads, it reads a bitwise OR between the new and old values */
GB_CONFLICT_READ_OR, GB_CONFLICT_READ_OR,
/* If the CPU and another component write at the same time, the CPU's value "wins"*/ /* If the CPU and another component write at the same time, the CPU's value "wins" */
GB_CONFLICT_WRITE_CPU, GB_CONFLICT_WRITE_CPU,
} GB_conflict_t; } GB_conflict_t;
/* Todo: How does double speed mode affect these? */
static const GB_conflict_t cgb_conflict_map[0x80] = { static const GB_conflict_t cgb_conflict_map[0x80] = {
[GB_IO_IF] = GB_CONFLICT_WRITE_CPU, [GB_IO_IF] = GB_CONFLICT_WRITE_CPU,
/* Todo: most values not verified, and probably differ between revisions */ /* Todo: most values not verified, and probably differ between revisions */
}; };
static const GB_conflict_t dmg_conflict_map[0x80] = { static const GB_conflict_t dmg_conflict_map[0x80] = {
[GB_IO_IF] = GB_CONFLICT_WRITE_CPU, [GB_IO_IF] = GB_CONFLICT_WRITE_CPU,
[GB_IO_LYC] = GB_CONFLICT_READ_OLD,
/* Todo: these are GB_CONFLICT_READ_NEW on MGB/SGB2 */ /* Todo: these are GB_CONFLICT_READ_NEW on MGB/SGB2 */
[GB_IO_BGP] = GB_CONFLICT_READ_OR, [GB_IO_BGP] = GB_CONFLICT_READ_OR,
@ -40,7 +42,6 @@ static const GB_conflict_t dmg_conflict_map[0x80] = {
/* Todo: these were not verified at all */ /* Todo: these were not verified at all */
[GB_IO_WY] = GB_CONFLICT_READ_NEW, [GB_IO_WY] = GB_CONFLICT_READ_NEW,
[GB_IO_WX] = GB_CONFLICT_READ_NEW, [GB_IO_WX] = GB_CONFLICT_READ_NEW,
[GB_IO_LYC] = GB_CONFLICT_READ_NEW,
}; };
static uint8_t cycle_read(GB_gameboy_t *gb, uint16_t addr) static uint8_t cycle_read(GB_gameboy_t *gb, uint16_t addr)