mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 10:59:16 -04:00
8a5df6cd1e
Parking DuckStation was the wrong design and it never worked. A paused DuckStation serves its debug socket from a Qt idle timer at about 1 Hz, so a list walk needing many round trips cannot finish; and a pc_break that re-fires on its next hit re-pauses the instant anything resumes it, wedging the emulator for the user as well as the tool. Two rounds of fixes went into making the parking safe when the parking itself was unnecessary. The effect lasts seconds and the game rebuilds its ordering table every frame, so the oracle is now read while it RUNS -- sampling often rather than freezing time, which is how psx-runtime's ring side already worked. psx-runtime is never paused either; it is read backwards out of the ring. Adds oracle_unwedge.py to clear a breakpoint an earlier run left armed, since that state lives in DuckStation and outlives the script that set it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""oracle_unwedge.py -- get a stuck DuckStation oracle running again.
|
|
|
|
python3 tools/oracle_unwedge.py
|
|
|
|
A breakpoint left armed by an earlier tool keeps firing and re-pausing the
|
|
emulator, so unpausing it by hand bounces straight back. That state lives in
|
|
DuckStation, not in the tool that set it, so it survives restarting the
|
|
script -- but not restarting DuckStation.
|
|
|
|
This removes every execute breakpoint the oracle holds, resumes it, and says
|
|
what it found. Run it whenever the oracle seems stuck.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from psx_gpu_frame import ( # noqa: E402
|
|
DEFAULT_DUCKSTATION_PORT, DebugConn, DebugError, oracle_break_list,
|
|
oracle_clear_breaks, oracle_resume,
|
|
)
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser(description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
ap.add_argument("--host", default="127.0.0.1")
|
|
ap.add_argument("--port", type=int, default=DEFAULT_DUCKSTATION_PORT)
|
|
ap.add_argument("--timeout", type=float, default=30.0)
|
|
args = ap.parse_args()
|
|
|
|
conn = DebugConn(args.host, args.port, args.timeout)
|
|
try:
|
|
held = oracle_break_list(conn)
|
|
except DebugError as e:
|
|
print(f"could not reach the oracle on port {args.port}: {e}")
|
|
return 1
|
|
|
|
if held:
|
|
print("breakpoints held: " + ", ".join(f"0x{a:08X}" for a in held))
|
|
else:
|
|
print("no breakpoints held")
|
|
|
|
# Resume first: a paused oracle answers at about 1 Hz, which is what makes
|
|
# the removal below time out in the first place.
|
|
oracle_resume(conn)
|
|
try:
|
|
n = oracle_clear_breaks(conn)
|
|
if n:
|
|
print(f"removed {n} breakpoint(s)")
|
|
except DebugError as e:
|
|
print(f"FAILED: {e}")
|
|
return 1
|
|
running = oracle_resume(conn)
|
|
print("oracle resumed" if running else
|
|
"could not confirm the oracle resumed; restart DuckStation")
|
|
return 0 if running else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|