From 0786d7fe3b6c78f46236cbb8fe2b91793d5304be Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jul 2017 09:59:26 -0700 Subject: [PATCH] GBA Timer: Fix reload timing regression --- include/mgba/internal/gba/timer.h | 1 - src/gba/io.c | 2 -- src/gba/timer.c | 6 +++++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/mgba/internal/gba/timer.h b/include/mgba/internal/gba/timer.h index 5cb23605b..664842e6b 100644 --- a/include/mgba/internal/gba/timer.h +++ b/include/mgba/internal/gba/timer.h @@ -23,7 +23,6 @@ struct GBATimer { uint16_t reload; int32_t lastEvent; struct mTimingEvent event; - int32_t overflowInterval; GBATimerFlags flags; }; diff --git a/src/gba/io.c b/src/gba/io.c index ebcb30d95..bae8236f3 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -928,7 +928,6 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) { STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload); STORE_32(gba->timers[i].lastEvent - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].lastEvent); STORE_32(gba->timers[i].event.when - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].nextEvent); - STORE_32(gba->timers[i].overflowInterval, 0, &state->timers[i].overflowInterval); STORE_32(gba->timers[i].flags, 0, &state->timers[i].flags); STORE_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource); STORE_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest); @@ -958,7 +957,6 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) { mTimingSchedule(&gba->timing, &gba->timerMaster, when); for (i = 0; i < 4; ++i) { LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload); - LOAD_32(gba->timers[i].overflowInterval, 0, &state->timers[i].overflowInterval); LOAD_32(gba->timers[i].flags, 0, &state->timers[i].flags); if (i > 0 && GBATimerFlagsIsCountUp(gba->timers[i].flags)) { // Overwrite invalid values in savestate diff --git a/src/gba/timer.c b/src/gba/timer.c index ee965aa78..d68fcbef4 100644 --- a/src/gba/timer.c +++ b/src/gba/timer.c @@ -13,7 +13,11 @@ static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) { struct GBATimer* timer = &gba->timers[timerId]; gba->memory.io[(REG_TM0CNT_LO >> 1) + (timerId << 1)] = timer->reload; - GBATimerUpdateRegister(gba, timerId, cyclesLate); + int32_t currentTime = mTimingCurrentTime(&gba->timing) - cyclesLate; + int32_t tickMask = (1 << GBATimerFlagsGetPrescaleBits(timer->flags)) - 1; + currentTime &= ~tickMask; + timer->lastEvent = currentTime; + GBATimerUpdateRegister(gba, timerId, 0); if (GBATimerFlagsIsDoIrq(timer->flags)) { GBARaiseIRQ(gba, IRQ_TIMER0 + timerId);