Files
BFM-decomp/src/sgap_8.c
T
Drew T 5c71326396 feat(decomp): main lane m16 — 13 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.

  FGO_04_OBJ_64
  _addque
  func_80013ED0
  func_80014028
  func_80017254
  func_800176F0
  func_80019A10
  func_80028F98
  func_8002A4FC
  func_800413B8
  func_8004D16C
  func_8004D1DC
  func_8005D4F0
2026-08-25 03:41:43 -06:00

353 lines
11 KiB
C

#include "common.h"
INCLUDE_ASM("asm/nonmatchings/sgap_8", _SsVmKeyOnNow);
__asm__(
".text\n"
".align\t2\n"
".globl\tVM_NOWON_OBJ_1C0\n"
".type\tVM_NOWON_OBJ_1C0, @function\n"
".ent\tVM_NOWON_OBJ_1C0\n"
"VM_NOWON_OBJ_1C0:\n"
".set\tnoreorder\n"
"lui $v1, %hi(D_800B9B2B)\n"
"lbu $v1, %lo(D_800B9B2B)($v1)\n"
"nop\n"
"sltiu $v0, $v1, 0x40\n"
"beqz $v0, .L80040B38\n"
" mult $a2, $v1\n"
"mflo $v0\n"
"lui $v1, 0x410\n"
"ori $v1, $v1, 0x4105\n"
"multu $v0, $v1\n"
"mfhi $v1\n"
"subu $v0, $v0, $v1\n"
"srl $v0, $v0, 1\n"
"addu $v1, $v1, $v0\n"
"j VM_NOWON_OBJ_230\n"
" srl $a2, $v1, 5\n"
".L80040B38:\n"
"addiu $v0, $zero, 0x7F\n"
"subu $v0, $v0, $v1\n"
"mult $a1, $v0\n"
"mflo $v0\n"
"lui $v1, 0x410\n"
"ori $v1, $v1, 0x4105\n"
"multu $v0, $v1\n"
"mfhi $v1\n"
"subu $v0, $v0, $v1\n"
"srl $v0, $v0, 1\n"
"addu $v1, $v1, $v0\n"
"srl $a1, $v1, 5\n"
".set\treorder\n"
".size\tVM_NOWON_OBJ_1C0, . - VM_NOWON_OBJ_1C0\n"
".end\tVM_NOWON_OBJ_1C0\n"
);
__asm__(
".text\n"
".align\t2\n"
".globl\tVM_NOWON_OBJ_230\n"
".type\tVM_NOWON_OBJ_230, @function\n"
".ent\tVM_NOWON_OBJ_230\n"
"VM_NOWON_OBJ_230:\n"
".set\tnoreorder\n"
"lui $v1, %hi(D_800B9B25)\n"
"lbu $v1, %lo(D_800B9B25)($v1)\n"
"nop\n"
"sltiu $v0, $v1, 0x40\n"
"beqz $v0, .L80040BA8\n"
" mult $a2, $v1\n"
"mflo $v0\n"
"lui $v1, 0x410\n"
"ori $v1, $v1, 0x4105\n"
"multu $v0, $v1\n"
"mfhi $v1\n"
"subu $v0, $v0, $v1\n"
"srl $v0, $v0, 1\n"
"addu $v1, $v1, $v0\n"
"j VM_NOWON_OBJ_2A0\n"
" srl $a2, $v1, 5\n"
".L80040BA8:\n"
"addiu $v0, $zero, 0x7F\n"
"subu $v0, $v0, $v1\n"
"mult $a1, $v0\n"
"mflo $v0\n"
"lui $v1, 0x410\n"
"ori $v1, $v1, 0x4105\n"
"multu $v0, $v1\n"
"mfhi $v1\n"
"subu $v0, $v0, $v1\n"
"srl $v0, $v0, 1\n"
"addu $v1, $v1, $v0\n"
"srl $a1, $v1, 5\n"
".set\treorder\n"
".size\tVM_NOWON_OBJ_230, . - VM_NOWON_OBJ_230\n"
".end\tVM_NOWON_OBJ_230\n"
);
/*
* VM_NOWON_OBJ_2A0 -- cookbook §179-C: the target has NO trailing jr $ra. Every exit is either a
* raw `bne`/`j VM_NOWON_OBJ_2C8` (args already live in $a0-$a2) or a one-instruction join block
* (`addu $a2,$a1,$zero` at 0x80040BFC) that FALLS THROUGH into VM_NOWON_OBJ_2C8 at 0x80040C00 --
* the callee owns the shared epilogue for this fallthrough chain (230 -> 2A0 -> 2C8 -> 3D4).
* gcc-2.7.2 has no sibcall/tail-merge and unconditionally appends its own return sequence to
* every ordinary C function (function.c:expand_function_end), so a C-bodied spelling can only
* reach +2 instructions (phantom jr/nop). FILE-SCOPE asm is the only spelling that emits exactly
* the target bytes: cc1 copies the blob verbatim, no .ent-triggered epilogue machinery runs.
* Literal tab-separated ".ent"/".end" text is load-bearing (maspsx process_line special-cases
* lines starting with ".ent\t"); "glabel" would leave `as` in reorder mode and scramble the
* hand-placed delay slots. In file-scope asm % is literal, so %hi/%lo stay un-doubled.
*
* MASPSX CRACK: maspsx raises "not enough values to unpack (expected 3, got 2)" on the bare
* mnemonic `sltu` -- proven by isolation bisect (head-only compiles; head+sltu alone crashes;
* every crashing variant contained sltu, every passing one lacked it). The instruction is
* therefore emitted as its raw word 0x00A6102B (== sltu $v0,$a1,$a2, byte-identical to the
* target column), which passes through maspsx untouched -- §179-C's sanctioned raw-.word escape.
*
* BNE SPELLING (gate-driven): the target's bne displacement is +6 == 0x80040C00 == the first
* instruction AFTER this blob, so it is spelled against a LOCAL .L label placed at the blob's
* end. That encodes 0x14620006 at assembly time, independent of TU emission order. The
* external-symbol spelling is NOT verifiable by match_one (R_MIPS_PC16 is masked 0xFFFF0000,
* §195-D/tooling-audit) and resolved against the real TU's layout at the gate, where it failed;
* the local-label form is byte-identical and layout-independent. The j (R_MIPS_26,
* position-independent within the region) keeps the target's own symbol.
*/
__asm__(
".text\n"
".align\t2\n"
".globl\tVM_NOWON_OBJ_2A0\n"
".ent\tVM_NOWON_OBJ_2A0\n"
"VM_NOWON_OBJ_2A0:\n"
".set\tnoreorder\n"
"lui $v1, %hi(D_800A6434)\n"
"lh $v1, %lo(D_800A6434)($v1)\n"
"addiu $v0, $zero, 0x1\n"
"bne $v1, $v0, .L80040C00\n"
" .word 0x00A6102B\n"
"beqz $v0, .L80040BFC\n"
" nop\n"
"j VM_NOWON_OBJ_2C8\n"
" addu $a1, $a2, $zero\n"
".L80040BFC:\n"
"addu $a2, $a1, $zero\n"
".L80040C00:\n"
".set\treorder\n"
".end\tVM_NOWON_OBJ_2A0\n"
);
/*
* VM_NOWON_OBJ_2C8 -- no epilogue: the not-taken arm FALLS THROUGH into
* VM_NOWON_OBJ_3D4's own code (which owns the shared tail). gcc-2.7.2 has no
* sibcall / cross-function tail-merge pass (matching-cookbook.md §179-C) and
* unconditionally appends its own return sequence to any ordinary C function
* body, so this can only be written as FILE-SCOPE __asm__ -- opaque text the
* compiler never runs expand_function_end over. Literal ".ent"/".end" (not
* glabel) so maspsx sees the boundary and leaves our hand-written delay slots
* and mult/mflo hazard nops alone; %hi/%lo un-doubled (file-scope asm).
*
* Placement: this block takes the INCLUDE_ASM(..., VM_NOWON_OBJ_2C8) slot.
* The TU's own INCLUDE_ASM(..., VM_NOWON_OBJ_3D4) follows on the next line --
* do NOT add a second one here (duplicate glabel breaks the link).
*/
__asm__(
".text\n"
".align\t2\n"
".globl\tVM_NOWON_OBJ_2C8\n"
".ent\tVM_NOWON_OBJ_2C8\n"
"VM_NOWON_OBJ_2C8:\n"
".frame\t$sp,0,$31\n"
".mask\t0x00000000,0\n"
".fmask\t0x00000000,0\n"
".set\tnoreorder\n"
"mult $5, $5\n"
"mflo $3\n"
"nop\n"
"nop\n"
"mult $6, $6\n"
"mflo $6\n"
"lui $2, 0x4\n"
"ori $2, $2, 0x11\n"
"multu $3, $2\n"
"mfhi $5\n"
"nop\n"
"nop\n"
"multu $6, $2\n"
"andi $4, $9, 0xFFFF\n"
"sll $4, $4, 1\n"
"lui $1, %hi(D_800B9B5C)\n"
"addu $1, $1, $4\n"
"sh $8, %lo(D_800B9B5C)($1)\n"
"subu $3, $3, $5\n"
"srl $3, $3, 1\n"
"addu $5, $5, $3\n"
"srl $5, $5, 13\n"
"lui $3, %hi(D_800B9B5C)\n"
"addiu $3, $3, %lo(D_800B9B5C)\n"
"mfhi $2\n"
"subu $6, $6, $2\n"
"srl $6, $6, 1\n"
"addu $2, $2, $6\n"
"srl $6, $2, 13\n"
"addiu $2, $3, -4\n"
"addu $2, $4, $2\n"
"addiu $3, $3, -2\n"
"addu $4, $4, $3\n"
"sh $5, 0($2)\n"
"sh $6, 0($4)\n"
"lui $4, %hi(D_800B9B3A)\n"
"addiu $4, $4, %lo(D_800B9B3A)\n"
"lh $3, 0($4)\n"
"lui $1, %hi(D_800A4620)\n"
"addu $1, $1, $3\n"
"lbu $2, %lo(D_800A4620)($1)\n"
"nop\n"
"ori $2, $2, 0x7\n"
"lui $1, %hi(D_800A4620)\n"
"addu $1, $1, $3\n"
"sb $2, %lo(D_800A4620)($1)\n"
"lh $3, 0($4)\n"
"nop\n"
"sll $2, $3, 1\n"
"addu $2, $2, $3\n"
"sll $2, $2, 2\n"
"addu $2, $2, $3\n"
"sll $2, $2, 2\n"
"lui $1, %hi(D_8007958C)\n"
"addu $1, $1, $2\n"
"sh $8, %lo(D_8007958C)($1)\n"
"lh $3, 0($4)\n"
"nop\n"
"slti $2, $3, 0x10\n"
"beqz $2, 1f\n"
"addiu $2, $0, 0x1\n"
"sllv $6, $2, $3\n"
"j VM_NOWON_OBJ_3D4\n"
"addu $5, $0, $0\n"
"1:\n"
"addu $6, $0, $0\n"
"addiu $3, $3, -0x10\n"
"sllv $5, $2, $3\n"
".set\treorder\n"
".end\tVM_NOWON_OBJ_2C8\n"
);
__asm__(".text\n.align 2\n.globl VM_NOWON_OBJ_3D4\n.ent VM_NOWON_OBJ_3D4\n"
"VM_NOWON_OBJ_3D4:\n"
".frame $sp,16,$31\n.mask 0,0\n.fmask 0,0\n.set noreorder\n"
"lui $v0, %hi(D_800B9B34)\n"
"lbu $v0, %lo(D_800B9B34)($v0)\n"
"nop\n"
"andi $v0, $v0, 4\n"
"beqz $v0, .L80040D54\n"
"nor $v1, $zero, $a2\n"
"lui $v0, %hi(D_80078D90)\n"
"lhu $v0, %lo(D_80078D90)($v0)\n"
"lui $v1, %hi(D_80078D92)\n"
"lhu $v1, %lo(D_80078D92)($v1)\n"
"or $v0, $v0, $a2\n"
"or $v1, $v1, $a1\n"
"lui $at, %hi(D_80078D90)\n"
"sh $v0, %lo(D_80078D90)($at)\n"
"lui $at, %hi(D_80078D92)\n"
"sh $v1, %lo(D_80078D92)($at)\n"
"j VM_NOWON_OBJ_44C\n"
".L80040D54:\n"
"lui $v0, %hi(D_80078D90)\n"
"lhu $v0, %lo(D_80078D90)($v0)\n"
"nop\n"
"and $v0, $v0, $v1\n"
"lui $at, %hi(D_80078D90)\n"
"sh $v0, %lo(D_80078D90)($at)\n"
"lui $v0, %hi(D_80078D92)\n"
"lhu $v0, %lo(D_80078D92)($v0)\n"
"nor $v1, $zero, $a1\n"
"and $v0, $v0, $v1\n"
"lui $at, %hi(D_80078D92)\n"
"sh $v0, %lo(D_80078D92)($at)\n"
".set reorder\n.end VM_NOWON_OBJ_3D4\n");
void VM_NOWON_OBJ_44C(s32 arg0, s32 arg1, s32 arg2) {
extern u16 D_80078D8C;
extern u16 D_80078D8E;
extern u16 D_800C7F04;
extern u16 D_800C7F06;
u16 a = D_80078D8C;
u16 b = D_80078D8E;
register u16 m __asm__("2");
__asm__ __volatile__("" ::: "memory");
m = D_800C7F04;
a |= arg2;
D_80078D8C = a;
__asm__ __volatile__("" ::: "memory");
m &= ~a;
D_800C7F04 = m;
m = D_800C7F06;
b |= arg1;
D_80078D8E = b;
__asm__ __volatile__("" ::: "memory");
m &= ~b;
D_800C7F06 = m;
__asm__ __volatile__("addiu $sp,$sp,0x10" ::: "memory");
}
INCLUDE_ASM("asm/nonmatchings/sgap_8", func_80040DE8);
extern s32 D_800C73D8[];
extern s16 D_800B9B36;
s32 func_80041354(s32 param_1, u16 *param_2, u16 *param_3)
{
s32 base;
s16 *attr;
s32 vab;
base = D_800C73D8[param_1 & 0xFF];
attr = &D_800B9B36;
*attr = param_1;
vab = (param_1 & 0xFF00) >> 8;
base += vab * 0xB0;
*param_2 = *(u16 *)(base + 0x58);
*param_3 = *(u16 *)(base + 0x5A);
return *attr;
}
extern s32 D_800C73D8[];
extern s16 D_800B9B36;
s32 func_800413B8(s32 param_1)
{
s32 base;
s32 vab;
base = D_800C73D8[param_1 & 0xFF];
__asm__ __volatile__("" ::: "memory");
D_800B9B36 = param_1;
vab = (param_1 & 0xFF00) >> 8;
base += vab * 0xB0;
return *(s16 *)(base + 0x58);
}
extern s32 D_800C73D8[];
extern s16 D_800B9B36;
s32 func_80041400(s32 param_1)
{
s32 base;
s32 vab;
base = D_800C73D8[param_1 & 0xFF];
__asm__ __volatile__("" ::: "memory");
D_800B9B36 = param_1;
vab = (param_1 & 0xFF00) >> 8;
base += vab * 0xB0;
return *(s16 *)(base + 0x5A);
}
INCLUDE_ASM("asm/nonmatchings/sgap_8", func_80041448);