diff options
| author | rozlette <uberpanzermensch@gmail.com> | 2020-01-12 20:18:31 -0600 |
|---|---|---|
| committer | rozlette <uberpanzermensch@gmail.com> | 2020-01-12 20:18:31 -0600 |
| commit | 30daa16255114a3d37c2197288a7194b360625d8 (patch) | |
| tree | 7059608b49f7f3755415228dbc430711d806a878 /src/boot_O2/stackcheck.c | |
| parent | 76c3d660a97526809b58ecc635ad46ef6bdaeefa (diff) | |
Port stackcheck.c from oot decomp
Diffstat (limited to 'src/boot_O2/stackcheck.c')
| -rw-r--r-- | src/boot_O2/stackcheck.c | 121 |
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); + } +} |
