diff --git a/recompiler/seeds/dispatch_miss_seeds.json b/recompiler/seeds/dispatch_miss_seeds.json index 95c36bca..de82a382 100644 --- a/recompiler/seeds/dispatch_miss_seeds.json +++ b/recompiler/seeds/dispatch_miss_seeds.json @@ -1,38 +1,131 @@ -{ - "schema": "psxrecomp-v4 dispatch-miss seeds", - "source": "runtime dispatch miss log — functions called indirectly (JALR / function pointer tables)", - "note": "These functions have no static JAL callers and cannot be found by transitive discovery. They are reached at runtime via BIOS API dispatch tables (A0/B0/C0 vectors) or other indirect call mechanisms.", - "seeds": [ - {"address": "0xBFC42380", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC42844", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC38AD4", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC42A90", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC42A10", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC27FB0", "rationale": "dispatch miss: Kernel Part 2 function, indirect call"}, - {"address": "0xBFC36D48", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC38AA4", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC1E3AC", "rationale": "dispatch miss: Shell function, called in vblank loop"}, - {"address": "0xBFC3045C", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC30470", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC30484", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC30498", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC30554", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC30560", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC3056C", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC30578", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC36DD0", "rationale": "dispatch miss: Shell function, indirect call via table"}, - {"address": "0xBFC11840", "rationale": "dispatch miss: KP2 function, indirect call"}, - {"address": "0xBFC36DF8", "rationale": "dispatch miss: Shell function, indirect call"}, - {"address": "0xBFC11524", "rationale": "dispatch miss: KP2 secondary entry point for exception handler, mid-function split of func_00001A00, called during VBlank"}, - {"address": "0xBFC11610", "rationale": "dispatch miss: KP2 function, tail-call target from 0xBFC11524 exception handler path"}, - - {"address": "0xBFC14A54", "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain BUSY-writer at RAM 0x4F54; alias rule RAM=ROM-0xBFC10000+0x500. Reached via JAL inside FUN_bfc147f4; never emitted as standalone entry."}, - {"address": "0xBFC158D0", "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain init slot-0 BUSY writer at RAM 0x5DD0; alias RAM=ROM-0xBFC10000+0x500. Inside FUN_bfc158a8 body."}, - {"address": "0xBFC158D8", "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain init slot-1 BUSY writer at RAM 0x5DD8; alias RAM=ROM-0xBFC10000+0x500. Inside FUN_bfc158a8 body."}, - {"address": "0xBFC159F4", "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain step handler that writes 0x02 OPEN to [0x7568+slot] at RAM 0x5EF4. Indirect-jr target from RAM 0x6c98 jump table; alias RAM=ROM-0xBFC10000+0x500. KEY entry — without this the gate never clears."}, - {"address": "0xBFC15AA8", "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain step handler that writes 0x04 OPEN to [0x7568+slot] at RAM 0x5FA8. Indirect-jr target from RAM 0x6c98 jump table; alias RAM=ROM-0xBFC10000+0x500. KEY entry — paired with 0xBFC159F4."}, - {"address": "0xBFC04910", "rationale": "Tomba boot dispatch miss after licensed PlayStation screen. Verified in Ghidra/runtime disassembly as a standalone BIOS init routine between 0xBFC048D0 and 0xBFC04ABC, with return at 0xBFC04A98 and table data reference from 0xBFC04554."}, - {"address": "0xBFC04850", "rationale": "Tomba boot dispatch miss after seeding 0xBFC04910. Verified in Ghidra/runtime disassembly as a standalone BIOS callback-list init routine between 0xBFC0472C and 0xBFC048D0, with return at 0xBFC048C8 and table data reference from 0xBFC04588."}, - {"address": "0xBFC079F8", "rationale": "Tomba boot dispatch miss after game callback coverage fixes. Verified in Ghidra as a tiny BIOS table leaf routine (sw a0,0(sp); jr ra; clear v0) referenced by data at 0xBFC04484 and 0xBFC0E30C."} - ] -} +{ + "schema": "psxrecomp-v4 dispatch-miss seeds", + "source": "runtime dispatch miss log \u00e2\u20ac\u201d functions called indirectly (JALR / function pointer tables)", + "note": "These functions have no static JAL callers and cannot be found by transitive discovery. They are reached at runtime via BIOS API dispatch tables (A0/B0/C0 vectors) or other indirect call mechanisms.", + "seeds": [ + { + "address": "0xBFC42380", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC42844", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC38AD4", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC42A90", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC42A10", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC27FB0", + "rationale": "dispatch miss: Kernel Part 2 function, indirect call" + }, + { + "address": "0xBFC36D48", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC38AA4", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC1E3AC", + "rationale": "dispatch miss: Shell function, called in vblank loop" + }, + { + "address": "0xBFC3045C", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC30470", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC30484", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC30498", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC30554", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC30560", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC3056C", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC30578", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC36DD0", + "rationale": "dispatch miss: Shell function, indirect call via table" + }, + { + "address": "0xBFC11840", + "rationale": "dispatch miss: KP2 function, indirect call" + }, + { + "address": "0xBFC36DF8", + "rationale": "dispatch miss: Shell function, indirect call" + }, + { + "address": "0xBFC11524", + "rationale": "dispatch miss: KP2 secondary entry point for exception handler, mid-function split of func_00001A00, called during VBlank" + }, + { + "address": "0xBFC11610", + "rationale": "dispatch miss: KP2 function, tail-call target from 0xBFC11524 exception handler path" + }, + { + "address": "0xBFC14A54", + "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain BUSY-writer at RAM 0x4F54; alias rule RAM=ROM-0xBFC10000+0x500. Reached via JAL inside FUN_bfc147f4; never emitted as standalone entry." + }, + { + "address": "0xBFC158D0", + "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain init slot-0 BUSY writer at RAM 0x5DD0; alias RAM=ROM-0xBFC10000+0x500. Inside FUN_bfc158a8 body." + }, + { + "address": "0xBFC158D8", + "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain init slot-1 BUSY writer at RAM 0x5DD8; alias RAM=ROM-0xBFC10000+0x500. Inside FUN_bfc158a8 body." + }, + { + "address": "0xBFC159F4", + "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain step handler that writes 0x02 OPEN to [0x7568+slot] at RAM 0x5EF4. Indirect-jr target from RAM 0x6c98 jump table; alias RAM=ROM-0xBFC10000+0x500. KEY entry \u00e2\u20ac\u201d without this the gate never clears." + }, + { + "address": "0xBFC15AA8", + "rationale": "dispatch miss (Beetle wtrace, docs/CASE_A_AOT_GAP.md): chain step handler that writes 0x04 OPEN to [0x7568+slot] at RAM 0x5FA8. Indirect-jr target from RAM 0x6c98 jump table; alias RAM=ROM-0xBFC10000+0x500. KEY entry \u00e2\u20ac\u201d paired with 0xBFC159F4." + }, + { + "address": "0xBFC04910", + "rationale": "Tomba boot dispatch miss after licensed PlayStation screen. Verified in Ghidra/runtime disassembly as a standalone BIOS init routine between 0xBFC048D0 and 0xBFC04ABC, with return at 0xBFC04A98 and table data reference from 0xBFC04554." + }, + { + "address": "0xBFC04850", + "rationale": "Tomba boot dispatch miss after seeding 0xBFC04910. Verified in Ghidra/runtime disassembly as a standalone BIOS callback-list init routine between 0xBFC0472C and 0xBFC048D0, with return at 0xBFC048C8 and table data reference from 0xBFC04588." + }, + { + "address": "0xBFC079F8", + "rationale": "Tomba boot dispatch miss after game callback coverage fixes. Verified in Ghidra as a tiny BIOS table leaf routine (sw a0,0(sp); jr ra; clear v0) referenced by data at 0xBFC04484 and 0xBFC0E30C." + }, + { + "address": "0xBFC15F1C", + "rationale": "dirty_ram hot: SIO/PAD interrupt handler entry point (RAM 0x641C), called via jalr. 10852+ hits/frame across internal branch targets (0x641C, 0x6430, 0x6444, 0x6458, 0x650C, 0x6514, 0x658C, 0x6594). Seeding entry only; CFG discovers internal labels." + } + ] +} \ No newline at end of file diff --git a/recompiler/seeds/phase2_ghidra_seeds.json b/recompiler/seeds/phase2_ghidra_seeds.json index d8216e59..9ecf9edc 100644 --- a/recompiler/seeds/phase2_ghidra_seeds.json +++ b/recompiler/seeds/phase2_ghidra_seeds.json @@ -1,7 +1,7 @@ { - "schema": "psxrecomp-v4 phase2 seeds", + "schema": "psxrecomp phase2 seeds", "source": "generated/ghidra_function_starts.json + phase1c seeds + dispatch_miss_seeds + preserved manual", - "seed_count": 1071, + "seed_count": 1072, "seeds": [ { "address": "0xBFC00000", @@ -3493,6 +3493,11 @@ "label": "dmiss_BFC079F8", "rationale": "Tomba boot dispatch miss after game callback coverage fixes. Verified in Ghidra as a tiny BIOS table leaf routine (sw a0,0(sp); jr ra; clear v0) referenced by data at 0xBFC04484 and 0xBFC0E30C." }, + { + "address": "0xBFC15F1C", + "label": "dmiss_BFC15F1C", + "rationale": "dirty_ram hot: SIO/PAD interrupt handler entry point (RAM 0x641C), called via jalr. 10852+ hits/frame across internal branch targets (0x641C, 0x6430, 0x6444, 0x6458, 0x650C, 0x6514, 0x658C, 0x6594). Seeding entry only; CFG discovers internal labels." + }, { "address": "0xBFC0193C", "label": "cache_flush_continuation", @@ -4677,11 +4682,11 @@ "label": "gte_lib_BFC34EC4", "rationale": "GTE math library function. Batch-discovered from BFC33000-BFC36000." }, - { - "address": "0xBFC34FA0", - "label": "gte_lib_BFC34FA0", - "rationale": "GTE math library function missed by adjacent batch discovery; contains the BFC34FF8-BFC350C4 MVMVA/SWC2 helper used by the BIOS disc logo screen." - }, + { + "address": "0xBFC34FA0", + "label": "gte_lib_BFC34FA0", + "rationale": "GTE math library function missed by adjacent batch discovery; contains the BFC34FF8-BFC350C4 MVMVA/SWC2 helper used by the BIOS disc logo screen." + }, { "address": "0xBFC35128", "label": "gte_lib_BFC35128", @@ -5320,4 +5325,4 @@ "rationale": "R3000 UTLB-miss vector; PS1 has no TLB; never executed" } ] -} +} \ No newline at end of file diff --git a/tools/probe_dirty_ram.py b/tools/probe_dirty_ram.py new file mode 100644 index 00000000..7091cf97 --- /dev/null +++ b/tools/probe_dirty_ram.py @@ -0,0 +1,49 @@ +import socket, json, time, sys + +port = int(sys.argv[1]) if len(sys.argv) > 1 else 4470 + +def send_cmd(cmd, **kwargs): + payload = {'id': 1, 'cmd': cmd} + payload.update(kwargs) + s = socket.create_connection(('127.0.0.1', port), timeout=3) + s.sendall(json.dumps(payload).encode() + b'\n') + data = b'' + while True: + chunk = s.recv(4096) + if not chunk: + break + data += chunk + try: + json.loads(data.decode()) + break + except: + pass + s.close() + return json.loads(data.decode()) + +# Wait for server +for i in range(15): + try: + r = send_cmd('ping') + print(f'Connected. frame={r.get("frame")}, dispatch_miss_total={r.get("dispatch_miss_total")}') + break + except Exception as e: + print(f' waiting... ({e})') + time.sleep(2) +else: + print('Could not connect after 30s') + sys.exit(1) + +# Query dirty_ram stats +try: + r = send_cmd('dirty_ram_stats') + print('dirty_ram_stats:', json.dumps(r, indent=2)) +except Exception as e: + print(f'dirty_ram_stats failed: {e}') + +# Also try heartbeat +try: + r = send_cmd('heartbeat') + print('heartbeat:', json.dumps(r, indent=2)) +except Exception as e: + print(f'heartbeat failed: {e}')