summaryrefslogtreecommitdiff
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
parent6f965a9eca507c27049fbd90a57f620b63c92d6d (diff)
RTC code/data
-rw-r--r--asm/crt0.s2
-rw-r--r--asm/rom.s836
-rw-r--r--data/data2.s7
-rw-r--r--data/rtc_util.s32
-rw-r--r--include/gba/gba.h34
-rw-r--r--include/global.h40
-rw-r--r--include/rtc.h54
-rw-r--r--include/rtc_util.h20
-rw-r--r--include/string_util.h10
-rw-r--r--iwram_syms.txt7
-rw-r--r--src/librtc.c174
-rw-r--r--src/rtc_util.c335
-rw-r--r--src/string_util.c7
13 files changed, 614 insertions, 944 deletions
diff --git a/asm/crt0.s b/asm/crt0.s
index 9729a9488..94d4a4b7a 100644
--- a/asm/crt0.s
+++ b/asm/crt0.s
@@ -12,7 +12,7 @@ GPIOPortData: ; 80000C4
GPIOPortDirection: ; 80000C6
.2byte 0
-GPIOPortReadWrite: ; 80000C8
+GPIOPortReadEnable: ; 80000C8
.2byte 0
.rept 6
diff --git a/asm/rom.s b/asm/rom.s
index 913d13834..0d916724f 100644
--- a/asm/rom.s
+++ b/asm/rom.s
@@ -27,7 +27,7 @@ AgbMain: ; 800024C
bl InitKeypadData
bl InitIntrHandlers
bl m4aSoundInit
- bl GameFreakRTC_Init
+ bl RtcInit
bl CheckForFlashMemory
bl init_saveblock_ptrs_and_set_copyright_callback2
bl sound_sources_off
@@ -204,7 +204,7 @@ _080003E0: .4byte 0x0000043c
thumb_func_start SeedRngWithRtc
SeedRngWithRtc: ; 80003E4
push {lr}
- bl GameFreakRTC_GetNumMinutes
+ bl RtcGetMinuteCount
adds r2, r0, 0
lsrs r0, r2, 16
ldr r1, _080003FC
@@ -620,7 +620,7 @@ DoSoftReset: ; 80006B4
ands r2, r1
strh r2, [r0, 0xA]
ldrh r0, [r0, 0xA]
- bl RTC_SetReadOnly
+ bl RTC_Protect
movs r0, 0xFF
bl SoftReset
pop {r4}
@@ -18378,803 +18378,7 @@ _080090EC: .4byte 0x00000fbc
_080090F0: .4byte 0x0000efff
thumb_func_end sub_8009084
- thumb_func_start GFRTC_DisableInterrupts
-GFRTC_DisableInterrupts: ; 80090F4
- ldr r2, _08009104
- ldr r1, _08009108
- ldrh r0, [r1]
- strh r0, [r2]
- movs r0, 0
- strh r0, [r1]
- bx lr
- .align 2
-_08009104: .4byte 0x0300046e
-_08009108: .4byte 0x04000208
- thumb_func_end GFRTC_DisableInterrupts
-
- thumb_func_start GFRTC_RestoreInterrupts
-GFRTC_RestoreInterrupts: ; 800910C
- ldr r0, _08009118
- ldr r1, _0800911C
- ldrh r1, [r1]
- strh r1, [r0]
- bx lr
- .align 2
-_08009118: .4byte 0x04000208
-_0800911C: .4byte 0x0300046e
- thumb_func_end GFRTC_RestoreInterrupts
-
- thumb_func_start GFRTC_ConvertBcdToBinary
-GFRTC_ConvertBcdToBinary: ; 8009120
- push {lr}
- lsls r0, 24
- lsrs r2, r0, 24
- cmp r2, 0x9F
- bhi _08009132
- movs r3, 0xF
- ands r3, r2
- cmp r3, 0x9
- bls _08009136
-_08009132:
- movs r0, 0xFF
- b _08009144
-_08009136:
- lsrs r1, r0, 28
- movs r0, 0xF
- ands r1, r0
- lsls r0, r1, 2
- adds r0, r1
- lsls r0, 1
- adds r0, r3
-_08009144:
- pop {r1}
- bx r1
- thumb_func_end GFRTC_ConvertBcdToBinary
-
- thumb_func_start GFRTC_IsLeapYear
-GFRTC_IsLeapYear: ; 8009148
- push {r4,lr}
- lsls r0, 24
- lsrs r1, r0, 24
- adds r4, r1, 0
- movs r0, 0x3
- ands r0, r1
- cmp r0, 0
- bne _08009166
- adds r0, r1, 0
- movs r1, 0x64
- bl __umodsi3
- lsls r0, 24
- cmp r0, 0
- bne _08009174
-_08009166:
- movs r1, 0xC8
- lsls r1, 1
- adds r0, r4, 0
- bl __modsi3
- cmp r0, 0
- bne _08009178
-_08009174:
- movs r0, 0x1
- b _0800917A
-_08009178:
- movs r0, 0
-_0800917A:
- pop {r4}
- pop {r1}
- bx r1
- thumb_func_end GFRTC_IsLeapYear
-
- thumb_func_start GFRTC_ConvertYmdToDayCount
-GFRTC_ConvertYmdToDayCount: ; 8009180
- push {r4-r7,lr}
- mov r7, r8
- push {r7}
- lsls r0, 24
- lsrs r7, r0, 24
- lsls r1, 24
- lsrs r6, r1, 24
- lsls r2, 24
- lsrs r2, 24
- mov r8, r2
- movs r5, 0
- subs r4, r7, 0x1
- cmp r4, 0
- ble _080091C0
-_0800919C:
- ldr r1, _08009204
- adds r0, r5, r1
- lsls r0, 16
- lsrs r5, r0, 16
- lsls r0, r4, 24
- lsrs r0, 24
- bl GFRTC_IsLeapYear
- lsls r0, 24
- lsrs r0, 24
- cmp r0, 0x1
- bne _080091BA
- adds r0, r5, 0x1
- lsls r0, 16
- lsrs r5, r0, 16
-_080091BA:
- subs r4, 0x1
- cmp r4, 0
- bgt _0800919C
-_080091C0:
- subs r0, r6, 0x1
- cmp r0, 0
- ble _080091D8
- ldr r1, _08009208
- adds r4, r0, 0
-_080091CA:
- ldm r1!, {r0}
- adds r0, r5, r0
- lsls r0, 16
- lsrs r5, r0, 16
- subs r4, 0x1
- cmp r4, 0
- bne _080091CA
-_080091D8:
- cmp r6, 0x2
- bls _080091F0
- adds r0, r7, 0
- bl GFRTC_IsLeapYear
- lsls r0, 24
- lsrs r0, 24
- cmp r0, 0x1
- bne _080091F0
- adds r0, r5, 0x1
- lsls r0, 16
- lsrs r5, r0, 16
-_080091F0:
- mov r1, r8
- adds r0, r5, r1
- lsls r0, 16
- lsrs r5, r0, 16
- adds r0, r5, 0
- pop {r3}
- mov r8, r3
- pop {r4-r7}
- pop {r1}
- bx r1
- .align 2
-_08009204: .4byte 0x0000016d
-_08009208: .4byte gUnknown_081E761C
- thumb_func_end GFRTC_ConvertYmdToDayCount
-
- thumb_func_start GFRTC_GetDayCount
-GFRTC_GetDayCount: ; 800920C
- push {r4-r6,lr}
- adds r6, r0, 0
- ldrb r0, [r6]
- bl GFRTC_ConvertBcdToBinary
- adds r5, r0, 0
- lsls r5, 24
- lsrs r5, 24
- ldrb r0, [r6, 0x1]
- bl GFRTC_ConvertBcdToBinary
- adds r4, r0, 0
- lsls r4, 24
- lsrs r4, 24
- ldrb r0, [r6, 0x2]
- bl GFRTC_ConvertBcdToBinary
- adds r2, r0, 0
- lsls r2, 24
- lsrs r2, 24
- adds r0, r5, 0
- adds r1, r4, 0
- bl GFRTC_ConvertYmdToDayCount
- lsls r0, 16
- lsrs r0, 16
- pop {r4-r6}
- pop {r1}
- bx r1
- thumb_func_end GFRTC_GetDayCount
-
- thumb_func_start GameFreakRTC_Init
-GameFreakRTC_Init: ; 8009248
- push {r4,r5,lr}
- ldr r5, _08009274
- movs r0, 0
- strh r0, [r5]
- bl GFRTC_DisableInterrupts
- bl RTC_SetReadWrite
- bl RTC_Init
- ldr r4, _08009278
- strb r0, [r4]
- bl GFRTC_RestoreInterrupts
- ldrb r4, [r4]
- movs r0, 0xF
- ands r0, r4
- cmp r0, 0
- bne _0800927C
- movs r0, 0x1
- strh r0, [r5]
- b _0800929A
- .align 2
-_08009274: .4byte 0x03000458
-_08009278: .4byte 0x0300046c
-_0800927C:
- movs r0, 0xF0
- ands r0, r4
- cmp r0, 0
- beq _08009286
- movs r0, 0x2
-_08009286:
- strh r0, [r5]
- ldr r4, _080092A0
- adds r0, r4, 0
- bl GFRTC_GetControlRegAndRtcDateTime
- adds r0, r4, 0
- bl GFRTC_TestForErrors
- ldr r1, _080092A4
- strh r0, [r1]
-_0800929A:
- pop {r4,r5}
- pop {r0}
- bx r0
- .align 2
-_080092A0: .4byte 0x03000460
-_080092A4: .4byte 0x03000458
- thumb_func_end GameFreakRTC_Init
-
- thumb_func_start sub_80092A8
-sub_80092A8: ; 80092A8
- ldr r0, _080092B0
- ldrh r0, [r0]
- bx lr
- .align 2
-_080092B0: .4byte 0x03000458
- thumb_func_end sub_80092A8
-
- thumb_func_start GameFreakRTC_GetRTCDateTime
-GameFreakRTC_GetRTCDateTime: ; 80092B4
- push {r4,lr}
- adds r2, r0, 0
- ldr r0, _080092D0
- ldrh r1, [r0]
- movs r0, 0xFF
- lsls r0, 4
- ands r0, r1
- cmp r0, 0
- beq _080092D8
- adds r1, r2, 0
- ldr r0, _080092D4
- ldm r0!, {r2-r4}
- stm r1!, {r2-r4}
- b _080092DE
- .align 2
-_080092D0: .4byte 0x03000458
-_080092D4: .4byte gUnknown_081E7610
-_080092D8:
- adds r0, r2, 0
- bl GFRTC_GetControlRegAndRtcDateTime
-_080092DE:
- pop {r4}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_GetRTCDateTime
-
- thumb_func_start GameFreakRTC_GetRTCDateTimeInternal
-GameFreakRTC_GetRTCDateTimeInternal: ; 80092E4
- push {r4,lr}
- adds r4, r0, 0
- bl GFRTC_DisableInterrupts
- adds r0, r4, 0
- bl RTC_GetDateTime
- bl GFRTC_RestoreInterrupts
- pop {r4}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_GetRTCDateTimeInternal
-
- thumb_func_start GameFreakRTC_GetControlReg
-GameFreakRTC_GetControlReg: ; 80092FC
- push {r4,lr}
- adds r4, r0, 0
- bl GFRTC_DisableInterrupts
- adds r0, r4, 0
- bl RTC_GetControlReg
- bl GFRTC_RestoreInterrupts
- pop {r4}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_GetControlReg
-
- thumb_func_start GFRTC_GetControlRegAndRtcDateTime
-GFRTC_GetControlRegAndRtcDateTime: ; 8009314
- push {r4,lr}
- adds r4, r0, 0
- bl GameFreakRTC_GetControlReg
- adds r0, r4, 0
- bl GameFreakRTC_GetRTCDateTimeInternal
- pop {r4}
- pop {r0}
- bx r0
- thumb_func_end GFRTC_GetControlRegAndRtcDateTime
-
- thumb_func_start GFRTC_TestForErrors
-GFRTC_TestForErrors: ; 8009328
- push {r4-r7,lr}
- mov r7, r8
- push {r7}
- adds r7, r0, 0
- ldrb r1, [r7, 0x7]
- movs r0, 0x80
- ands r0, r1
- lsls r0, 24
- lsrs r0, 24
- negs r0, r0
- asrs r4, r0, 31
- movs r0, 0x20
- ands r4, r0
- movs r0, 0x40
- ands r0, r1
- cmp r0, 0
- bne _0800934E
- movs r0, 0x10
- orrs r4, r0
-_0800934E:
- ldrb r0, [r7]
- bl GFRTC_ConvertBcdToBinary
- mov r8, r0
- cmp r0, 0xFF
- bne _08009362
- movs r0, 0x40
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_08009362:
- ldrb r0, [r7, 0x1]
- bl GFRTC_ConvertBcdToBinary
- adds r6, r0, 0
- cmp r6, 0xFF
- beq _08009376
- cmp r6, 0
- beq _08009376
- cmp r6, 0xC
- ble _0800937E
-_08009376:
- movs r0, 0x80
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_0800937E:
- ldrb r0, [r7, 0x2]
- bl GFRTC_ConvertBcdToBinary
- adds r5, r0, 0
- cmp r5, 0xFF
- bne _08009396
- movs r1, 0x80
- lsls r1, 1
- adds r0, r1, 0
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_08009396:
- cmp r6, 0x2
- bne _080093B4
- mov r1, r8
- lsls r0, r1, 24
- lsrs r0, 24
- bl GFRTC_IsLeapYear
- lsls r0, 24
- lsrs r0, 24
- ldr r1, _080093B0
- ldr r1, [r1, 0x4]
- adds r0, r1
- b _080093BE
- .align 2
-_080093B0: .4byte gUnknown_081E761C
-_080093B4:
- ldr r0, _08009424
- subs r1, r6, 0x1
- lsls r1, 2
- adds r1, r0
- ldr r0, [r1]
-_080093BE:
- cmp r5, r0
- ble _080093CE
- movs r1, 0x80
- lsls r1, 1
- adds r0, r1, 0
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_080093CE:
- ldrb r0, [r7, 0x4]
- bl GFRTC_ConvertBcdToBinary
- adds r5, r0, 0
- cmp r5, 0x18
- ble _080093E6
- movs r1, 0x80
- lsls r1, 2
- adds r0, r1, 0
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_080093E6:
- ldrb r0, [r7, 0x5]
- bl GFRTC_ConvertBcdToBinary
- adds r5, r0, 0
- cmp r5, 0x3C
- ble _080093FE
- movs r1, 0x80
- lsls r1, 3
- adds r0, r1, 0
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_080093FE:
- ldrb r0, [r7, 0x6]
- bl GFRTC_ConvertBcdToBinary
- adds r5, r0, 0
- cmp r5, 0x3C
- ble _08009416
- movs r1, 0x80
- lsls r1, 4
- adds r0, r1, 0
- orrs r4, r0
- lsls r0, r4, 16
- lsrs r4, r0, 16
-_08009416:
- adds r0, r4, 0
- pop {r3}
- mov r8, r3
- pop {r4-r7}
- pop {r1}
- bx r1
- .align 2
-_08009424: .4byte gUnknown_081E761C
- thumb_func_end GFRTC_TestForErrors
-
- thumb_func_start sub_8009428
-sub_8009428: ; 8009428
- push {lr}
- bl GFRTC_DisableInterrupts
- bl RTC_Reset
- bl GFRTC_RestoreInterrupts
- pop {r0}
- bx r0
- thumb_func_end sub_8009428
-
- thumb_func_start GameFreakRTC_FormatDecimalTimeString
-GameFreakRTC_FormatDecimalTimeString: ; 800943C
- push {r4-r6,lr}
- adds r5, r2, 0
- adds r6, r3, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToDecimalStringN
- movs r4, 0xF0
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r5, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToDecimalStringN
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r6, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToDecimalStringN
- movs r1, 0xFF
- strb r1, [r0]
- pop {r4-r6}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_FormatDecimalTimeString
-
- thumb_func_start GameFreakRTC_FormatHexTimeString
-GameFreakRTC_FormatHexTimeString: ; 8009474
- push {r4-r6,lr}
- adds r5, r2, 0
- adds r6, r3, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToHexStringN
- movs r4, 0xF0
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r5, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToHexStringN
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r6, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToHexStringN
- movs r1, 0xFF
- strb r1, [r0]
- pop {r4-r6}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_FormatHexTimeString
-
- thumb_func_start GameFreakRTC_FormatHexTimeStringFromRTCInfo
-GameFreakRTC_FormatHexTimeStringFromRTCInfo: ; 80094AC
- push {lr}
- ldr r3, _080094C0
- ldrb r1, [r3, 0x4]
- ldrb r2, [r3, 0x5]
- ldrb r3, [r3, 0x6]
- bl GameFreakRTC_FormatHexTimeString
- pop {r0}
- bx r0
- .align 2
-_080094C0: .4byte 0x03000460
- thumb_func_end GameFreakRTC_FormatHexTimeStringFromRTCInfo
-
- thumb_func_start GameFreakRTC_FormatDecimalYearMonthDayString
-GameFreakRTC_FormatDecimalYearMonthDayString: ; 80094C4
- push {r4-r6,lr}
- adds r5, r2, 0
- adds r6, r3, 0
- movs r2, 0x2
- movs r3, 0x4
- bl ConvertIntToDecimalStringN
- movs r4, 0xAE
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r5, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToDecimalStringN
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r6, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToDecimalStringN
- movs r1, 0xFF
- strb r1, [r0]
- pop {r4-r6}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_FormatDecimalYearMonthDayString
-
- thumb_func_start GameFreakRTC_FormatHexYearMonthDayString
-GameFreakRTC_FormatHexYearMonthDayString: ; 80094FC
- push {r4-r6,lr}
- adds r5, r2, 0
- adds r6, r3, 0
- movs r2, 0x2
- movs r3, 0x4
- bl ConvertIntToHexStringN
- movs r4, 0xAE
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r5, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToHexStringN
- strb r4, [r0]
- adds r0, 0x1
- adds r1, r6, 0
- movs r2, 0x2
- movs r3, 0x2
- bl ConvertIntToHexStringN
- movs r1, 0xFF
- strb r1, [r0]
- pop {r4-r6}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_FormatHexYearMonthDayString
-
- thumb_func_start GameFreakRTC_GetRTCDelta
-GameFreakRTC_GetRTCDelta: ; 8009534
- push {r4-r7,lr}
- adds r5, r0, 0
- adds r7, r1, 0
- adds r6, r2, 0
- bl GFRTC_GetDayCount
- adds r4, r0, 0
- lsls r4, 16
- lsrs r4, 16
- ldrb r0, [r5, 0x6]
- bl GFRTC_ConvertBcdToBinary
- ldrb r1, [r6, 0x4]
- subs r0, r1
- strb r0, [r7, 0x4]
- ldrb r0, [r5, 0x5]
- bl GFRTC_ConvertBcdToBinary
- ldrb r1, [r6, 0x3]
- subs r0, r1
- strb r0, [r7, 0x3]
- ldrb r0, [r5, 0x4]
- bl GFRTC_ConvertBcdToBinary
- ldrb r1, [r6, 0x2]
- subs r0, r1
- strb r0, [r7, 0x2]
- ldrh r0, [r6]
- subs r4, r0
- strh r4, [r7]
- ldrb r1, [r7, 0x4]
- movs r0, 0x4
- ldrsb r0, [r7, r0]
- cmp r0, 0
- bge _08009586
- adds r0, r1, 0
- adds r0, 0x3C
- strb r0, [r7, 0x4]
- ldrb r0, [r7, 0x3]
- subs r0, 0x1
- strb r0, [r7, 0x3]
-_08009586:
- ldrb r1, [r7, 0x3]
- movs r0, 0x3
- ldrsb r0, [r7, r0]
- cmp r0, 0
- bge _0800959C
- adds r0, r1, 0
- adds r0, 0x3C
- strb r0, [r7, 0x3]
- ldrb r0, [r7, 0x2]
- subs r0, 0x1
- strb r0, [r7, 0x2]
-_0800959C:
- ldrb r1, [r7, 0x2]
- movs r0, 0x2
- ldrsb r0, [r7, r0]
- cmp r0, 0
- bge _080095B2
- adds r0, r1, 0
- adds r0, 0x18
- strb r0, [r7, 0x2]
- ldrh r0, [r7]
- subs r0, 0x1
- strh r0, [r7]
-_080095B2:
- pop {r4-r7}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_GetRTCDelta
-
- thumb_func_start GameFreakRTC_CalcLocalDateTime
-GameFreakRTC_CalcLocalDateTime: ; 80095B8
- push {r4,lr}
- ldr r4, _080095D4
- adds r0, r4, 0
- bl GameFreakRTC_GetRTCDateTime
- ldr r1, _080095D8
- ldr r2, _080095DC
- adds r0, r4, 0
- bl GameFreakRTC_GetRTCDelta
- pop {r4}
- pop {r0}
- bx r0
- .align 2
-_080095D4: .4byte 0x03000460
-_080095D8: .4byte 0x03004038
-_080095DC: .4byte 0x02024f3c
- thumb_func_end GameFreakRTC_CalcLocalDateTime
-
- thumb_func_start GameFreakRTC_CalcRTCToLocalDelta_DayZero
-GameFreakRTC_CalcRTCToLocalDelta_DayZero: ; 80095E0
- push {lr}
- adds r3, r0, 0
- adds r2, r1, 0
- movs r0, 0
- adds r1, r3, 0
- movs r3, 0
- bl GameFreakRTC_CalcRTCToLocalDelta
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_CalcRTCToLocalDelta_DayZero
-
- thumb_func_start GameFreakRTC_CalcRTCToLocalDelta
-GameFreakRTC_CalcRTCToLocalDelta: ; 80095F4
- push {r4,r5,lr}
- ldr r4, _08009618
- strh r0, [r4]
- strb r1, [r4, 0x2]
- strb r2, [r4, 0x3]
- strb r3, [r4, 0x4]
- ldr r5, _0800961C
- adds r0, r5, 0
- bl GameFreakRTC_GetRTCDateTime
- ldr r1, _08009620
- adds r0, r5, 0
- adds r2, r4, 0
- bl GameFreakRTC_GetRTCDelta
- pop {r4,r5}
- pop {r0}
- bx r0
- .align 2
-_08009618: .4byte 0x03004038
-_0800961C: .4byte 0x03000460
-_08009620: .4byte 0x02024f3c
- thumb_func_end GameFreakRTC_CalcRTCToLocalDelta
-
- thumb_func_start GameFreakRTC_GetDelta
-GameFreakRTC_GetDelta: ; 8009624
- push {r4-r6,lr}
- adds r4, r0, 0
- ldrb r3, [r2, 0x4]
- ldrb r0, [r1, 0x4]
- subs r5, r3, r0
- strb r5, [r4, 0x4]
- ldrb r3, [r2, 0x3]
- ldrb r0, [r1, 0x3]
- subs r6, r3, r0
- strb r6, [r4, 0x3]
- ldrb r0, [r2, 0x2]
- ldrb r3, [r1, 0x2]
- subs r0, r3
- strb r0, [r4, 0x2]
- ldrh r0, [r2]
- ldrh r1, [r1]
- subs r0, r1
- strh r0, [r4]
- lsls r0, r5, 24
- cmp r0, 0
- bge _08009658
- adds r0, r5, 0
- adds r0, 0x3C
- strb r0, [r4, 0x4]
- subs r0, r6, 0x1
- strb r0, [r4, 0x3]
-_08009658:
- ldrb r1, [r4, 0x3]
- movs r0, 0x3
- ldrsb r0, [r4, r0]
- cmp r0, 0
- bge _0800966E
- adds r0, r1, 0
- adds r0, 0x3C
- strb r0, [r4, 0x3]
- ldrb r0, [r4, 0x2]
- subs r0, 0x1
- strb r0, [r4, 0x2]
-_0800966E:
- ldrb r1, [r4, 0x2]
- movs r0, 0x2
- ldrsb r0, [r4, r0]
- cmp r0, 0
- bge _08009684
- adds r0, r1, 0
- adds r0, 0x18
- strb r0, [r4, 0x2]
- ldrh r0, [r4]
- subs r0, 0x1
- strh r0, [r4]
-_08009684:
- pop {r4-r6}
- pop {r0}
- bx r0
- thumb_func_end GameFreakRTC_GetDelta
-
- thumb_func_start GameFreakRTC_GetNumMinutes
-GameFreakRTC_GetNumMinutes: ; 800968C
- push {r4,lr}
- ldr r4, _080096C0
- adds r0, r4, 0
- bl GameFreakRTC_GetRTCDateTime
- adds r0, r4, 0
- bl GFRTC_GetDayCount
- lsls r0, 16
- lsrs r0, 16
- lsls r1, r0, 1
- adds r1, r0
- lsls r0, r1, 4
- subs r0, r1
- lsls r0, 5
- ldrb r2, [r4, 0x4]
- lsls r1, r2, 4
- subs r1, r2
- lsls r1, 2
- adds r0, r1
- ldrb r4, [r4, 0x5]
- adds r0, r4
- pop {r4}
- pop {r1}
- bx r1
- .align 2
-_080096C0: .4byte 0x03000460
- thumb_func_end GameFreakRTC_GetNumMinutes
+ .include "genasm/rtc_util.s"
thumb_func_start sub_80096C4
sub_80096C4: ; 80096C4
@@ -19647,7 +18851,7 @@ sub_8009A64: ; 8009A64
adds r1, 0x4
movs r0, 0x7
strh r0, [r1]
- bl sub_80092A8
+ bl RtcGetErrorFlags
movs r1, 0xFF
lsls r1, 4
ands r1, r0
@@ -126160,7 +125364,7 @@ _0803F5D0:
adds r0, r3
b _0803F61C
_0803F5DA:
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r0, _0803F5F8
ldrb r0, [r0, 0x2]
subs r0, 0xC
@@ -126179,7 +125383,7 @@ _0803F5F6:
.align 2
_0803F5F8: .4byte 0x03004038
_0803F5FC:
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r0, _0803F624
ldrb r0, [r0, 0x2]
cmp r0, 0xB
@@ -165175,7 +164379,7 @@ NewGameInitData: ; 8052E6C
cmp r0, 0x2
bne _08052E7E
_08052E7A:
- bl sub_8009428
+ bl RtcReset
_08052E7E:
ldr r1, _08052F40
movs r0, 0x1
@@ -208403,7 +207607,7 @@ s2C_unknown: ; 8066300
lsls r1, 24
lsrs r1, 24
adds r0, r4, 0
- bl GameFreakRTC_CalcRTCToLocalDelta_DayZero
+ bl RtcInitLocalTimeOffset
movs r0, 0
pop {r4,r5}
pop {r1}
@@ -208422,7 +207626,7 @@ s2D_unknown: ; 8066338
thumb_func_start s2E_unknown
s2E_unknown: ; 8066344
push {lr}
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r2, _0806636C
ldr r1, _08066370
movs r0, 0x2
@@ -216900,7 +216104,7 @@ sub_806A328: ; 806A328
push {lr}
ldr r0, _0806A350
bl FlagSet
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r2, _0806A354
adds r2, 0xA0
ldr r3, _0806A358
@@ -216928,7 +216132,7 @@ InTrainerHill: ; 806A360
lsls r0, 24
cmp r0, 0
beq _0806A380
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r4, _0806A38C
adds r0, r4, 0
bl sub_806A390
@@ -216998,7 +216202,7 @@ sub_806A3F4: ; 806A3F4
mov r0, sp
adds r1, r6, 0
adds r2, r5, 0
- bl GameFreakRTC_GetDelta
+ bl CalcTimeDifference
mov r0, sp
movs r2, 0
ldrsh r1, [r0, r2]
@@ -218186,7 +217390,7 @@ _0806AD5C: .4byte 0x0202f388
_0806AD60: .4byte 0x03005eb8
_0806AD64: .4byte gUnknown_084118A0
_0806AD68:
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r0, _0806AD7C
movs r1, 0x50
bl AddTask
@@ -218261,7 +217465,7 @@ _0806AE04: .4byte 0x03004b20
_0806AE08:
ldrb r0, [r5, 0x2]
bl remove_task
- bl sub_8009428
+ bl RtcReset
ldr r4, _0806AE4C
movs r1, 0
ldrsh r0, [r4, r1]
@@ -218271,7 +217475,7 @@ _0806AE08:
ldrsb r2, [r4, r2]
movs r3, 0x4
ldrsb r3, [r4, r3]
- bl GameFreakRTC_CalcRTCToLocalDelta
+ bl RtcCalcLocalTimeOffset
ldr r2, _0806AE50
adds r2, 0xA0
ldr r0, [r4]
@@ -547951,7 +547155,7 @@ sub_810AD58: ; 810AD58
ldrsh r0, [r4, r1]
movs r2, 0xE
ldrsh r1, [r4, r2]
- bl GameFreakRTC_CalcRTCToLocalDelta_DayZero
+ bl RtcInitLocalTimeOffset
movs r0, 0x1
negs r0, r0
movs r1, 0
@@ -548310,7 +547514,7 @@ sub_810AFE0: ; 810AFE0
adds r4, r0, 0
lsls r4, 24
lsrs r4, 24
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r1, _0810B048
lsls r0, r4, 2
adds r0, r4
@@ -552842,7 +552046,7 @@ sub_810D378: ; 810D378
lsls r0, 24
cmp r0, 0
beq _0810D3BE
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
ldr r1, _0810D3AC
ldr r0, _0810D3B0
ldrb r0, [r0, 0x2]
@@ -568816,7 +568020,7 @@ _0811536C:
lsrs r4, r0, 24
cmp r4, 0x5
bls _08115322
- bl GameFreakRTC_CalcLocalDateTime
+ bl RtcCalcLocalTime
add sp, 0x8
pop {r4-r6}
pop {r0}
diff --git a/data/data2.s b/data/data2.s
index 88cf02113..9f5b37cd8 100644
--- a/data/data2.s
+++ b/data/data2.s
@@ -363,11 +363,8 @@ gUnknown_081E75CC: ; 81E75CC
gUnknown_081E75FC: ; 81E75FC
.incbin "baserom.gba", 0x001e75fc, 0x14
-gUnknown_081E7610: ; 81E7610
- .incbin "baserom.gba", 0x001e7610, 0xc
-
-gUnknown_081E761C: ; 81E761C
- .incbin "baserom.gba", 0x001e761c, 0x30
+; 81E7610
+ .include "data/rtc_util.s"
gUnknown_081E764C: ; 81E764C
.incbin "baserom.gba", 0x001e764c, 0x40
diff --git a/data/rtc_util.s b/data/rtc_util.s
new file mode 100644
index 000000000..9ee05f47e
--- /dev/null
+++ b/data/rtc_util.s
@@ -0,0 +1,32 @@
+ .align 2
+
+; 2000 Jan 1 00:00:00
+gDefaultRtcInfo: ; 81E7610
+ .byte 0
+ .byte 1
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+
+ .align 2
+
+gNumDaysInMonths: ; 81E761C
+ .4byte 31
+ .4byte 28
+ .4byte 31
+ .4byte 30
+ .4byte 31
+ .4byte 30
+ .4byte 31
+ .4byte 31
+ .4byte 30
+ .4byte 31
+ .4byte 30
+ .4byte 31
diff --git a/include/gba/gba.h b/include/gba/gba.h
new file mode 100644
index 000000000..5a9dc9b2d
--- /dev/null
+++ b/include/gba/gba.h
@@ -0,0 +1,34 @@
+#ifndef GUARD_GBA_GBA_H
+#define GUARD_GBA_GBA_H
+
+#include <stddef.h>
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef signed char s8;
+typedef signed short s16;
+typedef signed int s32;
+
+typedef volatile u8 vu8;
+typedef volatile u16 vu16;
+typedef volatile u32 vu32;
+typedef volatile s8 vs8;
+typedef volatile s16 vs16;
+typedef volatile s32 vs32;
+
+typedef float f32;
+typedef double f64;
+
+typedef u8 bool8;
+typedef u16 bool16;
+typedef u32 bool32;
+
+#define TRUE 1
+#define FALSE 0
+
+#include "gba/io_reg.h"
+#include "gba/syscall.h"
+#include "gba/macro.h"
+
+#endif // GUARD_GBA_GBA_H
diff --git a/include/global.h b/include/global.h
index 0c7fef66e..1747446f3 100644
--- a/include/global.h
+++ b/include/global.h
@@ -1,35 +1,7 @@
#ifndef GUARD_GLOBAL_H
#define GUARD_GLOBAL_H
-#include <stddef.h>
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef signed char s8;
-typedef signed short s16;
-typedef signed int s32;
-
-typedef volatile u8 vu8;
-typedef volatile u16 vu16;
-typedef volatile u32 vu32;
-typedef volatile s8 vs8;
-typedef volatile s16 vs16;
-typedef volatile s32 vs32;
-
-typedef float f32;
-typedef double f64;
-
-typedef u8 bool8;
-typedef u16 bool16;
-typedef u32 bool32;
-
-#define TRUE 1
-#define FALSE 0
-
-#include "gba/io_reg.h"
-#include "gba/syscall.h"
-#include "gba/macro.h"
+#include "gba/gba.h"
extern u8 gStringVar1[];
extern u8 gStringVar2[];
@@ -41,6 +13,14 @@ enum
FEMALE
};
+struct Time
+{
+ s16 days;
+ s8 hours;
+ s8 minutes;
+ s8 seconds;
+};
+
struct SaveBlock2
{
u8 playerName[8];
@@ -51,6 +31,8 @@ struct SaveBlock2
u8 playTimeMinutes;
u8 playTimeSeconds;
u8 playTimeVBlanks;
+ u8 filler[0x85];
+ struct Time localTimeOffset;
};
extern struct SaveBlock2 gSaveBlock2;
diff --git a/include/rtc.h b/include/rtc.h
new file mode 100644
index 000000000..5ecff238f
--- /dev/null
+++ b/include/rtc.h
@@ -0,0 +1,54 @@
+#ifndef GUARD_RTC_H
+#define GUARD_RTC_H
+
+#include "gba/gba.h"
+
+#define RTC_INFO_CTRL_UNK1 0x01 // unknown
+#define RTC_INFO_CTRL_IRQ_ENABLE 0x02 // per-minute IRQ enable
+#define RTC_INFO_CTRL_UNK2 0x04 // unknown
+#define RTC_INFO_CTRL_24HOUR 0x40 // 0: 12-hour mode, 1: 24-hour mode
+#define RTC_INFO_CTRL_POWER_FAILURE 0x80 // power failure occurred
+
+enum
+{
+ MONTH_JAN = 1,
+ MONTH_FEB,
+ MONTH_MAR,
+ MONTH_APR,
+ MONTH_MAY,
+ MONTH_JUN,
+ MONTH_JUL,
+ MONTH_AUG,
+ MONTH_SEP,
+ MONTH_OCT,
+ MONTH_NOV,
+ MONTH_DEC
+};
+
+struct RtcInfo
+{
+ u8 year;
+ u8 month;
+ u8 day;
+ u8 dayOfWeek;
+ u8 hour;
+ u8 minute;
+ u8 second;
+ u8 control;
+ u8 unknown1;
+ u8 unknown2;
+};
+
+void RTC_Unprotect();
+void RTC_Protect();
+u8 RTC_Probe();
+bool8 RTC_Reset();
+bool8 RTC_GetControl(struct RtcInfo *rtc);
+bool8 RTC_SetControl(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);
+
+#endif // GUARD_RTC_H
diff --git a/include/rtc_util.h b/include/rtc_util.h
new file mode 100644
index 000000000..584b675d6
--- /dev/null
+++ b/include/rtc_util.h
@@ -0,0 +1,20 @@
+#ifndef GUARD_RTC_UTIL_H
+#define GUARD_RTC_UTIL_H
+
+#include "global.h"
+
+void RtcInit();
+u16 RtcGetErrorFlags();
+void RtcReset();
+void FormatDecimalTime(u8 *dest, s32 hour, s32 minute, s32 second);
+void FormatHexTime(u8 *dest, s32 hour, s32 minute, s32 second);
+void FormatHexRtcTime(u8 *dest);
+void FormatDecimalDate(u8 *dest, s32 year, s32 month, s32 day);
+void FormatHexDate(u8 *dest, s32 year, s32 month, s32 day);
+void RtcCalcLocalTime();
+void RtcInitLocalTimeOffset(s32 hours, s32 minutes);
+void RtcCalcLocalTimeOffset(s32 days, s32 hours, s32 minutes, s32 seconds);
+void CalcTimeDifference(struct Time *result, struct Time *t1, struct Time *t2);
+u32 RtcGetMinuteCount();
+
+#endif // GUARD_RTC_UTIL_H
diff --git a/include/string_util.h b/include/string_util.h
index d1b90aa34..0dee55828 100644
--- a/include/string_util.h
+++ b/include/string_util.h
@@ -1,6 +1,16 @@
#ifndef GUARD_STRING_UTIL_H
#define GUARD_STRING_UTIL_H
+#include "global.h"
+
+#define CHAR_SPACE 0x00
+#define CHAR_QUESTION_MARK 0xAC
+#define CHAR_HYPHEN 0xAE
+#define CHAR_COLON 0xF0
+#define EXT_CTRL_CODE_BEGIN 0xFC // extended control code
+#define PLACEHOLDER_BEGIN 0xFD // string placeholder
+#define EOS 0xFF // end of string
+
enum StringConvertMode
{
STR_CONV_MODE_LEFT_ALIGN,
diff --git a/iwram_syms.txt b/iwram_syms.txt
index cbcd2de7b..5f6e9a8ab 100644
--- a/iwram_syms.txt
+++ b/iwram_syms.txt
@@ -1,5 +1,12 @@
+gRtcErrorFlags = 0x3000458;
+gRtcInfo = 0x3000460;
+gRtcProbeResult = 0x300046C;
+gRtcSavedIme = 0x300046E;
+
gPlayTimeCounterState = 0x300057C;
gRtcLocked = 0x3000F36;
gUnknownStringVar = 0x3002900;
+
+gLocalTime = 0x3004038;
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)();