summaryrefslogtreecommitdiff
path: root/arm9/src
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src')
-rw-r--r--arm9/src/game_init.c5
-rw-r--r--arm9/src/heap.c380
2 files changed, 382 insertions, 3 deletions
diff --git a/arm9/src/game_init.c b/arm9/src/game_init.c
index 327c66c6..a7508fab 100644
--- a/arm9/src/game_init.c
+++ b/arm9/src/game_init.c
@@ -4,16 +4,15 @@
#include "main.h"
#include "FS_rom.h"
#include "PAD_pad.h"
-#include "heap.h"
#include "MWC_string.h"
#include "tp.h"
#include "unk_0201B4E8.h"
#include "game_init.h"
#include "registers.h"
+#include "heap.h"
#pragma thumb on
-extern void FUN_020166C8(const u32 (*)[2], int, int, int);
extern void FUN_02022450(void);
typedef volatile struct
@@ -142,7 +141,7 @@ void FUN_02015FC8(void)
{
csum++;
}
- FUN_020166C8(UNK_020EDB10, 4, 92, (int)csum);
+ FUN_020166C8((u32 *)UNK_020EDB10, 4, 92, (int)csum);
}
void InitSystemForTheGame(void)
diff --git a/arm9/src/heap.c b/arm9/src/heap.c
new file mode 100644
index 00000000..c27a40c0
--- /dev/null
+++ b/arm9/src/heap.c
@@ -0,0 +1,380 @@
+#include "heap.h"
+
+extern void *tempName_NNS_FndCreateExpHeapEx(void *param0, u32 param1, u32 param2);
+extern void *tempName_NNS_FndAllocFromExpHeapEx(void *param0, u32 param1, s32 param2);
+extern void thunk_FUN_020adc8c();
+extern void FUN_020ADDF0(void *ptr1, void *ptr2);
+extern u32 FUN_02031810(void);
+extern void PrintErrorMessageAndReset(void);
+extern u32 FUN_020ADDC8(void *param0);
+extern void FUN_020AE82C(u32 param0, void *param1, u32 param2);
+extern u32 FUN_020ADDC0(void *param0);
+extern void FUN_020ADE2C(void *ptr1, void *ptr2, u32 param2);
+
+
+struct UnkStruct_020166C8 UNK_021C4D28;
+
+
+THUMB_FUNC void FUN_020166C8(u32 *param0, u32 param1, u32 param2, u32 pre_size)
+{
+ u32 unk_size = param1 + 24;
+
+ if (param2 < unk_size)
+ {
+ param2 = unk_size;
+ }
+ if (pre_size != 0)
+ {
+ while (pre_size % 4 != 0)
+ {
+ pre_size++;
+ }
+
+ OS_AllocFromArenaLo(OS_ARENA_MAIN, pre_size, 4);
+ }
+
+ u32 r7 = param2 * 2;
+
+ void *ptr = OS_AllocFromArenaLo(OS_ARENA_MAIN, (unk_size * 3 + 1) * sizeof(u32) + r7 + param2, 4);
+ UNK_021C4D28.unk00 = ptr;
+ ptr += (unk_size + 1) * 4;
+ UNK_021C4D28.unk04 = ptr;
+ ptr += unk_size * 4;
+ UNK_021C4D28.unk08 = ptr;
+ ptr += unk_size * 4;
+ UNK_021C4D28.unk0c = ptr;
+ ptr += r7;
+ UNK_021C4D28.unk10 = ptr;
+ UNK_021C4D28.unk14 = (u16)param2;
+ UNK_021C4D28.unk16 = (u16)param1;
+
+ r7 = 0;
+ UNK_021C4D28.unk1a = (u16)unk_size;
+ UNK_021C4D28.unk18 = (u16)unk_size;
+
+ while (r7 < param1)
+ {
+ void *ptr;
+ if (param0[1] == 0 || param0[1] != 2)
+ {
+ ptr = OS_AllocFromArenaLo(OS_ARENA_MAIN, param0[0], 4);
+ }
+ else
+ {
+ ptr = OS_AllocFromArenaHi(OS_ARENA_MAINEX, param0[0], 4);
+ }
+
+ if (ptr != 0)
+ {
+
+ UNK_021C4D28.unk00[r7] = tempName_NNS_FndCreateExpHeapEx(ptr, param0[0], 0);
+ UNK_021C4D28.unk10[r7] = (u8)r7;
+ }
+ else
+ {
+ ErrorHandling();
+ }
+
+ param0 += 2;
+ r7++;
+ }
+
+ while (param1 < unk_size + 1)
+ {
+ UNK_021C4D28.unk00[param1] = 0;
+ UNK_021C4D28.unk10[param1] = (u8)UNK_021C4D28.unk1a;
+
+ param1++;
+ }
+
+ while (param1 < param2)
+ {
+ UNK_021C4D28.unk10[param1] = (u8)UNK_021C4D28.unk1a;
+
+ param1++;
+ }
+
+ for (param1 = 0; param1 < param2; param1++)
+ {
+ UNK_021C4D28.unk0c[param1] = 0;
+ }
+}
+
+THUMB_FUNC s32 FUN_020167F4()
+{
+ s32 i = UNK_021C4D28.unk16;
+ s32 j = UNK_021C4D28.unk18;
+
+ if (i < j)
+ {
+ void **ptr = UNK_021C4D28.unk00 + i;
+ do
+ {
+ if (*ptr == 0)
+ {
+ return i;
+ }
+ i++;
+ ptr++;
+ } while (i < j);
+ }
+
+ return -1;
+}
+
+THUMB_FUNC u32 FUN_0201681C(u32 param0, u32 param1, u32 param2)
+{
+ return FUN_02016834(param0, param1, param2, 4);
+}
+
+THUMB_FUNC u32 FUN_02016828(u32 param0, u32 param1, u32 param2)
+{
+ return FUN_02016834(param0, param1, param2, -4);
+}
+
+THUMB_FUNC u32 FUN_02016834(u32 param0, u32 param1, u32 param2, s32 param3)
+{
+ GF_ASSERT(OS_GetProcMode() != OS_PROCMODE_IRQ);
+
+ u8 *ptr = UNK_021C4D28.unk10;
+ if (UNK_021C4D28.unk1a == ptr[param1])
+ {
+ void *ptr2 = UNK_021C4D28.unk00[ptr[param0]];
+ if (ptr2 != 0)
+ {
+ void *ptr3 = tempName_NNS_FndAllocFromExpHeapEx(ptr2, param2, param3);
+ if (ptr3 != 0)
+ {
+ param3 = FUN_020167F4();
+ if (param3 >= 0)
+ {
+ UNK_021C4D28.unk00[param3] = tempName_NNS_FndCreateExpHeapEx(ptr3, param2, 0);
+
+
+ if (UNK_021C4D28.unk00[param3] != 0)
+ {
+ UNK_021C4D28.unk04[param3] = ptr2;
+ UNK_021C4D28.unk08[param3] = ptr3;
+ UNK_021C4D28.unk10[param1] = (u8)param3;
+
+ return 1;
+ }
+ else
+ {
+ ErrorHandling();
+ }
+ }
+ else
+ {
+ ErrorHandling();
+ }
+ }
+ else
+ {
+ ErrorHandling();
+ }
+ }
+ else
+ {
+ ErrorHandling();
+ }
+ }
+ else
+ {
+ ErrorHandling();
+ }
+ return 0;
+}
+
+THUMB_FUNC void FUN_020168D0(u32 heap_id)
+{
+ GF_ASSERT (OS_GetProcMode() != OS_PROCMODE_IRQ);
+
+ if (UNK_021C4D28.unk00[UNK_021C4D28.unk10[heap_id]] != 0)
+ {
+ thunk_FUN_020adc8c();
+
+ u8 index = UNK_021C4D28.unk10[heap_id];
+ void *ptr1 = UNK_021C4D28.unk04[index];
+ void *ptr2 = UNK_021C4D28.unk08[index];
+ if (ptr1 != 0 && ptr2 != 0)
+ {
+ FUN_020ADDF0(ptr1, ptr2);
+ }
+ else
+ {
+ ErrorHandling();
+ }
+
+ UNK_021C4D28.unk00[UNK_021C4D28.unk10[heap_id]] = 0;
+ UNK_021C4D28.unk04[UNK_021C4D28.unk10[heap_id]] = 0;
+ UNK_021C4D28.unk08[UNK_021C4D28.unk10[heap_id]] = 0;
+
+ UNK_021C4D28.unk10[heap_id] = (u8)UNK_021C4D28.unk1a;
+ }
+}
+
+THUMB_FUNC u32 *FUN_02016944(void *param0, u32 param1, s32 param2, u32 param3)
+{
+ GF_ASSERT(param0);
+
+ OSIntrMode intr_mode = OS_DisableInterrupts();
+ param1 += 16;
+ u32 *ptr = (u32 *)tempName_NNS_FndAllocFromExpHeapEx(param0, param1, param2);
+
+ OS_RestoreInterrupts(intr_mode);
+ if (ptr != 0)
+ {
+ ptr[3] = (ptr[3] & ~0xff) | (param3 & 0xff);
+
+ ptr += 4;
+ }
+
+ return ptr;
+}
+
+THUMB_FUNC void FUN_02016988()
+{
+ if (FUN_02031810() != 0)
+ {
+ PrintErrorMessageAndReset();
+ }
+}
+
+void *AllocFromHeap(u32 heap_id, u32 size)
+{
+ void *ptr = 0;
+ if (heap_id < UNK_021C4D28.unk14)
+ {
+ u8 index = UNK_021C4D28.unk10[heap_id];
+ ptr = FUN_02016944(UNK_021C4D28.unk00[index], size, 4, heap_id);
+ }
+ if (ptr != 0)
+ {
+ UNK_021C4D28.unk0c[heap_id]++;
+ }
+ else
+ {
+ FUN_02016988();
+ }
+
+ return ptr;
+}
+
+void *AllocFromHeapAtEnd(u32 heap_id, u32 size)
+{
+ void *ptr = 0;
+ if (heap_id < UNK_021C4D28.unk14)
+ {
+ u8 index = UNK_021C4D28.unk10[heap_id];
+ ptr = FUN_02016944(UNK_021C4D28.unk00[index], size, -4, heap_id);
+ }
+
+ if (ptr != 0)
+ {
+ UNK_021C4D28.unk0c[heap_id]++;
+ }
+ else
+ {
+ FUN_02016988();
+ }
+
+ return ptr;
+}
+
+void FreeToHeap(void *ptr)
+{
+ u8 heap_id = (u8)((u32 *)ptr)[-1];
+
+ if ((u16)heap_id < UNK_021C4D28.unk14)
+ {
+ u8 index = UNK_021C4D28.unk10[heap_id];
+ void *ptr2 = UNK_021C4D28.unk00[index];
+ GF_ASSERT(ptr2);
+
+ if (UNK_021C4D28.unk0c[heap_id] == 0)
+ {
+ FUN_02016B90(heap_id);
+ }
+ GF_ASSERT(UNK_021C4D28.unk0c[heap_id]);
+
+ UNK_021C4D28.unk0c[heap_id]--;
+ OSIntrMode intr_mode = OS_DisableInterrupts();
+ FUN_020ADDF0(ptr2, ptr - 16);
+ OS_RestoreInterrupts(intr_mode);
+ return;
+ }
+
+ ErrorHandling();
+}
+
+void FUN_02016A8C(u32 param0, void *param1)
+{
+ GF_ASSERT (OS_GetProcMode() != OS_PROCMODE_IRQ);
+
+ if (param0 < UNK_021C4D28.unk14)
+ {
+ u8 index = UNK_021C4D28.unk10[param0];
+ void *ptr = UNK_021C4D28.unk00[index];
+ GF_ASSERT (ptr );
+
+ u8 heap_id = (u8)((u32 *)param1)[-1];
+ GF_ASSERT (heap_id == param0);
+
+ FUN_020ADDF0(ptr, param1 - 16);
+ GF_ASSERT (UNK_021C4D28.unk0c[param0]);
+
+ UNK_021C4D28.unk0c[param0]--;
+ return;
+ }
+
+ ErrorHandling();
+}
+
+THUMB_FUNC u32 FUN_02016AF8(u32 param0)
+{
+ if (param0 < UNK_021C4D28.unk14)
+ {
+ u8 index = UNK_021C4D28.unk10[param0];
+ return FUN_020ADDC8(UNK_021C4D28.unk00[index]);
+ }
+
+ ErrorHandling();
+ return 0;
+}
+
+THUMB_FUNC void FUN_02016B20(u32 param0, u32 param1, u32 param2)
+{
+ if (param1 < UNK_021C4D28.unk14)
+ {
+
+ u8 index = UNK_021C4D28.unk10[param1];
+ FUN_020AE82C(param0, UNK_021C4D28.unk00[index], param2);
+ return;
+ }
+
+ ErrorHandling();
+}
+
+THUMB_FUNC void FUN_02016B44(void *ptr, u32 param1)
+{
+ GF_ASSERT (OS_GetProcMode() != OS_PROCMODE_IRQ);
+
+ param1 += 16;
+ if (FUN_020ADDC0(ptr - 16) >= param1)
+ {
+ u8 heap_id = (u8)((u32 *)ptr)[-1];
+
+ u8 index = UNK_021C4D28.unk10[heap_id];
+
+ FUN_020ADE2C(UNK_021C4D28.unk00[index], ptr - 16, param1);
+ return;
+ }
+ ErrorHandling();
+}
+
+THUMB_FUNC u32 FUN_02016B90(u32 param0)
+{
+#pragma unused(param0)
+ return 1;
+}