Intial commit
This commit is contained in:
87
h8536/render.py
Normal file
87
h8536/render.py
Normal file
@@ -0,0 +1,87 @@
|
||||
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")
|
||||
Reference in New Issue
Block a user