diff --git a/src/core/timing.c b/src/core/timing.c index 9ee376fb0..1a9bc88b5 100644 --- a/src/core/timing.c +++ b/src/core/timing.c @@ -7,10 +7,11 @@ DEFINE_VECTOR(mTimingEventList, struct mTimingEvent*); -void mTimingInit(struct mTiming* timing, int32_t* relativeCycles) { +void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextEvent) { mTimingEventListInit(&timing->events, 0); timing->masterCycles = 0; timing->relativeCycles = relativeCycles; + timing->nextEvent = nextEvent; } void mTimingDeinit(struct mTiming* timing) { @@ -23,7 +24,11 @@ void mTimingClear(struct mTiming* timing) { } void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t when) { - event->when = when + timing->masterCycles + *timing->relativeCycles; + int32_t nextEvent = when + *timing->relativeCycles; + event->when = nextEvent + timing->masterCycles; + if (nextEvent < *timing->nextEvent) { + *timing->nextEvent = nextEvent; + } size_t e; for (e = 0; e < mTimingEventListSize(&timing->events); ++e) { struct mTimingEvent* next = *mTimingEventListGetPointer(&timing->events, e); @@ -54,6 +59,7 @@ void mTimingTick(struct mTiming* timing, int32_t cycles) { struct mTimingEvent* next = *mTimingEventListGetPointer(&timing->events, 0); int32_t nextWhen = next->when - timing->masterCycles; if (nextWhen > 0) { + *timing->nextEvent = nextWhen; return; } mTimingEventListShift(&timing->events, 0, 1); diff --git a/src/core/timing.h b/src/core/timing.h index 55934c6b4..3877a0f1b 100644 --- a/src/core/timing.h +++ b/src/core/timing.h @@ -24,9 +24,10 @@ struct mTiming { uint32_t masterCycles; int32_t* relativeCycles; + int32_t* nextEvent; }; -void mTimingInit(struct mTiming* timing, int32_t* relativeCycles); +void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextEvent); void mTimingDeinit(struct mTiming* timing); void mTimingClear(struct mTiming* timing); void mTimingSchedule(struct mTiming* timing, struct mTimingEvent*, int32_t when); diff --git a/src/gb/gb.c b/src/gb/gb.c index d304f3449..4424d3b0d 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -83,7 +83,7 @@ static void GBInit(void* cpu, struct mCPUComponent* component) { gb->coreCallbacks = NULL; gb->stream = NULL; - mTimingInit(&gb->timing, &gb->cpu->cycles); + mTimingInit(&gb->timing, &gb->cpu->cycles, &gb->cpu->nextEvent); } static void GBDeinit(struct mCPUComponent* component) { diff --git a/src/gba/gba.c b/src/gba/gba.c index c6049b8d3..556bf6655 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -112,7 +112,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { gba->pristineRomSize = 0; gba->yankedRomSize = 0; - mTimingInit(&gba->timing, &gba->cpu->cycles); + mTimingInit(&gba->timing, &gba->cpu->cycles, &gba->cpu->nextEvent); } void GBAUnloadROM(struct GBA* gba) { @@ -188,6 +188,7 @@ void GBAReset(struct ARMCore* cpu) { gba->memory.romMask = toPow2(gba->memory.romSize) - 1; gba->yankedRomSize = 0; } + mTimingClear(&gba->timing); GBAMemoryReset(gba); GBAVideoReset(&gba->video); GBAAudioReset(&gba->audio); @@ -235,10 +236,11 @@ static void GBAProcessEvents(struct ARMCore* cpu) { do { int32_t cycles = cpu->nextEvent; - int32_t nextEvent = INT_MAX; + int32_t nextEvent; int32_t testEvent; cpu->cycles -= cycles; + cpu->nextEvent = INT_MAX; #ifndef NDEBUG if (cycles < 0) { @@ -247,10 +249,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { #endif mTimingTick(&gba->timing, cycles); - testEvent = mTimingNextEvent(&gba->timing); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } + nextEvent = cpu->nextEvent; testEvent = GBAVideoProcessEvents(&gba->video, cycles); if (testEvent < nextEvent) {