diff options
Diffstat (limited to 'berry_fix/payload/src/rtc.c')
-rw-r--r-- | berry_fix/payload/src/rtc.c | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/berry_fix/payload/src/rtc.c b/berry_fix/payload/src/rtc.c deleted file mode 100644 index e73f522aa..000000000 --- a/berry_fix/payload/src/rtc.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "gba/gba.h" -#include "siirtc.h" -#include "global.h" -#include "main.h" - -struct Time gTimeSinceBerryUpdate; -struct Time gRtcUTCTime; - -static u16 sRtcProbeStatus; -static struct SiiRtcInfo sRtcInfoBuffer; -static u8 sRtcProbeCode; -static u16 sImeBak; -static struct SiiRtcInfo sRtcInfoWork; - -const struct SiiRtcInfo sDefaultRTC = { - .year = 0, // 2000 - .month = 1, // January - .day = 1, // 01 - .dayOfWeek = 0, - .hour = 0, - .minute = 0, - .second = 0, - .status = 0, - .alarmHour = 0, - .alarmMinute = 0 -}; -const s32 sDaysPerMonth[] = { - 31, - 28, - 31, - 30, - 31, - 30, - 31, - 31, - 30, - 31, - 30, - 31 -}; - -void rtc_get_status_and_datetime(struct SiiRtcInfo *); -u16 rtc_validate_datetime(struct SiiRtcInfo *); - - -void rtc_intr_disable(void) -{ - sImeBak = REG_IME; - REG_IME = 0; -} - -void rtc_intr_enable(void) -{ - REG_IME = sImeBak; -} - -s32 bcd_to_hex(u8 a0) -{ - if (a0 >= 0xa0 || (a0 & 0xF) >= 10) - return 0xFF; - return ((a0 >> 4) & 0xF) * 10 + (a0 & 0xF); -} - -bool8 is_leap_year(u8 year) -{ - if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) - return TRUE; - return FALSE; -} - -u16 rtc_count_days_parameterized(u8 year, u8 month, u8 day) -{ - u16 numDays = 0; - s32 i; - for (i = year - 1; i > 0; i--) - { - numDays += 365; - if (is_leap_year(i) == TRUE) - numDays++; - } - for (i = 0; i < month - 1; i++) - numDays += sDaysPerMonth[i]; - if (month > MONTH_FEB && is_leap_year(year) == TRUE) - numDays++; - numDays += day; - return numDays; -} - -u16 rtc_count_days_from_info(struct SiiRtcInfo *info) -{ - return rtc_count_days_parameterized(bcd_to_hex(info->year), bcd_to_hex(info->month), bcd_to_hex(info->day)); -} - -static void rtc_probe_status(void) -{ - sRtcProbeStatus = 0; - rtc_intr_disable(); - SiiRtcUnprotect(); - sRtcProbeCode = SiiRtcProbe(); - rtc_intr_enable(); - if ((sRtcProbeCode & 0xF) != 1) - sRtcProbeStatus = 1; - else - { - if (sRtcProbeCode & 0xF0) - sRtcProbeStatus = 2; - else - sRtcProbeStatus = 0; - rtc_get_status_and_datetime(&sRtcInfoBuffer); - sRtcProbeStatus = rtc_validate_datetime(&sRtcInfoBuffer); - } -} - -u16 rtc_get_probe_status(void) -{ - return sRtcProbeStatus; -} - -void sub_020106EC(struct SiiRtcInfo * info) -{ - if (sRtcProbeStatus & 0xFF0) - *info = sDefaultRTC; - else - rtc_get_status_and_datetime(info); -} - -void rtc_get_datetime(struct SiiRtcInfo * info) -{ - rtc_intr_disable(); - SiiRtcGetDateTime(info); - rtc_intr_enable(); -} - -void rtc_get_status(struct SiiRtcInfo * info) -{ - rtc_intr_disable(); - SiiRtcGetStatus(info); - rtc_intr_enable(); -} - -void rtc_get_status_and_datetime(struct SiiRtcInfo * info) -{ - rtc_get_status(info); - rtc_get_datetime(info); -} - -u16 rtc_validate_datetime(struct SiiRtcInfo * info) -{ - s32 year, month, day; - u16 r4 = (info->status & SIIRTCINFO_POWER) ? 0x20 : 0; - if (!(info->status & SIIRTCINFO_24HOUR)) - r4 |= 0x10; - year = bcd_to_hex(info->year); - if (year == 0xFF) - r4 |= 0x40; - month = bcd_to_hex(info->month); - if (month == 0xFF || month == 0 || month > 12) - r4 |= 0x80; - day = bcd_to_hex(info->day); - if (day == 0xFF) - r4 |= 0x100; - if (month == MONTH_FEB) - { - if (day > is_leap_year(year) + sDaysPerMonth[1]) - r4 |= 0x100; - } - else - { - if (day > sDaysPerMonth[month - 1]) - r4 |= 0x100; - } - day = bcd_to_hex(info->hour); - if (day > 24) - r4 |= 0x200; - day = bcd_to_hex(info->minute); - if (day > 60) - r4 |= 0x400; - day = bcd_to_hex(info->second); - if (day > 60) - r4 |= 0x800; - return r4; -} - -void rtc_reset(void) -{ - rtc_intr_disable(); - SiiRtcReset(); - rtc_intr_enable(); -} - -void rtc_sub_time_from_datetime(struct SiiRtcInfo * datetime, struct Time * dest, struct Time * timediff) -{ - u16 r4 = rtc_count_days_from_info(datetime); - dest->seconds = bcd_to_hex(datetime->second) - timediff->seconds; - dest->minutes = bcd_to_hex(datetime->minute) - timediff->minutes; - dest->hours = bcd_to_hex(datetime->hour) - timediff->hours; - dest->days = r4 - timediff->days; - if (dest->seconds < 0) - { - dest->seconds += 60; - dest->minutes--; - } - if (dest->minutes < 0) - { - dest->minutes += 60; - dest->hours--; - } - if (dest->hours < 0) - { - dest->hours += 24; - dest->days--; - } -} - -void rtc_sub_time_from_time(struct Time * dest, struct Time * diff, struct Time * src) -{ - dest->seconds = src->seconds - diff->seconds; - dest->minutes = src->minutes - diff->minutes; - dest->hours = src->hours - diff->hours; - dest->days = src->days - diff->days; - if (dest->seconds < 0) - { - dest->seconds += 60; - dest->minutes--; - } - if (dest->minutes < 0) - { - dest->minutes += 60; - dest->hours--; - } - if (dest->hours < 0) - { - dest->hours += 24; - dest->days--; - } -} - -bool32 rtc_maincb_is_rtc_working(void) -{ - rtc_probe_status(); - if (rtc_get_probe_status() & 0xFF0) - return FALSE; - return TRUE; -} - -void rtc_set_datetime(struct SiiRtcInfo * info) -{ - vu16 imeBak = REG_IME; - REG_IME = 0; - SiiRtcSetDateTime(info); - REG_IME = imeBak; -} - -bool32 rtc_maincb_is_time_since_last_berry_update_positive(u8 * a0) -{ - rtc_get_status_and_datetime(&sRtcInfoWork); - *a0 = bcd_to_hex(sRtcInfoWork.year); - rtc_sub_time_from_datetime(&sRtcInfoWork, &gRtcUTCTime, LocalTimeOffset); - rtc_sub_time_from_time(&gTimeSinceBerryUpdate, LastBerryTreeUpdate, &gRtcUTCTime); - if (gTimeSinceBerryUpdate.days * 1440 + gTimeSinceBerryUpdate.hours * 60 + gTimeSinceBerryUpdate.minutes >= 0) - return TRUE; - return FALSE; -} - -u32 hex_to_bcd(u8 a0) -{ - u32 r4; - if (a0 > 99) - return 0xFF; - r4 = Div(a0, 10) << 4; - r4 |= Mod(a0, 10); - return r4; -} - -void sii_rtc_inc(u8 * a0) -{ - *a0 = hex_to_bcd(bcd_to_hex(*a0) + 1); -} - -void sii_rtc_inc_month(struct SiiRtcInfo * a0) -{ - sii_rtc_inc(&a0->month); - if (bcd_to_hex(a0->month) > 12) - { - sii_rtc_inc(&a0->year); - a0->month = MONTH_JAN; - } -} - -void sii_rtc_inc_day(struct SiiRtcInfo * a0) -{ - sii_rtc_inc(&a0->day); - if (bcd_to_hex(a0->day) > sDaysPerMonth[bcd_to_hex(a0->month) - 1]) - { - if (!is_leap_year(bcd_to_hex(a0->year)) || bcd_to_hex(a0->month) != MONTH_FEB || bcd_to_hex(a0->day) != 29) - { - a0->day = 1; - sii_rtc_inc_month(a0); - } - } -} - -bool32 rtc_is_past_feb_28_2000(struct SiiRtcInfo * a0) -{ - if (bcd_to_hex(a0->year) == 0) - { - if (bcd_to_hex(a0->month) == MONTH_JAN) - return FALSE; - if (bcd_to_hex(a0->month) > MONTH_FEB) - return TRUE; - if (bcd_to_hex(a0->day) == 29) - return TRUE; - return FALSE; - } - if (bcd_to_hex(a0->year) == 1) - return TRUE; - return FALSE; -} - -void rtc_maincb_fix_date(void) -{ - rtc_get_status_and_datetime(&sRtcInfoWork); - if (bcd_to_hex(sRtcInfoWork.year) == 0 || bcd_to_hex(sRtcInfoWork.year) == 1) - { - if (bcd_to_hex(sRtcInfoWork.year) == 1) - { - sRtcInfoWork.year = 2; - sRtcInfoWork.month = MONTH_JAN; - sRtcInfoWork.day = 2; - rtc_set_datetime(&sRtcInfoWork); - } - else - { - if (rtc_is_past_feb_28_2000(&sRtcInfoWork) == TRUE) - { - sii_rtc_inc_day(&sRtcInfoWork); - sii_rtc_inc(&sRtcInfoWork.year); - } - else - { - sii_rtc_inc(&sRtcInfoWork.year); - } - rtc_set_datetime(&sRtcInfoWork); - } - } -} |