all repos — mgba @ da50382cd42765d48451fdf1f2fa608d87813626

mGBA Game Boy Advance Emulator

GBA Timer: Improve accuracy of timers
Vicki Pfau vi@endrift.com
Sun, 02 Jul 2017 10:06:05 -0700
commit

da50382cd42765d48451fdf1f2fa608d87813626

parent

11354ac23ea6cbc41df04f2132e3b44d38c1494a

2 files changed, 11 insertions(+), 5 deletions(-)

jump to
M CHANGESCHANGES

@@ -75,6 +75,8 @@ - Qt: Fix game unpausing after frame advancing and refocusing

- GB Timer: Fix sub-M-cycle DIV reset timing and edge triggering - Core: Fix interrupting a thread while on the thread (fixes mgba.io/i/692) - Core: Fix directory sets crashing on close if base isn't properly detached + - Qt: Fix window icon being stretched + - Qt: Fix data directory path Misc: - SDL: Remove scancode key input - GBA Video: Clean up unused timers

@@ -145,6 +147,7 @@ - GB: Reset with initial state of DIV register

- GB MBC: New MBC7 implementation - Qt: Better highlight active key in control binding - Core: Improved threading interrupted detection + - GBA Timer: Improve accuracy of timers 0.6 beta 2: (Future) Bugfixes:

@@ -154,6 +157,7 @@ - Qt: Fix initial window size (fixes mgba.io/i/766)

- Qt: Fix data directory path Misc: - Qt: Add language selector + - GBA Timer: Improve accuracy of timers 0.6 beta 1: (2017-06-29) - Initial beta for 0.6
M src/gba/timer.csrc/gba/timer.c

@@ -103,20 +103,22 @@ struct GBATimer* currentTimer = &gba->timers[timer];

GBATimerUpdateRegister(gba, timer); unsigned oldPrescale = GBATimerFlagsGetPrescaleBits(currentTimer->flags); + unsigned prescaleBits; switch (control & 0x0003) { case 0x0000: - currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 0); + prescaleBits = 0; break; case 0x0001: - currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 6); + prescaleBits = 6; break; case 0x0002: - currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 8); + prescaleBits = 8; break; case 0x0003: - currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, 10); + prescaleBits = 10; break; } + currentTimer->flags = GBATimerFlagsSetPrescaleBits(currentTimer->flags, prescaleBits); currentTimer->flags = GBATimerFlagsTestFillCountUp(currentTimer->flags, timer > 0 && (control & 0x0004)); currentTimer->flags = GBATimerFlagsTestFillDoIrq(currentTimer->flags, control & 0x0040); currentTimer->overflowInterval = (0x10000 - currentTimer->reload) << GBATimerFlagsGetPrescaleBits(currentTimer->flags);

@@ -125,7 +127,7 @@ currentTimer->flags = GBATimerFlagsTestFillEnable(currentTimer->flags, control & 0x0080);

if (!wasEnabled && GBATimerFlagsIsEnable(currentTimer->flags)) { mTimingDeschedule(&gba->timing, &currentTimer->event); if (!GBATimerFlagsIsCountUp(currentTimer->flags)) { - mTimingSchedule(&gba->timing, &currentTimer->event, currentTimer->overflowInterval); + mTimingSchedule(&gba->timing, &currentTimer->event, currentTimer->overflowInterval + 7 - 6 * prescaleBits); } gba->memory.io[(REG_TM0CNT_LO + (timer << 2)) >> 1] = currentTimer->reload; currentTimer->oldReload = currentTimer->reload;