src/ds/timer.c (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/ds/timer.h>
7
8#include <mgba/internal/arm/arm.h>
9#include <mgba/internal/ds/ds.h>
10
11static void DSTimerUpdate0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
12 struct DSCommon* dscore = context;
13 struct GBATimer* timer = &dscore->timers[0];
14 if (GBATimerFlagsIsDoIrq(timer->flags)) {
15 DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_TIMER0);
16 }
17 GBATimerUpdate(timing, &dscore->timers[0], &dscore->memory.io[DS_REG_TM0CNT_LO >> 1], cyclesLate);
18 GBATimerUpdateCountUp(timing, &dscore->timers[1], &dscore->memory.io[DS_REG_TM1CNT_LO >> 1], cyclesLate);
19}
20
21static void DSTimerUpdate1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
22 struct DSCommon* dscore = context;
23 struct GBATimer* timer = &dscore->timers[1];
24 if (GBATimerFlagsIsDoIrq(timer->flags)) {
25 DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_TIMER1);
26 }
27 GBATimerUpdate(timing, &dscore->timers[1], &dscore->memory.io[DS_REG_TM1CNT_LO >> 1], cyclesLate);
28 GBATimerUpdateCountUp(timing, &dscore->timers[2], &dscore->memory.io[DS_REG_TM2CNT_LO >> 1], cyclesLate);
29}
30
31static void DSTimerUpdate2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
32 struct DSCommon* dscore = context;
33 struct GBATimer* timer = &dscore->timers[2];
34 if (GBATimerFlagsIsDoIrq(timer->flags)) {
35 DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_TIMER2);
36 }
37 GBATimerUpdate(timing, &dscore->timers[2], &dscore->memory.io[DS_REG_TM2CNT_LO >> 1], cyclesLate);
38 GBATimerUpdateCountUp(timing, &dscore->timers[3], &dscore->memory.io[DS_REG_TM3CNT_LO >> 1], cyclesLate);
39}
40
41static void DSTimerUpdate3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
42 struct DSCommon* dscore = context;
43 struct GBATimer* timer = &dscore->timers[3];
44 if (GBATimerFlagsIsDoIrq(timer->flags)) {
45 DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_TIMER3);
46 }
47 GBATimerUpdate(timing, &dscore->timers[3], &dscore->memory.io[DS_REG_TM3CNT_LO >> 1], cyclesLate);
48}
49
50void DSTimerInit(struct DS* ds) {
51 memset(ds->ds7.timers, 0, sizeof(ds->ds7.timers));
52 ds->ds7.timers[0].event.name = "DS7 Timer 0";
53 ds->ds7.timers[0].event.callback = DSTimerUpdate0;
54 ds->ds7.timers[0].event.context = &ds->ds7;
55 ds->ds7.timers[0].event.priority = 0x20;
56 ds->ds7.timers[1].event.name = "DS7 Timer 1";
57 ds->ds7.timers[0].event.callback = DSTimerUpdate1;
58 ds->ds7.timers[0].event.context = &ds->ds7;
59 ds->ds7.timers[1].event.priority = 0x21;
60 ds->ds7.timers[2].event.name = "DS7 Timer 2";
61 ds->ds7.timers[0].event.callback = DSTimerUpdate2;
62 ds->ds7.timers[0].event.context = &ds->ds7;
63 ds->ds7.timers[2].event.priority = 0x22;
64 ds->ds7.timers[3].event.name = "DS7 Timer 3";
65 ds->ds7.timers[0].event.callback = DSTimerUpdate3;
66 ds->ds7.timers[0].event.context = &ds->ds7;
67 ds->ds7.timers[3].event.priority = 0x23;
68
69 memset(ds->ds9.timers, 0, sizeof(ds->ds9.timers));
70 ds->ds9.timers[0].event.name = "DS9 Timer 0";
71 ds->ds9.timers[0].event.callback = DSTimerUpdate0;
72 ds->ds9.timers[0].event.context = ds;
73 ds->ds9.timers[0].event.priority = 0x20;
74 ds->ds9.timers[1].event.name = "DS9 Timer 1";
75 ds->ds9.timers[1].event.callback = DSTimerUpdate1;
76 ds->ds9.timers[1].event.context = ds;
77 ds->ds9.timers[1].event.priority = 0x21;
78 ds->ds9.timers[2].event.name = "DS9 Timer 2";
79 ds->ds9.timers[2].event.callback = DSTimerUpdate2;
80 ds->ds9.timers[2].event.context = ds;
81 ds->ds9.timers[2].event.priority = 0x22;
82 ds->ds9.timers[3].event.name = "DS9 Timer 3";
83 ds->ds9.timers[3].event.callback = DSTimerUpdate3;
84 ds->ds9.timers[3].event.context = ds;
85 ds->ds9.timers[3].event.priority = 0x23;
86}
87
88void DSTimerWriteTMCNT_HI(struct GBATimer* timer, struct mTiming* timing, struct ARMCore* cpu, uint16_t* io, uint16_t value) {
89 GBATimerUpdateRegisterInternal(timer, timing, cpu, io, 0);
90 GBATimerWriteTMCNT_HI(timer, timing, cpu, io, value);
91}