diff --git a/src/ov_SC01_077/ov_SC01_077_jr_80183CF4.c b/src/ov_SC01_077/ov_SC01_077_jr_80183CF4.c index 8d8a1fbc39..ae60b035c0 100644 --- a/src/ov_SC01_077/ov_SC01_077_jr_80183CF4.c +++ b/src/ov_SC01_077/ov_SC01_077_jr_80183CF4.c @@ -4414,7 +4414,79 @@ void func_80185BA4(void* p) } -INCLUDE_ASM("asm/ov_SC01_077/nonmatchings/ov_SC01_077_jr_80183CF4", func_80185E68); +extern void func_80019064(void *a0); +extern s32 func_8016B428(s32 a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8012A828(s32 a0, void *a1); +extern void func_8012B21C(void *a0); +extern s32 rand(void); + +typedef struct { u8 b[12]; } Blk12_80185E68; + + +void func_80185E68(s32 arg0) { + + extern u8 D_80062BDC; + extern s32 D_801D55AC[]; + extern u8 D_801D5588[]; + extern Blk12_80185E68 D_801DA910[]; + extern u8 D_801D5578; + extern u8 D_801D6F8C[]; + extern s16 D_801DA98A[]; + extern s16 D_801DA98E[]; + extern s16 D_801DA992[]; + s32 idx; + s32 i; + s32 v; + + *(s16 *)(arg0 + 2) = 2; + *(s16 *)(arg0 + 0x34) = 0; + *(s32 *)(arg0 + 0x1C) = 0x15; + *(u16 *)(arg0 + 0x5C) = *(u16 *)(arg0 + 0x5C) & 0xFFFE; + if (*(u8 *)(arg0 + 0x5E) == 5) { + func_80019064(&D_80062BDC); + } + if ((*(u16 *)(arg0 + 0x82) & 1) != 0) { + func_8016B428(arg0); + func_80019064(D_80062C04); + } + if (--*(s16 *)(arg0 + 0x76) == 0) { + *(u16 *)(arg0 + 0x5C) = *(u16 *)(arg0 + 0x5C) & 0x7FFF; + func_8002D4C8(0x4A8, 0); + } else { + func_8002D4C8(0x4A9, 0); + } + + idx = *(s16 *)(arg0 + 0xFC) = D_801D5588[*(s16 *)(arg0 + 0x76)]; + + for (i = 0; i < 10; i++) { + D_801DA910[i] = ((Blk12_80185E68 *)(*(s32 *)D_801D55AC[*(s16 *)(arg0 + 0x76)]))[i]; + } + + func_8012A828(arg0, &D_801D5578); + + { + u8 *p = &D_801D6F8C[idx * 12]; + *(u16 *)D_801DA98A = *(u16 *)p; + *(u16 *)D_801DA98E = *(u16 *)(p + 2); + *(u16 *)D_801DA992 = *(u16 *)(p + 4); + } + + func_8012B21C((void *)arg0); + *(s32 *)(arg0 + 0x48) = 0x18000; + v = rand() << 4; + if ((rand() & 1) == 0) { + v = -v; + } + *(s32 *)(arg0 + 0x10) = v; + v = rand() << 4; + if ((rand() & 1) == 0) { + v = -v; + } + *(s32 *)(arg0 + 0x18) = v; + *(s32 *)(arg0 + 0x14) = -0xC0000; +} + extern void func_8012A828(s32 a0, void * a1); extern s32 func_8012BEE8(s32 a0); diff --git a/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c b/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c index 06f131da01..b74a95e1eb 100644 --- a/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c +++ b/src/ov_SC01_080/ov_SC01_080_jr_8017AE2C.c @@ -4021,7 +4021,100 @@ void func_8017D468(void* p) } -INCLUDE_ASM("asm/ov_SC01_080/nonmatchings/ov_SC01_080_jr_8017AE2C", func_8017D72C); +#include "common.h" + +extern void func_80019064(void *a0); +extern s32 func_8016B428(s32 a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8012A828(s32 a0, void *a1); +extern void func_8012B21C(void *a0); +extern s32 rand(void); + + +/* §160a: the lwl/lwr + swl/swr 12-byte block move is an ALIGN-1 struct + * assignment. A u32/u16 copy loop gives aligned lw/sw and is wrong. */ +typedef struct { char c[12]; } Blk12_801C5A30; + +void func_8017D72C(s32 arg0) { + + extern u8 D_80062BDC; + extern u8 D_80186F7C; + extern u8 D_80186F8C[]; /* indexed u8 table -> lui $at / addu $at / lbu %lo (§250) */ + extern s32 D_80186FB0[]; + extern u16 D_80188990[]; /* stride-12 record table; read through a materialised base */ + extern s16 D_801C5AAA[]; + extern s16 D_801C5AAE[]; + extern s16 D_801C5AB2[]; + extern Blk12_801C5A30 D_801C5A30[]; + s32 i; + s32 n; + /* The lbu result must stay in a CALLER-saved reg while `n` lives across + * func_8012A828, so the target's `addu $s0,$v0,$zero` copy survives. + * Without the pin gcc coalesces the two pseudos (`lbu $s0` / `sh $s0`) + * and the copy disappears -- one instruction short. */ + register s32 t __asm__("$2"); + s32 v; + u16 t5c; + s32 t5e; + u16 *p; + + /* Head block is pure schedule. Three things are load-bearing: + * - the 0x34 store FIRST (lowest LUID): it is the sched tie-break that + * keeps it out of the bne delay slot, which is a `nop` in the target; + * - the 0x5C read/write SPLIT across a temp (an in-place `&= 0xFFFE` + * keeps lhu/andi/sh adjacent and the whole block re-orders); + * - t5e as s32, not u8 (a u8 temp adds a redundant `andi $v1,0xff`). */ + *(s16 *)(arg0 + 0x34) = 0; + *(s16 *)(arg0 + 2) = 2; + t5c = *(u16 *)(arg0 + 0x5C); + *(s32 *)(arg0 + 0x1C) = 0x15; + t5e = *(u8 *)(arg0 + 0x5E); + *(u16 *)(arg0 + 0x5C) = t5c & 0xFFFE; + if (t5e == 5) { + func_80019064(&D_80062BDC); + } + if ((*(u16 *)(arg0 + 0x82) & 1) != 0) { + func_8016B428(arg0); + func_80019064(D_80062C04); + } + /* SIGNED field: `--*(s16*)` gives the target's `sll $v0,$v0,16` + bnez + * (combine drops the sra for an ==0 test). A u16 field gives + * `andi $v0,0xffff` instead -- the load itself is lhu either way. */ + if (--*(s16 *)(arg0 + 0x76) == 0) { + *(u16 *)(arg0 + 0x5C) &= 0x7FFF; + func_8002D4C8(0x4A8, 0); + } else { + func_8002D4C8(0x4A9, 0); + } + t = D_80186F8C[*(s16 *)(arg0 + 0x76)]; + n = t; + *(s16 *)(arg0 + 0xFC) = t; + for (i = 0; i < 10; i++) { + D_801C5A30[i] = *(Blk12_801C5A30 *)(i * 12 + *(s32 *)D_80186FB0[*(s16 *)(arg0 + 0x76)]); + } + func_8012A828(arg0, &D_80186F7C); + /* §250: the POINTER form materialises one lui/addiu/addu base. Writing + * D_80188990[n*6 + k] directly folds %lo into each access -- 3 extra + * instructions AND 16 bytes of phantom stack frame (0x30 vs 0x20). */ + p = &D_80188990[n * 6]; + D_801C5AAA[0] = p[0]; + D_801C5AAE[0] = p[1]; + D_801C5AB2[0] = p[2]; + func_8012B21C((void *)arg0); + *(s32 *)(arg0 + 0x48) = 0x18000; + v = rand() << 4; + if ((rand() & 1) == 0) { + v = -v; + } + *(s32 *)(arg0 + 0x10) = v; + v = rand() << 4; + if ((rand() & 1) == 0) { + v = -v; + } + *(s32 *)(arg0 + 0x18) = v; + *(s32 *)(arg0 + 0x14) = -0xC0000; +} + #include "common.h" diff --git a/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c b/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c index 24ed41046d..0b38ebae7a 100644 --- a/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c +++ b/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c @@ -4864,7 +4864,17 @@ extern void func_8012A828(s32 *a0, s32 a1); } -INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_8017AE2C", func_8017E7CC); +void func_8017E7CC(int param_1) +{ + extern short D_801B9AA8; + extern void func_8012A828(s32 *a0, s32 a1); + + *(short *)(param_1 + 2) = 3; + *(short *)(param_1 + 0x34) = 0; + func_8012A828((s32 *)param_1, (s32)&D_801B9AA8); + *(int *)(param_1 + 0x1c) = 0x10; +} + extern void (*D_801912C8[])(void); diff --git a/src/ov_SC05_011/ov_SC05_011_jr_8017BEBC.c b/src/ov_SC05_011/ov_SC05_011_jr_8017BEBC.c index 84ee8048bd..195dff7609 100644 --- a/src/ov_SC05_011/ov_SC05_011_jr_8017BEBC.c +++ b/src/ov_SC05_011/ov_SC05_011_jr_8017BEBC.c @@ -3544,7 +3544,19 @@ void func_8017D7DC(void *a0) { } -INCLUDE_ASM("asm/ov_SC05_011/nonmatchings/ov_SC05_011_jr_8017BEBC", func_8017D818); +extern s32 func_80012ABC(s32 a0, s32 a1, s32 a2); +extern s32 func_8012A828(void *a0, void *a1); + +void func_8017D818(void *arg0) { + if (*(s16 *)((char *)arg0 + 0x10A) & 0x8000) { + *(s16 *)(*(s32 *)((char *)arg0 + 0x20) + 0x12) = func_80012ABC((s32)*(s16 *)(*(s32 *)((char *)arg0 + 0x20) + 0x12), *(s16 *)((char *)arg0 + 0x10A) & 0xFFF, 4); + } + if (*(void **)((char *)arg0 + 0xF8) != 0 && *(void **)((char *)arg0 + 0x90) != *(void **)((char *)arg0 + 0xF8)) { + func_8012A828(arg0, *(void **)((char *)arg0 + 0xF8)); + *(void **)((char *)arg0 + 0xF8) = 0; + } +} + void func_8017D8A0(void *a0) { *(short *)(*(int *)((char *)a0 + 0xcc) + 0x10a) = -0x7800; diff --git a/src/ov_SC07_000/ov_SC07_000_jr_8017BEBC.c b/src/ov_SC07_000/ov_SC07_000_jr_8017BEBC.c index 9592affe6d..7c023421bf 100644 --- a/src/ov_SC07_000/ov_SC07_000_jr_8017BEBC.c +++ b/src/ov_SC07_000/ov_SC07_000_jr_8017BEBC.c @@ -4484,7 +4484,15 @@ void func_8017F044(s32 a0) { } -INCLUDE_ASM("asm/ov_SC07_000/nonmatchings/ov_SC07_000_jr_8017BEBC", func_8017F098); +extern void func_8017F4F8(s32 a0); +extern void func_8012AD44(s32 *a0, s16 a1); + +void func_8017F098(s32 a0) { + s32 s0 = a0; + func_8017F4F8(0); + func_8012AD44((s32 *)s0, 5); +} + extern void func_8012A828(s32 a0, void *a1); extern s32 func_80132EF4(s32 a0, s32 a1);