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;
int32_t lastEvent;
struct mTimingEvent event;
int32_t overflowInterval;
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_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

View File

@ -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);