all repos — mgba @ d620a8c38c9f49fb4b40a26c0954f0cff2147ab5

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