First public commit.
This commit is contained in:
parent
2a48f52979
commit
4bac9d83ed
288 changed files with 18417 additions and 1076 deletions
49
lenser/coleco/cartridge.py
Normal file
49
lenser/coleco/cartridge.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"""Build a ColecoVision/Adam cartridge ROM (.col) holding the Z80 viewer + image.
|
||||
|
||||
Cartridge maps at $8000. Header: magic $55 $AA (skip the Coleco title screen and
|
||||
run immediately), eight pointer words, then a table of JP vectors -- the BIOS
|
||||
jumps to the one at $800A (the game entry). We point that at our viewer; the RST
|
||||
and interrupt vectors go to a stub (we run with interrupts disabled).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import struct
|
||||
|
||||
from . import viewer
|
||||
|
||||
CART_BASE = 0x8000
|
||||
CART_SIZE = 0x2000 # 8 KB (viewer + 6912-byte image fit comfortably)
|
||||
VECTORS = 8 # entry + 7 RST/INT stubs
|
||||
CODE_BASE = CART_BASE + 10 + VECTORS * 3 # after magic(2)+ptrs(8)+vectors
|
||||
|
||||
|
||||
def build_rom(data: bytes, display: str = "forever", seconds: int = 0) -> bytes:
|
||||
if len(data) != viewer.PATTERN_BYTES + viewer.NCELLS:
|
||||
raise ValueError(f"unexpected image length {len(data)}")
|
||||
|
||||
vk = dict(display=display, seconds=seconds)
|
||||
code = viewer.build(CODE_BASE, 0, **vk) # pass 1: measure code length
|
||||
data_addr = CODE_BASE + len(code) + 1 # +1 for the stub RET
|
||||
code = viewer.build(CODE_BASE, data_addr, **vk) # pass 2: real data address
|
||||
stub_addr = CODE_BASE + len(code)
|
||||
data_addr = stub_addr + 1
|
||||
|
||||
if data_addr - CART_BASE + len(data) > CART_SIZE:
|
||||
raise ValueError("viewer + image exceed the 8KB cartridge")
|
||||
|
||||
header = bytearray([0x55, 0xAA]) + bytes(8) # magic + 8 pointer bytes
|
||||
vecs = bytearray()
|
||||
targets = [CODE_BASE] + [stub_addr] * (VECTORS - 1)
|
||||
for t in targets:
|
||||
vecs += bytes([0xC3]) + struct.pack("<H", t) # JP t
|
||||
|
||||
rom = bytearray(header + vecs + code + bytes([0xC9])) # stub = RET
|
||||
rom += bytes(data)
|
||||
return bytes(rom) + bytes(CART_SIZE - len(rom))
|
||||
|
||||
|
||||
def write_col(rom: bytes, path: str) -> str:
|
||||
with open(path, "wb") as f:
|
||||
f.write(rom)
|
||||
return path
|
||||
Loading…
Add table
Add a link
Reference in a new issue