GBA: Count up timers should not count themselves
Jeffrey Pfau jeffrey@endrift.com
Wed, 14 Sep 2016 01:34:53 -0700
3 files changed,
16 insertions(+),
9 deletions(-)
M
CHANGES
→
CHANGES
@@ -40,6 +40,7 @@ - GBA: Timer 0 cannot be count up
- Qt: Fix being unable to pause manually when using auto-pausing - GBA Memory: Fix ldm {pc} - GBA Video: Fix out-of-order OBJWIN + - GBA: Count up timers should not count themselves Misc: - 3DS: Use blip_add_delta_fast for a small speed improvement - OpenGL: Log shader compilation failure
M
src/gba/gba.c
→
src/gba/gba.c
@@ -306,7 +306,7 @@ struct GBATimer* timer;
struct GBATimer* nextTimer; timer = &gba->timers[0]; - if (GBATimerFlagsIsEnable(timer->flags)) { + if (GBATimerFlagsIsEnable(timer->flags) && timer->nextEvent != INT_MAX) { timer->nextEvent -= cycles; timer->lastEvent -= cycles; while (timer->nextEvent <= 0) {@@ -333,7 +333,7 @@ nextTimer = &gba->timers[1];
if (GBATimerFlagsIsCountUp(nextTimer->flags)) { ++gba->memory.io[REG_TM1CNT_LO >> 1]; if (!gba->memory.io[REG_TM1CNT_LO >> 1]) { - nextTimer->nextEvent = 0; + nextTimer->nextEvent = cycles; } } }@@ -341,7 +341,7 @@ nextEvent = timer->nextEvent;
} timer = &gba->timers[1]; - if (GBATimerFlagsIsEnable(timer->flags)) { + if (GBATimerFlagsIsEnable(timer->flags) && timer->nextEvent != INT_MAX) { timer->nextEvent -= cycles; timer->lastEvent -= cycles; if (timer->nextEvent <= 0) {@@ -372,7 +372,7 @@ nextTimer = &gba->timers[2];
if (GBATimerFlagsIsCountUp(nextTimer->flags)) { ++gba->memory.io[REG_TM2CNT_LO >> 1]; if (!gba->memory.io[REG_TM2CNT_LO >> 1]) { - nextTimer->nextEvent = 0; + nextTimer->nextEvent = cycles; } } }@@ -382,7 +382,7 @@ }
} timer = &gba->timers[2]; - if (GBATimerFlagsIsEnable(timer->flags)) { + if (GBATimerFlagsIsEnable(timer->flags) && timer->nextEvent != INT_MAX) { timer->nextEvent -= cycles; timer->lastEvent -= cycles; if (timer->nextEvent <= 0) {@@ -403,7 +403,7 @@ nextTimer = &gba->timers[3];
if (GBATimerFlagsIsCountUp(nextTimer->flags)) { ++gba->memory.io[REG_TM3CNT_LO >> 1]; if (!gba->memory.io[REG_TM3CNT_LO >> 1]) { - nextTimer->nextEvent = 0; + nextTimer->nextEvent = cycles; } } }@@ -413,7 +413,7 @@ }
} timer = &gba->timers[3]; - if (GBATimerFlagsIsEnable(timer->flags)) { + if (GBATimerFlagsIsEnable(timer->flags) && timer->nextEvent != INT_MAX) { timer->nextEvent -= cycles; timer->lastEvent -= cycles; if (timer->nextEvent <= 0) {
M
src/gba/io.c
→
src/gba/io.c
@@ -883,10 +883,16 @@ gba->timersEnabled = 0;
for (i = 0; i < 4; ++i) { LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload); LOAD_16(gba->timers[i].oldReload, 0, &state->timers[i].oldReload); - LOAD_32(gba->timers[i].lastEvent, 0, &state->timers[i].lastEvent); - LOAD_32(gba->timers[i].nextEvent, 0, &state->timers[i].nextEvent); 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 + gba->timers[i].lastEvent = 0; + gba->timers[i].nextEvent = INT_MAX; + } else { + LOAD_32(gba->timers[i].lastEvent, 0, &state->timers[i].lastEvent); + LOAD_32(gba->timers[i].nextEvent, 0, &state->timers[i].nextEvent); + } LOAD_16(gba->memory.dma[i].reg, (REG_DMA0CNT_HI + i * 12), state->io); LOAD_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource); LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);