mirror of https://github.com/mgba-emu/mgba.git
GBA Timer: Fix reload timing regression
This commit is contained in:
parent
7a5190e95e
commit
0786d7fe3b
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue