First public commit.

This commit is contained in:
The Dust Council 2026-07-03 19:35:35 -07:00
parent 2a48f52979
commit 4bac9d83ed
288 changed files with 18417 additions and 1076 deletions

View file

View file

@ -0,0 +1,62 @@
"""Assemble the C16 TED viewer with `xa` and build the loadable PRG.
The PRG loads at the C16 BASIC start ($1001): a BASIC stub (`10 SYS4128`)
followed by the 7501 viewer (at $1020), the two colour matrices ($1800 / $1C00)
and the bitmap ($2000). MAME's quickload runs it, the stub SYSes the viewer.
"""
from __future__ import annotations
import os
import shutil
import subprocess
import tempfile
VIEWER_DIR = os.path.dirname(os.path.abspath(__file__))
BASIC_START = 0x1001
ML_ORG = 0x1020
ATTR_ORG = 0x1800 # luminance matrix (video matrix base)
CH_ORG = 0x1C00 # hue matrix (video base | $400)
BITMAP_ORG = 0x2000
# BASIC: 10 SYS4128 ($1020 = 4128) -- bytes as they sit from $1001
_STUB = bytes([0x0B, 0x10, 0x0A, 0x00, 0x9E,
0x34, 0x31, 0x32, 0x38, 0x00, 0x00, 0x00])
class AssemblerError(RuntimeError):
pass
def have_xa() -> bool:
return shutil.which("xa") is not None
def _assemble() -> bytes:
if not have_xa():
raise AssemblerError("The 'xa' (xa65) assembler was not found on PATH.\n"
"Install it with: sudo apt install xa65")
proc = subprocess.run(["xa", "-o", "/dev/stdout", "viewer.s"],
capture_output=True, cwd=VIEWER_DIR)
if proc.returncode != 0:
raise AssemblerError(f"xa failed:\n{proc.stderr.decode()}")
return proc.stdout
def build_prg(payload: bytes) -> bytes:
"""payload = bitmap(8000) + attr(1000) + ch(1000); returns the loadable PRG."""
bitmap, attr, ch = payload[:8000], payload[8000:9000], payload[9000:10000]
code = _assemble()
mem = bytearray()
mem += _STUB # $1001..
mem += b"\x00" * (ML_ORG - BASIC_START - len(mem))
mem += code # $1020..
if len(mem) > ATTR_ORG - BASIC_START:
raise AssemblerError("viewer code overruns the $1800 matrix area")
mem += b"\x00" * (ATTR_ORG - BASIC_START - len(mem))
mem += attr # $1800..
mem += b"\x00" * (CH_ORG - BASIC_START - len(mem))
mem += ch # $1C00..
mem += b"\x00" * (BITMAP_ORG - BASIC_START - len(mem))
mem += bitmap # $2000..
return bytes([BASIC_START & 0xFF, BASIC_START >> 8]) + bytes(mem)

View file

@ -0,0 +1,26 @@
; Commodore 16 (TED 7360/8360) hires bitmap viewer.
;
; The whole picture is already laid out in RAM by the PRG (loaded via quickload):
; $1800 attribute matrix (luminance) 1000 bytes
; $1C00 colour matrix (hue) 1000 bytes
; $2000 bitmap 8000 bytes
; This just programs the TED for 320x200 hires bitmap mode and holds the display.
* = $1020
start:
sei
lda #$08
sta $ff12 ; bitmap base = $2000
lda #$18
sta $ff14 ; video matrix base = $1800 (hue matrix at $1C00)
lda #$00
sta $ff15 ; background colour (per-cell in hires; black)
lda #$00
sta $ff19 ; border / frame colour = black
lda #$08
sta $ff07 ; MCM off (hires), 40 columns
lda #$3b
sta $ff06 ; bitmap mode on, display on, 25 rows (set last)
loop:
jmp loop