GB: Allow pausing event loop while CPU is blocked
Vicki Pfau vi@endrift.com
Sun, 12 Jul 2020 23:50:28 -0700
5 files changed,
13 insertions(+),
1 deletions(-)
M
CHANGES
→
CHANGES
@@ -55,6 +55,7 @@ - Util: Fix crash if PNG header fails to write
- SM83: Simplify register pair access on big endian - Wii: Fix pixelated filtering on interframe blending (fixes mgba.io/i/1830) Misc: + - GB: Allow pausing event loop while CPU is blocked - Debugger: Keep track of global cycle count - FFmpeg: Add looping option for GIF/APNG - FFmpeg: Use range coder for FFV1 to reduce output size
M
include/mgba/internal/gb/serialize.h
→
include/mgba/internal/gb/serialize.h
@@ -235,6 +235,8 @@ DECL_BIT(GBSerializedCpuFlags, Condition, 0);
DECL_BIT(GBSerializedCpuFlags, IrqPending, 1); DECL_BIT(GBSerializedCpuFlags, DoubleSpeed, 2); DECL_BIT(GBSerializedCpuFlags, EiPending, 3); +DECL_BIT(GBSerializedCpuFlags, Halted, 4); +DECL_BIT(GBSerializedCpuFlags, Blocked, 5); DECL_BITFIELD(GBSerializedTimerFlags, uint8_t); DECL_BIT(GBSerializedTimerFlags, IrqPending, 0);
M
src/gb/gb.c
→
src/gb/gb.c
@@ -681,7 +681,7 @@
nextEvent = cycles; do { nextEvent = mTimingTick(&gb->timing, nextEvent); - } while (gb->cpuBlocked); + } while (gb->cpuBlocked && !gb->earlyExit); cpu->nextEvent = nextEvent; if (cpu->halted) {@@ -695,6 +695,9 @@ break;
} } while (cpu->cycles >= cpu->nextEvent); gb->earlyExit = false; + if (gb->cpuBlocked) { + cpu->cycles = cpu->nextEvent; + } } void GBSetInterrupts(struct SM83Core* cpu, bool enable) {
M
src/gb/serialize.c
→
src/gb/serialize.c
@@ -56,6 +56,8 @@ flags = GBSerializedCpuFlagsSetCondition(flags, gb->cpu->condition);
flags = GBSerializedCpuFlagsSetIrqPending(flags, gb->cpu->irqPending); flags = GBSerializedCpuFlagsSetDoubleSpeed(flags, gb->doubleSpeed); flags = GBSerializedCpuFlagsSetEiPending(flags, mTimingIsScheduled(&gb->timing, &gb->eiPending)); + flags = GBSerializedCpuFlagsSetHalted(flags, gb->cpu->halted); + flags = GBSerializedCpuFlagsSetBlocked(flags, gb->cpuBlocked); STORE_32LE(flags, 0, &state->cpu.flags); STORE_32LE(gb->eiPending.when - mTimingCurrentTime(&gb->timing), 0, &state->cpu.eiPending);@@ -173,6 +175,9 @@ LOAD_32LE(flags, 0, &state->cpu.flags);
gb->cpu->condition = GBSerializedCpuFlagsGetCondition(flags); gb->cpu->irqPending = GBSerializedCpuFlagsGetIrqPending(flags); gb->doubleSpeed = GBSerializedCpuFlagsGetDoubleSpeed(flags); + gb->cpu->halted = GBSerializedCpuFlagsGetHalted(flags); + gb->cpuBlocked = GBSerializedCpuFlagsGetBlocked(flags); + gb->audio.timingFactor = gb->doubleSpeed + 1; LOAD_32LE(gb->cpu->cycles, 0, &state->cpu.cycles);
M
src/gb/video.c
→
src/gb/video.c
@@ -379,6 +379,7 @@ }
GBFrameEnded(video->p); mCoreSyncPostFrame(video->p->sync); ++video->frameCounter; + video->p->earlyExit = true; GBFrameStarted(video->p); }