summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYamaArashi <shadow962@live.com>2016-02-01 02:09:10 -0800
committerYamaArashi <shadow962@live.com>2016-02-01 02:09:10 -0800
commit6f965a9eca507c27049fbd90a57f620b63c92d6d (patch)
tree4abd3f69ee39faea15a2aa52dd5a0a091d18e3d9
parent32ec0474b05b36e6b0ad0354ae0e91a3b69f5bc5 (diff)
librtc
-rw-r--r--Makefile2
-rw-r--r--asm/rom.s108
-rw-r--r--include/global.h4
-rw-r--r--iwram_syms.txt2
-rw-r--r--ld_script.txt1
-rw-r--r--src/librtc.c406
-rw-r--r--src/play_time.c1
7 files changed, 468 insertions, 56 deletions
diff --git a/Makefile b/Makefile
index 0864d959f..6175c5cd3 100644
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,8 @@ include tilesets.mk
$(OBJS): $(CSRCS:src/%.c=genasm/%.s)
+genasm/librtc.s: CFLAGS := -mthumb-interwork -Iinclude
+
# TODO: fix this .syntax hack
genasm/prefix.tmp:
diff --git a/asm/rom.s b/asm/rom.s
index f98d7cd5d..913d13834 100644
--- a/asm/rom.s
+++ b/asm/rom.s
@@ -18378,8 +18378,8 @@ _080090EC: .4byte 0x00000fbc
_080090F0: .4byte 0x0000efff
thumb_func_end sub_8009084
- thumb_func_start GameFreakRTC_ClearIME
-GameFreakRTC_ClearIME: ; 80090F4
+ thumb_func_start GFRTC_DisableInterrupts
+GFRTC_DisableInterrupts: ; 80090F4
ldr r2, _08009104
ldr r1, _08009108
ldrh r0, [r1]
@@ -18390,10 +18390,10 @@ GameFreakRTC_ClearIME: ; 80090F4
.align 2
_08009104: .4byte 0x0300046e
_08009108: .4byte 0x04000208
- thumb_func_end GameFreakRTC_ClearIME
+ thumb_func_end GFRTC_DisableInterrupts
- thumb_func_start sub_800910C
-sub_800910C: ; 800910C
+ thumb_func_start GFRTC_RestoreInterrupts
+GFRTC_RestoreInterrupts: ; 800910C
ldr r0, _08009118
ldr r1, _0800911C
ldrh r1, [r1]
@@ -18402,10 +18402,10 @@ sub_800910C: ; 800910C
.align 2
_08009118: .4byte 0x04000208
_0800911C: .4byte 0x0300046e
- thumb_func_end sub_800910C
+ thumb_func_end GFRTC_RestoreInterrupts
- thumb_func_start GameFreakRTC_ConvertFromBCD
-GameFreakRTC_ConvertFromBCD: ; 8009120
+ thumb_func_start GFRTC_ConvertBcdToBinary
+GFRTC_ConvertBcdToBinary: ; 8009120
push {lr}
lsls r0, 24
lsrs r2, r0, 24
@@ -18429,10 +18429,10 @@ _08009136:
_08009144:
pop {r1}
bx r1
- thumb_func_end GameFreakRTC_ConvertFromBCD
+ thumb_func_end GFRTC_ConvertBcdToBinary
- thumb_func_start GameFreakRTC_IsLeapYear
-GameFreakRTC_IsLeapYear: ; 8009148
+ thumb_func_start GFRTC_IsLeapYear
+GFRTC_IsLeapYear: ; 8009148
push {r4,lr}
lsls r0, 24
lsrs r1, r0, 24
@@ -18463,10 +18463,10 @@ _0800917A:
pop {r4}
pop {r1}
bx r1
- thumb_func_end GameFreakRTC_IsLeapYear
+ thumb_func_end GFRTC_IsLeapYear
- thumb_func_start GameFreakRTC_ConvertYearMonthDayToNumDays
-GameFreakRTC_ConvertYearMonthDayToNumDays: ; 8009180
+ thumb_func_start GFRTC_ConvertYmdToDayCount
+GFRTC_ConvertYmdToDayCount: ; 8009180
push {r4-r7,lr}
mov r7, r8
push {r7}
@@ -18488,7 +18488,7 @@ _0800919C:
lsrs r5, r0, 16
lsls r0, r4, 24
lsrs r0, 24
- bl GameFreakRTC_IsLeapYear
+ bl GFRTC_IsLeapYear
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
@@ -18518,7 +18518,7 @@ _080091D8:
cmp r6, 0x2
bls _080091F0
adds r0, r7, 0
- bl GameFreakRTC_IsLeapYear
+ bl GFRTC_IsLeapYear
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
@@ -18540,36 +18540,36 @@ _080091F0:
.align 2
_08009204: .4byte 0x0000016d
_08009208: .4byte gUnknown_081E761C
- thumb_func_end GameFreakRTC_ConvertYearMonthDayToNumDays
+ thumb_func_end GFRTC_ConvertYmdToDayCount
- thumb_func_start GameFreakRTC_GetNumDaysInternal
-GameFreakRTC_GetNumDaysInternal: ; 800920C
+ thumb_func_start GFRTC_GetDayCount
+GFRTC_GetDayCount: ; 800920C
push {r4-r6,lr}
adds r6, r0, 0
ldrb r0, [r6]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r5, r0, 0
lsls r5, 24
lsrs r5, 24
ldrb r0, [r6, 0x1]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r4, r0, 0
lsls r4, 24
lsrs r4, 24
ldrb r0, [r6, 0x2]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r2, r0, 0
lsls r2, 24
lsrs r2, 24
adds r0, r5, 0
adds r1, r4, 0
- bl GameFreakRTC_ConvertYearMonthDayToNumDays
+ bl GFRTC_ConvertYmdToDayCount
lsls r0, 16
lsrs r0, 16
pop {r4-r6}
pop {r1}
bx r1
- thumb_func_end GameFreakRTC_GetNumDaysInternal
+ thumb_func_end GFRTC_GetDayCount
thumb_func_start GameFreakRTC_Init
GameFreakRTC_Init: ; 8009248
@@ -18577,12 +18577,12 @@ GameFreakRTC_Init: ; 8009248
ldr r5, _08009274
movs r0, 0
strh r0, [r5]
- bl GameFreakRTC_ClearIME
+ bl GFRTC_DisableInterrupts
bl RTC_SetReadWrite
bl RTC_Init
ldr r4, _08009278
strb r0, [r4]
- bl sub_800910C
+ bl GFRTC_RestoreInterrupts
ldrb r4, [r4]
movs r0, 0xF
ands r0, r4
@@ -18604,9 +18604,9 @@ _08009286:
strh r0, [r5]
ldr r4, _080092A0
adds r0, r4, 0
- bl GameFreakRTC_GetControlRegAndRTCDateTime
+ bl GFRTC_GetControlRegAndRtcDateTime
adds r0, r4, 0
- bl GameFreakRTC_TestForErrors
+ bl GFRTC_TestForErrors
ldr r1, _080092A4
strh r0, [r1]
_0800929A:
@@ -18648,7 +18648,7 @@ _080092D0: .4byte 0x03000458
_080092D4: .4byte gUnknown_081E7610
_080092D8:
adds r0, r2, 0
- bl GameFreakRTC_GetControlRegAndRTCDateTime
+ bl GFRTC_GetControlRegAndRtcDateTime
_080092DE:
pop {r4}
pop {r0}
@@ -18659,10 +18659,10 @@ _080092DE:
GameFreakRTC_GetRTCDateTimeInternal: ; 80092E4
push {r4,lr}
adds r4, r0, 0
- bl GameFreakRTC_ClearIME
+ bl GFRTC_DisableInterrupts
adds r0, r4, 0
bl RTC_GetDateTime
- bl sub_800910C
+ bl GFRTC_RestoreInterrupts
pop {r4}
pop {r0}
bx r0
@@ -18672,17 +18672,17 @@ GameFreakRTC_GetRTCDateTimeInternal: ; 80092E4
GameFreakRTC_GetControlReg: ; 80092FC
push {r4,lr}
adds r4, r0, 0
- bl GameFreakRTC_ClearIME
+ bl GFRTC_DisableInterrupts
adds r0, r4, 0
bl RTC_GetControlReg
- bl sub_800910C
+ bl GFRTC_RestoreInterrupts
pop {r4}
pop {r0}
bx r0
thumb_func_end GameFreakRTC_GetControlReg
- thumb_func_start GameFreakRTC_GetControlRegAndRTCDateTime
-GameFreakRTC_GetControlRegAndRTCDateTime: ; 8009314
+ thumb_func_start GFRTC_GetControlRegAndRtcDateTime
+GFRTC_GetControlRegAndRtcDateTime: ; 8009314
push {r4,lr}
adds r4, r0, 0
bl GameFreakRTC_GetControlReg
@@ -18691,10 +18691,10 @@ GameFreakRTC_GetControlRegAndRTCDateTime: ; 8009314
pop {r4}
pop {r0}
bx r0
- thumb_func_end GameFreakRTC_GetControlRegAndRTCDateTime
+ thumb_func_end GFRTC_GetControlRegAndRtcDateTime
- thumb_func_start GameFreakRTC_TestForErrors
-GameFreakRTC_TestForErrors: ; 8009328
+ thumb_func_start GFRTC_TestForErrors
+GFRTC_TestForErrors: ; 8009328
push {r4-r7,lr}
mov r7, r8
push {r7}
@@ -18716,7 +18716,7 @@ GameFreakRTC_TestForErrors: ; 8009328
orrs r4, r0
_0800934E:
ldrb r0, [r7]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
mov r8, r0
cmp r0, 0xFF
bne _08009362
@@ -18726,7 +18726,7 @@ _0800934E:
lsrs r4, r0, 16
_08009362:
ldrb r0, [r7, 0x1]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r6, r0, 0
cmp r6, 0xFF
beq _08009376
@@ -18741,7 +18741,7 @@ _08009376:
lsrs r4, r0, 16
_0800937E:
ldrb r0, [r7, 0x2]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r5, r0, 0
cmp r5, 0xFF
bne _08009396
@@ -18757,7 +18757,7 @@ _08009396:
mov r1, r8
lsls r0, r1, 24
lsrs r0, 24
- bl GameFreakRTC_IsLeapYear
+ bl GFRTC_IsLeapYear
lsls r0, 24
lsrs r0, 24
ldr r1, _080093B0
@@ -18783,7 +18783,7 @@ _080093BE:
lsrs r4, r0, 16
_080093CE:
ldrb r0, [r7, 0x4]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r5, r0, 0
cmp r5, 0x18
ble _080093E6
@@ -18795,7 +18795,7 @@ _080093CE:
lsrs r4, r0, 16
_080093E6:
ldrb r0, [r7, 0x5]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r5, r0, 0
cmp r5, 0x3C
ble _080093FE
@@ -18807,7 +18807,7 @@ _080093E6:
lsrs r4, r0, 16
_080093FE:
ldrb r0, [r7, 0x6]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
adds r5, r0, 0
cmp r5, 0x3C
ble _08009416
@@ -18826,14 +18826,14 @@ _08009416:
bx r1
.align 2
_08009424: .4byte gUnknown_081E761C
- thumb_func_end GameFreakRTC_TestForErrors
+ thumb_func_end GFRTC_TestForErrors
thumb_func_start sub_8009428
sub_8009428: ; 8009428
push {lr}
- bl GameFreakRTC_ClearIME
+ bl GFRTC_DisableInterrupts
bl RTC_Reset
- bl sub_800910C
+ bl GFRTC_RestoreInterrupts
pop {r0}
bx r0
thumb_func_end sub_8009428
@@ -18970,22 +18970,22 @@ GameFreakRTC_GetRTCDelta: ; 8009534
adds r5, r0, 0
adds r7, r1, 0
adds r6, r2, 0
- bl GameFreakRTC_GetNumDaysInternal
+ bl GFRTC_GetDayCount
adds r4, r0, 0
lsls r4, 16
lsrs r4, 16
ldrb r0, [r5, 0x6]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
ldrb r1, [r6, 0x4]
subs r0, r1
strb r0, [r7, 0x4]
ldrb r0, [r5, 0x5]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
ldrb r1, [r6, 0x3]
subs r0, r1
strb r0, [r7, 0x3]
ldrb r0, [r5, 0x4]
- bl GameFreakRTC_ConvertFromBCD
+ bl GFRTC_ConvertBcdToBinary
ldrb r1, [r6, 0x2]
subs r0, r1
strb r0, [r7, 0x2]
@@ -19154,7 +19154,7 @@ GameFreakRTC_GetNumMinutes: ; 800968C
adds r0, r4, 0
bl GameFreakRTC_GetRTCDateTime
adds r0, r4, 0
- bl GameFreakRTC_GetNumDaysInternal
+ bl GFRTC_GetDayCount
lsls r0, 16
lsrs r0, 16
lsls r1, r0, 1
@@ -678074,7 +678074,7 @@ _0814AE2C: .4byte gUnknown_0842F6C0
.include "asm/libgcnmultiboot.s"
.include "asm/libmks4agb.s"
.include "asm/libagbbackup.s"
- .include "asm/librtc.s"
+ .include "genasm/librtc.s"
.include "asm/libagbsyscall.s"
.include "asm/libgcc.s"
.include "data/data2.s"
diff --git a/include/global.h b/include/global.h
index fec0500f7..0c7fef66e 100644
--- a/include/global.h
+++ b/include/global.h
@@ -1,6 +1,8 @@
#ifndef GUARD_GLOBAL_H
#define GUARD_GLOBAL_H
+#include <stddef.h>
+
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
@@ -22,8 +24,6 @@ typedef u8 bool8;
typedef u16 bool16;
typedef u32 bool32;
-#define NULL (void *)0
-
#define TRUE 1
#define FALSE 0
diff --git a/iwram_syms.txt b/iwram_syms.txt
index 96d059ec9..cbcd2de7b 100644
--- a/iwram_syms.txt
+++ b/iwram_syms.txt
@@ -1,3 +1,5 @@
gPlayTimeCounterState = 0x300057C;
+gRtcLocked = 0x3000F36;
+
gUnknownStringVar = 0x3002900;
diff --git a/ld_script.txt b/ld_script.txt
index 48982d49d..30ef0fa11 100644
--- a/ld_script.txt
+++ b/ld_script.txt
@@ -3,4 +3,5 @@ ENTRY(Start)
SECTIONS {
. = 0x8000000;
.text : { *(.text); }
+ /DISCARD/ : { *(.rodata) }
}
diff --git a/src/librtc.c b/src/librtc.c
new file mode 100644
index 000000000..a64c5af89
--- /dev/null
+++ b/src/librtc.c
@@ -0,0 +1,406 @@
+#include "global.h"
+
+struct RtcInfo
+{
+ u8 year;
+ u8 month;
+ u8 dayOfMonth;
+ u8 dayOfWeek;
+ u8 hour;
+ u8 minute;
+ u8 second;
+ u8 control;
+ u8 unknown1;
+ u8 unknown2;
+};
+
+#define OFFSET_YEAR offsetof(struct RtcInfo, year)
+#define OFFSET_MONTH offsetof(struct RtcInfo, month)
+#define OFFSET_DAY_OF_MONTH offsetof(struct RtcInfo, dayOfMonth)
+#define OFFSET_DAY_OF_WEEK offsetof(struct RtcInfo, dayOfWeek)
+#define OFFSET_HOUR offsetof(struct RtcInfo, hour)
+#define OFFSET_MINUTE offsetof(struct RtcInfo, minute)
+#define OFFSET_SECOND offsetof(struct RtcInfo, second)
+#define OFFSET_CONTROL offsetof(struct RtcInfo, control)
+#define OFFSET_UNKNOWN1 offsetof(struct RtcInfo, unknown1)
+#define OFFSET_UNKNOWN2 offsetof(struct RtcInfo, unknown2)
+
+#define RTC_BUF(info, index) (*((u8 *)(info) + (index)))
+
+#define RTC_DATETIME_BUF(info, index) (*((u8 *)(info) + OFFSET_YEAR + (index)))
+#define RTC_DATETIME_BUF_LEN (OFFSET_SECOND - OFFSET_YEAR + 1)
+
+#define RTC_TIME_BUF(info, index) (*((u8 *)(info) + OFFSET_HOUR + (index)))
+#define RTC_TIME_BUF_LEN (OFFSET_SECOND - OFFSET_HOUR + 1)
+
+extern vu16 GPIOPortData;
+extern vu16 GPIOPortDirection;
+extern vu16 GPIOPortReadWrite;
+
+extern bool8 gRtcLocked;
+
+void RTC_SetReadWrite();
+void RTC_SetReadOnly();
+u8 RTC_Init();
+bool8 RTC_Reset();
+bool8 RTC_GetControlReg(struct RtcInfo *rtc);
+bool8 RTC_SetControlReg(struct RtcInfo *rtc);
+bool8 RTC_GetDateTime(struct RtcInfo *rtc);
+bool8 RTC_SetDateTime(struct RtcInfo *rtc);
+bool8 RTC_GetTime(struct RtcInfo *rtc);
+bool8 RTC_SetTime(struct RtcInfo *rtc);
+bool8 RTC_SetUnknownData(struct RtcInfo *rtc);
+s32 RTC_WriteByte(u8 value);
+s32 RTC_WriteByteReversed(u8 value);
+u8 RTC_ReadByte();
+void RTC_SetReadWriteInternal();
+void RTC_SetReadOnlyInternal();
+
+void RTC_SetReadWrite()
+{
+ RTC_SetReadWriteInternal();
+ gRtcLocked = FALSE;
+}
+
+void RTC_SetReadOnly()
+{
+ RTC_SetReadOnlyInternal();
+ gRtcLocked = TRUE;
+}
+
+u8 RTC_Init()
+{
+ u8 v2;
+ struct RtcInfo rtc;
+
+ if (!RTC_GetControlReg(&rtc))
+ return 0;
+
+ v2 = 0;
+
+ if ((rtc.control & 0xC0) == 0x80 || !(rtc.control & 0xC0))
+ {
+ if (!RTC_Reset())
+ return 0;
+
+ v2++;
+ }
+
+ RTC_GetTime(&rtc);
+
+ if (rtc.second & 0x80)
+ {
+ if (!RTC_Reset())
+ return (v2 << 4) & 0xF0;
+
+ v2++;
+ }
+
+ return (v2 << 4) | 1;
+}
+
+bool8 RTC_Reset()
+{
+ u8 result;
+ struct RtcInfo rtc;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x60);
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ rtc.control = 0x40;
+
+ result = RTC_SetControlReg(&rtc);
+
+ return result;
+}
+
+bool8 RTC_GetControlReg(struct RtcInfo *rtc)
+{
+ u8 controlData;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x63);
+
+ GPIOPortDirection = 5;
+
+ controlData = RTC_ReadByte();
+
+ rtc->control = (controlData & 0xC0) | ((controlData & 0x20) >> 3) | ((controlData & 8) >> 2) | ((controlData & 2) >> 1);
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+bool8 RTC_SetControlReg(struct RtcInfo *rtc)
+{
+ u8 controlData;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ controlData = ((rtc->control & 4) << 3) | (1 << 6) | ((rtc->control & 2) << 2) | ((rtc->control & 1) << 1);
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x62);
+
+ RTC_WriteByteReversed(controlData);
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+bool8 RTC_GetDateTime(struct RtcInfo *rtc)
+{
+ u8 i;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x65);
+
+ GPIOPortDirection = 5;
+
+ for (i = 0; i < RTC_DATETIME_BUF_LEN; i++)
+ RTC_DATETIME_BUF(rtc, i) = RTC_ReadByte();
+
+ RTC_BUF(rtc, OFFSET_HOUR) &= 0x7F;
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+bool8 RTC_SetDateTime(struct RtcInfo *rtc)
+{
+ u8 i;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x64);
+
+ for (i = 0; i < RTC_DATETIME_BUF_LEN; i++)
+ RTC_WriteByteReversed(RTC_DATETIME_BUF(rtc, i));
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+bool8 RTC_GetTime(struct RtcInfo *rtc)
+{
+ u8 i;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x67);
+
+ GPIOPortDirection = 5;
+
+ for (i = 0; i < RTC_TIME_BUF_LEN; i++)
+ RTC_TIME_BUF(rtc, i) = RTC_ReadByte();
+
+ RTC_BUF(rtc, OFFSET_HOUR) &= 0x7F;
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+bool8 RTC_SetTime(struct RtcInfo *rtc)
+{
+ u8 i;
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x66);
+
+ for (i = 0; i < RTC_TIME_BUF_LEN; i++)
+ RTC_WriteByteReversed(RTC_TIME_BUF(rtc, i));
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+bool8 RTC_SetUnknownData(struct RtcInfo *rtc)
+{
+ u8 i;
+ u8 a[2];
+
+ if (gRtcLocked == TRUE)
+ return FALSE;
+
+ gRtcLocked = TRUE;
+
+ a[0] = ((rtc->unknown1 & 0xF) + 10 * ((rtc->unknown1 >> 4) & 0xF));
+
+ if (a[0] <= 0xB)
+ a[0] = rtc->unknown1;
+ else
+ a[0] = rtc->unknown1 | 0x80;
+
+ a[1] = rtc->unknown2;
+
+ GPIOPortData = 1;
+ GPIOPortData = 5;
+
+ GPIOPortDirection = 7;
+
+ RTC_WriteByte(0x68);
+
+ for (i = 0; i < 2; i++)
+ RTC_WriteByteReversed(a[i]);
+
+ GPIOPortData = 1;
+ GPIOPortData = 1;
+
+ gRtcLocked = FALSE;
+
+ return TRUE;
+}
+
+s32 RTC_WriteByte(u8 value)
+{
+ u8 i;
+ u8 temp;
+
+ for (i = 0; i < 8; i++)
+ {
+ temp = ((value >> (7 - i)) & 1);
+ GPIOPortData = (temp << 1) | 4;
+ GPIOPortData = (temp << 1) | 4;
+ GPIOPortData = (temp << 1) | 4;
+ GPIOPortData = (temp << 1) | 5;
+ }
+
+ // control reaches end of non-void function
+}
+
+s32 RTC_WriteByteReversed(u8 value)
+{
+ u8 i;
+ u8 temp;
+
+ for (i = 0; i < 8; i++)
+ {
+ temp = ((value >> i) & 1);
+ GPIOPortData = (temp << 1) | 4;
+ GPIOPortData = (temp << 1) | 4;
+ GPIOPortData = (temp << 1) | 4;
+ GPIOPortData = (temp << 1) | 5;
+ }
+
+ // control reaches end of non-void function
+}
+
+u8 RTC_ReadByte()
+{
+ u8 i;
+ u8 temp;
+ u8 value;
+
+ for (i = 0; i < 8; i++)
+ {
+ GPIOPortData = 4;
+ GPIOPortData = 4;
+ GPIOPortData = 4;
+ GPIOPortData = 4;
+ GPIOPortData = 4;
+ GPIOPortData = 5;
+
+ temp = ((GPIOPortData & 2) >> 1);
+ value = (value >> 1) | (temp << 7); // UB: accessing uninitialized var
+ }
+
+ return value;
+}
+
+void RTC_SetReadWriteInternal()
+{
+ GPIOPortReadWrite = 1;
+}
+
+void RTC_SetReadOnlyInternal()
+{
+ GPIOPortReadWrite = 0;
+}
diff --git a/src/play_time.c b/src/play_time.c
index 69633ca48..f950e31a5 100644
--- a/src/play_time.c
+++ b/src/play_time.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "play_time.h"
enum
{