diff options
| author | Prakxo <87568477+Prakxo@users.noreply.github.com> | 2024-07-01 17:02:29 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-01 08:02:29 -0700 |
| commit | 0e66d077f8cf321c3f11978f531502ec592c0cdb (patch) | |
| tree | f726b2a6bfcca0e45d5cacc9604dbcaaf5e197df | |
| parent | 235b6575c208667fa39592bfe0c885c3ca006595 (diff) | |
lbrtc OK (#196)
* lbrtc OK
* format
* names
* format 2
* review + docs
* format
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | include/code_variables.h | 3 | ||||
| -rw-r--r-- | include/lb_rtc.h | 12 | ||||
| -rw-r--r-- | include/lbrtc.h | 103 | ||||
| -rw-r--r-- | include/m_all_grow.h | 6 | ||||
| -rw-r--r-- | linker_scripts/jp/symbol_addrs_code.txt | 15 | ||||
| -rw-r--r-- | src/code/lb_rtc.c | 17 | ||||
| -rw-r--r-- | src/code/lbrtc/7220C0.c | 72 | ||||
| -rw-r--r-- | src/code/lbrtc/722570.c | 78 | ||||
| -rw-r--r-- | src/code/lbrtc/722880.c | 26 | ||||
| -rw-r--r-- | src/code/lbrtc/722AB0.c | 120 | ||||
| -rw-r--r-- | src/code/lbrtc/lbrtc_getTime.c | 31 | ||||
| -rw-r--r-- | src/code/lbrtc/lbrtc_init.c | 33 | ||||
| -rw-r--r-- | src/code/lbrtc/lbrtc_setTime.c | 41 | ||||
| -rw-r--r-- | src/overlays/gamestates/ovl_select/m_select.h | 4 | ||||
| -rw-r--r-- | yamls/jp/code.yaml | 16 |
16 files changed, 537 insertions, 44 deletions
@@ -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} |
