summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm9/asm/OS_tick.s165
-rw-r--r--arm9/lib/include/OS_interrupt.h4
-rw-r--r--arm9/lib/include/OS_tick.h9
-rw-r--r--arm9/lib/include/OS_timer.h32
-rw-r--r--arm9/lib/include/registers.h6
-rw-r--r--arm9/lib/src/OS_tick.c70
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)&reg_OS_TM0CNT_L + id * 4)) = count;
+}
+
+static inline void OS_SetTimerControl(OSTimer id, u16 control)
+{
+ *((REGType16 *)((u32)&reg_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)&reg_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;
+}