all repos — mgba @ 7ea686a7d937de42533ca15989d3a48d6bf6d51d

mGBA Game Boy Advance Emulator

GB Timer: Fix TIMA/TMA timing
Vicki Pfau vi@endrift.com
Sat, 03 Feb 2018 23:12:57 -0800
commit

7ea686a7d937de42533ca15989d3a48d6bf6d51d

parent

a382c1ee9bb7bc79ce0445658eb2d4d771554766

5 files changed, 15 insertions(+), 7 deletions(-)

jump to
M CHANGESCHANGES

@@ -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)
M src/gb/io.csrc/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.csrc/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 {