First public commit.
This commit is contained in:
parent
2a48f52979
commit
4bac9d83ed
288 changed files with 18417 additions and 1076 deletions
99
lenser/coco/mc6809.py
Normal file
99
lenser/coco/mc6809.py
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
"""A tiny Motorola 6809 machine-code emitter (just what the CoCo viewer needs).
|
||||
|
||||
No 6809 assembler is installed, so -- as with the TI's TMS9900 emitter -- we emit
|
||||
opcodes directly. Supports labels + 8-bit relative-branch backpatching.
|
||||
Index-register codes for ,R+ postbytes: X=0x80, Y=0xA0, U=0xC0, S=0xE0.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
_IDX = {"x": 0x80, "y": 0xA0, "u": 0xC0, "s": 0xE0}
|
||||
|
||||
|
||||
class Asm:
|
||||
def __init__(self, base: int):
|
||||
self.base = base
|
||||
self.code = bytearray()
|
||||
self.labels: dict[str, int] = {}
|
||||
self._fix: list[tuple[int, str]] = [] # (pos of rel byte, label)
|
||||
|
||||
def pos(self) -> int:
|
||||
return self.base + len(self.code)
|
||||
|
||||
def label(self, name: str):
|
||||
self.labels[name] = self.pos()
|
||||
|
||||
def _b(self, *bs):
|
||||
self.code += bytes(bs)
|
||||
|
||||
def _w(self, v): # 16-bit, big-endian
|
||||
self.code += bytes([(v >> 8) & 0xFF, v & 0xFF])
|
||||
|
||||
# ---- inherent ----
|
||||
def nop(self): self._b(0x12)
|
||||
def clra(self): self._b(0x4F)
|
||||
def clrb(self): self._b(0x5F)
|
||||
def deca(self): self._b(0x4A)
|
||||
def decb(self): self._b(0x5A)
|
||||
def inca(self): self._b(0x4C)
|
||||
def incb(self): self._b(0x5C)
|
||||
def rts(self): self._b(0x39)
|
||||
def sync(self): self._b(0x13)
|
||||
|
||||
# ---- immediate ----
|
||||
def lda_imm(self, v): self._b(0x86, v & 0xFF)
|
||||
def ldb_imm(self, v): self._b(0xC6, v & 0xFF)
|
||||
def anda_imm(self, v): self._b(0x84, v & 0xFF)
|
||||
def ora_imm(self, v): self._b(0x8A, v & 0xFF)
|
||||
def cmpa_imm(self, v): self._b(0x81, v & 0xFF)
|
||||
def cmpb_imm(self, v): self._b(0xC1, v & 0xFF)
|
||||
def orcc(self, v): self._b(0x1A, v & 0xFF)
|
||||
def andcc(self, v): self._b(0x1C, v & 0xFF)
|
||||
|
||||
def ldd_imm(self, v): self._b(0xCC); self._w(v)
|
||||
def subd_imm(self, v): self._b(0x83); self._w(v)
|
||||
def ldx_imm(self, v): self._b(0x8E); self._w(v)
|
||||
def ldu_imm(self, v): self._b(0xCE); self._w(v)
|
||||
def ldy_imm(self, v): self._b(0x10, 0x8E); self._w(v)
|
||||
def lds_imm(self, v): self._b(0x10, 0xCE); self._w(v)
|
||||
def cmpx_imm(self, v): self._b(0x8C); self._w(v)
|
||||
def cmpu_imm(self, v): self._b(0x11, 0x83); self._w(v)
|
||||
|
||||
# ---- extended (16-bit address) ----
|
||||
def lda_ext(self, a): self._b(0xB6); self._w(a)
|
||||
def sta_ext(self, a): self._b(0xB7); self._w(a)
|
||||
def ldb_ext(self, a): self._b(0xF6); self._w(a)
|
||||
def stb_ext(self, a): self._b(0xF7); self._w(a)
|
||||
def std_ext(self, a): self._b(0xFD); self._w(a)
|
||||
def jmp_ext(self, a): self._b(0x7E); self._w(a)
|
||||
def jsr_ext(self, a): self._b(0xBD); self._w(a)
|
||||
def jmp_ind(self, a): self._b(0x6E, 0x9F); self._w(a) # JMP [addr] (indirect)
|
||||
|
||||
# ---- indexed auto-increment: LDA ,R+ / STA ,R+ ----
|
||||
def lda_postinc(self, r): self._b(0xA6, _IDX[r])
|
||||
def sta_postinc(self, r): self._b(0xA7, _IDX[r])
|
||||
def ldb_postinc(self, r): self._b(0xE6, _IDX[r])
|
||||
def stb_postinc(self, r): self._b(0xE7, _IDX[r])
|
||||
|
||||
# ---- 8-bit relative branches ----
|
||||
def _branch(self, op, label):
|
||||
self._b(op)
|
||||
self._fix.append((len(self.code), label))
|
||||
self._b(0x00) # placeholder
|
||||
|
||||
def bra(self, label): self._branch(0x20, label)
|
||||
def bne(self, label): self._branch(0x26, label)
|
||||
def beq(self, label): self._branch(0x27, label)
|
||||
def bpl(self, label): self._branch(0x2A, label)
|
||||
def bmi(self, label): self._branch(0x2B, label)
|
||||
def bcc(self, label): self._branch(0x24, label)
|
||||
def bcs(self, label): self._branch(0x25, label)
|
||||
|
||||
def resolve(self) -> bytes:
|
||||
for pos, label in self._fix:
|
||||
target = self.labels[label]
|
||||
rel = target - (self.base + pos + 1)
|
||||
if not -128 <= rel <= 127:
|
||||
raise ValueError(f"branch to {label} out of range ({rel})")
|
||||
self.code[pos] = rel & 0xFF
|
||||
return bytes(self.code)
|
||||
Loading…
Add table
Add a link
Reference in a new issue