diff --git a/src/ferrolang_vm/cli.py b/src/ferrolang_vm/cli.py index 28aa392..e749203 100644 --- a/src/ferrolang_vm/cli.py +++ b/src/ferrolang_vm/cli.py @@ -44,6 +44,8 @@ def main() -> int: commands.add_parser(name) reset = commands.add_parser("reset") reset.add_argument("--timeout", type=int, default=45) + soft_reset = commands.add_parser("soft-reset") + soft_reset.add_argument("--timeout", type=int, default=45) execute = commands.add_parser("exec") execute.add_argument("command") put = commands.add_parser("put") @@ -63,10 +65,13 @@ def main() -> int: recognized = RapidOCR()(result["path"]) print("\n".join(recognized.txts or ())) return 0 - if args.op == "reset": - rpc({"op": "stop"}, start_daemon=True) - time.sleep(.5) - rpc({"op": "start"}, start_daemon=True) + if args.op in ("reset", "soft-reset"): + if args.op == "reset": + rpc({"op": "stop"}, start_daemon=True) + time.sleep(.5) + rpc({"op": "start"}, start_daemon=True) + else: + rpc({"op": "soft-reset"}) # FreeDOS displays its default boot menu before FDAUTO.BAT starts # TCPAGENT. This is input, not a readiness delay. time.sleep(2) @@ -75,7 +80,7 @@ def main() -> int: while time.monotonic() < deadline: try: if str(rpc({"op": "ping"})["response"]).startswith("OK 504F4E47"): - print(json.dumps({"reset": True, "agent": "PONG"})) + print(json.dumps({"reset": args.op, "agent": "PONG"})) return 0 except RuntimeError: time.sleep(.5) diff --git a/src/ferrolang_vm/daemon.py b/src/ferrolang_vm/daemon.py index 84ab4bd..8c55bcb 100644 --- a/src/ferrolang_vm/daemon.py +++ b/src/ferrolang_vm/daemon.py @@ -232,6 +232,10 @@ class Host: return {"agent_connected": self.agent_ready.is_set(), "qemu_running": running, "log": str(LOG_PATH)} if op == "start": return self.start() if op == "stop": return self.stop() + if op == "soft-reset": + self.monitor("system_reset") + log_event(logging.INFO, "qemu soft reset requested") + return {"reset": "requested"} if op == "ping": return self.ping() if op == "exec": return self.exec(str(request["command"])) if op == "put": return self.put(str(request["source"]), str(request["destination"])) diff --git a/tools/README.md b/tools/README.md index 2b0b4b8..810ebea 100644 --- a/tools/README.md +++ b/tools/README.md @@ -26,6 +26,8 @@ lnav .qemu/ferro-vm.log Commands: ```powershell +uv run ferro-vm reset # clean QEMU quit and restart +uv run ferro-vm soft-reset # QEMU system_reset uv run ferro-vm ping uv run ferro-vm exec 'dir C:\FEC' uv run ferro-vm put fec/src/check.c 'C:\FEC\SRC\CHECK.C' @@ -35,8 +37,9 @@ uv run ferro-vm ocr uv run ferro-vm stop ``` -The daemon logs command metadata, DOS output, exit status, transfers, and -agent lifecycle events as UTF-8 lines. It deliberately never logs raw binary +Both reset modes wait for FreeDOS to boot, submit the default boot-menu Enter, +and require TCPAGENT `PING`/`PONG` before succeeding. The daemon logs command +metadata, DOS output, exit status, transfers, and agent lifecycle events as UTF-8 lines. It deliberately never logs raw binary payloads or protocol hex. ## Standalone OCR