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 DSTimerIrq(struct DSCommon* dscore, int timerId) {
12 struct GBATimer* timer = &dscore->timers[timerId];
13 if (GBATimerFlagsIsIrqPending(timer->flags)) {
14 timer->flags = GBATimerFlagsClearIrqPending(timer->flags);
15 DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_TIMER0 + timerId);
16 }
17}
18
19static void DSTimerIrq0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
20 UNUSED(timing);
21 UNUSED(cyclesLate);
22 DSTimerIrq(context, 0);
23}
24
25static void DSTimerIrq1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
26 UNUSED(timing);
27 UNUSED(cyclesLate);
28 DSTimerIrq(context, 1);
29}
30
31static void DSTimerIrq2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
32 UNUSED(timing);
33 UNUSED(cyclesLate);
34 DSTimerIrq(context, 2);
35}
36
37static void DSTimerIrq3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
38 UNUSED(timing);
39 UNUSED(cyclesLate);
40 DSTimerIrq(context, 3);
41}
42
43static void DSTimerUpdate0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
44 struct DSCommon* dscore = context;
45 GBATimerUpdate(timing, &dscore->timers[0], &dscore->memory.io[DS_REG_TM0CNT_LO >> 1], cyclesLate);
46 GBATimerUpdateCountUp(timing, &dscore->timers[1], &dscore->memory.io[DS_REG_TM1CNT_LO >> 1], cyclesLate);
47}
48
49static void DSTimerUpdate1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
50 struct DSCommon* dscore = context;
51 GBATimerUpdate(timing, &dscore->timers[1], &dscore->memory.io[DS_REG_TM1CNT_LO >> 1], cyclesLate);
52 GBATimerUpdateCountUp(timing, &dscore->timers[2], &dscore->memory.io[DS_REG_TM2CNT_LO >> 1], cyclesLate);
53}
54
55static void DSTimerUpdate2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
56 struct DSCommon* dscore = context;
57 GBATimerUpdate(timing, &dscore->timers[2], &dscore->memory.io[DS_REG_TM2CNT_LO >> 1], cyclesLate);
58 GBATimerUpdateCountUp(timing, &dscore->timers[3], &dscore->memory.io[DS_REG_TM3CNT_LO >> 1], cyclesLate);
59}
60
61static void DSTimerUpdate3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
62 struct DSCommon* dscore = context;
63 GBATimerUpdate(timing, &dscore->timers[3], &dscore->memory.io[DS_REG_TM3CNT_LO >> 1], cyclesLate);
64}
65
66void DSTimerInit(struct DS* ds) {
67 memset(ds->ds7.timers, 0, sizeof(ds->ds7.timers));
68 ds->ds7.timers[0].event.name = "DS7 Timer 0";
69 ds->ds7.timers[0].event.callback = DSTimerUpdate0;
70 ds->ds7.timers[0].event.context = &ds->ds7;
71 ds->ds7.timers[0].event.priority = 0x20;
72 ds->ds7.timers[1].event.name = "DS7 Timer 1";
73 ds->ds7.timers[1].event.callback = DSTimerUpdate1;
74 ds->ds7.timers[1].event.context = &ds->ds7;
75 ds->ds7.timers[1].event.priority = 0x21;
76 ds->ds7.timers[2].event.name = "DS7 Timer 2";
77 ds->ds7.timers[2].event.callback = DSTimerUpdate2;
78 ds->ds7.timers[2].event.context = &ds->ds7;
79 ds->ds7.timers[2].event.priority = 0x22;
80 ds->ds7.timers[3].event.name = "DS7 Timer 3";
81 ds->ds7.timers[3].event.callback = DSTimerUpdate3;
82 ds->ds7.timers[3].event.context = &ds->ds7;
83 ds->ds7.timers[3].event.priority = 0x23;
84 ds->ds7.timers[0].irq.name = "DS7 Timer 0 IRQ";
85 ds->ds7.timers[0].irq.callback = DSTimerIrq0;
86 ds->ds7.timers[0].irq.context = &ds->ds7;
87 ds->ds7.timers[0].irq.priority = 0x28;
88 ds->ds7.timers[1].irq.name = "DS7 Timer 1 IRQ";
89 ds->ds7.timers[1].irq.callback = DSTimerIrq1;
90 ds->ds7.timers[1].irq.context = &ds->ds7;
91 ds->ds7.timers[1].irq.priority = 0x29;
92 ds->ds7.timers[2].irq.name = "DS7 Timer 2 IRQ";
93 ds->ds7.timers[2].irq.callback = DSTimerIrq2;
94 ds->ds7.timers[2].irq.context = &ds->ds7;
95 ds->ds7.timers[2].irq.priority = 0x2A;
96 ds->ds7.timers[3].irq.name = "DS7 Timer 3 IRQ";
97 ds->ds7.timers[3].irq.callback = DSTimerIrq3;
98 ds->ds7.timers[3].irq.context = &ds->ds7;
99 ds->ds7.timers[3].irq.priority = 0x2B;
100
101 memset(ds->ds9.timers, 0, sizeof(ds->ds9.timers));
102 ds->ds9.timers[0].event.name = "DS9 Timer 0";
103 ds->ds9.timers[0].event.callback = DSTimerUpdate0;
104 ds->ds9.timers[0].event.context = &ds->ds9;
105 ds->ds9.timers[0].event.priority = 0x20;
106 ds->ds9.timers[0].forcedPrescale = 1;
107 ds->ds9.timers[1].event.name = "DS9 Timer 1";
108 ds->ds9.timers[1].event.callback = DSTimerUpdate1;
109 ds->ds9.timers[1].event.context = &ds->ds9;
110 ds->ds9.timers[1].event.priority = 0x21;
111 ds->ds9.timers[1].forcedPrescale = 1;
112 ds->ds9.timers[2].event.name = "DS9 Timer 2";
113 ds->ds9.timers[2].event.callback = DSTimerUpdate2;
114 ds->ds9.timers[2].event.context = &ds->ds9;
115 ds->ds9.timers[2].event.priority = 0x22;
116 ds->ds9.timers[2].forcedPrescale = 1;
117 ds->ds9.timers[3].event.name = "DS9 Timer 3";
118 ds->ds9.timers[3].event.callback = DSTimerUpdate3;
119 ds->ds9.timers[3].event.context = &ds->ds9;
120 ds->ds9.timers[3].event.priority = 0x23;
121 ds->ds9.timers[3].forcedPrescale = 1;
122 ds->ds9.timers[0].irq.name = "DS9 Timer 0 IRQ";
123 ds->ds9.timers[0].irq.callback = DSTimerIrq0;
124 ds->ds9.timers[0].irq.context = &ds->ds9;
125 ds->ds9.timers[0].irq.priority = 0x28;
126 ds->ds9.timers[1].irq.name = "DS9 Timer 1 IRQ";
127 ds->ds9.timers[1].irq.callback = DSTimerIrq1;
128 ds->ds9.timers[1].irq.context = &ds->ds9;
129 ds->ds9.timers[1].irq.priority = 0x29;
130 ds->ds9.timers[2].irq.name = "DS9 Timer 2 IRQ";
131 ds->ds9.timers[2].irq.callback = DSTimerIrq2;
132 ds->ds9.timers[2].irq.context = &ds->ds9;
133 ds->ds9.timers[2].irq.priority = 0x2A;
134 ds->ds9.timers[3].irq.name = "DS9 Timer 3 IRQ";
135 ds->ds9.timers[3].irq.callback = DSTimerIrq3;
136 ds->ds9.timers[3].irq.context = &ds->ds9;
137 ds->ds9.timers[3].irq.priority = 0x2B;
138}
139
140void DSTimerWriteTMCNT_HI(struct GBATimer* timer, struct mTiming* timing, uint16_t* io, uint16_t value) {
141 GBATimerWriteTMCNT_HI(timer, timing, io, value);
142}