mirror of
https://github.com/pret/pokediamond.git
synced 2026-09-10 01:56:24 -05:00
arm9 OS_tick
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
32
arm9/lib/include/OS_timer.h
Normal file
32
arm9/lib/include/OS_timer.h
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
70
arm9/lib/src/OS_tick.c
Normal file
70
arm9/lib/src/OS_tick.c
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user