diff --git a/include/mgba/core/timing.h b/include/mgba/core/timing.h index 3db79493c..6e938970e 100644 --- a/include/mgba/core/timing.h +++ b/include/mgba/core/timing.h @@ -33,14 +33,20 @@ struct mTiming { void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextEvent); void mTimingDeinit(struct mTiming* timing); + void mTimingClear(struct mTiming* timing); +void mTimingInterrupt(struct mTiming* timing); + void mTimingSchedule(struct mTiming* timing, struct mTimingEvent*, int32_t when); void mTimingScheduleAbsolute(struct mTiming* timing, struct mTimingEvent*, int32_t when); void mTimingDeschedule(struct mTiming* timing, struct mTimingEvent*); bool mTimingIsScheduled(const struct mTiming* timing, const struct mTimingEvent*); + int32_t mTimingTick(struct mTiming* timing, int32_t cycles); + int32_t mTimingCurrentTime(const struct mTiming* timing); uint64_t mTimingGlobalTime(const struct mTiming* timing); + int32_t mTimingNextEvent(struct mTiming* timing); int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent*); diff --git a/src/core/timing.c b/src/core/timing.c index 4ac09a5a0..a44bbb786 100644 --- a/src/core/timing.c +++ b/src/core/timing.c @@ -25,6 +25,14 @@ void mTimingClear(struct mTiming* timing) { timing->masterCycles = 0; } +void mTimingInterrupt(struct mTiming* timing) { + if (!timing->root) { + return; + } + timing->reroot = timing->root; + timing->root = NULL; +} + void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t when) { int32_t nextEvent = when + *timing->relativeCycles; event->when = nextEvent + timing->masterCycles; diff --git a/src/gb/core.c b/src/gb/core.c index 8cc0f21f2..7edb1a607 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -660,6 +660,8 @@ static void _GBCoreReset(struct mCore* core) { if (core->opts.skipBios) { GBSkipBIOS(core->board); } + + mTimingInterrupt(&gb->timing); } static void _GBCoreRunFrame(struct mCore* core) { diff --git a/src/gb/serialize.c b/src/gb/serialize.c index ad7ebe756..0abdc1958 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -217,8 +217,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { gb->cpu->memory.setActiveRegion(gb->cpu, gb->cpu->pc); - gb->timing.reroot = gb->timing.root; - gb->timing.root = NULL; + mTimingInterrupt(&gb->timing); return true; } diff --git a/src/gba/core.c b/src/gba/core.c index 2ad7322e4..5b134338f 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -712,6 +712,8 @@ static void _GBACoreReset(struct mCore* core) { if (forceSkip || (core->opts.skipBios && (gba->romVf || gba->memory.rom))) { GBASkipBIOS(core->board); } + + mTimingInterrupt(&gba->timing); } static void _GBACoreRunFrame(struct mCore* core) { diff --git a/src/gba/serialize.c b/src/gba/serialize.c index c64d7c22b..1079932be 100644 --- a/src/gba/serialize.c +++ b/src/gba/serialize.c @@ -211,8 +211,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) { GBAMatrixDeserialize(gba, state); } - gba->timing.reroot = gba->timing.root; - gba->timing.root = NULL; + mTimingInterrupt(&gba->timing); return true; }