feat(decomp): main lane m19 — 10 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.

  DpqColorLight
  FGO_02_OBJ_160
  SsUtReverbOff
  StoreImage
  __main
  func_80013FBC
  func_80014564
  func_80028ECC
  func_8002A28C
  func_80062768
This commit is contained in:
Drew T
2026-08-25 04:59:44 -06:00
parent 29e8114b16
commit fd8ae5327f
6 changed files with 252 additions and 10 deletions
+25 -5
View File
@@ -817,7 +817,11 @@ void func_80013F68(s16 *a0) {
INCLUDE_ASM("asm/nonmatchings/800", func_80013F98);
INCLUDE_ASM("asm/nonmatchings/800", func_80013FBC);
void func_80013FBC(void *a0, void *a1) {
*(u16 *)((s32)a1 + 0x0) = *(u16 *)((s32)a0 + 0x2);
*(u16 *)((s32)a1 + 0x2) = *(u16 *)((s32)a0 + 0x8);
*(u16 *)((s32)a1 + 0x4) = *(u16 *)((s32)a0 + 0xE);
}
void func_80013FE0(void *a0, void *a1) {
*(u16 *)((s32)a1 + 0x0) = *(u16 *)((s32)a0 + 0x4);
@@ -1107,7 +1111,10 @@ void func_80014554(void) {
void func_8001455C(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_80014564);
void func_80014564(void *arg0) {
extern void func_8005C358(void *a0, s32 a1, s32 a2);
func_8005C358(arg0, 0, 0x10);
}
INCLUDE_ASM("asm/nonmatchings/800", func_80014588);
@@ -12407,7 +12414,11 @@ void func_80028558(s32 a0, s32 a1, s32 a2, s32 a3) {
func_80028620(a0, (u8 *)&D_800A5E88 + v0);
}
INCLUDE_ASM("asm/nonmatchings/800", SsUtReverbOff);
extern void func_800538EC(s32 param);
void SsUtReverbOff(void) {
func_800538EC(0);
}
extern s16 D_800C6D18;
@@ -12633,7 +12644,11 @@ INCLUDE_ASM("asm/nonmatchings/800", func_80028E88);
INCLUDE_ASM("asm/nonmatchings/800", func_80028EAC);
INCLUDE_ASM("asm/nonmatchings/800", func_80028ECC);
extern void func_80029124(s32, s32);
void func_80028ECC(s32 a0) {
func_80029124(0x10, a0 & 0xFF);
}
INCLUDE_ASM("asm/nonmatchings/800", func_80028EF0);
@@ -13223,7 +13238,12 @@ s32 func_8002A27C(void) {
return D_80078EE8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002A28C);
extern s32 D_80078EE4;
extern u8 D_800638F8[];
s32 func_8002A28C(void) {
return *(u16 *)(D_800638F8 + D_80078EE4 * 16);
}
extern s32 D_80078EE4;
extern u8 D_800638FA[];
+15 -1
View File
@@ -17,7 +17,21 @@ void LightColor(void)
: : : "memory");
}
INCLUDE_ASM("asm/nonmatchings/800b_2", DpqColorLight);
void DpqColorLight()
{
__asm__ __volatile__(
".set\tnoreorder\n"
"lwc2 $9, 0($4)\n"
"lwc2 $10, 4($4)\n"
"lwc2 $11, 8($4)\n"
"lwc2 $6, 0($5)\n"
"mtc2 $6, $8\n"
"nop\n"
"dpcl\n"
"swc2 $22, 0($7)\n"
".set\treorder\n"
);
}
/* DpqColor3 @ 0x8004929C -- handwritten PsyQ depth-cue colour routine.
+80 -1
View File
@@ -14,7 +14,86 @@ INCLUDE_ASM("asm/nonmatchings/800b_5", FGO_02_OBJ_68);
INCLUDE_ASM("asm/nonmatchings/800b_5", FGO_02_OBJ_CC);
INCLUDE_ASM("asm/nonmatchings/800b_5", FGO_02_OBJ_160);
__asm__(".text\n.align 2\n.globl FGO_02_OBJ_160\n.ent\tFGO_02_OBJ_160\n"
"FGO_02_OBJ_160:\n.frame $sp,0,$31\n"
".set\tnoreorder\n"
"multu $t5, $t0\n"
"nop\n"
"nop\n"
"mflo $t7\n"
"sra $t6, $t7, 12\n"
"sh $t6, 6($a1)\n"
"multu $t2, $t0\n"
"nop\n"
"nop\n"
"mflo $t7\n"
"sra $t6, $t7, 12\n"
"nop\n"
"multu $t4, $t3\n"
"sh $t6, 8($a1)\n"
"nop\n"
"mflo $t7\n"
"sra $t8, $t7, 12\n"
"nop\n"
"multu $t8, $t5\n"
"nop\n"
"nop\n"
"mflo $t7\n"
"sra $t6, $t7, 12\n"
"nop\n"
"multu $t1, $t2\n"
"nop\n"
"nop\n"
"mflo $t7\n"
"sra $t9, $t7, 12\n"
"addu $t7, $t9, $t6\n"
"multu $t1, $t5\n"
"sh $t7, 0($a1)\n"
"nop\n"
"mflo $t6\n"
"sra $t9, $t6, 12\n"
"negu $t7, $t9\n"
"multu $t8, $t2\n"
"nop\n"
"nop\n"
"mflo $t6\n"
"sra $t9, $t6, 12\n"
"addu $t6, $t7, $t9\n"
"multu $t1, $t3\n"
"sh $t6, 2($a1)\n"
"nop\n"
"mflo $t7\n"
"sra $t8, $t7, 12\n"
"nop\n"
"multu $t8, $t2\n"
"nop\n"
"nop\n"
"mflo $t7\n"
"sra $t6, $t7, 12\n"
"nop\n"
"multu $t4, $t5\n"
"nop\n"
"nop\n"
"mflo $t7\n"
"sra $t9, $t7, 12\n"
"addu $t7, $t9, $t6\n"
"multu $t4, $t2\n"
"sh $t7, 14($a1)\n"
"nop\n"
"mflo $t6\n"
"sra $t9, $t6, 12\n"
"negu $t7, $t9\n"
"multu $t8, $t5\n"
"nop\n"
"nop\n"
"mflo $t6\n"
"sra $t9, $t6, 12\n"
"addu $t6, $t7, $t9\n"
"sh $t6, 12($a1)\n"
"jr $ra\n"
"nop\n"
".set\treorder\n.end\tFGO_02_OBJ_160\n");
__asm__(".word 0");
INCLUDE_ASM("asm/nonmatchings/800b_5", func_80049CAC);
+10 -1
View File
@@ -544,7 +544,16 @@ s32 func_800599B8(void *rect, void *p)
*(void **)((u8 *)D_80072780 + 0x20), rect, 8, p);
}
INCLUDE_ASM("asm/nonmatchings/800c", StoreImage);
extern void *D_80072780;
extern char D_80074190;
extern void func_80059760();
s32 StoreImage(void *rect, void *p)
{
func_80059760(&D_80074190, rect);
return (*(s32 (**)(void *, void *, s32, s32))((u8 *)D_80072780 + 0x8))(
*(void **)((u8 *)D_80072780 + 0x1C), rect, 8, p);
}
/* ===========================================================================
+52 -1
View File
@@ -49,4 +49,55 @@ __asm__(
"nop\n"
);
INCLUDE_ASM("asm/nonmatchings/800c2_3", func_80062768);
/* Handwritten function (splat header) — banked verbatim per §265 form 1.
* Recovered semantics:
* D_80078D28 = return address; func_8005CF08(); call vector 0xB0 ($t2=176);
* p = (*(ret + 0x16C)) + 0x62C; for (i = 9; i; --i) *p++ = 0;
* FlushCache(); func_8005CF18(); return via saved $ra.
* NOTE: maspsx did NOT auto-insert load-delay nops here (after
* "lw $v0,364($v0)" and "lw $ra,%lo(D_80078D28)($ra)") — both written by
* hand, matching the banked sibling func_800626F0 in this same TU; this
* contradicts §179-B rule 4 as observed on this build.
*/
__asm__(
".text\n"
".align 2\n"
".globl func_80062768\n"
".ent\tfunc_80062768\n"
"func_80062768:\n"
".frame $sp, 0, $31\n"
".mask 0x00000000, 0\n"
".fmask 0x00000000, 0\n"
".set\tnoreorder\n"
"lui $at, %hi(D_80078D28)\n"
"sw $ra, %lo(D_80078D28)($at)\n"
"jal func_8005CF08\n"
"nop\n"
"addiu $t1, $0, 87\n"
"addiu $t2, $0, 176\n"
"jalr $t2\n"
"nop\n"
"addiu $t2, $0, 9\n"
"lw $v0, 364($v0)\n"
"nop\n"
"addi $v1, $v0, 1580\n"
".L80062798:\n"
"sw $0, 0($v1)\n"
"addiu $v1, $v1, 4\n"
"addiu $t2, $t2, -1\n"
"bnez $t2, .L80062798\n"
"nop\n"
"jal FlushCache\n"
"nop\n"
"jal func_8005CF18\n"
"nop\n"
"lui $ra, %hi(D_80078D28)\n"
"lw $ra, %lo(D_80078D28)($ra)\n"
"nop\n"
"jr $ra\n"
"nop\n"
".set\treorder\n"
".end\tfunc_80062768\n"
"nop\n"
"nop\n"
);
+70 -1
View File
@@ -67,7 +67,76 @@ __asm__(".text\n"
void start(void);
INCLUDE_ASM("asm/nonmatchings/boot", __main);
/* __main (0x800100A0) -- crt0 constructor-runner, HANDWRITTEN assembly.
* Replaces the boot __main stub line in src/boot.c IN PLACE (order preserved:
* lands right after the `start` artifact, before __do_global_dtors). Same
* lane-2 file-scope __asm__ form already byte-gated in this TU for `start`,
* and used by banked StopRCnt/gfx2D_BG0_OBJ_658/FGO_06_OBJ_64/func_800D0440
* elsewhere in the tree. Per cookbook §265: ship NO C externs/prototype with
* the file-scope form -- the asm resolves symbols at link time; a guessed
* decl for a crt-reserved name is pure conflict risk.
*
* WHY ASM, NOT C: this TU builds -O0 per-file (the boot.c precedent), but
* __main's target bytes are -O2/handwritten-shaped code (loop state held in
* $s0/$s1 across the call, delay slots filled, zero local spill/reload) --
* no C body in this TU can produce them (a C draft compiles to 47 spilled
* -O0 insns).
*
* RECOVERED SEMANTICS (for the eventual real decomp):
* static int done; // D_80062998
* void __main(void) {
* if (!done) {
* done = 1;
* int *p = (int *)&start; // init-array base
* int n = 3; // count ships as literal zeros in the
* // target (splat renders `lui $s1,(0x0>>16)`
* // / `addiu $s1,$s1,0x0` -- its display of a
* // bare 32-bit literal, cf. `(0x80000000 >> 16)`
* // for raw 0080033C); emitted as plain zero
* // immediates, byte-identical, no relocation
* do { ((void (*)(void))*p)(); p++; n--; } while (n != 0);
* }
* }
* Maspsx rules honored per the start artifact: decimal immediates only,
* .set noreorder with explicit delay-slot nops, .ent/.end wrappers. */
__asm__(".text\n"
".align 2\n"
".globl __main\n"
".ent\t__main\n"
"__main:\n"
".set\tnoreorder\n"
"lui $t0, %hi(D_80062998)\n"
"lw $t0, %lo(D_80062998)($t0)\n"
"addiu $sp, $sp, -16\n"
"sw $s0, 4($sp)\n"
"sw $s1, 8($sp)\n"
"sw $ra, 12($sp)\n"
"bnez $t0, .L800100F8\n"
"ori $t0, $zero, 1\n"
"lui $at, %hi(D_80062998)\n"
"sw $t0, %lo(D_80062998)($at)\n"
"lui $s0, %hi(start)\n"
"addiu $s0, $s0, %lo(start)\n"
"lui $s1, 0\n"
"addiu $s1, $s1, 0\n"
"beqz $s1, .L800100F8\n"
"nop\n"
".L800100E0:\n"
"lw $t0, 0($s0)\n"
"addiu $s0, $s0, 4\n"
"jalr $t0\n"
"addiu $s1, $s1, -1\n"
"bnez $s1, .L800100E0\n"
"nop\n"
".L800100F8:\n"
"lw $ra, 12($sp)\n"
"lw $s1, 8($sp)\n"
"lw $s0, 4($sp)\n"
"addiu $sp, $sp, 16\n"
"jr $ra\n"
"nop\n"
".set\treorder\n"
".end\t__main\n");
INCLUDE_ASM("asm/nonmatchings/boot", __do_global_dtors);