diff options
-rw-r--r-- | arm9/asm/DGT_hash2.s | 2 | ||||
-rw-r--r-- | arm9/asm/RTC_convert.s | 344 | ||||
-rw-r--r-- | arm9/lib/include/RTC_convert.h | 9 | ||||
-rw-r--r-- | arm9/lib/src/RTC_convert.c | 164 |
4 files changed, 172 insertions, 347 deletions
diff --git a/arm9/asm/DGT_hash2.s b/arm9/asm/DGT_hash2.s index 1c89ebf9..f309204e 100644 --- a/arm9/asm/DGT_hash2.s +++ b/arm9/asm/DGT_hash2.s @@ -10,7 +10,7 @@ Unk_02106A00: ; 0x02106A00 .global Unk_02106A04 Unk_02106A04: ; 0x02106A04 .byte 0x14, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 .text diff --git a/arm9/asm/RTC_convert.s b/arm9/asm/RTC_convert.s deleted file mode 100644 index 37e8cd0e..00000000 --- a/arm9/asm/RTC_convert.s +++ /dev/null @@ -1,344 +0,0 @@ - .include "asm/macros.inc" - .include "global.inc" - - .extern UNK_02106A1C - .extern UNK_02106A20 - - .section .data - - .global UNK_02106A1C -UNK_02106A1C: ; 0x02106A1C - .word 0 - - .global UNK_02106A20 -UNK_02106A20: ; 0x02106A20 - .word 0 ; Jan - .word 31 ; Feb - .word 59 ; Mar - .word 90 ; Apr - .word 120 ; May - .word 151 ; Jun - .word 181 ; Jul - .word 212 ; Aug - .word 243 ; Sep - .word 273 ; Oct - .word 304 ; Nov - .word 334 ; Dec - - .text - - arm_func_start RTC_GetDayOfWeek -RTC_GetDayOfWeek: ; 0x020D6248 - stmdb sp!, {r4-r6,lr} - ldr r1, [r0, #0x4] - ldr r2, [r0, #0x0] - sub r3, r1, #0x2 - cmp r3, #0x1 - add lr, r2, #0x7d0 - ldr r4, _020D630C ; =0x51EB851F - sublt lr, lr, #0x1 - ldr r12, [r0, #0x8] - smull r0, r2, r4, lr - addlt r3, r3, #0xc - mov r1, #0x1a - mul r0, r3, r1 - smull r1, r3, r4, lr - ldr r5, _020D6310 ; =0x66666667 - sub r0, r0, #0x2 - smull r4, r1, r5, r0 - mov r4, lr, lsr #0x1f - mov r2, r2, asr #0x5 - mov r3, r3, asr #0x5 - add r3, r4, r3 - ldr r5, _020D6314 ; =0x00000064 - add r2, r4, r2 - smull r2, r4, r5, r2 - sub r2, lr, r2 - mov r1, r1, asr #0x2 - mov r0, r0, lsr #0x1f - add r1, r0, r1 - mov r4, r2, asr #0x1 - add r0, r12, r1 - add r1, r2, r4, lsr #0x1e - add r2, r2, r0 - mov r6, r3, asr #0x1 - add r0, r3, r6, lsr #0x1e - add r1, r2, r1, asr #0x2 - add r1, r1, r0, asr #0x2 - mov r0, #0x5 - mla r4, r3, r0, r1 - ldr r3, _020D6318 ; =0x92492493 - mov r1, r4, lsr #0x1f - smull r2, r0, r3, r4 - add r0, r4, r0 - mov r0, r0, asr #0x2 - ldr r2, _020D631C ; =0x00000007 - add r0, r1, r0 - smull r0, r1, r2, r0 - sub r0, r4, r0 - ldmia sp!, {r4-r6,lr} - bx lr - .balign 4 -_020D630C: .word 0x51EB851F -_020D6310: .word 0x66666667 -_020D6314: .word 0x00000064 -_020D6318: .word 0x92492493 -_020D631C: .word 0x00000007 - - arm_func_start RTC_ConvertSecondToDateTime -RTC_ConvertSecondToDateTime: ; 0x020D6320 - stmdb sp!, {r4-r7,lr} - sub sp, sp, #0x4 - mov r5, r2 - mov r12, #0x0 - mov r4, r3 - subs r2, r5, r12 - sbcs r2, r4, r12 - mov r7, r0 - mov r6, r1 - movlt r5, r12 - movlt r4, r12 - blt _020D6364 - ldr r1, _020D63B0 ; =0xBC19137F - subs r0, r1, r5 - sbcs r0, r12, r4 - movlt r5, r1 - movlt r4, r12 -_020D6364: - ldr r2, _020D63B4 ; =0x00015180 - mov r0, r5 - mov r1, r4 - mov r3, #0x0 - bl _ll_mod - mov r1, r0 - mov r0, r6 - bl RTCi_ConvertSecondToTime - ldr r2, _020D63B4 ; =0x00015180 - mov r0, r5 - mov r1, r4 - mov r3, #0x0 - bl _ll_sdiv - mov r1, r0 - mov r0, r7 - bl RTC_ConvertDayToDate - add sp, sp, #0x4 - ldmia sp!, {r4-r7,lr} - bx lr - .balign 4 -_020D63B0: .word 0xBC19137F -_020D63B4: .word 0x00015180 - - arm_func_start RTCi_ConvertSecondToTime -RTCi_ConvertSecondToTime: ; 0x020D63B8 - stmdb sp!, {r4-r6,lr} - ldr r2, _020D6448 ; =0x0001517F - cmp r1, #0x0 - movlt r1, #0x0 - cmp r1, r2 - ldr ip, _020D644C ; =0x88888889 - movgt r1, r2 - smull r2, r3, r12, r1 - smull r2, lr, r12, r1 - ldr r5, _020D6450 ; =0x91A2B3C5 - add r3, r1, r3 - smull r4, r2, r5, r1 - mov r5, r1, lsr #0x1f - mov r3, r3, asr #0x5 - add r3, r5, r3 - smull r4, r6, r12, r3 - add lr, r1, lr - mov lr, lr, asr #0x5 - add r6, r3, r6 - add r2, r1, r2 - ldr r4, _020D6454 ; =0x0000003C - add lr, r5, lr - smull r12, lr, r4, lr - sub lr, r1, r12 - mov r2, r2, asr #0xb - mov r6, r6, asr #0x5 - mov r1, r3, lsr #0x1f - add r6, r1, r6 - smull r1, r12, r4, r6 - str lr, [r0, #0x8] - sub r6, r3, r1 - str r6, [r0, #0x4] - add r2, r5, r2 - str r2, [r0, #0x0] - ldmia sp!, {r4-r6,lr} - bx lr - .balign 4 -_020D6448: .word 0x0001517F -_020D644C: .word 0x88888889 -_020D6450: .word 0x91A2B3C5 -_020D6454: .word 0x0000003C - - arm_func_start RTC_ConvertDayToDate -RTC_ConvertDayToDate: ; 0x020D6458 - stmdb sp!, {r4,lr} - ldr r2, _020D6560 ; =0x00008EAC - cmp r1, #0x0 - movlt r1, #0x0 - cmp r1, r2 - movgt r1, r2 - ldr r3, _020D6564 ; =0x92492493 - add lr, r1, #0x6 - smull r2, r4, r3, lr - add r4, lr, r4 - mov r4, r4, asr #0x2 - mov r2, lr, lsr #0x1f - ldr ip, _020D6568 ; =0x00000007 - add r4, r2, r4 - smull r2, r3, r12, r4 - sub r4, lr, r2 - ldr r2, _020D656C ; =0x0000016D - ldr r3, _020D6570 ; =0x0000016E - str r4, [r0, #0xc] - mov lr, #0x0 -_020D64A8: - ands r12, lr, #0x3 - moveq r12, r3 - movne r12, r2 - mov r4, r1 - subs r1, r1, r12 - movmi r1, r4 - bmi _020D64D0 - add lr, lr, #0x1 - cmp lr, #0x63 - blo _020D64A8 -_020D64D0: - ldr r2, _020D656C ; =0x0000016D - str lr, [r0, #0x0] - cmp r1, r2 - movgt r1, r2 - ands r2, lr, #0x3 - bne _020D6518 - cmp r1, #0x3c - bge _020D6514 - cmp r1, #0x1f - movlt r2, #0x1 - subge r1, r1, #0x1f - movge r2, #0x2 - str r2, [r0, #0x4] - add r1, r1, #0x1 - str r1, [r0, #0x8] - ldmia sp!, {r4,lr} - bx lr -_020D6514: - sub r1, r1, #0x1 -_020D6518: - ldr r3, _020D6574 ; =UNK_02106A20 - mov r4, #0xb -_020D6520: - ldr r2, [r3, r4, lsl #0x2] - mov r12, r4, lsl #0x2 - cmp r1, r2 - blt _020D6550 - add r2, r4, #0x1 - str r2, [r0, #0x4] - ldr r2, [r3, r12] - sub r1, r1, r2 - add r1, r1, #0x1 - str r1, [r0, #0x8] - ldmia sp!, {r4,lr} - bx lr -_020D6550: - subs r4, r4, #0x1 - bpl _020D6520 - ldmia sp!, {r4,lr} - bx lr - .balign 4 -_020D6560: .word 0x00008EAC -_020D6564: .word 0x92492493 -_020D6568: .word 0x00000007 -_020D656C: .word 0x0000016D -_020D6570: .word 0x0000016E -_020D6574: .word UNK_02106A20 - - arm_func_start RTC_ConvertDateTimeToSecond -RTC_ConvertDateTimeToSecond: ; 0x020D6578 - stmdb sp!, {r4-r5,lr} - sub sp, sp, #0x4 - mov r5, r1 - bl RTC_ConvertDateToDay - mov r4, r0 - mvn r0, #0x0 - cmp r4, r0 - addeq sp, sp, #0x4 - moveq r1, r0 - ldmeqia sp!, {r4-r5,lr} - bxeq lr - mov r0, r5 - bl RTCi_ConvertTimeToSecond - mvn r2, #0x0 - cmp r0, r2 - moveq r1, r2 - beq _020D65DC - ldr r1, _020D65EC ; =0x00015180 - mov r2, #0x0 - umull r12, r3, r4, r1 - mla r3, r4, r2, r3 - mov r2, r4, asr #0x1f - mla r3, r2, r1, r3 - adds r2, r0, r12 - adc r1, r3, r0, asr #0x1f -_020D65DC: - mov r0, r2 - add sp, sp, #0x4 - ldmia sp!, {r4-r5,lr} - bx lr - .balign 4 -_020D65EC: .word 0x00015180 - - arm_func_start RTCi_ConvertTimeToSecond -RTCi_ConvertTimeToSecond: ; 0x020D65F0 - ldr r3, [r0, #0x4] - ldr r2, [r0, #0x0] - mov r1, #0x3c - mla r3, r2, r1, r3 - ldr r0, [r0, #0x8] - mla r0, r3, r1, r0 - bx lr - - arm_func_start RTC_ConvertDateToDay -RTC_ConvertDateToDay: ; 0x020D660C - ldr r3, [r0, #0x0] - cmp r3, #0x64 - bhs _020D665C - ldr r2, [r0, #0x4] - cmp r2, #0x1 - blo _020D665C - cmp r2, #0xc - bhi _020D665C - ldr r1, [r0, #0x8] - cmp r1, #0x1 - blo _020D665C - cmp r1, #0x1f - bhi _020D665C - ldr r0, [r0, #0xc] - cmp r0, #0x7 - bge _020D665C - cmp r2, #0x1 - blo _020D665C - cmp r2, #0xc - bls _020D6664 -_020D665C: - mvn r0, #0x0 - bx lr -_020D6664: - ldr r0, _020D6698 ; =UNK_02106A1C - sub r1, r1, #0x1 - ldr r0, [r0, r2, lsl #0x2] - cmp r2, #0x3 - add r2, r1, r0 - blo _020D6684 - ands r0, r3, #0x3 - addeq r2, r2, #0x1 -_020D6684: - ldr r0, _020D669C ; =0x0000016D - add r1, r3, #0x3 - mla r0, r3, r0, r2 - add r0, r0, r1, lsr #0x2 - bx lr - .balign 4 -_020D6698: .word UNK_02106A1C -_020D669C: .word 0x0000016D diff --git a/arm9/lib/include/RTC_convert.h b/arm9/lib/include/RTC_convert.h index 255ebf73..a75928b9 100644 --- a/arm9/lib/include/RTC_convert.h +++ b/arm9/lib/include/RTC_convert.h @@ -1,7 +1,12 @@ #ifndef NITRO_RTC_CONVERT_H_ #define NITRO_RTC_CONVERT_H_ -s32 RTC_ConvertDateToDay(RTCDate *); -s64 RTC_ConvertDateTimeToSecond(RTCDate *, RTCTime *); +s32 RTC_ConvertDateToDay(const RTCDate * date); +s32 RTCi_ConvertTimeToSecond(const RTCTime * time); +s64 RTC_ConvertDateTimeToSecond(const RTCDate * date, const RTCTime * time); +void RTC_ConvertDayToDate(RTCDate * date, s32 day); +void RTCi_ConvertSecondToTime(RTCTime * time, s32 sec); +void RTC_ConvertSecondToDateTime(RTCDate * date, RTCTime * time, s64 sec); +RTCWeek RTC_GetDayOfWeek(RTCDate * date); #endif //NITRO_RTC_CONVERT_H_ diff --git a/arm9/lib/src/RTC_convert.c b/arm9/lib/src/RTC_convert.c new file mode 100644 index 00000000..af5574dc --- /dev/null +++ b/arm9/lib/src/RTC_convert.c @@ -0,0 +1,164 @@ +#include "global.h" +#include "RTC_api.h" +#include "RTC_convert.h" + +static s32 sDayOfYear[12] = { + 0, // Jan + 31, // Feb + 59, // Mar + 90, // Apr + 120, // May + 151, // Jun + 181, // Jul + 212, // Aug + 243, // Sep + 273, // Oct + 304, // Nov + 334, // Dec +}; + +static inline BOOL RTCi_IsLeapYear(u32 year) +{ + return !((year & 0x03)); +} + +s32 RTC_ConvertDateToDay(const RTCDate * date) +{ + if (date->year >= 100 + || date->month < 1 + || date->month > 12 + || date->day < 1 + || date->day > 31 + || date->week >= RTC_WEEK_MAX + || date->month < 1 // can't be + || date->month > 12 // too sure + ) + return -1; + s32 dayNum = (s32)(date->day - 1); + dayNum += sDayOfYear[date->month - 1]; + if (date->month >= 3 && RTCi_IsLeapYear(date->year)) + dayNum++; + dayNum += date->year * 365; + dayNum += (date->year + 3) / 4; + return dayNum; +} + +s32 RTCi_ConvertTimeToSecond(const RTCTime * time) +{ + return (time->hour * 60 + time->minute) * 60 + time->second; +} + +s64 RTC_ConvertDateTimeToSecond(const RTCDate * date, const RTCTime * time) +{ + s32 day = RTC_ConvertDateToDay(date); + if (day == -1) + return -1; + s32 second = RTCi_ConvertTimeToSecond(time); + if (second == -1) + return -1; + return ((s64)day) * (60 * 60 * 24) + second; +} + +void RTC_ConvertDayToDate(RTCDate * date, s32 day) +{ + u32 year; + s32 month; + + if (day < 0) + { + day = 0; + } + if (day > 36524) // max number of days that can be recorded + { + day = 36524; + } + date->week = (RTCWeek)((day + 6) % 7); + for (year = 0; year < 99; year++) + { + s32 prev = day; + day -= (RTCi_IsLeapYear(year)) ? 366 : 365; + if (day < 0) + { + day = prev; + break; + } + } + if (day > 365) + { + day = 365; + } + date->year = year; + if (RTCi_IsLeapYear(year)) + { + if (day < 31 + 29) + { + if (day < 31) + { + month = 1; + } + else + { + month = 2; + day -= 31; + } + date->month = (u32)month; + date->day = (u32)(day + 1); + return; + } + else + { + day--; + } + } + for (month = 11; month >= 0; month--) + { + if (day >= sDayOfYear[month]) + { + date->month = (u32)(month + 1); + date->day = (u32)(day - sDayOfYear[month] + 1); + return; + } + } + // Internal Error. +} + +void RTCi_ConvertSecondToTime(RTCTime * time, s32 sec) +{ + if (sec < 0) + sec = 0; + if (sec > 86399) + sec = 86399; + time->second = (u32)(sec % 60); + sec /= 60; + time->minute = (u32)(sec % 60); + sec /= 60; + time->hour = (u32)sec; +} + +void RTC_ConvertSecondToDateTime(RTCDate * date, RTCTime * time, s64 sec) +{ + if (sec < 0) + sec = 0; + else if (sec > 3155759999) + sec = 3155759999; + RTCi_ConvertSecondToTime(time, (s32)(sec % 86400)); + RTC_ConvertDayToDate(date, (s32)(sec / 86400)); +} + +RTCWeek RTC_GetDayOfWeek(RTCDate * date) +{ + int cent; + int year = (int)(2000 + date->year); + int month = (int)date->month; + int day = (int)date->day; + + month -= 2; + if (month < 1) + { + month += 12; + --year; + } + cent = year / 100; + year %= 100; + return (RTCWeek)(((26 * month - 2) / 10 + day + year + year / 4 + cent / 4 + 5 * cent) % 7); +} |