mirror of https://github.com/mgba-emu/mgba.git
GBA Timers: Improve timer startup emulation
This commit is contained in:
parent
ab1d825e30
commit
0e49b2d391
1
CHANGES
1
CHANGES
|
@ -92,6 +92,7 @@ Emulation fixes:
|
|||
- 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
|
||||
|
|
|
@ -712,16 +712,16 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
|||
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:
|
||||
|
|
|
@ -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 @@ static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) {
|
|||
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 @@ void GBATimerWriteTMCNT_HI(struct GBA* gba, int timer, uint16_t control) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue