summaryrefslogtreecommitdiff
path: root/arm7/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arm7/lib')
-rw-r--r--arm7/lib/include/MI_dma.h6
-rw-r--r--arm7/lib/include/OS_spinLock.h28
-rw-r--r--arm7/lib/include/mmap.h2
-rw-r--r--arm7/lib/include/syscall.h6
-rw-r--r--arm7/lib/src/OS_spinLock.c192
-rw-r--r--arm7/lib/src/OS_system.c3
6 files changed, 232 insertions, 5 deletions
diff --git a/arm7/lib/include/MI_dma.h b/arm7/lib/include/MI_dma.h
index b728f814..e65f0b89 100644
--- a/arm7/lib/include/MI_dma.h
+++ b/arm7/lib/include/MI_dma.h
@@ -1,7 +1,7 @@
-#ifndef GUARD_MI_DMA_H
-#define GUARD_MI_DMA_H
+#ifndef POKEDIAMOND_ARM7_MI_DMA_H
+#define POKEDIAMOND_ARM7_MI_DMA_H
-#include "nitro/dma.h"
+#include "nitro/MI_dma_shared.h"
#include "nitro/types.h"
void MI_StopDma(u32 channel);
diff --git a/arm7/lib/include/OS_spinLock.h b/arm7/lib/include/OS_spinLock.h
new file mode 100644
index 00000000..f7366d1f
--- /dev/null
+++ b/arm7/lib/include/OS_spinLock.h
@@ -0,0 +1,28 @@
+#ifndef POKEDIAMOND_ARM7_OS_SPINLOCK_H
+#define POKEDIAMOND_ARM7_OS_SPINLOCK_H
+
+#include "consts.h"
+#include "nitro/OS_spinLock_shared.h"
+#include "syscall.h"
+
+void OS_InitLock(void);
+void FUN_037F8CB4(s32 ct);
+s32 OSi_DoLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void), BOOL disableFiq);
+s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), BOOL disableFIQ);
+s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), BOOL disableFiq);
+s32 OS_LockCartridge(u16 lockID);
+s32 OS_UnlockCartridge(u16 lockID);
+s32 OS_TryLockCartridge(u16 lockID);
+void OSi_AllocateCartridgeBus(void);
+void OSi_FreeCartridgeBus(void);
+u16 OS_ReadOwnerOfLockWord(OSLockWord * lock);
+s32 OS_UnLockCartridge(u16 lockID);
+s32 OS_GetLockID(void);
+void OS_ReleaseLockID(register u16 lockID);
+
+static inline void OSi_WaitByLoop(void)
+{
+ FUN_037F8CB4(0x1000 / 4);
+}
+
+#endif //POKEDIAMOND_ARM7_OS_SPINLOCK_H
diff --git a/arm7/lib/include/mmap.h b/arm7/lib/include/mmap.h
index 24d15ad7..064938e2 100644
--- a/arm7/lib/include/mmap.h
+++ b/arm7/lib/include/mmap.h
@@ -23,4 +23,6 @@
#define HW_PRV_WRAM_SYSRV (HW_PRV_WRAM + HW_PRV_WRAM_SIZE - HW_PRV_WRAM_SYSRV_SIZE)
+#define HW_LOCK_ID_FLAG_SUB (HW_MAIN_MEM + 0x007fffb8)
+
#endif //POKEDIAMOND_ARM7_MMAP_H
diff --git a/arm7/lib/include/syscall.h b/arm7/lib/include/syscall.h
new file mode 100644
index 00000000..55462cc7
--- /dev/null
+++ b/arm7/lib/include/syscall.h
@@ -0,0 +1,6 @@
+#ifndef POKEDIAMOND_ARM7_SYSCALL_H
+#define POKEDIAMOND_ARM7_SYSCALL_H
+
+void SVC_WaitByLoop(u32 ct);
+
+#endif //POKEDIAMOND_ARM7_SYSCALL_H
diff --git a/arm7/lib/src/OS_spinLock.c b/arm7/lib/src/OS_spinLock.c
new file mode 100644
index 00000000..2857de05
--- /dev/null
+++ b/arm7/lib/src/OS_spinLock.c
@@ -0,0 +1,192 @@
+#include "function_target.h"
+#include "OS_spinLock.h"
+#include "OS_system.h"
+#include "MI_swap.h"
+
+ARM_FUNC void OS_InitLock(void)
+{
+ static BOOL isInitialized = FALSE;
+
+ if (isInitialized)
+ return;
+ isInitialized = TRUE;
+
+ OSLockWord *lockp = (OSLockWord *)HW_INIT_LOCK_BUF;
+
+ lockp->extension = 0;
+ while (lockp->ownerID != 0x7f)
+ {
+ OSi_WaitByLoop();
+ }
+
+ ((u32 *)HW_LOCK_ID_FLAG_SUB)[0] = 0xffffffff;
+ ((u32 *)HW_LOCK_ID_FLAG_SUB)[1] = 0xffff0000;
+
+ lockp->extension = 0xbf;
+}
+
+ARM_FUNC void FUN_037F8CB4(s32 ct)
+{
+ SVC_WaitByLoop((u32)ct); //todo this should be linker generated, figure out why it broke
+}
+
+ARM_FUNC s32 OSi_DoLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void),
+ BOOL disableFiq)
+{
+ s32 lastLockFlag;
+ while ((lastLockFlag = OSi_DoTryLockByWord(lockId, lockp, ctrlFuncp, disableFiq)) > 0) {
+ OSi_WaitByLoop();
+ }
+
+ return lastLockFlag;
+}
+
+ARM_FUNC s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
+ BOOL disableFIQ)
+{
+ if (lockID != lockp->ownerID)
+ {
+ return -2;
+ }
+
+ OSIntrMode lastIntrMode = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts();
+ lockp->ownerID = 0;
+ if (ctrlFuncp)
+ {
+ ctrlFuncp();
+ }
+ lockp->lockFlag = 0;
+ if (disableFIQ)
+ {
+ (void)OS_RestoreInterrupts_IrqAndFiq(lastIntrMode);
+ }
+ else
+ {
+ (void)OS_RestoreInterrupts(lastIntrMode);
+ }
+ return 0;
+}
+
+ARM_FUNC s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
+ BOOL disableFiq)
+{
+ OSIntrMode lastIntrMode = (disableFiq) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts();
+
+ s32 lastLockFlag = (s32)MI_SwapWord(lockID, (u32 *)&lockp->lockFlag);
+
+ if (!lastLockFlag)
+ {
+ if (ctrlFuncp)
+ {
+ ctrlFuncp();
+ }
+ lockp->ownerID = lockID;
+ }
+
+ if (disableFiq)
+ {
+ (void)OS_RestoreInterrupts_IrqAndFiq(lastIntrMode);
+ }
+ else
+ {
+ (void)OS_RestoreInterrupts(lastIntrMode);
+ }
+
+ return lastLockFlag;
+}
+
+ARM_FUNC s32 OS_LockCartridge(u16 lockID)
+{
+ return OSi_DoLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE);
+}
+
+ARM_FUNC s32 OS_UnlockCartridge(u16 lockID)
+{
+ return OSi_DoUnlockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_FreeCartridgeBus, TRUE);
+}
+
+ARM_FUNC s32 OS_TryLockCartridge(u16 lockID)
+{
+ return OSi_DoTryLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE);
+}
+
+ARM_FUNC void OSi_AllocateCartridgeBus(void)
+{
+ //noop
+}
+
+ARM_FUNC void OSi_FreeCartridgeBus(void)
+{
+ //noop
+}
+
+ARM_FUNC u16 OS_ReadOwnerOfLockWord(OSLockWord * lock)
+{
+ return lock->ownerID;
+}
+
+ARM_FUNC asm s32 OS_UnLockCartridge(u16 lockID)
+{
+ ldr r1, =OS_UnlockCartridge
+ bx r1
+}
+
+ARM_FUNC asm s32 OS_GetLockID(void)
+{
+ ldr r3, =HW_LOCK_ID_FLAG_SUB
+ ldr r1, [r3]
+ mov r2, #0
+ mov r0, #0x80000000
+_037F8A34:
+ tst r1, r0
+ bne _037F8A50
+ add r2, r2, #1
+ cmp r2, #32
+ beq _037F8A50
+ mov r0, r0, lsr #1
+ b _037F8A34
+_037F8A50:
+ cmp r2, #32
+ movne r0, #0x80
+ bne _037F8A98
+ add r3, r3, #4
+ ldr r1, [r3]
+ mov r2, #0
+ mov r0, #0x80000000
+_037F8A6C:
+ tst r1, r0
+ bne _037F8A88
+ add r2, r2, #1
+ cmp r2, #32
+ beq _037F8A88
+ mov r0, r0, lsr #1
+ b _037F8A6C
+_037F8A88:
+ cmp r2, #32
+ ldr r0, =0xFFFFFFFD
+ bxeq lr
+ mov r0, #160
+_037F8A98:
+ add r0, r0, r2
+ mov r1, #0x80000000
+ mov r1, r1, lsr r2
+ ldr r2, [r3]
+ bic r2, r2, r1
+ str r2, [r3]
+ bx lr
+}
+
+ARM_FUNC asm void OS_ReleaseLockID(register u16 lockID)
+{
+ ldr r3, =HW_LOCK_ID_FLAG_SUB
+ cmp r0, #0xa0
+ addpl r3, r3, #0x4
+ subpl r0, r0, #0xa0
+ submi r0, r0, #0x80
+ mov r1, #0x80000000
+ mov r1, r1, lsr r0
+ ldr r2, [r3, #0x0]
+ orr r2, r2, r1
+ str r2, [r3, #0x0]
+ bx lr
+}
diff --git a/arm7/lib/src/OS_system.c b/arm7/lib/src/OS_system.c
index 11417e91..503bd854 100644
--- a/arm7/lib/src/OS_system.c
+++ b/arm7/lib/src/OS_system.c
@@ -1,7 +1,6 @@
#include "function_target.h"
#include "OS_system.h"
-
-extern void FUN_037F8CB4(s32 count);
+#include "OS_spinLock.h"
ARM_FUNC asm OSIntrMode OS_EnableInterrupts(void)
{