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 (GBATimerFlagsIsDoIrq(timer->flags)) {
14 DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_TIMER0 + timerId);
15 }
16}
17
18static void DSTimerUpdate0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
19 struct DSCommon* dscore = context;
20 GBATimerUpdate(timing, &dscore->timers[0], &dscore->memory.io[DS_REG_TM0CNT_LO >> 1], cyclesLate);
21 DSTimerIrq(dscore, 0);
22 if (GBATimerUpdateCountUp(timing, &dscore->timers[1], &dscore->memory.io[DS_REG_TM1CNT_LO >> 1], cyclesLate)) {
23 DSTimerIrq(dscore, 1);
24 }
25}
26
27static void DSTimerUpdate1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
28 struct DSCommon* dscore = context;
29 GBATimerUpdate(timing, &dscore->timers[1], &dscore->memory.io[DS_REG_TM1CNT_LO >> 1], cyclesLate);
30 DSTimerIrq(dscore, 1);
31 if (GBATimerUpdateCountUp(timing, &dscore->timers[2], &dscore->memory.io[DS_REG_TM2CNT_LO >> 1], cyclesLate)) {
32 DSTimerIrq(dscore, 2);
33 }
34}
35
36static void DSTimerUpdate2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
37 struct DSCommon* dscore = context;
38 GBATimerUpdate(timing, &dscore->timers[2], &dscore->memory.io[DS_REG_TM2CNT_LO >> 1], cyclesLate);
39 DSTimerIrq(dscore, 2);
40 if (GBATimerUpdateCountUp(timing, &dscore->timers[3], &dscore->memory.io[DS_REG_TM3CNT_LO >> 1], cyclesLate)) {
41 DSTimerIrq(dscore, 3);
42 }
43}
44
45static void DSTimerUpdate3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
46 struct DSCommon* dscore = context;
47 GBATimerUpdate(timing, &dscore->timers[3], &dscore->memory.io[DS_REG_TM3CNT_LO >> 1], cyclesLate);
48 DSTimerIrq(dscore, 3);
49}
50
51void DSTimerInit(struct DS* ds) {
52 memset(ds->ds7.timers, 0, sizeof(ds->ds7.timers));
53 ds->ds7.timers[0].event.name = "DS7 Timer 0";
54 ds->ds7.timers[0].event.callback = DSTimerUpdate0;
55 ds->ds7.timers[0].event.context = &ds->ds7;
56 ds->ds7.timers[0].event.priority = 0x20;
57 ds->ds7.timers[1].event.name = "DS7 Timer 1";
58 ds->ds7.timers[1].event.callback = DSTimerUpdate1;
59 ds->ds7.timers[1].event.context = &ds->ds7;
60 ds->ds7.timers[1].event.priority = 0x21;
61 ds->ds7.timers[2].event.name = "DS7 Timer 2";
62 ds->ds7.timers[2].event.callback = DSTimerUpdate2;
63 ds->ds7.timers[2].event.context = &ds->ds7;
64 ds->ds7.timers[2].event.priority = 0x22;
65 ds->ds7.timers[3].event.name = "DS7 Timer 3";
66 ds->ds7.timers[3].event.callback = DSTimerUpdate3;
67 ds->ds7.timers[3].event.context = &ds->ds7;
68 ds->ds7.timers[3].event.priority = 0x23;
69
70 memset(ds->ds9.timers, 0, sizeof(ds->ds9.timers));
71 ds->ds9.timers[0].event.name = "DS9 Timer 0";
72 ds->ds9.timers[0].event.callback = DSTimerUpdate0;
73 ds->ds9.timers[0].event.context = &ds->ds9;
74 ds->ds9.timers[0].event.priority = 0x20;
75 ds->ds9.timers[0].forcedPrescale = 1;
76 ds->ds9.timers[1].event.name = "DS9 Timer 1";
77 ds->ds9.timers[1].event.callback = DSTimerUpdate1;
78 ds->ds9.timers[1].event.context = &ds->ds9;
79 ds->ds9.timers[1].event.priority = 0x21;
80 ds->ds9.timers[1].forcedPrescale = 1;
81 ds->ds9.timers[2].event.name = "DS9 Timer 2";
82 ds->ds9.timers[2].event.callback = DSTimerUpdate2;
83 ds->ds9.timers[2].event.context = &ds->ds9;
84 ds->ds9.timers[2].event.priority = 0x22;
85 ds->ds9.timers[2].forcedPrescale = 1;
86 ds->ds9.timers[3].event.name = "DS9 Timer 3";
87 ds->ds9.timers[3].event.callback = DSTimerUpdate3;
88 ds->ds9.timers[3].event.context = &ds->ds9;
89 ds->ds9.timers[3].event.priority = 0x23;
90 ds->ds9.timers[3].forcedPrescale = 1;
91}
92
93void DSTimerWriteTMCNT_HI(struct GBATimer* timer, struct mTiming* timing, uint16_t* io, uint16_t value) {
94 GBATimerWriteTMCNT_HI(timer, timing, io, value);
95}