docs(phase-32): T4b hand pass — row (d) harvest: cookbook §501-P (the atlas's 0.55 "weak cousin" was the same-shape sibling; its natural spelling ported with ZERO pins/fences; the 12-variant element census), accelerators (14), decision-log P32 S85, NOTES + 12 measured variants + rtu logs; backlog 3 open; census 2 stubs / 940 ins; T4b hand pass COMPLETE (13/15 banked + 2 verdicts)

- 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
This commit is contained in:
Drew T
2026-09-06 13:21:29 -06:00
parent cdd9a2cb8e
commit 0ab474ed5d
38 changed files with 5360 additions and 4 deletions
+9
View File
@@ -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
+44
View File
@@ -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"
}
]
+49
View File
@@ -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)
+48
View File
@@ -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/<variant>/` 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).
+356
View File
@@ -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;
}
+220
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
cookbook index -> docs/cookbook-index.md (1169 sections, 14 symptom buckets)
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+340
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+339
View File
@@ -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;
}
+111
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
clean: removed build/, expected/, and the regenerated splat tree (asm/, assets/, include macros, undefined_*_auto.txt).
EXIT=0
+254
View File
@@ -0,0 +1,254 @@
splat 0.41.0 (powered by spimdisasm 1.41.0)
0%| | 0/1096 [00:00<?, ?it/s]
Loading symbols (symbols.us): 0%| | 0/1096 [00:00<?, ?it/s]
Loading symbols (symbols.us): 100%|██████████| 1096/1096 [00:00<00:00, 227324.56it/s]
0%| | 0/47 [00:00<?, ?it/s]
Loading symbols (symbols.us.ram): 0%| | 0/47 [00:00<?, ?it/s]
Loading symbols (symbols.us.ram): 100%|██████████| 47/47 [00:00<00:00, 612212.07it/s]
0%| | 0/2 [00:00<?, ?it/s]
Scanning header: 0%| | 0/2 [00:00<?, ?it/s]
Scanning main: 0%| | 0/2 [00:00<?, ?it/s]
Rodata segment '800' may belong to the text segment '800'
Based on the usage from the function LzssDecodeSector to the symbol jtbl_80072A38
The rodata segment '800' has jumptables that are not aligned properly file-wise, indicating one or more likely file split.
File split suggestions for this segment will follow in config yaml format:
- [0x6324C, .rodata]
- [0x63388, .rodata]
- [0x633FC, .rodata]
Rodata segment '800_b' may belong to the text segment '800_b'
Based on the usage from the function func_8002B0B4 to the symbol jtbl_80072E44
Rodata segment '800_b_2' may belong to the text segment '800_b_2'
Based on the usage from the function func_8002DC68 to the symbol jtbl_80072F3C
The rodata segment '800_b_2' has jumptables that are not aligned properly file-wise, indicating one or more likely file split.
File split suggestions for this segment will follow in config yaml format:
- [0x63920, .rodata]
Rodata segment '800_c' may belong to the text segment '800_c'
Based on the usage from the function func_80035270 to the symbol jtbl_800732A0
Scanning main: 100%|██████████| 2/2 [00:01<00:00, 1.72it/s]
Scanning main: 100%|██████████| 2/2 [00:01<00:00, 1.72it/s]
0%| | 0/2 [00:00<?, ?it/s]
Splitting header: 0%| | 0/2 [00:00<?, ?it/s]
Splitting main: 0%| | 0/2 [00:00<?, ?it/s]
Splitting main: 100%|██████████| 2/2 [00:00<00:00, 2.75it/s]
Splitting main: 100%|██████████| 2/2 [00:00<00:00, 2.75it/s]
0%| | 0/2 [00:00<?, ?it/s]
Linker script header: 0%| | 0/2 [00:00<?, ?it/s]
Linker script main: 0%| | 0/2 [00:00<?, ?it/s]
Linker script main: 100%|██████████| 2/2 [00:00<00:00, 94.06it/s]
Split 340 KB (82.28%) in defined segments
header: 2 KB (0.50%) 1 split, 0 cached
c: 338 KB (81.78%) 85 split, 0 cached
unknown: 0 B (0.00%) from unknown bin files
ld_interleave --order: .main island = 8 pieces [53198.data.o, 800.o, 63470.data.o, 800_b.o, 800_b_2.o, 63940.data.o, 800_c.o, 63C4C.data.o]; pre=0 text=85 empties=166 bss=85
[ OK ] resident
[ OK ] ov_SC05_000
[ OK ] ov_SC01_000
[ OK ] ov_SC04_000
[ OK ] ov_SC06_000
[ OK ] ov_SC03_002
[ OK ] ov_SC01_005
[ OK ] ov_SC01_006
[ OK ] ov_SC01_077
[ OK ] ov_SC04_018
[ OK ] ov_SC02_000
[ OK ] ov_SC02_003
[ OK ] ov_SC04_019
[ OK ] ov_SC03_001
[ OK ] ov_SC03_006
[ OK ] ov_SC01_004
[ OK ] ov_SC01_001
[ OK ] ov_SC01_074
[ OK ] ov_SC01_008
[ OK ] ov_SC07_000
[ OK ] ov_SC02_004
[ OK ] ov_SC02_015
[ OK ] ov_SC02_021
[ OK ] ov_SC01_080
[ OK ] ov_SC01_009
[ OK ] ov_SC01_084
[ OK ] ov_SC02_016
[ OK ] ov_SC02_026
[ OK ] ov_SC02_005
[ OK ] ov_SC02_011
[ OK ] ov_SC02_039
[ OK ] ov_SC02_027
[ OK ] ov_SC02_028
[ OK ] ov_SC02_031
[ OK ] ov_SC02_035
[ OK ] ov_SC03_003
[ OK ] ov_SC02_017
[ OK ] ov_SC02_041
[ OK ] ov_SC03_012
[ OK ] ov_SC03_010
[ OK ] ov_SC03_011
[ OK ] ov_SC03_013
[ OK ] ov_SC03_023
[ OK ] ov_SC03_007
[ OK ] ov_SC03_024
[ OK ] ov_SC03_031
[ OK ] ov_SC03_014
[ OK ] ov_SC03_089
[ OK ] ov_SC03_015
[ OK ] ov_SC03_090
[ OK ] ov_SC03_092
[ OK ] ov_SC03_029
[ OK ] ov_SC03_030
[ OK ] ov_SC03_095
[ OK ] ov_SC03_091
[ OK ] ov_SC03_028
[ OK ] ov_SC03_096
[ OK ] ov_SC03_093
[ OK ] ov_SC03_094
[ OK ] ov_SC03_097
[ OK ] ov_SC03_101
[ OK ] ov_SC03_098
[ OK ] ov_SC03_109
[ OK ] ov_SC03_108
[ OK ] ov_SC03_099
[ OK ] ov_SC03_110
[ OK ] ov_SC03_102
[ OK ] ov_SC03_113
[ OK ] ov_SC03_100
[ OK ] ov_SC03_104
[ OK ] ov_SC03_103
[ OK ] ov_SC03_105
[ OK ] ov_SC03_112
[ OK ] ov_SC03_114
[ OK ] ov_SC03_111
[ OK ] ov_SC03_115
[ OK ] ov_SC03_116
[ OK ] ov_SC03_126
[ OK ] ov_SC04_008
[ OK ] ov_SC04_003
[ OK ] ov_SC04_009
[ OK ] ov_SC03_121
[ OK ] ov_SC03_117
[ OK ] ov_SC04_006
[ OK ] ov_SC03_118
[ OK ] ov_SC03_119
[ OK ] ov_SC04_004
[ OK ] ov_SC03_125
[ OK ] ov_SC04_007
[ OK ] ov_SC04_002
[ OK ] ov_SC04_005
[ OK ] ov_SC04_010
[ OK ] ov_SC03_124
[ OK ] ov_SC04_012
[ OK ] ov_SC04_021
[ OK ] ov_SC05_006
[ OK ] ov_SC04_016
[ OK ] ov_SC05_002
[ OK ] ov_SC05_007
[ OK ] ov_SC05_001
[ OK ] ov_SC05_004
[ OK ] ov_SC05_003
[ OK ] ov_SC05_009
[ OK ] ov_SC04_020
[ OK ] ov_SC04_015
[ OK ] ov_SC05_008
[ OK ] ov_SC05_005
[ OK ] ov_SC04_011
[ OK ] ov_SC05_010
[ OK ] ov_SC05_011
[ OK ] ov_SC05_019
[ OK ] ov_SC06_013
[ OK ] ov_SC06_015
[ OK ] ov_SC06_008
[ OK ] ov_SC06_014
[ OK ] ov_SC06_011
[ OK ] ov_SC06_010
[ OK ] ov_SC06_016
[ OK ] ov_SC05_017
[ OK ] ov_SC06_020
[ OK ] ov_SC05_018
[ OK ] ov_SC06_018
[ OK ] ov_SC06_027
[ OK ] ov_SC06_025
[ OK ] ov_SC06_006
[ OK ] ov_SC06_022
[ OK ] ov_SC06_024
[ OK ] ov_SC07_008
[ OK ] md_MAIN_013
[ OK ] md_MAIN_014
[ OK ] ov_SC07_002
[ OK ] md_MAIN_015
[ OK ] md_MAIN_016
[ OK ] ov_SC07_001
[ OK ] md_MAIN_017
[ OK ] md_MAIN_018
[ OK ] md_MAIN_019
[ OK ] ov_SC06_030
[ OK ] md_MAIN_020
[ OK ] md_MAIN_021
[ OK ] md_MAIN_022
[ OK ] md_MAIN_023
[ OK ] md_MAIN_024
[ OK ] md_MAIN_025
[ OK ] ov_SC07_009
[ OK ] md_MAIN_026
[ OK ] md_MAIN_027
[ OK ] md_MAIN_029
[ OK ] md_MAIN_028
[ OK ] ov_SC06_032
[ OK ] md_MAIN_030
[ OK ] md_MAIN_031
[ OK ] md_MAIN_032
[ OK ] ov_MAIN_012
[ OK ] md_MAIN_033
[ OK ] md_MAIN_035
[ OK ] ov_SC06_033
[ OK ] md_MAIN_034
[ OK ] ov_SC07_011
[ OK ] md_MAIN_037
[ OK ] md_MAIN_036
[ OK ] ov_SC06_029
[ OK ] md_MAIN_039
[ OK ] md_MAIN_038
[ OK ] md_MAIN_040
[ OK ] md_MAIN_041
[ OK ] md_MAIN_042
[ OK ] md_MAIN_043
[ OK ] md_MAIN_047
[ OK ] md_MAIN_045
[ OK ] md_MAIN_046
[ OK ] md_MAIN_044
[ OK ] md_MAIN_008
[ OK ] md_MAIN_001
[ OK ] md_MAIN_011
[ OK ] ov_SC07_010
[ OK ] ov_SC03_107
[ OK ] md_SC03_078
[ OK ] md_SC03_073
[ OK ] md_SC03_074
[ OK ] md_SC03_075
[ OK ] md_SC03_077
[ OK ] ov_SC07_007
[ OK ] md_SC03_133
[ OK ] md_SC03_132
[ OK ] md_SC03_076
[ OK ] md_SC03_079
[ OK ] md_SC03_134
[ OK ] md_SC03_137
[ OK ] md_SC03_135
[ OK ] md_SC04_025
[ OK ] md_SC03_136
[ OK ] md_SC04_029
[ OK ] md_SC04_024
[ OK ] md_SC04_026
[ OK ] md_SC03_138
[ OK ] md_SC04_028
[ OK ] md_MAIN_003
[ OK ] md_SC04_027
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+44
View File
@@ -0,0 +1,44 @@
DIFF func_80185810 mine=489 ins, target=489 ins, 42 mismatched
idx | MINE | TARGET
331 | 00132602 srl a0,s3,0x18 | 00132e02 srl $a1, $s3, 24
332 | 3c100000 lui s0,0x0 | 30a50003 andi $a1, $a1, 0x3
333 | 8e100000 lw s0,0(s0) | 3c10800a lui $s0, %hi(D_800A5E60)
334 | 30840003 andi a0,a0,0x3 | 8e105e60 lw $s0, %lo(D_800A5E60)($s0)
335 | 26020028 addiu v0,s0,40 | 000519c0 sll $v1, $a1, 7
336 | 3c010000 lui at,0x0 | 26020028 addiu $v0, $s0, 0x28
337 | ac220000 sw v0,0(at) | 3c01800a lui $at, %hi(D_800A5E60)
338 | 24020009 li v0,9 | ac225e60 sw $v0, %lo(D_800A5E60)($at)
339 | a2020003 sb v0,3(s0) | 24020009 addiu $v0, $zero, 0x9
340 | 2402002c li v0,44 | a2020003 sb $v0, 0x3($s0)
341 | a2020007 sb v0,7(s0) | 2402002c addiu $v0, $zero, 0x2C
342 | 3c010001 lui at,0x1 | a2020007 sb $v0, 0x7($s0)
343 | 02810821 addu at,s4,at | 3c010001 lui $at, (0x10000 >> 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)
+62
View File
@@ -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)
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+6
View File
@@ -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)
+6
View File
@@ -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)
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+1
View File
@@ -0,0 +1 @@
MATCH (489 ins) func_80185810
+11
View File
@@ -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).
+2 -3
View File
@@ -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) | |
+27
View File
@@ -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.
+30
View File
@@ -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.
+2 -1
View File
@@ -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/<fn>/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/<fn>/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).