feat(decomp): main lane m11b — 19 banked

One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  GS_001_OBJ_5D0
  GsInitGraph2
  GsTMDfastF4GNL
  Square0
  func_800168C4
  func_80018194
  func_8001A9F8
  func_8001CA88
  func_8001F97C
  func_8001FB8C
  func_800296F8
  func_80029D3C
  func_8002E79C
  func_8002EDE4
  func_8002F1CC
  func_80036F18
  func_8003775C
  func_800385C0
  func_80062644
This commit is contained in:
Drew T
2026-08-25 00:59:27 -06:00
parent 133c1d45a9
commit 5e2c15b454
5 changed files with 533 additions and 19 deletions
+303 -14
View File
@@ -2411,7 +2411,30 @@ void func_800168B4(void) {
D_800AF7CE = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_800168C4);
extern u8 D_800AF630[];
extern u16 D_800AF7CE;
extern s32 D_800B9A18;
extern u8 D_80062BA0[];
s32 func_800168C4(register s32 arg0) {
register s32 t __asm__("$3");
u8 *base = D_800AF630;
arg0 &= 3;
if (arg0 == 0) {
t = D_80062BA0[D_800B9A18];
} else {
t = D_80062BA0[arg0];
}
D_800AF7CE += t;
__asm__ __volatile__("" : : : "memory");
t = *(u16 *) (base + 0x19E);
if (t >= 0xFFU) {
return *(u16 *) (base + 0x188) != 0;
}
return 0;
}
extern u16 D_800AF7CE;
@@ -3882,7 +3905,26 @@ void func_80018094(void *a0, s32 a1, u32 a2_p) {
}
}
INCLUDE_ASM("asm/nonmatchings/800", func_80018194);
void func_80018194(void *arg0, s32 arg1, u32 arg2)
{
extern s32 AddPrim(s32, void *);
extern u16 D_800B9A02;
extern struct { s32 a; s32 b[4]; } D_800A651C[];
void *a3;
s32 sz;
a3 = arg0;
if (arg2 & 0x40000000) {
*(u32 *)((u8 *)a3 + 4) |= 0x02000000;
}
sz = arg1;
if ((u32)sz >= 0x1000) {
sz = 0xFFF;
}
AddPrim(D_800A651C[D_800B9A02].a + sz * 4, a3);
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001820C);
@@ -5477,7 +5519,26 @@ INCLUDE_ASM("asm/nonmatchings/800", CdReadSectorReadyCB);
INCLUDE_ASM("asm/nonmatchings/800", func_8001A9D8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001A9F8);
void func_8001A9F8(s32 a0)
{
extern u16 D_800B9A02;
extern u8 D_800A6610[];
extern u32 D_80063108;
extern u32 D_80063120;
u32 *p = (u32 *)(D_800A6610 + (D_800B9A02 << 14));
u32 *q1;
u32 *q2;
q1 = &D_80063108;
*q1 = (p[1] & 0xFFFFFF) | 0x5000000;
p[1] = (p[1] & 0xFF000000) | ((u32)q1 & 0xFFFFFF);
q2 = &D_80063120;
*q2 = (p[1] & 0xFFFFFF) | 0x5000000;
p[1] = (p[1] & 0xFF000000) | ((u32)q2 & 0xFFFFFF);
}
extern s32 cdReq_curSector;
s32 func_8001AA78(void) {
@@ -6700,7 +6761,31 @@ void func_8001CA1C(void *a0, void *a1)
*(s32 *)((s32)s0 + 0x20) = (s32)s2;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001CA88);
extern void func_8001C9D0(void);
extern void func_80052D90(s32 a0, void *a1);
extern void func_80054514(s32 a0, s32 a1);
void func_8001CA88(s32 a0, s32 a1)
{
s32 local_10[8];
s32 s0_val = a0;
s32 s2_val = a1;
s32 s1_val;
func_8001C9D0();
s1_val = s0_val + 0x30;
*(s16 *)s0_val = 1;
*(s16 *)(s0_val + 0x2) = 4;
func_80052D90(0, (void *)s1_val);
func_80054514(s1_val, (s32)&local_10[0]);
*(s32 *)(s0_val + 0x20) = s2_val;
*(s32 *)(s0_val + 0x74) = 0;
*(s16 *)(s0_val + 0xE) = 0;
*(s16 *)(s0_val + 0x1E) = 0;
}
extern void func_8001CF48(s32 a0);
@@ -7679,11 +7764,39 @@ void func_8001F730(s32 a0, void *a1, void *a2)
void func_8001F974(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001F97C);
void func_8001F97C(void *a0)
{
extern void func_80020F34(s32 a0, s32 a1);
s32 t1, t2, t3;
func_80020DA4((s32)((u8 *)a0 + 0x10), (s32)((u8 *)a0 + 0x34));
if (*(u16 *)((u8 *)a0 + 0x2C) & 0x10) {
func_80020F34((s32)((u8 *)a0 + 0x34), (s32)((u8 *)a0 + 0x18));
}
t1 = *(s16 *)((u8 *)a0 + 0x08);
t2 = *(s16 *)((u8 *)a0 + 0x0A);
t3 = *(s16 *)((u8 *)a0 + 0x0C);
*(s32 *)((u8 *)a0 + 0x48) = t1;
*(s32 *)((u8 *)a0 + 0x4C) = t2;
*(s32 *)((u8 *)a0 + 0x50) = t3;
*(u16 *)((u8 *)a0 + 0x2C) |= 1;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001F9F8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001FB8C);
extern void (*D_80063500[])();
void func_8001FB8C(s32 *a0, s32 *a1)
{
if (a0[1] < 0) return;
if (*(u16 *)a0 != 1) return;
if (*(u16 *)((u8 *)a0 + 2) < 9) {
D_80063500[*(u16 *)((u8 *)a0 + 2)](a0);
a1[0]++;
}
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001FC08);
@@ -11909,7 +12022,19 @@ void func_80029664(void) {
INCLUDE_ASM("asm/nonmatchings/800", func_80029690);
INCLUDE_ASM("asm/nonmatchings/800", func_800296F8);
typedef struct {
s32 w[9];
} Blk36_800296F8;
extern void func_80029774(s32);
extern Blk36_800296F8 D_80079204;
extern s32 D_800A5E5C;
s32 func_800296F8(s32 arg0) {
func_80029774(1);
D_80079204 = *(Blk36_800296F8 *)arg0;
return D_800A5E5C = 1;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80029774);
@@ -11954,7 +12079,33 @@ s32 func_80029CD4(s32 a0) {
return rand() % a0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80029D3C);
/* func_80029D3C — banked candidate, rounds 1-9.
* Canonical s32(void) def per engine_core.h caller macros; incoming $a0
* bridged via register pins ($4 -> $16) because the prototype takes no
* named parameters. Clamp MUST stay a ternary: an if/else spelling moves
* ret into $a0 and breaks the early-exit delay-slot chain (verified R9).
* Divisor 4800 forced by choose_multiplier arithmetic on M=0x1B4E81B5,l=9.
*/
extern s32 func_8002A4FC(s32 a0);
s32 func_80029D3C(void) {
register s32 n __asm__("$4");
register s32 s0 __asm__("$16");
s32 p;
s32 q;
s32 ret;
__asm__("" : "=r"(n));
s0 = n;
if (s0 <= 0) {
ret = 0;
} else {
p = func_8002A4FC(s0) * 60;
q = s0 - s0 * p / 4800;
ret = q > 0 ? q : 1;
}
return ret;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80029DB4);
@@ -13527,7 +13678,31 @@ void func_8002E700(s32 a0)
D_800A4E8A = D_8006A9B0[index];
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002E79C);
void func_8002E79C(s32 a0)
{
extern u8 D_800A4EE6;
extern u16 D_800A4EE0;
extern u16 D_800A4EE2;
extern u16 D_800A4EE4;
extern u16 D_8006A9C8[];
u8 *fl;
u16 v;
fl = &D_800A4EE6;
if (!(*fl & 2)) {
*fl |= 2;
if (!(*fl & 4)) {
v = (u16)a0;
if (v >= 5) {
v = 4;
}
D_800A4EE0 = 0x4000;
D_800A4EE4 = 0x2FFF;
D_800A4EE2 = D_8006A9C8[v];
*fl |= 3;
}
}
}
void func_8002E818(s32 a0)
{
@@ -13770,7 +13945,28 @@ void func_8002ED90(void) {
}
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002EDE4);
extern void func_8002EE90(void);
extern void func_80031CC8(void);
extern void func_8002EC10(void);
extern void func_800385C0(s16);
extern u16 D_800A4EA2;
extern s16 D_800A4E9A;
extern u8 D_800A4EE6;
extern s16 D_800A4EF6;
void func_8002EDE4(void) {
func_8002EE90();
func_80031CC8();
func_8002EC10();
if (D_800A4EA2 & 0x4) {
func_800385C0(D_800A4E9A);
D_800A4EA2 = 0;
}
D_800A4EF6 = 1;
D_800A4EE6 &= 0xF9;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002EE64);
@@ -13892,7 +14088,43 @@ void func_8002F12C(s32 a0) {
INCLUDE_ASM("asm/nonmatchings/800", func_8002F150);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F1CC);
typedef struct F1ccRec {
u8 pad[0x0E];
u8 flg[8];
u8 tail[0x3E];
} F1ccRec;
typedef struct F1ccSlot {
u8 pad[0x20];
u32 u20;
u32 u24;
u32 u28;
u32 u2C;
u16 u30;
u8 mid[5];
u8 u37;
u8 u38;
u8 tail[0x1B];
} F1ccSlot;
extern u8 D_800A4694[];
void func_8002F1CC(s32 arg0) {
F1ccRec *sp = (F1ccRec *)D_800A4694 + arg0;
F1ccSlot *slots = (F1ccSlot *)(D_800A4694 + 0x2F4);
s32 i;
s32 val;
for (i = 0, val = 0x18; i < 8; i++) {
if (sp->flg[i]) {
slots[i].u28 = slots[i].u20 + 0x100;
slots[i].u37 |= 1;
slots[i].u30 = 0;
slots[i].u38 = 0;
slots[i].u2C = val;
}
}
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002F248);
@@ -16651,7 +16883,24 @@ void func_80036EE8(void) {
D_800A4F1A = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80036F18);
extern s32 D_800C6D28;
extern s32 D_80078F10;
extern s32 D_800A63E8;
extern s32 D_8006AEE8;
extern void func_80034DFC(short);
void func_80036F18(void) {
s32 i;
if (D_8006AEE8 != 0) {
D_800C6D28 = D_800A63E8;
for (i = 0; i < D_8006AEE8; i++) {
func_80034DFC(*(short *)(&D_80078F10 + i));
(&D_80078F10)[i] = 0;
}
D_8006AEE8 = 0;
}
}
extern s32 D_80078F10;
extern s32 D_8006AEE8;
@@ -17024,7 +17273,29 @@ s32 func_8003750C(void) {
}
}
INCLUDE_ASM("asm/nonmatchings/800", func_8003775C);
typedef struct { u8 v; } W8_;
extern W8_ D_80076242_ __asm__("D_80076242");
extern u8 D_8006AEF4;
extern s32 func_8003C4F0(s32);
extern void func_800373D0(void);
int func_8003775C(void) {
u32 t;
if (D_80076242_.v != 0) {
if (func_8003C4F0(0) == 0) {
return 0;
}
D_80076242_.v = 0;
t = D_8006AEF4;
} else {
t = D_8006AEF4;
}
D_8006AEF4 = t & 0xFC;
func_800373D0();
return 1;
}
INCLUDE_ASM("asm/nonmatchings/800", func_800377D8);
@@ -17300,7 +17571,25 @@ INCLUDE_ASM("asm/nonmatchings/800", func_800383A4);
INCLUDE_ASM("asm/nonmatchings/800", func_800384A8);
INCLUDE_ASM("asm/nonmatchings/800", func_800385C0);
void func_800385C0(s16 a0)
{
extern u8 D_800C6E2A[];
extern u8 D_800B9ED2[];
extern u8 D_800B9ED3[];
register s32 a0v __asm__("$4");
register u8 *v1 __asm__("$3");
s32 a1;
for (a1 = 0, v1 = D_800C6E2A; a1 < 0x10; a1++, v1 += 0x60) {
if (v1[2] != 0 && *(s16 *)(*(s32 *)(v1 - 0xA) + 0x1F0) == a0v) {
v1[2] = 0;
v1[0] = 0;
}
}
D_800B9ED2[((a0v << 7) - a0v) << 2] = 0;
D_800B9ED3[((a0v << 7) - a0v) << 2] = 0;
}
extern u8 D_800B9E92[];
+143 -1
View File
@@ -470,7 +470,149 @@ void *GsTMDfastF4GL(void)
);
}
INCLUDE_ASM("asm/nonmatchings/800b2", GsTMDfastF4GNL);
/* GsTMDfastF4GNL @ 0x80058284 -- HANDWRITTEN PsyQ libgs TMD primitive walker
* (flat, 4-vertex, lit, non-textured "fast" path). Splat marks it "Handwritten
* function": raw GTE code (rtpt/nclip/rtps/avsz4), direct lwc2/swc2 to numbered
* cop2 data registers, cfc2 $31, hand-filled branch delay slots and explicit
* load-latency nops, 8 arguments (4 in $a0-$a3, 4 on the stack), allocation in
* $t0-$t9 only. Not expressible as compiler-generated C; reproduced verbatim
* the way the project's other handwritten GTE bodies are (see GsTMDfastG3GL
* above): one __asm__ __volatile__ block under .set noreorder. gcc supplies the
* label, the 8-byte frame for the two-word flag/otz scratch pair, and the
* trailing "jr $ra / nop" epilogue -- exactly the target's head and tail.
* GTE compute ops are written as `cop2 <imm>` (binutils has no mnemonics):
* rtpt = 0x4A280030 -> cop2 0x0280030
* nclip = 0x4B400006 -> cop2 0x1400006
* rtps = 0x4A180001 -> cop2 0x0180001
* avsz4 = 0x4B68002E -> cop2 0x168002E
* No relocations and no symbol references: the body touches only its arguments,
* the stack scratch pair and the GTE. */
void *GsTMDfastF4GNL()
{
volatile int g[2];
__asm__ __volatile__(
".set\tnoreorder\n"
"lw $24, 24($29)\n"
"lw $2, 28($29)\n"
"lw $3, 32($29)\n"
"lw $8, 36($29)\n"
"lw $3, 4($3)\n"
"addu $10, $0, $0\n"
"sw $2, 12($8)\n"
"blez $24, 2f\n"
" sw $3, 16($8)\n"
"lui $11, 0xFF\n"
"ori $11, $11, 0xFFFF\n"
"addiu $14, $8, 40\n"
"lui $15, 0x8000\n"
"addiu $13, $8, 24\n"
"addiu $6, $4, 16\n"
"addiu $9, $7, 28\n"
"1:\n"
"lhu $4, 6($6)\n"
"lhu $3, 8($6)\n"
"lhu $2, 10($6)\n"
"sll $4, $4, 3\n"
"addu $4, $5, $4\n"
"sll $3, $3, 3\n"
"addu $3, $5, $3\n"
"sll $2, $2, 3\n"
"addu $2, $5, $2\n"
"lwc2 $0, 0($4)\n"
"lwc2 $1, 4($4)\n"
"lwc2 $2, 0($3)\n"
"lwc2 $3, 4($3)\n"
"lwc2 $4, 0($2)\n"
"lwc2 $5, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x0280030\n" /* rtpt */
"lw $2, -12($6)\n"
"nop\n"
"and $2, $2, $11\n"
"sw $2, -24($9)\n"
"lbu $2, -13($6)\n"
"nop\n"
"ori $2, $2, 0x10\n"
"sb $2, -21($9)\n"
"cfc2 $12, $31\n"
"nop\n"
"sw $12, 0($14)\n"
"lw $2, 40($8)\n"
"nop\n"
"and $2, $2, $15\n"
"bnez $2, 3f\n"
" nop\n"
"nop\n"
"nop\n"
"cop2 0x1400006\n" /* nclip */
"lw $2, -8($6)\n"
"nop\n"
"sw $2, -16($9)\n"
"swc2 $24, 0($13)\n"
"lw $2, 24($8)\n"
"nop\n"
"blez $2, 3f\n"
" nop\n"
"swc2 $12, 8($7)\n"
"swc2 $13, 16($7)\n"
"swc2 $14, 24($7)\n"
"lhu $2, 12($6)\n"
"nop\n"
"sll $2, $2, 3\n"
"addu $2, $5, $2\n"
"lwc2 $0, 0($2)\n"
"lwc2 $1, 4($2)\n"
"nop\n"
"nop\n"
"cop2 0x0180001\n" /* rtps */
"lw $2, -4($6)\n"
"nop\n"
"sw $2, -8($9)\n"
"cfc2 $12, $31\n"
"nop\n"
"sw $12, 0($14)\n"
"lw $2, 40($8)\n"
"nop\n"
"and $2, $2, $15\n"
"bnez $2, 3f\n"
" addiu $2, $7, 32\n"
"swc2 $14, 0($2)\n"
"nop\n"
"nop\n"
"cop2 0x168002E\n" /* avsz4 */
"lw $2, 0($6)\n"
"nop\n"
"sw $2, 0($9)\n"
"swc2 $7, 0($13)\n"
"lw $3, 24($8)\n"
"lw $2, 12($8)\n"
"addiu $9, $9, 36\n"
"srav $3, $3, $2\n"
"lw $2, 16($8)\n"
"sll $3, $3, 2\n"
"addu $2, $2, $3\n"
"sw $2, 56($8)\n"
"lw $3, 0($2)\n"
"lui $2, 0x800\n"
"and $3, $3, $11\n"
"or $3, $3, $2\n"
"sw $3, 0($7)\n"
"and $3, $7, $11\n"
"lw $2, 56($8)\n"
"addiu $7, $7, 36\n"
"sw $3, 0($2)\n"
"3:\n"
"addiu $10, $10, 1\n"
"slt $2, $10, $24\n"
"bnez $2, 1b\n"
" addiu $6, $6, 32\n"
"2:\n"
"addu $2, $7, $0\n"
".set\treorder\n"
: : : "memory");
}
/*
+18 -1
View File
@@ -87,7 +87,24 @@ s32 *Square12(s32 *a0, s32 *a1)
return a1;
}
INCLUDE_ASM("asm/nonmatchings/800b_2", Square0);
s32 *Square0(s32 *a0, s32 *a1)
{
register s32 *out __asm__("$5");
out = a1;
__asm__ __volatile__(
".set\tnoreorder\n"
"lwc2 $9, 0(%0)\n"
"lwc2 $10, 4(%0)\n"
"lwc2 $11, 8(%0)\n"
"nop\n"
"sqr 0\n"
"swc2 $25, 0(%1)\n"
"swc2 $26, 4(%1)\n"
"swc2 $27, 8(%1)\n"
".set\treorder\n"
: : "r"(a0), "r"(out) : "$9", "$10", "$11", "memory");
return a1;
}
void AverageZ3()
{
+17 -1
View File
@@ -120,4 +120,20 @@ s32 func_800625DC(void) {
return 0;
}
INCLUDE_ASM("asm/nonmatchings/800c2_2", func_80062644);
s32 func_80062644(void) {
extern s32 *D_80072A2C;
s32 *p = D_80072A2C;
if ((p[1] & 1) == 0) {
return 0;
}
if ((p[0] & 1) != 0) {
return 1;
}
if ((p[0] & 1) != 0) {
return 1;
}
return 0;
}
__asm__(".word 0x00000000\n");
+52 -2
View File
@@ -90,7 +90,36 @@ void func_80052654(u16 w, u16 h, u16 intmode, u16 dither, u16 varh)
func_80059FC0((u8 *)q);
}
INCLUDE_ASM("asm/nonmatchings/gsgap3", GsInitGraph2);
extern s16 D_800A644C;
extern u8 D_800A644E;
extern u8 D_800A644F;
extern u8 D_800A6450;
extern s16 D_800A649C;
extern s16 D_800A649E;
extern u8 D_800A64A8;
extern u8 D_800A64A9;
extern s16 D_800C7C88;
void func_8005283C(s32 a0, s32 a1);
/* hostile fleet-canonical prototype, as carried by caller TUs */
void GsInitGraph2(s32 w, s32 h, s32 mode, s32 a3, s32 st);
void GsInitGraph2_body(u16 w, u16 h, u16 intmode, u16 dither, u16 varh) __asm__("GsInitGraph2");
void GsInitGraph2_body(u16 w, u16 h, u16 intmode, u16 dither, u16 varh)
{
D_800A649C = w;
D_800A649E = h;
D_800A644C = 0;
D_800A644E = dither;
D_800A644F = 0;
D_800A6450 = 0;
D_800A64A8 = intmode & 1;
D_800C7C88 = intmode & 4;
D_800A64A9 = varh;
func_8005283C(w, h);
}
typedef struct {
@@ -266,4 +295,25 @@ __asm__(
".end\tGsSortClear\n"
);
INCLUDE_ASM("asm/nonmatchings/gsgap3", GS_001_OBJ_5D0);
__asm__(
".text\n"
".align\t2\n"
".globl\tGS_001_OBJ_5D0\n"
".ent\tGS_001_OBJ_5D0\n"
"GS_001_OBJ_5D0:\n"
".set\tnoreorder\n"
"lui $2, %hi(D_80078810)\n"
"addiu $2, $2, %lo(D_80078810)\n"
"lui $5, %hi(D_800C7C74)\n"
"lh $5, %lo(D_800C7C74)($5)\n"
"lw $4, 16($7)\n"
"sll $5, $5, 4\n"
"jal AddPrim\n"
"addu $5, $5, $2\n"
"lw $31, 16($sp)\n"
"addiu $sp, $sp, 24\n"
"jr $31\n"
"nop\n"
".set\treorder\n"
".end\tGS_001_OBJ_5D0\n"
);