From 38faa55a56bd9da6a7bd3f3369bf8aa3cd98ff67 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Wed, 2 Sep 2026 10:00:36 -0600 Subject: [PATCH] =?UTF-8?q?feat(decomp):=20parallel=20gate=20=E2=80=94=202?= =?UTF-8?q?=20fns=20across=202=20binaries=20(10=20workers)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ov_SC03_105 func_801803A0 ov_SC06_033 func_80190E64 --- config/overlays.mk | 2 +- config/splat.ov_SC03_105.yaml | 2 +- src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.c | 139 +++++++++++++++++- src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c | 163 +++++++++++++++++++++- 4 files changed, 302 insertions(+), 4 deletions(-) diff --git a/config/overlays.mk b/config/overlays.mk index 93c00aba8..d7011a105 100644 --- a/config/overlays.mk +++ b/config/overlays.mk @@ -2427,7 +2427,7 @@ build/src/ov_SC03_105/ov_SC03_105_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads ( build/src/ov_SC03_105/ov_SC03_105_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20 build/src/ov_SC03_105/ov_SC03_105_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20 build/src/ov_SC03_105/ov_SC03_105_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178 -build/src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20 +build/src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20,+0x34 build/src/ov_SC03_105/ov_SC03_105_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118 ov_SC03_105_CHECK_SHA := config/check.ov_SC03_105.sha ov_SC03_105_SYMBOLS := config/symbols.ov_SC03_105.txt diff --git a/config/splat.ov_SC03_105.yaml b/config/splat.ov_SC03_105.yaml index c7948628e..2508f6222 100644 --- a/config/splat.ov_SC03_105.yaml +++ b/config/splat.ov_SC03_105.yaml @@ -167,7 +167,7 @@ segments: - [0x8fe5c, .rodata, ov_SC03_105_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py) - [0x8fe70, data, tail18] - [0x8ffa8, .rodata, ov_SC03_105_jr_8017C8D0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py) - - [0x8ffdc, data, tail19] + - [0x8fff4, data, tail19] - [0x90138, .rodata, ov_SC03_105_jr_80186B24] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py) - [0x90160, .rodata, ov_SC03_105_jr_80186DDC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py) - [0x90188, data, tail20] diff --git a/src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.c b/src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.c index 36b8def6a..14b04b7f1 100644 --- a/src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.c +++ b/src/ov_SC03_105/ov_SC03_105_jr_8017C8D0.c @@ -5046,7 +5046,144 @@ void func_801802E0(s32 a0) { } -INCLUDE_ASM("asm/ov_SC03_105/nonmatchings/ov_SC03_105_jr_8017C8D0", func_801803A0); +#include "common.h" + +extern s32 D_80126B58; /* TU:7037 house spelling; base taken as (u8 *)& like TU:7059 */ +extern s32 D_801BCBBC; /* TU:5024 */ +extern u16 D_801BA59A; /* sh/lhu width; no prior TU decl */ +extern u16 D_801BA59C; /* sh/lhu width; no prior TU decl */ +extern s32 D_8018E610; /* TU:4975 */ +extern s32 func_80047948(s32 a0); /* TU:2206 */ +extern s32 func_8004787C(s32 a0); /* TU:2207 */ +extern s32 rand(void); /* TU:958 */ +extern s32 func_8012BEE8(s32 a0); /* TU:3924 */ +extern s32 func_8012CBF4(s32 a0); /* TU:3927 */ +extern void func_8012AD80(s32 a0); /* TU:4390 */ +extern s32 func_8018233C(s32 arg0); /* defined later in this TU (:5121) */ +extern void func_80183768(void *a0, s32 a1, s32 a2); /* defined later in this TU (:5669) */ +extern void func_80183D38(void *a0, s16 a1, s32 a2); /* defined later in this TU (:5930) */ +extern s32 func_80183A64(s32 *a0, s32 a1, s32 a2); /* defined later in this TU (:5775) */ +extern s32 func_8018388C(void *a0, s32 a1); /* defined later in this TU (:5714) */ +extern void func_80183DA0(s32 a0); /* defined later in this TU (:5953) */ +extern void func_801824CC(s32, s32, s32, s32, s32); /* TU:5009 spelling; K&R s16 def at :5191 */ + +void func_801803A0(s32 a0) +{ + s32 s0 = a0; + register s32 s3 __asm__("$19"); + u8 *b58; + s32 v; + u32 v1; + /* LOAD-BEARING: ONE pointer temp per switch arm. A single temp assigned in both arms has + * reg_n_sets==2, which kills sched1's birthing_insn_p launch boost (§350): its `lw 0x20` + * floats to the block top, overlaps the `li $v1,0x40` range, and the allocno lands in $a0 + * (measured 9 rows). Set once each, both loads sit after the sw and colour $v1. */ + s32 pA; + s32 pB; + s32 i; + s32 r; + /* LOAD-BEARING: dead 16-byte aggregate gives the 0x40 frame (0x30 without it); gcc-2.7.2 + * allocates an aggregate local at declaration even when unreferenced (§226/§333). */ + s32 pad[4]; + + v = func_80047948((*(s32 *)(s0 + 0xEC) << 5) & 0xFE0); + *(u16 *)(s0 + 0x50) = ((u32)(v * 3)) >> 9; + v = func_8004787C((*(s32 *)(s0 + 0xEC) << 5) & 0x7E0); + *(u16 *)(s0 + 0x52) = ((u32)(v * 3)) >> 9; + + /* LOAD-BEARING: `u8 *` base + `*(s16 *)(b58 + 6)` (the TU:7059 idiom), NOT an s16 array + * `tbl[3]`. The ARRAY_REF is a /s MEM and true_dependence's struct-vs-fixed-scalar escape + * lets the `lh 0x6($s1)` hoist above the `sh D_801BA59C` store; the cast INDIRECT_REF is + * not /s, so the load stays pinned after both global stores as in the target (§351; 4 rows). + * Keep it set ONCE — a §194-K re-tie moves the `la $s1` to the prologue top (§350). */ + b58 = (u8 *)&D_80126B58; + + switch (*(u16 *)(s0 + 0x34)) { + case 0: + v1 = *(u32 *)*(s32 *)(s0 + 0xCC); + s3 = 0x1800; + if (v1 == -2) goto lA; + if ((u32)v1 >= 0xFFFFFFFFu) goto lB; + if (v1 == -3) goto lC; + goto lD; + lA: + *(s32 *)(s0 + 0x1C) = 0x40; + pA = *(s32 *)(s0 + 0x20); + *(u16 *)(s0 + 0x34) = *(u16 *)(s0 + 0x34) + 1; + *(u16 *)(pA + 0x1A) = 0x2000; + *(u16 *)(pA + 0x18) = 0x2000; + goto lE; + lC: + *(u16 *)(s0 + 0x34) = 4; + *(s32 *)(s0 + 0x1C) = 0x3C; + for (i = 0; i < 3; i++) { + r = rand(); + func_80183D38((void *)s0, i + 1, 0xFFFC0000 - ((r % 5) << 16)); + } + goto lE; + lB: + *(s32 *)(s0 + 0xCC) = *(s32 *)((s32)&D_8018E610 + D_801BCBBC * 4); + return; + lD: + *(u16 *)(s0 + 2) = v1; + *(s32 *)(s0 + 0xCC) = *(s32 *)(s0 + 0xCC) + 4; + return; + lE: + *(s32 *)(s0 + 0xCC) = *(s32 *)(s0 + 0xCC) + 4; + break; + case 1: + s3 = 0x2000; + if (func_8012BEE8(s0) != 0) { + *(u16 *)(s0 + 0x34) = *(u16 *)(s0 + 0x34) + 1; + D_801BA59A = *(u16 *)(s0 + 0xA); + D_801BA59C = *(u16 *)(s0 + 0xE); + *(s16 *)(s0 + 0xE8) = (*(s16 *)(s0 + 6) - *(s16 *)(b58 + 6)) >> 1; + *(s32 *)(s0 + 0x1C) = 1; + *(u16 *)(s0 + 0xEA) = *(u16 *)(s0 + 0xA) + 0x102; + } + break; + case 2: + func_80183768((void *)s0, *(s16 *)(s0 + 0xE8), *(s16 *)(s0 + 0xEA)); + func_8012CBF4(s0); + v = *(s32 *)(s0 + 0x1C) + 1; + *(s32 *)(s0 + 0x1C) = v; + s3 = 0x2000; + if (v >= 0x41) { + pB = *(s32 *)(s0 + 0x20); + *(s32 *)(s0 + 0x1C) = 0x1E; + *(u16 *)(s0 + 0x34) = 0; + *(u16 *)(pB + 0x1A) = 0x1800; + *(u16 *)(pB + 0x18) = 0x1800; + *(u16 *)(s0 + 0xA) = D_801BA59A; + *(u16 *)(s0 + 0xE) = D_801BA59C; + } + break; + case 4: + s3 = 0x1800; + if (func_8012BEE8(s0) != 0) { + *(u16 *)(s0 + 0x34) = 0; + *(s32 *)(s0 + 0x1C) = 0x1E; + } + break; + case 5: + func_8012AD80(s0); + s3 = 0x1800; + if (func_8012BEE8(s0) != 0) { + *(s32 *)(s0 + 0x1C) = 0x1E; + *(u16 *)(s0 + 0x34) = 0; + *(s32 *)(s0 + 0xC) = 0xFE380000; + } + break; + } + + func_80183A64((s32 *)s0, 0x1800000, 0xFE800000); + func_8018388C((void *)s0, 0x30); + func_8018233C(s0); + func_80183DA0(s0); + func_801824CC(s0, (s16)s3, 0, -0x20, 0x800000); + *(s32 *)(s0 + 0xEC) += 1; +} + INCLUDE_ASM("asm/ov_SC03_105/nonmatchings/ov_SC03_105_jr_8017C8D0", func_801806F8); diff --git a/src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c b/src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c index 0508c46d6..ac4d2db67 100644 --- a/src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c +++ b/src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c @@ -4993,7 +4993,168 @@ void func_80190CE0(s32 a0) { } -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8018D98C", func_80190E64); +/* func_80190E64 — ov_SC06_033 — 3-state (0/1/2 on +0x34) boss-intro/spawn driver. + match_one MATCH 302/302, all 53 relocations audited against the .s (law 1c). + + Levers, in the order they mattered (each byte-proven on this function): + + 1. `first = D_801CB512;` — the 16-entry u16 rotate (house style of the already-banked + func_801916BC in this TU) must load `first` through the SYMBOL, not `*q1`: the target + has `lui/lhu %lo(D_801CB512)`, and the load must be written BEFORE `k = 0` (§3-T2). + 2. `*(u16 *)(e + 6) = *(s16 *)(e + 6) - 0x40 + (rand() & 0x7F);` — the s16 LOAD is the + dial. Read as u16 the fold+narrowing produces a u16 `0xFFC0` constant that local-alloc + parks in $s0 (a 1-block pseudo crossing one call), which then bars `e` from $s0 in BOTH + cases and cascades through the whole callee-saved file (75 residual rows). Read as s16 + the narrowed HImode arithmetic is signed, the negated constant sign-extends to -64 and + becomes `addiu $v1,$v1,-0x40` on the FIELD side, then `addu` with the rand term. + (Ablated 19 spellings; `(u16)(f - K)` cast and `+= (r) - K` both keep the 0xFFC0 reg.) + 3. ONE `p` variable for `*(s32 *)(a0 + 0xCC)` in case 0 AND case 1 — a global pseudo that + does not cross calls gets the lowest used-so-far reg not conflicting with the local + RMW temps: $a0 in both blocks (a per-block temp gets $v1). + 4. `i = rand() % 100` reuses the case-0 counter — that pseudo must cross calls to land in + $s1 (an 8-ref/12-insn temp takes $a1); it also lifts `i` above the D_801CB52C giv in + allocno order so the giv falls through to $s3 (pass 1: s0..s2 taken), and `tbl` then + shares $s3 with it in pass 0. + Free from the shape: `while (*tp <= i) tp += 3;` (duplicate_loop_exit_test + reorg's + delay-slot steal with the `addiu -6` undo), `-(cond) & 0x1E` (store_flag normalised to -1, + L9163), u16 dividend -> `multu 0xAAAAAAAB` (§201-D), state in $s0 reused for the `== 2` + compare via record_jump_equiv. */ +extern u8 D_80078E78[]; +extern u16 D_801CB512; +extern u16 D_801CB514; +extern u16 D_801CB4F4; +extern s32 D_801CB52C[]; +extern u8 D_801CB540[]; +extern u8 D_801CB4CC[]; +extern s16 D_801CB398[]; +extern u8 D_801CD99C[]; +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_800599B8(); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern void func_8001C214(s32 a0, s32 a1); +extern s32 rand(void); +extern void func_8001D0E8(s32 a0, s32 a1, s32 a2); +extern int func_80143C74(short *, int); +extern void func_80128EA8(); +extern void func_80016714(void *a0, s32 a1); +extern void func_8002A04C(s32 a0); + +void func_80190E64(s32 a0) +{ + u16 *tbl = (u16 *)D_80078E78; + s32 e; + s32 i; + s32 child; + s32 off; + s16 *tp; + s32 t; + s32 p; + s16 cnt; + u16 *q1, *q2; + u16 first, v; + s32 k; + + switch (*(u16 *)(a0 + 0x34)) { + case 0: + func_8002D4C8(0xB33, 0); + q1 = &D_801CB512; + q2 = &D_801CB512 - 1; + first = D_801CB512; + k = 0; + do { + v = *q2; + q2--; + k++; + *q1 = v; + q1--; + } while (k < 0xF); + *q1 = first; + func_800599B8(&D_801CB514, &D_801CB4F4); + p = *(s32 *)(a0 + 0xCC); + *(u16 *)(p + 0x2C) |= 0x10; + for (i = 0; i < 5; i++) { + e = func_8012C658(0x33C, 1, a0); + if (e != 0) { + func_8001C214(*(s32 *)(e + 0x20), D_801CB52C[i]); + *(u16 *)(e + 0x12) = (rand() & 0xF) - 8; + *(u16 *)(e + 0x1A) = (rand() & 0xF) - 8; + *(u16 *)(e + 0x16) = -((rand() & 7) + 7); + *(u16 *)(e + 0xFC) = (rand() & 0x3F) + 4; + *(u16 *)(e + 0xFE) = (rand() & 0x3F) + 4; + *(u16 *)(e + 0x100) = (rand() & 0x3F) + 4; + *(u16 *)(e + 0xA) -= 0x30; + } + } + func_8001C214(*(s32 *)(a0 + 0x20), (s32)D_801CD99C); + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = (s32)D_801CB4CC; + func_8001D0E8(*(s32 *)(a0 + 0x20), 0x280, 0x1E0); + *(u16 *)(a0 + 0x34) += 1; + break; + case 1: + q1 = &D_801CB512; + q2 = &D_801CB512 - 1; + first = D_801CB512; + k = 0; + do { + v = *q2; + q2--; + k++; + *q1 = v; + q1--; + } while (k < 0xF); + *q1 = first; + func_800599B8(&D_801CB514, &D_801CB4F4); + e = ((s32 (*)(s32, s32))func_80143C74)(a0, 0); + if (e != 0) { + child = *(s32 *)(e + 0xCC); + *(u16 *)(child + 0x18) = rand() % 0x2000 + 0x3000; + *(u16 *)(child + 0x1A) = rand() % 0x2000 + 0x3000; + func_80128EA8(child, e + 0xD0, (s32)D_801CB540); + *(u16 *)(e + 0x6) = *(s16 *)(e + 0x6) - 0x40 + (rand() & 0x7F); + *(u16 *)(e + 0xE) = *(s16 *)(e + 0xE) - 0x40 + (rand() & 0x7F); + *(u16 *)(e + 0xA) = *(u16 *)(e + 0xA) - (rand() & 0x7F); + } + p = *(s32 *)(a0 + 0xCC); + *(u16 *)(p + 0x18) -= 0x88; + *(u16 *)(p + 0x1A) -= 0x88; + *(u16 *)(p + 0x1C) -= 0x88; + if (*(s16 *)(p + 0x18) < 0x89) { + *(u16 *)(a0 + 0x34) += 1; + func_80016714(*(void **)(a0 + 0xCC), 0x84); + *(s32 *)(a0 + 0xCC) = 0; + if (*(s16 *)(a0 + 0x70) == 1) { + off = -((u16)(tbl[0x1D] / 3) >= tbl[0x1E]) & 0x1E; + if ((u16)(tbl[0x1F] / 3) >= tbl[0x20]) { + off += 0x3C; + } + tp = &D_801CB398[off]; + i = rand() % 100; + while (*tp <= i) { + tp += 3; + } + t = func_8012C658(tp[1], tp[2], a0); + if (t != 0) { + *(u16 *)(t + 0xA) -= 0x40; + } + } + } + break; + case 2: + *(u16 *)(a0 + 0xFC) = cnt = *(u16 *)(a0 + 0xFC) + 1; + if (cnt >= 0x20) { + func_80016714(*(void **)(a0 + 0xD0), 0x84); + *(s32 *)(a0 + 0xD0) = 0; + *(u16 *)(a0 + 0x34) += 1; + if (*(s16 *)(a0 + 0x70) == 2) { + *(u16 *)(a0 + 0x34) = 0; + *(u16 *)(a0 + 2) = 4; + } + func_8002A04C(a0); + } + break; + } +} + extern void func_8012BE54(s32); extern s32 func_8012B8A4(s32);