summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/nitro/consts.h45
-rw-r--r--include/nitro/mmap.h45
-rw-r--r--include/nitro/nitro.h6
-rw-r--r--include/nitro/os.c33
-rw-r--r--include/nitro/os.h9
-rw-r--r--include/nitro/os_alloc.c257
-rw-r--r--include/nitro/os_alloc.h38
-rw-r--r--include/nitro/os_arena.c539
-rw-r--r--include/nitro/os_arena.h41
-rw-r--r--include/nitro/os_asm.h12
-rw-r--r--include/nitro/os_asm.s7
-rw-r--r--include/nitro/os_protectionRegion.c17
-rw-r--r--include/nitro/os_protectionRegion.h47
-rw-r--r--include/nitro/os_system.c28
-rw-r--r--include/nitro/os_system.h44
-rw-r--r--include/nitro/types.h10
16 files changed, 1144 insertions, 34 deletions
diff --git a/include/nitro/consts.h b/include/nitro/consts.h
new file mode 100644
index 00000000..6fc71be2
--- /dev/null
+++ b/include/nitro/consts.h
@@ -0,0 +1,45 @@
+//
+// Created by mart on 4/15/20.
+//
+
+#ifndef POKEDIAMOND_CONSTS_H
+#define POKEDIAMOND_CONSTS_H
+
+#include "mmap.h"
+
+#define HW_PSR_CPU_MODE_MASK 0x1f // CPU mode
+
+#define HW_PSR_FIQ_DISABLE 0x40 // Disable FIQ
+#define HW_PSR_IRQ_DISABLE 0x80 // Disable IRQ
+#define HW_PSR_IRQ_FIQ_DISABLE 0xc0 // Disable FIQ and IRQ
+
+#define HW_C6_PR_4KB 0x16
+#define HW_C6_PR_8KB 0x18
+#define HW_C6_PR_16KB 0x1a
+#define HW_C6_PR_32KB 0x1c
+#define HW_C6_PR_64KB 0x1e
+#define HW_C6_PR_128KB 0x20
+#define HW_C6_PR_256KB 0x22
+#define HW_C6_PR_512KB 0x24
+#define HW_C6_PR_1MB 0x26
+#define HW_C6_PR_2MB 0x28
+#define HW_C6_PR_4MB 0x2a
+#define HW_C6_PR_8MB 0x2c
+#define HW_C6_PR_16MB 0x2e
+#define HW_C6_PR_32MB 0x30
+#define HW_C6_PR_64MB 0x32
+#define HW_C6_PR_128MB 0x34
+#define HW_C6_PR_256MB 0x36
+#define HW_C6_PR_512MB 0x38
+#define HW_C6_PR_1GB 0x3a
+#define HW_C6_PR_2GB 0x3c
+#define HW_C6_PR_4GB 0x3e
+
+#define OS_CONSOLE_SIZE_MASK 0x00000003
+#define OS_CONSOLE_SIZE_4MB 0x00000001
+
+#define OSi_GetArenaInfo() (*(OSArenaInfo*)HW_ARENA_INFO_BUF)
+#define OSi_TRUNC(n, a) (((u32) (n)) & ~((a) - 1))
+#define OSi_ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1))
+
+#endif //POKEDIAMOND_CONSTS_H
diff --git a/include/nitro/mmap.h b/include/nitro/mmap.h
new file mode 100644
index 00000000..14820c39
--- /dev/null
+++ b/include/nitro/mmap.h
@@ -0,0 +1,45 @@
+#ifndef NITRO_MMAP_H
+#define NITRO_MMAP_H
+
+#include "types.h"
+
+extern u32 SDK_AUTOLOAD_DTCM_START[];
+
+#define HW_MAIN_MEM 0x02000000
+#define HW_MAIN_MEM_SIZE 0x00400000
+#define HW_MAIN_MEM_EX_SIZE 0x00800000
+#define HW_MAIN_MEM_MAIN_SIZE 0x003E0000
+#define HW_MAIN_MEM_SHARED_SIZE 0x00001000
+#define HW_MAIN_MEM_DEBUGGER_OFFSET 0x00700000
+
+#define HW_ITCM 0x01FF8000
+#define HW_ITCM_SIZE 0x00008000
+
+#define HW_WRAM 0x037F8000
+
+#define HW_DTCM ((u32)SDK_AUTOLOAD_DTCM_START)
+#define HW_DTCM_SIZE 0x00004000
+
+#define HW_CARD_ROM_HEADER_SIZE 0x00000160
+#define HW_DOWNLOAD_PARAMETER_SIZE 0x00000020
+
+#define HW_ARENA_INFO_BUF (HW_MAIN_MEM + 0x007ffda0) // Arena data structure
+#define HW_ROM_HEADER_BUF (HW_MAIN_MEM + 0x007ffe00) // ROM registration area data buffer
+#define HW_RED_RESERVED (HW_MAIN_MEM + 0x007ff800) // Some kind of reserved data for shared memory
+#define HW_MAIN_MEM_MAIN_END (HW_MAIN_MEM + HW_MAIN_MEM_MAIN_SIZE)
+#define HW_MAIN_MEM_EX_END (HW_MAIN_MEM + HW_MAIN_MEM_EX_SIZE)
+#define HW_MAIN_MEM_SHARED (HW_MAIN_MEM_EX_END - HW_MAIN_MEM_SHARED_SIZE)
+#define HW_DTCM_SVC_STACK_END (HW_DTCM + 0x00003fc0)
+#define HW_SVC_STACK_SIZE 0x00000040
+#define HW_DTCM_SVC_STACK (HW_DTCM_SVC_STACK_END - HW_SVC_STACK_SIZE)
+#define HW_DTCM_IRQ_STACK_END (HW_DTCM_SVC_STACK)
+
+#define OSi_MAIN_ARENA_HI_DEFAULT (HW_MAIN_MEM_MAIN_END)
+#define OSi_MAINEX_ARENA_HI_DEFAULT (HW_MAIN_MEM + HW_MAIN_MEM_DEBUGGER_OFFSET)
+#define HW_ITCM_ARENA_HI_DEFAULT (HW_ITCM + HW_ITCM_SIZE)
+#define HW_SHARED_ARENA_HI_DEFAULT (HW_RED_RESERVED - HW_CARD_ROM_HEADER_SIZE - HW_DOWNLOAD_PARAMETER_SIZE)
+#define HW_SHARED_ARENA_LO_DEFAULT (HW_MAIN_MEM_SHARED)
+#define OSi_WRAM_MAIN_ARENA_HI_DEFAULT (HW_WRAM)
+#define OSi_WRAM_MAIN_ARENA_LO_DEFAULT (HW_WRAM)
+
+#endif \ No newline at end of file
diff --git a/include/nitro/nitro.h b/include/nitro/nitro.h
index 017f3708..8cf603f5 100644
--- a/include/nitro/nitro.h
+++ b/include/nitro/nitro.h
@@ -6,8 +6,10 @@ extern "C" {
#endif
// Include all nitro files
-#include "nitro/types.h"
-#include "nitro/os.h"
+#include "types.h"
+#include "consts.h"
+#include "os.h"
+#include "mmap.h"
#ifdef __cplusplus
};
diff --git a/include/nitro/os.c b/include/nitro/os.c
index a531740d..2531a636 100644
--- a/include/nitro/os.c
+++ b/include/nitro/os.c
@@ -4,6 +4,35 @@
#include "os.h"
-asm void OS_GetProcMode() {
+extern void PXI_Init();
+extern void OS_InitLock();
+extern void OS_InitIrqTable();
+extern void OS_SetIrqStackChecker();
+extern void OS_InitException();
+extern void MI_Init();
+extern void OS_InitVAlarm();
+extern void OSi_InitVramExclusive();
+extern void OS_InitThread();
+extern void OS_InitReset();
+extern void CTRDG_Init();
+extern void CARD_Init();
+extern void PM_Init();
+
+void OS_Init(void) {
+ OS_InitArena();
+ PXI_Init();
+ OS_InitLock();
+ OS_InitArenaEx();
+ OS_InitIrqTable();
+ OS_SetIrqStackChecker();
+ OS_InitException();
+ MI_Init();
+ OS_InitVAlarm();
+ OSi_InitVramExclusive();
+ OS_InitThread();
+ OS_InitReset();
+ CTRDG_Init();
+ CARD_Init();
+ PM_Init();
+}
-} \ No newline at end of file
diff --git a/include/nitro/os.h b/include/nitro/os.h
index c14b2891..591d8db0 100644
--- a/include/nitro/os.h
+++ b/include/nitro/os.h
@@ -5,6 +5,13 @@
#ifndef POKEDIAMOND_OS_H
#define POKEDIAMOND_OS_H
-#include "nitro/os_asm.h"
+#include "types.h"
+#include "consts.h"
+#include "os_protectionRegion.h"
+#include "os_arena.h"
+#include "os_alloc.h"
+#include "os_system.h"
+
+void OS_Init();
#endif //POKEDIAMOND_OS_H
diff --git a/include/nitro/os_alloc.c b/include/nitro/os_alloc.c
new file mode 100644
index 00000000..9ba92e18
--- /dev/null
+++ b/include/nitro/os_alloc.c
@@ -0,0 +1,257 @@
+//
+// Created by mart on 4/23/20.
+//
+
+#include "os_alloc.h"
+#include "consts.h"
+#include "os_system.h"
+
+extern Cell* DLInsert(Cell* list, Cell* cell);
+extern Cell* DLAddFront(Cell* list, Cell* cell);
+
+void* OSiHeapInfo[OS_ARENA_MAX] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+#ifdef MATCH_ASM
+asm static Cell* DLExtract(Cell* list, Cell* cell)
+{
+ ldr r3, [r1, #0x4]
+ cmp r3, #0x0
+ ldrne r2, [r1, #0x0]
+ strne r2, [r3, #0x0]
+ ldr r2, [r1, #0x0]
+ cmp r2, #0x0
+ ldreq r0, [r1, #0x4]
+ ldrne r1, [r1, #0x4]
+ strne r1, [r2, #0x4]
+ bx lr
+}
+#else
+static Cell* DLExtract(Cell* list, Cell* cell)
+{
+ if (cell->next) {
+ cell->prev = cell->next->prev;
+ }
+ if (cell->prev) {
+ cell->prev->next = cell->next;
+ return list;
+ }
+ else {
+ return cell->next;
+ }
+}
+#endif
+
+#define HEADERSIZE OSi_ROUND(sizeof(Cell), 32)
+#define MINOBJSIZE (HEADERSIZE+32)
+
+#ifdef MATCH_ASM
+asm void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void* ptr) {
+ stmdb sp!, {r4-r7, lr}
+ sub sp,sp,#0x4
+ mov r7,r0
+ mov r5,r1
+ mov r4,r2
+ bl OS_DisableInterrupts
+ ldr r1,=OSiHeapInfo
+ mov r6,r0
+ ldr r0,[r1,r7,lsl #0x2]
+ cmp r5,#0x0
+ ldrlt r5,[r0,#0x0]
+ ldr r1,[r0,#0x10]
+ mov r0,#0xc
+ mla r7,r5,r0,r1
+ sub r4,r4,#0x20
+ ldr r0,[r7,#0x8]
+ mov r1,r4
+ bl DLExtract
+ str r0,[r7,#0x8]
+ ldr r0,[r7,#0x4]
+ mov r1,r4
+ bl DLInsert
+ str r0,[r7,#0x4]
+ mov r0,r6
+ bl OS_RestoreInterrupts
+ add sp,sp,#0x4
+ ldmia sp!,{ r4-r7, lr }
+ bx lr
+}
+#else
+void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void* ptr) {
+ OSHeapInfo *heapInfo;
+ HeapDesc *hd;
+ Cell *cell;
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ heapInfo = OSiHeapInfo[id];
+
+ if (heap < 0) {
+ heap = heapInfo->currentHeap;
+ }
+
+ cell = (Cell *) ((char *)ptr - HEADERSIZE);
+ hd = &heapInfo->heapArray[heap];
+
+ hd->allocated = DLExtract(hd->allocated, cell);
+ hd->free = DLInsert(hd->free, cell);
+
+ OS_RestoreInterrupts(enabled);
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size) {
+ stmdb sp!, {r4-r7,lr}
+ sub sp, sp, #0x4
+ mov r6, r0
+ mov r5, r1
+ mov r7, r2
+ bl OS_DisableInterrupts
+ ldr r1, =OSiHeapInfo
+ mov r4, r0
+ ldr r1, [r1, r6, lsl #0x2]
+ cmp r1, #0x0
+ bne _020CC7AC
+ bl OS_RestoreInterrupts
+ add sp, sp, #0x4
+ mov r0, #0x0
+ ldmia sp!, {r4-r7,lr}
+ bx lr
+_020CC7AC:
+ cmp r5, #0x0
+ ldrlt r5, [r1, #0x0]
+ ldr r1, [r1, #0x10]
+ mov r0, #0xc
+ mla r6, r5, r0, r1
+ ldr r0, [r6, #0x4]
+ add r1, r7, #0x20
+ add r1, r1, #0x1f
+ mov r5, r0
+ cmp r0, #0x0
+ bic r7, r1, #0x1f
+ beq _020CC7F4
+_020CC7DC:
+ ldr r1, [r5, #0x8]
+ cmp r7, r1
+ ble _020CC7F4
+ ldr r5, [r5, #0x4]
+ cmp r5, #0x0
+ bne _020CC7DC
+_020CC7F4:
+ cmp r5, #0x0
+ bne _020CC814
+ mov r0, r4
+ bl OS_RestoreInterrupts
+ add sp, sp, #0x4
+ mov r0, #0x0
+ ldmia sp!, {r4-r7,lr}
+ bx lr
+_020CC814:
+ ldr r1, [r5, #0x8]
+ sub r1, r1, r7
+ cmp r1, #0x40
+ bhs _020CC834
+ mov r1, r5
+ bl DLExtract
+ str r0, [r6, #0x4]
+ b _020CC86C
+_020CC834:
+ str r7, [r5, #0x8]
+ add r2, r5, r7
+ str r1, [r2, #0x8]
+ ldr r0, [r5, #0x0]
+ str r0, [r5, r7]
+ ldr r0, [r5, #0x4]
+ str r0, [r2, #0x4]
+ ldr r0, [r2, #0x4]
+ cmp r0, #0x0
+ strne r2, [r0, #0x0]
+ ldr r0, [r2, #0x0]
+ cmp r0, #0x0
+ strne r2, [r0, #0x4]
+ streq r2, [r6, #0x4]
+_020CC86C:
+ ldr r0, [r6, #0x8]
+ mov r1, r5
+ bl DLAddFront
+ str r0, [r6, #0x8]
+ mov r0, r4
+ bl OS_RestoreInterrupts
+ add r0, r5, #0x20
+ add sp, sp, #0x4
+ ldmia sp!, {r4-r7,lr}
+ bx lr
+}
+#else
+void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size) {
+ OSHeapInfo* heapInfo;
+ HeapDesc* hd;
+ Cell* cell;
+ Cell* newCell;
+ long leftoverSize;
+
+ OSIntrMode enabled = OS_DisableInterrupts();
+ heapInfo = OSiHeapInfo[id];
+ if (!heapInfo) {
+ OS_RestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ if (heap < 0) {
+ heap = heapInfo->currentHeap;
+ }
+
+ hd = &heapInfo->heapArray[heap];
+
+ size += HEADERSIZE;
+ size = OSi_ROUND(size, 32);
+
+ for (cell = hd->free; cell != NULL; cell = cell->next) {
+ if ((long)size <= cell->size) {
+ break;
+ }
+ }
+
+ if (cell == NULL) {
+ OS_RestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ leftoverSize = cell->size - (long)size;
+ if (leftoverSize < MINOBJSIZE) {
+ hd->free = DLExtract(hd->free, cell);
+ } else {
+ cell->size = (long)size;
+
+ newCell = (Cell *) ((char *)cell + size);
+ newCell->size = leftoverSize;
+
+ newCell->prev = cell->prev;
+ newCell->next = cell->next;
+
+ if (newCell->next != NULL) {
+ newCell->next->prev = newCell;
+ }
+
+ if (newCell->prev != NULL) {
+ newCell->prev->next = newCell;
+ } else {
+ hd->free = newCell;
+ }
+ }
+
+ hd->allocated = DLAddFront(hd->allocated, cell);
+
+ OS_RestoreInterrupts(enabled);
+ return (void *)((char *)cell + HEADERSIZE);
+}
+#endif \ No newline at end of file
diff --git a/include/nitro/os_alloc.h b/include/nitro/os_alloc.h
new file mode 100644
index 00000000..1c4b6122
--- /dev/null
+++ b/include/nitro/os_alloc.h
@@ -0,0 +1,38 @@
+//
+// Created by mart on 4/23/20.
+//
+
+#ifndef POKEDIAMOND_OS_ALLOC_H
+#define POKEDIAMOND_OS_ALLOC_H
+
+#include "types.h"
+#include "os_arena.h"
+
+typedef int OSHeapHandle;
+
+typedef struct Cell Cell;
+
+struct Cell {
+ Cell* prev;
+ Cell* next;
+ long size;
+};
+
+typedef struct {
+ long size;
+ Cell *free;
+ Cell *allocated;
+} HeapDesc;
+
+typedef struct {
+ volatile OSHeapHandle currentHeap;
+ int numHeaps;
+ void* arenaStart;
+ void* arenaEnd;
+ HeapDesc* heapArray;
+} OSHeapInfo;
+
+void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void *ptr);
+void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size);
+
+#endif //POKEDIAMOND_OS_ALLOC_H
diff --git a/include/nitro/os_arena.c b/include/nitro/os_arena.c
new file mode 100644
index 00000000..31d66289
--- /dev/null
+++ b/include/nitro/os_arena.c
@@ -0,0 +1,539 @@
+//
+// Created by red031000 on 2020-04-27.
+//
+
+#include "consts.h"
+#include "os_arena.h"
+#include "os_protectionRegion.h"
+
+extern u32 OS_GetConsoleType();
+extern BOOL OSi_MainExArenaEnabled;
+extern BOOL OSi_Initialized; // TODO: located at 0x021d36f0
+void SDK_MAIN_ARENA_LO(); // TODO: technically this should be defined in the lcf
+extern void SDK_SECTION_ARENA_EX_START(); // TODO: technically this should be defined in the lcf
+extern void SDK_SECTION_ARENA_ITCM_START(); // TODO: technically this should be defined in the lcf
+extern void SDK_SECTION_ARENA_DTCM_START(); // TODO: technically this should be defined in the lcf
+extern void SDK_IRQ_STACKSIZE(); // TODO: technically this should be defined in the lcf
+extern void SDK_SYS_STACKSIZE(); // TODO: technically this should be defined in the lcf
+
+#ifdef MATCH_ASM
+asm void OS_InitArena() {
+ stmdb sp!,{ lr }
+ sub sp,sp,#0x4
+ ldr r1, =OSi_Initialized
+ ldr r0,[r1,#0x0]
+ cmp r0,#0x0
+ addne sp,sp,#0x4
+ ldmneia sp!,{ lr }
+ bxne lr
+ mov r2,#0x1
+ mov r0,#0x0
+ str r2,[r1,#0x0]
+ bl OS_GetInitArenaHi
+ mov r1,r0
+ mov r0,#0x0
+ bl OS_SetArenaHi
+ mov r0,#0x0
+ bl OS_GetInitArenaLo
+ mov r1,r0
+ mov r0,#0x0
+ bl OS_SetArenaLo
+ mov r0,#0x2
+ mov r1,#0x0
+ bl OS_SetArenaLo
+ mov r0,#0x2
+ mov r1,#0x0
+ bl OS_SetArenaHi
+ mov r0,#0x3
+ bl OS_GetInitArenaHi
+ mov r1,r0
+ mov r0,#0x3
+ bl OS_SetArenaHi
+ mov r0,#0x3
+ bl OS_GetInitArenaLo
+ mov r1,r0
+ mov r0,#0x3
+ bl OS_SetArenaLo
+ mov r0,#0x4
+ bl OS_GetInitArenaHi
+ mov r1,r0
+ mov r0,#0x4
+ bl OS_SetArenaHi
+ mov r0,#0x4
+ bl OS_GetInitArenaLo
+ mov r1,r0
+ mov r0,#0x4
+ bl OS_SetArenaLo
+ mov r0,#0x5
+ bl OS_GetInitArenaHi
+ mov r1,r0
+ mov r0,#0x5
+ bl OS_SetArenaHi
+ mov r0,#0x5
+ bl OS_GetInitArenaLo
+ mov r1,r0
+ mov r0,#0x5
+ bl OS_SetArenaLo
+ mov r0,#0x6
+ bl OS_GetInitArenaHi
+ mov r1,r0
+ mov r0,#0x6
+ bl OS_SetArenaHi
+ mov r0,#0x6
+ bl OS_GetInitArenaLo
+ mov r1,r0
+ mov r0,#0x6
+ bl OS_SetArenaLo
+ add sp,sp,#0x4
+ ldmia sp!,{ lr }
+ bx lr
+}
+#else
+void OS_InitArena() {
+ if (OSi_Initialized) {
+ return;
+ }
+ OSi_Initialized = TRUE;
+
+ OS_SetArenaHi(OS_ARENA_MAIN, OS_GetInitArenaHi(OS_ARENA_MAIN));
+ OS_SetArenaLo(OS_ARENA_MAIN, OS_GetInitArenaLo(OS_ARENA_MAIN));
+
+ OS_SetArenaLo(OS_ARENA_MAINEX, (void *)0);
+ OS_SetArenaHi(OS_ARENA_MAINEX, (void *)0);
+
+ OS_SetArenaHi(OS_ARENA_ITCM, OS_GetInitArenaHi(OS_ARENA_ITCM));
+ OS_SetArenaLo(OS_ARENA_ITCM, OS_GetInitArenaLo(OS_ARENA_ITCM));
+
+ OS_SetArenaHi(OS_ARENA_DTCM, OS_GetInitArenaHi(OS_ARENA_DTCM));
+ OS_SetArenaLo(OS_ARENA_DTCM, OS_GetInitArenaLo(OS_ARENA_DTCM));
+
+ OS_SetArenaHi(OS_ARENA_SHARED, OS_GetInitArenaHi(OS_ARENA_SHARED));
+ OS_SetArenaLo(OS_ARENA_SHARED, OS_GetInitArenaLo(OS_ARENA_SHARED));
+
+ OS_SetArenaHi(OS_ARENA_WRAM_MAIN, OS_GetInitArenaHi(OS_ARENA_WRAM_MAIN));
+ OS_SetArenaLo(OS_ARENA_WRAM_MAIN, OS_GetInitArenaLo(OS_ARENA_WRAM_MAIN));
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void OS_InitArenaEx() {
+ stmdb sp!,{ lr }
+ sub sp,sp,#0x4
+ mov r0,#0x2
+ bl OS_GetInitArenaHi
+ mov r1,r0
+ mov r0,#0x2
+ bl OS_SetArenaHi
+ mov r0,#0x2
+ bl OS_GetInitArenaLo
+ mov r1,r0
+ mov r0,#0x2
+ bl OS_SetArenaLo
+ ldr r0, =OSi_MainExArenaEnabled
+ ldr r0,[r0,#0x0]
+ cmp r0,#0x0
+ beq _020CC5B8
+ bl OS_GetConsoleType
+ and r0,r0,#0x3
+ cmp r0,#0x1
+ addne sp,sp,#0x4
+ ldmneia sp!,{ lr }
+ bxne lr
+_020CC5B8:
+ ldr r0, =0x0200002b
+ bl OS_SetProtectionRegion1
+ ldr r0, =0x023e0021
+ bl OS_SetProtectionRegion2
+ add sp,sp,#0x4
+ ldmia sp!,{ lr }
+ bx lr
+}
+#else
+void OS_InitArenaEx() {
+ OS_SetArenaHi(2, OS_GetInitArenaHi(OS_ARENA_MAINEX));
+ OS_SetArenaLo(2, OS_GetInitArenaLo(OS_ARENA_MAINEX));
+
+ if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) {
+ OS_SetProtectionRegion(1, HW_MAIN_MEM, 4MB);
+ OS_SetProtectionRegion(2, HW_MAIN_MEM_MAIN_END, 128KB);
+ }
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_GetArenaHi(OSArenaId id) {
+ mov r0,r0, lsl #0x2
+ add r0,r0,#0x2700000
+ add r0,r0,#0xff000
+ ldr r0,[r0,#0xdc4]
+ bx lr
+}
+#else
+void* OS_GetArenaHi(OSArenaId id) {
+ return OSi_GetArenaInfo().hi[id];
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_GetArenaLo(OSArenaId id) {
+ mov r0,r0, lsl #0x2
+ add r0,r0,#0x2700000
+ add r0,r0,#0xff000
+ ldr r0,[r0,#0xda0]
+ bx lr
+}
+#else
+void* OS_GetArenaLo(OSArenaId id) {
+ return OSi_GetArenaInfo().lo[id];
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_GetInitArenaHi(OSArenaId id) {
+ stmdb sp!, {lr}
+ sub sp, sp, #0x4
+ cmp r0, #0x6
+ addls pc, pc, r0, lsl #0x2
+ b _020CC508
+_020CC41C:
+ b _020CC438
+ b _020CC508
+ b _020CC448
+ b _020CC488
+ b _020CC498
+ b _020CC4E8
+ b _020CC4F8
+_020CC438:
+ add sp, sp, #0x4
+ ldr r0, =OSi_MAIN_ARENA_HI_DEFAULT
+ ldmfd sp!, {lr}
+ bx lr
+_020CC448:
+ ldr r0, =OSi_MainExArenaEnabled
+ ldr r0, [r0]
+ cmp r0, #0x0
+ beq _020CC468
+ bl OS_GetConsoleType
+ and r0, r0, #0x3
+ cmp r0, #0x1
+ bne _020CC478
+_020CC468:
+ add sp, sp, #0x4
+ mov r0, #0x0
+ ldmfd sp!, {lr}
+ bx lr
+_020CC478:
+ add sp, sp, #0x4
+ mov r0, #OSi_MAINEX_ARENA_HI_DEFAULT
+ ldmfd sp!, {lr}
+ bx lr
+_020CC488:
+ add sp, sp, #0x4
+ mov r0, #HW_ITCM_ARENA_HI_DEFAULT
+ ldmfd sp!, {lr}
+ bx lr
+_020CC498:
+ ldr r0, =0x027E0000
+ ldr r1, =0x00000000
+ ldr r2, =0x00000400
+ add r3, r0, #0x3f80
+ cmp r1, #0x0
+ sub r2, r3, r2
+ bne _020CC4CC
+ ldr r1, =0x027E0080
+ add sp, sp, #0x4
+ cmp r0, r1
+ movcc r0, r1
+ ldmfd sp!, {lr}
+ bx lr
+_020CC4CC:
+ cmp r1, #0x0
+ ldrlt r0, =0x027E0080
+ add sp, sp, #0x4
+ sublt r0, r0, r1
+ subge r0, r2, r1
+ ldmfd sp!, {lr}
+ bx lr
+_020CC4E8:
+ add sp, sp, #0x4
+ ldr r0, =HW_SHARED_ARENA_HI_DEFAULT
+ ldmfd sp!, {lr}
+ bx lr
+_020CC4F8:
+ add sp, sp, #0x4
+ ldr r0, =OSi_WRAM_MAIN_ARENA_HI_DEFAULT;
+ ldmfd sp!, {lr}
+ bx lr
+_020CC508:
+ mov r0, #0x0
+ add sp, sp, #0x4
+ ldmia sp!, {lr}
+ bx lr
+}
+#else
+void* OS_GetInitArenaHi(OSArenaId id) {
+ switch (id) {
+ case OS_ARENA_MAIN:
+ return (void *)OSi_MAIN_ARENA_HI_DEFAULT;
+ case OS_ARENA_MAINEX:
+ if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) {
+ return (void *)0;
+ } else {
+ return (void *)OSi_MAINEX_ARENA_HI_DEFAULT;
+ }
+ case OS_ARENA_ITCM:
+ return (void *)HW_ITCM_ARENA_HI_DEFAULT;
+ case OS_ARENA_DTCM:
+ u32 irqStackLo = (u32)HW_DTCM_IRQ_STACK_END - (s32)SDK_IRQ_STACKSIZE;
+ u32 sysStackLo;
+
+ if (!(s32)SDK_SYS_STACKSIZE) {
+ sysStackLo = HW_DTCM;
+ if (sysStackLo < (u32)SDK_SECTION_ARENA_DTCM_START) {
+ sysStackLo = (u32)SDK_SECTION_ARENA_DTCM_START;
+ }
+ }
+ else if ((s32)SDK_SYS_STACKSIZE < 0) {
+ sysStackLo = (u32)SDK_SECTION_ARENA_DTCM_START - (s32)SDK_SYS_STACKSIZE;
+ }
+ else {
+ sysStackLo = irqStackLo - (s32)SDK_SYS_STACKSIZE;
+ }
+ return (void*)sysStackLo;
+ case OS_ARENA_SHARED:
+ return (void *)HW_SHARED_ARENA_HI_DEFAULT;
+ case OS_ARENA_WRAM_MAIN:
+ return (void *)OSi_WRAM_MAIN_ARENA_HI_DEFAULT;
+ default:
+ return NULL;
+ }
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_GetInitArenaLo(OSArenaId id) {
+ stmdb sp!, {lr}
+ sub sp, sp, #0x4
+ cmp r0, #0x6
+ addls pc, pc, r0, lsl #0x2
+ b _020CC3DC
+_020CC330:
+ b _020CC34C
+ b _020CC3DC
+ b _020CC35C
+ b _020CC39C
+ b _020CC3AC
+ b _020CC3BC
+ b _020CC3CC
+_020CC34C:
+ add sp, sp, #0x4
+ ldr r0, =SDK_MAIN_ARENA_LO
+ ldmfd sp!, {lr}
+ bx lr
+_020CC35C:
+ ldr r0, =OSi_MainExArenaEnabled
+ ldr r0, [r0]
+ cmp r0, #0x0
+ beq _020CC37C
+ bl OS_GetConsoleType
+ and r0, r0, #0x3
+ cmp r0, #0x1
+ bne _020CC38C
+_020CC37C:
+ add sp, sp, #0x4
+ mov r0, #0x0
+ ldmfd sp!, {lr}
+ bx lr
+_020CC38C:
+ add sp, sp, #0x4
+ ldr r0, =SDK_SECTION_ARENA_EX_START
+ ldmfd sp!, {lr}
+ bx lr
+_020CC39C:
+ add sp, sp, #0x4
+ ldr r0, =SDK_SECTION_ARENA_ITCM_START
+ ldmfd sp!, {lr}
+ bx lr
+_020CC3AC:
+ add sp, sp, #0x4
+ ldr r0, =SDK_SECTION_ARENA_DTCM_START
+ ldmfd sp!, {lr}
+ bx lr
+_020CC3BC:
+ add sp, sp, #0x4
+ ldr r0, =HW_SHARED_ARENA_LO_DEFAULT
+ ldmfd sp!, {lr}
+ bx lr
+_020CC3CC:
+ add sp, sp, #0x4
+ ldr r0, =OSi_WRAM_MAIN_ARENA_LO_DEFAULT
+ ldmfd sp!, {lr}
+ bx lr
+_020CC3DC:
+ mov r0, #0x0
+ add sp, sp, #0x4
+ ldmia sp!, {lr}
+ bx lr
+}
+#else
+void* OS_GetInitArenaLo(OSArenaId id) {
+ switch (id) {
+ case OS_ARENA_MAIN:
+ return (void *)SDK_MAIN_ARENA_LO;
+ case OS_ARENA_MAINEX:
+ if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) {
+ return NULL;
+ } else {
+ return (void *)SDK_SECTION_ARENA_EX_START;
+ }
+ case OS_ARENA_ITCM:
+ return (void *)SDK_SECTION_ARENA_ITCM_START;
+ case OS_ARENA_DTCM:
+ return (void *)SDK_SECTION_ARENA_DTCM_START;
+ case OS_ARENA_SHARED:
+ return (void *)HW_SHARED_ARENA_LO_DEFAULT;
+ case OS_ARENA_WRAM_MAIN:
+ return (void *)OSi_WRAM_MAIN_ARENA_LO_DEFAULT;
+ default:
+ return NULL;
+ }
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void OS_SetArenaHi(OSArenaId id, void* newHi) {
+ mov r0,r0, lsl #0x2
+ add r0,r0,#0x2700000
+ add r0,r0,#0xff000
+ str r1,[r0,#0xdc4]
+ bx lr
+}
+#else
+void OS_SetArenaHi(OSArenaId id, void* newHi) {
+ OSi_GetArenaInfo().hi[id] = newHi;
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void OS_SetArenaLo(OSArenaId id, void* newLo) {
+ mov r0,r0, lsl #0x2
+ add r0,r0,#0x2700000
+ add r0,r0,#0xff000
+ str r1,[r0,#0xda0]
+ bx lr
+}
+#else
+void OS_SetArenaLo(OSArenaId id, void* newLo) {
+ OSi_GetArenaInfo().lo[id] = newLo;
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
+ stmdb sp!,{ r4-r7, lr }
+ sub sp,sp,#0x4
+ mov r7,r0
+ mov r6,r1
+ mov r5,r2
+ bl OS_GetArenaLo
+ cmp r0,#0x0
+ addeq sp,sp,#0x4
+ moveq r0,#0x0
+ ldmeqia sp!,{ r4-r7, lr }
+ bxeq lr
+ add r0,r0,r5
+ sub r1,r5,#0x1
+ mvn r2,r1
+ sub r0,r0,#0x1
+ and r4,r2,r0
+ add r0,r4,r6
+ add r0,r0,r5
+ sub r1,r0,#0x1
+ mov r0,r7
+ and r5,r2,r1
+ bl OS_GetArenaHi
+ cmp r5,r0
+ addhi sp,sp,#0x4
+ movhi r0,#0x0
+ ldmhiia sp!,{ r4-r7, lr }
+ bxhi lr
+ mov r0,r7
+ mov r1,r5
+ bl OS_SetArenaLo
+ mov r0,r4
+ add sp,sp,#0x4
+ ldmia sp!,{ r4-r7, lr }
+ bx lr
+}
+#else
+void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
+ void* ptr;
+ u8* arenaLo;
+ ptr = OS_GetArenaLo(id);
+ if (!ptr) {
+ return NULL;
+ }
+ arenaLo = ptr = (void *)OSi_ROUND(ptr, align);
+ arenaLo += size;
+ arenaLo = (u8 *)OSi_ROUND(arenaLo, align);
+ if (arenaLo > (u8*)OS_GetArenaHi(id)) {
+ return NULL;
+ }
+ OS_SetArenaLo(id, arenaLo);
+
+ return ptr;
+}
+#endif
+
+#ifdef MATCH_ASM
+asm void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
+ stmdb sp!,{ r4-r6, lr }
+ mov r4,r0
+ mov r6,r1
+ mov r5,r2
+ bl OS_GetArenaHi
+ cmp r0,#0x0
+ moveq r0,#0x0
+ ldmeqia sp!,{ r4-r6, lr }
+ bxeq lr
+ sub r1,r5,#0x1
+ mvn r2,r1
+ and r0,r0,r2
+ sub r1,r0,r6
+ mov r0,r4
+ and r5,r1,r2
+ bl OS_GetArenaLo
+ cmp r5,r0
+ movcc r0,#0x0
+ ldmccia sp!,{ r4-r6, lr }
+ bxcc lr
+ mov r0,r4
+ mov r1,r5
+ bl OS_SetArenaHi
+ mov r0,r5
+ ldmia sp!,{ r4-r6, lr }
+ bx lr
+}
+#else
+void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
+ void* ptr;
+ u8* arenaHi;
+
+ arenaHi = OS_GetArenaHi(id);
+ if (!arenaHi) {
+ return NULL;
+ }
+
+ arenaHi = (u8 *)OSi_TRUNC(arenaHi, align);
+ arenaHi -= size;
+ arenaHi = ptr = (void *)OSi_TRUNC(arenaHi, align);
+
+ if (arenaHi < (u8*)OS_GetArenaLo(id)) {
+ return NULL;
+ }
+
+ OS_SetArenaHi(id, arenaHi);
+
+ return ptr;
+}
+#endif \ No newline at end of file
diff --git a/include/nitro/os_arena.h b/include/nitro/os_arena.h
new file mode 100644
index 00000000..f1893a3d
--- /dev/null
+++ b/include/nitro/os_arena.h
@@ -0,0 +1,41 @@
+//
+// Created by red031000 on 2020-04-27.
+//
+
+#ifndef POKEDIAMOND_OS_ARENA_H
+#define POKEDIAMOND_OS_ARENA_H
+
+#include "types.h"
+
+typedef enum {
+ OS_ARENA_MAIN = 0,
+ OS_ARENA_MAIN_SUBPRIV = 1,
+ OS_ARENA_MAINEX = 2,
+ OS_ARENA_ITCM = 3,
+ OS_ARENA_DTCM = 4,
+ OS_ARENA_SHARED = 5,
+ OS_ARENA_WRAM_MAIN = 6,
+ OS_ARENA_WRAM_SUB = 7,
+ OS_ARENA_WRAM_SUBPRIV = 8,
+ OS_ARENA_MAX = 9
+} OSArenaId;
+
+typedef struct {
+ void* lo[OS_ARENA_MAX];
+ void* hi[OS_ARENA_MAX];
+ u16 initialized;
+ u8 padding[2];
+} OSArenaInfo;
+
+void OS_InitArena();
+void OS_InitArenaEx();
+void* OS_GetArenaHi(OSArenaId id);
+void* OS_GetArenaLo(OSArenaId id);
+void* OS_GetInitArenaHi(OSArenaId id);
+void* OS_GetInitArenaLo(OSArenaId id);
+void OS_SetArenaHi(OSArenaId id, void *newHi);
+void OS_SetArenaLo(OSArenaId id, void *newLo);
+void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align);
+void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align);
+
+#endif //POKEDIAMOND_OS_ARENA_H
diff --git a/include/nitro/os_asm.h b/include/nitro/os_asm.h
deleted file mode 100644
index 775955f1..00000000
--- a/include/nitro/os_asm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// Created by mart on 4/12/20.
-//
-
-#ifndef POKEDIAMOND_OS_ASM_H
-#define POKEDIAMOND_OS_ASM_H
-
-#include "nitro/types.h"
-
-OSProcMode OS_GetProcMode();
-
-#endif //POKEDIAMOND_OS_ASM_H
diff --git a/include/nitro/os_asm.s b/include/nitro/os_asm.s
deleted file mode 100644
index 86d7603c..00000000
--- a/include/nitro/os_asm.s
+++ /dev/null
@@ -1,7 +0,0 @@
-
-# TODO: make this syntax look correct in CLion
-# Potentially switch to AT&T syntax?
-OS_GetProcMode:
- mrs r0, cpsr
- and r0, r0, #0x80
- bx lr
diff --git a/include/nitro/os_protectionRegion.c b/include/nitro/os_protectionRegion.c
new file mode 100644
index 00000000..b70f9056
--- /dev/null
+++ b/include/nitro/os_protectionRegion.c
@@ -0,0 +1,17 @@
+//
+// Created by red031000 on 2020-04-24.
+//
+
+#include "os_protectionRegion.h"
+
+asm void OS_SetProtectionRegion1(u32 param)
+{
+ mcr p15, 0x0, r0, c6, c1, 0x0
+ bx lr
+}
+
+asm void OS_SetProtectionRegion2(u32 param)
+{
+ mcr p15, 0x0, r0, c6, c2, 0x0
+ bx lr
+} \ No newline at end of file
diff --git a/include/nitro/os_protectionRegion.h b/include/nitro/os_protectionRegion.h
new file mode 100644
index 00000000..7b212934
--- /dev/null
+++ b/include/nitro/os_protectionRegion.h
@@ -0,0 +1,47 @@
+//
+// Created by red031000 on 2020-04-24.
+//
+
+#ifndef POKEDIAMOND_OS_PROTECTIONREGION_H
+#define POKEDIAMOND_OS_PROTECTIONREGION_H
+
+#include "types.h"
+#include "consts.h"
+
+void OS_SetProtectionRegion1(u32 param);
+void OS_SetProtectionRegion2(u32 param);
+
+typedef enum
+{
+ OSi_PR_BASE_MASK_4KB = 0xfffff000,
+ OSi_PR_BASE_MASK_8KB = 0xffffe000,
+ OSi_PR_BASE_MASK_16KB = 0xffffc000,
+ OSi_PR_BASE_MASK_32KB = 0xffff8000,
+ OSi_PR_BASE_MASK_64KB = 0xffff0000,
+ OSi_PR_BASE_MASK_128KB = 0xfffe0000,
+ OSi_PR_BASE_MASK_256KB = 0xfffc0000,
+ OSi_PR_BASE_MASK_512KB = 0xfff80000,
+ OSi_PR_BASE_MASK_1MB = 0xfff00000,
+ OSi_PR_BASE_MASK_2MB = 0xffe00000,
+ OSi_PR_BASE_MASK_4MB = 0xffc00000,
+ OSi_PR_BASE_MASK_8MB = 0xff800000,
+ OSi_PR_BASE_MASK_16MB = 0xff000000,
+ OSi_PR_BASE_MASK_32MB = 0xfe000000,
+ OSi_PR_BASE_MASK_64MB = 0xfc000000,
+ OSi_PR_BASE_MASK_128MB = 0xf8000000,
+ OSi_PR_BASE_MASK_256MB = 0xf0000000,
+ OSi_PR_BASE_MASK_512MB = 0xe0000000,
+ OSi_PR_BASE_MASK_1GB = 0xc0000000,
+ OSi_PR_BASE_MASK_2GB = 0x80000000,
+ OSi_PR_BASE_MASK_4GB = 0x00000000
+} OSiProtectionRegionBaseMask;
+
+static inline u32 OSi_CalcPRParam(u32 address, u32 size, OSiProtectionRegionBaseMask mask) {
+ return ((address & mask) | size);
+}
+
+#define OS_SetProtectionRegion(regionNo, address, sizeStr) \
+ OS_SetProtectionRegion##regionNo(OSi_CalcPRParam(address, HW_C6_PR_##sizeStr, OSi_PR_BASE_MASK_##sizeStr) \
+ | 1)
+
+#endif //POKEDIAMOND_OS_PROTECTIONREGION_H
diff --git a/include/nitro/os_system.c b/include/nitro/os_system.c
new file mode 100644
index 00000000..2ccb7fc1
--- /dev/null
+++ b/include/nitro/os_system.c
@@ -0,0 +1,28 @@
+//
+// Created by mart on 4/23/20.
+//
+
+#include "os_system.h"
+
+asm OSIntrMode OS_DisableInterrupts() {
+ mrs r0, cpsr
+ orr r1, r0, #HW_PSR_IRQ_DISABLE
+ msr cpsr_c, r1
+ and r0, r0, #HW_PSR_IRQ_DISABLE
+ bx lr
+}
+
+asm OSIntrMode OS_RestoreInterrupts(OSIntrMode state) {
+ mrs r1, cpsr
+ bic r2, r1, #HW_PSR_IRQ_DISABLE
+ orr r2, r2, r0
+ msr cpsr_c, r2
+ and r0, r1, #HW_PSR_IRQ_DISABLE
+ bx lr
+}
+
+asm OSProcMode OS_GetProcMode() {
+ mrs r0, cpsr
+ and r0, r0, #HW_PSR_CPU_MODE_MASK
+ bx lr
+} \ No newline at end of file
diff --git a/include/nitro/os_system.h b/include/nitro/os_system.h
new file mode 100644
index 00000000..fc6a2f81
--- /dev/null
+++ b/include/nitro/os_system.h
@@ -0,0 +1,44 @@
+//
+// Created by mart on 4/23/20.
+//
+
+#ifndef POKEDIAMOND_OS_SYSTEM_H
+#define POKEDIAMOND_OS_SYSTEM_H
+
+#include "consts.h"
+
+typedef enum {
+ OS_PROCMODE_USER=16,
+ OS_PROCMODE_FIQ=17,
+ OS_PROCMODE_IRQ=18,
+ OS_PROCMODE_SVC=19,
+ OS_PROCMODE_ABORT=23,
+ OS_PROCMODE_UNDEF=27,
+ OS_PROCMODE_SYS=31
+} OSProcMode;
+
+typedef enum {
+ OS_INTRMODE_IRQ_DISABLE = HW_PSR_IRQ_DISABLE,
+ OS_INTRMODE_IRQ_ENABLE = 0
+} OSIntrMode_Irq;
+
+typedef enum {
+ OS_INTRMODE_FIQ_DISABLE = HW_PSR_FIQ_DISABLE,
+ OS_INTRMODE_FIQ_ENABLE = 0
+} OSIntrMode_Fiq;
+
+typedef union {
+ OSIntrMode_Fiq mode_fiq;
+ OSIntrMode_Irq mode_irq;
+} OSIntrMode;
+
+OSIntrMode OS_EnableInterrupts();
+OSIntrMode OS_DisableInterrupts();
+OSIntrMode OS_RestoreInterrupts(OSIntrMode state);
+OSIntrMode OS_DisableInterrupts_IrqAndFiq();
+OSIntrMode OS_RestoreInterrupts_IrqAndFiq(OSIntrMode state);
+OSIntrMode_Irq OS_GetCpsrIrq();
+OSProcMode OS_GetProcMode();
+
+
+#endif //POKEDIAMOND_OS_SYSTEM_H
diff --git a/include/nitro/types.h b/include/nitro/types.h
index d702de23..5ad2c75e 100644
--- a/include/nitro/types.h
+++ b/include/nitro/types.h
@@ -37,14 +37,4 @@ typedef int BOOL;
#endif // __cplusplus
#endif
-typedef enum {
- OS_PROCMODE_USER=16,
- OS_PROCMODE_FIQ=17,
- OS_PROCMODE_IRQ=18,
- OS_PROCMODE_SVC=19,
- OS_PROCMODE_ABORT=23,
- OS_PROCMODE_UNDEF=27,
- OS_PROCMODE_SYS=31
-} OSProcMode;
-
#endif //POKEDIAMOND_NITRO_TYPES_H