From c7af030709e0fe4fddb2bd7d528793876d4a22f6 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Sat, 18 Jul 2026 11:45:36 -0600 Subject: [PATCH] =?UTF-8?q?feat(phase-29=20fable):=20bank=20func=5F8013D53?= =?UTF-8?q?C=20(240)=20x1=20=E2=80=94=20the=20cse.c=20address-CSE=20wall?= =?UTF-8?q?=20crack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fable cracked the cross-statement address-CSE via a neighboring-symbol offset (*(S9*)(&D_801DA998+0x20) never unifies with SYMBOL_REF while gas folds %hi/%lo(sym+k) byte-identical) + dead-pad frame + block-local coalesce + 2 density anchors. Reconcile: void* def-sig (byte-neutral — caller func_8013D3D4 keeps param_1 in $a0) + dropped decls colliding with banked 8013CB84's Rec12/Rec9 (uses cast at site). --- src/ov_SC01_077/ov_SC01_077.c | 144 +++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 3 deletions(-) diff --git a/src/ov_SC01_077/ov_SC01_077.c b/src/ov_SC01_077/ov_SC01_077.c index 5a3f61045..dc226079f 100644 --- a/src/ov_SC01_077/ov_SC01_077.c +++ b/src/ov_SC01_077/ov_SC01_077.c @@ -445,7 +445,7 @@ extern u8 D_801873B0[]; extern u8 D_80187430[]; extern u8 D_80187308[]; -extern void func_8013D53C(void); +extern void func_8013D53C(void *); extern void func_8013DD68(void); extern void func_8013D8FC(void); extern void func_8013CF68(void); @@ -466,7 +466,7 @@ void func_8013D3D4(int param_1, int param_2) D_801D9574 = D_80187430; D_801D9578 = D_80187308; } - func_8013D53C(); + func_8013D53C((void *)param_1); if ((param_2 & 1) != 0) { if (D_801D95A8 != 0) { func_8013DD68(); @@ -489,7 +489,145 @@ void func_8013D3D4(int param_1, int param_2) } } -INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077", func_8013D53C); +#include "common.h" + +typedef struct { u8 b[9]; } S9; /* 9-byte, align-1 -> unaligned block copy */ + +typedef struct { + u16 cmd; /* 0x0 */ + u16 pad2; /* 0x2 */ + u16 pad4; /* 0x4 */ + u16 pad6; /* 0x6 */ + s16 w; /* 0x8 */ + s16 h; /* 0xA */ + u16 *data; /* 0xC */ +} Cmd; /* 0x10 */ + +extern s32 D_801D95A0; +extern u8 D_80078EAF; +extern s32 D_801D9588; + + +extern u8 D_801DAABA; +extern u8 D_801DAB2E; +extern u8 D_801DA9C2; +extern u8 D_801DAA9C; +extern u8 D_801DA998; +extern u8 D_801DA9C1; + +extern u8 D_801DAA78; + +extern s32 D_801DAAA0; +extern s32 D_801D959C; +extern s32 D_801D9598; +extern s32 D_801D9594; +extern s32 D_801D9580; +extern s32 D_801D958C; +extern s32 D_801D9590; + +extern void *D_801D9570; +extern s32 D_801D95A8; +extern void *D_801D9578; + +void func_8013D53C(void *arg0v) { + Cmd *arg0 = arg0v; + + extern u8 D_80187488[]; + extern u8 D_8018748C[]; + extern unsigned char D_801DA9B8; + extern s16 *D_801D957C; + extern s32 D_801D95AC; + extern s32 D_801D95B0; + extern s32 D_801D95B4; + s32 s0v; + s32 t9v; + s32 t8v; + u8 b0, b1, b2; + u8 pad[8]; /* dead BLKmode local: frame 0x10 -> 0x18, zero code */ + + if (!(D_801D95A0 & 1)) { + D_801D9588 = 1; + } else { + D_801D9588 = D_80078EAF; + } + + b0 = ((u8 *)D_80187484)[D_801D9588 * 12]; + D_801DAABA = b0; + D_801DAB2E = b0; + b1 = D_80187488[D_801D9588 * 12]; + D_801DA9C2 = b1; + D_801DAA9C = b1; + b2 = D_8018748C[D_801D9588 * 12]; + D_801DA998 = b2; + D_801DA9C1 = b2; + + (*(S9 *)&D_801DA9B8) = ((S9 *)D_8018744C)[D_801D9588]; + (*(S9 *)&D_801DAA78) = *(S9 *)(&D_801DA998 + 0x20); /* same addr as (*(S9 *)&D_801DA9B8); distinct sym defeats cse, keeps %hi/%lo */ + + D_801DAAA0 = 1; + D_801D959C = -1; + D_801D9598 = 0; + D_801D9594 = -1; + D_801D9580 = 0; + D_801D958C = 0; + D_801D9590 = 0; + + if ((D_801D95A0 & 2) && (D_801D9588 == 4)) { + s0v = (*(s32 * *)&D_801D9570)[18]; + t9v = (*(s32 * *)&D_801D9570)[19]; + t8v = (*(s32 * *)&D_801D9570)[20]; + } else { + s32 *p = (s32 *)(D_801D9588 * 12 + (s32) (*(s32 * *)&D_801D9570)); /* block-local: local-alloc ties sum into mul chain */ + s0v = p[0]; + t9v = p[1]; + t8v = p[2]; + } + + (*(Cmd * *)&D_801D957C) = arg0; + if (arg0 != 0) { + if (D_801D95A8 != 0) { + s32 *p = (s32 *)(D_801D9588 * 12 + (s32) (*(s32 * *)&D_801D9578)); + D_801D95AC = p[0]; + D_801D95B0 = p[1]; + D_801D95B4 = p[2]; + } else { + while ((arg0->cmd & 0xFFFF) != 0xFF) { + if ((arg0->cmd & 0xFFFF) == 9) { + s32 n; + s32 i; + u16 *src; + u16 *dst; + n = arg0->w * arg0->h; + i = 0; + src = arg0->data; + __asm__("" :: "r"(src)); /* +2 refs on src (depth-2): keeps src above i, below the mfhi temp */ + dst = src + n; + if (n > 0) { + do { + u16 px; + s32 r, g, b, out; + __asm__("" :: "r"(i)); /* +3 refs on i (depth-3): lifts i over dst in the $t2 race */ + px = *src; + r = ((px & 0x1F) * s0v) / 2560; + g = (((px & 0x3E0) * t9v) / 2560) & 0x3E0; + b = (((px & 0x7C00) * t8v) / 2560) & 0x7C00; + out = r | g | b | (px & 0x8000); + if (out == 0 && px != 0) { + out = 0x8000; + } + *dst = out; + dst++; + i++; + src++; + } while (i < n); + } + } + arg0++; + } + } + } +} + // @class: schedule // @stuck: none — MATCH (45 ins, match_one verified)