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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#include <dolphin/os.h>
#define OS_TIME_MONTH_MAX 12
#define OS_TIME_WEEK_DAY_MAX 7
#define OS_TIME_YEAR_DAY_MAX 365
static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152,
182, 213, 244, 274, 305, 335};
asm OSTime OSGetTime(void) {
nofralloc
mftbu r3
mftb r4
mftbu r5
cmpw r3, r5
bne OSGetTime
blr
}
asm OSTick OSGetTick(void){
nofralloc
mftb r3
blr
}
#define OS_SYSTEMTIME_BASE 0x30D8
OSTime __OSGetSystemTime(void) {
BOOL enabled;
OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE);
OSTime result;
enabled = OSDisableInterrupts();
result = *timeAdjustAddr + OSGetTime();
OSRestoreInterrupts(enabled);
return result;
}
OSTime __OSTimeToSystemTime(OSTime time) {
BOOL enabled;
OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE);
OSTime result;
enabled = OSDisableInterrupts();
result = *timeAdjustAddr + time;
OSRestoreInterrupts(enabled);
return result;
}
static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }
static s32 GetYearDays(s32 year, s32 mon) {
return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon];
}
static s32 GetLeapDays(s32 year) {
if (year < 1) {
return 0;
}
return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400;
}
static void GetDates(s32 days, OSCalendarTime* cal) {
s32 year;
s32 totalDays;
s32* p_days;
s32 month;
cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX;
for (year = days / OS_TIME_YEAR_DAY_MAX;
days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) {
year--;
}
days -= totalDays;
cal->year = year;
cal->yday = days;
p_days = IsLeapYear(year) ? LeapYearDays : YearDays;
month = OS_TIME_MONTH_MAX;
while (days < p_days[--month]) {
;
}
cal->mon = month;
cal->mday = days - p_days[month] + 1;
}
#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400)
#pragma push
#pragma dont_inline on
void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) {
int days;
int secs;
OSTime d;
d = ticks % OSSecondsToTicks(1);
if (d < 0) {
d += OSSecondsToTicks(1);
}
td->usec = (int)(OSTicksToMicroseconds(d) % 1000);
td->msec = (int)(OSTicksToMilliseconds(d) % 1000);
ticks -= d;
days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS);
secs = (int)(OSTicksToSeconds(ticks) % 86400);
if (secs < 0) {
days -= 1;
secs += 24 * 60 * 60;
}
GetDates(days, td);
td->hour = secs / 60 / 60;
td->min = (secs / 60) % 60;
td->sec = secs % 60;
}
#pragma dont_inline reset
OSTime OSCalendarTimeToTicks(OSCalendarTime* time) {
;
;
}
|