summaryrefslogtreecommitdiff
path: root/arm9/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/lib')
-rw-r--r--arm9/lib/include/CP_context.h3
-rw-r--r--arm9/lib/include/OS_irqHandler.h2
-rw-r--r--arm9/lib/include/OS_thread.h2
-rw-r--r--arm9/lib/src/OS_irqHandler.c121
4 files changed, 128 insertions, 0 deletions
diff --git a/arm9/lib/include/CP_context.h b/arm9/lib/include/CP_context.h
index d1e0062c..cfed9735 100644
--- a/arm9/lib/include/CP_context.h
+++ b/arm9/lib/include/CP_context.h
@@ -15,4 +15,7 @@ typedef struct CPContext {
u16 sqrt_mode;
} CPContext;
+void CP_SaveContext(CPContext *context);
+void CPi_RestoreContext(const CPContext* context);
+
#endif //POKEDIAMOND_CP_CONTEXT_H
diff --git a/arm9/lib/include/OS_irqHandler.h b/arm9/lib/include/OS_irqHandler.h
index 17bde1c9..f052016d 100644
--- a/arm9/lib/include/OS_irqHandler.h
+++ b/arm9/lib/include/OS_irqHandler.h
@@ -14,6 +14,8 @@ static inline OSIrqMask OS_GetIrqCheckFlag(void)
return *(OSIrqMask *)HW_INTR_CHECK_BUF;
}
+void OS_IrqHandler(void);
+void OS_IrqHandler_ThreadSwitch(void);
void OS_WaitIrq(BOOL param1, u32 param2);
#endif //POKEDIAMOND_OS_IRQHANDLER_H
diff --git a/arm9/lib/include/OS_thread.h b/arm9/lib/include/OS_thread.h
index adcadf2e..bbdb33c9 100644
--- a/arm9/lib/include/OS_thread.h
+++ b/arm9/lib/include/OS_thread.h
@@ -87,6 +87,8 @@ struct _OSThread
u32 systemErrno;
};
+extern OSThreadInfo OSi_ThreadInfo;
+
void OS_SleepThread(OSThreadQueue * queue);
void OS_WakeupThread(OSThreadQueue * queue);
diff --git a/arm9/lib/src/OS_irqHandler.c b/arm9/lib/src/OS_irqHandler.c
index 31f4453e..b1211b98 100644
--- a/arm9/lib/src/OS_irqHandler.c
+++ b/arm9/lib/src/OS_irqHandler.c
@@ -3,11 +3,132 @@
#include "OS_system.h"
#include "OS_thread.h"
#include "sections.h"
+#include "CP_context.h"
#pragma section DTCM begin
OSThreadQueue OSi_IrqThreadQueue = { NULL, NULL };
#pragma section DTCM end
+#pragma section ITCM begin
+ARM_FUNC asm void OS_IrqHandler(void)
+{
+ stmfd sp!, {lr}
+ mov ip, #0x04000000
+ add ip, ip, #0x210
+ ldr r1, [ip, #-8]
+ cmp r1, #0
+ ldmeqfd sp!, {pc}
+ ldmia ip, {r1, r2}
+ ands r1, r1, r2
+ ldmeqfd sp!, {pc}
+ mov r3, #0x80000000
+_01FF8028:
+ clz r0, r1
+ bics r1, r1, r3, lsr r0
+ bne _01FF8028
+ mov r1, r3, lsr r0
+ str r1, [ip, #0x4]
+ rsbs r0, r0, #0x1f
+ ldr r1, =OS_IRQTable
+ ldr r0, [r1, r0, lsl #2]
+ ldr lr, =OS_IrqHandler_ThreadSwitch
+ bx r0
+}
+
+ARM_FUNC asm void OS_IrqHandler_ThreadSwitch(void)
+{
+ ldr ip, =OSi_IrqThreadQueue
+ mov r3, #0x0
+ ldr ip, [ip]
+ mov r2, #0x1
+ cmp ip, #0x0
+ beq _01FF80A8
+_01FF8070:
+ str r2, [ip, #0x64]
+ str r3, [ip, #0x78]
+ str r3, [ip, #0x7c]
+ ldr r0, [ip, #0x80]
+ str r3, [ip, #0x80]
+ mov ip, r0
+ cmp ip, #0x0
+bne _01FF8070
+ ldr ip, =OSi_IrqThreadQueue
+ str r3, [ip]
+ str r3, [ip, #0x4]
+ ldr ip, =OSi_ThreadInfo
+ mov r1, #0x1
+ strh r1, [ip]
+_01FF80A8:
+ ldr ip, =OSi_ThreadInfo
+ ldrh r1, [ip]
+ cmp r1, #0x0
+ ldreq pc, [sp], #0x4
+ mov r1, #0x0
+ strh r1, [ip]
+ mov r3, #0xd2
+ msr CPSR_c, r3
+ add r2, ip, #0x8
+ ldr r1, [r2]
+_01FF80D0:
+ cmp r1, #0x0
+ ldrneh r0, [r1, #0x64]
+ cmpne r0, #0x1
+ ldrne r1, [r1, #0x68]
+ bne _01FF80D0
+ cmp r1, #0x0
+ bne _01FF80F8
+_01FF80EC:
+ mov r3, #0x92
+ msr CPSR_c, r3
+ ldr pc, [sp], #0x4
+_01FF80F8:
+ ldr r0, [ip, #0x4]
+ cmp r1, r0
+ beq _01FF80EC
+ ldr r3, [ip, #0xC]
+ cmp r3, #0x0
+ beq _01FF8120
+ stmdb sp!, {r0, r1, ip}
+ mov lr, pc
+ bx r3
+ ldmia sp!, {r0, r1, ip}
+_01FF8120:
+ str r1, [ip, #0x4]
+ mrs r2, SPSR
+ str r2, [r0, #0x0]!
+ stmdb sp!, {r0, r1}
+ add r0, r0, #0x0
+ add r0, r0, #0x48
+ ldr r1, =CP_SaveContext
+ blx r1
+ ldmia sp!, {r0, r1}
+ ldmib sp!, {r2, r3}
+ stmib r0!, {r2, r3}
+ ldmib sp!, {r2, r3, ip, lr}
+ stmib r0!, {r2-r14}^
+ stmib r0!, {lr}
+ mov r3, #0xd3
+ msr CPSR_c, r3
+ stmib r0!, {sp}
+ stmfd sp!, {r1}
+ add r0, r1, #0x0
+ add r0, r0, #0x48
+ ldr r1, =CPi_RestoreContext
+ blx r1
+ ldmfd sp!, {r1}
+ ldr sp, [r1, #0x44]
+ mov r3, #0xd2
+ msr CPSR_c, r3
+ ldr r2, [r1, #0x0]!
+ msr SPSR_fc, r2
+ ldr lr, [r1, #0x40]
+ ldmib r1!, {r0-r14}^
+ nop
+ stmda sp!, {r0, r1, r2, r3, ip, lr}
+ ldmfd sp!, {pc}
+}
+#pragma section ITCM end
+
ARM_FUNC void OS_WaitIrq(BOOL clear, OSIrqMask irqFlags)
{
OSIntrMode lastIntrMode = OS_DisableInterrupts();