summaryrefslogtreecommitdiff
path: root/src/boot_O2
diff options
context:
space:
mode:
authorrozlette <uberpanzermensch@gmail.com>2020-01-12 20:18:31 -0600
committerrozlette <uberpanzermensch@gmail.com>2020-01-12 20:18:31 -0600
commit30daa16255114a3d37c2197288a7194b360625d8 (patch)
tree7059608b49f7f3755415228dbc430711d806a878 /src/boot_O2
parent76c3d660a97526809b58ecc635ad46ef6bdaeefa (diff)
Port stackcheck.c from oot decomp
Diffstat (limited to 'src/boot_O2')
-rw-r--r--src/boot_O2/stackcheck.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/boot_O2/stackcheck.c b/src/boot_O2/stackcheck.c
new file mode 100644
index 000000000..b2e28a34d
--- /dev/null
+++ b/src/boot_O2/stackcheck.c
@@ -0,0 +1,121 @@
+#include <ultra64.h>
+#include <global.h>
+
+void StackCheck_Init(StackEntry* entry, u32 stackTop, u32 stackBottom, u32 initValue, s32 minSpace, char* name) {
+ StackEntry* iter;
+ u32* addr;
+
+ if (!entry) {
+ sStackInfoListStart = NULL;
+ } else {
+ entry->head = stackTop;
+ entry->tail = stackBottom;
+ entry->initValue = initValue;
+ entry->minSpace = minSpace;
+ entry->name = name;
+ iter = sStackInfoListStart;
+ while (iter) {
+ if (iter == entry) {
+ return;
+ }
+ iter = iter->next;
+ }
+
+ entry->prev = sStackInfoListEnd;
+ entry->next = NULL;
+
+ if (sStackInfoListEnd) {
+ sStackInfoListEnd->next = entry;
+ }
+
+ sStackInfoListEnd = entry;
+ if (!sStackInfoListStart) {
+ sStackInfoListStart = entry;
+ }
+
+ if (entry->minSpace != -1) {
+ addr = (u32*)entry->head;
+ while ((u32)addr < entry->tail) {
+ *addr++ = entry->initValue;
+ }
+ }
+ }
+}
+
+void StackCheck_Cleanup(StackEntry* entry) {
+ u32 inconsistency = 0; // unused variable needed to match
+
+ if (!entry->prev) {
+ if (entry == sStackInfoListStart) {
+ sStackInfoListStart = entry->next;
+ } else {
+ inconsistency = 1;
+ }
+ } else {
+ entry->prev->next = entry->next;
+ }
+
+ if (!entry->next) {
+ if (entry == sStackInfoListEnd) {
+ sStackInfoListEnd = entry->prev;
+ } else {
+ inconsistency = 1;
+ }
+ }
+
+ if (inconsistency) {}
+}
+
+#ifdef NON_MATCHING
+// Missing useless move
+s32 StackCheck_GetState(StackEntry* entry) {
+ u32* last;
+ u32 used;
+ u32 free;
+ s32 ret;
+
+ for (last = (u32*)entry->head; (u32)last < entry->tail; last++) {
+ if (entry->initValue != *last) {
+ break;
+ }
+ }
+
+ used = entry->tail - (u32)last;
+ free = (u32)last - entry->head;
+
+ if (free == 0) {
+ return 2;
+ }
+
+ if (free < entry->minSpace && entry->minSpace != -1) {
+ return 1;
+ }
+
+ return 0;
+}
+#else
+GLOBAL_ASM("asm/nonmatching/stackcheck/StackCheck_GetState.asm")
+#endif
+
+u32 StackCheck_CheckAll() {
+ u32 ret = 0;
+
+ StackEntry* iter = sStackInfoListStart;
+ while(iter) {
+ u32 state = StackCheck_GetState(iter);
+ if (state) {
+ ret = 1;
+ }
+ iter = iter->next;
+ }
+
+ return ret;
+}
+
+u32 StackCheck_Check(StackEntry* entry) {
+ if (!entry) {
+ return StackCheck_CheckAll();
+ } else {
+ return StackCheck_GetState(entry);
+ }
+}