mirror of https://github.com/mgba-emu/mgba.git
GB Timer: Fix TAC write fix
This commit is contained in:
parent
c1a4f17ebd
commit
3c64a2e432
|
@ -38,6 +38,7 @@ bool mTimingIsScheduled(const struct mTiming* timing, const struct mTimingEvent*
|
||||||
int32_t mTimingTick(struct mTiming* timing, int32_t cycles);
|
int32_t mTimingTick(struct mTiming* timing, int32_t cycles);
|
||||||
int32_t mTimingCurrentTime(const struct mTiming* timing);
|
int32_t mTimingCurrentTime(const struct mTiming* timing);
|
||||||
int32_t mTimingNextEvent(struct mTiming* timing);
|
int32_t mTimingNextEvent(struct mTiming* timing);
|
||||||
|
int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent*);
|
||||||
|
|
||||||
CXX_GUARD_END
|
CXX_GUARD_END
|
||||||
|
|
||||||
|
|
|
@ -91,3 +91,7 @@ int32_t mTimingNextEvent(struct mTiming* timing) {
|
||||||
}
|
}
|
||||||
return next->when - timing->masterCycles;
|
return next->when - timing->masterCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent* event) {
|
||||||
|
return event->when - timing->masterCycles;
|
||||||
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
#include <mgba/internal/gb/io.h>
|
#include <mgba/internal/gb/io.h>
|
||||||
#include <mgba/internal/gb/serialize.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) {
|
void _GBTimerIRQ(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||||
UNUSED(timing);
|
UNUSED(timing);
|
||||||
UNUSED(cyclesLate);
|
UNUSED(cyclesLate);
|
||||||
|
@ -36,12 +34,8 @@ void _GBTimerIncrement(struct mTiming* timing, void* context, uint32_t cyclesLat
|
||||||
++timer->internalDiv;
|
++timer->internalDiv;
|
||||||
timer->p->memory.io[REG_DIV] = timer->internalDiv >> 4;
|
timer->p->memory.io[REG_DIV] = timer->internalDiv >> 4;
|
||||||
}
|
}
|
||||||
_GBTimerUpdateDIV(timer, cyclesLate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _GBTimerUpdateDIV(struct GBTimer* timer, uint32_t cyclesLate) {
|
|
||||||
// Batch div increments
|
// Batch div increments
|
||||||
int divsToGo = 16 - (timer->internalDiv & 15) + (timer->nextDiv / GB_DMG_DIV_PERIOD);
|
int divsToGo = 16 - (timer->internalDiv & 15);
|
||||||
int timaToGo = INT_MAX;
|
int timaToGo = INT_MAX;
|
||||||
if (timer->timaPeriod) {
|
if (timer->timaPeriod) {
|
||||||
timaToGo = timer->timaPeriod - (timer->internalDiv & (timer->timaPeriod - 1));
|
timaToGo = timer->timaPeriod - (timer->internalDiv & (timer->timaPeriod - 1));
|
||||||
|
@ -49,12 +43,8 @@ void _GBTimerUpdateDIV(struct GBTimer* timer, uint32_t cyclesLate) {
|
||||||
if (timaToGo < divsToGo) {
|
if (timaToGo < divsToGo) {
|
||||||
divsToGo = timaToGo;
|
divsToGo = timaToGo;
|
||||||
}
|
}
|
||||||
if (divsToGo > 16) {
|
timer->nextDiv = GB_DMG_DIV_PERIOD * divsToGo;
|
||||||
divsToGo = 16;
|
mTimingSchedule(timing, &timer->event, timer->nextDiv - cyclesLate);
|
||||||
}
|
|
||||||
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) {
|
void GBTimerReset(struct GBTimer* timer) {
|
||||||
|
@ -96,11 +86,13 @@ uint8_t GBTimerUpdateTAC(struct GBTimer* timer, GBRegisterTAC tac) {
|
||||||
timer->timaPeriod = 256 >> 4;
|
timer->timaPeriod = 256 >> 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer->nextDiv -= mTimingUntil(&timer->p->timing, &timer->event);
|
||||||
|
mTimingDeschedule(&timer->p->timing, &timer->event);
|
||||||
|
mTimingSchedule(&timer->p->timing, &timer->event, 0);
|
||||||
} else {
|
} else {
|
||||||
timer->timaPeriod = 0;
|
timer->timaPeriod = 0;
|
||||||
}
|
}
|
||||||
mTimingDeschedule(&timer->p->timing, &timer->event);
|
|
||||||
_GBTimerUpdateDIV(timer, 0);
|
|
||||||
return tac;
|
return tac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue