diff --git a/Core/display.c b/Core/display.c index 41f85bf..dda9fab 100755 --- a/Core/display.c +++ b/Core/display.c @@ -527,6 +527,8 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles) gb->vram_read_blocked = false; gb->oam_write_blocked = false; gb->vram_write_blocked = false; + } + else if (position_in_line == MODE2_LENGTH + MODE3_LENGTH + stat_delay + scx_delay + 16) { if (gb->hdma_on_hblank) { gb->hdma_on = true; gb->hdma_cycles = 0; diff --git a/Core/gb.h b/Core/gb.h index 3dea996..c93aa3d 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -254,7 +254,7 @@ struct GB_gameboy_internal_s { bool halted; bool stopped; bool boot_rom_finished; - bool ime_toggle; /* ei (and di in CGB) have delayed effects.*/ + bool ime_toggle; /* ei has delayed a effect.*/ bool halt_bug; /* Misc state */ @@ -275,6 +275,7 @@ struct GB_gameboy_internal_s { uint16_t dma_current_src; int16_t dma_cycles; bool is_dma_restarting; + uint8_t last_opcode_read; /* Required to emulte HDMA reads from Exxx */ ); /* MBC */ diff --git a/Core/memory.c b/Core/memory.c index ef2f007..dca92aa 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -111,6 +111,9 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) { if (addr < 0xFE00) { + if (gb->hdma_on) { + return gb->last_opcode_read; + } return gb->ram[addr & 0x0FFF]; } @@ -122,7 +125,8 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) } if (addr < 0xFF00) { - /* Unusable. CGB results are verified, but DMG results were tested on a SGB2 */ + /* Unusable. CGB results are verified, but DMG results were tested on a SGB2 */ + /* Also, writes to this area are not emulated */ if ((gb->io_registers[GB_IO_STAT] & 0x3) >= 2) { /* Seems to be disabled in Modes 2 and 3 */ return 0xFF; } diff --git a/Core/z80_cpu.c b/Core/z80_cpu.c index 16dbd08..4794df5 100644 --- a/Core/z80_cpu.c +++ b/Core/z80_cpu.c @@ -1392,12 +1392,12 @@ void GB_cpu_run(GB_gameboy_t *gb) GB_debugger_call_hook(gb, call_addr); } else if(!gb->halted && !gb->stopped) { - uint8_t opcode = GB_read_memory(gb, gb->pc++); + gb->last_opcode_read = GB_read_memory(gb, gb->pc++); if (gb->halt_bug) { gb->pc--; gb->halt_bug = false; } - opcodes[opcode](gb, opcode); + opcodes[gb->last_opcode_read](gb, gb->last_opcode_read); } else { GB_advance_cycles(gb, 4);