diff options
author | YamaArashi <shadow962@live.com> | 2016-02-03 00:26:25 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-02-03 00:26:25 -0800 |
commit | 5fd538d1802b2ae9e3e854140f68cb45fe50e97a (patch) | |
tree | a7d3cc4b70435a6cc4a94b4497307393d743f28d | |
parent | 6f965a9eca507c27049fbd90a57f620b63c92d6d (diff) |
RTC code/data
-rw-r--r-- | asm/crt0.s | 2 | ||||
-rw-r--r-- | asm/rom.s | 836 | ||||
-rw-r--r-- | data/data2.s | 7 | ||||
-rw-r--r-- | data/rtc_util.s | 32 | ||||
-rw-r--r-- | include/gba/gba.h | 34 | ||||
-rw-r--r-- | include/global.h | 40 | ||||
-rw-r--r-- | include/rtc.h | 54 | ||||
-rw-r--r-- | include/rtc_util.h | 20 | ||||
-rw-r--r-- | include/string_util.h | 10 | ||||
-rw-r--r-- | iwram_syms.txt | 7 | ||||
-rw-r--r-- | src/librtc.c | 174 | ||||
-rw-r--r-- | src/rtc_util.c | 335 | ||||
-rw-r--r-- | src/string_util.c | 7 |
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 @@ -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)(); |