all repos — mgba @ ba2175f5c513288d7c1feba3dad6a964cb7a22b4

mGBA Game Boy Advance Emulator

GB: Allow pausing event loop while CPU is blocked
Vicki Pfau vi@endrift.com
Sun, 12 Jul 2020 23:50:28 -0700
commit

ba2175f5c513288d7c1feba3dad6a964cb7a22b4

parent

0fd6532b3817c375836002716c90a21d1111a197

5 files changed, 13 insertions(+), 1 deletions(-)

jump to
M CHANGESCHANGES

@@ -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.hinclude/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.csrc/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.csrc/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.csrc/gb/video.c

@@ -379,6 +379,7 @@ }

GBFrameEnded(video->p); mCoreSyncPostFrame(video->p->sync); ++video->frameCounter; + video->p->earlyExit = true; GBFrameStarted(video->p); }