diff --git a/generated/SCPH1001_dispatch.c b/generated/SCPH1001_dispatch.c index 779a4f64..2e5fd915 100644 --- a/generated/SCPH1001_dispatch.c +++ b/generated/SCPH1001_dispatch.c @@ -1,7 +1,7 @@ /* AUTO-GENERATED by psxrecomp-bios --emit-full. DO NOT EDIT. * * BIOS SHA256: 71af94d1e47a68c11e8fdb9f8368040601514a42a5a399cda48c7d3bff1e99d3 - * Dispatch entries: 4354 + * Dispatch entries: 4388 */ #include "cpu_state.h" @@ -1767,6 +1767,40 @@ extern void func_1FC1A17C(CPUState* cpu); extern void func_1FC1A17C_cont_BFC1A18C(CPUState* cpu); extern void func_1FC1A19C(CPUState* cpu); extern void func_1FC1A19C_cont_BFC1A1AC(CPUState* cpu); +extern void func_1FC1A1BC(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A1DC(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A1E4(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A1F0(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A1F8(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A204(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A20C(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A218(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A220(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A22C(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A234(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A240(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A248(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A254(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A25C(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A268(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A270(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A27C(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A284(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A290(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2B8(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2C0(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2CC(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2D4(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2E0(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2E8(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A2F0(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A300(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A310(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A320(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A378(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A380(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A394(CPUState* cpu); +extern void func_1FC1A1BC_cont_BFC1A3A8(CPUState* cpu); extern void func_1FC1A3B8(CPUState* cpu); extern void func_1FC1A414(CPUState* cpu); extern void func_1FC1A420(CPUState* cpu); @@ -4380,7 +4414,7 @@ typedef struct { PsxRecompFunc func; } DispatchEntry; -static const DispatchEntry dispatch_table[4354] = { +static const DispatchEntry dispatch_table[4388] = { { 0x00000500u, func_00000500 }, { 0x00000510u, func_00000510 }, { 0x00000520u, func_00000520 }, @@ -6130,6 +6164,40 @@ static const DispatchEntry dispatch_table[4354] = { { 0x1FC1A18Cu, func_1FC1A17C_cont_BFC1A18C }, { 0x1FC1A19Cu, func_1FC1A19C }, { 0x1FC1A1ACu, func_1FC1A19C_cont_BFC1A1AC }, + { 0x1FC1A1BCu, func_1FC1A1BC }, + { 0x1FC1A1DCu, func_1FC1A1BC_cont_BFC1A1DC }, + { 0x1FC1A1E4u, func_1FC1A1BC_cont_BFC1A1E4 }, + { 0x1FC1A1F0u, func_1FC1A1BC_cont_BFC1A1F0 }, + { 0x1FC1A1F8u, func_1FC1A1BC_cont_BFC1A1F8 }, + { 0x1FC1A204u, func_1FC1A1BC_cont_BFC1A204 }, + { 0x1FC1A20Cu, func_1FC1A1BC_cont_BFC1A20C }, + { 0x1FC1A218u, func_1FC1A1BC_cont_BFC1A218 }, + { 0x1FC1A220u, func_1FC1A1BC_cont_BFC1A220 }, + { 0x1FC1A22Cu, func_1FC1A1BC_cont_BFC1A22C }, + { 0x1FC1A234u, func_1FC1A1BC_cont_BFC1A234 }, + { 0x1FC1A240u, func_1FC1A1BC_cont_BFC1A240 }, + { 0x1FC1A248u, func_1FC1A1BC_cont_BFC1A248 }, + { 0x1FC1A254u, func_1FC1A1BC_cont_BFC1A254 }, + { 0x1FC1A25Cu, func_1FC1A1BC_cont_BFC1A25C }, + { 0x1FC1A268u, func_1FC1A1BC_cont_BFC1A268 }, + { 0x1FC1A270u, func_1FC1A1BC_cont_BFC1A270 }, + { 0x1FC1A27Cu, func_1FC1A1BC_cont_BFC1A27C }, + { 0x1FC1A284u, func_1FC1A1BC_cont_BFC1A284 }, + { 0x1FC1A290u, func_1FC1A1BC_cont_BFC1A290 }, + { 0x1FC1A2B8u, func_1FC1A1BC_cont_BFC1A2B8 }, + { 0x1FC1A2C0u, func_1FC1A1BC_cont_BFC1A2C0 }, + { 0x1FC1A2CCu, func_1FC1A1BC_cont_BFC1A2CC }, + { 0x1FC1A2D4u, func_1FC1A1BC_cont_BFC1A2D4 }, + { 0x1FC1A2E0u, func_1FC1A1BC_cont_BFC1A2E0 }, + { 0x1FC1A2E8u, func_1FC1A1BC_cont_BFC1A2E8 }, + { 0x1FC1A2F0u, func_1FC1A1BC_cont_BFC1A2F0 }, + { 0x1FC1A300u, func_1FC1A1BC_cont_BFC1A300 }, + { 0x1FC1A310u, func_1FC1A1BC_cont_BFC1A310 }, + { 0x1FC1A320u, func_1FC1A1BC_cont_BFC1A320 }, + { 0x1FC1A378u, func_1FC1A1BC_cont_BFC1A378 }, + { 0x1FC1A380u, func_1FC1A1BC_cont_BFC1A380 }, + { 0x1FC1A394u, func_1FC1A1BC_cont_BFC1A394 }, + { 0x1FC1A3A8u, func_1FC1A1BC_cont_BFC1A3A8 }, { 0x1FC1A3B8u, func_1FC1A3B8 }, { 0x1FC1A414u, func_1FC1A414 }, { 0x1FC1A420u, func_1FC1A420 }, @@ -8757,7 +8825,7 @@ void psx_dispatch(CPUState* cpu, uint32_t addr) { for (;;) { cpu->pc = 0; uint32_t phys = normalize(addr); - int lo = 0, hi = 4354 - 1; + int lo = 0, hi = 4388 - 1; int found = 0; while (lo <= hi) { int mid = (lo + hi) / 2; diff --git a/generated/SCPH1001_full.c b/generated/SCPH1001_full.c index 575b7cc5..cc9001b0 100644 --- a/generated/SCPH1001_full.c +++ b/generated/SCPH1001_full.c @@ -1,7 +1,7 @@ /* AUTO-GENERATED by psxrecomp-bios --emit-full. DO NOT EDIT. * * BIOS SHA256: 71af94d1e47a68c11e8fdb9f8368040601514a42a5a399cda48c7d3bff1e99d3 - * Functions: 1272 + * Functions: 1273 */ #include "cpu_state.h" @@ -562,6 +562,7 @@ void func_1FC1A11C(CPUState* cpu); void func_1FC1A15C(CPUState* cpu); void func_1FC1A17C(CPUState* cpu); void func_1FC1A19C(CPUState* cpu); +void func_1FC1A1BC(CPUState* cpu); void func_1FC1A3B8(CPUState* cpu); void func_1FC1A414(CPUState* cpu); void func_1FC1A420(CPUState* cpu); @@ -80753,6 +80754,621 @@ label_BFC1A1AC: return; } +void func_1FC1A1BC(CPUState* cpu) { + debug_server_log_call_entry(0x1FC1A1BCu); + if (cpu->pc != 0) { + uint32_t _cont = cpu->pc; + cpu->pc = 0; + switch (_cont) { + case 0xBFC1A1DCu: goto label_BFC1A1DC; + case 0xBFC1A1E4u: goto label_BFC1A1E4; + case 0xBFC1A1F0u: goto label_BFC1A1F0; + case 0xBFC1A1F8u: goto label_BFC1A1F8; + case 0xBFC1A204u: goto label_BFC1A204; + case 0xBFC1A20Cu: goto label_BFC1A20C; + case 0xBFC1A218u: goto label_BFC1A218; + case 0xBFC1A220u: goto label_BFC1A220; + case 0xBFC1A22Cu: goto label_BFC1A22C; + case 0xBFC1A234u: goto label_BFC1A234; + case 0xBFC1A240u: goto label_BFC1A240; + case 0xBFC1A248u: goto label_BFC1A248; + case 0xBFC1A254u: goto label_BFC1A254; + case 0xBFC1A25Cu: goto label_BFC1A25C; + case 0xBFC1A268u: goto label_BFC1A268; + case 0xBFC1A270u: goto label_BFC1A270; + case 0xBFC1A27Cu: goto label_BFC1A27C; + case 0xBFC1A284u: goto label_BFC1A284; + case 0xBFC1A290u: goto label_BFC1A290; + case 0xBFC1A2B8u: goto label_BFC1A2B8; + case 0xBFC1A2C0u: goto label_BFC1A2C0; + case 0xBFC1A2CCu: goto label_BFC1A2CC; + case 0xBFC1A2D4u: goto label_BFC1A2D4; + case 0xBFC1A2E0u: goto label_BFC1A2E0; + case 0xBFC1A2E8u: goto label_BFC1A2E8; + case 0xBFC1A2F0u: goto label_BFC1A2F0; + case 0xBFC1A300u: goto label_BFC1A300; + case 0xBFC1A310u: goto label_BFC1A310; + case 0xBFC1A320u: goto label_BFC1A320; + case 0xBFC1A378u: goto label_BFC1A378; + case 0xBFC1A380u: goto label_BFC1A380; + case 0xBFC1A394u: goto label_BFC1A394; + case 0xBFC1A3A8u: goto label_BFC1A3A8; + default: break; + } + } + int psx_taken_BFC1A1CC = 0; + int psx_taken_BFC1A2F0 = 0; + int psx_taken_BFC1A300 = 0; + int psx_taken_BFC1A310 = 0; + int psx_taken_BFC1A320 = 0; + int psx_taken_BFC1A334 = 0; + int psx_taken_BFC1A33C = 0; + int psx_taken_BFC1A344 = 0; + int psx_taken_BFC1A34C = 0; + int psx_taken_BFC1A358 = 0; + int psx_taken_BFC1A360 = 0; + int psx_taken_BFC1A384 = 0; + int psx_taken_BFC1A398 = 0; +label_BFC1A1BC: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(6u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A1BC: 3C0100F0 lui $at, 0xF0 */ + cpu->gpr[1] = 0x00F00000u; + /* 0xBFC1A1C0: 342100F0 ori $at, $at, 0xF0 */ + cpu->gpr[1] = cpu->gpr[1] | 0xF0u; + /* 0xBFC1A1C4: 27BDFFE8 addiu $sp, $sp, -24 */ + cpu->gpr[29] = (uint32_t)((int32_t)cpu->gpr[29] + (-24)); + /* 0xBFC1A1C8: 00817024 and $t6, $a0, $at */ + cpu->gpr[14] = cpu->gpr[4] & cpu->gpr[1]; + /* 0xBFC1A1CC: 11C00076 beq $t6, $zero, 0xBFC1A3A8 */ + uint32_t psx_brA_BFC1A1CC = cpu->gpr[14]; uint32_t psx_brB_BFC1A1CC = cpu->gpr[0]; + psx_taken_BFC1A1CC = (psx_brA_BFC1A1CC == psx_brB_BFC1A1CC); + /* 0xBFC1A1D0: AFBF0014 sw $ra, 20($sp) */ + { uint32_t psx_addr = (uint32_t)((int32_t)cpu->gpr[29] + (20)); if (psx_addr & 3u) { psx_unaligned_access(cpu, psx_addr, 0xBFC1A1D0u); return; } g_debug_last_store_pc = 0xBFC1A1D0u; cpu->write_word(psx_addr, cpu->gpr[31]); } + if (psx_taken_BFC1A1CC) goto label_BFC1A3A8; +label_BFC1A1D4: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A1D4: 0C00F928 jal 0xB003E4A0 */ + /* 0xBFC1A1D8: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x800321DCu; + psx_dispatch(cpu, 0x8003E4A0u); +label_BFC1A1DC: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A1DC: 0C011997 jal 0xB004665C */ + /* 0xBFC1A1E0: 2404000A addiu $a0, $zero, 10 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (10)); + cpu->gpr[31] = 0x800321E4u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A1E4: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A1E4: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A1E8: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A1EC: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x800321F0u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A1F0: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A1F0: 0C011997 jal 0xB004665C */ + /* 0xBFC1A1F4: 2404000B addiu $a0, $zero, 11 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (11)); + cpu->gpr[31] = 0x800321F8u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A1F8: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A1F8: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A1FC: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A200: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x80032204u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A204: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A204: 0C011997 jal 0xB004665C */ + /* 0xBFC1A208: 2404000C addiu $a0, $zero, 12 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (12)); + cpu->gpr[31] = 0x8003220Cu; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A20C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A20C: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A210: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A214: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x80032218u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A218: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A218: 0C011997 jal 0xB004665C */ + /* 0xBFC1A21C: 2404000D addiu $a0, $zero, 13 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (13)); + cpu->gpr[31] = 0x80032220u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A220: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A220: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A224: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A228: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x8003222Cu; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A22C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A22C: 0C011997 jal 0xB004665C */ + /* 0xBFC1A230: 2404006E addiu $a0, $zero, 110 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (110)); + cpu->gpr[31] = 0x80032234u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A234: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A234: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A238: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A23C: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x80032240u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A240: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A240: 0C011997 jal 0xB004665C */ + /* 0xBFC1A244: 2404006F addiu $a0, $zero, 111 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (111)); + cpu->gpr[31] = 0x80032248u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A248: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A248: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A24C: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A250: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x80032254u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A254: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A254: 0C011997 jal 0xB004665C */ + /* 0xBFC1A258: 24040011 addiu $a0, $zero, 17 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (17)); + cpu->gpr[31] = 0x8003225Cu; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A25C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A25C: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A260: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A264: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x80032268u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A268: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A268: 0C011997 jal 0xB004665C */ + /* 0xBFC1A26C: 24040012 addiu $a0, $zero, 18 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (18)); + cpu->gpr[31] = 0x80032270u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A270: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A270: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A274: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A278: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x8003227Cu; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A27C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A27C: 0C011997 jal 0xB004665C */ + /* 0xBFC1A280: 24040013 addiu $a0, $zero, 19 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (19)); + cpu->gpr[31] = 0x80032284u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A284: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A284: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A288: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A28C: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x80032290u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A290: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(10u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A290: 3C0F8008 lui $t7, 0x8008 */ + cpu->gpr[15] = 0x80080000u; + /* 0xBFC1A294: 8DEF9E24 lw $t7, -25052($t7) */ + { uint32_t psx_addr = (uint32_t)((int32_t)cpu->gpr[15] + (-25052)); if (psx_addr & 3u) { psx_unaligned_access(cpu, psx_addr, 0xBFC1A294u); return; } cpu->gpr[15] = cpu->read_word(psx_addr); } + /* 0xBFC1A298: 3C19800F lui $t9, 0x800F */ + cpu->gpr[25] = 0x800F0000u; + /* 0xBFC1A29C: 000FC0C0 sll $t8, $t7, 3 */ + cpu->gpr[24] = cpu->gpr[15] << 3u; + /* 0xBFC1A2A0: 030FC023 subu $t8, $t8, $t7 */ + cpu->gpr[24] = cpu->gpr[24] - cpu->gpr[15]; + /* 0xBFC1A2A4: 0018C280 sll $t8, $t8, 10 */ + cpu->gpr[24] = cpu->gpr[24] << 10u; + /* 0xBFC1A2A8: 273986A8 addiu $t9, $t9, -31064 */ + cpu->gpr[25] = (uint32_t)((int32_t)cpu->gpr[25] + (-31064)); + /* 0xBFC1A2AC: 03192021 addu $a0, $t8, $t9 */ + cpu->gpr[4] = cpu->gpr[24] + cpu->gpr[25]; + /* 0xBFC1A2B0: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A2B4: 240503FE addiu $a1, $zero, 1022 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (1022)); + cpu->gpr[31] = 0x800322B8u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A2B8: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2B8: 0C011997 jal 0xB004665C */ + /* 0xBFC1A2BC: 24040004 addiu $a0, $zero, 4 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (4)); + cpu->gpr[31] = 0x800322C0u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A2C0: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2C0: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A2C4: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A2C8: 24050004 addiu $a1, $zero, 4 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (4)); + cpu->gpr[31] = 0x800322CCu; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A2CC: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2CC: 0C011997 jal 0xB004665C */ + /* 0xBFC1A2D0: 24040005 addiu $a0, $zero, 5 */ + cpu->gpr[4] = (uint32_t)((int32_t)cpu->gpr[0] + (5)); + cpu->gpr[31] = 0x800322D4u; + psx_dispatch(cpu, 0x8004665Cu); +label_BFC1A2D4: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2D4: 00402021 addu $a0, $v0, $zero */ + cpu->gpr[4] = cpu->gpr[2] + cpu->gpr[0]; + /* 0xBFC1A2D8: 0C011294 jal 0xB0044A50 */ + /* 0xBFC1A2DC: 24050005 addiu $a1, $zero, 5 */ + cpu->gpr[5] = (uint32_t)((int32_t)cpu->gpr[0] + (5)); + cpu->gpr[31] = 0x800322E0u; + psx_dispatch(cpu, 0x80044A50u); +label_BFC1A2E0: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2E0: 0C01195D jal 0xB0046574 */ + /* 0xBFC1A2E4: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x800322E8u; + psx_dispatch(cpu, 0x80046574u); +label_BFC1A2E8: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2E8: 0C011934 jal 0xB00464D0 */ + /* 0xBFC1A2EC: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x800322F0u; + psx_dispatch(cpu, 0x800464D0u); +label_BFC1A2F0: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2F0: 10000019 beq $zero, $zero, 0xBFC1A358 */ + uint32_t psx_brA_BFC1A2F0 = cpu->gpr[0]; uint32_t psx_brB_BFC1A2F0 = cpu->gpr[0]; + psx_taken_BFC1A2F0 = (psx_brA_BFC1A2F0 == psx_brB_BFC1A2F0); + /* 0xBFC1A2F4: 2401000A addiu $at, $zero, 10 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (10)); + if (psx_taken_BFC1A2F0) goto label_BFC1A358; +label_BFC1A2F8: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A2F8: 0C00C857 jal 0xB003215C */ + /* 0xBFC1A2FC: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x80032300u; + psx_dispatch(cpu, 0x8003215Cu); +label_BFC1A300: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A300: 10000011 beq $zero, $zero, 0xBFC1A348 */ + uint32_t psx_brA_BFC1A300 = cpu->gpr[0]; uint32_t psx_brB_BFC1A300 = cpu->gpr[0]; + psx_taken_BFC1A300 = (psx_brA_BFC1A300 == psx_brB_BFC1A300); + /* 0xBFC1A304: 00000000 nop */ + /* nop */ + if (psx_taken_BFC1A300) goto label_BFC1A348; +label_BFC1A308: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A308: 0C00C85F jal 0xB003217C */ + /* 0xBFC1A30C: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x80032310u; + psx_dispatch(cpu, 0x8003217Cu); +label_BFC1A310: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A310: 1000000D beq $zero, $zero, 0xBFC1A348 */ + uint32_t psx_brA_BFC1A310 = cpu->gpr[0]; uint32_t psx_brB_BFC1A310 = cpu->gpr[0]; + psx_taken_BFC1A310 = (psx_brA_BFC1A310 == psx_brB_BFC1A310); + /* 0xBFC1A314: 00000000 nop */ + /* nop */ + if (psx_taken_BFC1A310) goto label_BFC1A348; +label_BFC1A318: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A318: 0C00C867 jal 0xB003219C */ + /* 0xBFC1A31C: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x80032320u; + psx_dispatch(cpu, 0x8003219Cu); +label_BFC1A320: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A320: 10000009 beq $zero, $zero, 0xBFC1A348 */ + uint32_t psx_brA_BFC1A320 = cpu->gpr[0]; uint32_t psx_brB_BFC1A320 = cpu->gpr[0]; + psx_taken_BFC1A320 = (psx_brA_BFC1A320 == psx_brB_BFC1A320); + /* 0xBFC1A324: 00000000 nop */ + /* nop */ + if (psx_taken_BFC1A320) goto label_BFC1A348; +label_BFC1A328: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(5u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A328: 3C088006 lui $t0, 0x8006 */ + cpu->gpr[8] = 0x80060000u; + /* 0xBFC1A32C: 8D086BB8 lw $t0, 27576($t0) */ + { uint32_t psx_addr = (uint32_t)((int32_t)cpu->gpr[8] + (27576)); if (psx_addr & 3u) { psx_unaligned_access(cpu, psx_addr, 0xBFC1A32Cu); return; } cpu->gpr[8] = cpu->read_word(psx_addr); } + /* 0xBFC1A330: 24010004 addiu $at, $zero, 4 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (4)); + /* 0xBFC1A334: 1101FFF0 beq $t0, $at, 0xBFC1A2F8 */ + uint32_t psx_brA_BFC1A334 = cpu->gpr[8]; uint32_t psx_brB_BFC1A334 = cpu->gpr[1]; + psx_taken_BFC1A334 = (psx_brA_BFC1A334 == psx_brB_BFC1A334); + /* 0xBFC1A338: 24010005 addiu $at, $zero, 5 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (5)); + if (psx_taken_BFC1A334) goto label_BFC1A2F8; +label_BFC1A33C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A33C: 1101FFF2 beq $t0, $at, 0xBFC1A308 */ + uint32_t psx_brA_BFC1A33C = cpu->gpr[8]; uint32_t psx_brB_BFC1A33C = cpu->gpr[1]; + psx_taken_BFC1A33C = (psx_brA_BFC1A33C == psx_brB_BFC1A33C); + /* 0xBFC1A340: 24010006 addiu $at, $zero, 6 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (6)); + if (psx_taken_BFC1A33C) goto label_BFC1A308; +label_BFC1A344: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(1u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A344: 1101FFF4 beq $t0, $at, 0xBFC1A318 */ + uint32_t psx_brA_BFC1A344 = cpu->gpr[8]; uint32_t psx_brB_BFC1A344 = cpu->gpr[1]; + psx_taken_BFC1A344 = (psx_brA_BFC1A344 == psx_brB_BFC1A344); +label_BFC1A348: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(1u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A348: 3C018006 lui $at, 0x8006 */ + cpu->gpr[1] = 0x80060000u; + if (psx_taken_BFC1A344) goto label_BFC1A318; +label_BFC1A34C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A34C: 10000006 beq $zero, $zero, 0xBFC1A368 */ + uint32_t psx_brA_BFC1A34C = cpu->gpr[0]; uint32_t psx_brB_BFC1A34C = cpu->gpr[0]; + psx_taken_BFC1A34C = (psx_brA_BFC1A34C == psx_brB_BFC1A34C); + /* 0xBFC1A350: AC206BBC sw $zero, 27580($at) */ + { uint32_t psx_addr = (uint32_t)((int32_t)cpu->gpr[1] + (27580)); if (psx_addr & 3u) { psx_unaligned_access(cpu, psx_addr, 0xBFC1A350u); return; } g_debug_last_store_pc = 0xBFC1A350u; cpu->write_word(psx_addr, cpu->gpr[0]); } + if (psx_taken_BFC1A34C) goto label_BFC1A368; +label_BFC1A354: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(1u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A354: 2401000A addiu $at, $zero, 10 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (10)); +label_BFC1A358: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A358: 1041FFF3 beq $v0, $at, 0xBFC1A328 */ + uint32_t psx_brA_BFC1A358 = cpu->gpr[2]; uint32_t psx_brB_BFC1A358 = cpu->gpr[1]; + psx_taken_BFC1A358 = (psx_brA_BFC1A358 == psx_brB_BFC1A358); + /* 0xBFC1A35C: 2401000B addiu $at, $zero, 11 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (11)); + if (psx_taken_BFC1A358) goto label_BFC1A328; +label_BFC1A360: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A360: 1041FFF9 beq $v0, $at, 0xBFC1A348 */ + uint32_t psx_brA_BFC1A360 = cpu->gpr[2]; uint32_t psx_brB_BFC1A360 = cpu->gpr[1]; + psx_taken_BFC1A360 = (psx_brA_BFC1A360 == psx_brB_BFC1A360); + /* 0xBFC1A364: 00000000 nop */ + /* nop */ + if (psx_taken_BFC1A360) goto label_BFC1A348; +label_BFC1A368: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(4u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A368: 3C048006 lui $a0, 0x8006 */ + cpu->gpr[4] = 0x80060000u; + /* 0xBFC1A36C: 8C846BB8 lw $a0, 27576($a0) */ + { uint32_t psx_addr = (uint32_t)((int32_t)cpu->gpr[4] + (27576)); if (psx_addr & 3u) { psx_unaligned_access(cpu, psx_addr, 0xBFC1A36Cu); return; } cpu->gpr[4] = cpu->read_word(psx_addr); } + /* 0xBFC1A370: 0C011913 jal 0xB004644C */ + /* 0xBFC1A374: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x80032378u; + psx_dispatch(cpu, 0x8004644Cu); +label_BFC1A378: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A378: 0C01195D jal 0xB0046574 */ + /* 0xBFC1A37C: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x80032380u; + psx_dispatch(cpu, 0x80046574u); +label_BFC1A380: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A380: 2401FFFF addiu $at, $zero, -1 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (-1)); + /* 0xBFC1A384: 10410006 beq $v0, $at, 0xBFC1A3A0 */ + uint32_t psx_brA_BFC1A384 = cpu->gpr[2]; uint32_t psx_brB_BFC1A384 = cpu->gpr[1]; + psx_taken_BFC1A384 = (psx_brA_BFC1A384 == psx_brB_BFC1A384); + /* 0xBFC1A388: 00000000 nop */ + /* nop */ + if (psx_taken_BFC1A384) goto label_BFC1A3A0; +label_BFC1A38C: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A38C: 0C01195D jal 0xB0046574 */ + /* 0xBFC1A390: 00000000 nop */ + /* nop */ + cpu->gpr[31] = 0x80032394u; + psx_dispatch(cpu, 0x80046574u); +label_BFC1A394: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(3u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A394: 2401FFFF addiu $at, $zero, -1 */ + cpu->gpr[1] = (uint32_t)((int32_t)cpu->gpr[0] + (-1)); + /* 0xBFC1A398: 1441FFFC bne $v0, $at, 0xBFC1A38C */ + uint32_t psx_brA_BFC1A398 = cpu->gpr[2]; uint32_t psx_brB_BFC1A398 = cpu->gpr[1]; + psx_taken_BFC1A398 = (psx_brA_BFC1A398 != psx_brB_BFC1A398); + /* 0xBFC1A39C: 00000000 nop */ + /* nop */ + if (psx_taken_BFC1A398) goto label_BFC1A38C; +label_BFC1A3A0: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(2u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A3A0: 0C00ED40 jal 0xB003B500 */ + /* 0xBFC1A3A4: 00002021 addu $a0, $zero, $zero */ + cpu->gpr[4] = cpu->gpr[0] + cpu->gpr[0]; + cpu->gpr[31] = 0x800323A8u; + psx_dispatch(cpu, 0x8003B500u); +label_BFC1A3A8: +#ifdef PSX_ENABLE_BLOCK_CYCLES + psx_advance_cycles(4u); +#endif + psx_check_interrupts(cpu); + /* 0xBFC1A3A8: 8FBF0014 lw $ra, 20($sp) */ + { uint32_t psx_addr = (uint32_t)((int32_t)cpu->gpr[29] + (20)); if (psx_addr & 3u) { psx_unaligned_access(cpu, psx_addr, 0xBFC1A3A8u); return; } cpu->gpr[31] = cpu->read_word(psx_addr); } + /* 0xBFC1A3AC: 27BD0018 addiu $sp, $sp, 24 */ + cpu->gpr[29] = (uint32_t)((int32_t)cpu->gpr[29] + (24)); + /* 0xBFC1A3B0: 03E00008 jr $ra */ + /* 0xBFC1A3B4: 00000000 nop */ + /* nop */ + return; +} + void func_1FC1A3B8(CPUState* cpu) { debug_server_log_call_entry(0x1FC1A3B8u); int psx_taken_BFC1A3F8 = 0; @@ -221830,7 +222446,7 @@ void func_1FC02324(CPUState* cpu) { } -/* --- 3082 continuation wrappers for jal/jalr return routing --- */ +/* --- 3115 continuation wrappers for jal/jalr return routing --- */ void func_00000C80_cont_BFC107C0(CPUState* cpu) { cpu->pc = 0xBFC107C0u; @@ -227877,6 +228493,171 @@ void func_1FC1A19C_cont_BFC1A1AC(CPUState* cpu) { func_1FC1A19C(cpu); } +void func_1FC1A1BC_cont_BFC1A1DC(CPUState* cpu) { + cpu->pc = 0xBFC1A1DCu; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A1E4(CPUState* cpu) { + cpu->pc = 0xBFC1A1E4u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A1F0(CPUState* cpu) { + cpu->pc = 0xBFC1A1F0u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A1F8(CPUState* cpu) { + cpu->pc = 0xBFC1A1F8u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A204(CPUState* cpu) { + cpu->pc = 0xBFC1A204u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A20C(CPUState* cpu) { + cpu->pc = 0xBFC1A20Cu; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A218(CPUState* cpu) { + cpu->pc = 0xBFC1A218u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A220(CPUState* cpu) { + cpu->pc = 0xBFC1A220u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A22C(CPUState* cpu) { + cpu->pc = 0xBFC1A22Cu; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A234(CPUState* cpu) { + cpu->pc = 0xBFC1A234u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A240(CPUState* cpu) { + cpu->pc = 0xBFC1A240u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A248(CPUState* cpu) { + cpu->pc = 0xBFC1A248u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A254(CPUState* cpu) { + cpu->pc = 0xBFC1A254u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A25C(CPUState* cpu) { + cpu->pc = 0xBFC1A25Cu; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A268(CPUState* cpu) { + cpu->pc = 0xBFC1A268u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A270(CPUState* cpu) { + cpu->pc = 0xBFC1A270u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A27C(CPUState* cpu) { + cpu->pc = 0xBFC1A27Cu; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A284(CPUState* cpu) { + cpu->pc = 0xBFC1A284u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A290(CPUState* cpu) { + cpu->pc = 0xBFC1A290u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2B8(CPUState* cpu) { + cpu->pc = 0xBFC1A2B8u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2C0(CPUState* cpu) { + cpu->pc = 0xBFC1A2C0u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2CC(CPUState* cpu) { + cpu->pc = 0xBFC1A2CCu; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2D4(CPUState* cpu) { + cpu->pc = 0xBFC1A2D4u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2E0(CPUState* cpu) { + cpu->pc = 0xBFC1A2E0u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2E8(CPUState* cpu) { + cpu->pc = 0xBFC1A2E8u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A2F0(CPUState* cpu) { + cpu->pc = 0xBFC1A2F0u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A300(CPUState* cpu) { + cpu->pc = 0xBFC1A300u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A310(CPUState* cpu) { + cpu->pc = 0xBFC1A310u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A320(CPUState* cpu) { + cpu->pc = 0xBFC1A320u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A378(CPUState* cpu) { + cpu->pc = 0xBFC1A378u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A380(CPUState* cpu) { + cpu->pc = 0xBFC1A380u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A394(CPUState* cpu) { + cpu->pc = 0xBFC1A394u; + func_1FC1A1BC(cpu); +} + +void func_1FC1A1BC_cont_BFC1A3A8(CPUState* cpu) { + cpu->pc = 0xBFC1A3A8u; + func_1FC1A1BC(cpu); +} + void func_1FC1A430_cont_BFC1A470(CPUState* cpu) { cpu->pc = 0xBFC1A470u; func_1FC1A430(cpu); diff --git a/recompiler/seeds/phase2_ghidra_seeds.json b/recompiler/seeds/phase2_ghidra_seeds.json index d88e9055..9fe8317e 100644 --- a/recompiler/seeds/phase2_ghidra_seeds.json +++ b/recompiler/seeds/phase2_ghidra_seeds.json @@ -1,7 +1,7 @@ { "schema": "psxrecomp-v4 phase2 seeds", - "source": "generated/ghidra_function_starts.json + phase1c seeds + dispatch_miss_seeds + preserved manual + audit_2026_05_04 trampoline dispatch-miss + audit_2026_05_04 trampoline dispatch-miss", - "seed_count": 1063, + "source": "generated/ghidra_function_starts.json + phase1c seeds + dispatch_miss_seeds + preserved manual + audit_2026_05_04 trampoline dispatch-miss + audit_2026_05_04 trampoline dispatch-miss + modal_stub_2026_05_05", + "seed_count": 1064, "seeds": [ { "address": "0xBFC00000", @@ -1728,6 +1728,11 @@ "label": "ghidra_BFC1A19C", "rationale": "Ghidra function start" }, + { + "address": "0xBFC1A1BC", + "label": "modal_stub_dispatch_miss", + "rationale": "Runtime dispatch miss confirmed 2026-05-05: psx_unknown_dispatch hit during YES/NO COPY confirm modal CROSS press. Beetle wtrace+fntrace shows this PC fires on modal close via JAL caller_pc=0x8004673C. Ghidra function discovery missed it. BANDAID per user permission — should be replaced by an improved heuristic that catches this gap." + }, { "address": "0xBFC1A430", "label": "ghidra_BFC1A430", diff --git a/runtime/src/debug_server.c b/runtime/src/debug_server.c index ff4080af..89b01a65 100644 --- a/runtime/src/debug_server.c +++ b/runtime/src/debug_server.c @@ -169,6 +169,59 @@ void debug_server_log_sio_write(uint32_t addr, uint32_t value, uint8_t width) { static uint32_t s_dispatch_ring[DISPATCH_TRACE_CAP]; static uint64_t s_dispatch_seq = 0; +/* ---- Unknown-dispatch ring buffer ---- + * Always-on log of every psx_dispatch target that doesn't resolve to a + * generated function AND doesn't match any trampoline pattern in + * traps.c. Used to identify functions the recompiler missed. + * 64K entries × 32 bytes = 2 MB. Replaces the prior file-based log. */ +#define UNKNOWN_DISPATCH_CAP (1 << 16) +typedef struct { + uint64_t seq; + uint32_t addr; + uint32_t phys; + uint32_t ra; + uint32_t a0; + uint32_t a1; + uint32_t frame; + uint32_t pad; +} UnknownDispatchEntry; +static UnknownDispatchEntry s_unknown_ring[UNKNOWN_DISPATCH_CAP]; +static uint64_t s_unknown_seq = 0; +/* Per-target hit count — bounded set, ~N unique targets typically. */ +#define UNKNOWN_UNIQUE_CAP 1024 +typedef struct { uint32_t phys; uint64_t count; } UnknownUniqueEntry; +static UnknownUniqueEntry s_unknown_unique[UNKNOWN_UNIQUE_CAP]; +static int s_unknown_unique_count = 0; + +void psx_unknown_dispatch_record(uint32_t addr, uint32_t phys, + uint32_t ra, uint32_t a0, uint32_t a1) +{ + uint64_t seq = s_unknown_seq++; + UnknownDispatchEntry *e = &s_unknown_ring[seq & (UNKNOWN_DISPATCH_CAP - 1u)]; + e->seq = seq; + e->addr = addr; + e->phys = phys; + e->ra = ra; + e->a0 = a0; + e->a1 = a1; + e->frame = (uint32_t)s_frame_count; + /* Per-target count (linear probe). */ + uint32_t idx = (phys >> 2) % UNKNOWN_UNIQUE_CAP; + for (int i = 0; i < UNKNOWN_UNIQUE_CAP; i++) { + uint32_t slot = (idx + i) % UNKNOWN_UNIQUE_CAP; + if (s_unknown_unique[slot].phys == phys) { + s_unknown_unique[slot].count++; + return; + } + if (s_unknown_unique[slot].phys == 0) { + s_unknown_unique[slot].phys = phys; + s_unknown_unique[slot].count = 1; + s_unknown_unique_count++; + return; + } + } +} + /* Unique dispatch set — tracks every unique function address ever dispatched. * Simple hash set with linear probing. */ #define DISPATCH_UNIQUE_CAP 4096 @@ -638,6 +691,7 @@ static const char *json_get_str(const char *json, const char *key, char *out, int out_sz); static uint32_t hex_to_u32(const char *s); static void handle_dirty_ram_stats(int id, const char *json); +static void send_err(int id, const char *msg); void debug_server_send_fmt(const char *fmt, ...); #define send_fmt debug_server_send_fmt @@ -764,6 +818,108 @@ static void handle_dirty_block_log(int id, const char *json) free(out); } +/* ---- unknown_dispatch_log: dump psx_unknown_dispatch hits ---- + * Two modes: + * - default: per-target count summary (sorted by hit count) + * - tail=N: most recent N entries from the ring */ +static void handle_unknown_dispatch_log(int id, const char *json) +{ + int tail = json_get_int(json, "tail", 0); + + if (tail > 0) { + if (tail > (int)UNKNOWN_DISPATCH_CAP) tail = UNKNOWN_DISPATCH_CAP; + uint64_t total = s_unknown_seq; + uint64_t avail = (total < UNKNOWN_DISPATCH_CAP) ? total : UNKNOWN_DISPATCH_CAP; + if ((uint64_t)tail > avail) tail = (int)avail; + + const size_t BUF_SZ = 2 * 1024 * 1024; + char *out = (char *)malloc(BUF_SZ); + if (!out) { send_err(id, "oom"); return; } + size_t pos = 0; + pos += snprintf(out + pos, BUF_SZ - pos, + "{\"id\":%d,\"ok\":true,\"total\":%llu,\"unique\":%d," + "\"tail\":%d,\"entries\":[", + id, (unsigned long long)total, s_unknown_unique_count, tail); + uint64_t start = total - (uint64_t)tail; + for (int i = 0; i < tail; i++) { + UnknownDispatchEntry *e = + &s_unknown_ring[(start + i) & (UNKNOWN_DISPATCH_CAP - 1u)]; + if (pos > BUF_SZ - 256) break; + pos += snprintf(out + pos, BUF_SZ - pos, + "%s{\"seq\":%llu,\"addr\":\"0x%08X\",\"phys\":\"0x%08X\"," + "\"ra\":\"0x%08X\",\"a0\":\"0x%08X\",\"a1\":\"0x%08X\"," + "\"frame\":%u}", + i == 0 ? "" : ",", + (unsigned long long)e->seq, + e->addr, e->phys, e->ra, e->a0, e->a1, e->frame); + } + pos += snprintf(out + pos, BUF_SZ - pos, "]}\n"); + debug_server_send_line(out); + free(out); + return; + } + + /* Summary mode: per-phys hit count, sorted descending. */ + const size_t BUF_SZ = 2 * 1024 * 1024; + char *out = (char *)malloc(BUF_SZ); + if (!out) { send_err(id, "oom"); return; } + size_t pos = 0; + pos += snprintf(out + pos, BUF_SZ - pos, + "{\"id\":%d,\"ok\":true,\"total\":%llu,\"unique\":%d," + "\"summary\":[", + id, (unsigned long long)s_unknown_seq, s_unknown_unique_count); + /* Sort by count desc — small cap, simple selection. */ + int emitted = 0; + for (int round = 0; round < UNKNOWN_UNIQUE_CAP && emitted < 200; round++) { + uint64_t best_count = 0; + int best_idx = -1; + for (int i = 0; i < UNKNOWN_UNIQUE_CAP; i++) { + if (s_unknown_unique[i].phys == 0) continue; + if (s_unknown_unique[i].count > best_count) { + best_count = s_unknown_unique[i].count; + best_idx = i; + } + } + if (best_idx < 0) break; + if (pos > BUF_SZ - 128) break; + pos += snprintf(out + pos, BUF_SZ - pos, + "%s{\"phys\":\"0x%08X\",\"count\":%llu}", + emitted == 0 ? "" : ",", + s_unknown_unique[best_idx].phys, + (unsigned long long)s_unknown_unique[best_idx].count); + s_unknown_unique[best_idx].count = 0; /* mark consumed */ + emitted++; + } + /* Restore: re-walk the ring once to rebuild counts. Cheap since cap is 1024. */ + /* (We mutated counts above to drive selection; rebuild by replaying the + * ring's most recent UNKNOWN_DISPATCH_CAP entries.) */ + for (int i = 0; i < UNKNOWN_UNIQUE_CAP; i++) s_unknown_unique[i].phys = 0; + s_unknown_unique_count = 0; + uint64_t avail = (s_unknown_seq < UNKNOWN_DISPATCH_CAP) ? s_unknown_seq : UNKNOWN_DISPATCH_CAP; + uint64_t start = s_unknown_seq - avail; + for (uint64_t i = 0; i < avail; i++) { + UnknownDispatchEntry *e = &s_unknown_ring[(start + i) & (UNKNOWN_DISPATCH_CAP - 1u)]; + uint32_t phys = e->phys; + uint32_t idx = (phys >> 2) % UNKNOWN_UNIQUE_CAP; + for (int k = 0; k < UNKNOWN_UNIQUE_CAP; k++) { + uint32_t slot = (idx + k) % UNKNOWN_UNIQUE_CAP; + if (s_unknown_unique[slot].phys == phys) { + s_unknown_unique[slot].count++; + break; + } + if (s_unknown_unique[slot].phys == 0) { + s_unknown_unique[slot].phys = phys; + s_unknown_unique[slot].count = 1; + s_unknown_unique_count++; + break; + } + } + } + pos += snprintf(out + pos, BUF_SZ - pos, "]}\n"); + debug_server_send_line(out); + free(out); +} + /* ---- SIO write PC tracer dump ---- * Returns the most recent N entries from the SIO PC tracer ring. * Optional addr_lo/addr_hi (hex-string) filter restricts to a single @@ -3012,6 +3168,7 @@ static const CmdEntry s_commands[] = { { "sio_pc_trace", handle_sio_pc_trace }, { "dirty_ram_stats", handle_dirty_ram_stats }, { "dirty_block_log", handle_dirty_block_log }, + { "unknown_dispatch_log", handle_unknown_dispatch_log }, { "card_txn_dump", handle_card_txn_dump }, { "card_read_summary", handle_card_read_summary }, { "card_read_summary_reset", handle_card_read_summary_reset }, diff --git a/runtime/src/traps.c b/runtime/src/traps.c index e0af0f8e..1474f798 100644 --- a/runtime/src/traps.c +++ b/runtime/src/traps.c @@ -359,22 +359,14 @@ void psx_unknown_dispatch(CPUState* cpu, uint32_t addr, uint32_t phys) { } { - /* Log dispatch miss to file and continue (collect all misses). */ - static FILE* miss_log = NULL; - static int miss_count = 0; - if (!miss_log) miss_log = fopen("psx_dispatch_misses.txt", "w"); - if (miss_log) { - fprintf(miss_log, "0x%08X phys=0x%08X ra=0x%08X t9=0x%08X pc=0x%08X\n", - addr, phys, cpu->gpr[31], cpu->gpr[25], cpu->pc); - fflush(miss_log); - } - miss_count++; - if (miss_count > 100000) { - fprintf(stderr, "DISPATCH MISS limit reached (%d misses). See psx_dispatch_misses.txt\n", miss_count); - fflush(stderr); - if (miss_log) fclose(miss_log); - exit(1); - } + /* Always-on ring buffer of dispatch misses. Queryable via the + * `unknown_dispatch_log` debug command. Replaces the prior + * file-based log per CLAUDE.md §3. */ + extern void psx_unknown_dispatch_record(uint32_t addr, uint32_t phys, + uint32_t ra, uint32_t a0, + uint32_t a1); + psx_unknown_dispatch_record(addr, phys, cpu->gpr[31], + cpu->gpr[4], cpu->gpr[5]); /* Return without executing — function is a no-op. */ cpu->pc = 0; } diff --git a/tools/_freeze_diag2.py b/tools/_freeze_diag2.py new file mode 100644 index 00000000..f6d3f35f --- /dev/null +++ b/tools/_freeze_diag2.py @@ -0,0 +1,38 @@ +"""Diagnose freeze: ping debug server, then dump unknown_dispatch_log +and dispatch_tail to see what's looping/hanging.""" +import socket, json, sys +def call(payload, port=4370, timeout=5): + s = socket.create_connection(('127.0.0.1', port), timeout=timeout) + s.sendall((json.dumps(dict(payload, id=1))+'\n').encode()) + buf = b'' + while True: + c = s.recv(1<<20) + if not c: break + buf += c + try: return json.loads(buf.decode()) + except: pass + raise RuntimeError("incomplete") + +try: + print("=== ping ===") + print(call({'cmd':'ping'}, timeout=2)) +except Exception as e: + print(f"DEBUG SERVER UNRESPONSIVE: {e}") + sys.exit(1) + +# It's responsive — diagnose +print("\n=== unknown_dispatch_log summary ===") +r = call({'cmd':'unknown_dispatch_log'}) +print(f"total={r.get('total')} unique={r.get('unique')}") +for s in r.get('summary', [])[:10]: + print(f" {s['phys']}: {s['count']:>8}") + +print("\n=== unknown_dispatch_log tail (last 20) ===") +r = call({'cmd':'unknown_dispatch_log','tail':20}) +for e in r.get('entries', [])[-20:]: + print(f" seq={e['seq']:>5} phys={e['phys']} ra={e['ra']} a0={e['a0']} a1={e['a1']} frame={e['frame']}") + +print("\n=== dispatch_tail (last 50 dispatched targets) ===") +r = call({'cmd':'dispatch_tail','count':50}) +for a in r.get('addrs', [])[-50:]: + print(f" {a}") diff --git a/tools/_unknown_dispatch.py b/tools/_unknown_dispatch.py new file mode 100644 index 00000000..d42b7e57 --- /dev/null +++ b/tools/_unknown_dispatch.py @@ -0,0 +1,38 @@ +"""Query psx-runtime for psx_unknown_dispatch hits since boot. +Default: per-target summary sorted by hit count. +With tail=N: most recent N entries from the ring.""" +import socket, json, sys +def call(payload): + s = socket.create_connection(('127.0.0.1', 4370), timeout=10) + s.sendall((json.dumps(dict(payload, id=1))+'\n').encode()) + buf = b'' + while True: + c = s.recv(1<<20) + if not c: break + buf += c + try: return json.loads(buf.decode()) + except: pass + raise RuntimeError("incomplete") + +if len(sys.argv) > 1 and sys.argv[1] == 'tail': + r = call({'cmd':'unknown_dispatch_log','tail':50}) + print(f"total={r.get('total')} unique={r.get('unique')} tail={r.get('tail')}") + for e in r.get('entries', [])[-30:]: + print(f" seq={e['seq']:>6} addr={e['addr']} phys={e['phys']} ra={e['ra']} a0={e['a0']} a1={e['a1']} frame={e['frame']}") +else: + r = call({'cmd':'unknown_dispatch_log'}) + print(f"=== Unknown dispatch summary ===") + print(f"total hits={r.get('total')} unique targets={r.get('unique')}\n") + summary = r.get('summary', []) + for s in summary[:30]: + phys = s['phys'] + cnt = s['count'] + # Highlight modal-investigation PCs + marker = '' + for known_phys, lbl in [ + (0x1FC1A1BC, 'MODAL STUB'), + (0x1FC1A300, 'cursor_mirror2 writer 2'), + ]: + if int(phys, 16) == known_phys: + marker = f' <-- {lbl}' + print(f" {phys}: {cnt:>8}{marker}")