From 0ab474ed5dd281ccd7eb98963c0de68614d4ef31 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Sun, 6 Sep 2026 13:21:29 -0600 Subject: [PATCH] =?UTF-8?q?docs(phase-32):=20T4b=20hand=20pass=20=E2=80=94?= =?UTF-8?q?=20row=20(d)=20harvest:=20cookbook=20=C2=A7501-P=20(the=20atlas?= =?UTF-8?q?'s=200.55=20"weak=20cousin"=20was=20the=20same-shape=20sibling;?= =?UTF-8?q?=20its=20natural=20spelling=20ported=20with=20ZERO=20pins/fence?= =?UTF-8?q?s;=20the=2012-variant=20element=20census),=20accelerators=20(14?= =?UTF-8?q?),=20decision-log=20P32=20S85,=20NOTES=20+=2012=20measured=20va?= =?UTF-8?q?riants=20+=20rtu=20logs;=20backlog=203=20open;=20census=202=20s?= =?UTF-8?q?tubs=20/=20940=20ins;=20T4b=20hand=20pass=20COMPLETE=20(13/15?= =?UTF-8?q?=20banked=20+=202=20verdicts)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ov_SC03_105:func_80185810 banked in commit:4004 (bank.sh: rtu MATCH 489/489, build rc 0, sha d305ff6d… == config) - §501-P: shape-grep the idiom's constants (`'0x200) << 2'`) and objdump the sibling's window before any dial; a pin/fence a draft "needs" is a property of its other dials — remove every pin after a sibling port (d9 = no pins = MATCH); census: F2 polarity 42, 2-set uu 63, ot16 pin load-bearing only next to 2-set neighbours (d3 = 4); the S83 "hard reg hides nonzero_bits" guess refuted (d5) - post-bank: twin_rescan 2 open / 0 free; verbatim_check --strict 5==5; backlog.py render 3 open; frontier_t4b_final.json 2 / 940 - .gitignore allowlist for .run/P32/t4d/ (variants, logs, notes, the banked body; rtu/ compile dirs stay ignored) - fleet R22 running in the background (.run/P32/t4d/r22_*.log) — recorded at the T4b close --- .gitignore | 9 + .run/P32/frontier_t4b_final.json | 44 +++ .run/P32/t3s3/bank_ov_SC03_105_131217.log | 49 +++ .run/P32/t4d/NOTES.md | 48 +++ .run/P32/t4d/bank/func_80185810.c | 356 ++++++++++++++++++++++ .run/P32/t4d/check_all_preflight.log | 220 +++++++++++++ .run/P32/t4d/cookbook_index.log | 1 + .run/P32/t4d/d10_ot16only.c | 339 ++++++++++++++++++++ .run/P32/t4d/d11_f2polarity.c | 339 ++++++++++++++++++++ .run/P32/t4d/d12_twoset_uu.c | 340 +++++++++++++++++++++ .run/P32/t4d/d1_sibport.c | 339 ++++++++++++++++++++ .run/P32/t4d/d2_nomode.c | 339 ++++++++++++++++++++ .run/P32/t4d/d3_noot16.c | 339 ++++++++++++++++++++ .run/P32/t4d/d4_nomode_noot16.c | 339 ++++++++++++++++++++ .run/P32/t4d/d5_nocl.c | 339 ++++++++++++++++++++ .run/P32/t4d/d6_min3.c | 339 ++++++++++++++++++++ .run/P32/t4d/d7_noc40.c | 339 ++++++++++++++++++++ .run/P32/t4d/d8_nouu.c | 339 ++++++++++++++++++++ .run/P32/t4d/d9_nopins.c | 339 ++++++++++++++++++++ .run/P32/t4d/r22_check.log | 111 +++++++ .run/P32/t4d/r22_clean.log | 2 + .run/P32/t4d/r22_extract.log | 254 +++++++++++++++ .run/P32/t4d/rtu_d10_ot16only.log | 1 + .run/P32/t4d/rtu_d11_f2polarity.log | 44 +++ .run/P32/t4d/rtu_d12_twoset_uu.log | 62 ++++ .run/P32/t4d/rtu_d2_nomode.log | 1 + .run/P32/t4d/rtu_d3_noot16.log | 6 + .run/P32/t4d/rtu_d4_nomode_noot16.log | 6 + .run/P32/t4d/rtu_d5_nocl.log | 1 + .run/P32/t4d/rtu_d6_min3.log | 1 + .run/P32/t4d/rtu_d7_noc40.log | 1 + .run/P32/t4d/rtu_d8_nouu.log | 1 + .run/P32/t4d/rtu_d9_nopins.log | 1 + docs/accelerators.md | 11 + docs/backlog.md | 5 +- docs/decision-log.md | 27 ++ docs/matching-cookbook.md | 30 ++ phase-ends/CURRENT_PHASE.md | 3 +- 38 files changed, 5360 insertions(+), 4 deletions(-) create mode 100644 .run/P32/frontier_t4b_final.json create mode 100644 .run/P32/t3s3/bank_ov_SC03_105_131217.log create mode 100644 .run/P32/t4d/NOTES.md create mode 100644 .run/P32/t4d/bank/func_80185810.c create mode 100644 .run/P32/t4d/check_all_preflight.log create mode 100644 .run/P32/t4d/cookbook_index.log create mode 100644 .run/P32/t4d/d10_ot16only.c create mode 100644 .run/P32/t4d/d11_f2polarity.c create mode 100644 .run/P32/t4d/d12_twoset_uu.c create mode 100644 .run/P32/t4d/d1_sibport.c create mode 100644 .run/P32/t4d/d2_nomode.c create mode 100644 .run/P32/t4d/d3_noot16.c create mode 100644 .run/P32/t4d/d4_nomode_noot16.c create mode 100644 .run/P32/t4d/d5_nocl.c create mode 100644 .run/P32/t4d/d6_min3.c create mode 100644 .run/P32/t4d/d7_noc40.c create mode 100644 .run/P32/t4d/d8_nouu.c create mode 100644 .run/P32/t4d/d9_nopins.c create mode 100644 .run/P32/t4d/r22_check.log create mode 100644 .run/P32/t4d/r22_clean.log create mode 100644 .run/P32/t4d/r22_extract.log create mode 100644 .run/P32/t4d/rtu_d10_ot16only.log create mode 100644 .run/P32/t4d/rtu_d11_f2polarity.log create mode 100644 .run/P32/t4d/rtu_d12_twoset_uu.log create mode 100644 .run/P32/t4d/rtu_d2_nomode.log create mode 100644 .run/P32/t4d/rtu_d3_noot16.log create mode 100644 .run/P32/t4d/rtu_d4_nomode_noot16.log create mode 100644 .run/P32/t4d/rtu_d5_nocl.log create mode 100644 .run/P32/t4d/rtu_d6_min3.log create mode 100644 .run/P32/t4d/rtu_d7_noc40.log create mode 100644 .run/P32/t4d/rtu_d8_nouu.log create mode 100644 .run/P32/t4d/rtu_d9_nopins.log diff --git a/.gitignore b/.gitignore index 24301ce07..ae0299534 100644 --- a/.gitignore +++ b/.gitignore @@ -322,3 +322,12 @@ unsloth_compiled_cache/ /.run/P32/t4c/func_*/* !/.run/P32/t4c/func_*/*.c !/.run/P32/t4c/func_*/*.md +# P32 T4b hand pass row (d) (S85, 2026-09-06): the sibling-port variants, their rtu verdict logs, the notes and the banked body (not the rtu/ compile dirs) +!/.run/P32/t4d/ +/.run/P32/t4d/* +!/.run/P32/t4d/*.c +!/.run/P32/t4d/*.md +!/.run/P32/t4d/*.log +!/.run/P32/t4d/bank/ +/.run/P32/t4d/bank/* +!/.run/P32/t4d/bank/*.c diff --git a/.run/P32/frontier_t4b_final.json b/.run/P32/frontier_t4b_final.json new file mode 100644 index 000000000..1370d7a59 --- /dev/null +++ b/.run/P32/frontier_t4b_final.json @@ -0,0 +1,44 @@ +[ + { + "fn": "func_80039308", + "binary": "main", + "nins": 518, + "klass": "D-NEAR", + "closeness": 4, + "closeness_last": 4, + "attempts": 2, + "warmstart_regression": false, + "journal_closeness": 402, + "jtbl": false, + "jr": false, + "jalr": false, + "o0": false, + "calls": 0, + "twins": 0, + "proven_twin": [], + "drafts": 10, + "verdict": "T4b HAND PASS S84 (2026-09-06): PLATEAU at 4. Rows 412/415: Fable Y4 (direct *(s16*)(p+6)=", + "path": "src/800_c.c" + }, + { + "fn": "func_80032A74", + "binary": "main", + "nins": 422, + "klass": "D-NEAR", + "closeness": 1, + "closeness_last": 1, + "attempts": 2, + "warmstart_regression": false, + "journal_closeness": 70, + "jtbl": false, + "jr": false, + "jalr": false, + "o0": false, + "calls": 6, + "twins": 0, + "proven_twin": [], + "drafts": 10, + "verdict": "T4b HAND PASS S84 (2026-09-06, Fable Max): PROVED at 1 by producer census. Residual = ONE ", + "path": "src/800_b_2.c" + } +] \ No newline at end of file diff --git a/.run/P32/t3s3/bank_ov_SC03_105_131217.log b/.run/P32/t3s3/bank_ov_SC03_105_131217.log new file mode 100644 index 000000000..beceefb14 --- /dev/null +++ b/.run/P32/t3s3/bank_ov_SC03_105_131217.log @@ -0,0 +1,49 @@ + CC build/src/ov_SC03_105/ov_SC03_105_jr_80181C84.o +In file included from src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:2: +src/ov_SC03_105/../shared/engine_core.h:161199: warning: "DEFINE_func_8013FFD8" redefined +161199 | #define DEFINE_func_8013FFD8() \ + | +src/ov_SC03_105/../shared/engine_core.h:32633: note: this is the location of the previous definition +32633 | #define DEFINE_func_8013FFD8() \ + | +src/ov_SC03_105/../shared/engine_core.h:169456: warning: "DEFINE_func_8013F350" redefined +169456 | #define DEFINE_func_8013F350() \ + | +src/ov_SC03_105/../shared/engine_core.h:40890: note: this is the location of the previous definition +40890 | #define DEFINE_func_8013F350() \ + | +src/ov_SC03_105/../shared/engine_core.h:185848: warning: "DEFINE_func_80181538" redefined +185848 | #define DEFINE_func_80181538() \ + | +src/ov_SC03_105/../shared/engine_core.h:57282: note: this is the location of the previous definition +57282 | #define DEFINE_func_80181538() \ + | +src/ov_SC03_105/../shared/engine_core.h:190943: warning: "DEFINE_func_801808C4" redefined +190943 | #define DEFINE_func_801808C4() \ + | +src/ov_SC03_105/../shared/engine_core.h:62377: note: this is the location of the previous definition +62377 | #define DEFINE_func_801808C4() \ + | +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:1558: warning: conflicting types for built-in function `memcpy' +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3827: warning: type mismatch with previous external decl +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3804: warning: previous external decl of `func_8018383C' +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3827: warning: type mismatch with previous implicit declaration +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3820: warning: previous implicit declaration of `func_8018383C' +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3827: warning: `func_8018383C' was previously implicitly declared to return `int' +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c: In function `func_8018388C': +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3871: warning: passing arg 3 of `func_8013361C' from incompatible pointer type +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3871: warning: passing arg 4 of `func_8013361C' from incompatible pointer type +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3878: warning: passing arg 5 of `func_8012F568' makes integer from pointer without a cast +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3878: warning: passing arg 6 of `func_8012F568' makes integer from pointer without a cast +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c: In function `func_80184500': +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:4472: warning: passing arg 1 of `func_800599B8' from incompatible pointer type +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c: At top level: +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:4607: warning: type mismatch with previous external decl +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:3339: warning: previous external decl of `D_801BA5A8' +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c: In function `func_80185480': +src/ov_SC03_105/ov_SC03_105_jr_80181C84.c:5196: warning: passing arg 2 makes pointer from integer without a cast + LD build/ov_SC03_105/ov_SC03_105.elf + OBJCOPY build/ov_SC03_105/ov_SC03_105 + TRIM build/ov_SC03_105/ov_SC03_105 (-1 B linker end-align pad) +[ OK ] build/ov_SC03_105/ov_SC03_105 + sha1 d305ff6da199b52d0d44023766643a8b661ed524 == config/check.ov_SC03_105.sha (BYTE-IDENTICAL) diff --git a/.run/P32/t4d/NOTES.md b/.run/P32/t4d/NOTES.md new file mode 100644 index 000000000..2b6451ccd --- /dev/null +++ b/.run/P32/t4d/NOTES.md @@ -0,0 +1,48 @@ +# func_80185810 (ov_SC03_105, 489 ins) — T4b hand pass row (d), S85 (2026-09-06, session 3a7e207c, Max, Fable 5.1, no agents) + +**Outcome: BANKED byte-identical `commit:4004`** (bank.sh: rtu MATCH 489/489 in the real TU → splice → `make build +BINARY=ov_SC03_105 -j8` rc 0 → sha `d305ff6da199b52d0d44023766643a8b661ed524` == `config/check.ov_SC03_105.sha`). +ov_SC03_105 is now 100% C. Zero pins, zero fences, zero asm dials — the cousin's natural spelling. + +## Step 0 — the §501-N sibling search (the whole crack) +- Twin oracle: `twins 0`, atlas knn: no entry for the function itself; the only reverse hit is `ov_SC02_027:80180b3c` at + 0.5501 (a "weak" cousin by the atlas's measure). +- Symbol grep (`D_801BC9B4` + `D_800A5E60`): only this overlay's own TUs (the matrix symbol is overlay-local bss). +- Shape grep (`0x200) << 2` = the getTPage bit chain): 20+ files; **`src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810 + func_80180B3C` is the same billboard-sprite drawer** (POLY_FT4 off the D_800A5E60 bump, `code = 0x2C; code |= 2`, + `tpage = getTPage-chain`, `code |= (w & 0x40) >> 6`, u/v from the sprite record, the v0 conditional, the P_TAG link). +- Its compiled window (`objdump -d build/src/ov_SC02_027/ov_SC02_027_jr_8017D898.o`, 0x34f8–0x3560) is + INSTRUCTION-FOR-INSTRUCTION this target's rows 362–386 (only the base registers differ: t0/t1/t2 vs s0/s2/s1). +- Time from the first grep to the MATCH: ~25 minutes, one draft. + +## The port (d1) and the pin/element census (all real-TU `rtu_match`, `--split ov_SC03_105_jr_80181C84 --source ov_SC03_105`) +| variant | change vs d1 | result | +|---|---|---| +| base (Fable v7) | — | DIFF 13 (rows 363–380), reproduced first | +| d1_sibport | cousin window ported; pins uu $4, cl $7, c40 $2 (cousin's) + mode $5, ot16 $6 (draft's) | **MATCH** | +| d2_nomode | − mode pin | MATCH | +| d3_noot16 | − ot16 pin | DIFF 4 (rows 343–346: the ot16 load sinks below the u/v loads) | +| d4 | − mode − ot16 | DIFF 4 (same rows) | +| d5_nocl | − cl pin | MATCH — the `$7` pin is NOT what keeps the andi alive | +| d6_min3 | − mode − cl | MATCH | +| d7 | d6 − c40 pin | MATCH | +| d8 | d6 − uu pin | MATCH | +| **d9_nopins** | **no pins at all** | **MATCH — banked** | +| d10 | ot16 pin only | MATCH | +| d11_f2polarity | d9 with `if (c) vv = vm - 0x100; else vv = vm;` | DIFF 42 (the packet block re-rolls from row 331) | +| d12_twoset_uu | d9 with `uu -= …; uu <<= shift;` instead of a fresh `u` | DIFF 63 (allocations move from row 218: t1↔t0, t2↔t1) | + +Reading of the census: with the cousin's spelling every load in the window is a single-set birth (ot16, uu, cl, vm, u, +shift) so sched1's birthing boost ties them all and the LUID tie-break gives source order (the ot16 pin was only needed +while uu/cl were 2-set and unboosted). d3 shows the pin is load-bearing ONLY in the mixed form. The `andi $a3,$a3,0xFFFF` +survives as a lone insn (`vm = cl & 0xFFFF`, single set, consumers in the two arms — a lone insn is never simplified by +combine, and the lhu that sets `cl` has intermediate uses); the S83 report's "combine folds a fresh clx via nonzero_bits" +(F2 → 59) was the OTHER polarity + the 2-set `uu`, which d11/d12 reproduce as 42/63 — the andi was never the problem once +the block's births are all single-set. The branch polarity `if (!(tpage & 0x10)) vv = vm; else vv = vm - 0x100;` is +load-bearing (42 rows): the copy arm is the fall-through that coalesces away, leaving the target's +`beqz → skip; addiu $a3,-0x100` shape. + +## Files +- `d1_sibport.c` … `d12_twoset_uu.c`, `rtu_*.log` (one per variant), `rtu//` work dirs (ignored), + `bank/func_80185810.c` (= d9 + the accurate header; the banked body), `check_all_preflight.log` (218/218 before the bank), + `r22_{clean,extract,check}.log` (the fleet R22 after the bank). diff --git a/.run/P32/t4d/bank/func_80185810.c b/.run/P32/t4d/bank/func_80185810.c new file mode 100644 index 000000000..e193c340a --- /dev/null +++ b/.run/P32/t4d/bank/func_80185810.c @@ -0,0 +1,356 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * COMPILER-EMITTED gcc-2.7.2 -O2 C using PsyQ GTE inline-asm macros (splat's + * "Handwritten function" banner is wrong). Billboard-sprite drawer: builds the + * rot/trans matrix (3 paths), RTPS the actor position, rejects it outside + * +-200/+-160, RTPT the two extent vectors through D_801BC9B4, fills a 0x28-byte + * POLY_FT4 packet off the D_800A5E60 bump allocator and addPrim()s it into the OT + * at &D_800A6610[D_800B9A02 << 14] (read base-relative: D_800AF630 + 0xA3D2). + * + * BANKED byte-identical, P32 T4b hand pass (S85, 2026-09-06), cookbook §501-P: + * the S83 Fable draft (DIFF 13 at exact length, five register pins + a zero-byte + * fence) was replaced by the SPELLING of the banked same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c), whose + * compiled packet window is instruction-for-instruction this target's rows + * 362-386. Zero pins, zero fences, zero asm dials. Load-bearing elements of the + * ported window, each measured in the real TU (.run/P32/t4d/): + * - the v coordinate is masked into a FRESH single-set copy (`vm = cl & 0xFFFF`) + * whose consumers live in the two arms of the v0 conditional: the andi survives + * combine (a lone insn is never simplified; the lhu has intermediate uses) and, + * being single-set, is birthing-boosted -- no anti-dependence starvation, so no + * fence is needed and sched2 interleaves it into the tpage/code window itself; + * - the branch is spelled `if (!(tpage & 0x10)) vv = vm; else vv = vm - 0x100;` + * (the copy arm coalesces away): the opposite polarity re-rolls 42 rows; + * - u is a FRESH single-set value from the shifted difference (a 2-set `uu -= ..; + * uu <<= ..` re-rolls 63 rows, moving allocations 100 rows away); + * - `shift = 2 - mode` is born early and unpinned (the birthing boost sinks it + * to its consumer, rows 370/372); + * - the OT base is computed right after the packet code byte, before the u/v loads. + * The P_TAG bitfield OT link and the HI-temp coordinate copy (t20/t22 around the + * D_801BA6B0 load) are kept from the Fable draft (§500-C, §501-L mechanisms). + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + u32 ot16; + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + u32 uu; + u32 cl; + u32 c40; + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/check_all_preflight.log b/.run/P32/t4d/check_all_preflight.log new file mode 100644 index 000000000..f8311594b --- /dev/null +++ b/.run/P32/t4d/check_all_preflight.log @@ -0,0 +1,220 @@ +[ OK ] resident +[ OK ] ov_SC01_005 +[ OK ] ov_SC05_000 +[ OK ] ov_SC01_000 +[ OK ] ov_SC01_006 +[ OK ] ov_SC03_006 +[ OK ] ov_SC04_000 +[ OK ] ov_SC01_001 +[ OK ] ov_SC02_003 +[ OK ] ov_SC03_001 +[ OK ] ov_SC02_000 +[ OK ] ov_SC01_077 +[ OK ] ov_SC03_002 +[ OK ] ov_SC04_019 +[ OK ] ov_SC04_018 +[ OK ] ov_SC06_000 +[ OK ] ov_SC01_004 +[ OK ] ov_SC01_074 +[ OK ] ov_SC07_000 +[ OK ] ov_SC01_008 +[ OK ] ov_SC01_080 +[ OK ] ov_SC02_004 +[ OK ] ov_SC02_016 +[ OK ] ov_SC02_015 +[ OK ] ov_SC02_005 +[ OK ] ov_SC02_017 +[ OK ] ov_SC01_084 +[ OK ] ov_SC01_009 +[ OK ] ov_SC02_021 +[ OK ] ov_SC02_011 +[ OK ] ov_SC02_026 +[ OK ] ov_SC02_027 +[ OK ] ov_SC02_028 +[ OK ] ov_SC02_035 +[ OK ] ov_SC02_031 +[ OK ] ov_SC03_012 +[ OK ] main +[ OK ] ov_SC03_007 +[ OK ] ov_SC02_039 +[ OK ] ov_SC03_011 +[ OK ] ov_SC02_041 +[ OK ] ov_SC03_013 +[ OK ] ov_SC03_003 +[ OK ] ov_SC03_010 +[ OK ] ov_SC03_014 +[ OK ] ov_SC03_015 +[ OK ] ov_SC03_023 +[ OK ] ov_SC03_030 +[ OK ] ov_SC03_029 +[ OK ] ov_SC03_024 +[ OK ] ov_SC03_031 +[ OK ] ov_SC03_093 +[ OK ] ov_SC03_028 +[ OK ] ov_SC03_091 +[ OK ] ov_SC03_092 +[ OK ] ov_SC03_095 +[ OK ] ov_SC03_089 +[ OK ] ov_SC03_090 +[ OK ] ov_SC03_097 +[ OK ] ov_SC03_096 +[ OK ] ov_SC03_094 +[ OK ] ov_SC03_098 +[ OK ] ov_SC03_100 +[ OK ] ov_SC03_099 +[ OK ] ov_SC03_102 +[ OK ] ov_SC03_101 +[ OK ] ov_SC03_108 +[ OK ] ov_SC03_104 +[ OK ] ov_SC03_103 +[ OK ] ov_SC03_105 +[ OK ] ov_SC03_111 +[ OK ] ov_SC03_110 +[ OK ] ov_SC03_113 +[ OK ] ov_SC03_112 +[ OK ] ov_SC03_109 +[ OK ] ov_SC03_115 +[ OK ] ov_SC03_114 +[ OK ] ov_SC03_116 +[ OK ] ov_SC03_117 +[ OK ] ov_SC03_119 +[ OK ] ov_SC03_121 +[ OK ] ov_SC03_125 +[ OK ] ov_SC04_007 +[ OK ] ov_SC03_118 +[ OK ] ov_SC03_126 +[ OK ] ov_SC03_124 +[ OK ] ov_SC04_003 +[ OK ] ov_SC04_006 +[ OK ] ov_SC04_002 +[ OK ] ov_SC04_005 +[ OK ] ov_SC04_004 +[ OK ] ov_SC04_009 +[ OK ] ov_SC04_010 +[ OK ] ov_SC04_008 +[ OK ] ov_SC04_011 +[ OK ] ov_SC04_016 +[ OK ] ov_SC04_021 +[ OK ] ov_SC04_015 +[ OK ] ov_SC05_002 +[ OK ] ov_SC04_020 +[ OK ] ov_SC04_012 +[ OK ] ov_SC05_001 +[ OK ] ov_SC05_003 +[ OK ] ov_SC05_004 +[ OK ] ov_SC05_005 +[ OK ] ov_SC05_006 +[ OK ] ov_SC05_008 +[ OK ] ov_SC05_007 +[ OK ] ov_SC05_010 +[ OK ] ov_SC05_009 +[ OK ] ov_SC05_011 +[ OK ] ov_SC06_006 +[ OK ] ov_SC05_018 +[ OK ] ov_SC06_015 +[ OK ] ov_SC06_013 +[ OK ] ov_SC05_019 +[ OK ] ov_SC06_008 +[ OK ] ov_SC06_014 +[ OK ] ov_SC06_011 +[ OK ] ov_SC06_016 +[ OK ] ov_SC05_017 +[ OK ] ov_SC06_010 +[ OK ] ov_SC06_018 +[ OK ] ov_SC06_022 +[ OK ] ov_SC06_020 +[ OK ] ov_SC06_024 +[ OK ] ov_SC06_025 +[ OK ] ov_SC06_027 +[ OK ] ov_SC07_009 +[ OK ] ov_SC06_029 +[ OK ] ov_SC07_008 +[ OK ] ov_SC06_030 +[ OK ] ov_SC06_032 +[ OK ] ov_SC06_033 +[ OK ] ov_SC07_002 +[ OK ] ov_SC07_001 +[ OK ] ov_SC07_007 +[ OK ] ov_SC07_010 +[ OK ] ov_SC07_006 +[ OK ] ov_SC07_011 +[ OK ] ov_SC03_107 +[ OK ] ov_MAIN_012 +[ OK ] md_MAIN_013 +[ OK ] md_MAIN_014 +[ OK ] ov_SC02_037 +[ OK ] md_MAIN_018 +[ OK ] md_MAIN_016 +[ OK ] md_MAIN_017 +[ OK ] md_MAIN_021 +[ OK ] md_MAIN_015 +[ OK ] md_MAIN_019 +[ OK ] md_MAIN_023 +[ OK ] md_MAIN_024 +[ OK ] md_MAIN_020 +[ OK ] md_MAIN_022 +[ OK ] md_MAIN_025 +[ OK ] md_MAIN_026 +[ OK ] md_MAIN_027 +[ OK ] md_MAIN_028 +[ OK ] md_MAIN_029 +[ OK ] md_MAIN_032 +[ OK ] md_MAIN_030 +[ OK ] md_MAIN_031 +[ OK ] md_MAIN_033 +[ OK ] md_MAIN_034 +[ OK ] md_MAIN_036 +[ OK ] md_MAIN_037 +[ OK ] md_MAIN_035 +[ OK ] md_MAIN_038 +[ OK ] md_MAIN_039 +[ OK ] md_MAIN_040 +[ OK ] md_MAIN_041 +[ OK ] md_MAIN_042 +[ OK ] md_MAIN_043 +[ OK ] md_MAIN_044 +[ OK ] md_MAIN_045 +[ OK ] md_MAIN_046 +[ OK ] md_MAIN_047 +[ OK ] md_MAIN_001 +[ OK ] md_MAIN_011 +[ OK ] md_MAIN_008 +[ OK ] md_SC07_003 +[ OK ] md_SC07_004 +[ OK ] md_MAIN_003 +[ OK ] md_SC03_074 +[ OK ] md_SC03_073 +[ OK ] md_SC03_075 +[ OK ] md_SC03_076 +[ OK ] md_SC03_078 +[ OK ] md_SC03_132 +[ OK ] md_SC03_077 +[ OK ] md_SC03_079 +[ OK ] md_SC03_133 +[ OK ] md_SC03_134 +[ OK ] md_SC03_137 +[ OK ] md_SC03_135 +[ OK ] md_SC03_136 +[ OK ] md_SC03_138 +[ OK ] md_SC04_024 +[ OK ] md_SC04_025 +[ OK ] md_SC04_026 +[ OK ] md_SC04_029 +[ OK ] md_SC04_027 +[ OK ] md_SC04_028 +[ OK ] md_SC04_030 +[ OK ] md_SC05_025 +[ OK ] md_SC05_023 +[ OK ] md_SC05_024 +[ OK ] md_SC05_028 +[ OK ] md_SC05_026 +[ OK ] md_SC05_027 +[ OK ] md_MAIN_007 +[ OK ] md_SC02_009 +[ OK ] md_SC05_029 +[ OK ] md_SC03_053 +[ OK ] md_SC03_056 +[ OK ] md_MAIN_009 +[ OK ] md_SC03_054 +check-all: 218 passed, 0 failed of 218 +EXIT=0 diff --git a/.run/P32/t4d/cookbook_index.log b/.run/P32/t4d/cookbook_index.log new file mode 100644 index 000000000..61a9bfbc8 --- /dev/null +++ b/.run/P32/t4d/cookbook_index.log @@ -0,0 +1 @@ +cookbook index -> docs/cookbook-index.md (1169 sections, 14 symptom buckets) diff --git a/.run/P32/t4d/d10_ot16only.c b/.run/P32/t4d/d10_ot16only.c new file mode 100644 index 000000000..cdff94ffb --- /dev/null +++ b/.run/P32/t4d/d10_ot16only.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + u32 uu; + u32 cl; + u32 c40; + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d11_f2polarity.c b/.run/P32/t4d/d11_f2polarity.c new file mode 100644 index 000000000..238366b1d --- /dev/null +++ b/.run/P32/t4d/d11_f2polarity.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + u32 ot16; + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + u32 uu; + u32 cl; + u32 c40; + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (*(u16 *)(p + 0x16) & 0x10) { + vv = vm - 0x100; + } else { + vv = vm; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d12_twoset_uu.c b/.run/P32/t4d/d12_twoset_uu.c new file mode 100644 index 000000000..21fee0a20 --- /dev/null +++ b/.run/P32/t4d/d12_twoset_uu.c @@ -0,0 +1,340 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + u32 ot16; + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + u32 uu; + u32 cl; + u32 c40; + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + uu -= (*(u16 *)(p + 0x16) & 0xF) << 6; + uu <<= shift; + p[0xC] = uu; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d1_sibport.c b/.run/P32/t4d/d1_sibport.c new file mode 100644 index 000000000..e63990b63 --- /dev/null +++ b/.run/P32/t4d/d1_sibport.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + register u32 mode __asm__("$5"); + u32 w; + register u32 uu __asm__("$4"); + register u32 cl __asm__("$7"); + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d2_nomode.c b/.run/P32/t4d/d2_nomode.c new file mode 100644 index 000000000..d6865b9e2 --- /dev/null +++ b/.run/P32/t4d/d2_nomode.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + register u32 uu __asm__("$4"); + register u32 cl __asm__("$7"); + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d3_noot16.c b/.run/P32/t4d/d3_noot16.c new file mode 100644 index 000000000..4fb23e176 --- /dev/null +++ b/.run/P32/t4d/d3_noot16.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + u32 ot16; + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + register u32 mode __asm__("$5"); + u32 w; + register u32 uu __asm__("$4"); + register u32 cl __asm__("$7"); + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d4_nomode_noot16.c b/.run/P32/t4d/d4_nomode_noot16.c new file mode 100644 index 000000000..6ca09f874 --- /dev/null +++ b/.run/P32/t4d/d4_nomode_noot16.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + u32 ot16; + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + register u32 uu __asm__("$4"); + register u32 cl __asm__("$7"); + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d5_nocl.c b/.run/P32/t4d/d5_nocl.c new file mode 100644 index 000000000..b69bb2d63 --- /dev/null +++ b/.run/P32/t4d/d5_nocl.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + register u32 mode __asm__("$5"); + u32 w; + register u32 uu __asm__("$4"); + u32 cl; + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d6_min3.c b/.run/P32/t4d/d6_min3.c new file mode 100644 index 000000000..ca1758b7a --- /dev/null +++ b/.run/P32/t4d/d6_min3.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + register u32 uu __asm__("$4"); + u32 cl; + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d7_noc40.c b/.run/P32/t4d/d7_noc40.c new file mode 100644 index 000000000..33ebae1c4 --- /dev/null +++ b/.run/P32/t4d/d7_noc40.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + register u32 uu __asm__("$4"); + u32 cl; + u32 c40; + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d8_nouu.c b/.run/P32/t4d/d8_nouu.c new file mode 100644 index 000000000..51d7fa361 --- /dev/null +++ b/.run/P32/t4d/d8_nouu.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + register u32 ot16 __asm__("$6"); + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + u32 uu; + u32 cl; + register u32 c40 __asm__("$2"); + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/d9_nopins.c b/.run/P32/t4d/d9_nopins.c new file mode 100644 index 000000000..6678807cb --- /dev/null +++ b/.run/P32/t4d/d9_nopins.c @@ -0,0 +1,339 @@ +/* func_80185810 (ov_SC03_105, sub ov_SC03_105_jr_80181C84) -- 489 ins. + * + * S85 hand pass, row (d): §501-N port of the BANKED same-shape cousin + * ov_SC02_027:func_80180B3C (src/ov_SC02_027/ov_SC02_027_jr_8017D898.c:4810) + * onto the S83 Fable draft (.run/P32/t5x/fable/func_80185810.c, DIFF 13). + * Everything outside the packet-fill window is the Fable draft verbatim. + * + * The cousin's window spelling (fence-free): the v coordinate is loaded into a + * $7-pinned variable and masked into a FRESH single-set `v = y & 0xFFFF` (a hard + * register hides nonzero_bits from combine, so the andi survives and, being a + * single set, is birthing-boosted -- no anti-dependence starvation, no fence); + * `c40 = (w & 0x40) >> 6` pinned $2; `shift = 2 - tp` early and unpinned; a + * fresh `u` from the $4-pinned x; the v0 store through an if/else copy `vv`. + */ + +#ifndef BFM_ENGINE_TYPES_H +typedef struct { short m[3][3]; long t[3]; } MATRIX_80188114; +#endif + +extern u8 D_800AF630[]; +extern MATRIX_80188114 D_801BC9B4; +extern u8 *D_800A5E60; +extern u8 D_800A6610[]; +extern u8 D_801BA6B0; +extern void func_80185FB4(s32 a0, s32 a1, s32 a2); +extern void func_8001F730(s32 a0, void *a1, void *a2); + +#define gte_SetRotMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_SetTransMatrix_85810(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_ldclmv_85810(r0) __asm__ volatile ( \ + "lhu $12, 0( %0 );" \ + "lhu $13, 6( %0 );" \ + "lhu $14, 12( %0 );" \ + "mtc2 $12, $9;" \ + "mtc2 $13, $10;" \ + "mtc2 $14, $11" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + +#define gte_rtir_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 3, 3, 0") + +#define gte_stclmv_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $9;" \ + "mfc2 $13, $10;" \ + "mfc2 $14, $11;" \ + "sh $12, 0( %0 );" \ + "sh $13, 6( %0 );" \ + "sh $14, 12( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14", "memory" ) + +#define gte_ldlvl_85810(r0) __asm__ volatile ( \ + "lhu $13, 4( %0 );" \ + "lhu $12, 0( %0 );" \ + "sll $13, $13, 16;" \ + "or $12, $12, $13;" \ + "mtc2 $12, $0;" \ + "lwc2 $1, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "$13" ) + +#define gte_rt_85810() __asm__ volatile ("nop;nop;mvmva 1, 0, 0, 0, 0") + +#define gte_stlvnl_85810(r0) __asm__ volatile ( \ + "swc2 $25, 0( %0 );" \ + "swc2 $26, 4( %0 );" \ + "swc2 $27, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv0_85810(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps_85810() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy_85810(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz_85810(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_ldv3_85810(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtpt_85810() __asm__ volatile ("nop;nop;rtpt") + +#define gte_stsxy0_85810(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy1_85810(r0) __asm__ volatile ( \ + "swc2 $13, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stflg_85810(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stszotz_85810(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +void func_80185810(s32 a0) +{ + typedef struct { u16 vx, vy, vz, pad; } UV_85810; + typedef struct { short m[3][3]; long t[3]; } MTX_85810; + typedef struct { u32 addr : 24; u32 len : 8; } PTag_85810; + + UV_85810 v[5]; /* sp+0x10 .. sp+0x37 */ + MTX_85810 m; /* sp+0x38 */ + long sz; /* sp+0x58 */ + long flag; /* sp+0x5C */ + long otz; /* sp+0x60 */ + u8 *base; + u8 *p; + u8 *ob; + u32 ot16; + PTag_85810 *q; + u32 flags; + s32 spr; + s32 t0; + s32 sx; + s32 sy; + u32 mode; + u32 w; + u32 uu; + u32 cl; + u32 c40; + u32 vm; + u32 vv; + u32 u; + s32 shift; + u32 tp; + u16 t20; + u16 t22; + + base = D_800AF630; + flags = *(u32 *)a0; + spr = *(s32 *)(a0 + 0x24); + + if (*(s32 *)(a0 + 0x20) != 0) { + if (flags & 0x800000) { + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x34)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x36)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x38)); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810((u8 *)(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x48)); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } else { + func_80185FB4(*(s32 *)(*(s32 *)(a0 + 0x20) + 0x20), flags, (s32)&m); + gte_SetRotMatrix_85810(base + 0x18); + gte_ldclmv_85810(&m.m[0][0]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][0]); + gte_ldclmv_85810(&m.m[0][1]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][1]); + gte_ldclmv_85810(&m.m[0][2]); + gte_rtir_85810(); + gte_stclmv_85810(&m.m[0][2]); + gte_SetTransMatrix_85810(base + 0x18); + gte_ldlvl_85810(&m.t[0]); + gte_rt_85810(); + gte_stlvnl_85810(&m.t[0]); + } + gte_SetRotMatrix_85810(&m); + gte_SetTransMatrix_85810(&m); + t0 = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) + 0x10; + } else { + gte_SetRotMatrix_85810(base + 0x18); + gte_SetTransMatrix_85810(base + 0x18); + t0 = a0 + 4; + } + + gte_ldv0_85810((u8 *)(a0 + 0x14)); + gte_rtps_85810(); + gte_stsxy_85810(&v[0]); + gte_stsz_85810(&sz); + + sx = *(s16 *)&v[0].vx; + if (sx < 0) sx = -sx; + if (sx >= 0xC9) return; + sy = *(s16 *)&v[0].vy; + if (sy < 0) sy = -sy; + if (sy >= 0xA1) return; + + *(u16 *)&D_801BC9B4 = *(u16 *)(a0 + 0xC); + *(u16 *)((u8 *)&D_801BC9B4 + 8) = *(u16 *)(a0 + 0xE); + gte_SetRotMatrix_85810(&D_801BC9B4); + gte_SetTransMatrix_85810(&D_801BC9B4); + + v[3].vx = *(u16 *)(spr + 8) + *(u16 *)(a0 + 0x1C); + v[3].vy = *(u16 *)(spr + 0xA) + *(u16 *)(a0 + 0x1E); + v[3].vz = sz; + v[4].vx = *(u8 *)(spr + 2); + v[4].vy = *(u8 *)(spr + 3); + v[4].vz = sz; + + gte_ldv3_85810(&v[3], &v[4], &v[4]); + gte_rtpt_85810(); + gte_stsxy0_85810(&v[1]); + gte_stsxy1_85810(&v[2]); + gte_stflg_85810(&flag); + gte_stszotz_85810(&otz); + if (flag & ~0x1000) return; + + /* ---- the packet-fill window: the cousin's spelling (func_80180B3C) ---- */ + mode = (flags >> 24) & 3; + shift = 2 - mode; + p = D_800A5E60; + D_800A5E60 = p + 0x28; + w = mode << 7; + p[3] = 9; + p[7] = 0x2C; + ot16 = *(u16 *)(base + 0xA3D2); + ob = &D_800A6610[ot16 << 14]; + uu = *(u16 *)(spr + 4); + cl = *(u16 *)(spr + 6); + p[7] |= 2; + *(u16 *)(p + 0x16) = w | ((flags >> 23) & 0x60) | ((cl & 0x100) >> 4) + | ((uu & 0x3C0) >> 6) | ((cl & 0x200) << 2); + c40 = (flags & 0x40) >> 6; + p[7] |= c40; + vm = cl & 0xFFFF; + u = (uu - ((*(u16 *)(p + 0x16) & 0xF) << 6)) << shift; + p[0xC] = u; + if (!(*(u16 *)(p + 0x16) & 0x10)) { + vv = vm; + } else { + vv = vm - 0x100; + } + p[0xD] = vv; + /* ---- end of the ported window ---- */ + + p[0x14] = p[0xC] + *(u8 *)(spr + 2) - 1; + p[0x15] = p[0xD]; + p[0x1C] = p[0xC]; + p[0x1D] = p[0xD] + *(u8 *)(spr + 3) - 1; + p[6] = 0x80; + p[5] = 0x80; + p[4] = 0x80; + p[0x24] = p[0x14]; + p[0x25] = p[0x1D]; + + *(u16 *)(p + 8) = v[0].vx + v[1].vx; + *(u16 *)(p + 0xA) = v[0].vy + v[1].vy; + *(u16 *)(p + 0x10) = *(u16 *)(p + 8) + v[2].vx; + *(u16 *)(p + 0x1A) = *(u16 *)(p + 0xA) + v[2].vy; + *(u16 *)(p + 0x12) = *(u16 *)(p + 0xA); + *(u16 *)(p + 0x18) = *(u16 *)(p + 8); + t20 = *(u16 *)(p + 0x10); + t22 = *(u16 *)(p + 0x1A); + tp = D_801BA6B0; + *(u16 *)(p + 0x20) = t20; + *(u16 *)(p + 0x22) = t22; + + if (tp == 0) { + u32 t2 = *(u8 *)(spr + 1); + u32 tb = (t2 + 0x100) << 6; + if (t2 < 0xE0) *(u16 *)(p + 0xE) = tb | 0x16; + else *(u16 *)(p + 0xE) = tb | 0x10; + } else { + u32 tb = (tp + 0x100) << 6; + { u32 vx; if (tp < 0xE0) vx = tb | 0x16; else vx = tb | 0x10; *(u16 *)(p + 0xE) = vx; } + } + + if ((flags & 0x300000) == 0x200000) { + func_8001F730(t0, &v[0], p); + } + + q = (PTag_85810 *)((otz << 2) + (u32)ob); + ((PTag_85810 *)p)->addr = q[1].addr; + q[1].addr = (u32)p; +} diff --git a/.run/P32/t4d/r22_check.log b/.run/P32/t4d/r22_check.log new file mode 100644 index 000000000..6bd2461d8 --- /dev/null +++ b/.run/P32/t4d/r22_check.log @@ -0,0 +1,111 @@ +[ OK ] resident +[ OK ] ov_SC03_006 +[ OK ] ov_SC05_000 +[ OK ] ov_SC01_000 +[ OK ] ov_SC06_000 +[ OK ] ov_SC04_000 +[ OK ] ov_SC01_001 +[ OK ] ov_SC01_005 +[ OK ] ov_SC01_006 +[ OK ] ov_SC03_002 +[ OK ] ov_SC01_077 +[ OK ] ov_SC04_019 +[ OK ] ov_SC04_018 +[ OK ] ov_SC02_003 +[ OK ] ov_SC03_001 +[ OK ] ov_SC02_000 +[ OK ] main +[ OK ] ov_SC01_074 +[ OK ] ov_SC01_080 +[ OK ] ov_SC02_004 +[ OK ] ov_SC01_004 +[ OK ] ov_SC07_000 +[ OK ] ov_SC01_008 +[ OK ] ov_SC01_009 +[ OK ] ov_SC01_084 +[ OK ] ov_SC02_015 +[ OK ] ov_SC02_005 +[ OK ] ov_SC02_021 +[ OK ] ov_SC02_017 +[ OK ] ov_SC02_011 +[ OK ] ov_SC02_016 +[ OK ] ov_SC02_026 +[ OK ] ov_SC02_027 +[ OK ] ov_SC02_031 +[ OK ] ov_SC03_003 +[ OK ] ov_SC02_041 +[ OK ] ov_SC02_035 +[ OK ] ov_SC02_028 +[ OK ] ov_SC02_039 +[ OK ] ov_SC03_010 +[ OK ] ov_SC03_007 +[ OK ] ov_SC03_011 +[ OK ] ov_SC03_012 +[ OK ] ov_SC03_023 +[ OK ] ov_SC03_013 +[ OK ] ov_SC03_014 +[ OK ] ov_SC03_024 +[ OK ] ov_SC03_015 +[ OK ] ov_SC03_028 +[ OK ] ov_SC03_030 +[ OK ] ov_SC03_029 +[ OK ] ov_SC03_031 +[ OK ] ov_SC03_090 +[ OK ] ov_SC03_089 +[ OK ] ov_SC03_092 +[ OK ] ov_SC03_093 +[ OK ] ov_SC03_094 +[ OK ] ov_SC03_095 +[ OK ] ov_SC03_091 +[ OK ] ov_SC03_096 +[ OK ] ov_SC03_097 +[ OK ] ov_SC03_099 +[ OK ] ov_SC03_098 +[ OK ] ov_SC03_100 +[ OK ] ov_SC03_101 +[ OK ] ov_SC03_102 +[ OK ] ov_SC03_103 +[ OK ] ov_SC03_104 +[ OK ] ov_SC03_109 +[ OK ] ov_SC03_108 +[ OK ] ov_SC03_110 +[ OK ] ov_SC03_111 +[ OK ] ov_SC03_113 +[ OK ] ov_SC03_114 +[ OK ] ov_SC03_112 +[ OK ] ov_SC03_105 +[ OK ] ov_SC03_115 +[ OK ] ov_SC03_116 +[ OK ] ov_SC03_117 +[ OK ] ov_SC03_118 +[ OK ] ov_SC03_119 +[ OK ] ov_SC03_121 +[ OK ] ov_SC03_126 +[ OK ] ov_SC03_125 +[ OK ] ov_SC04_002 +[ OK ] ov_SC03_124 +[ OK ] ov_SC04_004 +[ OK ] ov_SC04_003 +[ OK ] ov_SC04_005 +[ OK ] ov_SC04_006 +[ OK ] ov_SC04_008 +[ OK ] ov_SC04_007 +[ OK ] ov_SC04_009 +[ OK ] ov_SC04_010 +[ OK ] ov_SC04_011 +[ OK ] ov_SC04_012 +[ OK ] ov_SC04_015 +[ OK ] ov_SC04_016 +[ OK ] ov_SC04_021 +[ OK ] ov_SC04_020 +[ OK ] ov_SC05_002 +[ OK ] ov_SC05_001 +[ OK ] ov_SC05_004 +[ OK ] ov_SC05_005 +[ OK ] ov_SC05_003 +[ OK ] ov_SC05_006 +[ OK ] ov_SC05_007 +[ OK ] ov_SC05_008 +[ OK ] ov_SC05_009 +[ OK ] ov_SC05_010 +[ OK ] ov_SC05_011 diff --git a/.run/P32/t4d/r22_clean.log b/.run/P32/t4d/r22_clean.log new file mode 100644 index 000000000..d0f60d598 --- /dev/null +++ b/.run/P32/t4d/r22_clean.log @@ -0,0 +1,2 @@ +clean: removed build/, expected/, and the regenerated splat tree (asm/, assets/, include macros, undefined_*_auto.txt). +EXIT=0 diff --git a/.run/P32/t4d/r22_extract.log b/.run/P32/t4d/r22_extract.log new file mode 100644 index 000000000..f14f6284e --- /dev/null +++ b/.run/P32/t4d/r22_extract.log @@ -0,0 +1,254 @@ +splat 0.41.0 (powered by spimdisasm 1.41.0) + 0%| | 0/1096 [00:00> 16) + 344 | 9426a3d2 lhu a2,-23598(at) | 02810821 addu $at, $s4, $at + 345 | 96450004 lhu a1,4(s2) | 9426a3d2 lhu $a2, -0x5C2E($at) + 346 | 96430006 lhu v1,6(s2) | 96440004 lhu $a0, 0x4($s2) + 347 | 2402002e li v0,46 | 96470006 lhu $a3, 0x6($s2) + 348 | a2020007 sb v0,7(s0) | 2402002e addiu $v0, $zero, 0x2E + 349 | 001315c2 srl v0,s3,0x17 | a2020007 sb $v0, 0x7($s0) + 350 | 30420060 andi v0,v0,0x60 | 001315c2 srl $v0, $s3, 23 + 351 | 00603821 move a3,v1 | 30420060 andi $v0, $v0, 0x60 + 352 | 000419c0 sll v1,a0,0x7 | 00621825 or $v1, $v1, $v0 + 353 | 00621825 or v1,v1,v0 | 30e20100 andi $v0, $a3, 0x100 + 354 | 30e20100 andi v0,a3,0x100 | 00021102 srl $v0, $v0, 4 + 355 | 00021102 srl v0,v0,0x4 | 00621825 or $v1, $v1, $v0 + 356 | 00621825 or v1,v1,v0 | 308203c0 andi $v0, $a0, 0x3C0 + 357 | 30a203c0 andi v0,a1,0x3c0 | 00021182 srl $v0, $v0, 6 + 358 | 00021182 srl v0,v0,0x6 | 00621825 or $v1, $v1, $v0 + 359 | 00621825 or v1,v1,v0 | 30e20200 andi $v0, $a3, 0x200 + 360 | 30e20200 andi v0,a3,0x200 | 00021080 sll $v0, $v0, 2 + 361 | 00021080 sll v0,v0,0x2 | 00621825 or $v1, $v1, $v0 + 362 | 00621825 or v1,v1,v0 | 32620040 andi $v0, $s3, 0x40 + 363 | 32620040 andi v0,s3,0x40 | 00021182 srl $v0, $v0, 6 + 364 | 00021182 srl v0,v0,0x6 | 00063380 sll $a2, $a2, 14 + 367 | 00063380 sll a2,a2,0xe | 30e7ffff andi $a3, $a3, 0xFFFF + 372 | 00641823 subu v1,v1,a0 | 00651823 subu $v1, $v1, $a1 + 375 | 00a22823 subu a1,a1,v0 | 00822023 subu $a0, $a0, $v0 + 376 | 00652804 sllv a1,a1,v1 | 3c02800a lui $v0, %hi(D_800A6610) + 377 | 3c030000 lui v1,0x0 | 24426610 addiu $v0, $v0, %lo(D_800A6610) + 378 | 24630000 addiu v1,v1,0 | 00c28821 addu $s1, $a2, $v0 + 380 | 00c38821 addu s1,a2,v1 | 00642004 sllv $a0, $a0, $v1 + 383 | a205000c sb a1,12(s0) | a204000c sb $a0, 0xC($s0) diff --git a/.run/P32/t4d/rtu_d12_twoset_uu.log b/.run/P32/t4d/rtu_d12_twoset_uu.log new file mode 100644 index 000000000..cca6e09e5 --- /dev/null +++ b/.run/P32/t4d/rtu_d12_twoset_uu.log @@ -0,0 +1,62 @@ +DIFF func_80185810 mine=489 ins, target=489 ins, 63 mismatched + idx | MINE | TARGET + 218 | 24490010 addiu t1,v0,16 | 24480010 addiu $t0, $v0, 0x10 + 236 | 26290004 addiu t1,s1,4 | 26280004 addiu $t0, $s1, 0x4 + 267 | 3c0a0000 lui t2,0x0 | 3c09801c lui $t1, %hi(D_801BC9B4) + 268 | 254a0000 addiu t2,t2,0 | 2529c9b4 addiu $t1, $t1, %lo(D_801BC9B4) + 271 | 8d4c0000 lw t4,0(t2) | 8d2c0000 lw $t4, 0x0($t1) + 272 | 8d4d0004 lw t5,4(t2) | 8d2d0004 lw $t5, 0x4($t1) + 275 | 8d4c0008 lw t4,8(t2) | 8d2c0008 lw $t4, 0x8($t1) + 276 | 8d4d000c lw t5,12(t2) | 8d2d000c lw $t5, 0xC($t1) + 277 | 8d4e0010 lw t6,16(t2) | 8d2e0010 lw $t6, 0x10($t1) + 281 | 8d4c0014 lw t4,20(t2) | 8d2c0014 lw $t4, 0x14($t1) + 282 | 8d4d0018 lw t5,24(t2) | 8d2d0018 lw $t5, 0x18($t1) + 284 | 8d4e001c lw t6,28(t2) | 8d2e001c lw $t6, 0x1C($t1) + 331 | 00133602 srl a2,s3,0x18 | 00132e02 srl $a1, $s3, 24 + 332 | 30c60003 andi a2,a2,0x3 | 30a50003 andi $a1, $a1, 0x3 + 333 | 000619c0 sll v1,a2,0x7 | 3c10800a lui $s0, %hi(D_800A5E60) + 334 | 32640040 andi a0,s3,0x40 | 8e105e60 lw $s0, %lo(D_800A5E60)($s0) + 335 | 3c100000 lui s0,0x0 | 000519c0 sll $v1, $a1, 7 + 336 | 8e100000 lw s0,0(s0) | 26020028 addiu $v0, $s0, 0x28 + 337 | 00042182 srl a0,a0,0x6 | 3c01800a lui $at, %hi(D_800A5E60) + 338 | 26020028 addiu v0,s0,40 | ac225e60 sw $v0, %lo(D_800A5E60)($at) + 339 | 3c010000 lui at,0x0 | 24020009 addiu $v0, $zero, 0x9 + 340 | ac220000 sw v0,0(at) | a2020003 sb $v0, 0x3($s0) + 341 | 24020009 li v0,9 | 2402002c addiu $v0, $zero, 0x2C + 342 | a2020003 sb v0,3(s0) | a2020007 sb $v0, 0x7($s0) + 343 | 2402002c li v0,44 | 3c010001 lui $at, (0x10000 >> 16) + 344 | a2020007 sb v0,7(s0) | 02810821 addu $at, $s4, $at + 345 | 96450004 lhu a1,4(s2) | 9426a3d2 lhu $a2, -0x5C2E($at) + 346 | 3c010001 lui at,0x1 | 96440004 lhu $a0, 0x4($s2) + 347 | 02810821 addu at,s4,at | 96470006 lhu $a3, 0x6($s2) + 348 | 9427a3d2 lhu a3,-23598(at) | 2402002e addiu $v0, $zero, 0x2E + 349 | 96480006 lhu t0,6(s2) | a2020007 sb $v0, 0x7($s0) + 350 | 2402002e li v0,46 | 001315c2 srl $v0, $s3, 23 + 351 | a2020007 sb v0,7(s0) | 30420060 andi $v0, $v0, 0x60 + 352 | 001315c2 srl v0,s3,0x17 | 00621825 or $v1, $v1, $v0 + 353 | 30420060 andi v0,v0,0x60 | 30e20100 andi $v0, $a3, 0x100 + 354 | 00621825 or v1,v1,v0 | 00021102 srl $v0, $v0, 4 + 355 | 31020100 andi v0,t0,0x100 | 00621825 or $v1, $v1, $v0 + 356 | 00021102 srl v0,v0,0x4 | 308203c0 andi $v0, $a0, 0x3C0 + 357 | 00621825 or v1,v1,v0 | 00021182 srl $v0, $v0, 6 + 358 | 30a203c0 andi v0,a1,0x3c0 | 00621825 or $v1, $v1, $v0 + 359 | 00021182 srl v0,v0,0x6 | 30e20200 andi $v0, $a3, 0x200 + 360 | 00621825 or v1,v1,v0 | 00021080 sll $v0, $v0, 2 + 361 | 31020200 andi v0,t0,0x200 | 00621825 or $v1, $v1, $v0 + 362 | 00021080 sll v0,v0,0x2 | 32620040 andi $v0, $s3, 0x40 + 363 | 00621825 or v1,v1,v0 | 00021182 srl $v0, $v0, 6 + 364 | 92020007 lbu v0,7(s0) | 00063380 sll $a2, $a2, 14 + 365 | 00073b80 sll a3,a3,0xe | a6030016 sh $v1, 0x16($s0) + 366 | a6030016 sh v1,22(s0) | 92030007 lbu $v1, 0x7($s0) + 367 | 96030016 lhu v1,22(s0) | 30e7ffff andi $a3, $a3, 0xFFFF + 368 | 00441025 or v0,v0,a0 | 00621825 or $v1, $v1, $v0 + 369 | 3063000f andi v1,v1,0xf | a2030007 sb $v1, 0x7($s0) + 370 | 00031980 sll v1,v1,0x6 | 24030002 addiu $v1, $zero, 0x2 + 371 | 00a32823 subu a1,a1,v1 | 96020016 lhu $v0, 0x16($s0) + 372 | a2020007 sb v0,7(s0) | 00651823 subu $v1, $v1, $a1 + 373 | 24020002 li v0,2 | 3042000f andi $v0, $v0, 0xF + 374 | 00461023 subu v0,v0,a2 | 00021180 sll $v0, $v0, 6 + 375 | 00452804 sllv a1,a1,v0 | 00822023 subu $a0, $a0, $v0 + 378 | 00e28821 addu s1,a3,v0 | 00c28821 addu $s1, $a2, $v0 + 380 | 3108ffff andi t0,t0,0xffff | 00642004 sllv $a0, $a0, $v1 + 383 | a205000c sb a1,12(s0) | a204000c sb $a0, 0xC($s0) diff --git a/.run/P32/t4d/rtu_d2_nomode.log b/.run/P32/t4d/rtu_d2_nomode.log new file mode 100644 index 000000000..e96d6e806 --- /dev/null +++ b/.run/P32/t4d/rtu_d2_nomode.log @@ -0,0 +1 @@ +MATCH (489 ins) func_80185810 diff --git a/.run/P32/t4d/rtu_d3_noot16.log b/.run/P32/t4d/rtu_d3_noot16.log new file mode 100644 index 000000000..1d7f02cfc --- /dev/null +++ b/.run/P32/t4d/rtu_d3_noot16.log @@ -0,0 +1,6 @@ +DIFF func_80185810 mine=489 ins, target=489 ins, 4 mismatched + idx | MINE | TARGET + 343 | 96440004 lhu a0,4(s2) | 3c010001 lui $at, (0x10000 >> 16) + 344 | 3c010001 lui at,0x1 | 02810821 addu $at, $s4, $at + 345 | 02810821 addu at,s4,at | 9426a3d2 lhu $a2, -0x5C2E($at) + 346 | 9426a3d2 lhu a2,-23598(at) | 96440004 lhu $a0, 0x4($s2) diff --git a/.run/P32/t4d/rtu_d4_nomode_noot16.log b/.run/P32/t4d/rtu_d4_nomode_noot16.log new file mode 100644 index 000000000..1d7f02cfc --- /dev/null +++ b/.run/P32/t4d/rtu_d4_nomode_noot16.log @@ -0,0 +1,6 @@ +DIFF func_80185810 mine=489 ins, target=489 ins, 4 mismatched + idx | MINE | TARGET + 343 | 96440004 lhu a0,4(s2) | 3c010001 lui $at, (0x10000 >> 16) + 344 | 3c010001 lui at,0x1 | 02810821 addu $at, $s4, $at + 345 | 02810821 addu at,s4,at | 9426a3d2 lhu $a2, -0x5C2E($at) + 346 | 9426a3d2 lhu a2,-23598(at) | 96440004 lhu $a0, 0x4($s2) diff --git a/.run/P32/t4d/rtu_d5_nocl.log b/.run/P32/t4d/rtu_d5_nocl.log new file mode 100644 index 000000000..e96d6e806 --- /dev/null +++ b/.run/P32/t4d/rtu_d5_nocl.log @@ -0,0 +1 @@ +MATCH (489 ins) func_80185810 diff --git a/.run/P32/t4d/rtu_d6_min3.log b/.run/P32/t4d/rtu_d6_min3.log new file mode 100644 index 000000000..e96d6e806 --- /dev/null +++ b/.run/P32/t4d/rtu_d6_min3.log @@ -0,0 +1 @@ +MATCH (489 ins) func_80185810 diff --git a/.run/P32/t4d/rtu_d7_noc40.log b/.run/P32/t4d/rtu_d7_noc40.log new file mode 100644 index 000000000..e96d6e806 --- /dev/null +++ b/.run/P32/t4d/rtu_d7_noc40.log @@ -0,0 +1 @@ +MATCH (489 ins) func_80185810 diff --git a/.run/P32/t4d/rtu_d8_nouu.log b/.run/P32/t4d/rtu_d8_nouu.log new file mode 100644 index 000000000..e96d6e806 --- /dev/null +++ b/.run/P32/t4d/rtu_d8_nouu.log @@ -0,0 +1 @@ +MATCH (489 ins) func_80185810 diff --git a/.run/P32/t4d/rtu_d9_nopins.log b/.run/P32/t4d/rtu_d9_nopins.log new file mode 100644 index 000000000..e96d6e806 --- /dev/null +++ b/.run/P32/t4d/rtu_d9_nopins.log @@ -0,0 +1 @@ +MATCH (489 ins) func_80185810 diff --git a/docs/accelerators.md b/docs/accelerators.md index 0102e6fa7..3d0aec614 100644 --- a/docs/accelerators.md +++ b/docs/accelerators.md @@ -811,3 +811,14 @@ had matched with the plain libgpu shape; porting that body with this function's was the TU's `u8` declaration of the OT symbol, solved by the fleet's asm-label alias (§501-N). Accelerator: a wave card for a row whose family has a banked exemplar must carry that exemplar's SOURCE as the seed (family_cousins/seed_ref), and a hand pass must open with `grep -l` for the family's banked bodies; a residual-class name is the family's signature, not a lever list. + +**(14) The atlas's similarity score is not a shape oracle — grep the idiom's CONSTANTS and read the sibling's OBJDUMP window +(P32 T4b hand pass, `ov_SC03_105:func_80185810`, S85).** The row had consumed an Opus pass, a 655k-token Fable pass with a +3,360-variant sweep, five pins and a fence, and sat at DIFF 13 with its mechanism correctly read and its cure judged blocked. The +atlas had listed the answer all along as a 0.55 "weak cousin" (`ov_SC02_027:func_80180B3C`): a grep for the getTPage chain's +constant (`'0x200) << 2'`) across `src/` surfaced it as the same billboard drawer, and its compiled window was the target's rows +362–386 verbatim. Porting the spelling matched in one draft, then with every pin removed (§501-P). Accelerator: before ANY +scheduling/allocation dial on a packet-building function, grep `src/` for the idiom's literal constants (tpage chain, prim codes, +`+ 0x100) << 6` cluts, `0xE1000000` tags) and objdump each hit's window against the target; a same-shape sibling with different +base registers scores as a stranger in every similarity metric we have, and its spelling is worth more than the diff's +mechanism (extends (13); the twin oracle, family maps and atlas knn all reported nothing for this row). diff --git a/docs/backlog.md b/docs/backlog.md index a1d7ca1e5..1c63e7a49 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -2,11 +2,10 @@ > Generated by `tools/backlog.py render` from `.run/backlog.jsonl`. These are functions the Phase-21 automation got **close** on but did NOT byte-match. The whole-binary byte-gate is the sole arbiter (G3/P9): **byte-matches bank and are NOT listed here** — only genuine near-misses/blockers are. Ranked by hand-session priority: **reach** (×N propagation leverage) → **closeness** (match_one mismatch count, lower = closer) → **size**. Each row's `best_draft` is the closest C the machine reached — resume from there. -**Open near-misses:** 4 · by status {'near': 3, 'failed': 1} · by class {'WALL-PROVED': 1, 'FRAME+SCHED': 1, 'SCHED': 1, None: 1} +**Open near-misses:** 3 · by status {'near': 2, 'failed': 1} · by class {'WALL-PROVED': 1, 'FRAME+SCHED': 1, None: 1} | # | addr | reach | class | nins | status | closeness | where it stuck | best draft | |--:|------|------:|-------|-----:|--------|----------:|----------------|------------| | 1 | func_80032A74 | None | WALL-PROVED | 422 | near | 1 | T4b HAND PASS S84 (2026-09-06, Fable Max): PROVED at 1 by producer census. Residual = ONE reload-time slot at sp+0x48 (the u16 lhu draft is 422/422 with DIFF 22 = frame rows only; the s16 lh draft is DIFF 1 at idx 244 with the frame exact). The four post-parameter slot producers (reload1.c:658 ghost alter_reg / caller-save.c:249 area / reload1.c:879 invalid-equiv address / reload1.c:3499 spill_stack_slot) each refuted on the bytes: the site loads lhu and the function has no lb and no double load (combine newi2pat ghosts re-derive a narrow load); no register-only insn shares a block with a call (no sched.c:4962 staleness, so no save area without sw/lw); no unallocated single-block equiv pseudo; $t0 holds no pseudo (else $t1 would be the spill reg) and LO mult results retry into GR_REGS. NEW mechanism measured: optimize_reg_copy_2 ghosts (tmp = x; tmp op= c; x = tmp) are minted AFTER regclass -> GR_REGS, allocated, vars=0 (P14). 18 isolated reproducers, 0 draft variants; cookbook §501-M; notes .run/P32/t4c/func_80032A74/NOTES.md | `.run/P32/t4/drafts/func_80032A74_tuclean.c` | | 2 | func_80039308 | None | FRAME+SCHED | 518 | near | 4 | T4b HAND PASS S84 (2026-09-06): PLATEAU at 4. Rows 412/415: Fable Y4 (direct *(s16*)(p+6)=arg1) is register-exact (lhu/sh $s7 = the spilled HImode parameter reloaded through the spill register) and natural; the residual is the frame: target [arg1 @0][8-byte no-traffic slot @8][cnt @0x10]. Producer census (§501-M/§501-O): cnt slot = spill_stack_slot[23] (cnt evicted from $s7, retry fails), so the phantom is an INITIAL-LOOP slot with no traffic — caller-save area dead (leaf), LO eviction lands after cnt (GR spilled first; products alternate to GR_REGS, C3), no unallocated single-block equiv pseudo ($t0 free at the k2 site), expand-time locals precede (Y1/Y3/Y4), all 13 lh single-use + no lb (no combine ghost). Rows 49/50: both preheader insns are move_movables hoists in body order (vol = b2*0x100 in the body); X2 measured 495 — a hoisted vbase needs §501-E steering to $s2 without the pin. Notes .run/P32/t4c/func_80039308/NOTES.md | `.run/P32/t5x/fable/func_80039308.c` | -| 3 | func_80185810 | None | SCHED | 489 | near | 13 | S83 Fable: 35 -> 13 at exact length; 3 of 4 windows closed (P_TAG bitfield OT link + integer add for the addu operand order; sched1 flush_pending_lists at the 33rd memory op explains the load order -> HI temps; hard-reg destinations are not birthing-boosted -> pins uu $4 / mode $5 / ot16 $6 give the LUID order; shf pin $3). Residual ONE cause idx 363-380: `cl &= 0xFFFF` is an unboosted 2nd set — the fence after p[7]/= is needed (else its two reads float to the block head, 43/51) yet it blocks sched2 fillers crossing into the tpage/code window. NEXT: a spelling in which cl is single-set (its high half cleared at birth: cl = *(u16*)... or the shift form) so no fence is needed, or the two cl reads consume a fresh single-set copy that combine cannot fold (nonzero_bits defeats a plain andi copy; try a subreg/HI-mode temp) | `.run/P32/t5x/fable/func_80185810.c` | -| 4 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | +| 3 | func_80062144 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | | diff --git a/docs/decision-log.md b/docs/decision-log.md index 0b5489a60..fc7d1b6f3 100644 --- a/docs/decision-log.md +++ b/docs/decision-log.md @@ -3373,3 +3373,30 @@ resumed, and the one that had written its draft first (func_800391D4) banked fro compiler-internals class is cheaper than another Opus wave on the same rows (9/12 vs 0/12), and Opus is the right tier once a sibling's recipe exists (§501-H → the md_MAIN_007 pair). No second round this session (Drew); the three NEAR rows carry their next lever in the backlog. + +## P32 S85 (2026-09-06) — T4b hand pass row (d): the last overlay stub falls to a sibling the atlas had scored 0.55 + +### Context and belief +Four rows were left after the S83 Fable pass; S84 settled three (one PROVED, one BANKED by a sibling port, one PLATEAU). Row (d) +`ov_SC03_105:func_80185810` (489 ins, DIFF 13) carried a report that had read its residual's mechanism from the dumps — the +unboosted 2nd set behind a needed fence — and judged every honest fix blocked by combine. The checkpoint's step 0 was the §501-N +sibling search; the twin oracle, the family maps and the atlas's own knn entry for the row all said "nothing". + +### What happened +A grep for the idiom's constant (`'0x200) << 2'`, the libgpu getTPage chain) across `src/` listed `ov_SC02_027:func_80180B3C` +— which the atlas had recorded only as a reverse 0.55 "weak cousin" — and its objdump window was the target's rows 362–386 +instruction for instruction. Porting its window spelling matched in the real TU on the first draft, then with every pin removed: +zero pins, zero fences, zero asm dials, BANKED `commit:4004`, ov_SC03_105 100% C. A 12-variant census then measured which spelling +elements carry the window (the fresh single-set masks, the branch polarity, the early unpinned shift) and refuted the S83 guess +that a hard-register pin was what kept the `andi` alive (§501-P). + +### Why (measurement-grounded) +The similarity metrics score REGISTER-RENAMED same-shape functions as strangers (base registers s0/s2/s1 vs t0/t1/t2 change most +of the instruction words); the idiom's literal constants do not change. The draft's "blocked" verdict was correct about the +mechanism and wrong about the cause: the block's other 2-set births (the `uu -= …` pair, the polarity) were what made the +fence necessary. + +### Hindsight path +Step 0 of every hand pass and every wave card for a packet-building function: grep `src/` for the idiom constants and objdump the +hits' windows against the target BEFORE the first dial — the whole crack was one grep, one port and 25 minutes, after ~1M tokens +of dial work on the draft. Remaining open: the two main rows with their verdicts (PROVED 1, PLATEAU 4), carried into the PhaseEnd. diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index e27d2d8ce..2d13f74f2 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -37476,3 +37476,33 @@ the product is LO-homed with an input reload or slot-homed with a deleted output whose traffic-free pseudo is a product cannot be excluded by the bytes alone — only by allocation (alternate class `GR_REGS` always saves a product); (3) rows 49/50 are two `move_movables` hoists in BODY order — the original computed `vol = b2 * 0x100` in the loop; steering the hoisted invariant into `$s2` without the `$18` pin (X2 = 495) is the open lever (§501-E launders). + +**§501-P — THE ATLAS'S "WEAK COUSIN" WAS THE SAME-SHAPE SIBLING; a ported natural spelling needs NO pins and NO fence, and the +census shows WHICH spelling elements carry a scheduling window (P32 T4b hand pass, S85 2026-09-06; `ov_SC03_105:func_80185810` +489/489 BANKED `commit:4004` — the phase's last overlay stub; zero pins, zero fences, zero asm bodies).** The S83 Fable draft sat at +DIFF 13 (rows 363–380, the tpage/code RMW window) after 3,360 region-2 variants, five register pins, HI temps and a zero-byte +fence; its report had correctly read the residual's mechanism (an unboosted 2nd set `cl &= 0xFFFF` whose anti-dependences hold +the w-chain's reads; the fence releases them but forbids sched2's fillers) and concluded the honest fix was blocked by combine. +**The §501-N step 0 found the answer in 25 minutes:** the atlas lists `ov_SC02_027:func_80180B3C` as a 0.55 knn cousin — a +"weak" score — yet a shape grep on the idiom's constants (`grep -rln '0x200) << 2' src` = the libgpu getTPage bit chain) shows it +is the SAME billboard-sprite drawer (POLY_FT4 off the `D_800A5E60` bump, `code = 0x2C; code |= 2`, the tpage chain, `code |= +(w & 0x40) >> 6`, the u/v loads, the v0 conditional, the P_TAG link), and its COMPILED window (`objdump -d build/src/ov_SC02_027/ +ov_SC02_027_jr_8017D898.o` 0x34f8–0x3560) is instruction-for-instruction the target's rows 362–386 with only the base registers +renamed. Porting its window spelling onto the draft matched first try WITH the cousin's three pins, and then with none. **The +element census (12 real-TU variants, `.run/P32/t4d/NOTES.md`):** (a) the v mask is a FRESH single-set copy `vm = cl & 0xFFFF` +whose consumers are the two arms of the v0 conditional — a lone insn is never simplified by combine and the `lhu` setting `cl` has +intermediate uses, so the `andi` survives WITHOUT a hard-register pin (d5: the `$7` pin removed, MATCH — the S83 "hard reg hides +nonzero_bits" guess is refuted as the mechanism); being single-set it is birthing-boosted, so nothing is starved and no fence is +needed; (b) `u = (uu - ((tpage & 0xF) << 6)) << shift` as a fresh single-set value — the 2-set `uu -= …; uu <<= …` form re-rolls +63 rows, moving allocations 100+ rows away (d12); (c) the branch polarity `if (!(tpage & 0x10)) vv = vm; else vv = vm - 0x100;` +— the copy arm is the fall-through that coalesces to nothing, leaving `beqz → skip; addiu $a3,-0x100`; the opposite polarity +re-rolls 42 rows (d11), which is what the S83 F2 variant (59) actually measured; (d) `shift = 2 - mode` born early and unpinned — +the boost sinks it to rows 370/372; (e) the OT base computed right after the code byte, before the u/v loads. With every birth in +the window single-set, sched1's boost ties them all and the LUID tie-break yields source order, so the S83 window-1 `ot16` pin is +load-bearing ONLY in the mixed form (d3: DIFF 4 with 2-set neighbours; d9: MATCH with none). **Laws:** (1) the atlas's knn score +is NOT a shape oracle — a 0.55 "weak cousin" can be the exact sibling when the register bases differ; step 0 of every hand pass +greps the idiom's CONSTANTS across `src/` (`0x200) << 2`, `0xE1000000`, `+ 0x100) << 6`…) and reads the sibling's OBJDUMP window +against the target before touching the draft (§501-N, accelerators (13)/(14)); (2) a pin or a fence that a draft "needs" is a +property of the draft's other dials — after a sibling port, remove every pin and re-measure before banking (§501-E), and record the +census so the next row inherits the elements, not the dials; (3) a residual's mechanism read from the dumps can be right and its +"blocked" verdict wrong: the block's OTHER births (2-set `uu`, the polarity) were what made the honest fix look blocked. diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index c7b9b71c2..0d8ff933b 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -99,7 +99,7 @@ Scale estimate: 3–5 sessions. `func_80011380` → `.run/m3/opus/func_80011380.c`; `func_801834A4` → `.run/S71_gate14/ov_SC03_105*/`), `exclude_audit --write`, `backlog.py render`; a T3 idiom naming a wall's mechanism re-opens that row (bounded: one attempt, permuter first). Wall table into this file; cookbook §496+; decision log; accelerators. -- [~] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive; supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish")** — **FIRST PASS COMPLETE 2026-09-05 (S83): 11 of 15 BANKED byte-identical, 4 carried to the NEXT session's HAND pass (Drew: no second agent round; hand-crack the remaining ones).** Hand pass first (22 spellings, 0 banks, every blocker refined to a mechanism in `.run/P32/t4b//NOTES.md`), then one Fable agent per row (permission, not requirement — Drew), resumed 3-at-a-time through three usage-limit outages. Banked (each: coordinator `rtu_match` in the CURRENT real TU → `gate_main` / `bank.sh` byte-identical → one commit; pins dropped by `exclude_audit --write`; mechanism in cookbook §501–§501-L): `main:func_800391D4` `commit:3956` · `main:func_80039DEC` `commit:3959` · `md_MAIN_009:func_800CD674` `commit:3964` · `ov_SC06_022:func_8017DF28` `commit:3966` · `main:func_80020DA4` `commit:3969` · `ov_SC03_105:func_801834A4` `commit:3972` · `md_MAIN_003:func_800CF3E8` `commit:3976` · `md_MAIN_009:func_800CD92C` `commit:3979` · `ov_SC07_002:func_8017DC80` `commit:3983` · `main:func_80011380` `commit:3990` (the §474 "PROVED" wall) · `md_MAIN_007:func_800CF6D0` `commit:3992`. Ten of the eleven were T4 "walls" or long-standing NEARs. **HAND PASS S84 (2026-09-06, Fable Max, no agents): row (a) `main:func_80032A74` → PROVED at 1 (§501-M producer census: the 0x48 slot can only be a combine-minted ghost, which needs an `lh`/`lb`; the pin stays with its final verdict; ledger + `tools/ghost_census.py` + `cc1_dumps.sh` repair; row (b) `md_MAIN_007:func_800CF408` → **BANKED byte-identical `commit:4001`** (the banked sibling func_800CD92C's spelling ported with a u32 array alias of the OT symbol, §501-N; zero pins/asm); row (c) `main:func_80039308` → PLATEAU at 4 (S84 verdict, §501-O: the phantom slot's producer census refutes every route; Y4 is register-exact); row (d) NEXT).** Carried (4, all exact length, in `docs/backlog.md` with next levers): `main:func_80032A74` 1 (the last pin; ghost pseudo — near-proved) · `md_MAIN_007:func_800CF408` 3 · `main:func_80039308` 4 · `ov_SC03_105:func_80185810` 13. Close: fleet R22 **218 passed / 0 failed, exits 0/0/0** (23:33–23:36 MDT, `.run/P32/t4b/r22_full.log`); `make report`: instr 13,486,890 / 13,488,497 = 100.0% · distinct 5,814,982 / 5,816,589 = 100.0% (90,982 / 90,984 unique) · fn-count 363,210 / 363,214 = 100.00% · **INCLUDE_ASM 4**; main REAL 787 · LINKED 1,256 · VERBATIM 3 · stubs 2 · 2,089 / 2,091 = 99.90% · `143dbb89…`; census `.run/P32/frontier_t4b_close.json` 4 stubs / 1,607 ins; decision-log P32 S83 T4b (R31); accelerators (10)–(11); tools-health OK (`.run/P32/t4b/tools_health.log`). +- [~] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive; supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish")** — **FIRST PASS COMPLETE 2026-09-05 (S83): 11 of 15 BANKED byte-identical, 4 carried to the NEXT session's HAND pass (Drew: no second agent round; hand-crack the remaining ones).** Hand pass first (22 spellings, 0 banks, every blocker refined to a mechanism in `.run/P32/t4b//NOTES.md`), then one Fable agent per row (permission, not requirement — Drew), resumed 3-at-a-time through three usage-limit outages. Banked (each: coordinator `rtu_match` in the CURRENT real TU → `gate_main` / `bank.sh` byte-identical → one commit; pins dropped by `exclude_audit --write`; mechanism in cookbook §501–§501-L): `main:func_800391D4` `commit:3956` · `main:func_80039DEC` `commit:3959` · `md_MAIN_009:func_800CD674` `commit:3964` · `ov_SC06_022:func_8017DF28` `commit:3966` · `main:func_80020DA4` `commit:3969` · `ov_SC03_105:func_801834A4` `commit:3972` · `md_MAIN_003:func_800CF3E8` `commit:3976` · `md_MAIN_009:func_800CD92C` `commit:3979` · `ov_SC07_002:func_8017DC80` `commit:3983` · `main:func_80011380` `commit:3990` (the §474 "PROVED" wall) · `md_MAIN_007:func_800CF6D0` `commit:3992`. Ten of the eleven were T4 "walls" or long-standing NEARs. **HAND PASS S84 (2026-09-06, Fable Max, no agents): row (a) `main:func_80032A74` → PROVED at 1 (§501-M producer census: the 0x48 slot can only be a combine-minted ghost, which needs an `lh`/`lb`; the pin stays with its final verdict; ledger + `tools/ghost_census.py` + `cc1_dumps.sh` repair; row (b) `md_MAIN_007:func_800CF408` → **BANKED byte-identical `commit:4001`** (the banked sibling func_800CD92C's spelling ported with a u32 array alias of the OT symbol, §501-N; zero pins/asm); row (c) `main:func_80039308` → PLATEAU at 4 (S84 verdict, §501-O: the phantom slot's producer census refutes every route; Y4 is register-exact); **row (d) `ov_SC03_105:func_80185810` → BANKED byte-identical `commit:4004` (S85, 2026-09-06): the banked same-shape cousin `ov_SC02_027:func_80180B3C`'s packet-window spelling ported — ZERO pins, zero fences, zero asm dials (§501-P); ov_SC03_105 100% C).** T4b hand pass COMPLETE: 13 of 15 banked, 2 verdicts (PROVED 1 · PLATEAU 4), both in main. Carried (4, all exact length, in `docs/backlog.md` with next levers): `main:func_80032A74` 1 (the last pin; ghost pseudo — near-proved) · `md_MAIN_007:func_800CF408` 3 · `main:func_80039308` 4 · `ov_SC03_105:func_80185810` 13. Close: fleet R22 **218 passed / 0 failed, exits 0/0/0** (23:33–23:36 MDT, `.run/P32/t4b/r22_full.log`); `make report`: instr 13,486,890 / 13,488,497 = 100.0% · distinct 5,814,982 / 5,816,589 = 100.0% (90,982 / 90,984 unique) · fn-count 363,210 / 363,214 = 100.00% · **INCLUDE_ASM 4**; main REAL 787 · LINKED 1,256 · VERBATIM 3 · stubs 2 · 2,089 / 2,091 = 99.90% · `143dbb89…`; census `.run/P32/frontier_t4b_close.json` 4 stubs / 1,607 ins; decision-log P32 S83 T4b (R31); accelerators (10)–(11); tools-health OK (`.run/P32/t4b/tools_health.log`). - [ ] **T5 — PhaseEnd** (Max, Tier 1 — prompt R27): P7 checkbox walk; milestone demo (R22 fleet N/N, tools-health, `verbatim_check --strict`, final census, wall ledger, parked-5 dispositions via `make audit-disc`, `make report` all three metrics + main `143dbb89…` with/without SDK dirs, corrected denominators); **WAIT @@ -135,6 +135,7 @@ cookbook before the next drafting step (R16/R30) · no `Co-Authored-By` trailer needed for T0–T2b; if T2d needs it: `tools/ghidra_mcp_start.sh` → pause → Drew runs `/mcp` (R29) → G2 ping. ## Log +- 2026-09-06 (S85, session 3a7e207c, Max, Fable 5.1, no agents) — **T4b hand pass, row (d) `ov_SC03_105:func_80185810` BANKED byte-identical (`commit:4004`: bank.sh — rtu MATCH 489/489 in the real TU, splice, `make build BINARY=ov_SC03_105 -j8` rc 0, sha `d305ff6d…` == `config/check.ov_SC03_105.sha`).** Preflight: tree clean, `verbatim_check --strict` 5==5, `make check-all` 218 passed / 0 failed EXIT=0 (`.run/P32/t4d/check_all_preflight.log`); the Fable draft re-verified DIFF 13 (rows 363–380). §501-N step 0: twin oracle 0, atlas knn nothing (only a REVERSE 0.55 "weak cousin" entry), symbol grep = this overlay only; the SHAPE grep (`'0x200) << 2'`, the getTPage chain) surfaced `ov_SC02_027:func_80180B3C` — the same billboard drawer, banked — whose objdump window (0x34f8–0x3560) is the target's rows 362–386 verbatim. Its window spelling ported onto the draft (`.run/P32/t4d/d1_sibport.c`) → MATCH first try; the pin census (d2–d12, all real-TU): mode/cl/c40/uu pins individually and jointly removable, `ot16` pin load-bearing ONLY next to 2-set neighbours (DIFF 4), **d9 with NO pins = MATCH → banked**; F2's polarity re-rolls 42 rows, a 2-set `uu` 63 rows (the S83 "combine folds the fresh andi via nonzero_bits / a hard reg hides it" reading refuted — the andi survives as a lone single-set insn). Post-bank: `twin_rescan` 2 open / 0 newly free; `verbatim_check --strict` 5==5; `backlog.py render` 3 open (row pruned); census `.run/P32/frontier_t4b_final.json` **2 stubs / 940 ins** (main `func_80039308` 4 · `func_80032A74` 1). Harvest: cookbook **§501-P** (+ index regen), accelerators (14), decision-log P32 S85 (R31), `.run/P32/t4d/NOTES.md` (the 12-variant census). Fleet R22 launched after the bank (`.run/P32/t4d/r22_*.log`) — see the T4b close entry. **T4b hand pass COMPLETE: 13/15 banked + 2 final verdicts. NEXT = the T4b close, then T5.** - 2026-09-06 (S84, continued) — **T4b hand pass, row (c) `main:func_80039308` → PLATEAU at 4 (verdict).** Producer census for the target's phantom slot `[arg1 @0][8 @8][cnt @0x10]` (§501-O): cnt's slot is `spill_stack_slot[23]` (cnt evicted from `$s7`, `.greg` "Register 95 now on stack"), so the phantom is an initial-loop slot with no traffic; every producer refuted on dump facts (leaf → no save area; LO spilled after GR; products alternate to GR_REGS — C3 measured `mflo $a1/$v1`; no unallocated single-block equiv pseudo; expand-time locals precede; all 13 `lh` single-use, no `lb`). Rows 49/50 = two `move_movables` hoists in body order (open: steer the hoisted `b2 * 0x100` into `$s2` without the pin). Ledger row updated (closeness 4, FRAME+SCHED), NOTES `.run/P32/t4c/func_80039308/NOTES.md`, probe `c3_twoprod.c`. **Row (d) `ov_SC03_105:func_80185810` (13) read (report + rtu DIFF 13 re-verified) — NOT started; per §501-N its step 0 is a banked-sibling search on its symbol set (`D_800A5E60`, `D_801BC9B4/BC`, `D_801BA6B0`, `D_800AF630`, `D_800A6610`).** Session paused here at Drew's request (87% context). - 2026-09-06 (S84, continued) — **T4b hand pass, row (b) `md_MAIN_007:func_800CF408` BANKED byte-identical (`commit:4001`: bank.sh — rtu MATCH 178/178 in the real TU, splice, `make build BINARY=md_MAIN_007 -j8` rc 0, sha `2ff702b6…` == `config/check.md_MAIN_007.sha`).** The Fable draft's 3-row prologue-weave residual (§501-L) was a shape symptom: the same-family banked sibling `md_MAIN_009:func_800CD92C` (§501-H) had matched with the plain libgpu addPrim shape; porting it with this function's constants matched first try (`b0d_sibport_alias.c`). The TU declares `extern u8 D_800AA60C[]`, which kills the sibling's `u32` ARRAY_REF (the form whose address `memory_address → force_reg` lets cse bind the OT base into `$t2`; every `u8` respelling emits the `$at` macro form ×8) — solved with the fleet's asm-label alias `extern u32 wD_800AA60C[] __asm__("D_800AA60C");` (1,438 banked files carry the pattern; a declaration, not an asm body). Measured and refuted on the way: the sibling's lever-7 trailing volatile asm 2-set dial (flips `$t1/$t0`), the struct-view and P_TAG-on-`u8` forms. Post-bank: `twin_rescan` 3 open / 0 newly free; `verbatim_check --strict` 5==5; backlog rendered 4 open (the row pruned). Harvest: cookbook **§501-N**, accelerators (13), NOTES `.run/P32/t4c/func_800CF408/NOTES.md` (7 variants). bank.sh's `Claude-Session` trailer now comes from `$CLAUDE_SESSION` (was S83's id hard-coded). NEXT = row (c) `main:func_80039308` (4). - 2026-09-06 (S84, session 72d8b4b1, Max, Fable 5.1) — **T4b hand pass, row (a) `main:func_80032A74` CLOSED: PROVED at 1 (verdict, not a bank).** Preflight: tree clean, `verbatim_check --strict` 5==5, `make check-all` 218 passed / 0 failed rc 0 (`.run/P32/t4c/check_all_preflight.log`). Re-verified in the real TU (`rtu_match … --tu src/800_b_2.c --asm-subdir asm/nonmatchings/800_b_2`): the `s16 u18` draft DIFF 1 (idx 244 `lh` vs `lhu`, frame exact); the `u16 u18` TU-clean variant DIFF 22 = the 22 frame rows only (422/422 code). The residual is ONE reload-time slot at sp+0x48. Instead of a spelling sweep, enumerated every post-parameter stack-slot producer from the 2.7.2 source (reload1.c:658 ghost `alter_reg` · caller-save.c:249 area · reload1.c:879 invalid-equiv address · reload1.c:3499 `spill_stack_slot`) and refuted each on the bytes/dumps: combine's `newi2pat` ghosts re-derive a narrow load (`lh`/`lb`) and the site is `lhu` with no `lb`/double load; a save area without `sw/lw` needs sched.c:4962 staleness and no register-only insn shares a block with any of the 7 calls; unallocated single-block equiv pseudos cannot exist; `$t0` holds no pseudo (`order_regs_for_reload`) and LO mult results retry into `GR_REGS`. Found and measured a NEW ghost producer — `local-alloc.c optimize_reg_copy_2` on `tmp = x; tmp op= c; x = tmp;` (P13 refs 5, P14 refs 1) — which cannot slot because it is minted after regclass (class `GR_REGS`, no conflicts → allocated, vars=0). 18 isolated reproducers, 0 draft variants. Deliverables: cookbook **§501-M**, `tools/ghost_census.py` (new) + `tools/cc1_dumps.sh` (repaired: frame line + census, the under-counting `(use)` grep gone) + SETUP rows (R21), accelerators (12), backlog row (WALL-PROVED) + `tools/backlog.py` tie-break repair (kept the EARLIEST record at equal closeness — the S84 row never rendered), `config/wave_exclude.txt` annotated (`exclude_audit --assert-fresh` 1/1), notes `.run/P32/t4c/func_80032A74/NOTES.md`. NEXT = row (b) `md_MAIN_007:func_800CF408` (3).