all repos — mgba @ 4fd170ac38a9c312f3dd1d0dd912d2c761f60fdb

mGBA Game Boy Advance Emulator

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}