mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
feat(decomp): bank 9 main functions, including main itself and the 670-ins giant
BANKED 9 of 28 after bisection, 143dbb89 BYTE-IDENTICAL. Verified from the SOURCE (every stub gone), not from the gate's own count. main 509 ins the game's entry point func_800226C0 670 ins the largest function in the project func_800215F4 465 func_800623A4 36 · func_80062434 36 · func_8005D410 42 func_8005D4B8 14 · func_8005D4F0 18 · StopRCnt 13 Reached by iterating the gate and dropping the compile-conflict culprit it named each round: func_8005E79C, func_8005E3AC, func_8005EAE8, func_8001FC08. Each of those is a §376/§378 declaration conflict, not a bad body — they go to the recovery chain, not the bin. Several were only reachable because of this session's oracle fixes: the 800c3 functions had been recorded as §182/§188 epilogue walls by an oracle modelling maspsx + as -O1 for a TU the Makefile builds through reorder_passthrough + as -O2. func_800226C0 came from the §476 finding that a hard-register pin strips nonzero_bits and reg_n_sets==1.
This commit is contained in:
@@ -12126,7 +12126,441 @@ void func_80021284(s32 arg0)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800", func_800215F4);
|
||||
|
||||
/* ---- PsyQ GTE inline macros (same spelling as the matched src/800.c blocks) ---- */
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
|
||||
#define gte_ldv3(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_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
|
||||
#define gte_stszotz(r0) __asm__ volatile ( \
|
||||
"mfc2 $12, $19;" \
|
||||
"nop;" \
|
||||
"sra $12, $12, 2;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
|
||||
typedef struct {
|
||||
s16 vx, vy, vz, pad;
|
||||
} SV_215F4; /* 8 */
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 unk00;
|
||||
/* 0x04 */ u32 unk04;
|
||||
/* 0x08 */ u8 pad08[6];
|
||||
/* 0x0E */ s16 unk0E;
|
||||
/* 0x10 */ u8 pad10[14];
|
||||
/* 0x1E */ s16 unk1E;
|
||||
/* 0x20 */ u8 *unk20;
|
||||
/* 0x24 */ u8 pad24[8];
|
||||
/* 0x2C */ u16 unk2C;
|
||||
/* 0x2E */ u16 unk2E;
|
||||
/* 0x30 */ u16 unk30;
|
||||
/* 0x32 */ u16 unk32;
|
||||
/* 0x34 */ s32 unk34;
|
||||
} Obj_215F4;
|
||||
|
||||
extern u8 D_800A6610[];
|
||||
extern u16 D_800B9A02;
|
||||
|
||||
/* func_8001E094 / func_8001E378 are DEFINED in src/800.c (file-scope decls at
|
||||
* 10238/10239, bodies at 10453/10588) with these exact prototypes -- do not
|
||||
* narrow them (cookbook 376/378). The target's missing `move $a0,$s1` before
|
||||
* the E094 call is cse_insn deleting the argument copy in the FALL-THROUGH arm
|
||||
* (a0 still equals the parameter); the else arm is a fresh basic block, so its
|
||||
* copy survives.
|
||||
*
|
||||
* func_800226C0 MUST stay unprototyped here: src/800.c already carries a
|
||||
* file-scope `extern void func_800226C0(Obj_80021D38 *, u8 *, DVec_80021D38 *,
|
||||
* u8 *)` at 12214, i.e. AFTER this function's slot at 12129, so a prototyped
|
||||
* decl of our own would be a conflicting-types build error. An unspecified
|
||||
* parameter list is compatible with both that decl and the `extern void
|
||||
* func_800226C0()` at 12556, and it is codegen-identical here (all four
|
||||
* arguments are pointers, unaffected by the default argument promotions).
|
||||
* func_80023138's spelling below is verbatim from its definition at 12688. */
|
||||
extern void func_8001E094(s32 arg0);
|
||||
extern void func_8001E378(s32 param_1);
|
||||
extern void func_800226C0();
|
||||
extern void func_80023138(s32 *arg0, u8 *col, u8 *pts, u32 *ot);
|
||||
|
||||
void func_800215F4(Obj_215F4 *obj)
|
||||
{
|
||||
SV_215F4 v[4]; /* 0x10 */
|
||||
s32 xy[36]; /* 0x30 */
|
||||
s32 flag; /* 0xC0 */
|
||||
s32 otz; /* 0xC4 */
|
||||
s32 flag2; /* 0xC8 */
|
||||
|
||||
u32 *ot;
|
||||
u8 *vp;
|
||||
/* pinned to the registers the target itself allocates (cookbook 179-F / 347) */
|
||||
register s32 i __asm__("$8"); /* $t0 loop counter, every loop */
|
||||
register u8 *q __asm__("$7"); /* $a3 loop1/3 walked ptr */
|
||||
register s32 o1 __asm__("$9"); /* $t1 */
|
||||
register s32 o2 __asm__("$10"); /* $t2 */
|
||||
register s32 d1 __asm__("$11"); /* $t3 */
|
||||
register s32 d2 __asm__("$12"); /* $t4 */
|
||||
register s32 d3 __asm__("$13"); /* $t5 */
|
||||
register u8 *xb __asm__("$14"); /* $t6 */
|
||||
register SV_215F4 *pv1 __asm__("$25");
|
||||
register SV_215F4 *pv2 __asm__("$24");
|
||||
register SV_215F4 *pv3 __asm__("$15");
|
||||
register u16 bx __asm__("$5");
|
||||
register u16 by __asm__("$4");
|
||||
register u16 bz __asm__("$6");
|
||||
register u8 *rs __asm__("$3");
|
||||
/* loop2 */
|
||||
register SV_215F4 *pw1 __asm__("$13");
|
||||
register u8 *xb2 __asm__("$11");
|
||||
register s32 *pf __asm__("$10");
|
||||
register s32 *dzp __asm__("$9");
|
||||
register s32 e __asm__("$7");
|
||||
register u8 *rw __asm__("$6");
|
||||
/* The three clamp sites: `x & 0xFFF` is computed SEPARATELY IN EACH ARM,
|
||||
* never hoisted above the `== 0xC000` test. reorg then merges the two
|
||||
* identical copies into the bne's delay slot -- which is the only way the
|
||||
* andi can reuse the $v0 that held the 0xC000 compare constant (a hoisted
|
||||
* copy is born BEFORE the bne, so it overlaps the constant and has to take
|
||||
* a third register). In the two inner loops the temp additionally has to
|
||||
* be PINNED off c2: fill_slots_from_thread rejects a delay-slot candidate
|
||||
* that sets a resource the opposite arm still reads, so an in-place
|
||||
* `andi $a0,$a0,0xFFF` over c2's own $a0 blocks the merge and costs +2.
|
||||
* `oz` likewise stops the otz load coalescing into dz's pinned $v1. */
|
||||
/* loop4 */
|
||||
register SV_215F4 *pw4 __asm__("$11");
|
||||
register u8 *xb4 __asm__("$10");
|
||||
/* loopC */
|
||||
register SV_215F4 *pa1 __asm__("$24");
|
||||
register SV_215F4 *pa2 __asm__("$15");
|
||||
register SV_215F4 *pa3 __asm__("$14");
|
||||
register u8 *xbc __asm__("$13");
|
||||
register s32 dc3 __asm__("$12");
|
||||
register s32 oc2 __asm__("$11");
|
||||
register s32 oc1 __asm__("$10");
|
||||
register u8 *qc __asm__("$9");
|
||||
register u32 dm __asm__("$2");
|
||||
register s32 oz __asm__("$2");
|
||||
u16 qx;
|
||||
u32 k;
|
||||
register s32 *pd __asm__("$4");
|
||||
register s32 dz __asm__("$3");
|
||||
register u32 c2 __asm__("$4");
|
||||
s32 *pz;
|
||||
u32 t, c;
|
||||
|
||||
ot = (u32 *)(D_800B9A02 * 0x4000 + (u32)D_800A6610);
|
||||
vp = obj->unk20;
|
||||
if (obj->unk34 != 0) {
|
||||
func_8001E094((s32)obj);
|
||||
} else {
|
||||
func_8001E378((s32)obj);
|
||||
}
|
||||
|
||||
if (obj->unk04 & 0x100) {
|
||||
v[2].vx = 0x10;
|
||||
v[3].vx = -0x10;
|
||||
v[1].vy = -0x13;
|
||||
v[3].vy = 8;
|
||||
v[2].vy = 8;
|
||||
v[1].vx = 0;
|
||||
v[3].vz = 0;
|
||||
v[2].vz = 0;
|
||||
v[1].vz = 0;
|
||||
gte_ldv3(&v[1], &v[2], &v[3]);
|
||||
gte_rtpt();
|
||||
gte_stflg(&flag);
|
||||
if (flag & ~0x1000) {
|
||||
return;
|
||||
}
|
||||
gte_nclip();
|
||||
gte_stopz(&otz);
|
||||
if (otz <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
v[0].vx = obj->unk2E;
|
||||
v[0].vy = obj->unk30;
|
||||
v[0].vz = obj->unk32;
|
||||
gte_ldv0(&v[0]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&xy[0]);
|
||||
gte_stflg(&flag);
|
||||
gte_stszotz(&otz);
|
||||
if (flag & ~0x1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
t = otz + 1;
|
||||
c = obj->unk2C;
|
||||
if (c & 0xC000) {
|
||||
if ((c & 0xC000) == 0xC000) {
|
||||
t -= c & 0xFFF;
|
||||
if ((s32)t < 0) {
|
||||
t = 0;
|
||||
}
|
||||
} else {
|
||||
t += c & 0xFFF;
|
||||
}
|
||||
}
|
||||
if (t < 0x1000) {
|
||||
i = 0;
|
||||
if ((obj->unk1E & 0x8000) || obj->unk0E != 0) {
|
||||
pv1 = &v[1];
|
||||
pv2 = &v[2];
|
||||
pv3 = &v[3];
|
||||
xb = (u8 *)xy;
|
||||
d3 = 0x14;
|
||||
d2 = 0xC;
|
||||
d1 = 4;
|
||||
o2 = 0x10;
|
||||
o1 = 8;
|
||||
q = vp;
|
||||
do {
|
||||
bx = v[0].vx;
|
||||
qx = *(u16 *)(q + 0x10);
|
||||
bz = v[0].vz;
|
||||
by = v[0].vy;
|
||||
v[1].vx = bx + qx;
|
||||
v[1].vy = by + *(u16 *)(q + 0x12);
|
||||
v[1].vz = bz;
|
||||
rs = vp + o1;
|
||||
v[2].vx = bx + *(u16 *)(rs + 0x10);
|
||||
v[2].vy = by + *(u16 *)(rs + 0x12);
|
||||
v[2].vz = bz;
|
||||
rs = vp + o2;
|
||||
v[3].vx = bx + *(u16 *)(rs + 0x10);
|
||||
v[3].vy = by + *(u16 *)(rs + 0x12);
|
||||
v[3].vz = bz;
|
||||
gte_ldv3(pv1, pv2, pv3);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(xb + d1, xb + d2, xb + d3);
|
||||
d3 += 0x18;
|
||||
d2 += 0x18;
|
||||
d1 += 0x18;
|
||||
o2 += 0x18;
|
||||
o1 += 0x18;
|
||||
i += 6;
|
||||
q += 0x18;
|
||||
} while (i < 12);
|
||||
|
||||
i = 1;
|
||||
pw1 = &v[1];
|
||||
xb2 = (u8 *)xy;
|
||||
pf = &flag2;
|
||||
dzp = &xy[13];
|
||||
e = 8;
|
||||
rw = vp + 4;
|
||||
do {
|
||||
v[1].vx = v[0].vx + *(u16 *)(rw + 0x10);
|
||||
v[1].vy = v[0].vy + *(u16 *)(rw + 0x12);
|
||||
v[1].vz = v[0].vz;
|
||||
gte_ldv0(pw1);
|
||||
gte_rtps();
|
||||
gte_stsxy(xb2 + e);
|
||||
gte_stflg(pf);
|
||||
pz = &otz;
|
||||
gte_stszotz(pz);
|
||||
oz = otz;
|
||||
dz = oz + 1;
|
||||
c2 = obj->unk2C;
|
||||
if (c2 & 0xC000) {
|
||||
k = 0xC000;
|
||||
if ((c2 & 0xC000) == k) {
|
||||
dm = c2 & 0xFFF;
|
||||
dz -= dm;
|
||||
if (dz < 1) {
|
||||
dz = 0;
|
||||
}
|
||||
} else {
|
||||
dm = c2 & 0xFFF;
|
||||
dz += dm;
|
||||
}
|
||||
}
|
||||
if (dz >= 0x1000) {
|
||||
k = 0xFFF;
|
||||
dz = k;
|
||||
}
|
||||
pz = &dzp[i >> 1];
|
||||
*pz = dz;
|
||||
e += 8;
|
||||
i += 2;
|
||||
rw += 8;
|
||||
} while (i < 12);
|
||||
|
||||
if (obj->unk0E != 0) {
|
||||
i = 0;
|
||||
pv1 = &v[1];
|
||||
pv2 = &v[2];
|
||||
pv3 = &v[3];
|
||||
xb = (u8 *)xy;
|
||||
d3 = 0x5C;
|
||||
d2 = 0x54;
|
||||
d1 = 0x4C;
|
||||
o2 = 0x10;
|
||||
o1 = 8;
|
||||
q = vp;
|
||||
v[0].vz = v[0].vz + obj->unk0E;
|
||||
do {
|
||||
bx = v[0].vx;
|
||||
qx = *(u16 *)(q + 0x10);
|
||||
bz = v[0].vz;
|
||||
by = v[0].vy;
|
||||
v[1].vx = bx + qx;
|
||||
v[1].vy = by + *(u16 *)(q + 0x12);
|
||||
v[1].vz = bz;
|
||||
rs = vp + o1;
|
||||
v[2].vx = bx + *(u16 *)(rs + 0x10);
|
||||
v[2].vy = by + *(u16 *)(rs + 0x12);
|
||||
v[2].vz = bz;
|
||||
rs = vp + o2;
|
||||
v[3].vx = bx + *(u16 *)(rs + 0x10);
|
||||
v[3].vy = by + *(u16 *)(rs + 0x12);
|
||||
v[3].vz = bz;
|
||||
gte_ldv3(pv1, pv2, pv3);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(xb + d1, xb + d2, xb + d3);
|
||||
d3 += 0x18;
|
||||
d2 += 0x18;
|
||||
d1 += 0x18;
|
||||
o2 += 0x18;
|
||||
o1 += 0x18;
|
||||
i += 6;
|
||||
q += 0x18;
|
||||
} while (i < 12);
|
||||
|
||||
i = 1;
|
||||
pw4 = &v[1];
|
||||
xb4 = (u8 *)xy;
|
||||
dzp = &xy[13];
|
||||
e = 0x50;
|
||||
rw = vp + 4;
|
||||
do {
|
||||
v[1].vx = v[0].vx + *(u16 *)(rw + 0x10);
|
||||
v[1].vy = v[0].vy + *(u16 *)(rw + 0x12);
|
||||
v[1].vz = v[0].vz;
|
||||
gte_ldv0(pw4);
|
||||
gte_rtps();
|
||||
gte_stsxy(xb4 + e);
|
||||
pz = &flag2;
|
||||
gte_stflg(pz);
|
||||
pz = &otz;
|
||||
gte_stszotz(pz);
|
||||
oz = otz;
|
||||
dz = oz + 1;
|
||||
c2 = obj->unk2C;
|
||||
if (c2 & 0xC000) {
|
||||
k = 0xC000;
|
||||
if ((c2 & 0xC000) == k) {
|
||||
dm = c2 & 0xFFF;
|
||||
dz -= dm;
|
||||
if (dz < 1) {
|
||||
dz = 0;
|
||||
}
|
||||
} else {
|
||||
dm = c2 & 0xFFF;
|
||||
dz += dm;
|
||||
}
|
||||
}
|
||||
if (dz >= 0x1000) {
|
||||
k = 0xFFF;
|
||||
dz = k;
|
||||
}
|
||||
pd = &dzp[i >> 1];
|
||||
if (dz < *pd) {
|
||||
*pd = dz;
|
||||
}
|
||||
e += 8;
|
||||
i += 2;
|
||||
rw += 8;
|
||||
} while (i < 12);
|
||||
func_80023138((s32 *)obj, vp, (u8 *)xy, ot);
|
||||
} else {
|
||||
func_800226C0((s32 *)obj, vp, (u8 *)xy, ot);
|
||||
}
|
||||
} else {
|
||||
pa1 = &v[1];
|
||||
pa2 = &v[2];
|
||||
pa3 = &v[3];
|
||||
xbc = (u8 *)xy;
|
||||
dc3 = 0xC;
|
||||
oc2 = 8;
|
||||
oc1 = 4;
|
||||
qc = vp;
|
||||
do {
|
||||
bx = v[0].vx;
|
||||
qx = *(u16 *)(qc + 0x10);
|
||||
bz = v[0].vz;
|
||||
by = v[0].vy;
|
||||
v[1].vx = bx + qx;
|
||||
v[1].vy = by + *(u16 *)(qc + 0x12);
|
||||
v[1].vz = bz;
|
||||
rs = vp + oc1;
|
||||
v[2].vx = bx + *(u16 *)(rs + 0x10);
|
||||
v[2].vy = by + *(u16 *)(rs + 0x12);
|
||||
v[2].vz = bz;
|
||||
rs = vp + oc2;
|
||||
v[3].vx = bx + *(u16 *)(rs + 0x10);
|
||||
v[3].vy = by + *(u16 *)(rs + 0x12);
|
||||
v[3].vz = bz;
|
||||
gte_ldv3(pa1, pa2, pa3);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(xbc + oc1, xbc + oc2, xbc + dc3);
|
||||
dc3 += 0xC;
|
||||
oc2 += 0xC;
|
||||
oc1 += 0xC;
|
||||
i += 3;
|
||||
qc += 0xC;
|
||||
} while (i < 12);
|
||||
func_800226C0((s32 *)obj, vp, (u8 *)xy, ot + t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* func_80021D38 — main / src/800.c — 284 ins. Splat marks it "Handwritten
|
||||
* function" only because of the cop2 opcodes: it is ordinary gcc-2.7.2 -O2 C
|
||||
@@ -12680,7 +13114,464 @@ void func_800221A8(Obj221A8 *o) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800", func_800226C0);
|
||||
/* func_800226C0 (main, src/800.c) — emit the 12-segment POLY_G4 strip for one Obj_80021D38
|
||||
* (plus the E1 draw-mode prims around it) into the D_800A5E60 bump allocator.
|
||||
*
|
||||
* Levers that closed it (S76y, from the S75 pinned draft at closeness 545 -> MATCH):
|
||||
* - `t` is ONE plain `s16` local, read UNINITIALISED at the top (`sll $v0,$s2,16; beqz` =
|
||||
* an HImode pseudo whose nonzero-bits are unknown before its set) and later assigned from
|
||||
* the s32 `tt`; the `addu $v0,$s2,$zero; beqz $v0; addu $t2,$v0,$zero` chain at 228E4 is
|
||||
* the sign-extension of that HImode pseudo folded to a copy (combine get_last_value) and
|
||||
* then reused by cse2 for the loop's hoisted multiplier -- a pinned $18 can never do it
|
||||
* (hard regs have no nonzero-bits). `mul` must stay an unpinned pseudo (global alloc never
|
||||
* coalesces a pseudo copy; a $10 pin swallows the $v0 temp).
|
||||
* - `o`, `col`, `sh23`, `abr` unpinned: gcc's own param copies give the prologue order and the
|
||||
* t/flags callee-saved order (density tie); the `or $v0,$v1,$v0` tie needs `abr` as a pseudo.
|
||||
* - The !useIdx single-prim block at 850 is the inline addPrim form with block-local temps:
|
||||
* a pinned `$a1` mask has reg_n_sets != 1 -> no birthing boost -> placed first in the block.
|
||||
* Symbols: only D_800A5E60 (14 %hi/%lo pairs in the .s) -- verified against the relocations.
|
||||
* The two struct typedefs are copies of src/800.c:12191-12209 for the standalone compile; the
|
||||
* harvest strips them (cdecl.typedef_names above the splice point).
|
||||
*/
|
||||
|
||||
|
||||
extern u8 *D_800A5E60;
|
||||
|
||||
void func_800226C0(Obj_80021D38 *arg0, u8 *col, DVec_80021D38 *pts, u8 *ot)
|
||||
{
|
||||
s16 t;
|
||||
s16 work[24];
|
||||
u32 flags;
|
||||
u16 f16;
|
||||
s32 tt;
|
||||
s32 uu;
|
||||
s32 tsh;
|
||||
u32 sh23;
|
||||
|
||||
u8 *p;
|
||||
u8 *s;
|
||||
u8 *w;
|
||||
u8 *e;
|
||||
s32 k;
|
||||
s32 m;
|
||||
s32 h;
|
||||
u32 x;
|
||||
u32 y;
|
||||
register u32 useIdx __asm__("$25");
|
||||
register u8 code __asm__("$24");
|
||||
register s32 i __asm__("$11");
|
||||
register s32 shadow __asm__("$17");
|
||||
register s32 *zp __asm__("$4");
|
||||
|
||||
f16 = *(u16 *)((u8 *)arg0 + 0x1E);
|
||||
flags = arg0->flags;
|
||||
useIdx = f16 & 0x8000;
|
||||
shadow = 0;
|
||||
if (flags & 0x800000) {
|
||||
p = D_800A5E60;
|
||||
shadow = 1;
|
||||
if (useIdx) {
|
||||
if (t) {
|
||||
register u8 *q __asm__("$5");
|
||||
register u32 e1 __asm__("$13");
|
||||
register u8 one __asm__("$14");
|
||||
register u32 maskAddr __asm__("$10");
|
||||
register u32 maskLen __asm__("$12");
|
||||
|
||||
D_800A5E60 = p + 0x60;
|
||||
i = 0;
|
||||
one = 1;
|
||||
e1 = 0xE1000000;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
q = p + 4;
|
||||
do {
|
||||
h = i >> 1;
|
||||
i++;
|
||||
zp = (s32 *)((h << 2) + (u32)((u8 *)pts));
|
||||
q[-1] = one;
|
||||
*(u32 *)q = e1;
|
||||
q += 8;
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zp[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zp[13]] = (((u32 *)ot)[zp[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
p += 8;
|
||||
} while (i < 12);
|
||||
} else {
|
||||
register u8 *q __asm__("$10");
|
||||
register s32 *zq __asm__("$5");
|
||||
register u32 e1 __asm__("$14");
|
||||
register u8 one __asm__("$15");
|
||||
register u32 maskAddr __asm__("$12");
|
||||
register u32 maskLen __asm__("$13");
|
||||
|
||||
D_800A5E60 = p + 0x30;
|
||||
i = 0;
|
||||
one = 1;
|
||||
e1 = 0xE1000000;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
q = p + 4;
|
||||
zq = (s32 *)((u8 *)pts);
|
||||
do {
|
||||
i++;
|
||||
q[-1] = one;
|
||||
*(u32 *)q = e1;
|
||||
q += 8;
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zq[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zq[13]] = (((u32 *)ot)[zq[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
zq = (s32 *)((u8 *)zq + 4);
|
||||
p += 8;
|
||||
} while (i < 6);
|
||||
}
|
||||
} else {
|
||||
D_800A5E60 = p + 8;
|
||||
p[3] = 1;
|
||||
*(u32 *)(p + 4) = 0xE1000000;
|
||||
*(u32 *)p = (*(u32 *)p & 0xFF000000) | (((u32 *)ot)[0] & 0x00FFFFFF);
|
||||
((u32 *)ot)[0] = (((u32 *)ot)[0] & 0xFF000000) | ((u32)p & 0x00FFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
f16 = *(u16 *)((u8 *)arg0 + 0x1E);
|
||||
p = D_800A5E60;
|
||||
tt = f16 & 0x1FFF;
|
||||
t = tt;
|
||||
D_800A5E60 = tt ? p + 0x1B0 : p + 0xD8;
|
||||
code = (flags & 0x40000000) ? 0x3A : 0x38;
|
||||
|
||||
if (t) {
|
||||
{
|
||||
s32 mul;
|
||||
register s16 *dst __asm__("$5");
|
||||
register s16 *src __asm__("$4");
|
||||
|
||||
i = 0;
|
||||
mul = t;
|
||||
dst = work;
|
||||
src = (s16 *)((u8 *)pts);
|
||||
do {
|
||||
*dst = *(s16 *)((u8 *)pts) + (((src[2] - *(s16 *)((u8 *)pts)) * mul) >> 12);
|
||||
dst[1] = *(s16 *)(((u8 *)pts) + 2) + (((src[3] - *(s16 *)(((u8 *)pts) + 2)) * mul) >> 12);
|
||||
i++;
|
||||
src += 2;
|
||||
dst += 2;
|
||||
} while (i < 12);
|
||||
}
|
||||
{
|
||||
register u32 maskAddr __asm__("$12");
|
||||
register u32 maskLen __asm__("$15");
|
||||
register s32 kk __asm__("$14");
|
||||
register u8 *ww __asm__("$13");
|
||||
register u8 *ss __asm__("$10");
|
||||
register u8 *d __asm__("$5");
|
||||
|
||||
i = 0;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
d = p + 0x22;
|
||||
kk = 4;
|
||||
ww = (u8 *)work;
|
||||
ss = ((u8 *)pts);
|
||||
do {
|
||||
d[-0x1F] = 8;
|
||||
d[-0x1B] = code;
|
||||
d[-0x1E] = col[4];
|
||||
d[-0x1D] = col[5];
|
||||
d[-0x1C] = col[6];
|
||||
d[-0x16] = col[4];
|
||||
d[-0x15] = col[5];
|
||||
d[-0x14] = col[6];
|
||||
d[-0x0E] = col[0];
|
||||
d[-0x0D] = col[1];
|
||||
d[-0x0C] = col[2];
|
||||
d[-0x06] = col[0];
|
||||
d[-0x05] = col[1];
|
||||
d[-0x04] = col[2];
|
||||
*(u16 *)(d - 0x1A) = *(u16 *)(ss + 4);
|
||||
*(u16 *)(d - 0x18) = *(u16 *)(ss + 6);
|
||||
*(u16 *)(d - 0x12) = *(u16 *)(ss + 8);
|
||||
*(u16 *)(d - 0x10) = *(u16 *)(ss + 0xA);
|
||||
*(u16 *)(d - 0x0A) = *(u16 *)(ww);
|
||||
*(u16 *)(d - 0x08) = *(u16 *)(ww + 2);
|
||||
e = (u8 *)work + kk;
|
||||
*(u16 *)(d - 0x02) = *(u16 *)e;
|
||||
*(u16 *)(d) = *(u16 *)(e + 2);
|
||||
if (useIdx) {
|
||||
h = i >> 1;
|
||||
zp = (s32 *)((h << 2) + (u32)((u8 *)pts));
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zp[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zp[13]] = (((u32 *)ot)[zp[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
} else {
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[0];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[0] = (((u32 *)ot)[0] & maskLen) | ((u32)p & maskAddr);
|
||||
}
|
||||
kk += 4;
|
||||
ww += 4;
|
||||
ss += 4;
|
||||
i++;
|
||||
d += 0x24;
|
||||
p += 0x24;
|
||||
} while (i < 12);
|
||||
}
|
||||
|
||||
*(u16 *)(p - 0x14) = *(u16 *)(((u8 *)pts) + 4);
|
||||
*(u16 *)(p - 0x12) = *(u16 *)(((u8 *)pts) + 6);
|
||||
*(u16 *)(p - 0x04) = *(u16 *)work;
|
||||
*(u16 *)(p - 0x02) = *(u16 *)((u8 *)work + 2);
|
||||
|
||||
if (*(u16 *)((u8 *)arg0 + 0x1E) & 0x4000) {
|
||||
register u32 maskAddr __asm__("$10");
|
||||
register u32 maskLen __asm__("$15");
|
||||
register s32 mm __asm__("$14");
|
||||
register s32 kk __asm__("$13");
|
||||
register u8 *ww __asm__("$12");
|
||||
register u8 *d __asm__("$5");
|
||||
|
||||
i = 0;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
mm = 8;
|
||||
kk = 4;
|
||||
p = D_800A5E60;
|
||||
ww = (u8 *)work;
|
||||
d = p + 0x22;
|
||||
D_800A5E60 = p + 0xD8;
|
||||
do {
|
||||
d[-0x1F] = 8;
|
||||
d[-0x1B] = code;
|
||||
d[-0x1E] = col[0x0C];
|
||||
d[-0x1D] = col[0x0D];
|
||||
d[-0x1C] = col[0x0E];
|
||||
d[-0x16] = col[0x0C];
|
||||
d[-0x15] = col[0x0D];
|
||||
d[-0x14] = col[0x0E];
|
||||
d[-0x0E] = col[0x08];
|
||||
d[-0x0D] = col[0x09];
|
||||
d[-0x0C] = col[0x0A];
|
||||
d[-0x06] = col[0x0C];
|
||||
d[-0x05] = col[0x0D];
|
||||
d[-0x04] = col[0x0E];
|
||||
*(u16 *)(d - 0x1A) = *(u16 *)(ww);
|
||||
*(u16 *)(d - 0x18) = *(u16 *)(ww + 2);
|
||||
e = (u8 *)work + kk;
|
||||
*(u16 *)(d - 0x12) = *(u16 *)e;
|
||||
*(u16 *)(d - 0x10) = *(u16 *)(e + 2);
|
||||
*(u16 *)(d - 0x0A) = *(u16 *)(((u8 *)pts));
|
||||
*(u16 *)(d - 0x08) = *(u16 *)(((u8 *)pts) + 2);
|
||||
e = (u8 *)work + mm;
|
||||
*(u16 *)(d - 0x02) = *(u16 *)e;
|
||||
*(u16 *)(d) = *(u16 *)(e + 2);
|
||||
if (useIdx) {
|
||||
h = i >> 1;
|
||||
zp = (s32 *)((h << 2) + (u32)work);
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zp[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zp[13]] = (((u32 *)ot)[zp[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
} else {
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[0];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[0] = (((u32 *)ot)[0] & maskLen) | ((u32)p & maskAddr);
|
||||
}
|
||||
mm += 8;
|
||||
kk += 8;
|
||||
ww += 8;
|
||||
i += 2;
|
||||
d += 0x24;
|
||||
p += 0x24;
|
||||
} while (i < 12);
|
||||
|
||||
*(u16 *)(p - 0x04) = *(u16 *)work;
|
||||
*(u16 *)(p - 0x02) = *(u16 *)((u8 *)work + 2);
|
||||
}
|
||||
} else {
|
||||
register u32 maskAddr __asm__("$12");
|
||||
register u32 maskLen __asm__("$13");
|
||||
register u8 *ss __asm__("$10");
|
||||
register u8 *d __asm__("$5");
|
||||
|
||||
i = 1;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
d = p + 0x22;
|
||||
ss = ((u8 *)pts) + 4;
|
||||
do {
|
||||
d[-0x1F] = 8;
|
||||
d[-0x1B] = code;
|
||||
d[-0x1E] = col[4];
|
||||
d[-0x1D] = col[5];
|
||||
d[-0x1C] = col[6];
|
||||
d[-0x16] = col[4];
|
||||
d[-0x15] = col[5];
|
||||
d[-0x14] = col[6];
|
||||
d[-0x0E] = col[0];
|
||||
d[-0x0D] = col[1];
|
||||
d[-0x0C] = col[2];
|
||||
d[-0x06] = col[4];
|
||||
d[-0x05] = col[5];
|
||||
d[-0x04] = col[6];
|
||||
*(u16 *)(d - 0x1A) = *(u16 *)(ss);
|
||||
*(u16 *)(d - 0x18) = *(u16 *)(ss + 2);
|
||||
*(u16 *)(d - 0x12) = *(u16 *)(ss + 4);
|
||||
*(u16 *)(d - 0x10) = *(u16 *)(ss + 6);
|
||||
*(u16 *)(d - 0x0A) = *(u16 *)(((u8 *)pts));
|
||||
*(u16 *)(d - 0x08) = *(u16 *)(((u8 *)pts) + 2);
|
||||
*(u16 *)(d - 0x02) = *(u16 *)(ss + 8);
|
||||
*(u16 *)(d) = *(u16 *)(ss + 0x0A);
|
||||
if (useIdx) {
|
||||
h = i >> 1;
|
||||
zp = (s32 *)((h << 2) + (u32)((u8 *)pts));
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zp[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zp[13]] = (((u32 *)ot)[zp[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
} else {
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[0];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[0] = (((u32 *)ot)[0] & maskLen) | ((u32)p & maskAddr);
|
||||
}
|
||||
ss += 8;
|
||||
i += 2;
|
||||
d += 0x24;
|
||||
p += 0x24;
|
||||
} while (i < 13);
|
||||
|
||||
*(u16 *)(p - 0x04) = *(u16 *)(((u8 *)pts) + 4);
|
||||
*(u16 *)(p - 0x02) = *(u16 *)(((u8 *)pts) + 6);
|
||||
}
|
||||
|
||||
if (flags & 0x40000000) {
|
||||
u32 abr;
|
||||
|
||||
sh23 = flags >> 23;
|
||||
abr = sh23 & 0x60;
|
||||
if (useIdx) {
|
||||
i = 0;
|
||||
if (t) {
|
||||
register u8 *q __asm__("$5");
|
||||
u32 e1s;
|
||||
u32 e1n;
|
||||
register u8 one __asm__("$14");
|
||||
register u32 maskAddr __asm__("$9");
|
||||
register u32 maskLen __asm__("$10");
|
||||
|
||||
one = 1;
|
||||
e1s = abr | 0xE1000200;
|
||||
e1n = abr | 0xE1000000;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
q = p + 4;
|
||||
D_800A5E60 = D_800A5E60 + 0x60;
|
||||
do {
|
||||
q[-1] = one;
|
||||
if (shadow) {
|
||||
*(u32 *)q = e1s;
|
||||
} else {
|
||||
*(u32 *)q = e1n;
|
||||
}
|
||||
h = i >> 1;
|
||||
i++;
|
||||
zp = (s32 *)((h << 2) + (u32)((u8 *)pts));
|
||||
q += 8;
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zp[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zp[13]] = (((u32 *)ot)[zp[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
p += 8;
|
||||
} while (i < 12);
|
||||
} else {
|
||||
register u8 *q __asm__("$5");
|
||||
u32 e1s;
|
||||
u32 e1n;
|
||||
register u8 one __asm__("$14");
|
||||
register u32 maskAddr __asm__("$9");
|
||||
register u32 maskLen __asm__("$10");
|
||||
register s32 *zq __asm__("$6");
|
||||
|
||||
one = 1;
|
||||
e1s = abr | 0xE1000200;
|
||||
e1n = abr | 0xE1000000;
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
q = p + 4;
|
||||
D_800A5E60 = D_800A5E60 + 0x30;
|
||||
zq = (s32 *)((u8 *)pts);
|
||||
do {
|
||||
q[-1] = one;
|
||||
if (shadow) {
|
||||
*(u32 *)q = e1s;
|
||||
} else {
|
||||
*(u32 *)q = e1n;
|
||||
}
|
||||
i++;
|
||||
q += 8;
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[zq[13]];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[zq[13]] = (((u32 *)ot)[zq[13]] & maskLen) | ((u32)p & maskAddr);
|
||||
zq = (s32 *)((u8 *)zq + 4);
|
||||
p += 8;
|
||||
} while (i < 6);
|
||||
}
|
||||
} else {
|
||||
register u32 maskAddr __asm__("$4");
|
||||
register u32 maskLen __asm__("$5");
|
||||
|
||||
D_800A5E60 = D_800A5E60 + 8;
|
||||
p[3] = 1;
|
||||
*(u32 *)(p + 4) = abr | (shadow ? 0xE1000200 : 0xE1000000);
|
||||
maskAddr = 0x00FFFFFF;
|
||||
maskLen = 0xFF000000;
|
||||
x = *(u32 *)p;
|
||||
y = ((u32 *)ot)[0];
|
||||
x &= maskLen;
|
||||
y &= maskAddr;
|
||||
x |= y;
|
||||
*(u32 *)p = x;
|
||||
((u32 *)ot)[0] = (((u32 *)ot)[0] & maskLen) | ((u32)p & maskAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern u8 *D_800A5E60;
|
||||
|
||||
+41
-2
@@ -24,10 +24,49 @@ s32 func_80062394(void)
|
||||
return D_80072A24;
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c2_2", func_800623A4);
|
||||
extern void func_80062768(void);
|
||||
extern void func_8005CF08(void);
|
||||
extern void func_800626F0(void);
|
||||
extern void func_8005CF18(void);
|
||||
extern s32 ChangeClearPAD(s32 mode);
|
||||
extern void func_8006252C(void);
|
||||
extern s32 PAD_init2(s32, s32, s32, s32);
|
||||
extern s32 D_80072A24;
|
||||
|
||||
void func_800623A4(s32 a0, s32 a1, s32 a2, s32 a3)
|
||||
{
|
||||
func_80062768();
|
||||
func_8005CF08();
|
||||
func_800626F0();
|
||||
func_8005CF18();
|
||||
ChangeClearPAD(0);
|
||||
func_8006252C();
|
||||
PAD_init2(a0, a1, a2, a3);
|
||||
D_80072A24 = 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c2_2", func_80062434);
|
||||
|
||||
extern void func_80062768(void);
|
||||
extern void func_8005CF08(void);
|
||||
extern void func_800626F0(void);
|
||||
extern void func_8005CF18(void);
|
||||
extern s32 ChangeClearPAD(s32 mode);
|
||||
extern void func_8006252C(void);
|
||||
extern void InitPAD2(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern s32 D_80072A24;
|
||||
|
||||
void func_80062434(s32 a0, s32 a1, s32 a2, s32 a3)
|
||||
{
|
||||
func_80062768();
|
||||
func_8005CF08();
|
||||
func_800626F0();
|
||||
func_8005CF18();
|
||||
ChangeClearPAD(0);
|
||||
func_8006252C();
|
||||
InitPAD2(a0, a1, a2, a3);
|
||||
D_80072A24 = 1;
|
||||
}
|
||||
|
||||
extern void StartPAD2(void);
|
||||
extern s32 ChangeClearPAD(s32 mode);
|
||||
|
||||
+42
-4
@@ -299,7 +299,16 @@ s32 StartRCnt(s32 spec) {
|
||||
return t < 3;
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c3", StopRCnt);
|
||||
extern s32 D_80072934;
|
||||
extern s32 D_8007293C[];
|
||||
|
||||
s32 StopRCnt(s32 spec) {
|
||||
s32 t;
|
||||
|
||||
t = spec & 0xFFFF;
|
||||
*(s32 *)(D_80072934 + 4) &= ~D_8007293C[t];
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern u32 D_80072938;
|
||||
|
||||
@@ -427,11 +436,40 @@ extern void* (*D_80072970)(void);
|
||||
|
||||
extern void* (*D_80072970)(void);
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c3", func_8005D410);
|
||||
extern void* (*D_80072970)(void);
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c3", func_8005D4B8);
|
||||
s32 func_8005D410(s32 arg0, s32 arg1, s32 arg2) {
|
||||
u8 *p;
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c3", func_8005D4F0);
|
||||
p = (u8 *)(*D_80072970)();
|
||||
if (arg1 < 0) {
|
||||
return *(p + 0xEA);
|
||||
}
|
||||
if (arg1 >= *(p + 0xEA)) {
|
||||
return 0;
|
||||
}
|
||||
p = *(u8 **)(p + 8) + (arg1 << 3);
|
||||
if (arg2 < 0) {
|
||||
return *p;
|
||||
}
|
||||
if (arg2 >= *p) {
|
||||
return 0;
|
||||
}
|
||||
return *(*(u8 **)(p + 4) + arg2);
|
||||
}
|
||||
|
||||
extern void* (*D_80072970)(void);
|
||||
extern void func_8005E79C();
|
||||
|
||||
void func_8005D4B8(void *a0, void *a1) {
|
||||
func_8005E79C(D_80072970(), a1);
|
||||
}
|
||||
|
||||
extern void* (*D_80072970)(void);
|
||||
|
||||
void func_8005D4F0(s32 arg0, s32 arg1, s32 arg2) {
|
||||
func_8005E8E8(D_80072970(), (u8)arg1, (u8)arg2);
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/800c3", func_8005D538);
|
||||
|
||||
|
||||
+218
-1
@@ -175,7 +175,224 @@ __asm__(".text\n"
|
||||
".set\treorder\n"
|
||||
".end\t__do_global_dtors\n");
|
||||
|
||||
INCLUDE_ASM("asm/nonmatchings/boot", main);
|
||||
|
||||
extern u8 D_800BA118;
|
||||
extern u8 D_800AF630[];
|
||||
extern s32 D_80074778;
|
||||
extern s32 D_800A2B7C;
|
||||
extern s32 D_800C7C70;
|
||||
extern s16 D_800C7C74;
|
||||
extern s32 D_800A5E60;
|
||||
extern u8 D_8007BA70[];
|
||||
extern u8 D_800A4F48[];
|
||||
extern s32 D_800A651C;
|
||||
extern u8 D_800A6528[];
|
||||
extern u8 D_800A6610[];
|
||||
extern u8 D_800AA60C[];
|
||||
extern s32 D_800AE7BC;
|
||||
extern s32 D_800AE7C8;
|
||||
extern u8 D_800BA0D8[];
|
||||
extern u8 D_800BA0E4[];
|
||||
|
||||
extern void func_80043060(s32);
|
||||
extern void func_800141F0(void);
|
||||
extern void func_8005FC68(s32);
|
||||
extern void func_8005FCB8(void);
|
||||
extern void func_80018918(void);
|
||||
extern s32 func_80043300(void);
|
||||
extern void func_8002C8F4(void);
|
||||
extern void LoaderInitFileTable(void);
|
||||
extern void func_80014238(void);
|
||||
extern void func_80014390(void);
|
||||
extern void func_800191A8(void);
|
||||
extern void func_80010A98(void);
|
||||
extern void func_800189A8(void);
|
||||
extern void func_80015208(void);
|
||||
extern void func_80059BFC(s32, s32);
|
||||
extern void GameModeDispatch(void);
|
||||
extern void func_80015498(void);
|
||||
extern void func_8001C00C(void);
|
||||
extern void func_800D25FC(void);
|
||||
extern void func_800184F0(void);
|
||||
extern void func_800596F4(s32);
|
||||
extern s32 VSync(s32);
|
||||
extern void func_80059FC0(u8 *);
|
||||
extern void func_80059D68(u8 *);
|
||||
extern void CatPrim(s32, s32);
|
||||
extern s32 func_80059CF4(s32);
|
||||
extern void func_8003500C(void);
|
||||
extern void func_8002D034(void);
|
||||
extern void func_8001AF34(void);
|
||||
extern void func_8001513C(void);
|
||||
extern void func_80042610(void (*)(void));
|
||||
|
||||
struct MainSlot { s32 unk0; s32 unk4; s32 unk8; };
|
||||
|
||||
// @class: other
|
||||
// @stuck: none -- MATCH (509 ins, -O0 boot object).
|
||||
/*
|
||||
* main (0x80010178) -- the game's outer frame loop, compiled -O0 like the rest of
|
||||
* src/boot.c (frame-pointer prologue, every global re-loaded per use).
|
||||
*
|
||||
* The four gcc-2.7.2 -O0 levers this needed (all NEW, none were in the cookbook):
|
||||
*
|
||||
* 1. TWO `register` locals, in declaration order, hold the two bases the whole
|
||||
* function addresses through: $s0 = &D_800BA118 (loaded, NEVER used again --
|
||||
* it must still be declared or the lui/addiu pair and the $s0 save/restore
|
||||
* both vanish) and $s1 = D_800AF630. Same lever GameModeDispatch/func_8001099C
|
||||
* already use in this TU; the >0x7FFF member offsets then assemble to the
|
||||
* +0x10000/-0x5Cxx split.
|
||||
*
|
||||
* 2. `s32 pad[6];` -- 24 bytes of DECLARED-BUT-UNUSED stack. At -O0 gcc reserves a
|
||||
* slot for every local whether or not it is read, and the target's frame is
|
||||
* 0x38 (16 outgoing-arg + 24 vars + 16 saved). Without it the frame is 0x20 and
|
||||
* every sp offset in the prologue/epilogue is wrong. The original's six words
|
||||
* were presumably dead locals left in the source.
|
||||
*
|
||||
* 3. THE SHIFT-FORM MULTIPLY. Inside a MEMORY ADDRESS, `base + i * K` with a
|
||||
* CONSTANT K expands (expand_expr MULT under EXPAND_SUM) to a `(mult reg K)`
|
||||
* rtx that force_operand emits with the INDEX FIRST: `addu d,index,base`.
|
||||
* Writing the same value as `base + ((i * (K>>n)) << n)` materialises the index
|
||||
* into a plain register first, and the address then comes out BASE-first --
|
||||
* `addu $v0,$s1,$a0` / `addu $at,$at,$v0` + `%lo(sym)($at)` -- which is what the
|
||||
* target has. Measured: `p + i*12` -> `addu $4,$3,$2` (wrong), `p + ((i*3)<<2)`
|
||||
* -> `addu $4,$2,$3` (right). Only address context is affected; in VALUE context
|
||||
* (`(s32)(D_800A6610 + i*16384)`) the plain multiply already comes out base-first.
|
||||
*
|
||||
* 4. The three 12-byte-strided stores go through a struct pointer, not
|
||||
* `*(s32 *)(p + ... + 8)`: only a COMPONENT_REF folds the member offset into the
|
||||
* store (`sw $v1,0x8($v0)`); the pointer-arithmetic spelling materialises it as
|
||||
* a separate `addiu`.
|
||||
*
|
||||
* Two smaller ones: `(*(u16 *)(p + 0xA3A8))++` emits the extra `addu $v0,$v1,$zero`
|
||||
* that `+= 1` does not; and CatPrim's second argument is written
|
||||
* `<load> + D_80074778 * 4` (NOT `D_80074778 * 4 + <load>`) -- with a MEM as operand
|
||||
* 0 gcc emits the MEM's address first, then operand 1, then the load, and the addu
|
||||
* comes out operand-1-first, exactly the target's interleave.
|
||||
*
|
||||
* The two scratchpad-stack switches around func_80015498/func_8001C00C/func_800D25FC
|
||||
* are the §261 idiom: the $sp repointing is inline asm, the calls stay C (so -O0
|
||||
* supplies the `jal` + delay-slot nop). $a2 here, not the overlays' $v1.
|
||||
*/
|
||||
void main(void) {
|
||||
register u8 *q = &D_800BA118;
|
||||
register u8 *p = D_800AF630;
|
||||
s32 pad[6];
|
||||
|
||||
func_80043060(0);
|
||||
D_80074778 = 0x3E0;
|
||||
func_800141F0();
|
||||
func_8005FC68(0);
|
||||
func_8005FCB8();
|
||||
func_80018918();
|
||||
D_800A2B7C = func_80043300();
|
||||
func_8002C8F4();
|
||||
LoaderInitFileTable();
|
||||
|
||||
while (1) {
|
||||
func_80014238();
|
||||
func_80014390();
|
||||
func_800191A8();
|
||||
func_80010A98();
|
||||
|
||||
while (*(u16 *)(p + 0xA3D4) == 0) {
|
||||
D_800C7C70++;
|
||||
D_800C7C70 = D_800C7C70 ? D_800C7C70 : 1;
|
||||
D_800C7C74 = !D_800C7C74;
|
||||
*(u16 *)(p + 0xA3D2) = D_800C7C74;
|
||||
|
||||
D_800A5E60 = (s32)(D_8007BA70 + *(u16 *)(p + 0xA3D2) * 80000);
|
||||
((struct MainSlot *)(p + ((*(u16 *)(p + 0xA3D2) * 3) << 2)))->unk8 =
|
||||
(s32)(D_800A4F48 + *(u16 *)(p + 0xA3D2) * 1600);
|
||||
((struct MainSlot *)(p + ((*(u16 *)(p + 0xA3D2) * 3) << 2)))->unk0 = 0x640;
|
||||
((struct MainSlot *)(p + ((*(u16 *)(p + 0xA3D2) * 3) << 2)))->unk4 = 0;
|
||||
|
||||
func_800189A8();
|
||||
func_80015208();
|
||||
|
||||
if (*(u8 *)(p + 0xA3E3) == 0) {
|
||||
(*(u16 *)(p + 0xA3A8))++;
|
||||
*(u16 *)(p + 0xA3AC) += *(u16 *)(p + 0xA3A8);
|
||||
|
||||
*(s32 *)((u8 *)&D_800A651C + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) =
|
||||
(s32)(D_800A6610 + *(u16 *)(p + 0xA3D2) * 16384);
|
||||
*(s32 *)(D_800A6528 + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) =
|
||||
*(u16 *)(p + 0xA3D2) * 16384 + (s32)D_800AA60C;
|
||||
func_80059BFC(*(s32 *)((u8 *)&D_800A651C + ((*(u16 *)(p + 0xA3D2) * 5) << 2)), 0x1000);
|
||||
*(s32 *)((u8 *)&D_800AE7BC + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) =
|
||||
(s32)(D_800BA0D8 + *(u16 *)(p + 0xA3D2) * 16);
|
||||
*(s32 *)((u8 *)&D_800AE7C8 + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) =
|
||||
*(u16 *)(p + 0xA3D2) * 16 + (s32)D_800BA0E4;
|
||||
func_80059BFC(*(s32 *)((u8 *)&D_800AE7BC + ((*(u16 *)(p + 0xA3D2) * 5) << 2)), 4);
|
||||
GameModeDispatch();
|
||||
|
||||
__asm__ __volatile__(
|
||||
"lui $a2, 0x1f80\n"
|
||||
"ori $a2, $a2, 0x03fc\n"
|
||||
"addu $t0, $a2, $zero\n"
|
||||
"sw $sp, 0($t0)\n"
|
||||
"addiu $t0, $t0, -4\n"
|
||||
"addu $sp, $t0, $zero\n" : : : "memory");
|
||||
func_80015498();
|
||||
__asm__ __volatile__(
|
||||
"addiu $sp, $sp, 4\n"
|
||||
"lw $sp, 0($sp)\n" : : : "memory");
|
||||
|
||||
__asm__ __volatile__(
|
||||
"lui $a2, 0x1f80\n"
|
||||
"ori $a2, $a2, 0x03fc\n"
|
||||
"addu $t0, $a2, $zero\n"
|
||||
"sw $sp, 0($t0)\n"
|
||||
"addiu $t0, $t0, -4\n"
|
||||
"addu $sp, $t0, $zero\n" : : : "memory");
|
||||
func_8001C00C();
|
||||
__asm__ __volatile__(
|
||||
"addiu $sp, $sp, 4\n"
|
||||
"lw $sp, 0($sp)\n" : : : "memory");
|
||||
} else {
|
||||
*(s32 *)((u8 *)&D_800AE7BC + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) =
|
||||
(s32)(D_800BA0D8 + *(u16 *)(p + 0xA3D2) * 16);
|
||||
*(s32 *)((u8 *)&D_800AE7C8 + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) =
|
||||
*(u16 *)(p + 0xA3D2) * 16 + (s32)D_800BA0E4;
|
||||
func_80059BFC(*(s32 *)((u8 *)&D_800AE7BC + ((*(u16 *)(p + 0xA3D2) * 5) << 2)), 4);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"lui $a2, 0x1f80\n"
|
||||
"ori $a2, $a2, 0x03fc\n"
|
||||
"addu $t0, $a2, $zero\n"
|
||||
"sw $sp, 0($t0)\n"
|
||||
"addiu $t0, $t0, -4\n"
|
||||
"addu $sp, $t0, $zero\n" : : : "memory");
|
||||
func_800D25FC();
|
||||
__asm__ __volatile__(
|
||||
"addiu $sp, $sp, 4\n"
|
||||
"lw $sp, 0($sp)\n" : : : "memory");
|
||||
}
|
||||
|
||||
func_800184F0();
|
||||
func_800596F4(0);
|
||||
VSync(*(s32 *)(p + 0xA3E8));
|
||||
|
||||
*(u16 *)(p + 0x188) = *(u16 *)(p + 0x18A);
|
||||
(*(u16 *)(p + 0x18A))++;
|
||||
if (*(u16 *)(p + 0x18A) > 1) {
|
||||
*(u16 *)(p + 0x18A) = 0;
|
||||
}
|
||||
func_80059FC0(&p[*(u16 *)(p + 0x188) * 20 + 0x14C]);
|
||||
func_80059D68(&p[*(u16 *)(p + 0x18A) * 92 + 0x38]);
|
||||
|
||||
CatPrim(*(s32 *)((u8 *)&D_800A651C + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) + 0x3FF0,
|
||||
*(s32 *)((u8 *)&D_800A651C + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) + D_80074778 * 4);
|
||||
func_80059CF4(*(s32 *)((u8 *)&D_800A651C + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) + 0x3FFC);
|
||||
func_80059CF4(*(s32 *)((u8 *)&D_800AE7BC + ((*(u16 *)(p + 0xA3D2) * 5) << 2)) + 0xC);
|
||||
func_8003500C();
|
||||
func_8002D034();
|
||||
func_8001AF34();
|
||||
func_8001513C();
|
||||
}
|
||||
func_80042610(0);
|
||||
}
|
||||
}
|
||||
|
||||
void func_8001096C(void) {
|
||||
extern void func_8002CDD8(void);
|
||||
|
||||
Reference in New Issue
Block a user