Files
BFM-decomp/src/800.c
T
Drew T a8ae190fa3 feat(phase-11): T3 — intra-binary collapse PROOF (one body, two addresses, byte-identical)
- src/shared/clearTbl40.h: CLEAR_TBL40 macro = the matched byte-clear loop body, authored ONCE;
  instantiated at both func_80037004 and func_80037334 in src/800.c (one source -> two vrams)
- matched first try; clean rebuild main -> 143dbb89 BYTE-IDENTICAL WITH the shared C AND WITHOUT
  it (INCLUDE_ASM stub fallback) -> dual invariant proven (R22 clean rebuilds, both states)
- config/dedup.us.yaml: I0_clearTbl40 group registered (h_exact a0744d60…); dedup_integrate
  --check validates it; negative tests (corrupt hash / wrong vram) fail-closed (exit 1)
- tools/progress.py: count dedup-shared members as REAL via the registry (the macro form isn't a
  parseable function def); REAL 52 -> 54, byte-identical 50.24% -> 50.33%; honest measurement (P9)
- tools/dedup_integrate.py: display vram in hex in diagnostics
- the machinery half of the Phase-11 milestone is proven on the byte-verified EXE
2026-06-16 00:56:35 -06:00

2837 lines
84 KiB
C

#include "common.h"
#include "psyq/libcd.h"
#include "shared/clearTbl40.h" /* dedup group I0: func_80037004 / func_80037334 share one body */
INCLUDE_ASM("asm/nonmatchings/800", func_800123F0);
INCLUDE_ASM("asm/nonmatchings/800", func_80012558);
INCLUDE_ASM("asm/nonmatchings/800", func_800126C4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001282C);
INCLUDE_ASM("asm/nonmatchings/800", func_800128B4);
INCLUDE_ASM("asm/nonmatchings/800", func_800128EC);
INCLUDE_ASM("asm/nonmatchings/800", func_800129CC);
INCLUDE_ASM("asm/nonmatchings/800", func_80012A60);
s32 func_80012AB0(s32 arg0, s32 arg1) {
return (arg0 - arg1) & 0xFFF;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80012ABC);
INCLUDE_ASM("asm/nonmatchings/800", func_80012B04);
INCLUDE_ASM("asm/nonmatchings/800", func_80012B58);
INCLUDE_ASM("asm/nonmatchings/800", func_80012C6C);
INCLUDE_ASM("asm/nonmatchings/800", func_80012CB8);
INCLUDE_ASM("asm/nonmatchings/800", func_80012D0C);
INCLUDE_ASM("asm/nonmatchings/800", func_80012DBC);
INCLUDE_ASM("asm/nonmatchings/800", func_80012E0C);
INCLUDE_ASM("asm/nonmatchings/800", func_80012E6C);
INCLUDE_ASM("asm/nonmatchings/800", func_80012F74);
INCLUDE_ASM("asm/nonmatchings/800", func_80012FC8);
INCLUDE_ASM("asm/nonmatchings/800", func_80013028);
INCLUDE_ASM("asm/nonmatchings/800", func_800130D0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001311C);
INCLUDE_ASM("asm/nonmatchings/800", func_80013154);
INCLUDE_ASM("asm/nonmatchings/800", func_80013200);
INCLUDE_ASM("asm/nonmatchings/800", func_80013228);
INCLUDE_ASM("asm/nonmatchings/800", func_80013294);
INCLUDE_ASM("asm/nonmatchings/800", func_800132BC);
INCLUDE_ASM("asm/nonmatchings/800", func_80013328);
INCLUDE_ASM("asm/nonmatchings/800", func_80013350);
INCLUDE_ASM("asm/nonmatchings/800", func_800133BC);
INCLUDE_ASM("asm/nonmatchings/800", func_800133E4);
INCLUDE_ASM("asm/nonmatchings/800", func_80013450);
INCLUDE_ASM("asm/nonmatchings/800", func_80013478);
INCLUDE_ASM("asm/nonmatchings/800", func_800134FC);
INCLUDE_ASM("asm/nonmatchings/800", func_80013694);
INCLUDE_ASM("asm/nonmatchings/800", func_8001382C);
INCLUDE_ASM("asm/nonmatchings/800", func_800139C8);
INCLUDE_ASM("asm/nonmatchings/800", func_80013B64);
INCLUDE_ASM("asm/nonmatchings/800", func_80013CFC);
INCLUDE_ASM("asm/nonmatchings/800", func_80013E94);
INCLUDE_ASM("asm/nonmatchings/800", func_80013ED0);
INCLUDE_ASM("asm/nonmatchings/800", func_80013F3C);
INCLUDE_ASM("asm/nonmatchings/800", func_80013F68);
INCLUDE_ASM("asm/nonmatchings/800", func_80013F98);
INCLUDE_ASM("asm/nonmatchings/800", func_80013FBC);
INCLUDE_ASM("asm/nonmatchings/800", func_80013FE0);
INCLUDE_ASM("asm/nonmatchings/800", func_80014004);
INCLUDE_ASM("asm/nonmatchings/800", func_80014028);
INCLUDE_ASM("asm/nonmatchings/800", func_8001404C);
INCLUDE_ASM("asm/nonmatchings/800", func_80014070);
INCLUDE_ASM("asm/nonmatchings/800", func_80014094);
INCLUDE_ASM("asm/nonmatchings/800", func_800140B8);
INCLUDE_ASM("asm/nonmatchings/800", func_80014128);
INCLUDE_ASM("asm/nonmatchings/800", func_80014148);
INCLUDE_ASM("asm/nonmatchings/800", func_80014168);
INCLUDE_ASM("asm/nonmatchings/800", func_800141AC);
INCLUDE_ASM("asm/nonmatchings/800", func_800141F0);
INCLUDE_ASM("asm/nonmatchings/800", func_80014238);
INCLUDE_ASM("asm/nonmatchings/800", func_800142C8);
INCLUDE_ASM("asm/nonmatchings/800", func_80014338);
INCLUDE_ASM("asm/nonmatchings/800", func_80014390);
INCLUDE_ASM("asm/nonmatchings/800", func_800143AC);
INCLUDE_ASM("asm/nonmatchings/800", func_80014444);
INCLUDE_ASM("asm/nonmatchings/800", func_800144D4);
void func_80014554(void) {
}
void func_8001455C(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_80014564);
INCLUDE_ASM("asm/nonmatchings/800", func_80014588);
INCLUDE_ASM("asm/nonmatchings/800", func_800145EC);
INCLUDE_ASM("asm/nonmatchings/800", func_800146B0);
INCLUDE_ASM("asm/nonmatchings/800", func_80014774);
INCLUDE_ASM("asm/nonmatchings/800", func_800147B8);
INCLUDE_ASM("asm/nonmatchings/800", func_80014928);
INCLUDE_ASM("asm/nonmatchings/800", func_80014960);
INCLUDE_ASM("asm/nonmatchings/800", func_80014998);
INCLUDE_ASM("asm/nonmatchings/800", func_800149E0);
INCLUDE_ASM("asm/nonmatchings/800", func_80014B10);
INCLUDE_ASM("asm/nonmatchings/800", func_80014BFC);
INCLUDE_ASM("asm/nonmatchings/800", func_80014C28);
INCLUDE_ASM("asm/nonmatchings/800", func_80014C54);
INCLUDE_ASM("asm/nonmatchings/800", func_80014CAC);
INCLUDE_ASM("asm/nonmatchings/800", func_80014CF8);
INCLUDE_ASM("asm/nonmatchings/800", func_80014D30);
INCLUDE_ASM("asm/nonmatchings/800", func_80014D68);
INCLUDE_ASM("asm/nonmatchings/800", func_80014D94);
INCLUDE_ASM("asm/nonmatchings/800", func_80014DC0);
INCLUDE_ASM("asm/nonmatchings/800", func_80014DEC);
INCLUDE_ASM("asm/nonmatchings/800", func_80014E24);
INCLUDE_ASM("asm/nonmatchings/800", func_80014E80);
INCLUDE_ASM("asm/nonmatchings/800", func_80014ED4);
INCLUDE_ASM("asm/nonmatchings/800", func_80015018);
INCLUDE_ASM("asm/nonmatchings/800", func_80015118);
void func_8001513C(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_80015144);
INCLUDE_ASM("asm/nonmatchings/800", func_80015208);
INCLUDE_ASM("asm/nonmatchings/800", func_800152F4);
INCLUDE_ASM("asm/nonmatchings/800", func_80015310);
INCLUDE_ASM("asm/nonmatchings/800", func_8001534C);
INCLUDE_ASM("asm/nonmatchings/800", func_800153A4);
INCLUDE_ASM("asm/nonmatchings/800", func_800153CC);
INCLUDE_ASM("asm/nonmatchings/800", func_80015424);
INCLUDE_ASM("asm/nonmatchings/800", func_8001544C);
INCLUDE_ASM("asm/nonmatchings/800", func_80015498);
INCLUDE_ASM("asm/nonmatchings/800", func_80015608);
INCLUDE_ASM("asm/nonmatchings/800", func_80015760);
INCLUDE_ASM("asm/nonmatchings/800", func_80015908);
INCLUDE_ASM("asm/nonmatchings/800", func_80015954);
INCLUDE_ASM("asm/nonmatchings/800", func_80015978);
INCLUDE_ASM("asm/nonmatchings/800", func_8001599C);
INCLUDE_ASM("asm/nonmatchings/800", func_800159C0);
INCLUDE_ASM("asm/nonmatchings/800", func_800159E4);
INCLUDE_ASM("asm/nonmatchings/800", func_80015A08);
INCLUDE_ASM("asm/nonmatchings/800", func_80015A2C);
INCLUDE_ASM("asm/nonmatchings/800", func_80015A50);
#ifdef NON_MATCHING
/* uint -> packed BCD (9 digits, ÷ powers of 10). All idioms match under the pinned
* triple (divu+break div-by-zero via --expand-div, multu 0xCCCCCCCD + srl 3 for ÷10);
* residual diff is a loop-setup instruction-scheduling permutation (li counter vs the
* hoisted magic constant) — a decomp-permuter target. See docs/matching-cookbook.md. */
u32 func_80015A74(u32 param_1) {
u32 result;
s32 i;
u32 divisor;
divisor = 1000000000;
result = 0;
for (i = 9; i >= 0; i--) {
result = (result << 4) | (param_1 / divisor);
param_1 = param_1 % divisor;
divisor = divisor / 10;
}
return result;
}
#else
INCLUDE_ASM("asm/nonmatchings/800", func_80015A74);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_80015AD0);
INCLUDE_ASM("asm/nonmatchings/800", func_80015B6C);
INCLUDE_ASM("asm/nonmatchings/800", func_80015D4C);
INCLUDE_ASM("asm/nonmatchings/800", func_80015F04);
INCLUDE_ASM("asm/nonmatchings/800", func_80016110);
INCLUDE_ASM("asm/nonmatchings/800", func_80016224);
INCLUDE_ASM("asm/nonmatchings/800", func_80016450);
INCLUDE_ASM("asm/nonmatchings/800", func_80016638);
INCLUDE_ASM("asm/nonmatchings/800", func_800166E8);
#ifdef NON_MATCHING
/* bzero(p, n): n<4 byte path; else align-to-4 -> word-fill (sw) -> remainder bytes.
* Logically correct and instruction-identical to the target EXCEPT gcc 2.7.2 emits a
* phantom empty 16-byte stack frame here (target is frameless) — that one frame
* prologue/epilogue is the entire residual. A decomp-permuter candidate (structural
* permutation can flip frame allocation). See docs/matching-cookbook.md §4. */
void func_80016714(s8 *a0, s32 a1) {
s32 v1;
if (a1 < 4) {
a1 = a1 - 1;
if (a1 != -1) {
do {
*a0 = 0;
a1 -= 1;
a0 += 1;
} while (a1 != -1);
}
} else {
v1 = (s32)a0;
if (((s32)a0 & 3) != 0) {
do {
*a0 = 0;
a0 += 1;
v1 += 1;
a1 -= 1;
} while ((v1 & 3) != 0);
}
v1 = (a1 >> 2) - 1;
if (v1 != -1) {
do {
*(s32 *)a0 = 0;
v1 -= 1;
a0 += 4;
} while (v1 != -1);
}
a1 = (a1 & 3) - 1;
if (a1 != -1) {
do {
*a0 = 0;
a1 -= 1;
a0 += 1;
} while (a1 != -1);
}
}
}
#else
INCLUDE_ASM("asm/nonmatchings/800", func_80016714);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_800167B8);
INCLUDE_ASM("asm/nonmatchings/800", func_800167F0);
extern u16 D_800AF7CE;
void func_800168B4(void) {
D_800AF7CE = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_800168C4);
INCLUDE_ASM("asm/nonmatchings/800", func_80016940);
INCLUDE_ASM("asm/nonmatchings/800", func_80016978);
INCLUDE_ASM("asm/nonmatchings/800", func_80016A3C);
INCLUDE_ASM("asm/nonmatchings/800", func_80016A5C);
INCLUDE_ASM("asm/nonmatchings/800", func_80016A7C);
INCLUDE_ASM("asm/nonmatchings/800", func_80016B60);
INCLUDE_ASM("asm/nonmatchings/800", func_80016C28);
INCLUDE_ASM("asm/nonmatchings/800", func_80016D78);
INCLUDE_ASM("asm/nonmatchings/800", func_80016EB0);
INCLUDE_ASM("asm/nonmatchings/800", func_80016ED4);
INCLUDE_ASM("asm/nonmatchings/800", func_80016EF8);
INCLUDE_ASM("asm/nonmatchings/800", func_80016F18);
INCLUDE_ASM("asm/nonmatchings/800", func_80017168);
INCLUDE_ASM("asm/nonmatchings/800", func_80017254);
INCLUDE_ASM("asm/nonmatchings/800", func_80017274);
INCLUDE_ASM("asm/nonmatchings/800", func_80017294);
INCLUDE_ASM("asm/nonmatchings/800", func_8001739C);
INCLUDE_ASM("asm/nonmatchings/800", func_800173BC);
INCLUDE_ASM("asm/nonmatchings/800", func_800173DC);
INCLUDE_ASM("asm/nonmatchings/800", func_800174DC);
INCLUDE_ASM("asm/nonmatchings/800", func_800174FC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001751C);
INCLUDE_ASM("asm/nonmatchings/800", func_800176F0);
INCLUDE_ASM("asm/nonmatchings/800", func_80017714);
INCLUDE_ASM("asm/nonmatchings/800", func_80017738);
INCLUDE_ASM("asm/nonmatchings/800", func_80017758);
INCLUDE_ASM("asm/nonmatchings/800", func_80017778);
INCLUDE_ASM("asm/nonmatchings/800", func_800178C8);
INCLUDE_ASM("asm/nonmatchings/800", func_800178EC);
INCLUDE_ASM("asm/nonmatchings/800", func_80017910);
INCLUDE_ASM("asm/nonmatchings/800", func_80017930);
INCLUDE_ASM("asm/nonmatchings/800", func_80017B98);
INCLUDE_ASM("asm/nonmatchings/800", func_80017D98);
INCLUDE_ASM("asm/nonmatchings/800", func_80017DC4);
INCLUDE_ASM("asm/nonmatchings/800", func_80017DF8);
INCLUDE_ASM("asm/nonmatchings/800", func_80017E30);
INCLUDE_ASM("asm/nonmatchings/800", func_80017E68);
INCLUDE_ASM("asm/nonmatchings/800", func_80017E8C);
INCLUDE_ASM("asm/nonmatchings/800", func_80017F14);
INCLUDE_ASM("asm/nonmatchings/800", func_80018094);
INCLUDE_ASM("asm/nonmatchings/800", func_80018194);
INCLUDE_ASM("asm/nonmatchings/800", func_8001820C);
INCLUDE_ASM("asm/nonmatchings/800", func_80018384);
INCLUDE_ASM("asm/nonmatchings/800", func_800183E0);
INCLUDE_ASM("asm/nonmatchings/800", func_80018450);
INCLUDE_ASM("asm/nonmatchings/800", func_800184F0);
INCLUDE_ASM("asm/nonmatchings/800", func_80018714);
/* LZSS streaming sector decompressor (resumable coroutine state machine).
* Decodes up to 0x800 input bytes per call out of an LZSS stream into a 0x400-byte
* scratchpad ring (lzss_ringBuffer @ 0x1F800000) and to lzss_outPtr. lzss_state is the
* resume point (0=idle/done, 1=fresh, 2=token loop, 3=have code low byte, 4=advance bit).
* Returns 1 if the input sector was consumed mid-stream (resume next call), 0 at the
* stream terminator (back-ref offset 0) or when idle. */
/* MATCHED — asm-differ score 0, full-binary SHA1 green (Phase 7, session F, 2026-06-15).
* Five constructs below are LOAD-BEARING for the byte-for-byte match against gcc 2.7.2 -O2; a
* future reader who "cleans them up" WILL break the match. Each is annotated inline and the
* compiler-internal root cause is in docs/matching-cookbook.md §10 (+ §5a). All five were
* ground-truthed against the pinned gcc-2.7.2 source (reorg.c, jump.c, local-alloc.c). */
extern u8 lzss_curMask; /* 0x800747A0 */
extern u8 lzss_curToken; /* 0x800747A4 */
extern u8 *lzss_outPtr; /* 0x800747AC */
extern u32 lzss_ringIndex; /* 0x800747B0 */
extern u16 lzss_partialCode; /* 0x800747B4 */
extern u32 lzss_state; /* 0x800C7D24 */
s32 LzssDecodeSector(u8 *src) {
s32 count = 0x800;
u32 ringIdx = lzss_ringIndex;
u8 mask = lzss_curMask;
u8 token = lzss_curToken;
u8 *out = lzss_outPtr;
u16 code = lzss_partialCode;
u8 *ring = (u8 *)0x1F800000; /* scratchpad ring; original uses the literal (lui 0x1f80), not the symbol */
u32 readIdx;
s32 len;
u8 b;
u8 nb; /* low-byte (state-3) source byte */
u8 cb;
u8 nh; /* LOAD-BEARING #1 (residual A): a SEPARATE high-byte source var, NOT a reuse of `nb`.
* `nb` is shared between the low- and high-byte paths; reusing it couples their
* register allocation, so any high-byte reshaping shoves `nb` out of $v1. A distinct
* `nh` decouples them. Cookbook §10/A. */
s32 newState;
s32 result; /* return-1 value carried in $v0 from each save predecessor (state-3/state-4) */
/* LOAD-BEARING #2 (residual B3): NO `default:` case and NO statement after the switch. The
* switch's own range check (`sltiu $v0,state,5; beqz $v0,<epilogue>`) is the ONLY state>=5
* guard; the `beqz` REUSES the sltiu result ($v0==0 when state>=5) as the return-0 value by
* threading straight to `jr ra`. An explicit `if(state>=5)return 0;`, a `default:`, or a
* trailing `return 0;` each makes gcc emit a separate `move $v0,$zero` (+1 insn / wrong branch
* target). Falling off the end here is deliberate (and matches the original). Cookbook §10/B3. */
switch (lzss_state) {
case 0:
goto term_ret;
case 1:
ringIdx = 1;
mask = 1;
token = *src++;
count--;
case 2:
for (;;) {
if (token & mask) {
b = *src++;
ring[ringIdx] = b;
ringIdx = (ringIdx + 1) & 0x3FF;
count--;
*out++ = b;
} else {
nb = *src++;
count--;
code = (code & 0xFF00) | nb;
if (count != 0) {
goto have_low;
}
/* LOAD-BEARING #3 (residual B): `result` is set in the state-3 PREDECESSOR (here,
* before `goto save`), not inside the shared `save:` tail. This makes gcc emit a
* distinct `li $v0,1` per return site instead of cross-jumping/sinking one copy into
* the tail's branch delay slot (reorg.c fill_simple_delay_slots). Cookbook §10/B. */
result = 1;
newState = 3;
goto save;
have_low:
case 3:
nh = *src++;
count--;
/* LOAD-BEARING #1 (residual A), cont.: operand order `(code & 0xFF) | (nh << 8)`,
* NOT `(nh<<8)|(code&0xFF)`. gcc local-alloc.c combine_regs ties a commutative OR's
* result to the FIRST RTL operand that dies; writing `code & 0xFF` first ties the
* result to $v0 (the target reg) → `or $v0,$v0,$v1`. Cookbook §10/A. */
code = (code & 0xFF) | (nh << 8);
readIdx = code & 0x3FF;
if (readIdx == 0) {
lzss_state = 0;
term_ret:
return 0;
}
len = (code >> 10) + 2;
while (len != 0) {
cb = ring[readIdx];
readIdx = (readIdx + 1) & 0x3FF;
ring[ringIdx] = cb;
ringIdx = (ringIdx + 1) & 0x3FF;
*out++ = cb;
len--;
}
}
if (count != 0) {
goto next_bit;
}
result = 1; /* state-4 save predecessor — see LOAD-BEARING #3 */
newState = 4;
save:
lzss_state = newState;
lzss_ringIndex = ringIdx;
lzss_curMask = mask;
lzss_curToken = token;
lzss_outPtr = out;
lzss_partialCode = code;
return result;
next_bit:
case 4:
if (mask == 0x80) {
mask = 1;
token = *src++;
count--;
if (count == 0) {
/* state-2 reload save. The original keeps this as a SEPARATE copy of the 6
* stores (not shared with `save:`). Two more load-bearing constructs: */
register s32 r __asm__("$2");
/* LOAD-BEARING #4 (residual B, state-2): an explicit $v0 local pinned early by a
* read-only input-asm. This forces `li $v0,1` to materialise BEFORE the stores
* (the target schedules the return value first; gcc otherwise, since `li $v0,1`'s
* only use is the shared epilogue, defers it to just before `jr ra`). Cookbook §10/B. */
r = 1;
__asm__ __volatile__("" : : "r"(r));
newState = 2;
lzss_state = newState;
lzss_ringIndex = ringIdx;
lzss_curMask = mask;
lzss_curToken = token;
lzss_outPtr = out;
lzss_partialCode = code;
/* LOAD-BEARING #5 (the cross-jump barrier): a zero-byte volatile asm. gcc 2.7.2
* -O2 jump.c find_cross_jump would otherwise MERGE this save with the identical
* `save:` tail (→111 insns); an ASM_INPUT node makes it bail (lose=1) so both
* survive (→122, the correct count). No -fno-crossjumping before gcc 3.3. Cookbook §5a. */
__asm__ __volatile__("" ::: "memory");
return r;
}
} else {
mask <<= 1;
}
}
}
}
INCLUDE_ASM("asm/nonmatchings/800", func_80018918);
INCLUDE_ASM("asm/nonmatchings/800", func_800189A8);
INCLUDE_ASM("asm/nonmatchings/800", func_80018A20);
INCLUDE_ASM("asm/nonmatchings/800", func_80018C64);
INCLUDE_ASM("asm/nonmatchings/800", func_80018CE8);
INCLUDE_ASM("asm/nonmatchings/800", func_80018E78);
INCLUDE_ASM("asm/nonmatchings/800", func_80018E9C);
void func_80018F20(s32 param_1) {
u32 uVar3;
s32 iVar2;
u32 uVar1;
uVar3 = 2;
do {
iVar2 = param_1 + uVar3;
uVar1 = *(u8 *)(iVar2 + 0x32);
if (uVar1 - 0x51 < 0x5f) {
*(u8 *)(iVar2 + 0x32) = 0x80;
} else if ((uVar1 & 0xff) < 8) {
*(u8 *)(iVar2 + 0x32) = 0;
} else if ((uVar1 & 0xff) >= 0xf8) {
*(u8 *)(iVar2 + 0x32) = 0xff;
}
uVar3 = uVar3 + 1;
} while (uVar3 < 8);
}
INCLUDE_ASM("asm/nonmatchings/800", func_80018F88);
INCLUDE_ASM("asm/nonmatchings/800", func_80018FC8);
extern s32 D_800747C8;
void func_80019018(void) {
D_800747C8 = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80019028);
INCLUDE_ASM("asm/nonmatchings/800", func_8001903C);
INCLUDE_ASM("asm/nonmatchings/800", func_80019064);
INCLUDE_ASM("asm/nonmatchings/800", func_800190AC);
extern s32 D_800747C0;
s32 func_80019198(void) {
return D_800747C0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_800191A8);
INCLUDE_ASM("asm/nonmatchings/800", func_800191BC);
INCLUDE_ASM("asm/nonmatchings/800", func_800191D4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001923C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001931C);
extern s32 debugBinPresent;
s32 func_80019378(void) {
return debugBinPresent;
}
extern s32 debugBinPresent;
void func_80019388(s32 arg0) {
debugBinPresent = arg0;
}
extern s32 D_800747D4;
s32 func_80019398(void) {
return D_800747D4;
}
extern s32 D_800747D4;
void func_800193A8(s32 arg0) {
D_800747D4 = arg0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_800193B8);
#ifdef NON_MATCHING
extern void LoaderResetReadState(void);
extern int VSync(int mode);
extern CdlFILE D_80063058;
extern char cdpath_DEBUG_BIN[];
extern u8 D_80062C38; /* path table entry[0].file (CdlFILE), entries stride 0x30; names at -0x14 */
extern u8 D_80062C68; /* path entry[1].file.pos (CdlLOC), the 8 .CD files, stride 0x30 */
extern s32 debugBinPresent;
extern s32 D_800747D4;
extern s32 D_80063074;
extern s32 D_800747D8;
extern u8 cdFileLocTable[]; /* out: {CdlLOC pos; u32 size} per sub-file, 8B stride */
extern u8 D_800AE834; /* cdFileLocTable + 4 (the size field) */
extern s32 listCdBuffer; /* LIST.CD content: 8B records {value; size} */
extern u8 D_80180004; /* listCdBuffer + 4 (the size field) */
/* file-loader directory resolver (boot @0x800101fc): probe \DEBUG.BIN;1, resolve the 21
* CdPathTable entries via CdSearchFile, read LIST.CD (0xE40 B) into listCdBuffer, then build
* cdFileLocTable (CdlLOC+size per sub-file) over the 8 .CD files. Phase 3 T2.
* NON_MATCHING: logically faithful, structurally close (138 vs 133 ins) but not byte-exact.
* Residual is register allocation / loop-invariant hoisting — the target keeps &D_80063058,
* &D_80062C38, &D_80062C68 in callee-saved regs and derives the name arg as (base - 0x14)
* rather than a separate symbol; a multi-iteration / decomp-permuter target for a later pass. */
void LoaderInitFileTable(void) {
CdlFILE *res;
int tries;
int pathOff;
int pathN;
int base;
int n;
int fileIdx;
int bufIdx;
int j;
int outer;
int locOff;
int dstOff;
int srcOff;
int *pCount;
int *pOff;
CdlLOC *p;
LoaderResetReadState();
tries = 0;
do {
res = CdSearchFile(&D_80063058, cdpath_DEBUG_BIN);
tries++;
if (res != (CdlFILE *)-1) {
break;
}
} while (tries < 0x10);
pathN = 0;
pathOff = 0;
debugBinPresent = (res != (CdlFILE *)0);
D_800747D4 = 1;
D_80063074 = 0;
D_800747D8 = 0;
do {
do {
res = CdSearchFile((CdlFILE *)(&D_80062C38 + pathOff), (char *)(&D_80062C38 - 0x14 + pathOff));
} while ((u32)((int)res + 1) < 2);
pathN++;
pathOff += 0x30;
} while (pathN < 0x15);
do {
fileIdx = 0;
n = CdReadRequest(&D_80062C38, &listCdBuffer, 0xE40, 0);
if (n != 0) {
break;
}
VSync(0);
} while (1);
bufIdx = 0;
outer = 0;
locOff = 0;
pCount = &listCdBuffer;
do {
base = CdPosToInt((CdlLOC *)(&D_80062C68 + locOff));
n = *pCount;
pCount += 2;
bufIdx++;
j = 0;
if (n > 0) {
dstOff = fileIdx * 8;
p = (CdlLOC *)(cdFileLocTable + dstOff);
srcOff = bufIdx * 8;
pOff = &listCdBuffer + bufIdx * 2;
do {
if (*pOff != 0) {
CdIntToPos(*pOff + base, p);
*(s32 *)(&D_800AE834 + dstOff) = *(s32 *)(&D_80180004 + srcOff);
}
pOff += 2;
srcOff += 8;
pCount += 2;
bufIdx++;
p += 2;
dstOff += 8;
j++;
fileIdx++;
} while (j < n);
}
outer++;
locOff += 0x30;
} while (outer < 8);
}
#else
INCLUDE_ASM("asm/nonmatchings/800", LoaderInitFileTable);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_80019930);
extern s32 cdReq_sink;
extern s32 cdReq_curSector;
extern s32 D_800BA1B4;
extern s32 D_800747F0;
extern s32 D_800747F4;
extern s32 cdReq_state;
extern s32 D_800AE6F8;
extern s32 D_800AE6FC;
extern s32 D_800AE700;
extern s32 cdReq_wordsRemaining;
extern s32 cdReq_drainPhase;
extern u8 D_800AE798;
extern u8 D_800AE799;
extern s32 D_800AE70C;
void LoaderResetReadState(void) {
cdReq_sink = 0x80010000;
cdReq_curSector = 0;
D_800BA1B4 = 0;
D_800747F0 = 0;
D_800747F4 = 0;
cdReq_state = 0;
D_800AE6F8 = 0;
D_800AE6FC = 0;
D_800AE700 = 0;
cdReq_wordsRemaining = 1;
cdReq_drainPhase = 0;
D_800AE798 = 0;
D_800AE799 = 0;
D_800AE70C = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80019A10);
extern s32 CdQueueBusy(void);
extern void CdReadStateMachine(int);
extern s32 cdReq_curSector;
extern void *cdReq_dest;
extern s32 cdReq_size;
extern void *cdReq_cdlFile;
extern s32 cdReq_result;
extern s32 D_800AE720;
extern s32 D_800AE724;
/* Read-request dispatcher (Phase 3 T2). Refuse while CdQueueBusy(); dedup on the request's
* start sector (*cdlFile) vs the in-flight cdReq_curSector; stash dest/size/cdlFile/mode into
* the control block, set the "first read" flag D_800AE720 = (mode == 0), drive the state
* machine, return cdReq_result. */
s32 CdReadRequest(int *cdlFile, void *dest, s32 size, s32 mode) {
s32 sector;
if (CdQueueBusy() != 0) {
return 0;
}
if (cdReq_curSector == 0) {
sector = *cdlFile;
} else {
sector = *cdlFile;
if (sector != cdReq_curSector) {
return 0;
}
}
cdReq_dest = dest;
cdReq_size = size;
cdReq_cdlFile = cdlFile;
D_800AE724 = mode;
D_800AE720 = 0;
cdReq_curSector = sector;
if (mode == 0) {
D_800AE720 = 1;
}
CdReadStateMachine(0);
return cdReq_result;
}
#ifdef NON_MATCHING
/* libcd low-level command API (the loader uses raw CdControl, NOT the PsyQ CdRead() wrapper;
* not in psyq/libcd.h yet). */
extern int CdControl(u8 com, u8 *param, u8 *result);
extern int CdSync(int mode, u8 *result);
extern void CdFlush(void);
extern void *CdReadyCallback(void *func);
extern void CdReadSectorReadyCB(char); /* the CdlReadN data-ready callback @0x8001A338 */
extern void start(void); /* EXE entry — used as the idle "sink" sentinel */
extern int func_8002FD14(int buf, int len); /* per-sector consumer (drains the queued list) */
extern void func_8001A0FC(void);
extern int func_8001A114(void);
/* cdReq_* async-read control block (Phase 3 T2); the D_800AE* are its unnamed members. */
extern int cdReq_state;
extern int cdReq_retry;
extern int cdReq_result; /* return-by-global: 0 = still busy, 1 = done */
extern u8 cdReq_cdResult; /* CdControl status byte (bit 0x10 = error) */
extern void *cdReq_cdlFile; /* seek target (a CdlLOC*) */
extern int cdReq_posInt;
extern int cdReq_timeout;
extern int cdReq_size; /* bytes to read */
extern void *cdReq_dest; /* read destination */
extern s32 cdReq_sink; /* sector sink address (dest while reading, &start idle) */
extern int cdReq_wordsRemaining;
extern int cdReq_drainPhase; /* 0 = reading, 1 = drained, 2 = finished */
extern void *cdReq_savedReadyCB; /* prior CdReadyCallback, restored on stop */
extern int cdReq_curSector;
extern u8 D_800AE740; /* CdlSetmode mode-byte buffer (0xA0) */
extern int D_800AE6E8; /* CdSync result scratch */
extern int D_800AE6F8;
extern s32 D_800AE70C; /* last/idle CdlLOC (held as a word) */
extern int D_800AE71C; /* count of queued sectors to drain (state 7) */
extern int D_800AE724; /* base of the queued {ptr,len} sector list */
extern int D_800AE6FC;
extern int D_800AE700;
extern u8 D_800AE798;
extern u8 D_800AE799;
/* Hand-rolled polled async CD reader: one state step per call, switch(cdReq_state). Sequence
* SetMode(0xA0) -> SeekL(+CdPosToInt) -> ReadN(+CdReadSectorReadyCB sector drain) -> Pause/Flush.
* Progress is returned via cdReq_result (0 busy / 1 done). The game does NOT use PsyQ CdRead()/
* CdReadSync(). pauseAfterSeek != 0 stops after the seek (state 8) instead of reading.
* Provenance: static trace, Phase 3 T2 (verified).
* NON_MATCHING: logically faithful to the Ghidra decompile; not byte-exact — a large switch state
* machine whose register allocation + jump-table placement are a later byte-match pass. */
void CdReadStateMachine(int pauseAfterSeek) {
int n;
int i;
int off;
switch (cdReq_state) {
case 0:
cdReq_retry = 0;
D_800AE71C = 0;
D_800AE70C = 0;
D_800AE740 = 0xA0;
CdControl(0x0E, &D_800AE740, &cdReq_cdResult); /* CdlSetmode */
if ((cdReq_cdResult & 0x10) == 0) {
cdReq_state++;
goto state1;
}
break;
case 1:
state1:
D_800AE6E8 = CdSync(1, &cdReq_cdResult);
if (D_800AE6E8 == 0) { cdReq_result = 0; return; }
if (D_800AE6E8 == 5) { cdReq_state = 0; cdReq_result = 0; return; }
if (D_800AE6E8 != 2) { cdReq_result = 0; return; }
cdReq_retry = 0;
cdReq_state++;
D_800AE6E8 = 2;
state2:
if (cdReq_retry + 1 < 3) {
cdReq_retry++;
cdReq_result = 0;
return;
}
cdReq_state++;
cdReq_retry = 0;
cdReq_result = 0;
return;
case 2:
goto state2;
case 3:
CdControl(0x15, (u8 *)cdReq_cdlFile, &cdReq_cdResult); /* CdlSeekL */
if ((cdReq_cdResult & 0x10) == 0) {
cdReq_timeout = 0;
cdReq_posInt = CdPosToInt((CdlLOC *)cdReq_cdlFile);
cdReq_state++;
goto state4;
}
break;
case 4:
state4:
D_800AE6E8 = CdSync(1, &cdReq_cdResult);
if (D_800AE6E8 == 5) {
cdReq_retry++;
flushRetry:
CdFlush();
cdReq_state = 3;
cdReq_result = 0;
return;
}
if (D_800AE6E8 == 0) { cdReq_result = 0; return; }
if (D_800AE6E8 != 2) {
cdReq_result = 0;
cdReq_timeout++;
if (cdReq_timeout < 0xB5) { cdReq_result = 0; return; }
goto flushRetry;
}
if (pauseAfterSeek == 0) {
cdReq_state++;
goto state5;
}
CdControl(0x09, (u8 *)0, &cdReq_cdResult); /* CdlPause */
if ((cdReq_cdResult & 0x10) == 0) {
cdReq_state = 8;
D_800AE70C = *(s32 *)cdReq_cdlFile;
cdReq_result = 0;
return;
}
break;
case 5:
state5:
cdReq_drainPhase = 0;
if (cdReq_size < 1) {
D_800AE6F8 = 0;
} else {
int bytes = cdReq_size + 3;
D_800AE6F8 = 3;
if (bytes < 0) bytes = cdReq_size + 6; /* round-up word count, neg-safe */
cdReq_wordsRemaining = bytes >> 2;
D_800AE798 = 1;
cdReq_sink = (s32)cdReq_dest;
}
cdReq_savedReadyCB = CdReadyCallback(CdReadSectorReadyCB);
CdControl(0x06, (u8 *)0, &cdReq_cdResult); /* CdlReadN */
if ((cdReq_cdResult & 0x10) == 0) {
cdReq_retry = 0;
cdReq_state++;
goto state6;
}
break;
case 6:
state6:
if (cdReq_drainPhase != 1) {
if (cdReq_drainPhase == 2) {
CdReadyCallback(cdReq_savedReadyCB);
cdReq_state = 0;
cdReq_result = 0;
return;
}
cdReq_retry++;
if (cdReq_retry > 299) {
CdReadyCallback(cdReq_savedReadyCB);
cdReq_state = 0;
CdFlush();
cdReq_result = 0;
return;
}
cdReq_result = 0;
return;
}
CdReadyCallback(cdReq_savedReadyCB);
CdControl(0x09, (u8 *)0, &cdReq_cdResult); /* CdlPause */
if ((cdReq_cdResult & 0x10) == 0) {
cdReq_state += (D_800AE71C == 0) ? 2 : 1; /* -> 8 (no drain) or 7 (drain) */
cdReq_result = 0;
return;
}
break;
case 7:
n = 0;
if (D_800AE71C > 0) {
off = 0;
do {
do {
i = func_8002FD14(*(int *)(D_800AE724 + off),
*(int *)(D_800AE724 + off + 4));
} while (i == 0);
n++;
off = n * 8;
} while (n < D_800AE71C);
}
cdReq_state++;
cdReq_result = 0;
return;
case 8:
D_800AE6E8 = CdSync(1, &cdReq_cdResult);
if (D_800AE6E8 == 2) {
cdReq_sink = (s32)start;
cdReq_state = 0;
D_800AE6F8 = 0;
D_800AE6FC = 0;
D_800AE700 = 0;
cdReq_curSector = 0;
D_800AE70C = 0;
cdReq_wordsRemaining = 1;
cdReq_drainPhase = 0;
D_800AE798 = 0;
D_800AE799 = 0;
cdReq_result = 1;
return;
}
if (D_800AE6E8 != 5) { cdReq_result = 0; return; }
CdFlush();
CdControl(0x09, (u8 *)0, &cdReq_cdResult); /* CdlPause */
if ((cdReq_cdResult & 0x10) == 0) { cdReq_result = 0; return; }
break;
case 9:
func_8001A0FC();
cdReq_state++;
/* fall through to state 10 */
case 10:
D_800AE6E8 = func_8001A114();
if (D_800AE6E8 != 0) {
cdReq_state = 0;
cdReq_result = 0;
return;
}
cdReq_result = 0;
return;
default:
goto setDefault;
}
cdReq_state = 9;
setDefault:
cdReq_result = 0;
return;
}
#else
INCLUDE_ASM("asm/nonmatchings/800", CdReadStateMachine);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_8001A0FC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001A114);
#ifdef NON_MATCHING
typedef struct { short x, y, w, h; } RECT; /* libgpu RECT (VRAM rectangle) */
extern int CdGetSector(void *madr, int nsector);
extern void LoadImage(RECT *rect, u32 *data); /* libgpu VRAM upload */
extern int func_8002FC64(int nbytes, u32 *src); /* stage/copy a payload run */
extern int func_8002FB08(int entry); /* kick off a queued list entry */
extern void func_8002FDC8(void); /* finalize the queued transfer */
extern void func_80018714(void); /* reset LZSS sector state */
/* shared cdReq_ control block (see CdReadStateMachine) + this callback's members */
extern int cdReq_posInt;
extern int cdReq_size;
extern int cdReq_wordsRemaining;
extern int cdReq_drainPhase;
extern void *cdReq_dest;
extern s32 cdReq_sink;
extern u32 lzss_sectorStagingBuf[]; /* 0x80079A70 — PAC header lands here ([0] = 'PAC' magic) */
extern u8 cdReq_sectorHdrBuf[]; /* sub-header scratch (3 words -> CdPosToInt) */
extern u8 D_80079A74; /* PAC type */
extern u8 D_80079A75; /* PAC flags -> D_800AE798 */
extern int D_80079A78; /* PAC sub-count (textures) */
extern int D_80079A7C; /* PAC payload size (bytes) */
extern int D_800AE6F8; /* load phase (PAC-type dispatcher state) */
extern u8 D_800AE798; /* saved PAC flags (nonzero = more sectors follow) */
extern int D_800AE704; /* texture sector index (0..3, round-robin) */
extern short D_800AE710, D_800AE712; /* VRAM dst x,y of the current tile (a RECT @0xAE710) */
extern short D_800AE714, D_800AE716; /* tile w,h (0x20 x 0x20) */
extern u8 D_800AE758[]; /* 64-byte present bitmask (which tiles are sent) */
extern u8 D_800AE79A, D_800AE79B; /* bit / byte cursor into the bitmask */
extern RECT *D_800AE718; /* current texture-rect pointer (PAC type 6) */
extern int D_800AE71C; /* queued-entry count */
extern int D_800AE720; /* "transfer already in progress" guard */
extern int D_800AE724; /* base of the queued {ptr,len} list */
extern void *D_80072C80; /* a fixed destination pointer (PAC type 7) */
extern u32 D_8007A280[]; /* texture RECT array (read from CD) */
extern u32 D_8007A310[]; /* texture pixel data (read from CD) */
/* CdReadyCallback for CdReadStateMachine (registered in its state 5). Per CD data-ready interrupt,
* drain one sector and dispatch on the load phase D_800AE6F8: parse the PAC header, then per PAC
* type either upload tiles to VRAM (LoadImage), copy raw sectors to cdReq_sink, or decompress via
* LzssDecodeSector (this is its ONLY caller). reason: 1 = data-ready, 5 = end/error.
* Provenance: static trace, Phase 3 T2/T4 (verified).
* NON_MATCHING: faithful translation of the Ghidra decompile — logically faithful, not byte-verified
* (large interrupt callback; register allocation + jump-table placement are a later byte-match pass). */
void CdReadSectorReadyCB(char reason) {
void *dst;
int pos;
int i, n;
if (reason != 1) goto endReason;
CdGetSector(cdReq_sectorHdrBuf, 3);
pos = CdPosToInt((CdlLOC *)cdReq_sectorHdrBuf);
if (pos != cdReq_posInt) { /* sector out of order -> abort the drain */
if (D_800AE6F8 == 4) func_8002FDC8();
cdReq_drainPhase = 2;
return;
}
cdReq_posInt = pos + 1;
switch (D_800AE6F8) {
case 0: /* expect a PAC header */
CdGetSector(lzss_sectorStagingBuf, 4);
if (lzss_sectorStagingBuf[0] != 0x434150) goto abortDrain; /* "PAC" magic? */
D_800AE798 = D_80079A75;
switch (D_80079A74) { /* PAC type */
case 0:
case 5: /* tiled texture: scan the present-bitmask */
D_800AE704 = 0;
CdGetSector(D_800AE758, 0x10);
D_800AE716 = 0x20; D_800AE714 = 0x20;
D_800AE712 = 0; D_800AE710 = 0;
D_800AE79A = 1; D_800AE79B = 0;
while (D_800AE79B < 0x40) {
if ((D_800AE79A & D_800AE758[D_800AE79B]) != 0) goto tilePhase;
if (D_800AE79A == 0x80) { D_800AE79A = 1; D_800AE79B++; }
else D_800AE79A <<= 1;
D_800AE710 += 0x20;
if (D_800AE710 > 0x3FF) { D_800AE710 = 0; D_800AE712 += 0x20; }
}
D_800AE6F8 = (D_800AE798 == 0) ? 0 : 2;
tilePhase:
D_800AE6F8++;
break;
case 1:
dst = cdReq_dest;
goto setSink;
case 2:
if (D_800AE720 != 0) goto phaseDone;
dst = *(void **)(D_800AE71C * 8 + D_800AE724 + 4);
goto setSink;
case 3:
if (D_800AE720 != 0) goto phaseDone;
do { i = func_8002FB08(*(int *)(D_800AE71C * 8 + D_800AE724)); } while (i == 0);
D_800AE6F8 = 4;
cdReq_wordsRemaining = D_80079A7C - 0x800;
break;
case 4:
D_800AE6F8 = 5;
cdReq_wordsRemaining = (D_80079A7C - 0x7FD) >> 2;
cdReq_sink = (s32)cdReq_dest;
func_80018714();
break;
case 6: /* multiple TIMs: LoadImage each */
CdGetSector(D_8007A280, 0x1FC);
n = D_80079A78;
{
u32 *p = D_8007A310;
i = 0;
D_800AE718 = (RECT *)D_8007A280;
if (n > 0) {
do {
LoadImage(D_800AE718, p);
i++;
p += D_800AE718->w / 2;
D_800AE718++;
} while (i < n);
}
}
goto sectorDone;
case 7:
dst = D_80072C80;
if (cdReq_size < 0) goto phaseDone;
setSink:
D_800AE6F8 = 3;
cdReq_wordsRemaining = (D_80079A7C - 0x7FD) >> 2;
cdReq_sink = dst;
break;
case 8:
D_800AE6F8 = 6;
cdReq_wordsRemaining = (D_80079A7C - 0x7FD) >> 2;
break;
}
break;
case 1: /* stream tile pixels to VRAM */
i = D_800AE704 * 0x200;
CdGetSector(&lzss_sectorStagingBuf[i], 0x200);
LoadImage((RECT *)&D_800AE710, &lzss_sectorStagingBuf[i]);
D_800AE704 = (D_800AE704 + 1) & 3;
do {
if (D_800AE79A == 0x80) { D_800AE79A = 1; D_800AE79B++; }
else D_800AE79A <<= 1;
if (D_800AE79B > 0x3F) goto sectorDone;
D_800AE710 += 0x20;
if (D_800AE710 > 0x3FF) { D_800AE710 = 0; D_800AE712 += 0x20; }
} while ((D_800AE79A & D_800AE758[D_800AE79B]) == 0);
break;
case 3: /* raw copy to cdReq_sink */
if (cdReq_wordsRemaining < 0x201) {
CdGetSector((void *)cdReq_sink, cdReq_wordsRemaining);
sectorDone:
D_800AE6F8 = (D_800AE798 == 0) ? 0 : 2;
} else {
CdGetSector((void *)cdReq_sink, 0x200);
cdReq_wordsRemaining -= 0x200;
cdReq_sink += 0x800;
}
break;
case 4: /* staged copy via func_8002FC64 */
if (cdReq_wordsRemaining < 0x801) {
n = cdReq_wordsRemaining + 3;
if (n < 0) n = cdReq_wordsRemaining + 6;
CdGetSector(lzss_sectorStagingBuf, n >> 2);
if (func_8002FC64(cdReq_wordsRemaining, lzss_sectorStagingBuf) == 0) {
stageFail:
func_8002FDC8();
D_800AE6F8 = 7;
} else {
D_800AE71C++;
if (D_800AE798 != 0) goto phaseDone;
D_800AE6F8 = 0;
}
} else {
CdGetSector(lzss_sectorStagingBuf, 0x200);
i = func_8002FC64(0x800, lzss_sectorStagingBuf);
cdReq_sink += 0x800;
cdReq_wordsRemaining -= 0x800;
if (i == 0) goto stageFail;
}
break;
case 5: /* LZSS decompress one sector */
CdGetSector(lzss_sectorStagingBuf, 0x200);
if (LzssDecodeSector(lzss_sectorStagingBuf) == 0) goto sectorDone;
break;
case 6: /* countdown the remaining words */
cdReq_wordsRemaining -= 0x200;
if (cdReq_wordsRemaining < 1) {
if (D_800AE798 != 0) goto phaseDone;
D_800AE6F8 = 0;
}
break;
}
if (D_800AE6F8 == 2) {
phaseDone: /* (reached by the switch above or by goto) */
D_800AE6F8 = 2;
cdReq_drainPhase = 1;
} else if (D_800AE6F8 == 7) {
cdReq_drainPhase = 2;
}
endReason:
if (reason == 5) {
if (D_800AE6F8 == 4) func_8002FDC8();
abortDrain:
cdReq_drainPhase = 2;
}
return;
}
#else
INCLUDE_ASM("asm/nonmatchings/800", CdReadSectorReadyCB);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_8001A9D8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001A9F8);
extern s32 cdReq_curSector;
s32 func_8001AA78(void) {
return cdReq_curSector;
}
extern s32 cdReq_curSector;
void func_8001AA88(s32 arg0) {
cdReq_curSector = arg0;
}
void func_8001AA98(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001AAA0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001AAD0);
void func_8001ABB4(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001ABBC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001ACF0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001AE90);
INCLUDE_ASM("asm/nonmatchings/800", func_8001AF04);
INCLUDE_ASM("asm/nonmatchings/800", func_8001AF34);
INCLUDE_ASM("asm/nonmatchings/800", func_8001B0D4);
extern s32 D_800747E8;
s32 func_8001B22C(void) {
return D_800747E8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001B23C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001B26C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001B324);
INCLUDE_ASM("asm/nonmatchings/800", func_8001B34C);
extern s32 resLoad_lastId;
s32 func_8001B374(void) {
return resLoad_lastId;
}
extern s32 resLoad_state;
void func_8001B384(void) {
resLoad_state = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001B394);
#ifdef NON_MATCHING
extern int func_8001A114(void);
extern void func_8001B710(void);
extern void func_8002D4C8(int arg0, int arg1);
extern void func_80036D58(int arg0);
extern int StreamLoadStateMachine(int arg0, void *loc, int n);
extern s32 CdQueueBusy(void); /* defined later in this file */
extern s32 ResourceGetCdLoc(s16 arg0); /* defined later in this file */
extern s32 resLoad_state;
extern s32 resLoad_curId;
extern s32 resLoad_lastId;
extern s32 resLoad_loadedFileIdx;
extern s32 resLoad_result;
extern s32 cdReq_curSector;
extern u8 resourceIdMap[]; /* 6B entries {s16 fileIdx; s16 D_8006313A; s16 D_8006313C} */
extern u8 D_8006313A;
extern u8 D_8006313C;
extern u8 cdFileLocTable[];
extern s32 D_800AE6F4;
extern s32 D_800AE70C;
/* loads a resource by resLoad_curId via resourceIdMap; load-once cache
* (resLoad_lastId/resLoad_loadedFileIdx). field0<0 -> non-CD path func_80036D58; else
* ResourceGetCdLoc -> StreamLoadStateMachine -> func_8002D4C8 post-process. Polled on
* resLoad_state; done flag resLoad_result. Phase 3 T3.
* NON_MATCHING: logically faithful (Ghidra-derived), body close but not byte-exact. Residuals:
* (1) block placement — the target lays state blocks 0->1->2->3 in order under a top beq-chain
* dispatch (order 1,0,2,3); this nested-if emits the state-2/3 block inline. (2) frame 0x38 vs
* 0x28 (~16B reserved locals the original keeps). (3) func_8002D4C8 arg is field2 & 0xFFFF.
* A switch() risks a rodata jump table (target has none). A later structural / permuter pass. */
void ResourceLoadStateMachine(void) {
int result;
result = 0;
if (resLoad_state != 1) {
if (resLoad_state != 0) {
if (resLoad_state == 2) {
D_800AE6F4 = 0;
D_800AE70C = 0;
resLoad_state = 3;
} else if (resLoad_state != 3) {
goto done;
}
if (func_8001A114() != 0) {
resLoad_state = 0;
}
goto done;
}
if (resLoad_curId == resLoad_lastId) {
resLoad_result = 1;
return;
}
if (*(s16 *)(resourceIdMap + resLoad_curId * 6) == resLoad_loadedFileIdx &&
*(s16 *)(&D_8006313C + resLoad_curId * 6) != 0) {
func_8002D4C8(*(s16 *)(&D_8006313C + resLoad_curId * 6), 0);
resLoad_lastId = resLoad_curId;
resLoad_result = 1;
return;
}
if (CdQueueBusy() != 0) {
goto done;
}
if (*(s16 *)(resourceIdMap + resLoad_curId * 6) < 0) {
func_80036D58(*(s16 *)(&D_8006313A + resLoad_curId * 6));
resLoad_result = 1;
return;
}
if (ResourceGetCdLoc((s16)resLoad_curId) == 0) {
resLoad_result = 1;
return;
}
if (cdReq_curSector != 0 &&
*(s32 *)(cdFileLocTable + *(s16 *)(resourceIdMap + resLoad_curId * 6) * 8) != cdReq_curSector) {
goto done;
}
cdReq_curSector = *(s32 *)(cdFileLocTable + *(s16 *)(resourceIdMap + resLoad_curId * 6) * 8);
resLoad_state++;
}
result = StreamLoadStateMachine(*(s16 *)(&D_8006313A + resLoad_curId * 6),
cdFileLocTable + *(s16 *)(resourceIdMap + resLoad_curId * 6) * 8, 0x10);
if (result == 2) {
resLoad_state++;
result = 0;
}
done:
if (result != 0) {
resLoad_loadedFileIdx = *(s16 *)(resourceIdMap + resLoad_curId * 6);
if (*(s16 *)(&D_8006313C + resLoad_curId * 6) > 0) {
func_8002D4C8(*(s16 *)(&D_8006313C + resLoad_curId * 6), 0);
resLoad_lastId = resLoad_curId;
if (resLoad_curId == 0x3D) {
func_8001B710();
}
}
resLoad_state = 0;
cdReq_curSector = 0;
}
resLoad_result = result;
}
#else
INCLUDE_ASM("asm/nonmatchings/800", ResourceLoadStateMachine);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_8001B710);
extern u8 resourceIdMap[];
extern u8 cdFileLocTable[];
s32 ResourceGetCdLoc(s16 arg0) {
s32 idx = *(s16 *)(resourceIdMap + arg0 * 6);
return *(s32 *)(cdFileLocTable + idx * 8);
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001B7C4);
extern s32 D_800747FC;
void func_8001B85C(void) {
D_800747FC = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001B86C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BA84);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BADC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BB60);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BBBC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BC6C);
INCLUDE_ASM("asm/nonmatchings/800", SsGetMute);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BDA0);
extern s32 D_800747EC;
void func_8001BE20(void) {
D_800747EC = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001BE30);
extern s32 D_80063074;
s32 func_8001BFA0(void) {
return D_80063074 & 0x1;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001BFB0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001BFD0);
extern s32 D_800747D8;
s32 func_8001BFE8(void) {
return D_800747D8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001BFF8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C00C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C044);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C0C8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C14C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C1E4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C214);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C2C4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C320);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C448);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C4A4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C558);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C5B8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C6E4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C744);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C7B0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C810);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C8C4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C924);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C97C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001C9D0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CA1C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CA88);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CB00);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CB6C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CBDC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CC3C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CCA0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CD04);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CD50);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CD9C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CDE8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CE28);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CE68);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CEC0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CF00);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CF30);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CF48);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CFB8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001CFDC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D050);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D074);
void func_8001D0E8(s32 arg0, s32 arg1, s32 arg2) {
*(s16 *)(arg0 + 0x28) = arg1;
*(s16 *)(arg0 + 0x2A) = arg2;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001D0F4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D130);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D150);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D16C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D1C4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D388);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D3FC);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D70C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001D8C4);
INCLUDE_ASM("asm/nonmatchings/800", func_8001DA34);
INCLUDE_ASM("asm/nonmatchings/800", func_8001E094);
INCLUDE_ASM("asm/nonmatchings/800", func_8001E378);
INCLUDE_ASM("asm/nonmatchings/800", func_8001E668);
INCLUDE_ASM("asm/nonmatchings/800", func_8001E7E0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001EA14);
INCLUDE_ASM("asm/nonmatchings/800", func_8001EFE0);
INCLUDE_ASM("asm/nonmatchings/800", func_8001F730);
void func_8001F974(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_8001F97C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001F9F8);
INCLUDE_ASM("asm/nonmatchings/800", func_8001FB8C);
INCLUDE_ASM("asm/nonmatchings/800", func_8001FC08);
INCLUDE_ASM("asm/nonmatchings/800", func_80020248);
INCLUDE_ASM("asm/nonmatchings/800", func_80020598);
INCLUDE_ASM("asm/nonmatchings/800", func_80020A28);
INCLUDE_ASM("asm/nonmatchings/800", func_80020DA4);
INCLUDE_ASM("asm/nonmatchings/800", func_80020F34);
INCLUDE_ASM("asm/nonmatchings/800", func_80021008);
INCLUDE_ASM("asm/nonmatchings/800", func_80021050);
INCLUDE_ASM("asm/nonmatchings/800", func_8002109C);
INCLUDE_ASM("asm/nonmatchings/800", func_80021120);
INCLUDE_ASM("asm/nonmatchings/800", func_80021174);
INCLUDE_ASM("asm/nonmatchings/800", func_80021284);
INCLUDE_ASM("asm/nonmatchings/800", func_800215F4);
INCLUDE_ASM("asm/nonmatchings/800", func_80021D38);
INCLUDE_ASM("asm/nonmatchings/800", func_800221A8);
INCLUDE_ASM("asm/nonmatchings/800", func_800226C0);
INCLUDE_ASM("asm/nonmatchings/800", func_80023138);
INCLUDE_ASM("asm/nonmatchings/800", func_800233CC);
INCLUDE_ASM("asm/nonmatchings/800", func_800234E4);
INCLUDE_ASM("asm/nonmatchings/800", func_80023570);
INCLUDE_ASM("asm/nonmatchings/800", func_8002374C);
INCLUDE_ASM("asm/nonmatchings/800", func_80023BF0);
INCLUDE_ASM("asm/nonmatchings/800", func_80024054);
INCLUDE_ASM("asm/nonmatchings/800", func_800241C0);
INCLUDE_ASM("asm/nonmatchings/800", func_800242D0);
INCLUDE_ASM("asm/nonmatchings/800", func_800243EC);
INCLUDE_ASM("asm/nonmatchings/800", func_80024448);
INCLUDE_ASM("asm/nonmatchings/800", func_800249F0);
INCLUDE_ASM("asm/nonmatchings/800", func_80024BC0);
INCLUDE_ASM("asm/nonmatchings/800", func_80024DE8);
INCLUDE_ASM("asm/nonmatchings/800", func_80025000);
INCLUDE_ASM("asm/nonmatchings/800", func_8002528C);
INCLUDE_ASM("asm/nonmatchings/800", func_80025504);
INCLUDE_ASM("asm/nonmatchings/800", func_80025818);
INCLUDE_ASM("asm/nonmatchings/800", func_80025A30);
INCLUDE_ASM("asm/nonmatchings/800", func_80025CBC);
INCLUDE_ASM("asm/nonmatchings/800", func_80025EB8);
INCLUDE_ASM("asm/nonmatchings/800", func_80026128);
INCLUDE_ASM("asm/nonmatchings/800", func_800262D8);
INCLUDE_ASM("asm/nonmatchings/800", func_80026514);
INCLUDE_ASM("asm/nonmatchings/800", func_800268D0);
INCLUDE_ASM("asm/nonmatchings/800", func_80026D64);
INCLUDE_ASM("asm/nonmatchings/800", func_80027058);
INCLUDE_ASM("asm/nonmatchings/800", func_80027200);
INCLUDE_ASM("asm/nonmatchings/800", func_800273F4);
INCLUDE_ASM("asm/nonmatchings/800", func_800275BC);
INCLUDE_ASM("asm/nonmatchings/800", func_800277DC);
INCLUDE_ASM("asm/nonmatchings/800", func_800279AC);
INCLUDE_ASM("asm/nonmatchings/800", func_80027BF0);
INCLUDE_ASM("asm/nonmatchings/800", func_80027C10);
INCLUDE_ASM("asm/nonmatchings/800", func_80027D20);
INCLUDE_ASM("asm/nonmatchings/800", func_80027F4C);
INCLUDE_ASM("asm/nonmatchings/800", func_80028200);
void func_80028234(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002823C);
void func_800282FC(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_80028304);
INCLUDE_ASM("asm/nonmatchings/800", func_80028394);
INCLUDE_ASM("asm/nonmatchings/800", func_80028428);
INCLUDE_ASM("asm/nonmatchings/800", func_80028488);
INCLUDE_ASM("asm/nonmatchings/800", func_8002850C);
INCLUDE_ASM("asm/nonmatchings/800", func_80028558);
INCLUDE_ASM("asm/nonmatchings/800", SsUtReverbOff);
INCLUDE_ASM("asm/nonmatchings/800", func_800285CC);
INCLUDE_ASM("asm/nonmatchings/800", func_80028620);
INCLUDE_ASM("asm/nonmatchings/800", func_80028694);
void func_80028A30(void) {
}
void func_80028A38(void) {
}
void func_80028A40(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_80028A48);
INCLUDE_ASM("asm/nonmatchings/800", func_80028C50);
INCLUDE_ASM("asm/nonmatchings/800", func_80028D58);
INCLUDE_ASM("asm/nonmatchings/800", func_80028D78);
INCLUDE_ASM("asm/nonmatchings/800", func_80028D9C);
INCLUDE_ASM("asm/nonmatchings/800", func_80028DBC);
INCLUDE_ASM("asm/nonmatchings/800", func_80028DE0);
INCLUDE_ASM("asm/nonmatchings/800", func_80028E00);
INCLUDE_ASM("asm/nonmatchings/800", func_80028E24);
INCLUDE_ASM("asm/nonmatchings/800", func_80028E44);
INCLUDE_ASM("asm/nonmatchings/800", func_80028E68);
INCLUDE_ASM("asm/nonmatchings/800", func_80028E88);
INCLUDE_ASM("asm/nonmatchings/800", func_80028EAC);
INCLUDE_ASM("asm/nonmatchings/800", func_80028ECC);
INCLUDE_ASM("asm/nonmatchings/800", func_80028EF0);
INCLUDE_ASM("asm/nonmatchings/800", func_80028F10);
INCLUDE_ASM("asm/nonmatchings/800", func_80028F34);
INCLUDE_ASM("asm/nonmatchings/800", func_80028F54);
INCLUDE_ASM("asm/nonmatchings/800", func_80028F78);
INCLUDE_ASM("asm/nonmatchings/800", func_80028F98);
INCLUDE_ASM("asm/nonmatchings/800", func_80028FBC);
INCLUDE_ASM("asm/nonmatchings/800", func_80028FDC);
INCLUDE_ASM("asm/nonmatchings/800", func_80029000);
INCLUDE_ASM("asm/nonmatchings/800", func_80029020);
INCLUDE_ASM("asm/nonmatchings/800", func_80029044);
INCLUDE_ASM("asm/nonmatchings/800", func_8002906C);
INCLUDE_ASM("asm/nonmatchings/800", func_80029094);
INCLUDE_ASM("asm/nonmatchings/800", func_800290BC);
INCLUDE_ASM("asm/nonmatchings/800", func_800290E0);
INCLUDE_ASM("asm/nonmatchings/800", func_80029104);
INCLUDE_ASM("asm/nonmatchings/800", func_80029124);
INCLUDE_ASM("asm/nonmatchings/800", func_80029178);
INCLUDE_ASM("asm/nonmatchings/800", func_800291A0);
INCLUDE_ASM("asm/nonmatchings/800", func_800291B4);
INCLUDE_ASM("asm/nonmatchings/800", func_800291C8);
INCLUDE_ASM("asm/nonmatchings/800", func_800291DC);
INCLUDE_ASM("asm/nonmatchings/800", func_800291F0);
INCLUDE_ASM("asm/nonmatchings/800", func_80029204);
INCLUDE_ASM("asm/nonmatchings/800", func_80029218);
INCLUDE_ASM("asm/nonmatchings/800", func_80029240);
extern s32 D_80075838;
void func_80029254(void) {
D_80075838 = 0;
}
extern s32 D_80075838;
s32 func_80029264(void) {
return D_80075838;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80029274);
INCLUDE_ASM("asm/nonmatchings/800", func_8002931C);
INCLUDE_ASM("asm/nonmatchings/800", func_80029344);
INCLUDE_ASM("asm/nonmatchings/800", func_8002941C);
INCLUDE_ASM("asm/nonmatchings/800", func_80029444);
extern s32 D_80078E80;
s32 func_80029504(void) {
return D_80078E80;
}
extern s32 D_80078E80;
void func_80029514(s32 arg0) {
D_80078E80 = arg0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80029524);
extern s32 D_80078E84;
s32 func_8002953C(void) {
return D_80078E84;
}
extern s32 D_80078E84;
void func_8002954C(s32 arg0) {
D_80078E84 = arg0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002955C);
extern s32 D_80078E88;
s32 func_8002957C(void) {
return D_80078E88;
}
extern s32 D_80078E88;
void func_8002958C(s32 arg0) {
D_80078E88 = arg0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002959C);
INCLUDE_ASM("asm/nonmatchings/800", func_800295D4);
INCLUDE_ASM("asm/nonmatchings/800", func_80029664);
INCLUDE_ASM("asm/nonmatchings/800", func_80029690);
INCLUDE_ASM("asm/nonmatchings/800", func_800296F8);
INCLUDE_ASM("asm/nonmatchings/800", func_80029774);
INCLUDE_ASM("asm/nonmatchings/800", func_800298BC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002992C);
INCLUDE_ASM("asm/nonmatchings/800", func_80029A58);
INCLUDE_ASM("asm/nonmatchings/800", func_80029A94);
INCLUDE_ASM("asm/nonmatchings/800", func_80029AAC);
INCLUDE_ASM("asm/nonmatchings/800", func_80029AF4);
INCLUDE_ASM("asm/nonmatchings/800", func_80029B4C);
INCLUDE_ASM("asm/nonmatchings/800", func_80029BC8);
INCLUDE_ASM("asm/nonmatchings/800", func_80029C44);
INCLUDE_ASM("asm/nonmatchings/800", func_80029CD4);
INCLUDE_ASM("asm/nonmatchings/800", func_80029D3C);
INCLUDE_ASM("asm/nonmatchings/800", func_80029DB4);
INCLUDE_ASM("asm/nonmatchings/800", func_80029E30);
INCLUDE_ASM("asm/nonmatchings/800", func_80029E94);
INCLUDE_ASM("asm/nonmatchings/800", func_80029EC0);
INCLUDE_ASM("asm/nonmatchings/800", func_80029ED4);
extern s32 D_80078F08;
s32 func_80029FD4(void) {
return D_80078F08;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80029FE4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A04C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A088);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A108);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A1B4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A200);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A234);
extern s32 D_80078EE4;
s32 func_8002A26C(void) {
return D_80078EE4;
}
extern s32 D_80078EE8;
s32 func_8002A27C(void) {
return D_80078EE8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002A28C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A2B0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A2D4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A354);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A400);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A44C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A480);
extern s32 D_80078EEC;
s32 func_8002A4B8(void) {
return D_80078EEC;
}
extern s32 D_80078EF0;
s32 func_8002A4C8(void) {
return D_80078EF0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002A4D8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A4FC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A520);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A544);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A5C4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A670);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A6BC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A6F0);
extern s32 D_80078EFC;
s32 func_8002A728(void) {
return D_80078EFC;
}
extern s32 D_80078F00;
s32 func_8002A738(void) {
return D_80078F00;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002A748);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A76C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A790);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A7B4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A834);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A8E0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A92C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A960);
extern s32 D_80078EF4;
s32 func_8002A998(void) {
return D_80078EF4;
}
extern s32 D_80078EF8;
s32 func_8002A9A8(void) {
return D_80078EF8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002A9B8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002A9DC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AA00);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AA3C);
void func_8002AAAC(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002AAB4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AB64);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AC00);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AC98);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AE60);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AED0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AEE4);
extern s32 D_800760C8;
void func_8002AEF8(void) {
D_800760C8 = 0;
}
s32 func_8002AF08(void) {
return D_800760C8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002AF18);
INCLUDE_ASM("asm/nonmatchings/800", func_8002AF48);
extern s32 D_80075A40;
s32 func_8002AF60(void) {
return D_80075A40;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002AF70);
INCLUDE_ASM("asm/nonmatchings/800", func_8002B00C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002B064);
INCLUDE_ASM("asm/nonmatchings/800", func_8002B08C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002B0B4);
/* DEFERRED: SaveLoadRoutine (0x8002B154) — Phase 7 (session G), per Drew, to Q#5.
* Original intent: the save / PS1 memory-card handler. Referenced by saveHeaderTemplate
* (0x80072DF0) via THREE entry-point pointers: 0x8002B154 / 0x8002B1AC / 0x8002BEA4.
* Dispatch branches on (selector & 7) (case 0 -> +1 counter; 1 -> 7; 2 -> 0x1E; 3 -> 0x23).
* Why deferred (NOT a clean state machine like the 3 CD loaders drafted this session):
* - splat emits ONE 1139-instruction stub spanning 0x8002B154-0x8002C31C with a SINGLE `jr $ra`
* => it is effectively one large MULTI-ENTRY function (the 3 saveHeaderTemplate entries share a
* return; the caller passes args in $s0/$s3) — awkward to express in C at all.
* - Ghidra mis-analyses it: get_code(0x8002B154) returns only a tiny fragment using unaff_s0/
* unaff_s3 (caller-set regs), so there is no faithful whole-function decompile to translate.
* - It is the save-data/memcard format, explicitly Phase-3 Q#5 "format still TBD" — a different
* subsystem from the file/overlay loader cluster (which IS drafted: CdReadStateMachine,
* CdReadSectorReadyCB, StreamLoadStateMachine here + the matched CdReadRequest/CdQueueBusy/…).
* - External helpers it calls (uncharacterised): func_800603BC (x20), func_80060614, func_8006023C,
* func_80060D9C, func_80060AE0, func_8005FFB4, func_8005FD58, func_80061114/524, func_80016714(bzero).
* Re-enable / revisit when Q#5 (save/memcard format) is studied: FIRST fix the Ghidra function
* boundary (make 0x8002B154 span the whole 1139 ins, or model the 3 entry points), re-decompile,
* characterise the func_80060xxx memcard helpers, THEN draft. A wrong faithful-looking draft here
* would be worse than this honest stub (P9/G3). The default build is byte-identical via this stub. */
INCLUDE_ASM("asm/nonmatchings/800", SaveLoadRoutine);
INCLUDE_ASM("asm/nonmatchings/800", func_8002C320);
INCLUDE_ASM("asm/nonmatchings/800", func_8002C3B0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002C410);
INCLUDE_ASM("asm/nonmatchings/800", func_8002C8BC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002C8F4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002CC4C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002CCB4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002CCD8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002CDD8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002CFE4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D034);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D1F0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D240);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D29C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D320);
extern u8 D_800A46BA;
u8 func_8002D4B8(void) {
return D_800A46BA;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002D4C8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D59C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D678);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D6D8);
void func_8002D7F4(void) {
}
extern s32 D_800A4E7C;
void func_8002D7FC(s32 arg0) {
D_800A4E7C = arg0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002D80C);
extern s16 D_8006A990;
void func_8002D834(void) {
D_8006A990 = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002D844);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D858);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D8A8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D8D4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002D904);
INCLUDE_ASM("asm/nonmatchings/800", func_8002DC68);
INCLUDE_ASM("asm/nonmatchings/800", func_8002DF80);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E138);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E5BC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E5F8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E638);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E700);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E79C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E818);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E8DC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002E94C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EA10);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EAB0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EB10);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EBAC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EC10);
INCLUDE_ASM("asm/nonmatchings/800", func_8002ED90);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EDE4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EE64);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EE90);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EEB8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EED8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EFD0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002EFF8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F064);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F0D0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F0F4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F12C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F150);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F1CC);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F248);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F4E4);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F5C8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F620);
extern s16 D_800A4EF0;
s16 func_8002F648(void) {
return D_800A4EF0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_8002F658);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F67C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F714);
INCLUDE_ASM("asm/nonmatchings/800", func_8002F80C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FA3C);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FAE0);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FB08);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FC64);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FD14);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FDC8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FDE8);
INCLUDE_ASM("asm/nonmatchings/800", func_8002FF0C);
INCLUDE_ASM("asm/nonmatchings/800", func_800301A4);
INCLUDE_ASM("asm/nonmatchings/800", func_800301C8);
INCLUDE_ASM("asm/nonmatchings/800", func_80030470);
INCLUDE_ASM("asm/nonmatchings/800", func_800304C8);
INCLUDE_ASM("asm/nonmatchings/800", func_80030538);
INCLUDE_ASM("asm/nonmatchings/800", func_80030634);
INCLUDE_ASM("asm/nonmatchings/800", func_80030730);
INCLUDE_ASM("asm/nonmatchings/800", func_80030A14);
INCLUDE_ASM("asm/nonmatchings/800", func_80030CA4);
INCLUDE_ASM("asm/nonmatchings/800", func_80030D80);
INCLUDE_ASM("asm/nonmatchings/800", func_80030F80);
INCLUDE_ASM("asm/nonmatchings/800", func_800314DC);
INCLUDE_ASM("asm/nonmatchings/800", func_800316F8);
INCLUDE_ASM("asm/nonmatchings/800", func_80031988);
INCLUDE_ASM("asm/nonmatchings/800", func_80031A98);
INCLUDE_ASM("asm/nonmatchings/800", func_80031B7C);
INCLUDE_ASM("asm/nonmatchings/800", func_80031BE0);
INCLUDE_ASM("asm/nonmatchings/800", func_80031CC8);
INCLUDE_ASM("asm/nonmatchings/800", func_80031D70);
INCLUDE_ASM("asm/nonmatchings/800", func_80031DEC);
INCLUDE_ASM("asm/nonmatchings/800", func_80031E94);
INCLUDE_ASM("asm/nonmatchings/800", func_80031F14);
INCLUDE_ASM("asm/nonmatchings/800", func_80031FC8);
INCLUDE_ASM("asm/nonmatchings/800", func_80032048);
INCLUDE_ASM("asm/nonmatchings/800", func_800322A8);
INCLUDE_ASM("asm/nonmatchings/800", func_800324A4);
INCLUDE_ASM("asm/nonmatchings/800", func_80032774);
INCLUDE_ASM("asm/nonmatchings/800", func_80032A74);
INCLUDE_ASM("asm/nonmatchings/800", func_8003310C);
INCLUDE_ASM("asm/nonmatchings/800", func_800331D4);
INCLUDE_ASM("asm/nonmatchings/800", func_8003324C);
INCLUDE_ASM("asm/nonmatchings/800", func_80033324);
INCLUDE_ASM("asm/nonmatchings/800", func_80033398);
INCLUDE_ASM("asm/nonmatchings/800", func_8003350C);
INCLUDE_ASM("asm/nonmatchings/800", func_800335B8);
INCLUDE_ASM("asm/nonmatchings/800", func_800336A8);
INCLUDE_ASM("asm/nonmatchings/800", func_8003388C);
INCLUDE_ASM("asm/nonmatchings/800", func_800342E8);
INCLUDE_ASM("asm/nonmatchings/800", func_80034314);
INCLUDE_ASM("asm/nonmatchings/800", func_80034650);
INCLUDE_ASM("asm/nonmatchings/800", func_800346D0);
INCLUDE_ASM("asm/nonmatchings/800", func_800347C8);
INCLUDE_ASM("asm/nonmatchings/800", func_80034844);
INCLUDE_ASM("asm/nonmatchings/800", func_800348A8);
INCLUDE_ASM("asm/nonmatchings/800", func_8003491C);
INCLUDE_ASM("asm/nonmatchings/800", func_80034A54);
INCLUDE_ASM("asm/nonmatchings/800", func_80034A9C);
INCLUDE_ASM("asm/nonmatchings/800", func_80034AE0);
INCLUDE_ASM("asm/nonmatchings/800", func_80034B0C);
INCLUDE_ASM("asm/nonmatchings/800", func_80034B3C);
extern s32 D_8006AEF8;
extern s32 D_8006AEFC;
extern u8 D_80076214;
extern u8 D_8007620C;
/* CD read-queue status: head==tail (D_8006AEF8/FC equal) => idle; flags D_80076214 (a
* pending/error byte) and D_8007620C (bit7/bit5) classify the busy/result state.
* Returns 0=idle done, 8=had pending, 2/4/1=busy variants. */
s32 CdQueueBusy(void) {
if (D_8006AEF8 != D_8006AEFC) {
if (D_80076214 == 0) {
if (D_8007620C & 0x80) {
return 2;
}
if (D_8007620C & 0x20) {
return 4;
}
return 1;
}
} else {
D_8007620C = 0;
if (D_80076214 == 0) {
return 0;
}
}
D_80076214 = 0;
return 8;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80034C24);
INCLUDE_ASM("asm/nonmatchings/800", func_80034CF0);
INCLUDE_ASM("asm/nonmatchings/800", func_80034DFC);
INCLUDE_ASM("asm/nonmatchings/800", func_8003500C);
INCLUDE_ASM("asm/nonmatchings/800", func_800351E8);
INCLUDE_ASM("asm/nonmatchings/800", func_80035210);
INCLUDE_ASM("asm/nonmatchings/800", func_80035270);
INCLUDE_ASM("asm/nonmatchings/800", func_800359B0);
INCLUDE_ASM("asm/nonmatchings/800", func_80035C4C);
INCLUDE_ASM("asm/nonmatchings/800", func_8003602C);
INCLUDE_ASM("asm/nonmatchings/800", func_80036130);
INCLUDE_ASM("asm/nonmatchings/800", func_800361CC);
INCLUDE_ASM("asm/nonmatchings/800", func_8003621C);
INCLUDE_ASM("asm/nonmatchings/800", func_80036260);
#ifdef NON_MATCHING
extern int CdControl(u8 com, u8 *param, u8 *result);
extern int CdSync(int mode, u8 *result);
extern u32 CdMode(void);
extern void CdFlush(void);
extern void *CdReadyCallback(void *func);
extern void func_800377D8(void); /* this loader's CdlReadN ready-callback */
extern void func_80036260(void); /* sub-handler passed to func_80037CD8 */
extern void func_8002EC10(void);
extern void func_80037334(void);
extern void func_80037358(int posInt);
extern void func_80037144(int idx);
extern int func_80037CD8(void *arg);
extern int func_8003750C(void);
extern int func_800374CC(int *out);
extern int func_8003775C(void);
extern void func_80037D74(void);
extern void *func_80037368(int *out);
extern int streamLoad_state; /* 0x8006AF00 */
extern void *streamLoad_savedReadyCB;
extern u8 streamLoad_cbActive;
extern int D_800A4F28; /* tick / timeout counter */
extern int D_800A4F2C; /* CdMode-derived retry budget */
extern int D_800A4F30; /* remaining sub-stream repeat count (from param_3) */
extern int D_800A4F34; /* last sector position (stall detection) */
extern int D_800A4F38; /* end/abort flag */
extern int D_800A6544;
extern u16 D_800A4E8E; /* 16-bit status flags */
extern u8 D_8006AEF4; /* 8-bit status flags */
extern u8 D_80068B60[]; /* per-resource descriptor table (0x10 stride) */
/* Second CD loader, DISTINCT from CdReadStateMachine: an 18-state machine (streamLoad_state) with
* its OWN ready-callback (func_800377D8). Runs SetMode(0xA0)/SeekL/ReadN with retry + CdMode
* handling, looping param_3 (D_800A4F30) times over sub-streams. Returns 0 = busy, 1 = done,
* 2 = error/abort. Driven by ResourceLoadStateMachine. Provenance: static trace, Phase 3 T4 (fn id
* verified; full semantics partial).
* NON_MATCHING: faithful translation of the Ghidra decompile — logically faithful, not byte-verified. */
int StreamLoadStateMachine(int param_1, void *param_2, int param_3) { /* param_2 is a CdlLOC* */
short sVar1;
int iVar4;
u32 uVar2;
char *pcVar3;
u8 local_28[8];
u8 local_20[8];
int local_18;
int local_14;
sVar1 = *(short *)(D_80068B60 + (param_1 - 0x100) * 0x10);
D_800A4F28++;
switch (streamLoad_state) {
case 0:
D_800A4F38 = 0;
D_800A6544 = 0;
D_800A4F30 = param_3;
func_8002EC10();
streamLoad_state++;
D_800A4E8E &= 0xFFDF;
return 0;
case 1:
func_80037334();
iVar4 = CdPosToInt((CdlLOC *)param_2);
func_80037358(iVar4);
func_80037144(sVar1);
streamLoad_state++;
/* fall through */
case 2:
local_14 = CdSync(1, local_20);
if (local_14 != 5 && local_14 != 2) return 0;
uVar2 = CdMode();
D_800A4F2C = ((uVar2 & 0x80) == 0) ? 3 : 0;
streamLoad_state++;
/* fall through */
case 3:
local_28[0] = 0xA0;
iVar4 = CdControl(0x0E, local_28, local_20); /* CdlSetmode */
if (iVar4 == 0) {
if ((local_20[0] & 0x10) != 0) { func_80037334(); streamLoad_state = 0; return 2; }
return 0;
}
D_800A4F28 = 0;
streamLoad_state++;
/* fall through */
case 4:
iVar4 = CdSync(1, local_20);
if (iVar4 != 5) {
if (iVar4 == 2) {
streamLoad_state++;
local_14 = 2;
modeWait:
if (D_800A4F2C != 0) { D_800A4F2C--; return 0; }
streamLoad_state++;
goto issueSeek;
}
if (D_800A4F28 < 0x3D) return 0;
}
streamLoad_state = 3;
return 0;
case 5:
goto modeWait;
case 6:
issueSeek:
iVar4 = func_80037CD8((void *)func_80036260);
if (iVar4 == 0) return 0;
streamLoad_state = 7;
/* fall through */
case 7:
iVar4 = func_8003750C();
if (iVar4 == 0) return 0;
streamLoad_state++;
/* fall through */
case 8:
local_14 = CdSync(1, local_20);
if (local_14 != 5 && local_14 != 2) return 0;
streamLoad_state++;
/* fall through */
case 9:
D_800A4F28 = 0;
iVar4 = CdControl(0x15, (u8 *)param_2, local_20); /* CdlSeekL */
if (iVar4 == 0) return 0;
streamLoad_state++;
/* fall through */
case 10:
local_14 = CdSync(1, local_20);
if (local_14 == 5) {
iVar4 = CdControl(0x01, (u8 *)0, local_20); /* CdlNop */
if (iVar4 == 0) { streamLoad_state = 9; return 0; }
if ((local_20[0] & 0x10) != 0) {
func_80037334();
D_8006AEF4 &= 0xFD;
streamLoad_state = 0;
return 2;
}
streamLoad_state = 9;
return 0;
}
if (local_14 != 2) {
if (D_800A4F28 < 0x12D) return 0;
CdFlush();
streamLoad_state = 9;
return 2;
}
streamLoad_state++;
local_14 = 2;
/* fall through */
case 0xB:
D_800A4F28 = 0;
iVar4 = CdControl(0x06, (u8 *)param_2, local_20); /* CdlReadN */
if (iVar4 != 0) {
if (streamLoad_cbActive == 0)
streamLoad_savedReadyCB = CdReadyCallback((void *)func_800377D8);
else
CdReadyCallback((void *)func_800377D8);
streamLoad_state++;
streamLoad_cbActive = 1;
return 0;
}
if ((local_20[0] & 0x10) == 0) return 0;
D_8006AEF4 &= 0xFD;
func_80037334();
streamLoad_state = 0;
return 2;
case 0xC:
iVar4 = func_800374CC(&local_18);
if (iVar4 == 0) {
if (local_18 != D_800A4F34) { D_800A4F34 = local_18; D_800A4F28 = 0; }
if (D_800A4F28 > 300) {
if (streamLoad_cbActive != 0) {
CdReadyCallback(streamLoad_savedReadyCB);
streamLoad_savedReadyCB = 0;
streamLoad_cbActive = 0;
}
streamLoad_state++;
}
return 0;
}
if (streamLoad_cbActive != 0) {
CdReadyCallback(streamLoad_savedReadyCB);
streamLoad_savedReadyCB = 0;
streamLoad_cbActive = 0;
}
streamLoad_state++;
/* fall through */
case 0xD:
iVar4 = func_8003775C();
if (iVar4 == 0) return 0;
func_80037D74();
streamLoad_state++;
return 0;
case 0xE:
pcVar3 = (char *)func_80037368(&local_14);
if (local_14 != 1) { streamLoad_state = 0x11; return 0; }
if (*pcVar3 != 1) {
if (*pcVar3 == 2) { streamLoad_state = 0x11; D_800A4F38 = 1; return 0; }
if (D_800A4F30 != 0) {
if (D_800A4F30 - 1 == 0) { streamLoad_state = 0x11; D_800A4F30 = 0; return 0; }
streamLoad_state = 1;
D_800A4F30--;
return 0;
}
streamLoad_state = 1;
return 0;
}
streamLoad_state++;
break; /* -> CdlPause (post-switch) */
case 0xF:
break; /* -> CdlPause (post-switch) */
case 0x10:
iVar4 = CdSync(1, local_20);
if (iVar4 != 5 && iVar4 != 2) return 0;
if (D_800A4F38 == 0) { streamLoad_state = 0; return 1; }
streamLoad_state = 0;
D_800A4F38 = 0;
return 2;
case 0x11:
iVar4 = CdControl(0x09, (u8 *)0, local_20); /* CdlPause */
if (iVar4 != 0) { streamLoad_state = 0x10; return 0; }
return 0;
default:
return 0;
}
/* shared tail for states 0xE (advance) and 0xF: pause, then wait for it */
iVar4 = CdControl(0x09, (u8 *)0, local_20); /* CdlPause */
if (iVar4 != 0) { streamLoad_state++; return 0; }
if ((local_20[0] & 0x10) != 0) { streamLoad_state = 0; return 1; }
return 0;
}
#else
INCLUDE_ASM("asm/nonmatchings/800", StreamLoadStateMachine);
#endif
INCLUDE_ASM("asm/nonmatchings/800", func_80036AF8);
INCLUDE_ASM("asm/nonmatchings/800", func_80036D24);
INCLUDE_ASM("asm/nonmatchings/800", func_80036D58);
INCLUDE_ASM("asm/nonmatchings/800", func_80036EB4);
INCLUDE_ASM("asm/nonmatchings/800", func_80036EE8);
INCLUDE_ASM("asm/nonmatchings/800", func_80036F18);
INCLUDE_ASM("asm/nonmatchings/800", func_80036F98);
INCLUDE_ASM("asm/nonmatchings/800", func_80036FB0);
CLEAR_TBL40(func_80037004) /* dedup I0: shared body (src/shared/clearTbl40.h) */
INCLUDE_ASM("asm/nonmatchings/800", func_80037028);
INCLUDE_ASM("asm/nonmatchings/800", func_80037144);
CLEAR_TBL40(func_80037334) /* dedup I0: shared body (src/shared/clearTbl40.h) */
extern s32 D_8007623C;
void func_80037358(int posInt) {
D_8007623C = posInt;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80037368);
INCLUDE_ASM("asm/nonmatchings/800", func_800373D0);
INCLUDE_ASM("asm/nonmatchings/800", func_800374CC);
INCLUDE_ASM("asm/nonmatchings/800", func_8003750C);
INCLUDE_ASM("asm/nonmatchings/800", func_8003775C);
INCLUDE_ASM("asm/nonmatchings/800", func_800377D8);
extern s32 D_800BA0F8;
void func_80037CC8(void) {
D_800BA0F8 = 0;
}
INCLUDE_ASM("asm/nonmatchings/800", func_80037CD8);
INCLUDE_ASM("asm/nonmatchings/800", func_80037D74);
INCLUDE_ASM("asm/nonmatchings/800", func_80037D98);
INCLUDE_ASM("asm/nonmatchings/800", func_80037EA0);
INCLUDE_ASM("asm/nonmatchings/800", func_80037F3C);
INCLUDE_ASM("asm/nonmatchings/800", func_80037FC4);
INCLUDE_ASM("asm/nonmatchings/800", func_8003819C);
INCLUDE_ASM("asm/nonmatchings/800", func_800381E4);
INCLUDE_ASM("asm/nonmatchings/800", func_80038210);
INCLUDE_ASM("asm/nonmatchings/800", func_80038308);
INCLUDE_ASM("asm/nonmatchings/800", func_8003834C);
INCLUDE_ASM("asm/nonmatchings/800", func_8003836C);
INCLUDE_ASM("asm/nonmatchings/800", func_800383A4);
INCLUDE_ASM("asm/nonmatchings/800", func_800384A8);
INCLUDE_ASM("asm/nonmatchings/800", func_800385C0);
INCLUDE_ASM("asm/nonmatchings/800", func_80038638);
INCLUDE_ASM("asm/nonmatchings/800", func_80038668);
INCLUDE_ASM("asm/nonmatchings/800", func_80038698);
INCLUDE_ASM("asm/nonmatchings/800", func_800387C0);
INCLUDE_ASM("asm/nonmatchings/800", func_80038838);
INCLUDE_ASM("asm/nonmatchings/800", func_800388E8);
INCLUDE_ASM("asm/nonmatchings/800", func_80038908);
INCLUDE_ASM("asm/nonmatchings/800", func_80038958);
INCLUDE_ASM("asm/nonmatchings/800", func_80038A00);
INCLUDE_ASM("asm/nonmatchings/800", func_80038A58);
INCLUDE_ASM("asm/nonmatchings/800", func_80038FC4);
INCLUDE_ASM("asm/nonmatchings/800", func_80038FFC);
INCLUDE_ASM("asm/nonmatchings/800", func_8003916C);
INCLUDE_ASM("asm/nonmatchings/800", func_800391D4);
void func_80039300(void) {
}
INCLUDE_ASM("asm/nonmatchings/800", func_80039308);
INCLUDE_ASM("asm/nonmatchings/800", func_80039B20);
INCLUDE_ASM("asm/nonmatchings/800", func_80039C5C);
INCLUDE_ASM("asm/nonmatchings/800", func_80039C70);
INCLUDE_ASM("asm/nonmatchings/800", func_80039DEC);
INCLUDE_ASM("asm/nonmatchings/800", func_80039F14);
INCLUDE_ASM("asm/nonmatchings/800", func_80039F50);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A098);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A0D0);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A0E4);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A234);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A3D8);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A404);
INCLUDE_ASM("asm/nonmatchings/800", func_8003A424);