Intial commit
This commit is contained in:
101
h8536/formatting.py
Normal file
101
h8536/formatting.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .model import EA
|
||||
from .tables import IO_BITFIELDS, IO_REGISTERS
|
||||
|
||||
|
||||
def h8(value: int) -> str:
|
||||
return f"H'{value & 0xFF:02X}"
|
||||
|
||||
|
||||
def h16(value: int) -> str:
|
||||
return f"H'{value & 0xFFFF:04X}"
|
||||
|
||||
|
||||
def h24(value: int) -> str:
|
||||
return f"H'{value & 0xFFFFFF:06X}"
|
||||
|
||||
|
||||
def s8(value: int) -> int:
|
||||
value &= 0xFF
|
||||
return value - 0x100 if value & 0x80 else value
|
||||
|
||||
|
||||
def s16(value: int) -> int:
|
||||
value &= 0xFFFF
|
||||
return value - 0x10000 if value & 0x8000 else value
|
||||
|
||||
|
||||
def parse_int(text: str) -> int:
|
||||
return int(text.replace("H'", "0x").replace("$", "0x"), 0)
|
||||
|
||||
|
||||
def reg_list(mask: int) -> str:
|
||||
regs = [f"R{idx}" for idx in range(8) if mask & (1 << idx)]
|
||||
return "{" + ",".join(regs) + "}" if regs else "{}"
|
||||
|
||||
|
||||
def disp_text(value: int) -> str:
|
||||
if value < 0:
|
||||
return f"-{h16(-value) if value < -0xFF else h8(-value)}"
|
||||
return h16(value) if value > 0xFF else h8(value)
|
||||
|
||||
|
||||
def short_abs(low: int) -> str:
|
||||
return f"@BR:{h8(low)}"
|
||||
|
||||
|
||||
def control_reg(ccc: int, size: str) -> str:
|
||||
if size == "W":
|
||||
return "SR" if ccc == 0 else f"CR{ccc}?"
|
||||
return {
|
||||
0: "CCR",
|
||||
1: "BR",
|
||||
2: "EP",
|
||||
3: "DP",
|
||||
4: "TP",
|
||||
}.get(ccc, f"CR{ccc}?")
|
||||
|
||||
|
||||
def label_for(address: int) -> str:
|
||||
return f"loc_{address:04X}"
|
||||
|
||||
|
||||
def label_or_h(address: int, labels: dict[int, str]) -> str:
|
||||
return labels.get(address, label_for(address))
|
||||
|
||||
|
||||
def _bitfield_name(address: int, bit: int) -> str | None:
|
||||
return IO_BITFIELDS.get(address, {}).get(bit)
|
||||
|
||||
|
||||
def _bitfield_values(address: int, value: int) -> str:
|
||||
fields = IO_BITFIELDS.get(address)
|
||||
if not fields:
|
||||
return ""
|
||||
parts = [f"{name}={(value >> bit) & 1}" for bit, name in sorted(fields.items(), reverse=True)]
|
||||
return " ".join(parts)
|
||||
|
||||
|
||||
def write_comment(ea: EA, value: int | None) -> str:
|
||||
if ea.address is None or ea.address not in IO_REGISTERS:
|
||||
return ""
|
||||
name = IO_REGISTERS[ea.address]
|
||||
if value is None:
|
||||
return name
|
||||
text = f"{name} = {h16(value) if value > 0xFF else h8(value)}"
|
||||
fields = _bitfield_values(ea.address, value)
|
||||
return f"{text} ({fields})" if fields else text
|
||||
|
||||
|
||||
def bit_comment(mnemonic: str, ea: EA, bit: int) -> str:
|
||||
if ea.address is None or ea.address not in IO_REGISTERS:
|
||||
return ""
|
||||
action = {"BSET": "set", "BCLR": "clear", "BNOT": "toggle", "BTST": "test"}.get(
|
||||
mnemonic.split(".")[0],
|
||||
"bit",
|
||||
)
|
||||
bit_name = _bitfield_name(ea.address, bit)
|
||||
if bit_name:
|
||||
return f"{action} {bit_name} (bit {bit}) of {IO_REGISTERS[ea.address]}"
|
||||
return f"{action} bit {bit} of {IO_REGISTERS[ea.address]}"
|
||||
Reference in New Issue
Block a user