all repos — mgba @ 6d3764d800a77c4587b0ce15d4e54bc9401a86fa

mGBA Game Boy Advance Emulator

DS Timers: Fix ARM9 timers running too fast
Vicki Pfau vi@endrift.com
Tue, 25 Apr 2017 16:14:08 -0700
commit

6d3764d800a77c4587b0ce15d4e54bc9401a86fa

parent

6265ff20bd8c9032eff146902a543148ac9c9167

4 files changed, 10 insertions(+), 4 deletions(-)

jump to
M CHANGESCHANGES

@@ -25,6 +25,7 @@ - DS: Fix exposed CPU frequencies and audio timing

- DS Audio: Fix audio sampling slightly too quickly - Feature: Fix resizing GIF buffer (fixes mgba.io/i/695) - DS GX: Retain translucent polygon ID when drawing opaque fragments (fixes mgba.io/i/661) + - DS Timers: Fix ARM9 timers running too fast Misc: - DS: Set boot complete bit in RAM on boot (fixes mgba.io/i/576, mgba.io/i/580, mgba.io/i/586) - DS Memory: Ensure DS9 I/O is 8-byte aligned
M include/mgba/internal/gba/timer.hinclude/mgba/internal/gba/timer.h

@@ -25,6 +25,7 @@ uint32_t lastEvent;

struct mTimingEvent event; int32_t overflowInterval; GBATimerFlags flags; + int forcedPrescale; }; struct ARMCore;
M src/ds/timer.csrc/ds/timer.c

@@ -71,18 +71,22 @@ ds->ds9.timers[0].event.name = "DS9 Timer 0";

ds->ds9.timers[0].event.callback = DSTimerUpdate0; ds->ds9.timers[0].event.context = &ds->ds9; ds->ds9.timers[0].event.priority = 0x20; + ds->ds9.timers[0].forcedPrescale = 1; ds->ds9.timers[1].event.name = "DS9 Timer 1"; ds->ds9.timers[1].event.callback = DSTimerUpdate1; ds->ds9.timers[1].event.context = &ds->ds9; ds->ds9.timers[1].event.priority = 0x21; + ds->ds9.timers[1].forcedPrescale = 1; ds->ds9.timers[2].event.name = "DS9 Timer 2"; ds->ds9.timers[2].event.callback = DSTimerUpdate2; ds->ds9.timers[2].event.context = &ds->ds9; ds->ds9.timers[2].event.priority = 0x22; + ds->ds9.timers[2].forcedPrescale = 1; ds->ds9.timers[3].event.name = "DS9 Timer 3"; ds->ds9.timers[3].event.callback = DSTimerUpdate3; ds->ds9.timers[3].event.context = &ds->ds9; ds->ds9.timers[3].event.priority = 0x23; + ds->ds9.timers[3].forcedPrescale = 1; } void DSTimerWriteTMCNT_HI(struct GBATimer* timer, struct mTiming* timing, struct ARMCore* cpu, uint16_t* io, uint16_t value) {
M src/gba/timer.csrc/gba/timer.c

@@ -128,16 +128,16 @@ void GBATimerWriteTMCNT_HI(struct GBATimer* timer, struct mTiming* timing, struct ARMCore* cpu, uint16_t* io, uint16_t control) {

unsigned oldPrescale = GBATimerFlagsGetPrescaleBits(timer->flags); switch (control & 0x0003) { case 0x0000: - timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 0); + timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, timer->forcedPrescale); break; case 0x0001: - timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 6); + timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 6 + timer->forcedPrescale); break; case 0x0002: - timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 8); + timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 8 + timer->forcedPrescale); break; case 0x0003: - timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 10); + timer->flags = GBATimerFlagsSetPrescaleBits(timer->flags, 10 + timer->forcedPrescale); break; } timer->flags = GBATimerFlagsTestFillCountUp(timer->flags, timer > 0 && (control & 0x0004));