diff options
-rw-r--r-- | arm9/asm/OS_tick.s | 165 | ||||
-rw-r--r-- | arm9/lib/include/OS_interrupt.h | 4 | ||||
-rw-r--r-- | arm9/lib/include/OS_tick.h | 9 | ||||
-rw-r--r-- | arm9/lib/include/OS_timer.h | 32 | ||||
-rw-r--r-- | arm9/lib/include/registers.h | 6 | ||||
-rw-r--r-- | arm9/lib/src/OS_tick.c | 70 |
6 files changed, 120 insertions, 166 deletions
diff --git a/arm9/asm/OS_tick.s b/arm9/asm/OS_tick.s deleted file mode 100644 index 3891f8c7..00000000 --- a/arm9/asm/OS_tick.s +++ /dev/null @@ -1,165 +0,0 @@ - .include "asm/macros.inc" - .include "global.inc" - - .section .bss - - .global OSi_UseTick -OSi_UseTick: ; 0x021D37AC - .space 0x4 - - .global OSi_NeedResetTimer -OSi_NeedResetTimer: ; 0x021D37B0 - .space 0x4 - - .global OSi_TickCounter -OSi_TickCounter: ; 0x021D37B4 - .space 0x8 - - .text - - arm_func_start OS_GetTickLo -OS_GetTickLo: ; 0x020CCC0C - ldr r0, _020CCC18 ; =0x04000100 - ldrh r0, [r0, #0x0] - bx lr - .balign 4 -_020CCC18: .word 0x04000100 - - arm_func_start OS_GetTick -OS_GetTick: ; 0x020CCC1C - stmdb sp!, {lr} - sub sp, sp, #0xc - bl OS_DisableInterrupts - ldr r1, _020CCCBC ; =0x04000100 - ldr r3, _020CCCC0 ; =OSi_TickCounter - ldrh r12, [r1, #0x0] - ldr r2, _020CCCC4 ; =0x0000FFFF - mvn r1, #0x0 - strh r12, [sp, #0x0] - ldr r12, [r3, #0x0] - ldr r3, [r3, #0x4] - and r1, r12, r1 - and r2, r3, r2 - str r1, [sp, #0x4] - ldr r1, _020CCCC8 ; =0x04000214 - str r2, [sp, #0x8] - ldr r1, [r1, #0x0] - ands r1, r1, #0x8 - beq _020CCC90 - ldrh r1, [sp, #0x0] - ands r1, r1, #0x8000 - bne _020CCC90 - ldr r3, [sp, #0x4] - mov r1, #0x1 - ldr r2, [sp, #0x8] - adds r3, r3, r1 - adc r1, r2, #0x0 - str r3, [sp, #0x4] - str r1, [sp, #0x8] -_020CCC90: - bl OS_RestoreInterrupts - ldr r2, [sp, #0x4] - ldr r1, [sp, #0x8] - ldrh r0, [sp, #0x0] - mov r1, r1, lsl #0x10 - orr r1, r1, r2, lsr #0x10 - orr r1, r1, r0, asr #0x1f - orr r0, r0, r2, lsl #0x10 - add sp, sp, #0xc - ldmia sp!, {lr} - bx lr - .balign 4 -_020CCCBC: .word 0x04000100 -_020CCCC0: .word OSi_TickCounter -_020CCCC4: .word 0x0000FFFF -_020CCCC8: .word 0x04000214 - - arm_func_start OSi_CountUpTick -OSi_CountUpTick: ; 0x020CCCCC - stmdb sp!, {lr} - sub sp, sp, #0x4 - ldr r2, _020CCD40 ; =OSi_TickCounter - ldr r1, _020CCD44 ; =OSi_NeedResetTimer - ldr r12, [r2, #0x0] - mov r0, #0x1 - ldr r3, [r2, #0x4] - adds r12, r12, r0 - ldr r0, [r1, #0x0] - adc r3, r3, #0x0 - str r12, [r2, #0x0] - str r3, [r2, #0x4] - cmp r0, #0x0 - mov r3, #0x0 - beq _020CCD24 - ldr r2, _020CCD48 ; =0x04000102 - ldr r0, _020CCD4C ; =0x04000100 - strh r3, [r2, #0x0] - strh r3, [r0, #0x0] - mov r0, #0xc1 - strh r0, [r2, #0x0] - str r3, [r1, #0x0] -_020CCD24: - mov r0, #0x0 - ldr r1, _020CCD50 ; =OSi_CountUpTick - mov r2, r0 - bl OSi_EnterTimerCallback - add sp, sp, #0x4 - ldmia sp!, {lr} - bx lr - .balign 4 -_020CCD40: .word OSi_TickCounter -_020CCD44: .word OSi_NeedResetTimer -_020CCD48: .word 0x04000102 -_020CCD4C: .word 0x04000100 -_020CCD50: .word OSi_CountUpTick - - arm_func_start OS_IsTickAvailable -OS_IsTickAvailable: ; 0x020CCD54 - ldr r0, _020CCD60 ; =OSi_UseTick - ldrh r0, [r0, #0x0] - bx lr - .balign 4 -_020CCD60: .word OSi_UseTick - - arm_func_start OS_InitTick -OS_InitTick: ; 0x020CCD64 - stmdb sp!, {lr} - sub sp, sp, #0x4 - ldr r1, _020CCDE8 ; =OSi_UseTick - ldrh r0, [r1, #0x0] - cmp r0, #0x0 - addne sp, sp, #0x4 - ldmneia sp!, {lr} - bxne lr - mov r2, #0x1 - mov r0, #0x0 - strh r2, [r1, #0x0] - bl OSi_SetTimerReserved - ldr r0, _020CCDEC ; =OSi_TickCounter - mov r2, #0x0 - str r2, [r0, #0x0] - ldr r3, _020CCDF0 ; =0x04000102 - str r2, [r0, #0x4] - ldr r0, _020CCDF4 ; =0x04000100 - strh r2, [r3, #0x0] - ldr r1, _020CCDF8 ; =OSi_CountUpTick - strh r2, [r0, #0x0] - mov r2, #0xc1 - mov r0, #0x8 - strh r2, [r3, #0x0] - bl OS_SetIrqFunction - mov r0, #0x8 - bl OS_EnableIrqMask - ldr r0, _020CCDFC ; =OSi_NeedResetTimer - mov r1, #0x0 - str r1, [r0, #0x0] - add sp, sp, #0x4 - ldmia sp!, {lr} - bx lr - .balign 4 -_020CCDE8: .word OSi_UseTick -_020CCDEC: .word OSi_TickCounter -_020CCDF0: .word 0x04000102 -_020CCDF4: .word 0x04000100 -_020CCDF8: .word OSi_CountUpTick -_020CCDFC: .word OSi_NeedResetTimer diff --git a/arm9/lib/include/OS_interrupt.h b/arm9/lib/include/OS_interrupt.h index ec58a636..481e6c6c 100644 --- a/arm9/lib/include/OS_interrupt.h +++ b/arm9/lib/include/OS_interrupt.h @@ -1,9 +1,11 @@ #ifndef POKEDIAMOND_ARM9_OS_INTERRUPT_H #define POKEDIAMOND_ARM9_OS_INTERRUPT_H -#include "nitro/types.h" +#include "consts.h" #include "nitro/OS_interrupt_shared.h" +#define OS_IE_TIMER0 (1UL << REG_OS_IE_T0_SHIFT) + typedef void (*OSIrqFunction) (void); typedef struct diff --git a/arm9/lib/include/OS_tick.h b/arm9/lib/include/OS_tick.h index f1c7145d..3dba9818 100644 --- a/arm9/lib/include/OS_tick.h +++ b/arm9/lib/include/OS_tick.h @@ -2,6 +2,7 @@ #define POKEDIAMOND_OS_TICK_H #include "consts.h" +#include "OS_timer.h" typedef u64 OSTick; @@ -9,4 +10,12 @@ typedef u64 OSTick; #define OS_MilliSecondsToTicks(msec) ((OSTick)(((OS_SYSTEM_CLOCK/1000) * (u64)(msec)) / 64)) +#define OSi_TICK_TIMERCONTROL (REG_OS_TM0CNT_H_E_MASK | REG_OS_TM0CNT_H_I_MASK | OS_TIMER_PRESCALER_64) + +void OS_InitTick(void); +BOOL OS_IsTickAvailable(void); +static void OSi_CountUpTick(void); +OSTick OS_GetTick(void); +u16 OS_GetTickLo(void); + #endif //POKEDIAMOND_OS_TICK_H diff --git a/arm9/lib/include/OS_timer.h b/arm9/lib/include/OS_timer.h new file mode 100644 index 00000000..8b2a97a9 --- /dev/null +++ b/arm9/lib/include/OS_timer.h @@ -0,0 +1,32 @@ +#ifndef POKEDIAMOND_OS_TIMER_H +#define POKEDIAMOND_OS_TIMER_H + +#include "consts.h" + +typedef enum +{ + OS_TIMER_PRESCALER_1 = (0UL << REG_OS_TM0CNT_H_PS_SHIFT), + OS_TIMER_PRESCALER_64 = (1UL << REG_OS_TM0CNT_H_PS_SHIFT), + OS_TIMER_PRESCALER_256 = (2UL << REG_OS_TM0CNT_H_PS_SHIFT), + OS_TIMER_PRESCALER_1024 = (3UL << REG_OS_TM0CNT_H_PS_SHIFT) +} OSTimerPrescaler; + +typedef enum +{ + OS_TIMER_0 = 0, + OS_TIMER_1 = 1, + OS_TIMER_2 = 2, + OS_TIMER_3 = 3 +} OSTimer; + +static inline void OS_SetTimerCount(OSTimer id, u16 count) +{ + *((REGType16 *)((u32)®_OS_TM0CNT_L + id * 4)) = count; +} + +static inline void OS_SetTimerControl(OSTimer id, u16 control) +{ + *((REGType16 *)((u32)®_OS_TM0CNT_H + id * 4)) = control; +} + +#endif //POKEDIAMOND_OS_TIMER_H diff --git a/arm9/lib/include/registers.h b/arm9/lib/include/registers.h index 4781ba1b..06f96d5a 100644 --- a/arm9/lib/include/registers.h +++ b/arm9/lib/include/registers.h @@ -356,6 +356,12 @@ #define reg_MI_MCD1 (*(REGType32v *)0x4100010) #define reg_CARD_DATA (*(REGType32v *)0x4100010) //? +#define REG_OS_TM0CNT_H_PS_SHIFT 0 +#define REG_OS_IE_T0_SHIFT 3 + +#define REG_OS_TM0CNT_H_I_MASK 0x0040 +#define REG_OS_TM0CNT_H_E_MASK 0x0080 + #define REG_PAD_KEYINPUT_L_SHIFT 9 #define REG_PAD_KEYINPUT_L_SIZE 1 #define REG_PAD_KEYINPUT_L_MASK 0x0200 diff --git a/arm9/lib/src/OS_tick.c b/arm9/lib/src/OS_tick.c new file mode 100644 index 00000000..f5f2df30 --- /dev/null +++ b/arm9/lib/src/OS_tick.c @@ -0,0 +1,70 @@ +#include "function_target.h" +#include "OS_tick.h" +#include "OS_interrupt.h" +#include "OS_timer.h" +#include "OS_system.h" + +static u16 OSi_UseTick = FALSE; +vu64 OSi_TickCounter; +BOOL OSi_NeedResetTimer = FALSE; + +extern void OSi_SetTimerReserved(u32 param1); + +ARM_FUNC void OS_InitTick(void) +{ + if (OSi_UseTick) + { + return; + } + OSi_UseTick = 1; + OSi_SetTimerReserved(0); + OSi_TickCounter = 0; + reg_OS_TM0CNT_H = 0; + reg_OS_TM0CNT_L = 0; + reg_OS_TM0CNT_H = 0xc1; + OS_SetIrqFunction(8, OSi_CountUpTick); + (void)OS_EnableIrqMask(8); + OSi_NeedResetTimer = FALSE; +} + +ARM_FUNC BOOL OS_IsTickAvailable(void) +{ + return OSi_UseTick; +} + +ARM_FUNC static void OSi_CountUpTick(void) +{ + OSi_TickCounter++; + + if (OSi_NeedResetTimer) + { + OS_SetTimerControl(OS_TIMER_0, 0); + OS_SetTimerCount(OS_TIMER_0, 0); + OS_SetTimerControl(OS_TIMER_0, OSi_TICK_TIMERCONTROL); + + OSi_NeedResetTimer = FALSE; + } + + OSi_EnterTimerCallback(OS_TIMER_0, (void (*)(void *))OSi_CountUpTick, 0); +} + +ARM_FUNC OSTick OS_GetTick(void) +{ + OSIntrMode prev = OS_DisableInterrupts(); + vu16 countL = *(REGType16 *)((u32)®_OS_TM0CNT_L + OS_TIMER_0 * 4); + vu64 countH = OSi_TickCounter & 0xffffffffffffULL; + + if (reg_OS_IF & OS_IE_TIMER0 && !(countL & 0x8000)) + { + countH++; + } + + (void)OS_RestoreInterrupts(prev); + + return (countH << 16) | countL; +} + +ARM_FUNC u16 OS_GetTickLo(void) +{ + return reg_OS_TM0CNT_L; +} |