diff --git a/config/regions.tsv b/config/regions.tsv index 71db94a..ced0808 100644 --- a/config/regions.tsv +++ b/config/regions.tsv @@ -27,6 +27,7 @@ 0x80017C60 0x80017C6C src/func_80017C60.c 0x80017D1C 0x80017D48 src/func_80017D1C.c 0x80017DD0 0x80017DF0 src/func_80017DD0.c +0x80019B6C 0x80019B94 src/func_80019B6C.c 0x80019C04 0x80019C10 src/func_80019C04.c 0x8001AA9C 0x8001AAA8 src/func_8001AA9C.c 0x8001AE3C 0x8001AE50 src/func_8001AE3C.c diff --git a/src/func_80019B6C.c b/src/func_80019B6C.c new file mode 100644 index 0000000..ebdd6ba --- /dev/null +++ b/src/func_80019B6C.c @@ -0,0 +1,34 @@ +/* func_80019B6C - 0x80019B6C..0x80019B94 (40 bytes). + * + * Original words: + * 0x24020110 li v0,272 i = 272 + * 0x3C018012 lui at,0x8012 \ address of D_80125E3C + i: the symbol's + * 0x00220821 addu at,at,v0 | high half in `at`, the byte index added, + * 0xAC205E3C sw zero,24124(at)/ the low half as the store offset + * 0x2442FFBC addiu v0,v0,-68 i -= 68 + * 0x0441FFFB bgez v0,-5 loop while i >= 0 + * 0x00000000 nop + * 0xAF800144 sw zero,324(gp) D_80121A7C = 0 + * 0x03E00008 jr ra + * 0x00000000 nop + * + * Pure C, no asm. Two details are load-bearing: + * - the index counts DOWN from 272 with `i >= 0`, which is the direction the + * original runs (an upward `for (i = 0; i <= 272; i += 68)` gives the + * `sltu`-guarded form and 8 differing words); + * - the index is a BYTE offset into a `char` array. The store is a single + * `sw`, so the target is a 4-byte int, but no scaling instruction appears, + * which is why the symbol is declared `char D_80125E3C[]` and the store + * casts to `int *`. + */ +extern char D_80125E3C[]; +extern int D_80121A7C; + +void func_80019B6C(void) +{ + int i; + + for (i = 272; i >= 0; i -= 68) + *(int *)(D_80125E3C + i) = 0; + D_80121A7C = 0; +}