Correct OAM interrupt behavior

This commit is contained in:
Lior Halphon 2016-04-02 16:29:27 +03:00
parent da00e240e5
commit b7555e9976
2 changed files with 17 additions and 18 deletions

View File

@ -242,23 +242,19 @@ void palette_changed(GB_gameboy_t *gb, bool background_palette, unsigned char in
void display_run(GB_gameboy_t *gb)
{
/*
/*
Display controller bug: For some reason, the OAM STAT interrupt is called, as expected, for LY = 0..143.
However, it is also called from LY = 144.
<del>Display controller bug: For some reason, the OAM STAT interrupt is called, as expected, for LY = 0..143.
However, it is also called from LY = 151! (The last LY is 153! Wonder why is it 151...).</del>
Todo: This discussion in NESDev proves this theory incorrect:
http://forums.nesdev.com/viewtopic.php?f=20&t=13727
Seems like there was a bug in one of my test ROMs.
This behavior needs to be corrected.
See http://forums.nesdev.com/viewtopic.php?f=20&t=13727
*/
unsigned char last_mode = gb->io_registers[GB_IO_STAT] & 3;
if (gb->display_cycles >= LCDC_PERIOD) {
/* VBlank! */
gb->display_cycles -= LCDC_PERIOD;
gb->ly151_bug_oam = false;
gb->ly151_bug_hblank = false;
gb->ly144_bug_oam = false;
gb->ly144_bug_hblank = false;
display_vblank(gb);
}
@ -310,22 +306,25 @@ void display_run(GB_gameboy_t *gb)
gb->io_registers[GB_IO_IF] |= 1;
}
// LY = 151 interrupt bug
if (gb->io_registers[GB_IO_LY] == 151) {
// LY = 144 interrupt bug
if (gb->io_registers[GB_IO_LY] == 144) {
if (gb->display_cycles % 456 < 80) { // Mode 2
if (gb->io_registers[GB_IO_STAT] & 0x20 && !gb->ly151_bug_oam) { /* User requests an interrupt on Mode 2 */
if (gb->io_registers[GB_IO_STAT] & 0x20 && !gb->ly144_bug_oam) { /* User requests an interrupt on Mode 2 */
gb->io_registers[GB_IO_IF] |= 2;
}
gb->ly151_bug_oam = true;
gb->ly144_bug_oam = true;
}
if (gb->display_cycles % 456 < 80 + 172) { /* Mode 3 */
// Nothing to do
}
else { /* Mode 0 */
if (gb->io_registers[GB_IO_STAT] & 8 && !gb->ly151_bug_hblank) { /* User requests an interrupt on Mode 0 */
if (gb->io_registers[GB_IO_STAT] & 8 && !gb->ly144_bug_hblank) { /* User requests an interrupt on Mode 0 */
/*
Todo: Verify if this actually happens.
gb->io_registers[GB_IO_IF] |= 2;
*/
}
gb->ly151_bug_hblank = true;
gb->ly144_bug_hblank = true;
}
}

View File

@ -216,8 +216,8 @@ typedef struct GB_gameboy_s{
unsigned char sprite_palletes_data[0x40];
uint32_t background_palletes_rgb[0x20];
uint32_t sprite_palletes_rgb[0x20];
bool ly151_bug_oam;
bool ly151_bug_hblank;
bool ly144_bug_oam;
bool ly144_bug_hblank;
signed short previous_lcdc_x;
signed short line_x_bias;
bool effective_window_enabled;