102 lines
2.6 KiB
Python
102 lines
2.6 KiB
Python
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]}"
|