diff --git a/src/800.c b/src/800.c index be4811e2a0..27ad65b32d 100644 --- a/src/800.c +++ b/src/800.c @@ -921,9 +921,211 @@ s32 func_80013478(void) { return result[0] + result[1] + result[2]; } -INCLUDE_ASM("asm/nonmatchings/800", func_800134FC); +extern void func_80013F3C(void *ptr); +extern s32 func_8004787C(s32 angle); +extern s32 func_80047948(s32 angle); +extern void func_8001282C(); +extern void func_800484EC(s32 a0, s32 a1, s32 a2); -INCLUDE_ASM("asm/nonmatchings/800", func_80013694); +void func_800134FC(s16 param_1, s32 param_2, s32 param_3) +{ + s16 m0[16]; + s16 m1[16]; + s32 sin_val; + s32 cos_val; + register s32 v1 __asm__("$3"); + + func_80013F3C(m0); + + sin_val = func_8004787C(param_1); + cos_val = func_80047948(param_1); + + v1 = 0x1000; + *(s16 *)((s32)m1 + 0x00) = v1; + v1 = -sin_val; + *(s16 *)((s32)m1 + 0x08) = cos_val; + *(s16 *)((s32)m1 + 0x10) = cos_val; + *(s16 *)((s32)m1 + 0x0E) = sin_val; + *(s16 *)((s32)m1 + 0x02) = 0; + *(s16 *)((s32)m1 + 0x04) = 0; + *(s16 *)((s32)m1 + 0x06) = 0; + *(s16 *)((s32)m1 + 0x0A) = v1; + *(s16 *)((s32)m1 + 0x0C) = 0; + + __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;" + "lhu $12, 0(%1);" + "lhu $13, 6(%1);" + "lhu $14, 12(%1);" + "mtc2 $12, $9;" + "mtc2 $13, $10;" + "mtc2 $14, $11;" + "nop;" + "nop;" + "mvmva 1, 0, 3, 3, 0;" + "mfc2 $12, $9;" + "mfc2 $13, $10;" + "mfc2 $14, $11;" + "sh $12, 0(%0);" + "sh $13, 6(%0);" + "sh $14, 12(%0);" + "addiu $2, $sp, 50;" + "lhu $12, 0($2);" + "lhu $13, 6($2);" + "lhu $14, 12($2);" + "mtc2 $12, $9;" + "mtc2 $13, $10;" + "mtc2 $14, $11;" + "nop;" + "nop;" + "mvmva 1, 0, 3, 3, 0;" + "addiu $2, $sp, 18;" + "mfc2 $12, $9;" + "mfc2 $13, $10;" + "mfc2 $14, $11;" + "sh $12, 0($2);" + "sh $13, 6($2);" + "sh $14, 12($2);" + "addiu $2, $sp, 52;" + "lhu $12, 0($2);" + "lhu $13, 6($2);" + "lhu $14, 12($2);" + "mtc2 $12, $9;" + "mtc2 $13, $10;" + "mtc2 $14, $11;" + "nop;" + "nop;" + "mvmva 1, 0, 3, 3, 0;" + "addiu $2, $sp, 20;" + "mfc2 $12, $9;" + "mfc2 $13, $10;" + "mfc2 $14, $11;" + "sh $12, 0($2);" + "sh $13, 6($2);" + "sh $14, 12($2)" + : + : "r"(m0), "r"(m1) + : "$12", "$13", "$14" + ); + + func_8001282C(m0); + func_800484EC(m0, param_2, param_3); +} + +extern void func_80013F3C(void *a0); +extern s32 func_8004787C(s32 angle); +extern s32 func_80047948(s32 angle); +extern void func_8001282C(void *a0); +extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + +void func_80013694(s16 angle, void *a1, void *a2) +{ + s16 matrix[16]; + s16 vec0[9]; + s16 pad[4]; + s32 sin_val; + s32 cos_val; + register s32 v1 __asm__("$3"); + register s16 *v0p __asm__("$2"); + s16 *m0p; + + func_80013F3C(matrix); + sin_val = func_8004787C((s32)angle); + cos_val = func_80047948((s32)angle); + + v1 = 0x1000; + vec0[0] = (s16)v1; + v1 = -sin_val; + vec0[4] = (s16)cos_val; + vec0[8] = (s16)cos_val; + __asm__ __volatile__(""); + v0p = vec0; + vec0[7] = (s16)sin_val; + m0p = matrix; + vec0[1] = 0; + vec0[2] = 0; + vec0[3] = 0; + __asm__ __volatile__(""); + vec0[5] = (s16)v1; + vec0[6] = 0; + + __asm__ __volatile__ ( + "lw $12, 0(%1);" + "lw $13, 4(%1);" + "ctc2 $12, $0;" + "ctc2 $13, $1;" + "lw $12, 8(%1);" + "lw $13, 12(%1);" + "lw $14, 16(%1);" + "ctc2 $12, $2;" + "ctc2 $13, $3;" + "ctc2 $14, $4;" + "lhu $12, 0(%0);" + "lhu $13, 6(%0);" + "lhu $14, 12(%0);" + "mtc2 $12, $9;" + "mtc2 $13, $10;" + "mtc2 $14, $11;" + "nop;" + "nop;" + "mvmva 1, 0, 3, 3, 0;" + "mfc2 $12, $9;" + "mfc2 $13, $10;" + "mfc2 $14, $11;" + "sh $12, 0(%1);" + "sh $13, 6(%1);" + "sh $14, 12(%1);" + "addiu $2, $sp, 50;" + "lhu $12, 0($2);" + "lhu $13, 6($2);" + "lhu $14, 12($2);" + "mtc2 $12, $9;" + "mtc2 $13, $10;" + "mtc2 $14, $11;" + "nop;" + "nop;" + "mvmva 1, 0, 3, 3, 0;" + "addiu $2, $sp, 18;" + "mfc2 $12, $9;" + "mfc2 $13, $10;" + "mfc2 $14, $11;" + "sh $12, 0($2);" + "sh $13, 6($2);" + "sh $14, 12($2);" + "addiu $2, $sp, 52;" + "lhu $12, 0($2);" + "lhu $13, 6($2);" + "lhu $14, 12($2);" + "mtc2 $12, $9;" + "mtc2 $13, $10;" + "mtc2 $14, $11;" + "nop;" + "nop;" + "mvmva 1, 0, 3, 3, 0;" + "addiu $2, $sp, 20;" + "mfc2 $12, $9;" + "mfc2 $13, $10;" + "mfc2 $14, $11;" + "sh $12, 0($2);" + "sh $13, 6($2);" + "sh $14, 12($2)" + : + : "r"(v0p), "r"(m0p) + : "$12", "$13", "$14", "$2" + ); + + func_8001282C(matrix); + ApplyMatrixSV(matrix, a1, a2); +} extern void func_80013F3C(); extern s32 func_8004787C(s32 angle); diff --git a/src/800b_7.c b/src/800b_7.c index e0866d7f73..102bd1d009 100644 --- a/src/800b_7.c +++ b/src/800b_7.c @@ -664,7 +664,484 @@ __asm__( ".end\tgfx2D_BG0_OBJ_698\n" ); -INCLUDE_ASM("asm/nonmatchings/800b_7", GsSortFastBg); +/* GsSortFastBg (asm/nonmatchings/800b_7/GsSortFastBg.s, 0x648 = 402 ins). + * + * Cookbook SS179-C + its P31-S60 ADDENDUM. This chunk has NO epilogue: it is + * fragment 1 of one larger routine whose shared tail lives in the next symbol, + * gfx2D_BG1_OBJ_648 (0x8005168C, already banked in this TU). Every exit is a raw + * "bnez $v0, gfx2D_BG1_OBJ_648" / "j gfx2D_BG1_OBJ_648" with $t0-$t9/$s0-$s7/$fp + * live-out, and the early-out "bltz $a0, .L800517D0" branches straight into that + * sibling's frame teardown. gcc-2.7.2 has no sibcall/tail-merge pass and + * expand_function_end unconditionally appends "jr $ra; nop" to anything cc1 + * compiles, so no C spelling can express this -- it must be file-scope basic asm. + * + * Transcription rules that are load-bearing (SS179-B): + * - literal tab-formed ".ent\t"/".end\t"/".set\t" text (glabel is an as macro + * maspsx never sees, and a space-formed ".set noreorder" leaves maspsx in + * reorder mode, where it appends a nop after every branch); + * - every load/store displacement and addiu immediate in DECIMAL (maspsx calls + * bare int() on them before its range check); + * - the hand-written load-delay nops are transcribed 1:1 and SUPPRESS maspsx's + * own insertion (its get_next_instruction only skips the literal "#nop", so a + * real "nop" reads as the next instruction and never loads from $r_dest); + * - the two div-by-zero traps are ".word" because maspsx rewrites "break N" to + * "break N>>10,N&0x3FF" (bits 6..15), giving 0x000001cd, not the target's + * 0x0007000d (bits 16..25); + * - internal targets keep their ".L" prefix (a bare label would become a symtab + * entry and truncate the objdump boundary walk); + * - ".type/.size" are required or the harness finds no function at this symbol. + * The out-of-chunk targets are written against the successor symbol + * (gfx2D_BG1_OBJ_648+324 == .L800517D0) exactly as the already-banked + * gfx2D_BG1_OBJ_648 block writes its own back-references into this one. + */ +__asm__( + ".set\tnoreorder\n" + ".set\tnoat\n" + ".section\t.text\n" + ".align\t2\n" + ".globl\tGsSortFastBg\n" + ".type\tGsSortFastBg, @function\n" + ".ent\tGsSortFastBg\n" + "GsSortFastBg:\n" + ".set\tnoreorder\n" + "addiu $sp,$sp,-168\n" + "addu $t7,$a0,$zero\n" + "sw $ra,164($sp)\n" + "sw $fp,160($sp)\n" + "sw $s7,156($sp)\n" + "sw $s6,152($sp)\n" + "sw $s5,148($sp)\n" + "sw $s4,144($sp)\n" + "sw $s3,140($sp)\n" + "sw $s2,136($sp)\n" + "sw $s1,132($sp)\n" + "sw $s0,128($sp)\n" + "sw $a1,16($sp)\n" + "lw $a0,0($t7)\n" + "nop\n" + "bltz $a0,gfx2D_BG1_OBJ_648+324\n" + "sh $a2,24($sp)\n" + "lw $t1,20($t7)\n" + "nop\n" + "lbu $s2,0($t1)\n" + "nop\n" + "bnez $s2,.L800510A8\n" + "sh $s2,64($sp)\n" + "addiu $s2,$zero,256\n" + "sh $s2,64($sp)\n" + ".L800510A8:\n" + "lbu $t3,1($t1)\n" + "nop\n" + "bnez $t3,.L800510BC\n" + "nop\n" + "addiu $t3,$zero,256\n" + ".L800510BC:\n" + "lhu $t6,2($t1)\n" + "lhu $t5,64($sp)\n" + "nop\n" + "mult $t5,$t6\n" + "srl $v1,$a0,17\n" + "andi $v1,$v1,0x180\n" + "srl $v0,$a0,23\n" + "andi $v0,$v0,0x60\n" + "or $v1,$v1,$v0\n" + "sh $v1,32($sp)\n" + "srl $v1,$a0,5\n" + "mflo $s6\n" + "lh $v0,12($t7)\n" + "sll $a2,$a0,18\n" + "div $zero,$v0,$s6\n" + "bnez $s6,.L80051104\n" + "nop\n" + ".word 0x0007000d\n" + ".L80051104:\n" + "addiu $at,$zero,-1\n" + "bne $s6,$at,.L8005111C\n" + "lui $at,0x8000\n" + "bne $v0,$at,.L8005111C\n" + "nop\n" + ".word 0x0006000d\n" + ".L8005111C:\n" + "mfhi $fp\n" + "lbu $a3,16($t7)\n" + "lbu $a0,17($t7)\n" + "lbu $a1,18($t7)\n" + "sll $a0,$a0,8\n" + "sll $a1,$a1,16\n" + "lui $v0,0x200\n" + "and $v1,$v1,$v0\n" + "lui $v0,0x100\n" + "and $a2,$a2,$v0\n" + "lui $v0,0x6400\n" + "or $v0,$a2,$v0\n" + "or $v0,$v1,$v0\n" + "or $v0,$v0,$a3\n" + "or $v0,$v0,$a0\n" + "or $v0,$v0,$a1\n" + "sw $v0,40($sp)\n" + "lui $v0,0x2C00\n" + "or $a2,$a2,$v0\n" + "or $v1,$v1,$a2\n" + "or $v1,$v1,$a3\n" + "or $v1,$v1,$a0\n" + "or $v1,$v1,$a1\n" + "lh $a0,4($t7)\n" + "lh $v0,24($t7)\n" + "lui $a1,%hi(D_800A6548)\n" + "lh $a1,%lo(D_800A6548)($a1)\n" + "sw $v1,48($sp)\n" + "lh $v1,26($t7)\n" + "subu $a0,$a0,$v0\n" + "lh $v0,6($t7)\n" + "addu $a0,$a0,$a1\n" + "sw $a0,72($sp)\n" + "lhu $a0,4($t1)\n" + "andi $t4,$t3,0xFFFF\n" + "mult $t4,$a0\n" + "lui $s0,%hi(D_800A5E60)\n" + "lw $s0,%lo(D_800A5E60)($s0)\n" + "lh $s2,8($t7)\n" + "subu $v0,$v0,$v1\n" + "lui $v1,%hi(D_800A654A)\n" + "lh $v1,%lo(D_800A654A)($v1)\n" + "sw $s2,56($sp)\n" + "lh $a0,10($t7)\n" + "mflo $s5\n" + "bgez $fp,.L800511DC\n" + "addu $a1,$v0,$v1\n" + "addu $fp,$fp,$s6\n" + ".L800511DC:\n" + "lh $v0,14($t7)\n" + "nop\n" + "div $zero,$v0,$s5\n" + "bnez $s5,.L800511F4\n" + "nop\n" + ".word 0x0007000d\n" + ".L800511F4:\n" + "addiu $at,$zero,-1\n" + "bne $s5,$at,.L8005120C\n" + "lui $at,0x8000\n" + "bne $v0,$at,.L8005120C\n" + "nop\n" + ".word 0x0006000d\n" + ".L8005120C:\n" + "mfhi $v1\n" + "nop\n" + "bgez $v1,.L80051224\n" + "addu $t8,$v1,$zero\n" + "addu $v1,$v1,$s5\n" + "addu $t8,$v1,$zero\n" + ".L80051224:\n" + "div $zero,$t8,$t4\n" + "bnez $t4,.L80051234\n" + "nop\n" + ".word 0x0007000d\n" + ".L80051234:\n" + "addiu $at,$zero,-1\n" + "bne $t4,$at,.L8005124C\n" + "lui $at,0x8000\n" + "bne $t8,$at,.L8005124C\n" + "nop\n" + ".word 0x0006000d\n" + ".L8005124C:\n" + "mfhi $s1\n" + "andi $t2,$t2,0xFFFF\n" + "sll $v0,$a1,16\n" + "or $t2,$t2,$v0\n" + "andi $t0,$t0,0xFFFF\n" + "subu $v0,$t3,$s1\n" + "sll $v0,$v0,16\n" + "or $t0,$t0,$v0\n" + "srl $v0,$t0,16\n" + "slt $v0,$a0,$v0\n" + "beqz $v0,.L80051284\n" + "sll $v0,$a0,16\n" + "andi $t0,$t0,0xFFFF\n" + "or $t0,$t0,$v0\n" + ".L80051284:\n" + "lui $t9,0xFFFF\n" + "lui $v0,0xE100\n" + "ori $v0,$v0,0x200\n" + "lhu $s2,32($sp)\n" + "addu $a0,$t8,$a0\n" + "or $s7,$s2,$v0\n" + "lw $s2,56($sp)\n" + "addu $s4,$t4,$zero\n" + "sw $a0,104($sp)\n" + "addu $s3,$fp,$s2\n" + "sll $s2,$s4,16\n" + "sw $s2,112($sp)\n" + ".L800512B4:\n" + "addu $t3,$fp,$zero\n" + "div $zero,$t3,$t5\n" + "bnez $t5,.L800512C8\n" + "nop\n" + ".word 0x0007000d\n" + ".L800512C8:\n" + "addiu $at,$zero,-1\n" + "bne $t5,$at,.L800512E0\n" + "lui $at,0x8000\n" + "bne $t3,$at,.L800512E0\n" + "nop\n" + ".word 0x0006000d\n" + ".L800512E0:\n" + "mfhi $t4\n" + "and $t2,$t2,$t9\n" + "and $t0,$t0,$t9\n" + "lhu $v0,72($sp)\n" + "lhu $s2,64($sp)\n" + "or $t2,$t2,$v0\n" + "subu $v0,$s2,$t4\n" + "andi $v0,$v0,0xFFFF\n" + "lw $s2,56($sp)\n" + "or $t0,$t0,$v0\n" + "slt $v0,$s2,$v0\n" + "beqz $v0,.L80051324\n" + "nop\n" + "and $t0,$t0,$t9\n" + "lhu $v0,56($sp)\n" + "nop\n" + "or $t0,$t0,$v0\n" + ".L80051324:\n" + "div $zero,$t8,$s5\n" + "bnez $s5,.L80051334\n" + "nop\n" + ".word 0x0007000d\n" + ".L80051334:\n" + "addiu $at,$zero,-1\n" + "bne $s5,$at,.L8005134C\n" + "lui $at,0x8000\n" + "bne $t8,$at,.L8005134C\n" + "nop\n" + ".word 0x0006000d\n" + ".L8005134C:\n" + "mfhi $v0\n" + "nop\n" + "nop\n" + "div $zero,$t3,$s6\n" + "bnez $s6,.L80051368\n" + "nop\n" + ".word 0x0007000d\n" + ".L80051368:\n" + "addiu $at,$zero,-1\n" + "bne $s6,$at,.L80051380\n" + "lui $at,0x8000\n" + "bne $t3,$at,.L80051380\n" + "nop\n" + ".word 0x0006000d\n" + ".L80051380:\n" + "mfhi $v1\n" + "nop\n" + "nop\n" + "div $zero,$v0,$s4\n" + "bnez $s4,.L8005139C\n" + "nop\n" + ".word 0x0007000d\n" + ".L8005139C:\n" + "addiu $at,$zero,-1\n" + "bne $s4,$at,.L800513B4\n" + "lui $at,0x8000\n" + "bne $v0,$at,.L800513B4\n" + "nop\n" + ".word 0x0006000d\n" + ".L800513B4:\n" + "mflo $v0\n" + "nop\n" + "nop\n" + "div $zero,$v1,$t5\n" + "bnez $t5,.L800513D0\n" + "nop\n" + ".word 0x0007000d\n" + ".L800513D0:\n" + "addiu $at,$zero,-1\n" + "bne $t5,$at,.L800513E8\n" + "lui $at,0x8000\n" + "bne $v1,$at,.L800513E8\n" + "nop\n" + ".word 0x0006000d\n" + ".L800513E8:\n" + "mflo $v1\n" + "nop\n" + "nop\n" + "mult $v0,$t6\n" + "lw $a1,20($t7)\n" + "mflo $s2\n" + "addu $t1,$v1,$s2\n" + "lw $v1,12($a1)\n" + "sll $v0,$t1,1\n" + "addu $v0,$v0,$v1\n" + "lhu $a0,0($v0)\n" + "ori $v0,$zero,0xFFFF\n" + "beq $a0,$v0,.L80051594\n" + "sll $v0,$a0,3\n" + "lw $v1,8($a1)\n" + "andi $s2,$t3,0x1\n" + "sw $s2,120($sp)\n" + "beqz $s2,.L80051514\n" + "addu $a3,$v1,$v0\n" + "addiu $a2,$s0,40\n" + "addiu $v0,$zero,9\n" + "sw $a2,0($s0)\n" + "sb $v0,3($s0)\n" + "lw $s2,48($sp)\n" + "sw $t2,8($s0)\n" + "sw $s2,4($s0)\n" + "lbu $v0,0($a3)\n" + "nop\n" + "addu $v0,$v0,$t4\n" + "sb $v0,12($s0)\n" + "lbu $v0,1($a3)\n" + "addiu $a1,$t2,1\n" + "addu $v0,$v0,$s1\n" + "sb $v0,13($s0)\n" + "lhu $v0,2($a3)\n" + "srl $a0,$t2,16\n" + "sh $a1,16($s0)\n" + "sh $a0,18($s0)\n" + "sh $v0,14($s0)\n" + "lbu $v0,0($a3)\n" + "nop\n" + "addu $v0,$v0,$t4\n" + "sb $v0,20($s0)\n" + "lbu $v0,1($a3)\n" + "srl $v1,$t0,16\n" + "addu $v0,$v0,$s1\n" + "sb $v0,21($s0)\n" + "lhu $v0,6($a3)\n" + "addu $a0,$a0,$v1\n" + "sh $t2,24($s0)\n" + "sh $a0,26($s0)\n" + "lhu $s2,32($sp)\n" + "andi $v0,$v0,0x1F\n" + "or $v0,$s2,$v0\n" + "sh $v0,22($s0)\n" + "lbu $v0,0($a3)\n" + "nop\n" + "addu $v0,$v0,$t4\n" + "sb $v0,28($s0)\n" + "lbu $v0,1($a3)\n" + "sh $a1,32($s0)\n" + "sh $a0,34($s0)\n" + "addu $v0,$v0,$s1\n" + "addu $v0,$v1,$v0\n" + "sb $v0,29($s0)\n" + "lbu $v0,0($a3)\n" + "nop\n" + "addu $v0,$v0,$t4\n" + "sb $v0,36($s0)\n" + "lbu $v0,1($a3)\n" + "nop\n" + "addu $v0,$v0,$s1\n" + "addu $v1,$v1,$v0\n" + "sb $v1,37($s0)\n" + "addu $s0,$a2,$zero\n" + ".L80051514:\n" + "andi $v0,$t0,0xFFFE\n" + "beqz $v0,.L80051594\n" + "addiu $a0,$s0,24\n" + "addiu $v0,$zero,5\n" + "sw $a0,0($s0)\n" + "sb $v0,3($s0)\n" + "lhu $v1,6($a3)\n" + "lw $s2,40($sp)\n" + "andi $v1,$v1,0x1F\n" + "sw $s2,8($s0)\n" + "lw $s2,120($sp)\n" + "or $v1,$v1,$s7\n" + "addu $v0,$t2,$s2\n" + "sh $v0,12($s0)\n" + "srl $v0,$t2,16\n" + "sh $v0,14($s0)\n" + "sw $v1,4($s0)\n" + "lbu $v0,0($a3)\n" + "addiu $s2,$zero,-2\n" + "addu $v0,$v0,$t4\n" + "addiu $v0,$v0,1\n" + "and $v0,$v0,$s2\n" + "sb $v0,16($s0)\n" + "lbu $v0,1($a3)\n" + "nop\n" + "addu $v0,$v0,$s1\n" + "sb $v0,17($s0)\n" + "lhu $v1,2($a3)\n" + "and $v0,$t0,$s2\n" + "sw $v0,20($s0)\n" + "sh $v1,18($s0)\n" + "addu $s0,$a0,$zero\n" + ".L80051594:\n" + "addiu $t1,$t1,1\n" + "div $zero,$t1,$t6\n" + "bnez $t6,.L800515A8\n" + "nop\n" + ".word 0x0007000d\n" + ".L800515A8:\n" + "addiu $at,$zero,-1\n" + "bne $t6,$at,.L800515C0\n" + "lui $at,0x8000\n" + "bne $t1,$at,.L800515C0\n" + "nop\n" + ".word 0x0006000d\n" + ".L800515C0:\n" + "mfhi $v0\n" + "nop\n" + "bnez $v0,gfx2D_BG1_OBJ_648\n" + "andi $v0,$t0,0xFFFF\n" + "j gfx2D_BG1_OBJ_648\n" + "subu $t1,$t1,$t6\n" + ".L800515D8:\n" + "ori $v0,$zero,0xFFFF\n" + "beq $a1,$v0,.L8005164C\n" + "addiu $a0,$s0,24\n" + "lw $v0,20($t7)\n" + "nop\n" + "lw $v1,8($v0)\n" + "addiu $v0,$zero,5\n" + "sw $a0,0($s0)\n" + "sb $v0,3($s0)\n" + "sll $v0,$a1,3\n" + "lw $s2,40($sp)\n" + "addu $a3,$v1,$v0\n" + "lhu $v0,6($a3)\n" + "sw $s2,8($s0)\n" + "sw $t2,12($s0)\n" + "andi $v0,$v0,0x1F\n" + "or $v0,$v0,$s7\n" + "sw $v0,4($s0)\n" + "lbu $v0,0($a3)\n" + "nop\n" + "sb $v0,16($s0)\n" + "lbu $v0,1($a3)\n" + "nop\n" + "addu $v0,$v0,$s1\n" + "sb $v0,17($s0)\n" + "lhu $v0,2($a3)\n" + "sw $t0,20($s0)\n" + "sh $v0,18($s0)\n" + "addu $s0,$a0,$zero\n" + ".L8005164C:\n" + "addiu $t1,$t1,1\n" + "div $zero,$t1,$t6\n" + "bnez $t6,.L80051660\n" + "nop\n" + ".word 0x0007000d\n" + ".L80051660:\n" + "addiu $at,$zero,-1\n" + "bne $t6,$at,.L80051678\n" + "lui $at,0x8000\n" + "bne $t1,$at,.L80051678\n" + "nop\n" + ".word 0x0006000d\n" + ".L80051678:\n" + "mfhi $v0\n" + "nop\n" + "bnez $v0,gfx2D_BG1_OBJ_648\n" + "andi $v0,$t0,0xFFFF\n" + "subu $t1,$t1,$t6\n" + ".set\treorder\n" + ".set\tat\n" + ".end\tGsSortFastBg\n" + ".size\tGsSortFastBg, .-GsSortFastBg\n" +); __asm__( ".text\n" diff --git a/src/800c.c b/src/800c.c index c692d2f3e9..426a985899 100644 --- a/src/800c.c +++ b/src/800c.c @@ -1181,7 +1181,125 @@ __asm__( ".end\tSYS_OBJ_FD8\n" ); -INCLUDE_ASM("asm/nonmatchings/800c", SYS_OBJ_1034); + +__asm__( + ".text\n" + ".align\t2\n" + ".globl\tSYS_OBJ_1034\n" + ".ent\tSYS_OBJ_1034\n" + "SYS_OBJ_1034:\n" + ".set\tnoreorder\n" + " addu $s2, $a1, $zero\n" + " andi $v0, $a2, 0xFFF\n" + " sll $v0, $v0, 12\n" + " andi $a0, $v1, 0xFFF\n" + " lui $v1, (0x6000000 >> 16)\n" + " lui $a1, %hi(D_80072780)\n" + " lw $a1, %lo(D_80072780)($a1)\n" + " or $a0, $a0, $v1\n" + " lw $v1, 16($a1)\n" + " nop\n" + " jalr $v1\n" + " or $a0, $v0, $a0\n" + " andi $v0, $s2, 0x3FF\n" + " sll $v0, $v0, 10\n" + " andi $a0, $s1, 0x3FF\n" + " lui $v1, (0x7000000 >> 16)\n" + " lui $a1, %hi(D_80072780)\n" + " lw $a1, %lo(D_80072780)($a1)\n" + " or $a0, $a0, $v1\n" + " lw $v1, 16($a1)\n" + " nop\n" + " jalr $v1\n" + " or $a0, $v0, $a0\n" + ".L8005A2C4:\n" + " lui $v1, %hi(D_80072804)\n" + " lw $v1, %lo(D_80072804)($v1)\n" + " lw $v0, 16($s0)\n" + " nop\n" + " bne $v1, $v0, .L8005A34C\n" + " nop\n" + " lui $v0, %hi(D_800727F4)\n" + " lhu $v0, %lo(D_800727F4)($v0)\n" + " lh $v1, 0($s0)\n" + " sll $v0, $v0, 16\n" + " sra $v0, $v0, 16\n" + " bne $v0, $v1, .L8005A34C\n" + " nop\n" + " lui $v0, %hi(D_800727F6)\n" + " lhu $v0, %lo(D_800727F6)($v0)\n" + " lh $v1, 2($s0)\n" + " sll $v0, $v0, 16\n" + " sra $v0, $v0, 16\n" + " bne $v0, $v1, .L8005A34C\n" + " nop\n" + " lui $v0, %hi(D_800727F8)\n" + " lhu $v0, %lo(D_800727F8)($v0)\n" + " lh $v1, 4($s0)\n" + " sll $v0, $v0, 16\n" + " sra $v0, $v0, 16\n" + " bne $v0, $v1, .L8005A34C\n" + " nop\n" + " lui $v0, %hi(D_800727FA)\n" + " lhu $v0, %lo(D_800727FA)($v0)\n" + " lh $v1, 6($s0)\n" + " sll $v0, $v0, 16\n" + " sra $v0, $v0, 16\n" + " beq $v0, $v1, .L8005A430\n" + " nop\n" + ".L8005A34C:\n" + " jal func_80043078\n" + " nop\n" + " sb $v0, 18($s0)\n" + " andi $v0, $v0, 0xFF\n" + " addiu $v1, $zero, 1\n" + " bne $v0, $v1, .L8005A36C\n" + " nop\n" + " ori $s3, $s3, 0x8\n" + ".L8005A36C:\n" + " lbu $v0, 17($s0)\n" + " nop\n" + " beqz $v0, .L8005A380\n" + " nop\n" + " ori $s3, $s3, 0x10\n" + ".L8005A380:\n" + " lbu $v0, 16($s0)\n" + " nop\n" + " beqz $v0, .L8005A394\n" + " nop\n" + " ori $s3, $s3, 0x20\n" + ".L8005A394:\n" + " lui $v0, %hi(D_8007278B)\n" + " lbu $v0, %lo(D_8007278B)($v0)\n" + " nop\n" + " beqz $v0, .L8005A3AC\n" + " nop\n" + " ori $s3, $s3, 0x80\n" + ".L8005A3AC:\n" + " lh $v1, 4($s0)\n" + " nop\n" + " slti $v0, $v1, 281\n" + " bnez $v0, SYS_OBJ_11C0\n" + " slti $v0, $v1, 353\n" + " beqz $v0, .L8005A3D0\n" + " slti $v0, $v1, 401\n" + " j SYS_OBJ_11C0\n" + " ori $s3, $s3, 0x1\n" + ".L8005A3D0:\n" + " beqz $v0, .L8005A3E0\n" + " slti $v0, $v1, 561\n" + " j SYS_OBJ_11C0\n" + " ori $s3, $s3, 0x40\n" + ".L8005A3E0:\n" + " beqz $v0, .L8005A3F0\n" + " nop\n" + " j SYS_OBJ_11C0\n" + " ori $s3, $s3, 0x2\n" + ".L8005A3F0:\n" + " ori $s3, $s3, 0x3\n" + ".set\treorder\n" + ".end\tSYS_OBJ_1034\n" +); __asm__( ".text\n" @@ -3297,7 +3415,88 @@ __asm__( ".end\tSYS_OBJ_2CC4\n" ); -INCLUDE_ASM("asm/nonmatchings/800c", SYS_OBJ_2CDC); +/* SYS_OBJ_2CDC: no epilogue (falls into the shared SYS_OBJ_2DD8 tail), and its two "exit" + * points are raw `j` jumps into SYS_OBJ_2CC4 / SYS_OBJ_2DD8 with live values in $v0/$s0 and + * the caller's (func_8005BED8) 0x18-byte frame already built. Cookbook SS179-C: transcribed + * 1:1 as file-scope basic asm (literal tab .ent/.end, un-doubled %hi/%lo, decimal displacements, + * hand-written BRANCH/CALL-delay slots only -- LOAD-delay nops omitted, maspsx auto-inserts + * them per SS179-B rule 4). + */ +__asm__( + ".text\n" + ".align\t2\n" + ".globl\tSYS_OBJ_2CDC\n" + ".type\tSYS_OBJ_2CDC, @function\n" + ".ent\tSYS_OBJ_2CDC\n" + "SYS_OBJ_2CDC:\n" + ".set\tnoreorder\n" + "lui $v1, %hi(D_8007288C)\n" + "lw $v1, %lo(D_8007288C)($v1)\n" + "lui $v0, %hi(D_80072890)\n" + "lw $v0, %lo(D_80072890)($v0)\n" + "beq $v1, $v0, .L8005BF44\n" + " nop\n" + "j SYS_OBJ_2CC4\n" + " nop\n" + ".L8005BF34:\n" + "jal func_8005C054\n" + " nop\n" + "bnez $v0, SYS_OBJ_2DD8\n" + " addiu $v0, $zero, -1\n" + ".L8005BF44:\n" + "lui $v0, %hi(D_80072868)\n" + "lw $v0, %lo(D_80072868)($v0)\n" + "lw $v0, 0($v0)\n" + "lui $v1, (0x1000000 >> 16)\n" + "and $v0, $v0, $v1\n" + "bnez $v0, .L8005BF34\n" + " nop\n" + "lui $v0, %hi(D_8007285C)\n" + "lw $v0, %lo(D_8007285C)($v0)\n" + "lw $v0, 0($v0)\n" + "lui $v1, (0x4000000 >> 16)\n" + "and $v0, $v0, $v1\n" + "beqz $v0, .L8005BF34\n" + " addu $v0, $zero, $zero\n" + "j SYS_OBJ_2DD8\n" + " nop\n" + ".L8005BF8C:\n" + "lui $v0, %hi(D_8007288C)\n" + "lw $v0, %lo(D_8007288C)($v0)\n" + "lui $v1, %hi(D_80072890)\n" + "lw $v1, %lo(D_80072890)($v1)\n" + "subu $v0, $v0, $v1\n" + "andi $s0, $v0, 0x3f\n" + "beqz $s0, .L8005BFB8\n" + " nop\n" + "jal func_8005BA90\n" + " nop\n" + ".L8005BFB8:\n" + "lui $v0, %hi(D_80072868)\n" + "lw $v0, %lo(D_80072868)($v0)\n" + "lw $v0, 0($v0)\n" + "lui $v1, (0x1000000 >> 16)\n" + "and $v0, $v0, $v1\n" + "bnez $v0, .L8005BFF8\n" + " nop\n" + "lui $v0, %hi(D_8007285C)\n" + "lw $v0, %lo(D_8007285C)($v0)\n" + "lw $v0, 0($v0)\n" + "lui $v1, (0x4000000 >> 16)\n" + "and $v0, $v0, $v1\n" + "bnez $v0, .L8005C008\n" + " nop\n" + ".L8005BFF8:\n" + "bnez $s0, SYS_OBJ_2DD8\n" + " addu $v0, $s0, $zero\n" + "j SYS_OBJ_2DD8\n" + " addiu $v0, $zero, 1\n" + ".L8005C008:\n" + "addu $v0, $s0, $zero\n" + ".set\treorder\n" + ".size\tSYS_OBJ_2CDC, . - SYS_OBJ_2CDC\n" + ".end\tSYS_OBJ_2CDC\n" +); /* SYS_OBJ_2DD8 is the SHARED EPILOGUE TAIL for the 0x18-byte frame family in this slice * (ra@0x14 / s0@0x10): SYS_OBJ_2CDC reaches it via "j SYS_OBJ_2DD8", SYS_OBJ_2CC4 via diff --git a/src/boot.c b/src/boot.c index 08c3208296..d60732bb18 100644 --- a/src/boot.c +++ b/src/boot.c @@ -693,7 +693,21 @@ void func_80011ADC(void) { *(u16 *)(p + 0xA3CE) = 0; } -INCLUDE_ASM("asm/nonmatchings/boot", func_80011B7C); +extern u8 D_800AF630[]; + +void func_80011B7C(arg0) + u16 arg0; +{ + register u8 *p = D_800AF630; + *(u16 *)(p + 0xA3C0) = arg0; + *(u16 *)(p + 0xA3C6) = 0; + *(u16 *)(p + 0xA3CC) = 0; + *(u16 *)(p + 0xA3CA) = 0; + *(u16 *)(p + 0xA3D0) = 0; + *(u16 *)(p + 0xA3C2) = 0; + *(u16 *)(p + 0xA3C8) = 0; + *(u16 *)(p + 0xA3CE) = 0; +} extern u8 D_800AF630[]; @@ -758,7 +772,23 @@ s32 func_80011DF4(void) { return D_80074780; } -INCLUDE_ASM("asm/nonmatchings/boot", func_80011E24); +extern u8 D_800AF630[]; + +void func_80011E24(void) { + extern s32 D_80074788; + extern s32 D_800629D0; + extern u16 D_80074794; + extern u16 D_80074798; + register u8 *p = D_800AF630; + long long pad; + + D_80074788 = 0; + if (D_800629D0 == 0) { + *(p + 0xA434) = 0; + } + D_80074794 = 0; + D_80074798 = 0; +} void func_80011E84(s32 a0) { extern s32 D_80074790; @@ -808,4 +838,90 @@ void func_800120DC(u16 *arg0, u16 *arg1) { *arg1 = D_80074798; } -INCLUDE_ASM("asm/nonmatchings/boot", func_8001212C); +/* func_8001212C -- boot (-O0). Builds two 0x18-byte SPRT-with-own-tpage prims at + * the D_800A5E60 prim-buffer cursor and addPrim()s each onto OT word [1] of the + * frame's ordering table (D_800A6610 + gameFrame*0x4000), then republishes the + * advanced cursor. + * + * -O0 spellings that are load-bearing (all byte-proven here): + * - `register u8 *base = D_800AF630;` far-offset base: cookbook ADDENDUM(c) to + * §261a -- lands caller-saved ($v0) with no calls, and the >0x7FFF member + * access assembles to lui $at,1 / addu $at,$v0,$at / lhu -0x5C2E($at). + * - `* 0x4000` (the MULTIPLY, not `<< 14`): the mul-style expansion emits the + * `addu $a0,$v1,$zero` copy of the index before the sll -- ADDENDUM(b) to + * §261a, read in the mirror direction (there `q << 2` was wanted, here the + * multiply is). + * - offset 4 is `((u32 *)p)[1]`, every other field is a member lvalue: §127 / + * its ADDENDUM -- the constant-offset fold keys on the COMPONENT_REF tree + * shape, so the ARRAY_REF form is what materialises `addiu $v1,$a0,0x4` + + * a 0-displacement `sw`, which is exactly what the target shows there. + * - `p++` and NOT `p = p + 1`: the increment expands add-into-fresh-pseudo + + * `addu $a0,$v1,$zero` copy-back before the spill store (§261a's copy row). + * `p = p + 1` / `p += 1` / `&p[1]` / the (u8*) cast all fold that copy away + * (-1 ins each). This was the whole residual: 175 ins vs 177. + * - the 24-bit `addr` bitfield reproduces libgpu's setaddr()/getaddr() RMW: + * and 0xFFFFFF (extract) + and 0xFFFFFF (store mask) + and 0xFF000000 + or. + */ + +extern u8 D_800AF630[]; +extern s32 D_800A5E60; +extern u8 D_800A6610[]; + +void func_8001212C(void) { + typedef struct { + unsigned int addr : 24; + unsigned int len : 8; + } PrimTag; + typedef struct { + u8 pad0, pad1, pad2, len; + u32 tpage; + u8 r0, g0, b0, code; + s16 x0, y0; + u8 u0, v0; + u16 clut; + s16 w, h; + } Sprt24; + + register u8 *base = D_800AF630; + Sprt24 *p; + u32 *ot; + + p = (Sprt24 *)D_800A5E60; + ot = (u32 *)(D_800A6610 + *(u16 *)(base + 0xA3D2) * 0x4000); + + p->len = 5; + ((u32 *)p)[1] = 0xE1000018; + p->code = 0x66; + p->clut = 0x77D6; + p->r0 = 0x80; + p->g0 = 0x80; + p->b0 = 0x80; + p->x0 = 0x30; + p->y0 = 0x2E; + p->u0 = 0x40; + p->v0 = 0xE0; + p->w = 0x60; + p->h = 0x18; + ((PrimTag *)p)->addr = ((PrimTag *)(ot + 1))->addr; + ((PrimTag *)(ot + 1))->addr = (u32)p; + p++; + + p->len = 5; + ((u32 *)p)[1] = 0xE1000018; + p->code = 0x66; + p->clut = 0x77D6; + p->r0 = 0x80; + p->g0 = 0x80; + p->b0 = 0x80; + p->x0 = 0x30; + p->y0 = 0x46; + p->u0 = 0xA0; + p->v0 = 0xE0; + p->w = 0x60; + p->h = 0x18; + ((PrimTag *)p)->addr = ((PrimTag *)(ot + 1))->addr; + ((PrimTag *)(ot + 1))->addr = (u32)p; + p++; + + D_800A5E60 = (s32)p; +}