1
0
Files
h8-536-decoder/h8536/render.py
2026-05-25 13:40:07 +10:00

88 lines
3.1 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from .formatting import h16, label_for
from .model import Instruction
from .rom import Rom
from .vectors import DtcVectorEntry
def format_listing(
rom_path: Path,
rom: Rom,
instructions: dict[int, Instruction],
vectors: dict[int, tuple[str, int]],
labels: dict[int, str],
mode: str,
traced: bool,
dtc_vectors: dict[int, DtcVectorEntry] | None = None,
) -> str:
lines: list[str] = []
lines.append("; H8/536 ROM disassembly")
lines.append(f"; input: {rom_path}")
lines.append(f"; bytes: {len(rom.data)}")
lines.append(f"; vector mode: {mode}")
lines.append(f"; analysis: {'recursive trace from vectors' if traced else 'linear sweep'}")
lines.append(";")
lines.append("; Notes from the manual:")
lines.append("; - H8/536 uses the H8/500 CPU instruction set.")
lines.append("; - In minimum mode the reset vector at H'0000-H'0001 is a 16-bit PC.")
lines.append("; - The register field is H'FE80-H'FFFF; names below come from appendix B.")
lines.append("")
lines.append("; Vectors")
for vector_addr, (name, target) in sorted(vectors.items()):
target_name = labels.get(target, label_for(target))
lines.append(f"; {h16(vector_addr)} {name:<24} -> {target_name} ({h16(target)})")
lines.append("")
if dtc_vectors:
lines.append("; DTC Vectors")
for vector_addr, entry in sorted(dtc_vectors.items()):
target = entry["register_info_address"]
lines.append(f"; {h16(vector_addr)} {entry['source']:<24} -> {h16(target)}")
lines.append("")
for address in sorted(instructions):
ins = instructions[address]
if address in labels:
lines.append("")
lines.append(f"{labels[address]}:")
raw = " ".join(f"{byte:02X}" for byte in ins.raw)
padded_raw = raw.ljust(14)
comment = f" ; {ins.comment}" if ins.comment else ""
lines.append(f"{address:04X}: {padded_raw} {ins.text}{comment}")
lines.append("")
return "\n".join(lines)
def write_json(
path: Path,
instructions: dict[int, Instruction],
vectors: dict[int, tuple[str, int]],
labels: dict[int, str],
dtc_vectors: dict[int, DtcVectorEntry] | None = None,
) -> None:
payload = {
"vectors": [
{"address": addr, "name": name, "target": target, "target_label": labels.get(target)}
for addr, (name, target) in sorted(vectors.items())
],
"dtc_vectors": list((dtc_vectors or {}).values()),
"instructions": [
{
"address": ins.address,
"bytes": ins.raw.hex().upper(),
"text": ins.text,
"mnemonic": ins.mnemonic,
"operands": ins.operands,
"kind": ins.kind,
"targets": ins.targets,
"comment": ins.comment,
"valid": ins.valid,
}
for ins in (instructions[addr] for addr in sorted(instructions))
],
}
path.write_text(json.dumps(payload, indent=2), encoding="utf-8")