all repos — mgba @ 616fa3956eb31055f052e2f5321d6c42250c9a04

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 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}