summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYamaArashi <shadow962@live.com>2016-02-03 00:26:25 -0800
committerYamaArashi <shadow962@live.com>2016-02-03 00:26:25 -0800
commit5fd538d1802b2ae9e3e854140f68cb45fe50e97a (patch)
treea7d3cc4b70435a6cc4a94b4497307393d743f28d /src
parent6f965a9eca507c27049fbd90a57f620b63c92d6d (diff)
RTC code/data
Diffstat (limited to 'src')
-rw-r--r--src/librtc.c174
-rw-r--r--src/rtc_util.c335
-rw-r--r--src/string_util.c7
3 files changed, 423 insertions, 93 deletions
diff --git a/src/librtc.c b/src/librtc.c
index a64c5af89..b87862a8f 100644
--- a/src/librtc.c
+++ b/src/librtc.c
@@ -1,29 +1,22 @@
-#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)
+#include "gba/gba.h"
+#include "rtc.h"
+
+#define RTC_CTRL_UNK1 0x02 // unknown
+#define RTC_CTRL_IRQ_ENABLE 0x08 // per-minute IRQ enable
+#define RTC_CTRL_UNK2 0x20 // unknown
+#define RTC_CTRL_24HOUR 0x40 // 0: 12-hour mode, 1: 24-hour mode
+#define RTC_CTRL_POWER_FAILURE 0x80 // power failure occurred
+
+#define OFFSET_YEAR offsetof(struct RtcInfo, year)
+#define OFFSET_MONTH offsetof(struct RtcInfo, month)
+#define OFFSET_DAY offsetof(struct RtcInfo, day)
+#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)))
@@ -33,57 +26,56 @@ struct RtcInfo
#define RTC_TIME_BUF(info, index) (*((u8 *)(info) + OFFSET_HOUR + (index)))
#define RTC_TIME_BUF_LEN (OFFSET_SECOND - OFFSET_HOUR + 1)
+#define RTC_CMD_RESET 0x60
+#define RTC_CMD_WR_CONTROL 0x62
+#define RTC_CMD_RD_CONTROL 0x63
+#define RTC_CMD_WR_DATETIME 0x64
+#define RTC_CMD_RD_DATETIME 0x65
+#define RTC_CMD_WR_TIME 0x66
+#define RTC_CMD_RD_TIME 0x67
+#define RTC_CMD_WR_UNKNOWN 0x68
+
extern vu16 GPIOPortData;
extern vu16 GPIOPortDirection;
-extern vu16 GPIOPortReadWrite;
+extern vu16 GPIOPortReadEnable;
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()
+s32 RTC_WriteCommand(u8 value);
+s32 RTC_WriteData(u8 value);
+u8 RTC_ReadData();
+void RTC_EnableGpioPortRead();
+void RTC_DisableGpioPortRead();
+
+void RTC_Unprotect()
{
- RTC_SetReadWriteInternal();
+ RTC_EnableGpioPortRead();
gRtcLocked = FALSE;
}
-void RTC_SetReadOnly()
+void RTC_Protect()
{
- RTC_SetReadOnlyInternal();
+ RTC_DisableGpioPortRead();
gRtcLocked = TRUE;
}
-u8 RTC_Init()
+u8 RTC_Probe()
{
- u8 v2;
+ u8 errorCode;
struct RtcInfo rtc;
- if (!RTC_GetControlReg(&rtc))
+ if (!RTC_GetControl(&rtc))
return 0;
- v2 = 0;
+ errorCode = 0;
- if ((rtc.control & 0xC0) == 0x80 || !(rtc.control & 0xC0))
+ if ((rtc.control & (RTC_INFO_CTRL_POWER_FAILURE | RTC_INFO_CTRL_24HOUR)) == RTC_INFO_CTRL_POWER_FAILURE
+ || (rtc.control & (RTC_INFO_CTRL_POWER_FAILURE | RTC_INFO_CTRL_24HOUR)) == 0)
{
if (!RTC_Reset())
return 0;
- v2++;
+ errorCode++;
}
RTC_GetTime(&rtc);
@@ -91,12 +83,12 @@ u8 RTC_Init()
if (rtc.second & 0x80)
{
if (!RTC_Reset())
- return (v2 << 4) & 0xF0;
+ return (errorCode << 4) & 0xF0;
- v2++;
+ errorCode++;
}
- return (v2 << 4) | 1;
+ return (errorCode << 4) | 1;
}
bool8 RTC_Reset()
@@ -114,21 +106,21 @@ bool8 RTC_Reset()
GPIOPortDirection = 7;
- RTC_WriteByte(0x60);
+ RTC_WriteCommand(RTC_CMD_RESET);
GPIOPortData = 1;
GPIOPortData = 1;
gRtcLocked = FALSE;
- rtc.control = 0x40;
+ rtc.control = RTC_INFO_CTRL_24HOUR;
- result = RTC_SetControlReg(&rtc);
+ result = RTC_SetControl(&rtc);
return result;
}
-bool8 RTC_GetControlReg(struct RtcInfo *rtc)
+bool8 RTC_GetControl(struct RtcInfo *rtc)
{
u8 controlData;
@@ -142,13 +134,16 @@ bool8 RTC_GetControlReg(struct RtcInfo *rtc)
GPIOPortDirection = 7;
- RTC_WriteByte(0x63);
+ RTC_WriteCommand(RTC_CMD_RD_CONTROL);
GPIOPortDirection = 5;
- controlData = RTC_ReadByte();
+ controlData = RTC_ReadData();
- rtc->control = (controlData & 0xC0) | ((controlData & 0x20) >> 3) | ((controlData & 8) >> 2) | ((controlData & 2) >> 1);
+ rtc->control = (controlData & (RTC_CTRL_POWER_FAILURE | RTC_CTRL_24HOUR))
+ | ((controlData & RTC_CTRL_UNK2) >> 3)
+ | ((controlData & RTC_CTRL_IRQ_ENABLE) >> 2)
+ | ((controlData & RTC_CTRL_UNK1) >> 1);
GPIOPortData = 1;
GPIOPortData = 1;
@@ -158,7 +153,7 @@ bool8 RTC_GetControlReg(struct RtcInfo *rtc)
return TRUE;
}
-bool8 RTC_SetControlReg(struct RtcInfo *rtc)
+bool8 RTC_SetControl(struct RtcInfo *rtc)
{
u8 controlData;
@@ -170,13 +165,16 @@ bool8 RTC_SetControlReg(struct RtcInfo *rtc)
GPIOPortData = 1;
GPIOPortData = 5;
- controlData = ((rtc->control & 4) << 3) | (1 << 6) | ((rtc->control & 2) << 2) | ((rtc->control & 1) << 1);
+ controlData = RTC_CTRL_24HOUR
+ | ((rtc->control & RTC_INFO_CTRL_UNK2) << 3)
+ | ((rtc->control & RTC_INFO_CTRL_IRQ_ENABLE) << 2)
+ | ((rtc->control & RTC_INFO_CTRL_UNK1) << 1);
GPIOPortDirection = 7;
- RTC_WriteByte(0x62);
+ RTC_WriteCommand(RTC_CMD_WR_CONTROL);
- RTC_WriteByteReversed(controlData);
+ RTC_WriteData(controlData);
GPIOPortData = 1;
GPIOPortData = 1;
@@ -200,12 +198,12 @@ bool8 RTC_GetDateTime(struct RtcInfo *rtc)
GPIOPortDirection = 7;
- RTC_WriteByte(0x65);
+ RTC_WriteCommand(RTC_CMD_RD_DATETIME);
GPIOPortDirection = 5;
for (i = 0; i < RTC_DATETIME_BUF_LEN; i++)
- RTC_DATETIME_BUF(rtc, i) = RTC_ReadByte();
+ RTC_DATETIME_BUF(rtc, i) = RTC_ReadData();
RTC_BUF(rtc, OFFSET_HOUR) &= 0x7F;
@@ -231,10 +229,10 @@ bool8 RTC_SetDateTime(struct RtcInfo *rtc)
GPIOPortDirection = 7;
- RTC_WriteByte(0x64);
+ RTC_WriteCommand(RTC_CMD_WR_DATETIME);
for (i = 0; i < RTC_DATETIME_BUF_LEN; i++)
- RTC_WriteByteReversed(RTC_DATETIME_BUF(rtc, i));
+ RTC_WriteData(RTC_DATETIME_BUF(rtc, i));
GPIOPortData = 1;
GPIOPortData = 1;
@@ -258,12 +256,12 @@ bool8 RTC_GetTime(struct RtcInfo *rtc)
GPIOPortDirection = 7;
- RTC_WriteByte(0x67);
+ RTC_WriteCommand(RTC_CMD_RD_TIME);
GPIOPortDirection = 5;
for (i = 0; i < RTC_TIME_BUF_LEN; i++)
- RTC_TIME_BUF(rtc, i) = RTC_ReadByte();
+ RTC_TIME_BUF(rtc, i) = RTC_ReadData();
RTC_BUF(rtc, OFFSET_HOUR) &= 0x7F;
@@ -289,10 +287,10 @@ bool8 RTC_SetTime(struct RtcInfo *rtc)
GPIOPortDirection = 7;
- RTC_WriteByte(0x66);
+ RTC_WriteCommand(RTC_CMD_WR_TIME);
for (i = 0; i < RTC_TIME_BUF_LEN; i++)
- RTC_WriteByteReversed(RTC_TIME_BUF(rtc, i));
+ RTC_WriteData(RTC_TIME_BUF(rtc, i));
GPIOPortData = 1;
GPIOPortData = 1;
@@ -312,9 +310,13 @@ bool8 RTC_SetUnknownData(struct RtcInfo *rtc)
gRtcLocked = TRUE;
+ // unknown1 appears to be a BCD number in the range 0-11,
+ // so it may be an hour in 12-hour format.
+ // Months are normally 1-12.
+
a[0] = ((rtc->unknown1 & 0xF) + 10 * ((rtc->unknown1 >> 4) & 0xF));
- if (a[0] <= 0xB)
+ if (a[0] < 12)
a[0] = rtc->unknown1;
else
a[0] = rtc->unknown1 | 0x80;
@@ -326,10 +328,10 @@ bool8 RTC_SetUnknownData(struct RtcInfo *rtc)
GPIOPortDirection = 7;
- RTC_WriteByte(0x68);
+ RTC_WriteCommand(RTC_CMD_WR_UNKNOWN);
for (i = 0; i < 2; i++)
- RTC_WriteByteReversed(a[i]);
+ RTC_WriteData(a[i]);
GPIOPortData = 1;
GPIOPortData = 1;
@@ -339,7 +341,7 @@ bool8 RTC_SetUnknownData(struct RtcInfo *rtc)
return TRUE;
}
-s32 RTC_WriteByte(u8 value)
+s32 RTC_WriteCommand(u8 value)
{
u8 i;
u8 temp;
@@ -356,7 +358,7 @@ s32 RTC_WriteByte(u8 value)
// control reaches end of non-void function
}
-s32 RTC_WriteByteReversed(u8 value)
+s32 RTC_WriteData(u8 value)
{
u8 i;
u8 temp;
@@ -373,7 +375,7 @@ s32 RTC_WriteByteReversed(u8 value)
// control reaches end of non-void function
}
-u8 RTC_ReadByte()
+u8 RTC_ReadData()
{
u8 i;
u8 temp;
@@ -395,12 +397,12 @@ u8 RTC_ReadByte()
return value;
}
-void RTC_SetReadWriteInternal()
+void RTC_EnableGpioPortRead()
{
- GPIOPortReadWrite = 1;
+ GPIOPortReadEnable = 1;
}
-void RTC_SetReadOnlyInternal()
+void RTC_DisableGpioPortRead()
{
- GPIOPortReadWrite = 0;
+ GPIOPortReadEnable = 0;
}
diff --git a/src/rtc_util.c b/src/rtc_util.c
new file mode 100644
index 000000000..b279ec753
--- /dev/null
+++ b/src/rtc_util.c
@@ -0,0 +1,335 @@
+#include "global.h"
+#include "rtc.h"
+#include "rtc_util.h"
+#include "string_util.h"
+
+extern const struct RtcInfo gDefaultRtcInfo;
+extern const s32 gNumDaysInMonths[];
+
+extern u16 gRtcErrorFlags;
+extern struct RtcInfo gRtcInfo;
+extern u8 gRtcProbeResult;
+extern u16 gRtcSavedIme;
+
+extern struct Time gLocalTime;
+
+void RtcDisableInterrupts();
+void RtcRestoreInterrupts();
+u32 ConvertBcdToBinary(u8 bcd);
+bool8 IsLeapYear(u8 year);
+u16 ConvertDateToDayCount(u8 year, u8 month, u8 day);
+u16 RtcGetDayCount(struct RtcInfo *rtc);
+void RtcGetInfo(struct RtcInfo *rtc);
+void RtcGetDateTime(struct RtcInfo *rtc);
+void RtcGetControl(struct RtcInfo *rtc);
+void RtcGetRawInfo(struct RtcInfo *rtc);
+u16 RtcCheckInfo(struct RtcInfo *rtc);
+void RtcCalcTimeDifference(struct RtcInfo *rtc, struct Time *result, struct Time *t);
+
+void RtcDisableInterrupts()
+{
+ gRtcSavedIme = REG_IME;
+ REG_IME = 0;
+}
+
+void RtcRestoreInterrupts()
+{
+ REG_IME = gRtcSavedIme;
+}
+
+u32 ConvertBcdToBinary(u8 bcd)
+{
+ if (bcd > 0x9F)
+ return 0xFF;
+
+ if ((bcd & 0xF) <= 9)
+ return (10 * ((bcd >> 4) & 0xF)) + (bcd & 0xF);
+ else
+ return 0xFF;
+}
+
+bool8 IsLeapYear(u8 year)
+{
+ if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
+ return TRUE;
+
+ return FALSE;
+}
+
+u16 ConvertDateToDayCount(u8 year, u8 month, u8 day)
+{
+ s32 i;
+ u16 dayCount = 0;
+
+ for (i = year - 1; i > 0; i--)
+ {
+ dayCount += 365;
+
+ if (IsLeapYear(i) == TRUE)
+ dayCount++;
+ }
+
+ for (i = 0; i < month - 1; i++)
+ dayCount += gNumDaysInMonths[i];
+
+ if (month > MONTH_FEB && IsLeapYear(year) == TRUE)
+ dayCount++;
+
+ dayCount += day;
+
+ return dayCount;
+}
+
+u16 RtcGetDayCount(struct RtcInfo *rtc)
+{
+ u8 year = ConvertBcdToBinary(rtc->year);
+ u8 month = ConvertBcdToBinary(rtc->month);
+ u8 day = ConvertBcdToBinary(rtc->day);
+ return ConvertDateToDayCount(year, month, day);
+}
+
+void RtcInit()
+{
+ gRtcErrorFlags = 0;
+
+ RtcDisableInterrupts();
+ RTC_Unprotect();
+ gRtcProbeResult = RTC_Probe();
+ RtcRestoreInterrupts();
+
+ if (!(gRtcProbeResult & 0xF))
+ {
+ gRtcErrorFlags = 1;
+ return;
+ }
+
+ if (gRtcProbeResult & 0xF0)
+ gRtcErrorFlags = 2;
+ else
+ gRtcErrorFlags = 0;
+
+ RtcGetRawInfo(&gRtcInfo);
+ gRtcErrorFlags = RtcCheckInfo(&gRtcInfo);
+}
+
+u16 RtcGetErrorFlags()
+{
+ return gRtcErrorFlags;
+}
+
+void RtcGetInfo(struct RtcInfo *rtc)
+{
+ if (gRtcErrorFlags & 0xFF0)
+ *rtc = gDefaultRtcInfo;
+ else
+ RtcGetRawInfo(rtc);
+}
+
+void RtcGetDateTime(struct RtcInfo *rtc)
+{
+ RtcDisableInterrupts();
+ RTC_GetDateTime(rtc);
+ RtcRestoreInterrupts();
+}
+
+void RtcGetControl(struct RtcInfo *rtc)
+{
+ RtcDisableInterrupts();
+ RTC_GetControl(rtc);
+ RtcRestoreInterrupts();
+}
+
+void RtcGetRawInfo(struct RtcInfo *rtc)
+{
+ RtcGetControl(rtc);
+ RtcGetDateTime(rtc);
+}
+
+u16 RtcCheckInfo(struct RtcInfo *rtc)
+{
+ u16 errorFlags = 0;
+ s32 year;
+ s32 month;
+ s32 value;
+
+ if (rtc->control & RTC_INFO_CTRL_POWER_FAILURE)
+ errorFlags |= 0x20;
+
+ if (!(rtc->control & RTC_INFO_CTRL_24HOUR))
+ errorFlags |= 0x10;
+
+ year = ConvertBcdToBinary(rtc->year);
+
+ if (year == 0xFF)
+ errorFlags |= 0x40;
+
+ month = ConvertBcdToBinary(rtc->month);
+
+ if (month == 0xFF || month == 0 || month > 12)
+ errorFlags |= 0x80;
+
+ value = ConvertBcdToBinary(rtc->day);
+
+ if (value == 0xFF)
+ errorFlags |= 0x100;
+
+ if (month == MONTH_FEB)
+ {
+ if (value > IsLeapYear(year) + gNumDaysInMonths[month - 1])
+ errorFlags |= 0x100;
+ }
+ else
+ {
+ if (value > gNumDaysInMonths[month - 1])
+ errorFlags |= 0x100;
+ }
+
+ value = ConvertBcdToBinary(rtc->hour);
+
+ if (value > 24)
+ errorFlags |= 0x200;
+
+ value = ConvertBcdToBinary(rtc->minute);
+
+ if (value > 60)
+ errorFlags |= 0x400;
+
+ value = ConvertBcdToBinary(rtc->second);
+
+ if (value > 60)
+ errorFlags |= 0x800;
+
+ return errorFlags;
+}
+
+void RtcReset()
+{
+ RtcDisableInterrupts();
+ RTC_Reset();
+ RtcRestoreInterrupts();
+}
+
+void FormatDecimalTime(u8 *dest, s32 hour, s32 minute, s32 second)
+{
+ dest = ConvertIntToDecimalStringN(dest, hour, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest++ = CHAR_COLON;
+ dest = ConvertIntToDecimalStringN(dest, minute, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest++ = CHAR_COLON;
+ dest = ConvertIntToDecimalStringN(dest, second, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest = EOS;
+}
+
+void FormatHexTime(u8 *dest, s32 hour, s32 minute, s32 second)
+{
+ dest = ConvertIntToHexStringN(dest, hour, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest++ = CHAR_COLON;
+ dest = ConvertIntToHexStringN(dest, minute, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest++ = CHAR_COLON;
+ dest = ConvertIntToHexStringN(dest, second, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest = EOS;
+}
+
+void FormatHexRtcTime(u8 *dest)
+{
+ FormatHexTime(dest, gRtcInfo.hour, gRtcInfo.minute, gRtcInfo.second);
+}
+
+void FormatDecimalDate(u8 *dest, s32 year, s32 month, s32 day)
+{
+ dest = ConvertIntToDecimalStringN(dest, year, STR_CONV_MODE_LEADING_ZEROS, 4);
+ *dest++ = CHAR_HYPHEN;
+ dest = ConvertIntToDecimalStringN(dest, month, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest++ = CHAR_HYPHEN;
+ dest = ConvertIntToDecimalStringN(dest, day, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest = EOS;
+}
+
+void FormatHexDate(u8 *dest, s32 year, s32 month, s32 day)
+{
+ dest = ConvertIntToHexStringN(dest, year, STR_CONV_MODE_LEADING_ZEROS, 4);
+ *dest++ = CHAR_HYPHEN;
+ dest = ConvertIntToHexStringN(dest, month, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest++ = CHAR_HYPHEN;
+ dest = ConvertIntToHexStringN(dest, day, STR_CONV_MODE_LEADING_ZEROS, 2);
+ *dest = EOS;
+}
+
+void RtcCalcTimeDifference(struct RtcInfo *rtc, struct Time *result, struct Time *t)
+{
+ u16 days = RtcGetDayCount(rtc);
+ result->seconds = ConvertBcdToBinary(rtc->second) - t->seconds;
+ result->minutes = ConvertBcdToBinary(rtc->minute) - t->minutes;
+ result->hours = ConvertBcdToBinary(rtc->hour) - t->hours;
+ result->days = days - t->days;
+
+ if (result->seconds < 0)
+ {
+ result->seconds += 60;
+ --result->minutes;
+ }
+
+ if (result->minutes < 0)
+ {
+ result->minutes += 60;
+ --result->hours;
+ }
+
+ if (result->hours < 0)
+ {
+ result->hours += 24;
+ --result->days;
+ }
+}
+
+void RtcCalcLocalTime()
+{
+ RtcGetInfo(&gRtcInfo);
+ RtcCalcTimeDifference(&gRtcInfo, &gLocalTime, &gSaveBlock2.localTimeOffset);
+}
+
+void RtcInitLocalTimeOffset(s32 hours, s32 minutes)
+{
+ RtcCalcLocalTimeOffset(0, hours, minutes, 0);
+}
+
+void RtcCalcLocalTimeOffset(s32 days, s32 hours, s32 minutes, s32 seconds)
+{
+ gLocalTime.days = days;
+ gLocalTime.hours = hours;
+ gLocalTime.minutes = minutes;
+ gLocalTime.seconds = seconds;
+ RtcGetInfo(&gRtcInfo);
+ RtcCalcTimeDifference(&gRtcInfo, &gSaveBlock2.localTimeOffset, &gLocalTime);
+}
+
+void CalcTimeDifference(struct Time *result, struct Time *t1, struct Time *t2)
+{
+ result->seconds = t2->seconds - t1->seconds;
+ result->minutes = t2->minutes - t1->minutes;
+ result->hours = t2->hours - t1->hours;
+ result->days = t2->days - t1->days;
+
+ if (result->seconds < 0)
+ {
+ result->seconds += 60;
+ --result->minutes;
+ }
+
+ if (result->minutes < 0)
+ {
+ result->minutes += 60;
+ --result->hours;
+ }
+
+ if (result->hours < 0)
+ {
+ result->hours += 24;
+ --result->days;
+ }
+}
+
+u32 RtcGetMinuteCount()
+{
+ RtcGetInfo(&gRtcInfo);
+ return (24 * 60) * RtcGetDayCount(&gRtcInfo) + 60 * gRtcInfo.hour + gRtcInfo.minute;
+}
diff --git a/src/string_util.c b/src/string_util.c
index 221319ae3..a2d2d9cd2 100644
--- a/src/string_util.c
+++ b/src/string_util.c
@@ -1,13 +1,6 @@
#include "global.h"
#include "string_util.h"
-#define CHAR_SPACE 0x00
-#define CHAR_QUESTION_MARK 0xAC
-
-#define EXT_CTRL_CODE_BEGIN 0xFC // extended control code
-#define PLACEHOLDER_BEGIN 0xFD // string placeholder
-#define EOS 0xFF // end of string
-
#define MAX_PLACEHOLDER_ID 0xD
typedef u8 *(*ExpandPlaceholderFunc)();