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 DS7TimerUpdate0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
12 struct DS* ds = context;
13 struct GBATimer* timer = &ds->timers7[0];
14 if (GBATimerFlagsIsDoIrq(timer->flags)) {
15 DSRaiseIRQ(ds->arm7, ds->memory.io7, DS_IRQ_TIMER0);
16 }
17 GBATimerUpdate(timing, &ds->timers7[0], &ds->memory.io7[DS7_REG_TM0CNT_LO >> 1], cyclesLate);
18 GBATimerUpdateCountUp(timing, &ds->timers7[1], &ds->memory.io7[DS7_REG_TM1CNT_LO >> 1], cyclesLate);
19}
20
21static void DS7TimerUpdate1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
22 struct DS* ds = context;
23 struct GBATimer* timer = &ds->timers7[1];
24 if (GBATimerFlagsIsDoIrq(timer->flags)) {
25 DSRaiseIRQ(ds->arm7, ds->memory.io7, DS_IRQ_TIMER1);
26 }
27 GBATimerUpdate(timing, &ds->timers7[1], &ds->memory.io7[DS7_REG_TM1CNT_LO >> 1], cyclesLate);
28 GBATimerUpdateCountUp(timing, &ds->timers7[2], &ds->memory.io7[DS7_REG_TM2CNT_LO >> 1], cyclesLate);
29}
30
31static void DS7TimerUpdate2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
32 struct DS* ds = context;
33 struct GBATimer* timer = &ds->timers7[2];
34 if (GBATimerFlagsIsDoIrq(timer->flags)) {
35 DSRaiseIRQ(ds->arm7, ds->memory.io7, DS_IRQ_TIMER2);
36 }
37 GBATimerUpdate(timing, &ds->timers7[2], &ds->memory.io7[DS7_REG_TM2CNT_LO >> 1], cyclesLate);
38 GBATimerUpdateCountUp(timing, &ds->timers7[3], &ds->memory.io7[DS7_REG_TM3CNT_LO >> 1], cyclesLate);
39}
40
41static void DS7TimerUpdate3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
42 struct DS* ds = context;
43 struct GBATimer* timer = &ds->timers7[3];
44 if (GBATimerFlagsIsDoIrq(timer->flags)) {
45 DSRaiseIRQ(ds->arm7, ds->memory.io7, DS_IRQ_TIMER3);
46 }
47 GBATimerUpdate(timing, &ds->timers7[3], &ds->memory.io7[DS7_REG_TM3CNT_LO >> 1], cyclesLate);
48}
49
50void DSTimerInit(struct DS* ds) {
51 memset(ds->timers7, 0, sizeof(ds->timers7));
52 ds->timers7[0].event.name = "DS7 Timer 0";
53 ds->timers7[0].event.callback = DS7TimerUpdate0;
54 ds->timers7[0].event.context = ds;
55 ds->timers7[0].event.priority = 0x20;
56 ds->timers7[1].event.name = "DS7 Timer 1";
57 ds->timers7[1].event.callback = DS7TimerUpdate1;
58 ds->timers7[1].event.context = ds;
59 ds->timers7[1].event.priority = 0x21;
60 ds->timers7[2].event.name = "DS7 Timer 2";
61 ds->timers7[2].event.callback = DS7TimerUpdate2;
62 ds->timers7[2].event.context = ds;
63 ds->timers7[2].event.priority = 0x22;
64 ds->timers7[3].event.name = "DS7 Timer 3";
65 ds->timers7[3].event.callback = DS7TimerUpdate3;
66 ds->timers7[3].event.context = ds;
67 ds->timers7[3].event.priority = 0x23;
68
69 memset(ds->timers9, 0, sizeof(ds->timers9));
70 ds->timers9[0].event.name = "DS9 Timer 0";
71 ds->timers9[0].event.callback = NULL;
72 ds->timers9[0].event.context = ds;
73 ds->timers9[0].event.priority = 0x20;
74 ds->timers9[1].event.name = "DS9 Timer 1";
75 ds->timers9[1].event.callback = NULL;
76 ds->timers9[1].event.context = ds;
77 ds->timers9[1].event.priority = 0x21;
78 ds->timers9[2].event.name = "DS9 Timer 2";
79 ds->timers9[2].event.callback = NULL;
80 ds->timers9[2].event.context = ds;
81 ds->timers9[2].event.priority = 0x22;
82 ds->timers9[3].event.name = "DS9 Timer 3";
83 ds->timers9[3].event.callback = NULL;
84 ds->timers9[3].event.context = ds;
85 ds->timers9[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}