mirror of https://github.com/mgba-emu/mgba.git
GB Timer: Fix DIV batching if TAC changes
This commit is contained in:
parent
126afa12d9
commit
59922fe2e9
1
CHANGES
1
CHANGES
|
@ -66,6 +66,7 @@ Bugfixes:
|
|||
- LR35902: Fix decoding LD r, $imm and 0-valued immediates (fixes mgba.io/i/735)
|
||||
- GB: Fix STAT blocking
|
||||
- GB MBC: Fix swapping carts not detect new MBC
|
||||
- GB Timer: Fix DIV batching if TAC changes
|
||||
Misc:
|
||||
- SDL: Remove scancode key input
|
||||
- GBA Video: Clean up unused timers
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <mgba/internal/gb/io.h>
|
||||
#include <mgba/internal/gb/serialize.h>
|
||||
|
||||
static void _GBTimerUpdateDIV(struct GBTimer* timer, uint32_t cyclesLate);
|
||||
|
||||
void _GBTimerIRQ(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||
UNUSED(timing);
|
||||
UNUSED(cyclesLate);
|
||||
|
@ -34,8 +36,12 @@ void _GBTimerIncrement(struct mTiming* timing, void* context, uint32_t cyclesLat
|
|||
++timer->internalDiv;
|
||||
timer->p->memory.io[REG_DIV] = timer->internalDiv >> 4;
|
||||
}
|
||||
_GBTimerUpdateDIV(timer, cyclesLate);
|
||||
}
|
||||
|
||||
void _GBTimerUpdateDIV(struct GBTimer* timer, uint32_t cyclesLate) {
|
||||
// Batch div increments
|
||||
int divsToGo = 16 - (timer->internalDiv & 15);
|
||||
int divsToGo = 16 - (timer->internalDiv & 15) + (timer->nextDiv / GB_DMG_DIV_PERIOD);
|
||||
int timaToGo = INT_MAX;
|
||||
if (timer->timaPeriod) {
|
||||
timaToGo = timer->timaPeriod - (timer->internalDiv & (timer->timaPeriod - 1));
|
||||
|
@ -43,8 +49,12 @@ void _GBTimerIncrement(struct mTiming* timing, void* context, uint32_t cyclesLat
|
|||
if (timaToGo < divsToGo) {
|
||||
divsToGo = timaToGo;
|
||||
}
|
||||
timer->nextDiv = GB_DMG_DIV_PERIOD * divsToGo;
|
||||
mTimingSchedule(timing, &timer->event, timer->nextDiv - cyclesLate);
|
||||
if (divsToGo > 16) {
|
||||
divsToGo = 16;
|
||||
}
|
||||
timer->nextDiv &= GB_DMG_DIV_PERIOD - 1;
|
||||
timer->nextDiv += GB_DMG_DIV_PERIOD * divsToGo;
|
||||
mTimingSchedule(&timer->p->timing, &timer->event, timer->nextDiv - cyclesLate);
|
||||
}
|
||||
|
||||
void GBTimerReset(struct GBTimer* timer) {
|
||||
|
@ -89,6 +99,8 @@ uint8_t GBTimerUpdateTAC(struct GBTimer* timer, GBRegisterTAC tac) {
|
|||
} else {
|
||||
timer->timaPeriod = 0;
|
||||
}
|
||||
mTimingDeschedule(&timer->p->timing, &timer->event);
|
||||
_GBTimerUpdateDIV(timer, 0);
|
||||
return tac;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue