63 lines
2.4 KiB
Python
63 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
# traceRun.py - run the game under VICE (NTSC) to $0800, then enable an exec tracepoint over the
|
|
# whole RAM range and collect every executed PC for a wall-clock budget; write a coverage file.
|
|
import socket, subprocess, sys, time, os, re
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from viceDriver import pickFreePort, recvUntilPrompt, SCRATCH
|
|
|
|
def main():
|
|
disk = os.path.abspath(sys.argv[1])
|
|
budget = int(sys.argv[2])
|
|
outName = sys.argv[3]
|
|
port = pickFreePort()
|
|
cmd = ["xvfb-run", "-a", "x64sc", "-remotemonitor", "-remotemonitoraddress", f"127.0.0.1:{port}",
|
|
"-drive8truedrive", "-drive8type", "1541", "-sounddev", "dummy", "-warp", "-jamaction", "2",
|
|
"-autostart-warp", "-model", "ntsc", "-chdir", SCRATCH, "-autostart", disk]
|
|
proc = subprocess.Popen(cmd, stdout=open(f"{SCRATCH}/trace_stdout.txt", "w"), stderr=subprocess.STDOUT)
|
|
sock = None
|
|
for _ in range(100):
|
|
try:
|
|
sock = socket.create_connection(("127.0.0.1", port), timeout=1); break
|
|
except OSError:
|
|
time.sleep(0.3)
|
|
print(recvUntilPrompt(sock, 10))
|
|
sock.sendall(b"break 0800\n"); print(recvUntilPrompt(sock, 10))
|
|
sock.sendall(b"x\n"); print(recvUntilPrompt(sock, 300))
|
|
sock.sendall(b"del\n"); print(recvUntilPrompt(sock, 10))
|
|
sock.sendall(b"tr exec 0000 ffff\n"); print(recvUntilPrompt(sock, 10))
|
|
sock.sendall(b"x\n")
|
|
pcs = {}
|
|
buf = b""
|
|
deadline = time.time() + budget
|
|
sock.settimeout(1.0)
|
|
total = 0
|
|
rx = re.compile(rb"\.C:([0-9a-f]{4})")
|
|
while time.time() < deadline:
|
|
try:
|
|
chunk = sock.recv(1 << 20)
|
|
if not chunk: break
|
|
total += len(chunk)
|
|
buf += chunk
|
|
lines = buf.split(b"\n")
|
|
buf = lines[-1]
|
|
for ln in lines[:-1]:
|
|
m = rx.search(ln)
|
|
if m:
|
|
pc = int(m.group(1), 16)
|
|
pcs[pc] = pcs.get(pc, 0) + 1
|
|
except socket.timeout:
|
|
pass
|
|
with open(f"{SCRATCH}/{outName}", "w") as f:
|
|
for pc in sorted(pcs):
|
|
f.write(f"{pc:04X} {pcs[pc]}\n")
|
|
print(f"bytes received {total}, distinct PCs {len(pcs)}")
|
|
try:
|
|
sock.sendall(b"\n")
|
|
time.sleep(0.5)
|
|
sock.sendall(b"quit\n")
|
|
except OSError:
|
|
pass
|
|
time.sleep(1)
|
|
proc.kill(); proc.wait()
|
|
|
|
main()
|