Emulate an HDMA quirk required to properly emulate Aevilia

This commit is contained in:
Lior Halphon 2018-02-25 22:32:41 +02:00
parent 058913f8a2
commit 90a943d05a
4 changed files with 11 additions and 4 deletions

View File

@ -527,6 +527,8 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles)
gb->vram_read_blocked = false; gb->vram_read_blocked = false;
gb->oam_write_blocked = false; gb->oam_write_blocked = false;
gb->vram_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) { if (gb->hdma_on_hblank) {
gb->hdma_on = true; gb->hdma_on = true;
gb->hdma_cycles = 0; gb->hdma_cycles = 0;

View File

@ -254,7 +254,7 @@ struct GB_gameboy_internal_s {
bool halted; bool halted;
bool stopped; bool stopped;
bool boot_rom_finished; 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; bool halt_bug;
/* Misc state */ /* Misc state */
@ -275,6 +275,7 @@ struct GB_gameboy_internal_s {
uint16_t dma_current_src; uint16_t dma_current_src;
int16_t dma_cycles; int16_t dma_cycles;
bool is_dma_restarting; bool is_dma_restarting;
uint8_t last_opcode_read; /* Required to emulte HDMA reads from Exxx */
); );
/* MBC */ /* MBC */

View File

@ -111,6 +111,9 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr)
{ {
if (addr < 0xFE00) { if (addr < 0xFE00) {
if (gb->hdma_on) {
return gb->last_opcode_read;
}
return gb->ram[addr & 0x0FFF]; 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) { 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 */ if ((gb->io_registers[GB_IO_STAT] & 0x3) >= 2) { /* Seems to be disabled in Modes 2 and 3 */
return 0xFF; return 0xFF;
} }

View File

@ -1392,12 +1392,12 @@ void GB_cpu_run(GB_gameboy_t *gb)
GB_debugger_call_hook(gb, call_addr); GB_debugger_call_hook(gb, call_addr);
} }
else if(!gb->halted && !gb->stopped) { 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) { if (gb->halt_bug) {
gb->pc--; gb->pc--;
gb->halt_bug = false; gb->halt_bug = false;
} }
opcodes[opcode](gb, opcode); opcodes[gb->last_opcode_read](gb, gb->last_opcode_read);
} }
else { else {
GB_advance_cycles(gb, 4); GB_advance_cycles(gb, 4);