From 3a03d180d2f7c7081f42d2ada5582c17ad2032cd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 22 Jun 2017 01:20:22 -0700 Subject: [PATCH] GB Timer: Fix sub-M-cycle DIV reset timing and edge triggering --- CHANGES | 1 + src/gb/timer.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 360f7a5e0..0f6f062dd 100644 --- a/CHANGES +++ b/CHANGES @@ -72,6 +72,7 @@ Bugfixes: - GBA Savedata: Update and fix Sharkport importing (fixes mgba.io/i/658) - OpenGL: Fix some shaders causing offset graphics - Qt: Fix game unpausing after frame advancing and refocusing + - GB Timer: Fix sub-M-cycle DIV reset timing and edge triggering Misc: - SDL: Remove scancode key input - GBA Video: Clean up unused timers diff --git a/src/gb/timer.c b/src/gb/timer.c index 1533792eb..ba34d4bb7 100644 --- a/src/gb/timer.c +++ b/src/gb/timer.c @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include #include #include @@ -63,11 +64,17 @@ void GBTimerReset(struct GBTimer* timer) { } void GBTimerDivReset(struct GBTimer* timer) { + if (timer->internalDiv & (timer->timaPeriod >> 1)) { + ++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)); + } + } timer->p->memory.io[REG_DIV] = 0; timer->internalDiv = 0; timer->nextDiv = GB_DMG_DIV_PERIOD; mTimingDeschedule(&timer->p->timing, &timer->event); - mTimingSchedule(&timer->p->timing, &timer->event, timer->nextDiv); + mTimingSchedule(&timer->p->timing, &timer->event, timer->nextDiv - ((timer->p->cpu->executionState + 1) & 3)); } uint8_t GBTimerUpdateTAC(struct GBTimer* timer, GBRegisterTAC tac) {