diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2020-05-01 07:54:42 -0400 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2020-05-01 07:54:42 -0400 |
commit | 9137144cc872024e7bf193b46b755330d66e343f (patch) | |
tree | 191c1c257dfceac54525667d4c620a7eb81e32fd /arm9/lib | |
parent | 6c3731902319116e8e73b14e2b75d5fd8c9642ff (diff) | |
parent | 90d38f053ff21a5d6cd967de29dc440cbba9aa29 (diff) |
Merge branch 'master' of https://github.com/martmists/pokediamond into pikalax_work
Diffstat (limited to 'arm9/lib')
-rw-r--r-- | arm9/lib/include/os_system.h | 15 | ||||
-rw-r--r-- | arm9/lib/src/OS_alloc.c | 169 | ||||
-rw-r--r-- | arm9/lib/src/OS_arena.c | 22 |
3 files changed, 182 insertions, 24 deletions
diff --git a/arm9/lib/include/os_system.h b/arm9/lib/include/os_system.h index fc6a2f81..c7f121bd 100644 --- a/arm9/lib/include/os_system.h +++ b/arm9/lib/include/os_system.h @@ -18,18 +18,8 @@ typedef enum { } 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; + OS_INTRMODE_DISABLE = HW_PSR_IRQ_DISABLE, + OS_INTRMODE_ENABLE = 0 } OSIntrMode; OSIntrMode OS_EnableInterrupts(); @@ -37,7 +27,6 @@ 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(); diff --git a/arm9/lib/src/OS_alloc.c b/arm9/lib/src/OS_alloc.c new file mode 100644 index 00000000..242c5571 --- /dev/null +++ b/arm9/lib/src/OS_alloc.c @@ -0,0 +1,169 @@ +//
+// Created by mart on 4/23/20.
+//
+#include "function_target.h"
+#include "os_alloc.h"
+#include "consts.h"
+#include "os_system.h"
+
+void* OSiHeapInfo[OS_ARENA_MAX];
+
+ARM_FUNC Cell* DLAddFront(Cell* list, Cell* cell)
+{
+ cell->next = list;
+ cell->prev = NULL;
+
+ if (list != NULL)
+ list->prev = cell;
+ return cell;
+}
+
+ARM_FUNC Cell* DLExtract(Cell* list, Cell* cell)
+{
+ if (cell->next) {
+ cell->next->prev = cell->prev;
+ }
+ if (cell->prev == NULL) {
+ list = cell->next;
+ } else {
+ cell->prev->next = cell->next;
+ }
+ return list;
+}
+
+ARM_FUNC Cell *DLInsert(Cell *original, Cell *inserted)
+{
+ Cell *prevCell = NULL;
+ Cell *nextCell = original;
+
+
+ while (nextCell != NULL)
+ {
+ if (inserted <= nextCell)
+ break;
+ prevCell = nextCell;
+ nextCell = nextCell->next;
+ }
+
+ inserted->next = nextCell;
+ inserted->prev = prevCell;
+
+ if (nextCell != NULL)
+ {
+ nextCell->prev = inserted;
+ Cell * temp = (Cell *)((char *)inserted + inserted->size);
+ if (temp == nextCell)
+ {
+ inserted->size += nextCell->size;
+ nextCell = nextCell->next;
+ inserted->next = nextCell;
+ if (nextCell != NULL)
+ nextCell->prev = inserted;
+ }
+ }
+
+ if (prevCell != NULL)
+ {
+ prevCell->next = inserted;
+ Cell * temp = (Cell *)((char *)prevCell + prevCell->size);
+
+ if (temp != inserted)
+ return original;
+
+ prevCell->size += inserted->size;
+ prevCell->next = nextCell;
+ if (nextCell != NULL)
+ nextCell->prev = prevCell;
+
+ return original;
+ }
+
+ return inserted;
+}
+
+#define HEADERSIZE OSi_ROUND(sizeof(Cell), 32)
+#define MINOBJSIZE (HEADERSIZE+32)
+
+ARM_FUNC 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);
+}
+
+ARM_FUNC 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);
+}
diff --git a/arm9/lib/src/OS_arena.c b/arm9/lib/src/OS_arena.c index b4bcbc1c..58b338f1 100644 --- a/arm9/lib/src/OS_arena.c +++ b/arm9/lib/src/OS_arena.c @@ -1,7 +1,7 @@ //
// Created by red031000 on 2020-04-27.
//
-
+#include "function_target.h"
#include "consts.h"
#include "os_arena.h"
#include "os_protectionRegion.h"
@@ -16,7 +16,7 @@ extern void SDK_SECTION_ARENA_DTCM_START(); // TODO: technically this should be 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
-void OS_InitArena() {
+ARM_FUNC void OS_InitArena() {
if (OSi_Initialized) {
return;
}
@@ -41,7 +41,7 @@ void OS_InitArena() { OS_SetArenaLo(OS_ARENA_WRAM_MAIN, OS_GetInitArenaLo(OS_ARENA_WRAM_MAIN));
}
-void OS_InitArenaEx() {
+ARM_FUNC void OS_InitArenaEx() {
OS_SetArenaHi(2, OS_GetInitArenaHi(OS_ARENA_MAINEX));
OS_SetArenaLo(2, OS_GetInitArenaLo(OS_ARENA_MAINEX));
@@ -51,15 +51,15 @@ void OS_InitArenaEx() { }
}
-void* OS_GetArenaHi(OSArenaId id) {
+ARM_FUNC void* OS_GetArenaHi(OSArenaId id) {
return OSi_GetArenaInfo().hi[id];
}
-void* OS_GetArenaLo(OSArenaId id) {
+ARM_FUNC void* OS_GetArenaLo(OSArenaId id) {
return OSi_GetArenaInfo().lo[id];
}
-void* OS_GetInitArenaHi(OSArenaId id) {
+ARM_FUNC void* OS_GetInitArenaHi(OSArenaId id) {
switch (id) {
case OS_ARENA_MAIN:
return (void *)OSi_MAIN_ARENA_HI_DEFAULT;
@@ -97,7 +97,7 @@ void* OS_GetInitArenaHi(OSArenaId id) { }
}
-void* OS_GetInitArenaLo(OSArenaId id) {
+ARM_FUNC void* OS_GetInitArenaLo(OSArenaId id) {
switch (id) {
case OS_ARENA_MAIN:
return (void *)SDK_MAIN_ARENA_LO;
@@ -120,15 +120,15 @@ void* OS_GetInitArenaLo(OSArenaId id) { }
}
-void OS_SetArenaHi(OSArenaId id, void* newHi) {
+ARM_FUNC void OS_SetArenaHi(OSArenaId id, void* newHi) {
OSi_GetArenaInfo().hi[id] = newHi;
}
-void OS_SetArenaLo(OSArenaId id, void* newLo) {
+ARM_FUNC void OS_SetArenaLo(OSArenaId id, void* newLo) {
OSi_GetArenaInfo().lo[id] = newLo;
}
-void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
+ARM_FUNC void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) {
void* ptr;
u8* arenaLo;
ptr = OS_GetArenaLo(id);
@@ -146,7 +146,7 @@ void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) { return ptr;
}
-void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
+ARM_FUNC void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) {
void* ptr;
u8* arenaHi;
|