Command-line reference
Install
Note
The uv and uvx commands shown below come from
Astral’s uv. If you don’t have
it yet, see the uv installation guide —
one-line installers are available for macOS, Linux, and Windows.
For one-shot CLI use, no install needed — uvx fetches Dasmos
into a transient environment and runs it:
uvx dasmos disassemble myrom.bin --load-addr '&8000'
To add dasmos to a project (required for driver scripts that
import dasmos):
uv add dasmos
Or with pip:
pip install dasmos
Either install form puts a dasmos script on your PATH.
Overview
Dasmos installs a single dasmos script, organised as a Click
command group. Three command families:
Discovery —
list-cpus,list-renderers,list-environmentsand the matchingdescribe-…commands. Read-only; useful for finding what’s installed and for--help-style introspection.Disassemble —
dasmos disassembleis the one-shot that runs the whole pipeline against a binary without a driver script.Init —
dasmos initscaffolds a runnable driver script pre-filled with the same configuration you’d pass todisassemble.
Run dasmos --help to see them all, or dasmos COMMAND --help for
per-command flags.
Address syntax
Every option that takes an address — --load-addr, --entry, and
the equivalents on init — accepts four notations interchangeably:
Notation |
Convention |
|---|---|
|
C / Python hex. |
|
beebasm / BBC BASIC hex. |
|
ca65 / Apple-II hex. |
|
bare decimal. |
Hex parsing is case-insensitive: &FFEE and &ffee both work.
Anything else — a stray prefix, embedded whitespace, a typo — fails at
parse with Click’s standard usage error rather than running with a
silently-wrong address.
dasmos disassemble — one-shot
dasmos disassemble ROM --load-addr ADDR [options]
Loads ROM at ADDR, seeds the trace from each --entry (or
from the load address by default), runs the trace + classification +
reference-analysis pipeline, and renders the result via the chosen
renderer plug-in.
The minimum is a binary plus its load address:
dasmos disassemble nfs365.rom --load-addr '&8000'
Output goes to stdout by default, or to a file with --out.
Options
-a,--load-addrADDR (required)Address where the binary is loaded. Required because every other address in the run is interpreted relative to this one.
-c,--cpuNAME (default:6502)CPU plug-in name. Run
dasmos list-cpusto see what’s installed.-r,--rendererNAME (default:beebasm)Renderer plug-in.
beebasmproduces re-assemblable assembly source;jsonproduces a structured representation suitable for downstream HTML generators or diff-based comparison tools. Rundasmos list-renderersto see the full list.-e,--envNAMEActivate an environment plug-in — a bundle of register names, subroutine hooks, OS-call analysers, and hardware-port labels for a target system. Repeatable, and comma-separated values are accepted per flag, so
--env acorn_mos --env acorn_model_b_hardwareand--env acorn_mos,acorn_model_b_hardwareare equivalent. Rundasmos list-environmentsfor the catalogue.--entryADDREntry-point address. Repeatable. Defaults to the load address. Use when the binary’s true entry isn’t its first byte — for example, a ROM image whose header bytes are data and whose code starts at
load_addr + 9.-o,--outPATHWrite the rendered output to this file instead of stdout.
--md5HASHPin the ROM’s MD5 hash. The disassembly fails (without writing output) if the actual hash differs. Use to catch the wrong-binary-for-this-driver mistake early.
Worked example
Disassemble a BBC Model B Acorn NFS ROM with the MOS environment active, seeding the trace from the standard service-ROM entry vectors:
dasmos disassemble nfs365.rom \
--load-addr '&8000' \
--env acorn_mos \
--env acorn_model_b_hardware \
--entry '&8000' \
--entry '&8003' \
--out nfs365.asm
The resulting nfs365.asm will resolve every jsr &FFxx to its
MOS entry-point name (osbyte, osword, osfile, …) and
every System/User VIA address to its hardware-port label.
dasmos init — scaffold a driver
dasmos init DRIVER --rom ROM --load-addr ADDR [options]
Writes a starter Python driver to DRIVER configured against
ROM. The generated file is fully functional — running
python DRIVER produces the same output as
dasmos disassemble with the same flags. From there you edit the
driver to add labels, comments, and classifications as your analysis
evolves.
The flag set mirrors disassemble plus a couple of init-specific
extras:
--romPATH (required)ROM the generated driver will disassemble. Embedded into the file as a
Path(...)literal.-a,--load-addrADDR (required)Embedded as
LOAD_ADDR.-c,--cpu,-r,--renderer,-e,--env,--entry,--md5Carry the same meanings as on
disassembleand are baked into the generatedDisassembler.create(...)/d.entry(...)/d.load(..., md5sum=...)calls.--forceOverwrite an existing driver file. Without it,
initrefuses to clobber existing work and exits with an error.
Worked example
Bootstrap a driver for the same ROM the disassemble example used:
dasmos init disasm_nfs365.py \
--rom nfs365.rom \
--load-addr '&8000' \
--env acorn_mos \
--env acorn_model_b_hardware \
--entry '&8000' \
--entry '&8003' \
--md5 $(md5 -q nfs365.rom)
Then python disasm_nfs365.py reproduces the listing, and the file
is the editable canvas where you add d.label(...),
d.subroutine(...), d.comment(...), and so on. See the
driver-script API guide for the full vocabulary.
Discovery commands
Three pairs of read-only commands enumerate and describe the plug-ins the current installation knows about:
Command |
Lists / describes |
|---|---|
|
Registered CPU plug-ins. |
|
Full description of one CPU plug-in. |
|
Registered renderer plug-ins. |
|
Full description of one renderer plug-in. |
|
Registered environment plug-ins. |
|
Full description of one environment plug-in. |
These commands are themselves asyoulikeit-decorated, so each
inherits --as / --report / --header / --detailed for free. Pipe
into jq:
dasmos list-cpus --as json | jq '.reports.cpus.rows[].name'
or just run with no flags for a human-readable table.