From 90e932e12c0e093d9ff35989bf12778d7ff079eb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 5 Jun 2020 20:29:31 -0700 Subject: [PATCH] SM83: Emulate HALT bug --- CHANGES | 1 + include/mgba/internal/sm83/sm83.h | 3 ++- src/gb/gb.c | 5 +++-- src/sm83/sm83.c | 11 +++++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index fef76ce8f..0953fc677 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Emulation fixes: - GBA Video: Fix disabling OBJWIN in GL renderer (fixes mgba.io/i/1759) - GBA Video: Add missing parts of 256-color mode 0 mosaic (fixes mgba.io/1701) - GBA Video: Fix double-size OBJ wrapping in GL renderer (fixes mgba.io/1712) + - SM83: Emulate HALT bug Other fixes: - 3DS: Fix framelimiter on newer citro3d (fixes mgba.io/i/1771) - All: Improve export headers (fixes mgba.io/i/1738) diff --git a/include/mgba/internal/sm83/sm83.h b/include/mgba/internal/sm83/sm83.h index e2cf89540..3e36e4e26 100644 --- a/include/mgba/internal/sm83/sm83.h +++ b/include/mgba/internal/sm83/sm83.h @@ -47,7 +47,8 @@ enum SM83ExecutionState { SM83_CORE_MEMORY_STORE = 11, SM83_CORE_READ_PC = 15, SM83_CORE_STALL = 19, - SM83_CORE_OP2 = 23 + SM83_CORE_OP2 = 23, + SM83_CORE_HALT_BUG = 27, }; struct SM83Memory { uint8_t (*cpuLoad8)(struct SM83Core*, uint16_t address); diff --git a/src/gb/gb.c b/src/gb/gb.c index 0aaa6ae54..fda3f214a 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -749,8 +749,9 @@ void GBHalt(struct SM83Core* cpu) { if (!(gb->memory.ie & gb->memory.io[REG_IF] & 0x1F)) { cpu->cycles = cpu->nextEvent; cpu->halted = true; - } else if (gb->model < GB_MODEL_CGB) { - mLOG(GB, STUB, "Unimplemented HALT bug"); + } else { + mLOG(GB, GAME_ERROR, "HALT bug"); + cpu->executionState = SM83_CORE_HALT_BUG; } } diff --git a/src/sm83/sm83.c b/src/sm83/sm83.c index eca13bbb8..28e9e4bd3 100644 --- a/src/sm83/sm83.c +++ b/src/sm83/sm83.c @@ -131,6 +131,17 @@ static void _SM83Step(struct SM83Core* cpu) { case SM83_CORE_STALL: cpu->instruction = _sm83InstructionTable[0]; // NOP break; + case SM83_CORE_HALT_BUG: + if (cpu->irqPending) { + cpu->index = cpu->sp; + cpu->irqPending = false; + cpu->instruction = _SM83InstructionIRQ; + cpu->irqh.setInterrupts(cpu, false); + break; + } + cpu->bus = cpu->memory.cpuLoad8(cpu, cpu->pc); + cpu->instruction = _sm83InstructionTable[cpu->bus]; + break; default: break; }