GB Timer: Fix TIMA/TMA timing
Vicki Pfau vi@endrift.com
Sat, 03 Feb 2018 23:12:57 -0800
5 files changed,
15 insertions(+),
7 deletions(-)
M
CHANGES
→
CHANGES
@@ -48,6 +48,7 @@ - PSP2: Fix issues causing poor audio
- Wii: Fix screen tear when unpausing - GBA: Fix some GBA ROM misdetection (fixes mgba.io/i/978) - GBA Hardware: RTC accuracy improvements + - GB Timer: Minor accuracy improvements Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)
D
cinema/gb/mooneye-gb/acceptance/timer/tima_write_reloading/manifest.yml
@@ -1,1 +0,0 @@
-fail: true
M
src/gb/io.c
→
src/gb/io.c
@@ -380,8 +380,17 @@ _writeSGBBits(gb, (value >> 4) & 3);
} break; case REG_TIMA: + if (value && mTimingUntil(&gb->timing, &gb->timer.irq) > 1) { + mTimingDeschedule(&gb->timing, &gb->timer.irq); + } + if (mTimingUntil(&gb->timing, &gb->timer.irq) == -1) { + return; + } + break; case REG_TMA: - // Handled transparently by the registers + if (mTimingUntil(&gb->timing, &gb->timer.irq) == -1) { + gb->memory.io[REG_TIMA] = value; + } break; case REG_TAC: value = GBTimerUpdateTAC(&gb->timer, value);
M
src/gb/timer.c
→
src/gb/timer.c
@@ -27,7 +27,7 @@ // Make sure to trigger when the correct bit is a falling edge
if (timer->timaPeriod > 0 && (timer->internalDiv & (timer->timaPeriod - 1)) == timer->timaPeriod - 1) { ++timer->p->memory.io[REG_TIMA]; if (!timer->p->memory.io[REG_TIMA]) { - mTimingSchedule(&timer->p->timing, &timer->irq, 4 - cyclesLate); + mTimingSchedule(&timer->p->timing, &timer->irq, 7 - ((timer->p->cpu->executionState - cyclesLate) & 3)); } } ++timer->internalDiv;@@ -69,11 +69,11 @@
void GBTimerDivReset(struct GBTimer* timer) { timer->nextDiv -= mTimingUntil(&timer->p->timing, &timer->event); mTimingDeschedule(&timer->p->timing, &timer->event); - _GBTimerDivIncrement(timer, (timer->p->cpu->executionState + 1) & 3); + _GBTimerDivIncrement(timer, 0); if (((timer->internalDiv << 1) | ((timer->nextDiv >> 3) & 1)) & timer->timaPeriod) { ++timer->p->memory.io[REG_TIMA]; if (!timer->p->memory.io[REG_TIMA]) { - mTimingSchedule(&timer->p->timing, &timer->irq, 4 - ((timer->p->cpu->executionState + 1) & 3)); + mTimingSchedule(&timer->p->timing, &timer->irq, 7 - (timer->p->cpu->executionState & 3)); } } timer->p->memory.io[REG_DIV] = 0;@@ -101,7 +101,7 @@ }
timer->nextDiv -= mTimingUntil(&timer->p->timing, &timer->event); mTimingDeschedule(&timer->p->timing, &timer->event); - _GBTimerDivIncrement(timer, (timer->p->cpu->executionState + 1) & 3); + _GBTimerDivIncrement(timer, (timer->p->cpu->executionState + 2) & 3); timer->nextDiv += GB_DMG_DIV_PERIOD; mTimingSchedule(&timer->p->timing, &timer->event, timer->nextDiv); } else {