67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from ..formatting import h16
|
|
from .memory import describe_regions
|
|
from .runner import H8536Emulator
|
|
|
|
|
|
def discover_rom_path(root: Path) -> Path | None:
|
|
candidates = [
|
|
root / "ROM" / "M27C512@DIP28_1.BIN",
|
|
root / "rom.bin",
|
|
]
|
|
candidates.extend(sorted((root / "ROM").glob("*.BIN")) if (root / "ROM").exists() else [])
|
|
candidates.extend(sorted((root / "ROM").glob("*.bin")) if (root / "ROM").exists() else [])
|
|
for candidate in candidates:
|
|
if candidate.is_file():
|
|
return candidate
|
|
return None
|
|
|
|
|
|
def load_rom(path: Path | None = None, root: Path | None = None) -> tuple[bytes, Path]:
|
|
root = root if root is not None else Path.cwd()
|
|
rom_path = path if path is not None else discover_rom_path(root)
|
|
if rom_path is None:
|
|
raise FileNotFoundError(
|
|
"could not discover ROM bytes; pass --rom PATH, expected ROM/M27C512@DIP28_1.BIN or another ROM/*.BIN"
|
|
)
|
|
return rom_path.read_bytes(), rom_path
|
|
|
|
|
|
def build_arg_parser() -> argparse.ArgumentParser:
|
|
parser = argparse.ArgumentParser(description="Minimal H8/536 emulation harness scaffold")
|
|
parser.add_argument("--rom", type=Path, help="ROM image path; defaults to ROM/M27C512@DIP28_1.BIN when present")
|
|
parser.add_argument("--max-steps", type=int, default=64, help="maximum CPU steps to execute")
|
|
parser.add_argument("--trace", action="store_true", help="print decoded/executed instruction trace")
|
|
parser.add_argument("--stop-on-heartbeat", action="store_true", help="stop only when 00 00 00 00 80 DA is emitted through SCI1 TDR")
|
|
parser.add_argument("--memory-map", action="store_true", help="print the scaffolded memory map before running")
|
|
parser.add_argument("--interval-steps", type=int, default=2048, help="rough step period for the scaffolded timer interrupt")
|
|
return parser
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
args = build_arg_parser().parse_args(argv)
|
|
try:
|
|
rom_bytes, rom_path = load_rom(args.rom)
|
|
except FileNotFoundError as exc:
|
|
print(str(exc))
|
|
return 2
|
|
|
|
emulator = H8536Emulator(rom_bytes, interval_steps=args.interval_steps)
|
|
print(f"rom={rom_path}")
|
|
print(f"reset_vector={h16(emulator.reset_vector())}")
|
|
if args.memory_map:
|
|
print(describe_regions())
|
|
report = emulator.run(args.max_steps, trace=args.trace, stop_on_heartbeat=args.stop_on_heartbeat)
|
|
if args.trace:
|
|
for line in report.trace:
|
|
print(line)
|
|
for line in report.summary_lines():
|
|
print(line)
|
|
if not report.heartbeat_seen:
|
|
print("heartbeat_status=not reached; no heartbeat is reported unless bytes are emitted via SCI1_TDR")
|
|
return 0
|