summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenzofc708 <47937189+enzofc708@users.noreply.github.com>2026-08-04 14:45:49 -0300
committerGitHub <noreply@github.com>2026-08-04 19:45:49 +0200
commit29e3578e388b2ff350388e2cdfe45497c4ebdae2 (patch)
tree1019aca1a8142880209e954487d37f3a03fb8aa2
parent51640eb100522a3986779599f057d72c8cb9e42e (diff)
decomp heap.c (#145)HEADmain
* add heap.c * add frmh heap * add heap_list * add unth heap * link heap.c * fix external references
-rw-r--r--config/eur/arm9/delinks.txt5
-rw-r--r--config/eur/arm9/symbols.txt94
-rw-r--r--config/usa/arm9/delinks.txt5
-rw-r--r--config/usa/arm9/symbols.txt94
-rw-r--r--include/Actor/ActorManager.hpp1
-rw-r--r--libs/nds/include/nds/heap.h104
-rw-r--r--libs/nds/src/heap.c781
-rw-r--r--src/04_Load/Actor/ActorManager_04.cpp6
-rw-r--r--src/08_GameStart/Init.cpp7
9 files changed, 995 insertions, 102 deletions
diff --git a/config/eur/arm9/delinks.txt b/config/eur/arm9/delinks.txt
index 48251da7..0967ac8d 100644
--- a/config/eur/arm9/delinks.txt
+++ b/config/eur/arm9/delinks.txt
@@ -89,3 +89,8 @@ libs/nds/src/sbc.c:
.text start:0x020198bc end:0x0201b1bc
.data start:0x02057354 end:0x02057434
.bss start:0x0205ae08 end:0x0205db08
+
+libs/nds/src/heap.c:
+ complete
+ .text start:0x02017034 end:0x020179ac
+ .bss start:0x0205ade4 end:0x0205adf4 \ No newline at end of file
diff --git a/config/eur/arm9/symbols.txt b/config/eur/arm9/symbols.txt
index f9dc3d5f..ad6e44cc 100644
--- a/config/eur/arm9/symbols.txt
+++ b/config/eur/arm9/symbols.txt
@@ -675,51 +675,51 @@ func_02016efc kind:function(thumb,size=0xd0) addr:0x02016efc
func_02016fcc kind:function(thumb,size=0x1a) addr:0x02016fcc
func_02016fe8 kind:function(thumb,size=0x2e) addr:0x02016fe8
func_02017018 kind:function(thumb,size=0x1c) addr:0x02017018
-func_02017034 kind:function(thumb,size=0x1a) addr:0x02017034
-func_02017050 kind:function(thumb,size=0x1c) addr:0x02017050
-func_0201706c kind:function(thumb,size=0x20) addr:0x0201706c
-func_0201708c kind:function(thumb,size=0x1a) addr:0x0201708c
-func_020170a8 kind:function(thumb,size=0x50) addr:0x020170a8
-func_020170f8 kind:function(thumb,size=0x100) addr:0x020170f8
-func_020171f8 kind:function(thumb,size=0x7c) addr:0x020171f8
-func_02017274 kind:function(thumb,size=0x74) addr:0x02017274
-func_020172e8 kind:function(thumb,size=0x8c) addr:0x020172e8
-func_02017374 kind:function(thumb,size=0x20) addr:0x02017374
-func_02017394 kind:function(thumb,size=0x8) addr:0x02017394
-NewEXPH kind:function(thumb,size=0x20) addr:0x0201739c
-func_020173bc kind:function(thumb,size=0xe8) addr:0x020173bc
-func_020174a4 kind:function(thumb,size=0x2a) addr:0x020174a4
-func_020174d0 kind:function(thumb,size=0x16) addr:0x020174d0
-func_020174e8 kind:function(thumb,size=0x46) addr:0x020174e8
-func_02017530 kind:function(thumb,size=0x2c) addr:0x02017530
-func_0201755c kind:function(thumb,size=0x3e) addr:0x0201755c
-func_0201759c kind:function(thumb,size=0x3c) addr:0x0201759c
-func_020175d8 kind:function(thumb,size=0xe) addr:0x020175d8
-func_020175e8 kind:function(thumb,size=0x1a) addr:0x020175e8
-func_02017604 kind:function(thumb,size=0x20) addr:0x02017604
-func_02017624 kind:function(thumb,size=0x8) addr:0x02017624
-NewFRMH kind:function(thumb,size=0x22) addr:0x0201762c
-func_02017650 kind:function(thumb,size=0x1e) addr:0x02017650
-func_02017670 kind:function(thumb,size=0x24) addr:0x02017670
-func_02017694 kind:function(thumb,size=0x2e) addr:0x02017694
-func_020176c4 kind:function(thumb,size=0x30) addr:0x020176c4
-func_020176f4 kind:function(thumb,size=0x1c) addr:0x020176f4
-func_02017710 kind:function(thumb,size=0x3e) addr:0x02017710
-func_02017750 kind:function(thumb,size=0x1c) addr:0x02017750
-func_0201776c kind:function(thumb,size=0x5c) addr:0x0201776c
-func_020177c8 kind:function(thumb,size=0x10) addr:0x020177c8
-func_020177d8 kind:function(thumb,size=0x10) addr:0x020177d8
-func_020177e8 kind:function(thumb,size=0xc) addr:0x020177e8
-func_020177f4 kind:function(thumb,size=0x1a) addr:0x020177f4
-func_02017810 kind:function(thumb,size=0x2c) addr:0x02017810
-func_0201783c kind:function(thumb,size=0x2a) addr:0x0201783c
-func_02017868 kind:function(thumb,size=0x36) addr:0x02017868
-func_020178a0 kind:function(thumb,size=0x3a) addr:0x020178a0
-func_020178dc kind:function(thumb,size=0x10) addr:0x020178dc
-func_020178ec kind:function(thumb,size=0xe) addr:0x020178ec
-func_020178fc kind:function(thumb,size=0x98) addr:0x020178fc
-func_02017994 kind:function(thumb,size=0x8) addr:0x02017994
-func_0201799c kind:function(thumb,size=0x10) addr:0x0201799c
+Heap_GetRegion kind:function(thumb,size=0x1a) addr:0x02017034
+Heap_RemoveBlock kind:function(thumb,size=0x1c) addr:0x02017050
+Heap_InsertBlock kind:function(thumb,size=0x20) addr:0x0201706c
+Heap_InitBlock kind:function(thumb,size=0x1a) addr:0x0201708c
+Heap_EXPHInit kind:function(thumb,size=0x50) addr:0x020170a8
+Heap_AllocFreeBlock kind:function(thumb,size=0x100) addr:0x020170f8
+Heap_EXPHAllocHead kind:function(thumb,size=0x7c) addr:0x020171f8
+Heap_EXPHAllocTail kind:function(thumb,size=0x74) addr:0x02017274
+Heap_EmptyRegion kind:function(thumb,size=0x8c) addr:0x020172e8
+Heap_EXPHCreate kind:function(thumb,size=0x20) addr:0x02017374
+Heap_EXPHDestroy kind:function(thumb,size=0x8) addr:0x02017394
+Heap_EXPHNew kind:function(thumb,size=0x20) addr:0x0201739c
+Heap_EXPHResizeBlock kind:function(thumb,size=0xe8) addr:0x020173bc
+Heap_EXPHFreeBlock kind:function(thumb,size=0x2a) addr:0x020174a4
+Heap_EXPHGetEmptySize kind:function(thumb,size=0x16) addr:0x020174d0
+Heap_EXPHGetMaxEmptySize kind:function(thumb,size=0x46) addr:0x020174e8
+Heap_FRMHInit kind:function(thumb,size=0x2c) addr:0x02017530
+Heap_FRMHAllocHead kind:function(thumb,size=0x3e) addr:0x0201755c
+Heap_FRMHAllocTail kind:function(thumb,size=0x3c) addr:0x0201759c
+Heap_FRMHFreeHead kind:function(thumb,size=0xe) addr:0x020175d8
+Heap_FRMHFreeTail kind:function(thumb,size=0x1a) addr:0x020175e8
+Heap_FRMHCreate kind:function(thumb,size=0x20) addr:0x02017604
+Heap_FRMHDestroy kind:function(thumb,size=0x8) addr:0x02017624
+Heap_FRMHNew kind:function(thumb,size=0x22) addr:0x0201762c
+Heap_FRMHFreeBlock kind:function(thumb,size=0x1e) addr:0x02017650
+Heap_FRMHGetMaxEmptySize kind:function(thumb,size=0x24) addr:0x02017670
+Heap_FRMHSaveState kind:function(thumb,size=0x2e) addr:0x02017694
+Heap_FRMHLoadState kind:function(thumb,size=0x30) addr:0x020176c4
+Heap_FRMHFreeEmpty kind:function(thumb,size=0x1c) addr:0x020176f4
+Heap_FindBlockInternal kind:function(thumb,size=0x3e) addr:0x02017710
+Heap_FindParentHeap kind:function(thumb,size=0x1c) addr:0x02017750
+Heap_InitHeader kind:function(thumb,size=0x5c) addr:0x0201776c
+Heap_DestroyInternal kind:function(thumb,size=0x10) addr:0x020177c8
+Heap_FindBlock kind:function(thumb,size=0x10) addr:0x020177d8
+Heap_InitList kind:function(thumb,size=0xc) addr:0x020177e8
+Heap_ListSetFirst kind:function(thumb,size=0x1a) addr:0x020177f4
+Heap_ListAppend kind:function(thumb,size=0x2c) addr:0x02017810
+Heap_ListPrepend kind:function(thumb,size=0x2a) addr:0x0201783c
+Heap_ListInsertBefore kind:function(thumb,size=0x36) addr:0x02017868
+Heap_ListRemove kind:function(thumb,size=0x3a) addr:0x020178a0
+Heap_ListNext kind:function(thumb,size=0x10) addr:0x020178dc
+Heap_ListPrev kind:function(thumb,size=0xe) addr:0x020178ec
+Heap_UNTHCreate kind:function(thumb,size=0x98) addr:0x020178fc
+Heap_Destroy kind:function(thumb,size=0x8) addr:0x02017994
+Heap_UNTHSize kind:function(thumb,size=0x10) addr:0x0201799c
func_020179ac kind:function(arm,size=0x20) addr:0x020179ac
func_020179cc kind:function(arm,size=0x18) addr:0x020179cc
func_020179e4 kind:function(arm,size=0x14) addr:0x020179e4
@@ -3014,8 +3014,8 @@ data_0205ada8 kind:bss addr:0x0205ada8
data_0205adac kind:bss addr:0x0205adac
data_0205adc0 kind:bss addr:0x0205adc0
data_0205ade0 kind:bss addr:0x0205ade0
-data_0205ade4 kind:bss addr:0x0205ade4
-data_0205ade8 kind:bss addr:0x0205ade8
+gHeapListInitialized kind:bss addr:0x0205ade4 local
+gHeapList kind:bss addr:0x0205ade8 local
data_0205adf4 kind:bss addr:0x0205adf4
data_0205ae08 kind:bss addr:0x0205ae08
data_0205db08 kind:bss addr:0x0205db08
diff --git a/config/usa/arm9/delinks.txt b/config/usa/arm9/delinks.txt
index 8317cf88..0a591ebc 100644
--- a/config/usa/arm9/delinks.txt
+++ b/config/usa/arm9/delinks.txt
@@ -85,3 +85,8 @@ libs/nds/src/sbc.c:
.text start:0x020198bc end:0x0201b1bc
.data start:0x020572f4 end:0x020573d4
.bss start:0x0205ada8 end:0x0205daa8
+
+libs/nds/src/heap.c:
+ complete
+ .text start:0x02017034 end:0x020179ac
+ .bss start:0x0205ad84 end:0x0205ad94 \ No newline at end of file
diff --git a/config/usa/arm9/symbols.txt b/config/usa/arm9/symbols.txt
index 992e9c13..893edec5 100644
--- a/config/usa/arm9/symbols.txt
+++ b/config/usa/arm9/symbols.txt
@@ -675,51 +675,51 @@ func_02016efc kind:function(thumb,size=0xd0) addr:0x02016efc
func_02016fcc kind:function(thumb,size=0x1a) addr:0x02016fcc
func_02016fe8 kind:function(thumb,size=0x2e) addr:0x02016fe8
func_02017018 kind:function(thumb,size=0x1c) addr:0x02017018
-func_02017034 kind:function(thumb,size=0x1a) addr:0x02017034
-func_02017050 kind:function(thumb,size=0x1c) addr:0x02017050
-func_0201706c kind:function(thumb,size=0x20) addr:0x0201706c
-func_0201708c kind:function(thumb,size=0x1a) addr:0x0201708c
-func_020170a8 kind:function(thumb,size=0x50) addr:0x020170a8
-func_020170f8 kind:function(thumb,size=0x100) addr:0x020170f8
-func_020171f8 kind:function(thumb,size=0x7c) addr:0x020171f8
-func_02017274 kind:function(thumb,size=0x74) addr:0x02017274
-func_020172e8 kind:function(thumb,size=0x8c) addr:0x020172e8
-func_02017374 kind:function(thumb,size=0x20) addr:0x02017374
-func_02017394 kind:function(thumb,size=0x8) addr:0x02017394
-NewEXPH kind:function(thumb,size=0x20) addr:0x0201739c
-func_020173bc kind:function(thumb,size=0xe8) addr:0x020173bc
-func_020174a4 kind:function(thumb,size=0x2a) addr:0x020174a4
-func_020174d0 kind:function(thumb,size=0x16) addr:0x020174d0
-func_020174e8 kind:function(thumb,size=0x46) addr:0x020174e8
-func_02017530 kind:function(thumb,size=0x2c) addr:0x02017530
-func_0201755c kind:function(thumb,size=0x3e) addr:0x0201755c
-func_0201759c kind:function(thumb,size=0x3c) addr:0x0201759c
-func_020175d8 kind:function(thumb,size=0xe) addr:0x020175d8
-func_020175e8 kind:function(thumb,size=0x1a) addr:0x020175e8
-func_02017604 kind:function(thumb,size=0x20) addr:0x02017604
-func_02017624 kind:function(thumb,size=0x8) addr:0x02017624
-NewFRMH kind:function(thumb,size=0x22) addr:0x0201762c
-func_02017650 kind:function(thumb,size=0x1e) addr:0x02017650
-func_02017670 kind:function(thumb,size=0x24) addr:0x02017670
-func_02017694 kind:function(thumb,size=0x2e) addr:0x02017694
-func_020176c4 kind:function(thumb,size=0x30) addr:0x020176c4
-func_020176f4 kind:function(thumb,size=0x1c) addr:0x020176f4
-func_02017710 kind:function(thumb,size=0x3e) addr:0x02017710
-func_02017750 kind:function(thumb,size=0x1c) addr:0x02017750
-func_0201776c kind:function(thumb,size=0x5c) addr:0x0201776c
-func_020177c8 kind:function(thumb,size=0x10) addr:0x020177c8
-func_020177d8 kind:function(thumb,size=0x10) addr:0x020177d8
-func_020177e8 kind:function(thumb,size=0xc) addr:0x020177e8
-func_020177f4 kind:function(thumb,size=0x1a) addr:0x020177f4
-func_02017810 kind:function(thumb,size=0x2c) addr:0x02017810
-func_0201783c kind:function(thumb,size=0x2a) addr:0x0201783c
-func_02017868 kind:function(thumb,size=0x36) addr:0x02017868
-func_020178a0 kind:function(thumb,size=0x3a) addr:0x020178a0
-func_020178dc kind:function(thumb,size=0x10) addr:0x020178dc
-func_020178ec kind:function(thumb,size=0xe) addr:0x020178ec
-func_020178fc kind:function(thumb,size=0x98) addr:0x020178fc
-func_02017994 kind:function(thumb,size=0x8) addr:0x02017994
-func_0201799c kind:function(thumb,size=0x10) addr:0x0201799c
+Heap_GetRegion kind:function(thumb,size=0x1a) addr:0x02017034
+Heap_RemoveBlock kind:function(thumb,size=0x1c) addr:0x02017050
+Heap_InsertBlock kind:function(thumb,size=0x20) addr:0x0201706c
+Heap_InitBlock kind:function(thumb,size=0x1a) addr:0x0201708c
+Heap_EXPHInit kind:function(thumb,size=0x50) addr:0x020170a8
+Heap_AllocFreeBlock kind:function(thumb,size=0x100) addr:0x020170f8
+Heap_EXPHAllocHead kind:function(thumb,size=0x7c) addr:0x020171f8
+Heap_EXPHAllocTail kind:function(thumb,size=0x74) addr:0x02017274
+Heap_EmptyRegion kind:function(thumb,size=0x8c) addr:0x020172e8
+Heap_EXPHCreate kind:function(thumb,size=0x20) addr:0x02017374
+Heap_EXPHDestroy kind:function(thumb,size=0x8) addr:0x02017394
+Heap_EXPHNew kind:function(thumb,size=0x20) addr:0x0201739c
+Heap_EXPHResizeBlock kind:function(thumb,size=0xe8) addr:0x020173bc
+Heap_EXPHFreeBlock kind:function(thumb,size=0x2a) addr:0x020174a4
+Heap_EXPHGetEmptySize kind:function(thumb,size=0x16) addr:0x020174d0
+Heap_EXPHGetMaxEmptySize kind:function(thumb,size=0x46) addr:0x020174e8
+Heap_FRMHInit kind:function(thumb,size=0x2c) addr:0x02017530
+Heap_FRMHAllocHead kind:function(thumb,size=0x3e) addr:0x0201755c
+Heap_FRMHAllocTail kind:function(thumb,size=0x3c) addr:0x0201759c
+Heap_FRMHFreeHead kind:function(thumb,size=0xe) addr:0x020175d8
+Heap_FRMHFreeTail kind:function(thumb,size=0x1a) addr:0x020175e8
+Heap_FRMHCreate kind:function(thumb,size=0x20) addr:0x02017604
+Heap_FRMHDestroy kind:function(thumb,size=0x8) addr:0x02017624
+Heap_FRMHNew kind:function(thumb,size=0x22) addr:0x0201762c
+Heap_FRMHFreeBlock kind:function(thumb,size=0x1e) addr:0x02017650
+Heap_FRMHGetMaxEmptySize kind:function(thumb,size=0x24) addr:0x02017670
+Heap_FRMHSaveState kind:function(thumb,size=0x2e) addr:0x02017694
+Heap_FRMHLoadState kind:function(thumb,size=0x30) addr:0x020176c4
+Heap_FRMHFreeEmpty kind:function(thumb,size=0x1c) addr:0x020176f4
+Heap_FindBlockInternal kind:function(thumb,size=0x3e) addr:0x02017710
+Heap_FindParentHeap kind:function(thumb,size=0x1c) addr:0x02017750
+Heap_InitHeader kind:function(thumb,size=0x5c) addr:0x0201776c
+Heap_DestroyInternal kind:function(thumb,size=0x10) addr:0x020177c8
+Heap_FindBlock kind:function(thumb,size=0x10) addr:0x020177d8
+Heap_InitList kind:function(thumb,size=0xc) addr:0x020177e8
+Heap_ListSetFirst kind:function(thumb,size=0x1a) addr:0x020177f4
+Heap_ListAppend kind:function(thumb,size=0x2c) addr:0x02017810
+Heap_ListPrepend kind:function(thumb,size=0x2a) addr:0x0201783c
+Heap_ListInsertBefore kind:function(thumb,size=0x36) addr:0x02017868
+Heap_ListRemove kind:function(thumb,size=0x3a) addr:0x020178a0
+Heap_ListNext kind:function(thumb,size=0x10) addr:0x020178dc
+Heap_ListPrev kind:function(thumb,size=0xe) addr:0x020178ec
+Heap_UNTHCreate kind:function(thumb,size=0x98) addr:0x020178fc
+Heap_Destroy kind:function(thumb,size=0x8) addr:0x02017994
+Heap_UNTHSize kind:function(thumb,size=0x10) addr:0x0201799c
func_020179ac kind:function(arm,size=0x20) addr:0x020179ac
func_020179cc kind:function(arm,size=0x18) addr:0x020179cc
func_020179e4 kind:function(arm,size=0x14) addr:0x020179e4
@@ -3014,8 +3014,8 @@ data_0205ada8 kind:bss addr:0x0205ad48
data_0205adac kind:bss addr:0x0205ad4c
data_0205adc0 kind:bss addr:0x0205ad60
data_0205ade0 kind:bss addr:0x0205ad80
-data_0205ade4 kind:bss addr:0x0205ad84
-data_0205ade8 kind:bss addr:0x0205ad88
+gHeapListInitialized kind:bss addr:0x0205ad84 local
+gHeapList kind:bss addr:0x0205ad88 local
data_0205adf4 kind:bss addr:0x0205ad94
data_0205ae08 kind:bss addr:0x0205ada8
data_0205db08 kind:bss addr:0x0205daa8
diff --git a/include/Actor/ActorManager.hpp b/include/Actor/ActorManager.hpp
index 0b3b2677..bbfada47 100644
--- a/include/Actor/ActorManager.hpp
+++ b/include/Actor/ActorManager.hpp
@@ -4,6 +4,7 @@
#include "types.h"
#include "lib/files.hpp"
+#include "nds/heap.h"
#include "Actor/Actor.hpp"
#include "Actor/ActorRef.hpp"
diff --git a/libs/nds/include/nds/heap.h b/libs/nds/include/nds/heap.h
new file mode 100644
index 00000000..221bac8a
--- /dev/null
+++ b/libs/nds/include/nds/heap.h
@@ -0,0 +1,104 @@
+#include "global.h"
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct Heap_Region_ {
+ /* 00 */ void *start;
+ /* 04 */ void *end;
+ /* 08 */
+} Heap_Region;
+
+typedef struct Heap_LinkedObject_ {
+ /* 00 */ void *prev;
+ /* 04 */ void *next;
+ /* 08 */
+} Heap_LinkedObject;
+
+typedef struct Heap_LinkedList_ {
+ /* 00 */ void *head;
+ /* 04 */ void *tail;
+ /* 08 */ u16 numElements;
+ /* 0a */ u16 offset;
+ /* 0c */
+} Heap_LinkedList;
+
+typedef struct Heap_Header_ {
+ /* 00 */ u32 stamp;
+ /* 04 */ Heap_LinkedObject link;
+ /* 0c */ Heap_LinkedList children;
+ /* 18 */ void *startAddr;
+ /* 1c */ void *endAddr;
+ /* 20 */ u32 flags;
+ /* 24 */
+} Heap_Header;
+
+typedef struct Heap_EXPHBlockHeader_ {
+ /* 00 */ u16 stamp;
+ /* 02 */ u16 flags;
+ /* 04 */ u32 size;
+ /* 08 */ struct Heap_EXPHBlockHeader_ *prev;
+ /* 0c */ struct Heap_EXPHBlockHeader_ *next;
+ /* 20 */
+} Heap_EXPHBlockHeader;
+
+typedef struct Heap_EXPHBlockList_ {
+ /* 00 */ Heap_EXPHBlockHeader *head;
+ /* 04 */ Heap_EXPHBlockHeader *tail;
+ /* 08 */
+} Heap_EXPHBlockList;
+
+typedef struct Heap_EXPHHeader_ {
+ /* 00 */ Heap_EXPHBlockList freeBlocks;
+ /* 08 */ Heap_EXPHBlockList usedBlocks;
+ /* 10 */ u16 id;
+ /* 12 */ u16 flags;
+ /* 14 */
+} Heap_EXPHHeader;
+
+typedef struct Heap_FRMHState_ {
+ /* 00 */ u32 id;
+ /* 04 */ void *head;
+ /* 08 */ void *tail;
+ /* 0c */ struct Heap_FRMHState_ *prev;
+ /* 10 */
+} Heap_FRMHState;
+
+typedef struct Heap_FRMHHeader_ {
+ /* 00 */ void *head;
+ /* 04 */ void *tail;
+ /* 08 */ Heap_FRMHState *state;
+ /* 0c */
+} Heap_FRMHHeader;
+
+typedef struct Heap_UNTHBlockHeader_ {
+ /* 00 */ struct Heap_UNTHBlockHeader_ *next;
+ /* 04 */
+} Heap_UNTHBlockHeader;
+
+typedef struct Heap_UNTHBlockList_ {
+ /* 00 */ Heap_UNTHBlockHeader *head;
+ /* 04 */
+} Heap_UNTHBlockList;
+
+typedef struct Heap_UNTHHeader_ {
+ /* 00 */ Heap_UNTHBlockList freeBlocks;
+ /* 04 */ u32 blockSize;
+ /* 08 */
+} Heap_UNTHHeader;
+
+// function declarations
+void *Heap_EXPHNew(Heap_Header *heap, u32 size, int alignment);
+void Heap_EXPHFreeBlock(Heap_Header *heap, void *memBlock);
+void Heap_InitHeader(Heap_Header *pHeapHd, u32 signature, void *heapStart, void *heapEnd, u16 optFlag);
+void Heap_DestroyInternal(Heap_Header *pHeapHd);
+void Heap_InitList(Heap_LinkedList *list, u16 offset);
+void Heap_ListAppend(Heap_LinkedList *list, void *object);
+void Heap_ListRemove(Heap_LinkedList *list, void *object);
+void *Heap_ListNext(Heap_LinkedList *list, void *object);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/libs/nds/src/heap.c b/libs/nds/src/heap.c
new file mode 100644
index 00000000..35188b0e
--- /dev/null
+++ b/libs/nds/src/heap.c
@@ -0,0 +1,781 @@
+#include "nds/heap.h"
+
+#define SetBit(data, st, bits, val) \
+ { \
+ u32 maskBits = ((1 << bits) - 1); \
+ u32 newVal = val & maskBits; \
+ maskBits <<= st; \
+ data &= ~maskBits; \
+ data |= newVal << st; \
+ };
+
+static Heap_LinkedList gHeapList;
+static u32 gHeapListInitialized = 0;
+
+static inline u32 Diff_Ptr_inline(const void *start, const void *end) {
+ return end - start;
+}
+
+static inline void *AddU32_inline(void *ptr, u32 val) {
+ return (void *) (val + (u32) ptr);
+}
+
+static inline void Fill32_inline(Heap_Header *header, void *address, u32 size) {
+ if ((u16) (header->flags & 0xFF) & 1) {
+ Fill32(0, address, size);
+ }
+}
+
+static inline Heap_EXPHHeader *GetEXPH_inline(Heap_Header *header) {
+ return (u32) header + sizeof(Heap_Header);
+}
+
+THUMB void Heap_GetRegion(Heap_Region *region, Heap_EXPHBlockHeader *block) {
+ region->start = (u32) block - (u16) (block->flags >> 8 & 0x7F);
+ region->end = block->size + ((u32) block + sizeof(Heap_EXPHBlockHeader));
+}
+
+Heap_EXPHBlockHeader *Heap_RemoveBlock(Heap_EXPHBlockList *list, Heap_EXPHBlockHeader *block) {
+ Heap_EXPHBlockHeader *const p = block->prev;
+ Heap_EXPHBlockHeader *const n = block->next;
+
+ if (p) {
+ p->next = n;
+ } else {
+ list->head = n;
+ }
+
+ if (n) {
+ n->prev = p;
+ } else {
+ list->tail = p;
+ }
+
+ return p;
+}
+
+Heap_EXPHBlockHeader *Heap_InsertBlock(Heap_EXPHBlockList *list, Heap_EXPHBlockHeader *block, Heap_EXPHBlockHeader *prev) {
+ Heap_EXPHBlockHeader *next;
+
+ block->prev = prev;
+ if (prev) {
+ next = prev->next;
+ prev->next = block;
+ } else {
+ next = list->head;
+ list->head = block;
+ }
+
+ block->next = next;
+ if (next) {
+ next->prev = block;
+ } else {
+ list->tail = block;
+ }
+
+ return block;
+}
+
+Heap_EXPHBlockHeader *Heap_InitBlock(const Heap_Region *r, u16 stamp) {
+ Heap_EXPHBlockHeader *block = r->start;
+ block->stamp = stamp;
+ block->flags = 0;
+ block->size = r->end - ((u32) block + 0x10);
+ block->prev = NULL;
+ block->next = NULL;
+ return block;
+}
+
+Heap_Header *Heap_EXPHInit(void *start, void *end, u16 flag) {
+ Heap_EXPHBlockHeader *emptyBlock;
+ Heap_Region region;
+ Heap_Header *header = start;
+ Heap_EXPHHeader *EXPHHeader = (void *) ((u32) header + sizeof(Heap_Header));
+
+ Heap_InitHeader(header, 'EXPH', (void *) ((u32) EXPHHeader + sizeof(Heap_EXPHHeader)), end, flag);
+
+ EXPHHeader->id = 0;
+ EXPHHeader->flags = 0;
+ SetBit(EXPHHeader->flags, 0, 1, 0);
+
+ region.start = header->startAddr;
+ region.end = header->endAddr;
+ emptyBlock = Heap_InitBlock(&region, 'FR');
+
+ EXPHHeader->freeBlocks.head = emptyBlock;
+ EXPHHeader->freeBlocks.tail = emptyBlock;
+ EXPHHeader->usedBlocks.head = NULL;
+ EXPHHeader->usedBlocks.tail = NULL;
+
+ return header;
+}
+
+void *Heap_AllocFreeBlock(Heap_EXPHHeader *EXPHHeader, Heap_EXPHBlockHeader *blockHeader, void *block, u32 size,
+ u16 direction) {
+ Heap_Region free1;
+ Heap_Region free2;
+ Heap_EXPHBlockHeader *prev;
+ Heap_EXPHBlockHeader *usedBlock;
+ Heap_Region r;
+
+ Heap_GetRegion(&free1, blockHeader);
+ free2.end = free1.end;
+ free2.start = AddU32_inline(block, size);
+ free1.end = (u32) block - (u32) sizeof(Heap_EXPHBlockHeader);
+ prev = Heap_RemoveBlock(&EXPHHeader->freeBlocks, blockHeader);
+
+ if (free1.end - free1.start < (u32) 0x14) {
+ free1.end = free1.start;
+ } else {
+ prev = Heap_InsertBlock(&EXPHHeader->freeBlocks, Heap_InitBlock(&free1, 'FR'), prev);
+ }
+
+ if (free2.end - free2.start < (u32) 0x14) {
+ free2.start = free2.end;
+ } else {
+ Heap_InsertBlock(&EXPHHeader->freeBlocks, Heap_InitBlock(&free2, 'FR'), prev);
+ }
+
+ Fill32_inline((u32) EXPHHeader - sizeof(Heap_Header), free1.end, free2.start - free1.end);
+
+ r.start = (u32) block - (u32) sizeof(Heap_EXPHBlockHeader);
+ r.end = free2.start;
+ usedBlock = Heap_InitBlock(&r, 'UD');
+ SetBit(usedBlock->flags, 15, 1, direction);
+ SetBit(usedBlock->flags, 8, 7, (u16) Diff_Ptr_inline(free1.end, usedBlock));
+ SetBit(usedBlock->flags, 0, 8, EXPHHeader->id);
+ Heap_InsertBlock(&EXPHHeader->usedBlocks, usedBlock, EXPHHeader->usedBlocks.tail);
+ return block;
+}
+
+void *Heap_EXPHAllocHead(Heap_Header *header, u32 size, int alignment) {
+ Heap_EXPHHeader *expHeader = GetEXPH_inline(header);
+ Heap_EXPHBlockHeader *blockHeader;
+ const u32 flag1 = (u16) (expHeader->flags & 1) == 0;
+
+ Heap_EXPHBlockHeader *foundBlockHeader = NULL;
+ u32 foundSize = 0xffffffff;
+ void *foundBlock = NULL;
+
+ for (blockHeader = expHeader->freeBlocks.head; blockHeader; blockHeader = blockHeader->next) {
+ void *const mblock = AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader));
+ void *const reqBlock = ((alignment - 1) + (u32) mblock) & ~(alignment - 1);
+ const u32 offset = reqBlock - mblock;
+
+ if (blockHeader->size >= size + offset && foundSize > blockHeader->size) {
+ foundBlockHeader = blockHeader;
+ foundSize = blockHeader->size;
+ foundBlock = reqBlock;
+
+ if (flag1 || foundSize == size) {
+ break;
+ }
+ }
+ }
+
+ if (!foundBlockHeader) {
+ return NULL;
+ }
+
+ return Heap_AllocFreeBlock(expHeader, foundBlockHeader, foundBlock, size, 0);
+}
+
+void *Heap_EXPHAllocTail(Heap_Header *header, u32 size, int alignment) {
+ Heap_EXPHHeader *expHeader = GetEXPH_inline(header);
+ Heap_EXPHBlockHeader *blockHeader;
+
+ const u32 flag1 = (u16) (expHeader->flags & 1) == 0;
+
+ Heap_EXPHBlockHeader *foundBlockHeader = NULL;
+ u32 foundSize = 0xffffffff;
+ void *foundBlock = NULL;
+
+ for (blockHeader = expHeader->freeBlocks.tail; blockHeader; blockHeader = blockHeader->prev) {
+ void *const mblock = AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader));
+ void *const mblockEnd = AddU32_inline(mblock, blockHeader->size);
+ void *const reqBlock = (u32) (mblockEnd - size) & ~(alignment - 1);
+
+ if (reqBlock - mblock >= 0 && foundSize > blockHeader->size) {
+ foundBlockHeader = blockHeader;
+ foundSize = blockHeader->size;
+ foundBlock = reqBlock;
+
+ if (flag1 || foundSize == size) {
+ break;
+ }
+ }
+ }
+
+ if (!foundBlockHeader) {
+ return NULL;
+ }
+
+ return Heap_AllocFreeBlock(expHeader, foundBlockHeader, foundBlock, size, 1);
+}
+
+u32 Heap_EmptyRegion(Heap_EXPHHeader *expHeader, const Heap_Region *r) {
+ Heap_EXPHBlockHeader *freeBlockHeader = NULL;
+ Heap_Region freeRgn = *r;
+ Heap_EXPHBlockHeader *block;
+
+ for (block = expHeader->freeBlocks.head; block; block = block->next) {
+ if (block < r->start) {
+ freeBlockHeader = block;
+ continue;
+ }
+
+ if (block == r->end) {
+ freeRgn.end = AddU32_inline(AddU32_inline(block, sizeof(Heap_EXPHBlockHeader)), block->size);
+ Heap_RemoveBlock(&expHeader->freeBlocks, block);
+ }
+ break;
+ }
+
+ if (freeBlockHeader &&
+ AddU32_inline(AddU32_inline(freeBlockHeader, sizeof(Heap_EXPHBlockHeader)), freeBlockHeader->size) == r->start) {
+ freeRgn.start = freeBlockHeader;
+ freeBlockHeader = Heap_RemoveBlock(&expHeader->freeBlocks, freeBlockHeader);
+ }
+
+ if (freeRgn.end - freeRgn.start < sizeof(Heap_EXPHBlockHeader)) {
+ return 0;
+ }
+
+ Heap_InsertBlock(&expHeader->freeBlocks, Heap_InitBlock(&freeRgn, 'FR'), freeBlockHeader);
+ return 1;
+}
+
+Heap_Header *Heap_EXPHCreate(void *startAddress, u32 size, u16 optFlag) {
+ void *endAddress;
+ Heap_Header *header;
+ endAddress = ((u32) AddU32_inline(startAddress, size)) & ~3;
+ startAddress = (u32) startAddress + 3 & ~3;
+
+ if (startAddress > endAddress || endAddress - startAddress < (u32) 0x4c) {
+ return NULL;
+ }
+
+ header = Heap_EXPHInit(startAddress, endAddress, optFlag);
+ return header;
+}
+
+void Heap_EXPHDestroy(Heap_Header *heap) {
+ Heap_DestroyInternal(heap);
+}
+
+void *Heap_EXPHNew(Heap_Header *heap, u32 size, int alignment) {
+ void *h = NULL;
+
+ if (size == 0) {
+ size = 1;
+ }
+
+ size = (size + 3) & ~3;
+
+ if (alignment >= 0) {
+ h = Heap_EXPHAllocHead(heap, size, alignment);
+ } else {
+ h = Heap_EXPHAllocTail(heap, size, -alignment);
+ }
+
+ return h;
+}
+
+u32 Heap_EXPHResizeBlock(Heap_Header *heap, void *memBlock, u32 size) {
+ Heap_EXPHHeader *expHeader;
+ Heap_EXPHBlockHeader *blockHeader;
+
+ expHeader = AddU32_inline(heap, sizeof(Heap_Header));
+ blockHeader = (u32) memBlock - sizeof(Heap_EXPHBlockHeader);
+
+ size = (size + 3) & ~3;
+ if (size == blockHeader->size) {
+ return size;
+ }
+
+ if (size > blockHeader->size) {
+ void *end = AddU32_inline(AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader)), blockHeader->size);
+ Heap_EXPHBlockHeader *block;
+ Heap_Region tmpRgn;
+ void *tmpStart;
+ Heap_EXPHBlockHeader *newPrev;
+
+ for (block = expHeader->freeBlocks.head; block; block = block->next) {
+ if (block == end) {
+ break;
+ }
+ }
+
+ if (!block || size > blockHeader->size + sizeof(Heap_EXPHBlockHeader) + block->size) {
+ return 0;
+ }
+
+ Heap_GetRegion(&tmpRgn, block);
+ newPrev = Heap_RemoveBlock(&expHeader->freeBlocks, block);
+
+ tmpStart = tmpRgn.start;
+ tmpRgn.start = AddU32_inline(memBlock, size);
+
+ if (tmpRgn.end - tmpRgn.start < sizeof(Heap_EXPHBlockHeader)) {
+ tmpRgn.start = tmpRgn.end;
+ }
+
+ blockHeader->size = tmpRgn.start - memBlock;
+
+ if (tmpRgn.end - tmpRgn.start >= sizeof(Heap_EXPHBlockHeader)) {
+ Heap_InsertBlock(&expHeader->freeBlocks, Heap_InitBlock(&tmpRgn, 'FR'), newPrev);
+ }
+
+ Fill32_inline(heap, tmpStart, tmpRgn.start - tmpStart);
+
+ } else {
+ Heap_Region tmpRgn;
+ const u32 oldBlockSize = blockHeader->size;
+
+ tmpRgn.start = AddU32_inline(memBlock, size);
+ tmpRgn.end = AddU32_inline(AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader)), blockHeader->size);
+ blockHeader->size = size;
+
+ if (!Heap_EmptyRegion(expHeader, &tmpRgn)) {
+ blockHeader->size = oldBlockSize;
+ }
+ }
+
+ return blockHeader->size;
+}
+
+void Heap_EXPHFreeBlock(Heap_Header *heap, void *memBlock) {
+ Heap_Header *header = heap;
+ Heap_EXPHHeader *expHeader = AddU32_inline(header, sizeof(Heap_Header));
+ Heap_EXPHBlockHeader *blockHeader = (Heap_EXPHBlockHeader *) (memBlock - sizeof(Heap_EXPHBlockHeader));
+ Heap_Region region;
+
+ Heap_GetRegion(&region, blockHeader);
+ Heap_RemoveBlock(&expHeader->usedBlocks, blockHeader);
+ Heap_EmptyRegion(expHeader, &region);
+}
+
+u32 Heap_EXPHGetEmptySize(Heap_Header *heap) {
+ u32 totalSize = 0;
+ Heap_EXPHBlockHeader *blockHeader;
+ Heap_EXPHHeader *expHeader = AddU32_inline(heap, sizeof(Heap_Header));
+
+ for (blockHeader = expHeader->freeBlocks.head; blockHeader; blockHeader = blockHeader->next) {
+ totalSize += blockHeader->size;
+ }
+
+ return totalSize;
+}
+
+u32 Heap_EXPHGetMaxEmptySize(Heap_Header *heap, int alignment) {
+
+ alignment = abs(alignment);
+
+ {
+ Heap_EXPHHeader *expHeader = AddU32_inline(heap, sizeof(Heap_Header));
+ u32 maxSize = 0;
+ u32 offsetMin = 0xFFFFFFFF;
+ Heap_EXPHBlockHeader *blockHeader;
+
+ for (blockHeader = expHeader->freeBlocks.head; blockHeader; blockHeader = blockHeader->next) {
+ void *baseAddress =
+ ((u32) AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader)) + (alignment - 1)) & ~(alignment - 1);
+
+ if (baseAddress < AddU32_inline(AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader)), blockHeader->size)) {
+ const u32 blockSize =
+ AddU32_inline(AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader)), blockHeader->size) - baseAddress;
+ const u32 offset = baseAddress - AddU32_inline(blockHeader, sizeof(Heap_EXPHBlockHeader));
+
+ if (maxSize < blockSize || (maxSize == blockSize && offsetMin > offset)) {
+ maxSize = blockSize;
+ offsetMin = offset;
+ }
+ }
+ }
+ return maxSize;
+ }
+}
+
+static inline Heap_FRMHHeader *Get_FRMHHeader_inline(Heap_Header *header) {
+ return AddU32_inline(header, sizeof(Heap_Header));
+}
+
+Heap_Header *Heap_FRMHInit(void *startAddress, void *endAddress, u16 optFlag) {
+ Heap_Header *header = startAddress;
+ Heap_FRMHHeader *frmHeader = (void *) header + sizeof(Heap_Header);
+
+ Heap_InitHeader(header, 'FRMH', (void *) frmHeader + sizeof(Heap_FRMHHeader), endAddress, optFlag);
+
+ frmHeader->head = header->startAddr;
+ frmHeader->tail = header->endAddr;
+ frmHeader->state = NULL;
+
+ return header;
+}
+
+void *Heap_FRMHAllocHead(Heap_FRMHHeader *header, u32 size, int alignment) {
+ void *newBlock = ((alignment - 1) + ((u32) header->head)) & ~(alignment - 1);
+ void *endAddress = AddU32_inline(newBlock, size);
+
+ if ((u32) endAddress > (u32) header->tail) {
+ return NULL;
+ }
+
+ Fill32_inline((void *) ((u32) (header) - sizeof(Heap_Header)), header->head, endAddress - header->head);
+ header->head = endAddress;
+
+ return newBlock;
+}
+
+void *Heap_FRMHAllocTail(Heap_FRMHHeader *header, u32 size, int alignment) {
+ void *newBlock = (u32) (header->tail - size) & ~(alignment - 1);
+
+ if ((u32) (newBlock) < (u32) (header->head)) {
+ return NULL;
+ }
+
+ Fill32_inline((void *) ((u32) (header) - sizeof(Heap_Header)), newBlock, header->tail - newBlock);
+ header->tail = newBlock;
+
+ return newBlock;
+}
+
+void Heap_FRMHFreeHead(Heap_Header *header) {
+ Heap_FRMHHeader *frmHeader = (u32) header + sizeof(Heap_Header);
+ frmHeader->head = header->startAddr;
+ frmHeader->state = NULL;
+}
+
+void Heap_FRMHFreeTail(Heap_Header *header) {
+ Heap_FRMHHeader *frmHeader = Get_FRMHHeader_inline(header);
+ Heap_FRMHState *pState;
+
+ for (pState = frmHeader->state; pState; pState = pState->prev) {
+ pState->tail = header->endAddr;
+ }
+
+ frmHeader->tail = header->endAddr;
+}
+
+Heap_Header *Heap_FRMHCreate(void *startAddress, u32 size, u16 optFlag) {
+ void *endAddress;
+ Heap_Header *header;
+
+ endAddress = (size + (u32) startAddress) & ~3;
+ startAddress = (3 + (u32) startAddress) & ~3;
+
+ if ((u32) (startAddress) > (u32) (endAddress) ||
+ endAddress - startAddress < sizeof(Heap_Header) + sizeof(Heap_FRMHHeader)) {
+ return NULL;
+ }
+
+ header = Heap_FRMHInit(startAddress, endAddress, optFlag);
+ return header;
+}
+
+void Heap_FRMHDestroy(Heap_Header *heap) {
+ Heap_DestroyInternal(heap);
+}
+
+void *Heap_FRMHNew(Heap_Header *heap, u32 size, int alignment) {
+ void *memory;
+ Heap_FRMHHeader *header;
+
+ header = (void *) heap + sizeof(Heap_Header);
+
+ if (size == 0) {
+ size = 1;
+ }
+
+ size = size + 3 & ~3;
+
+ if (alignment >= 0) {
+ memory = Heap_FRMHAllocHead(header, size, alignment);
+ } else {
+ memory = Heap_FRMHAllocTail(header, size, -alignment);
+ }
+
+ return memory;
+}
+
+void Heap_FRMHFreeBlock(Heap_Header *heap, int mode) {
+ if (mode & 1) {
+ Heap_FRMHFreeHead(heap);
+ }
+
+ if (mode & 2) {
+ Heap_FRMHFreeTail(heap);
+ }
+}
+
+u32 Heap_FRMHGetMaxEmptySize(Heap_Header *heap, int alignment) {
+ const Heap_FRMHHeader *header;
+ const void *block;
+
+ alignment = abs(alignment);
+ header = AddU32_inline(heap, sizeof(Heap_Header));
+ block = (alignment - 1) + (u32) header->head & ~(alignment - 1);
+
+ if ((u32) block > (u32) header->tail) {
+ return 0;
+ }
+
+ return header->tail - (u32) block;
+}
+
+u32 Heap_FRMHSaveState(Heap_Header *heap, u32 id) {
+ Heap_FRMHHeader *header = Get_FRMHHeader_inline(heap);
+ void *oldHead = header->head;
+
+ Heap_FRMHState *state = Heap_FRMHAllocHead(header, sizeof(Heap_FRMHState), 4);
+ if (!state) {
+ return 0;
+ }
+
+ state->id = id;
+ state->head = oldHead;
+ state->tail = header->tail;
+ state->prev = header->state;
+ header->state = state;
+
+ return 1;
+}
+
+u32 Heap_FRMHLoadState(Heap_Header *heap, u32 id) {
+ Heap_FRMHHeader *header = AddU32_inline(heap, sizeof(Heap_Header));
+ Heap_FRMHState *state = header->state;
+
+ if (id != 0) {
+ while (state) {
+ if (state->id == id) {
+ break;
+ }
+ state = state->prev;
+ }
+ }
+
+ if (!state) {
+ return 0;
+ }
+
+ header->head = state->head;
+ header->tail = state->tail;
+ header->state = state->prev;
+
+ return 1;
+}
+
+u32 Heap_FRMHFreeEmpty(Heap_Header *heap) {
+ Heap_Header *header = heap;
+ Heap_FRMHHeader *frmHeader = AddU32_inline(header, sizeof(Heap_Header));
+
+ if (0 < ((u32) header->endAddr - (u32) frmHeader->tail)) {
+ return 0;
+ }
+
+ frmHeader->tail = header->endAddr = frmHeader->head;
+
+ return ((u32) header->endAddr - (u32) heap);
+}
+
+Heap_Header *Heap_FindBlockInternal(Heap_LinkedList *list, const void *block) {
+ Heap_Header *header = NULL;
+ while (NULL != (header = Heap_ListNext(list, header))) {
+ if ((u32) (header->startAddr) <= (u32) (block) && (u32) (block) < (u32) (header->endAddr)) {
+ Heap_Header *subHeader = Heap_FindBlockInternal(&header->children, block);
+ if (subHeader) {
+ return subHeader;
+ }
+ return header;
+ }
+ }
+ return NULL;
+}
+
+Heap_LinkedList *Heap_FindParentHeap(Heap_Header *header) {
+ Heap_LinkedList *list = &gHeapList;
+ Heap_Header *res = Heap_FindBlockInternal(&gHeapList, header);
+ if (res) {
+ list = &res->children;
+ }
+
+ return list;
+}
+
+void Heap_InitHeader(Heap_Header *header, u32 stamp, void *heapStart, void *heapEnd, u16 optFlag) {
+ header->stamp = stamp;
+ header->startAddr = heapStart;
+ header->endAddr = heapEnd;
+ header->flags = 0;
+ SetBit(header->flags, 0, 8, optFlag);
+
+ Heap_InitList(&header->children, offsetof(Heap_Header, link));
+
+ if (!gHeapListInitialized) {
+ Heap_InitList(&gHeapList, offsetof(Heap_Header, link));
+ gHeapListInitialized = 1;
+ }
+
+ Heap_ListAppend(Heap_FindParentHeap(header), header);
+}
+
+void Heap_DestroyInternal(Heap_Header *header) {
+ Heap_ListRemove(Heap_FindParentHeap(header), header);
+}
+
+Heap_Header *Heap_FindBlock(const void *memBlock) {
+ return Heap_FindBlockInternal(&gHeapList, memBlock);
+}
+
+void Heap_InitList(Heap_LinkedList *list, u16 offset) {
+ list->head = NULL;
+ list->tail = NULL;
+ list->numElements = 0;
+ list->offset = offset;
+}
+
+void Heap_ListSetFirst(Heap_LinkedList *list, void *object) {
+ Heap_LinkedObject *link;
+
+ link = ((Heap_LinkedObject *) ((u32) (object) + list->offset));
+ link->next = NULL;
+ link->prev = NULL;
+ list->head = object;
+ list->tail = object;
+ list->numElements++;
+}
+
+void Heap_ListAppend(Heap_LinkedList *list, void *object) {
+ if (list->head == NULL) {
+ Heap_ListSetFirst(list, object);
+ } else {
+ Heap_LinkedObject *link = ((Heap_LinkedObject *) ((u32) (object) + list->offset));
+
+ link->prev = list->tail;
+ link->next = NULL;
+
+ ((Heap_LinkedObject *) ((u32) (list->tail) + list->offset))->next = object;
+ list->tail = object;
+ list->numElements++;
+ }
+}
+
+void Heap_ListPrepend(Heap_LinkedList *list, void *object) {
+ if (list->head == NULL) {
+ Heap_ListSetFirst(list, object);
+ } else {
+ Heap_LinkedObject *link = ((Heap_LinkedObject *) ((u32) (object) + list->offset));
+ link->prev = NULL;
+ link->next = list->head;
+ ((Heap_LinkedObject *) ((u32) (list->head) + list->offset))->prev = object;
+ list->head = object;
+ list->numElements++;
+ }
+}
+
+void Heap_ListInsertBefore(Heap_LinkedList *list, void *target, void *object) {
+ if (target == NULL) {
+ Heap_ListAppend(list, object);
+ } else if (target == list->head) {
+ Heap_ListPrepend(list, object);
+ } else {
+ Heap_LinkedObject *link = ((Heap_LinkedObject *) ((u32) (object) + list->offset));
+ void *prevObj = ((Heap_LinkedObject *) ((u32) (target) + list->offset))->prev;
+ Heap_LinkedObject *prevLnk = ((Heap_LinkedObject *) ((u32) (prevObj) + list->offset));
+
+ link->prev = prevObj;
+ link->next = target;
+ prevLnk->next = object;
+ ((Heap_LinkedObject *) ((u32) (target) + list->offset))->prev = object;
+ list->numElements++;
+ }
+}
+
+void Heap_ListRemove(Heap_LinkedList *list, void *object) {
+ Heap_LinkedObject *link;
+
+ link = ((Heap_LinkedObject *) ((u32) (object) + list->offset));
+
+ if (link->prev == NULL) {
+ list->head = link->next;
+ } else {
+ ((Heap_LinkedObject *) ((u32) (link->prev) + list->offset))->next = link->next;
+ }
+ if (link->next == NULL) {
+ list->tail = link->prev;
+ } else {
+ ((Heap_LinkedObject *) ((u32) (link->next) + list->offset))->prev = link->prev;
+ }
+ link->prev = NULL;
+ link->next = NULL;
+ list->numElements--;
+}
+
+void *Heap_ListNext(Heap_LinkedList *list, void *object) {
+ if (object == NULL) {
+ return list->head;
+ }
+ return ((Heap_LinkedObject *) ((u32) (object) + list->offset))->next;
+}
+
+void *Heap_ListPrev(Heap_LinkedList *list, void *object) {
+ if (object == NULL) {
+ return list->tail;
+ }
+ return ((Heap_LinkedObject *) ((u32) (object) + list->offset))->prev;
+}
+
+Heap_Header *Heap_UNTHCreate(void *startAddress, u32 heapSize, u32 memBlockSize, int alignment, u16 optFlag) {
+ Heap_Header *header;
+ void *heapEnd;
+ Heap_UNTHHeader *pUntHeapHd;
+ void *heapStart;
+ u32 elementNum;
+
+ header = (void *) ((u32) startAddress + 3 & ~3);
+ heapEnd = (void *) ((u32) AddU32_inline(startAddress, heapSize) & ~3);
+
+ if ((const u8 *) header - (const u8 *) heapEnd > 0) {
+ return 0;
+ }
+
+ memBlockSize = memBlockSize + (alignment - 1) & ~(alignment - 1);
+ pUntHeapHd = (void *) (sizeof(Heap_Header) + (u32) header);
+ heapStart = (void *) (((u32) AddU32_inline(pUntHeapHd, sizeof(Heap_UNTHHeader)) + (alignment - 1)) & ~(alignment - 1));
+
+ if ((u8 *) heapStart - (u8 *) heapEnd > 0) {
+ return 0;
+ }
+
+ elementNum = (heapEnd - heapStart) / memBlockSize;
+ if (elementNum == 0) {
+ return 0;
+ }
+
+ heapEnd = AddU32_inline(heapStart, elementNum * memBlockSize);
+ Heap_InitHeader(header, 'UNTH', heapStart, heapEnd, optFlag);
+ pUntHeapHd->freeBlocks.head = heapStart;
+ pUntHeapHd->blockSize = memBlockSize;
+
+ {
+ Heap_UNTHBlockHeader *pMBlkHd = pUntHeapHd->freeBlocks.head;
+ int i;
+
+ for (i = 0; i < elementNum - 1; ++i, pMBlkHd = pMBlkHd->next) {
+ pMBlkHd->next = AddU32_inline(pMBlkHd, memBlockSize);
+ }
+
+ pMBlkHd->next = NULL;
+ }
+
+ return header;
+}
+
+void Heap_Destroy(Heap_Header *heap) {
+ Heap_DestroyInternal(heap);
+}
+
+u32 Heap_UNTHSize(u32 memBlockSize, u32 memBlockNum, int alignment) {
+ return sizeof(Heap_Header) + sizeof(Heap_UNTHHeader) + (alignment - 4) +
+ memBlockNum * (((memBlockSize) + (alignment - 1)) & ~(alignment - 1));
+} \ No newline at end of file
diff --git a/src/04_Load/Actor/ActorManager_04.cpp b/src/04_Load/Actor/ActorManager_04.cpp
index 84a1f970..497f0208 100644
--- a/src/04_Load/Actor/ActorManager_04.cpp
+++ b/src/04_Load/Actor/ActorManager_04.cpp
@@ -129,7 +129,6 @@ THUMB void ActorManager::func_ov004_0210532c() {
return;
}
-extern "C" void func_020174a4(u32 *, void *);
extern "C" void func_ov017_02168a90();
extern "C" void func_ov025_0216d6dc();
extern "C" void func_ov029_0216d6f0(unk32 *);
@@ -147,7 +146,7 @@ THUMB void ActorManager::func_ov004_021053dc() {
this->DeleteActor(i, true);
}
}
- func_020174a4(data_027e0ce0[1], this->mActorTable);
+ Heap_EXPHFreeBlock((Heap_Header *) data_027e0ce0[1], this->mActorTable);
this->mActorTable = NULL;
delete this->mUnk_14;
this->mUnk_14 = NULL;
@@ -179,7 +178,6 @@ THUMB void ActorManager::func_ov004_021053dc() {
}
extern "C" void func_ov000_020c3388(unk32);
-extern "C" void *NewEXPH(u32 *id, s32 length, s32 param_3);
THUMB void ActorManager::func_ov004_021054a4(FileEntryFlag *param1, s32 param2, unk32 param3) {
u16 sVar1;
u16 sVar2;
@@ -205,7 +203,7 @@ THUMB void ActorManager::func_ov004_021054a4(FileEntryFlag *param1, s32 param2,
}
param1->vfunc_0c();
func_ov000_020c3388(sVar2);
- this->mActorTable = (Actor **) NewEXPH(data_027e0ce0[1], this->mMaxActors * 4, 4);
+ this->mActorTable = (Actor **) Heap_EXPHNew((Heap_Header *) data_027e0ce0[1], this->mMaxActors * 4, 4);
Fill256(0, this->mActorTable, this->mMaxActors * 4);
this->mUnk_14 = new(data_027e0ce0[1], 4) ActorManager_Unk14(this->mMaxActors);
}
diff --git a/src/08_GameStart/Init.cpp b/src/08_GameStart/Init.cpp
index 0481ca38..ce835be9 100644
--- a/src/08_GameStart/Init.cpp
+++ b/src/08_GameStart/Init.cpp
@@ -15,6 +15,7 @@
#include "Unknown/UnkStruct_027e0d54.hpp"
#include "Unknown/UnkStruct_027e0dbc.hpp"
#include "Unknown/UnkStruct_027e0f88.hpp"
+#include "nds/heap.h"
extern "C" {
void func_0200a23c();
@@ -22,9 +23,7 @@ void func_0200a318(u8 *);
unk32 func_0200dd94();
unk32 func_0200a284(u8 *);
u16 func_ov001_020efdac();
-void *NewEXPH(char *id, s32 length, s32 param_3);
unk32 func_ov000_020773c0();
-void func_020174a4(u32 *, void *);
void func_0201f378();
void func_0202019c(void *, const char *, u32 *, unk32);
void func_020213f0(u32 *);
@@ -165,13 +164,13 @@ ARM UnkStruct_020ee698::UnkStruct_020ee698() :
mUnk_02(0),
mUnk_04(func_ov001_020efdac()),
mUnk_08(0x0D) {
- void *newHeap = NewEXPH((char *) data_027e0ce0[1], 0x700, 0x20);
+ void *newHeap = Heap_EXPHNew((Heap_Header *) data_027e0ce0[1], 0x700, 0x20);
if (func_ov000_020773c0() == 3) {
this->mUnk_00 = 1;
}
- func_020174a4(data_027e0ce0[1], newHeap);
+ Heap_EXPHFreeBlock((Heap_Header *) data_027e0ce0[1], newHeap);
}
// --- data_ov000_020ee734 ---