41 lines
1.5 KiB
Python
41 lines
1.5 KiB
Python
"""Build an Amiga Copper list that displays a static 320x200 low-res screen.
|
|
|
|
The Copper runs every frame and re-loads the bitplane pointers + registers, so
|
|
the picture stays stable. Each instruction is a MOVE (register offset, value);
|
|
the list ends with WAIT $FFFF,$FFFE.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import struct
|
|
|
|
DIWSTRT, DIWSTOP, DDFSTRT, DDFSTOP = 0x08E, 0x090, 0x092, 0x094
|
|
BPLCON0, BPLCON1, BPLCON2 = 0x100, 0x102, 0x104
|
|
BPL1MOD, BPL2MOD = 0x108, 0x10A
|
|
BPLPT = 0x0E0 # BPL1PTH; +4 per plane
|
|
COLOR0 = 0x180
|
|
|
|
|
|
def list_len(nplanes, ncolors) -> int:
|
|
pairs = 9 + nplanes * 2 + ncolors # DIW*2, DDF*2, BPLCON0/1/2, BPLMOD*2 = 9
|
|
return pairs * 4 + 4 # + end WAIT
|
|
|
|
|
|
def build(nplanes, ham, plane_addrs, colors) -> bytes:
|
|
bplcon0 = (nplanes << 12) | (0x0800 if ham else 0) | 0x0200
|
|
moves = [
|
|
(DIWSTRT, 0x2C81), (DIWSTOP, 0xF4C1),
|
|
(DDFSTRT, 0x0038), (DDFSTOP, 0x00D0),
|
|
(BPLCON0, bplcon0), (BPLCON1, 0x0000), (BPLCON2, 0x0024),
|
|
(BPL1MOD, 0x0000), (BPL2MOD, 0x0000),
|
|
]
|
|
for p, addr in enumerate(plane_addrs):
|
|
moves.append((BPLPT + p * 4, (addr >> 16) & 0xFFFF))
|
|
moves.append((BPLPT + p * 4 + 2, addr & 0xFFFF))
|
|
for i, c in enumerate(colors):
|
|
moves.append((COLOR0 + i * 2, c & 0x0FFF))
|
|
|
|
out = bytearray()
|
|
for reg, val in moves:
|
|
out += struct.pack(">HH", reg & 0x1FE, val & 0xFFFF)
|
|
out += struct.pack(">HH", 0xFFFF, 0xFFFE) # end of copper list
|
|
return bytes(out)
|