GBA Timer: Fix reload timing regression

This commit is contained in:
Vicki Pfau 2017-07-04 09:59:26 -07:00
parent 7a5190e95e
commit 0786d7fe3b
3 changed files with 5 additions and 4 deletions

View File

@ -23,7 +23,6 @@ struct GBATimer {
uint16_t reload; uint16_t reload;
int32_t lastEvent; int32_t lastEvent;
struct mTimingEvent event; struct mTimingEvent event;
int32_t overflowInterval;
GBATimerFlags flags; GBATimerFlags flags;
}; };

View File

@ -928,7 +928,6 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload); 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].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].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->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].nextSource, 0, &state->dma[i].nextSource);
STORE_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest); 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); mTimingSchedule(&gba->timing, &gba->timerMaster, when);
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload); 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); LOAD_32(gba->timers[i].flags, 0, &state->timers[i].flags);
if (i > 0 && GBATimerFlagsIsCountUp(gba->timers[i].flags)) { if (i > 0 && GBATimerFlagsIsCountUp(gba->timers[i].flags)) {
// Overwrite invalid values in savestate // Overwrite invalid values in savestate

View File

@ -13,7 +13,11 @@
static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) { static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) {
struct GBATimer* timer = &gba->timers[timerId]; struct GBATimer* timer = &gba->timers[timerId];
gba->memory.io[(REG_TM0CNT_LO >> 1) + (timerId << 1)] = timer->reload; 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)) { if (GBATimerFlagsIsDoIrq(timer->flags)) {
GBARaiseIRQ(gba, IRQ_TIMER0 + timerId); GBARaiseIRQ(gba, IRQ_TIMER0 + timerId);