summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakxo <87568477+Prakxo@users.noreply.github.com>2024-07-01 17:02:29 +0200
committerGitHub <noreply@github.com>2024-07-01 08:02:29 -0700
commit0e66d077f8cf321c3f11978f531502ec592c0cdb (patch)
treef726b2a6bfcca0e45d5cacc9604dbcaaf5e197df
parent235b6575c208667fa39592bfe0c885c3ca006595 (diff)
lbrtc OK (#196)
* lbrtc OK * format * names * format 2 * review + docs * format
-rw-r--r--Makefile4
-rw-r--r--include/code_variables.h3
-rw-r--r--include/lb_rtc.h12
-rw-r--r--include/lbrtc.h103
-rw-r--r--include/m_all_grow.h6
-rw-r--r--linker_scripts/jp/symbol_addrs_code.txt15
-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
-rw-r--r--yamls/jp/code.yaml16
16 files changed, 537 insertions, 44 deletions
diff --git a/Makefile b/Makefile
index 87e4981..a6e7bdb 100644
--- a/Makefile
+++ b/Makefile
@@ -245,6 +245,10 @@ build/src/boot/libu64/%.o: OPTFLAGS := -O2
build/src/boot/fault.o: CFLAGS += -trapuv
build/src/boot/fault_drawer.o: CFLAGS += -trapuv
+build/src/code/lbrtc/%.o: CC = $(CC_OLD)
+build/src/code/lbrtc/%.o: OPTFLAGS = -O1 -g1
+
+
# cc & asm-processor
build/src/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) --
diff --git a/include/code_variables.h b/include/code_variables.h
index ef7a780..b484b81 100644
--- a/include/code_variables.h
+++ b/include/code_variables.h
@@ -2223,8 +2223,5 @@ extern UNK_TYPE B_80145FFC_jp;
// extern UNK_TYPE B_80152460_jp;
// extern UNK_TYPE B_80152464_jp;
// extern UNK_TYPE B_80152468_jp;
-// extern UNK_TYPE B_80152480_jp;
-// extern UNK_TYPE B_801524A0_jp;
-// extern UNK_TYPE B_801524B8_jp;
#endif
diff --git a/include/lb_rtc.h b/include/lb_rtc.h
index 09d9960..223147c 100644
--- a/include/lb_rtc.h
+++ b/include/lb_rtc.h
@@ -2,6 +2,7 @@
#define LB_RTC_H
#include "ultra64.h"
+#include "lbrtc.h"
/* TODO: do these have a better header? */
#define GAME_YEAR_MIN 2000 /* Minimum year supported by the game */
@@ -18,16 +19,7 @@ typedef u8 lbRTC_weekday_t;
typedef u8 lbRTC_month_t;
typedef u16 lbRTC_year_t;
-/* Name leaked in lbRTC_time_c_save_data_check */
-typedef struct lbRTC_time_c {
- /* 0x00 */ lbRTC_sec_t sec;
- /* 0x01 */ lbRTC_min_t min;
- /* 0x02 */ lbRTC_hour_t hour;
- /* 0x03 */ lbRTC_day_t day;
- /* 0x04 */ lbRTC_weekday_t weekday;
- /* 0x05 */ lbRTC_month_t month;
- /* 0x06 */ lbRTC_year_t year;
-} lbRTC_time_c; // size = 0x8
+typedef OSRTCTime lbRTC_time_c;
/* Name leaked in mTM_ymd_2_time */
typedef struct lbRTC_ymd_t {
diff --git a/include/lbrtc.h b/include/lbrtc.h
new file mode 100644
index 0000000..cf42577
--- /dev/null
+++ b/include/lbrtc.h
@@ -0,0 +1,103 @@
+#ifndef LBRTC_H
+#define LBRTC_H
+
+#include "ultra64.h"
+
+typedef struct OSRTCTime { // assumed from m_flashrom
+ /* 0x00 */ u8 sec;
+ /* 0x01 */ u8 min;
+ /* 0x02 */ u8 hour;
+ /* 0x03 */ u8 day;
+ /* 0x04 */ u8 weekday;
+ /* 0x05 */ u8 month;
+ /* 0x06 */ u16 year;
+} OSRTCTime; // size = 0x8
+
+// Internal
+
+// docs from: https://n64brew.dev/wiki/Joybus_Protocol
+
+#define RTC_CR_BLOCK_TYPE 0
+#define RTC_SRAM_BLOCK_TYPE 1
+#define RTC_TIME_BLOCK_TYPE 2
+#define RTC_BLOCK_TYPE_3 3
+
+#define CONT_CMD_RTC_INFO 6
+#define CONT_CMD_READ_RTC 7
+#define CONT_CMD_WRITE_RTC 8
+
+#define CONT_CMD_RTC_INFO_TX 1
+#define CONT_CMD_RTC_INFO_RX 3
+
+#define CONT_CMD_READ_RTC_TX 2
+#define CONT_CMD_READ_RTC_RX 9
+
+#define CONT_CMD_WRITE_RTC_TX 10
+#define CONT_CMD_WRITE_RTC_RX 1
+
+#define RTC_STATUS_STOPPED 0x80
+#define RTC_STATUS_CRYSTAL_FAILURE 0x2
+#define RTC_STATUS_BATTERY_FAILURE 0x1
+
+#define RTC_ERR_BATTERY 0x11
+#define RTC_ERR_CRYSTAL 0x12
+
+#define RTC_STOPPED 0x10
+
+typedef struct __OSContRTCData {
+ /* 0x00 */ u8 sec;
+ /* 0x01 */ u8 min;
+ /* 0x02 */ u8 hour;
+ /* 0x03 */ u8 day;
+ /* 0x04 */ u8 weekday;
+ /* 0x05 */ u8 month;
+ /* 0x06 */ u8 yearLo;
+ /* 0x07 */ u8 centuriesSince1900;
+} __OSContRTCData; // size = 0x8
+
+typedef struct __OSContRTCRWFormat {
+ /* 0x0 */ u8 txsize;
+ /* 0x1 */ u8 rxsize;
+ /* 0x2 */ u8 cmd;
+ /* 0x3 */ u8 blockType;
+ /* 0x4 */ __OSContRTCData data;
+ /* 0xC */ u8 status;
+} __OSContRTCRWFormat; // size = 0xD
+
+typedef struct __OSContRTCInfoFormat {
+ /* 0x0 */ u8 txsize;
+ /* 0x1 */ u8 rxsize;
+ /* 0x2 */ u8 cmd;
+ /* 0x3 */ u8 unk3;
+ /* 0x4 */ u8 unk4;
+ /* 0x5 */ u8 status;
+} __OSContRTCInfoFormat; // size = 0x6
+
+#define RTC_WRITE_PROTECT_NVRAM_BIT 1
+#define RTC_WRITE_PROTECT_RTC_BIT 2
+#define RTC_WRITE_STOP_COUNT_BIT 4
+#define RTC_WRITE_STOP_COUNT2_BIT 6
+
+typedef struct __OSContRTCControlRegs {
+ /* 0x0 */ u8 writeProtectBitfield;
+ /* 0x1 */ u8 flagsBitfield;
+} __OSContRTCControlRegs; // size = 0x2
+
+extern OSMesgQueue __contRTCMesgQ;
+extern OSMesg __contRTCMesg;
+
+//
+
+s32 lbrtc_getTime(OSMesgQueue* mq, OSRTCTime* time);
+s32 func_800FE420_jp(OSMesgQueue* mq, OSRTCTime* time);
+s32 func_800FE480_jp(OSMesgQueue* mq, u8* status);
+s32 lbrtc_setTime(OSMesgQueue* mq, OSRTCTime* time);
+s32 func_800FE8D0_jp(OSMesgQueue* mq, u8 blockType, u8* data);
+s32 func_800FEABC_jp(u8 blockType, u8* data);
+s32 func_800FEBE0_jp(OSMesgQueue* mq, OSRTCTime* time);
+s32 lbrtc_init(OSMesgQueue* mq);
+s32 func_800FEE10_jp(OSMesgQueue* mq, u8 blockType, u8* buf);
+void func_800FEF9C_jp(u8 blockType);
+s32 lbrtc_GetIntervalMinutes(OSRTCTime* t0, OSRTCTime* t1);
+
+#endif
diff --git a/include/m_all_grow.h b/include/m_all_grow.h
index 7e53e16..69796de 100644
--- a/include/m_all_grow.h
+++ b/include/m_all_grow.h
@@ -5,7 +5,7 @@
struct Foreground;
struct gfxprint;
-struct lbRTC_time_c;
+struct OSRTCTime;
#define AGrw_DUMP_WIDTH 4
#define AGrw_DUMP_HEIGHT 4
@@ -51,12 +51,12 @@ void mAGrw_OrderSetHaniwa(void);
u8 func_80055E34_jp(u16* items);
void mAGrw_ChangeItemBlock(u16* blockItems, u16 newItem, u16 targetItem, u8 possibleNum);
void mAGrw_ChangeItemBlock2(u16* blockItems, u16 newItem, u8 possibleNum);
-s32 mAGrw_CheckPutXmasTree(struct lbRTC_time_c* time);
+s32 mAGrw_CheckPutXmasTree(struct OSRTCTime* time);
void mAGrw_SetXmasTreeBlock(u16* blockItems);
void mAGrw_ClearXmasTreeBlock(u16* blockItems);
void mAGrw_XmasTreeField(s32 type);
void mAGrw_SetXmasTree(void);
-void mAGrw_RenewalFgItem(struct lbRTC_time_c* time);
+void mAGrw_RenewalFgItem(struct OSRTCTime* time);
void mAGrw_ChangeTree2OtherBlock(u16* items, u16 other);
void mAGrw_ChangeTree2FruitTreeLine(struct Foreground* fg, u16 fruitTree);
void mAGrw_ChangeTree2FruitTree(void);
diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt
index bde00ea..f093435 100644
--- a/linker_scripts/jp/symbol_addrs_code.txt
+++ b/linker_scripts/jp/symbol_addrs_code.txt
@@ -4163,17 +4163,17 @@ func_800FD13C_jp = 0x800FD13C; // type:func
Na_FurnitureInst = 0x800FD170; // type:func
func_800FD280_jp = 0x800FD280; // type:func
D_800FD2D0_jp = 0x800FD2D0; //
-func_800FE220_jp = 0x800FE220; // type:func
+lbrtc_getTime = 0x800FE220; // type:func
func_800FE420_jp = 0x800FE420; // type:func
func_800FE480_jp = 0x800FE480; // type:func
-func_800FE670_jp = 0x800FE670; // type:func
+lbrtc_setTime = 0x800FE670; // type:func
func_800FE8D0_jp = 0x800FE8D0; // type:func
func_800FEABC_jp = 0x800FEABC; // type:func
func_800FEBE0_jp = 0x800FEBE0; // type:func
-func_800FECD0_jp = 0x800FECD0; // type:func
+lbrtc_init = 0x800FECD0; // type:func
func_800FEE10_jp = 0x800FEE10; // type:func
func_800FEF9C_jp = 0x800FEF9C; // type:func
-func_800FF060_jp = 0x800FF060; // type:func
+lbrtc_GetIntervalMinutes = 0x800FF060; // type:func
gspS2DEX2_fifoTextStart = 0x800FF370; // type:u64 size:0x18C0 name_end:gspS2DEX2_fifoTextEnd
// .data
@@ -5151,7 +5151,6 @@ D_80115020_jp = 0x80115020; //
D_80115090_jp = 0x80115090; // type:s16
D_80115D80_jp = 0x80115D80; //
D_801160C0_jp = 0x801160C0; //
-D_801160CE_jp = 0x801160CE; // type:u16
// .rodata
@@ -6464,6 +6463,6 @@ B_8015245C_jp = 0x8015245C; //
B_80152460_jp = 0x80152460; //
B_80152464_jp = 0x80152464; //
B_80152468_jp = 0x80152468; //
-B_80152480_jp = 0x80152480; //
-B_801524A0_jp = 0x801524A0; //
-B_801524B8_jp = 0x801524B8; //
+__contRTCTimer = 0x80152480; //
+__contRTCMesgQ = 0x801524A0; //
+__contRTCMesg = 0x801524B8; //
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);
diff --git a/yamls/jp/code.yaml b/yamls/jp/code.yaml
index 1ad1abb..d66f54f 100644
--- a/yamls/jp/code.yaml
+++ b/yamls/jp/code.yaml
@@ -129,13 +129,13 @@
- [0x7206E0, asm, code/7206E0]
- [0x720B20, asm, code/720B20]
- [0x720F70, asm, code/720F70]
- - [0x721EC0, asm, code/721EC0]
- - [0x7220C0, asm, code/7220C0]
- - [0x722310, asm, code/722310]
- - [0x722570, asm, code/722570]
- - [0x722880, asm, code/722880]
- - [0x722970, asm, code/722970]
- - [0x722AB0, asm, code/722AB0]
+ - [0x721EC0, c, code/lbrtc/lbrtc_getTime] #made-up name
+ - [0x7220C0, c, code/lbrtc/7220C0]
+ - [0x722310, c, code/lbrtc/lbrtc_setTime] #made-up name
+ - [0x722570, c, code/lbrtc/722570]
+ - [0x722880, c, code/lbrtc/722880]
+ - [0x722970, c, code/lbrtc/lbrtc_init] #made-up name
+ - [0x722AB0, c, code/lbrtc/722AB0]
- [0x723010, data, code/rsp/723010]
@@ -199,6 +199,7 @@
- [0x7339F0, .data, code/sys_ucode]
- [0x733A00, .data, code/zurumode]
- [0x733A10, data, code/733A10]
+ - [0x739D60, .data, code/lbrtc/lbrtc_init]
- [0x739DB0, .rodata, code/c_keyframe]
- [0x739E00, .rodata, code/m_all_grow]
@@ -317,3 +318,4 @@
- { start: 0x73F4D0, type: bss, vram: 0x801462C0, name: code/801462C0 }
- { start: 0x73F4D0, type: .bss, vram: 0x801492C0, name: code/zurumode }
- { start: 0x73F4D0, type: bss, vram: 0x801492D0, name: code/801492D0 }
+ - { start: 0x73F4D0, type: .bss, vram: 0x80152480, name: code/lbrtc/722570}