GBA Timers: Improve timer startup emulation
Vicki Pfau vi@endrift.com
Wed, 15 Jan 2020 18:52:35 -0800
3 files changed,
10 insertions(+),
12 deletions(-)
M
CHANGES
→
CHANGES
@@ -92,6 +92,7 @@ - ARM: Partially fix LDM/STM writeback with empty register list
- ARM: Fix stepping when events are pending - GBA DMA: Fix case where DMAs could get misaligned (fixes mgba.io/i/1092) - GBA Memory: Fix open bus from IWRAM (fixes mgba.io/i/1575) + - GBA Timers: Improve timer startup emulation - GBA Video: Fix OpenGL renderer 512x512 backgrounds (fixes mgba.io/i/1572) - GBA Video: Fix BLDY for semitransparent sprite on non-target-2 backgrounds - GBA Video: Fix effects blending improperly in some non-last windows
M
src/gba/io.c
→
src/gba/io.c
@@ -712,16 +712,16 @@
switch (address) { // Reading this takes two cycles (1N+1I), so let's remove them preemptively case REG_TM0CNT_LO: - GBATimerUpdateRegister(gba, 0, 4); + GBATimerUpdateRegister(gba, 0, 2); break; case REG_TM1CNT_LO: - GBATimerUpdateRegister(gba, 1, 4); + GBATimerUpdateRegister(gba, 1, 2); break; case REG_TM2CNT_LO: - GBATimerUpdateRegister(gba, 2, 4); + GBATimerUpdateRegister(gba, 2, 2); break; case REG_TM3CNT_LO: - GBATimerUpdateRegister(gba, 3, 4); + GBATimerUpdateRegister(gba, 3, 2); break; case REG_KEYINPUT:
M
src/gba/timer.c
→
src/gba/timer.c
@@ -8,9 +8,6 @@
#include <mgba/internal/gba/gba.h> #include <mgba/internal/gba/io.h> -#define TIMER_RELOAD_DELAY 0 -#define TIMER_STARTUP_DELAY 2 - #define REG_TMCNT_LO(X) (REG_TM0CNT_LO + ((X) << 2)) static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) {@@ -18,7 +15,7 @@ struct GBATimer* timer = &gba->timers[timerId];
if (GBATimerFlagsIsCountUp(timer->flags)) { gba->memory.io[REG_TMCNT_LO(timerId) >> 1] = timer->reload; } else { - GBATimerUpdateRegister(gba, timerId, TIMER_RELOAD_DELAY + cyclesLate); + GBATimerUpdateRegister(gba, timerId, cyclesLate); } if (GBATimerFlagsIsDoIrq(timer->flags)) {@@ -150,14 +147,14 @@ if (!wasEnabled && GBATimerFlagsIsEnable(currentTimer->flags)) {
mTimingDeschedule(&gba->timing, ¤tTimer->event); gba->memory.io[REG_TMCNT_LO(timer) >> 1] = currentTimer->reload; int32_t tickMask = (1 << prescaleBits) - 1; - currentTimer->lastEvent = (mTimingCurrentTime(&gba->timing) - TIMER_STARTUP_DELAY) & ~tickMask; - GBATimerUpdateRegister(gba, timer, TIMER_STARTUP_DELAY); + currentTimer->lastEvent = mTimingCurrentTime(&gba->timing) & ~tickMask; + GBATimerUpdateRegister(gba, timer, 0); } else if (wasEnabled && !GBATimerFlagsIsEnable(currentTimer->flags)) { mTimingDeschedule(&gba->timing, ¤tTimer->event); } else if (GBATimerFlagsIsEnable(currentTimer->flags) && GBATimerFlagsGetPrescaleBits(currentTimer->flags) != oldPrescale && !GBATimerFlagsIsCountUp(currentTimer->flags)) { mTimingDeschedule(&gba->timing, ¤tTimer->event); int32_t tickMask = (1 << prescaleBits) - 1; - currentTimer->lastEvent = (mTimingCurrentTime(&gba->timing) - TIMER_STARTUP_DELAY) & ~tickMask; - GBATimerUpdateRegister(gba, timer, TIMER_STARTUP_DELAY); + currentTimer->lastEvent = mTimingCurrentTime(&gba->timing) & ~tickMask; + GBATimerUpdateRegister(gba, timer, 0); } }