aboutsummaryrefslogtreecommitdiff
path: root/arm9/source/devices/clock.c
blob: c05ba2b62a0625ab1d0a5cc6881f75790c8affca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "clock.h"


/*
TODO: Add functions to set the system time and date.
*/


// ------ UPTIME AND DATETIME --------------------------------------------------

// Uptime is the number of 1/256th second ticks elapsed since the emulator began.
static u32 uptime;

// Increment the local uptime value.
void uptime_handler(void) { uptime++; }

// Configure timer 0 to increment the local uptime value every tick.
void init_nds_clock(void) {
    // Start a 256Hz timer to increment the uptime value.
    timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(256), uptime_handler);
}

// Return the current time and date.
struct tm* get_datetime(void) {
    time_t timestamp = time(NULL);
    struct tm* datetime = localtime(&timestamp);
    return datetime;
}


// ------ TIMERS ---------------------------------------------------------------

// Reset a clock timer.
void timer_reset(ClockTimer *timer) {
    timer->end = 0;
    timer->read = 0;
    timer->write = 0;
}

// Update the cached read value of a timer.
void timer_read(ClockTimer *timer) {
    if (timer->end > uptime) {
        timer->read = timer->end - uptime;
    } else {
        timer->read = 0;
        timer->end = 0;
    }
}

// Update the value of a timer using the cached write value.
void timer_write(ClockTimer *timer) {
    if (timer->write) {
        timer->end = uptime + timer->write;
    } else {
        timer->end = 0;
    }
}


// ------ CLOCK ----------------------------------------------------------------

// Reset the clock device.
void clock_reset(ClockDevice *clock) {
    clock->start = uptime;
    timer_reset(&clock->t1);
    timer_reset(&clock->t2);
    timer_reset(&clock->t3);
    timer_reset(&clock->t4);
}

// Update the cached uptime value.
void clock_uptime_read(ClockDevice *clock) {
    clock->uptime = uptime - clock->start;
}

// Return true if any timer has expired.
bool clock_check_timers(ClockDevice *clock) {
    bool output = false;
    if (clock->t1.end && clock->t1.end <= uptime) { clock->t1.end = 0; output = true; }
    if (clock->t2.end && clock->t2.end <= uptime) { clock->t2.end = 0; output = true; }
    if (clock->t3.end && clock->t3.end <= uptime) { clock->t3.end = 0; output = true; }
    if (clock->t4.end && clock->t4.end <= uptime) { clock->t4.end = 0; output = true; }
    return output;
}