Host Tools¶
ROM building and host-side control of the Pico live in the separate
Romulan repository, checked out as a sibling
of this repo (for example ~/Downloads/romulan). Romulan assembles ROM images from
annotated hex and speaks the v1 Hardware API over the framed serial link.
Set it up once:
cd ~/Downloads/romulan
uv sync
Workflow¶
Build and upload a ROM, then capture the bus:
uv run romulan program.txt --build --upload # assemble + framed Hardware API upload
uv run romulan hardware upload bin/rom.bin --port /dev/ttyACM0
uv run romulan hardware capture --max-cycles 500 --port /dev/ttyACM0
Note
rom_image[] is lost on Pico power-cycle, re-upload after each reboot.
Python client¶
from romulan.hardware_api import HardwareAPI
with HardwareAPI("/dev/ttyACM0") as api:
print(api.status())
api.reset(assert_reset=True) # hold CPU in reset
api.upload_rom(open("bin/rom.bin", "rb").read()) # chunked, base64-encoded upload
# commit leaves RESET asserted — capture arms then releases reset
capture = api.read_until_stp(max_cycles=500) # disables monitor; polls at ~1 kHz PHI2
print(capture.reason, len(capture.cycles))
read_until_stp() captures one JSON event per PHI2 rising edge until the CPU fetches STP
(0xDB) or max_cycles is reached. The firmware default clock is 1 kHz.
Demo program¶
Romulan’s sample program ends in STP so automated capture stops deterministically:
$8000: CLC
LDA #$05
STA $4000 ; visible via read / monitor
ADC #$0F ; A = 20
STA $4000
STP ; stops read_until_stp capture (opcode $DB)
$FFFC: $8000 ; reset vector