GB Timer: Fix sub-M-cycle DIV reset timing and edge triggering
Vicki Pfau vi@endrift.com
Thu, 22 Jun 2017 01:20:22 -0700
2 files changed,
9 insertions(+),
1 deletions(-)
M
CHANGES
→
CHANGES
@@ -72,6 +72,7 @@ - GBA BIOS: Fix INT_MIN/-1 crash
- 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
M
src/gb/timer.c
→
src/gb/timer.c
@@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <mgba/internal/gb/timer.h> +#include <mgba/internal/lr35902/lr35902.h> #include <mgba/internal/gb/gb.h> #include <mgba/internal/gb/io.h> #include <mgba/internal/gb/serialize.h>@@ -63,11 +64,17 @@ timer->internalDiv = 0;
} 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) {