summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/code/lb_rtc.c17
-rw-r--r--src/code/lbrtc/7220C0.c72
-rw-r--r--src/code/lbrtc/722570.c78
-rw-r--r--src/code/lbrtc/722880.c26
-rw-r--r--src/code/lbrtc/722AB0.c120
-rw-r--r--src/code/lbrtc/lbrtc_getTime.c31
-rw-r--r--src/code/lbrtc/lbrtc_init.c33
-rw-r--r--src/code/lbrtc/lbrtc_setTime.c41
-rw-r--r--src/overlays/gamestates/ovl_select/m_select.h4
9 files changed, 409 insertions, 13 deletions
diff --git a/src/code/lb_rtc.c b/src/code/lb_rtc.c
index d9e6453..885fb90 100644
--- a/src/code/lb_rtc.c
+++ b/src/code/lb_rtc.c
@@ -1,12 +1,7 @@
#include "lb_rtc.h"
+#include "lbrtc.h"
#include "m_common_data.h"
#include "padmgr.h"
-#include "722970.h"
-#include "721EC0.h"
-#include "7220C0.h"
-#include "722310.h"
-#include "722AB0.h"
-#include "722880.h"
#include "macros.h"
#include "attributes.h"
@@ -22,7 +17,7 @@ s32 lbRTC_Initial() {
if (l_lbRTC_isInitial == 1) {
mq = padmgr_LockSerialMesgQ();
l_lbRTC_isInitial = 0;
- B_80145620_jp = func_800FECD0_jp(mq);
+ B_80145620_jp = lbrtc_init(mq);
padmgr_UnlockSerialMesgQ(mq);
}
return B_80145620_jp;
@@ -36,7 +31,7 @@ s32 lbRTC_IsOki(lbRTC_time_c* ptr) {
if (isInitial == 0) {
mq = padmgr_LockSerialMesgQ();
- isInitial = func_800FE220_jp(mq, ptr);
+ isInitial = lbrtc_getTime(mq, ptr);
padmgr_UnlockSerialMesgQ(mq);
if (isInitial == 0) {
return isInitial;
@@ -97,7 +92,7 @@ void lbRTC_SetTime(lbRTC_time_c* time) {
if (common_data.time.rtcEnabled == 1 && !common_data.time.rtcCrashed) {
time->weekday = lbRTC_Week(time->year, time->month, time->day);
mq = padmgr_LockSerialMesgQ();
- func_800FE670_jp(mq, time);
+ lbrtc_setTime(mq, time);
padmgr_UnlockSerialMesgQ(mq);
} else {
lbRTC_TimeCopy(&common_data.time.rtcTime, time);
@@ -109,7 +104,7 @@ void lbRTC_GetTime(lbRTC_time_c* time) {
if (common_data.time.rtcEnabled == 1 && !common_data.time.rtcCrashed) {
mq = padmgr_LockSerialMesgQ();
- func_800FE220_jp(mq, time);
+ lbrtc_getTime(mq, time);
padmgr_UnlockSerialMesgQ(mq);
} else {
lbRTC_TimeCopy(time, &common_data.time.rtcTime);
@@ -291,7 +286,7 @@ s32 lbRTC_IntervalTime(lbRTC_time_c* t0, lbRTC_time_c* t1) {
t2 = *t0;
t3 = *t1;
- func_800FF060_jp(&t3, &t2);
+ lbrtc_GetIntervalMinutes(&t3, &t2);
}
const int total_days[2][lbRTC_MONTHS_MAX + 1] = {
diff --git a/src/code/lbrtc/7220C0.c b/src/code/lbrtc/7220C0.c
new file mode 100644
index 0000000..efbf300
--- /dev/null
+++ b/src/code/lbrtc/7220C0.c
@@ -0,0 +1,72 @@
+#include "lbrtc.h"
+#include "lib/ultralib/src/io/siint.h"
+#include "lib/ultralib/src/io/controller.h"
+
+s32 func_800FE420_jp(OSMesgQueue* mq, OSRTCTime* time) {
+ u8 status;
+ s32 ret;
+
+ ret = func_800FE480_jp(mq, &status);
+
+ if (ret == 0) {
+ ret = func_800FEE10_jp(mq, RTC_SRAM_BLOCK_TYPE, (u8*)time);
+ }
+
+ return ret;
+}
+
+s32 func_800FE480_jp(OSMesgQueue* mq, u8* status) {
+ s32 ret = 0;
+ s32 i;
+ u8* ptr;
+ __OSContRTCInfoFormat format;
+
+ __osSiGetAccess();
+
+ __osEepPifRam.pifstatus = CONT_CMD_EXE;
+
+ ptr = (u8*)&__osEepPifRam.ramarray;
+
+ for (i = 0; i < 4; i++) {
+ *ptr++ = 0;
+ }
+
+ format.txsize = CONT_CMD_RTC_INFO_TX;
+ format.rxsize = CONT_CMD_RTC_INFO_RX;
+ format.cmd = CONT_CMD_RTC_INFO;
+
+ *(__OSContRTCInfoFormat*)ptr = format;
+
+ ptr += sizeof(__OSContRTCInfoFormat);
+
+ *ptr = CONT_CMD_END;
+
+ ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+
+ __osContLastCmd = CONT_CMD_RTC_INFO;
+
+ ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+
+ ptr = (u8*)&__osEepPifRam.ramarray[1];
+
+ format = *(__OSContRTCInfoFormat*)ptr;
+
+ ret = (format.rxsize & CHNL_ERR_MASK) & 0xFF;
+
+ if (ret == 0) {
+ if (!(((format.unk4 << 8) | format.unk3) & 0xFFFF & 0x1000)) {
+ ret = 0xB;
+ } else {
+ *status = format.status;
+ }
+ } else if (ret & CHNL_ERR_NORESP) {
+ ret = 1;
+ } else {
+ ret = 4;
+ }
+
+ __osSiRelAccess();
+ return ret;
+}
diff --git a/src/code/lbrtc/722570.c b/src/code/lbrtc/722570.c
new file mode 100644
index 0000000..010815d
--- /dev/null
+++ b/src/code/lbrtc/722570.c
@@ -0,0 +1,78 @@
+#include "lbrtc.h"
+#include "lib/ultralib/src/io/siint.h"
+#include "lib/ultralib/src/io/controller.h"
+
+OSTimer __contRTCTimer;
+OSMesgQueue __contRTCMesgQ;
+OSMesg __contRTCMesg;
+
+s32 func_800FE8D0_jp(OSMesgQueue* mq, u8 blockType, u8* data) {
+ s32 ret;
+ u8* ptr;
+ __OSContRTCRWFormat format;
+
+ __osSiGetAccess();
+ func_800FEABC_jp(blockType, data);
+ ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
+ __osContLastCmd = CONT_CMD_WRITE_RTC;
+
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+ ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
+ ptr = (u8*)(&__osEepPifRam.ramarray[1]);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+
+ format = *((__OSContRTCRWFormat*)ptr);
+ ret = CHNL_ERR(format);
+
+ __osSiRelAccess();
+
+ osSetTimer(&__contRTCTimer, OS_USEC_TO_CYCLES(300), 0, &__contRTCMesgQ, &__contRTCMesg);
+ osRecvMesg(&__contRTCMesgQ, NULL, OS_MESG_BLOCK);
+ if (ret == 0) {
+ bcopy(&format.data, data, sizeof(__OSContRTCData));
+ if (format.status & RTC_STATUS_BATTERY_FAILURE) {
+ ret = RTC_ERR_BATTERY;
+ //! @bug should have checked for RTC_STATUS_CRYSTAL_FAILURE
+ } else if (format.status & RTC_STATUS_BATTERY_FAILURE) {
+ ret = RTC_ERR_CRYSTAL;
+ } else if (format.status & RTC_STATUS_STOPPED) {
+ ret = RTC_STOPPED;
+ }
+ } else if (ret & CHNL_ERR_NORESP) {
+ ret = 1;
+ } else {
+ ret = 4;
+ }
+ __osSiRelAccess();
+
+ return ret;
+}
+
+s32 func_800FEABC_jp(u8 blockType, u8* data) {
+ s32 i;
+ u8* ptr = (u8*)&__osEepPifRam;
+ __OSContRTCRWFormat format;
+
+ for (i = 0; i < ARRLEN(__osEepPifRam.ramarray); i++) {
+ __osEepPifRam.ramarray[i] = 0xFF;
+ }
+
+ __osEepPifRam.pifstatus = CONT_CMD_EXE;
+
+ format.txsize = CONT_CMD_WRITE_RTC_TX;
+ format.rxsize = CONT_CMD_WRITE_RTC_RX;
+ format.cmd = CONT_CMD_WRITE_RTC;
+ format.blockType = blockType;
+
+ for (i = 0; i < (s32)sizeof(__OSContRTCData); i++) {
+ (&format.txsize)[i + 4] = *data++;
+ }
+
+ for (i = 0; i < 4; i++) {
+ *ptr++ = 0;
+ }
+ *(__OSContRTCRWFormat*)ptr = format;
+
+ ptr += sizeof(__OSContRTCRWFormat);
+ *ptr = CONT_CMD_END;
+}
diff --git a/src/code/lbrtc/722880.c b/src/code/lbrtc/722880.c
new file mode 100644
index 0000000..6c57977
--- /dev/null
+++ b/src/code/lbrtc/722880.c
@@ -0,0 +1,26 @@
+#include "lbrtc.h"
+#include "attributes.h"
+
+s32 func_800FEBE0_jp(OSMesgQueue* mq, OSRTCTime* time) {
+ u32 ret;
+ UNUSED s32 pad;
+ __OSContRTCControlRegs rtc[1];
+ u8 status;
+
+ ret = func_800FE480_jp(mq, &status);
+ if (ret == 0) {
+ ret = func_800FEE10_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&rtc);
+ if (ret == 0) {
+ rtc[0].writeProtectBitfield &= ~RTC_WRITE_PROTECT_NVRAM_BIT;
+ ret = func_800FE8D0_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&rtc);
+ if (ret == 0) {
+ ret = func_800FE8D0_jp(mq, RTC_SRAM_BLOCK_TYPE, (u8*)time);
+ if (ret == 0) {
+ rtc[0].writeProtectBitfield |= RTC_WRITE_PROTECT_NVRAM_BIT;
+ ret = func_800FE8D0_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&rtc);
+ }
+ }
+ }
+ }
+ return ret;
+}
diff --git a/src/code/lbrtc/722AB0.c b/src/code/lbrtc/722AB0.c
new file mode 100644
index 0000000..0c1ed89
--- /dev/null
+++ b/src/code/lbrtc/722AB0.c
@@ -0,0 +1,120 @@
+#include "lbrtc.h"
+#include "lb_rtc.h"
+#include "lib/ultralib/src/io/siint.h"
+#include "lib/ultralib/src/io/controller.h"
+
+u16 total_days_internal[2][lbRTC_MONTHS_MAX + 1] = {
+ // Standard year
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ // Leap year (flawed leap year calculation)
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+s32 func_800FEE10_jp(OSMesgQueue* mq, u8 blockType, u8* buf) {
+ s32 ret;
+ __OSContRTCRWFormat* ptr;
+ __OSContRTCRWFormat format;
+
+ __osSiGetAccess();
+ func_800FEF9C_jp(blockType);
+ __osContLastCmd = CONT_CMD_READ_RTC;
+
+ ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+
+ ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
+ osRecvMesg(mq, NULL, OS_MESG_BLOCK);
+
+ ptr = (__OSContRTCRWFormat*)&__osEepPifRam.ramarray[1];
+
+ format = *ptr;
+ ret = format.rxsize & CHNL_ERR_MASK;
+
+ if (ret == 0) {
+ bcopy(&format.data, buf, 8);
+ if (format.status & RTC_STATUS_BATTERY_FAILURE) {
+ ret = RTC_ERR_BATTERY;
+ //! @bug should have checked for RTC_STATUS_CRYSTAL_FAILURE
+ } else if (format.status & RTC_STATUS_BATTERY_FAILURE) {
+ ret = RTC_ERR_CRYSTAL;
+ } else if (format.status & RTC_STATUS_STOPPED) {
+ ret = RTC_STOPPED;
+ }
+ } else if (ret & CHNL_ERR_NORESP) {
+ ret = 1;
+ } else {
+ ret = 4;
+ }
+
+ __osSiRelAccess();
+ return ret;
+}
+
+void func_800FEF9C_jp(u8 blockType) {
+ u8* ptr = (u8*)&__osEepPifRam.ramarray;
+ s32 i;
+ __OSContRTCRWFormat format;
+
+ __osEepPifRam.pifstatus = CONT_CMD_EXE;
+
+ format.txsize = CONT_CMD_READ_RTC_TX;
+ format.rxsize = CONT_CMD_READ_RTC_RX;
+ format.cmd = CONT_CMD_READ_RTC;
+ format.blockType = blockType;
+
+ for (i = 0; i < 4; i++) {
+ *ptr++ = 0;
+ }
+
+ *(__OSContRTCRWFormat*)ptr = format;
+
+ ptr += sizeof(__OSContRTCRWFormat);
+ *ptr = CONT_CMD_END;
+}
+
+s32 lbrtc_GetIntervalMinutes(OSRTCTime* t0, OSRTCTime* t1) {
+ u8 yearLeapPeriod = (t1->year - t0->year) / 4;
+ /* Total 'leap years' (missing extra not divisible by 100, except when divisible by 400 rule) */
+
+ u8 extraYears = (t1->year - t0->year) % 4; /* Non-leap year remainder */
+ u8 lessLeap = (t0->year % 4) == 0; /* Is the lesser year a leap year? */
+ u8 overLeap = (t1->year % 4) == 0; /* Is the greater year a leap year? */
+ u8 leapAdd = ((4 - (t0->year % 4)) % 4) < extraYears; /* Add leap day when leap day occurs during 'extra years' */
+
+ s32 days;
+ s32 hour;
+ s32 min;
+ if (t0->year > t1->year) {
+ return 0;
+ } else if (t0->year == t1->year) {
+ if (t0->month > t1->month) {
+ return 0;
+ } else if (t0->month == t1->month) {
+ if (t0->day > t1->day) {
+ return 0;
+ } else if (t0->day == t1->day) {
+ if (t0->hour > t1->hour) {
+ return 0;
+ } else if (t0->hour == t1->hour) {
+ if (t0->min > t1->min) {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+
+ days = yearLeapPeriod * 1461 + extraYears * 365 + leapAdd;
+ days += t1->day - 1;
+ days += total_days_internal[overLeap][t1->month - 1];
+ days -= t0->day - 1;
+ days -= total_days_internal[lessLeap][t0->month - 1];
+
+ hour = days * 24;
+ hour = (t1->hour + hour) - t0->hour;
+
+ min = hour * 60;
+ min = (t1->min + min) - t0->min;
+
+ return min;
+}
diff --git a/src/code/lbrtc/lbrtc_getTime.c b/src/code/lbrtc/lbrtc_getTime.c
new file mode 100644
index 0000000..4dd8669
--- /dev/null
+++ b/src/code/lbrtc/lbrtc_getTime.c
@@ -0,0 +1,31 @@
+#include "lbrtc.h"
+
+s32 lbrtc_getTime(OSMesgQueue* mq, OSRTCTime* time) {
+ __OSContRTCData rtc[1];
+ __OSContRTCData data;
+ u8 status;
+ s32 ret;
+
+ ret = func_800FE480_jp(mq, &status);
+ if (ret == 0) {
+ ret = func_800FEE10_jp(mq, RTC_TIME_BLOCK_TYPE, (u8*)&data);
+ if (ret == 0) {
+ ret = func_800FEE10_jp(mq, RTC_TIME_BLOCK_TYPE, (u8*)&rtc);
+ if (bcmp(&data, &rtc, sizeof(__OSContRTCData)) != 0) {
+ ret = func_800FEE10_jp(mq, RTC_TIME_BLOCK_TYPE, (u8*)&rtc);
+ }
+ time->sec = (rtc[0].sec & 0xF) + ((rtc[0].sec >> 4) * 10);
+ time->min = (rtc[0].min & 0xF) + ((rtc[0].min >> 4) * 10);
+ time->hour = (((rtc[ret * 0].hour - 0x80) >> 4) * 10) + (((rtc + 0)->hour - 0x80) & 0xF);
+ time->day = (rtc[0].day & 0xF) + ((rtc[0].day >> 4) * 10);
+ time->weekday = rtc[0].weekday;
+ time->month = (rtc[0].month & 0xF) + ((rtc[0].month >> 4) * 10);
+ if (rtc[0].centuriesSince1900 != 0) {
+ time->year = ((rtc[0].yearLo & 0xF) + ((rtc[0].yearLo >> 4) * 10)) + 2000;
+ } else {
+ time->year = ((rtc[0].yearLo & 0xF) + ((rtc[0].yearLo >> 4) * 10)) + 1900;
+ }
+ }
+ }
+ return ret;
+}
diff --git a/src/code/lbrtc/lbrtc_init.c b/src/code/lbrtc/lbrtc_init.c
new file mode 100644
index 0000000..e298065
--- /dev/null
+++ b/src/code/lbrtc/lbrtc_init.c
@@ -0,0 +1,33 @@
+#include "lbrtc.h"
+#include "attributes.h"
+
+s32 D_801160C0_jp = 0;
+
+s32 lbrtc_init(OSMesgQueue* mq) {
+ s32 ret;
+ u8 status;
+ UNUSED s32 pad;
+ __OSContRTCControlRegs rtc[1];
+
+ ret = func_800FE480_jp(mq, &status);
+ if (ret == 0) {
+ if (D_801160C0_jp == 0) {
+ osCreateMesgQueue(&__contRTCMesgQ, &__contRTCMesg, OS_MESG_BLOCK);
+ D_801160C0_jp = 1;
+ }
+ if (status & RTC_STATUS_STOPPED) {
+ ret = func_800FEE10_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&rtc);
+ if ((ret == 0) || (ret == RTC_STOPPED)) {
+ rtc[0].flagsBitfield &= ~RTC_WRITE_STOP_COUNT2_BIT;
+ ret = func_800FE8D0_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&rtc);
+ }
+ }
+ if (status & RTC_STATUS_BATTERY_FAILURE) {
+ ret = (status & RTC_STATUS_CRYSTAL_FAILURE) ? 0x13 : RTC_ERR_BATTERY;
+
+ } else if (status & RTC_STATUS_CRYSTAL_FAILURE) {
+ ret = RTC_ERR_CRYSTAL;
+ }
+ }
+ return ret;
+}
diff --git a/src/code/lbrtc/lbrtc_setTime.c b/src/code/lbrtc/lbrtc_setTime.c
new file mode 100644
index 0000000..900803d
--- /dev/null
+++ b/src/code/lbrtc/lbrtc_setTime.c
@@ -0,0 +1,41 @@
+#include "lbrtc.h"
+#include "attributes.h"
+
+s32 lbrtc_setTime(OSMesgQueue* mq, OSRTCTime* time) {
+ __OSContRTCData rtc[1];
+ UNUSED s32 pad;
+ __OSContRTCControlRegs cr[1];
+ u8 status;
+ s32 ret;
+
+ ret = func_800FE480_jp(mq, &status);
+ if (ret == 0) {
+ ret = func_800FEE10_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&cr);
+ if (ret == 0) {
+ cr[0].writeProtectBitfield &= ~RTC_WRITE_PROTECT_RTC_BIT;
+ cr[0].flagsBitfield |= RTC_WRITE_STOP_COUNT_BIT;
+ ret = func_800FE8D0_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&cr);
+ if (ret == RTC_STOPPED) {
+ rtc[0].sec = (time->sec % 10) + ((time->sec / 10) * 0x10);
+ rtc[0].min = (time->min % 10) + ((time->min / 10) * 0x10);
+ rtc[0].hour = (time->hour % 10) + ((time->hour / 10) * 0x10);
+ rtc[0].day = (time->day % 10) + ((time->day / 10) * 0x10);
+ rtc[0].weekday = time->weekday;
+ rtc[0].month = (time->month % 10) + ((time->month / 10) * 0x10);
+ rtc[0].yearLo = (time->year % 10) + (((time->year % 100) / 10) * 0x10);
+ if (time->year >= 2000) {
+ rtc[0].centuriesSince1900 = 1;
+ } else {
+ rtc[0].centuriesSince1900 = 0;
+ }
+ ret = func_800FE8D0_jp(mq, RTC_TIME_BLOCK_TYPE, (u8*)&rtc);
+ if (ret == RTC_STOPPED) {
+ cr[0].writeProtectBitfield |= RTC_WRITE_PROTECT_RTC_BIT;
+ cr[0].flagsBitfield &= ~RTC_WRITE_STOP_COUNT_BIT;
+ ret = func_800FE8D0_jp(mq, RTC_CR_BLOCK_TYPE, (u8*)&cr);
+ }
+ }
+ }
+ }
+ return ret;
+}
diff --git a/src/overlays/gamestates/ovl_select/m_select.h b/src/overlays/gamestates/ovl_select/m_select.h
index 9ef78df..0024827 100644
--- a/src/overlays/gamestates/ovl_select/m_select.h
+++ b/src/overlays/gamestates/ovl_select/m_select.h
@@ -21,7 +21,7 @@ typedef enum SelectCheck {
/* 10 */ SELECT_CHECK_A_BUTTON_NUM
} SelectCheck;
-struct lbRTC_time_c;
+struct OSRTCTime;
struct gfxprint;
typedef struct Game_Select {
@@ -86,7 +86,7 @@ void select_move(Game_Select* select);
void select_print_wait(struct gfxprint* gfxprint);
void select_print_course_name(Game_Select* select, struct gfxprint* gfxprint);
void select_print_rtc(struct gfxprint* gfxprint, Game_Select* select);
-void select_print_time_sub(struct gfxprint* gfxprint, Game_Select* select, struct lbRTC_time_c* time);
+void select_print_time_sub(struct gfxprint* gfxprint, Game_Select* select, struct OSRTCTime* time);
void select_print_time(struct gfxprint* gfxprint, Game_Select* select);
void select_print_step_sub2(struct gfxprint* gfxprint);
void select_print_step(struct gfxprint* gfxprint, Game_Select* select);