Inventory of disasm_tools/ across the four sibling projects
Living document. Captures the state of the four disasm_tools/ packages at
the time of fantasm’s initial consolidation, and notes the strategy for
each module.
Project |
path |
|---|---|
acorn-6502-tube-client |
|
acorn-adfs |
|
acorn-econet-bridge |
|
acorn-nfs |
|
All four packages share a near-identical surface, but acorn-nfs has
absorbed the most additions over time and is the working baseline for most
modules. A handful of modules exist in only one fork.
Per-module status
Line counts and diff-line counts (versus NFS) collected on 2026-05-01.
Module |
NFS |
ADFS |
EBR |
TUBE |
Status |
Port |
|---|---|---|---|---|---|---|
|
0 |
1 |
1 |
1 |
Trivial |
✅ done |
|
152 |
97 |
98 |
99 |
NFS adds CMOS (65C02) overrides + dispatcher |
✅ done — ROM_BASE/ROM_SIZE moved out, set up for |
|
28 |
32 |
32 |
36 |
Project-specific PREFIX; NFS supports two |
✅ done — refactored against ProjectContext; |
|
105 |
100 |
100 |
100 |
NFS has 5 extra lines (relocation indexing) |
✅ done — typed extract_section() returning AsmSection |
|
828 |
828 |
828 |
828 |
Byte-identical |
⚠️ partial — pure-logic + load_subroutines + find_undeclared_subs ported; |
|
621 |
621 |
621 |
621 |
Byte-identical |
⚠️ partial — build_confidence_map + parse_annotations + translate_* ported; VERSION_CHAIN and chained_map deferred (NFS-specific data → fantasm.toml) |
|
415 |
415 |
415 |
415 |
NFS = ADFS = TUBE; EBR has 4 diff lines |
⚠️ partial — build_call_graph + resolve_sub_node ported with KEY FIX (uses audit.build_memory_regions(meta), not hardcoded NFS regions); format_* deferred |
|
677 |
677 |
677 |
677 |
Byte-identical |
⚠️ partial — every check function + run_checks ported; format_findings + comment_check() deferred |
|
470 |
319 |
319 |
319 |
NFS has ~150 extra lines of capability |
✅ done — Instruction/RomHeader dataclasses, parse_rom_header, disassemble_linear, compare_roms; rom_base parameterised, “NFS” hardcode removed |
|
459 |
459 |
459 |
459 |
Byte-identical |
⚠️ partial — compute_call_depths ported; generate_context (file IO) deferred |
|
183 |
183 |
183 |
183 |
Byte-identical |
⚠️ partial — parse_subroutine_declarations + find_main_block + new compute_insert_point ported; print/IO wrapper deferred |
|
495 |
495 |
495 |
495 |
Byte-identical |
⚠️ partial — classify_labels + sort_labels + collect_auto_labels (was |
|
555 |
522 |
522 |
492 |
NFS most capable; check others for unique rules |
⚠️ partial — extract_annotations (multi-line aware, with names) + valid_addresses_from_data + address_ranges_from_data + markdown helpers ported; ROM size now a parameter; lint_*() and lint() top-level deferred |
|
284 |
284 |
284 |
284 |
Byte-identical |
⚠️ partial — parse_label_declarations + find_rename_section + find_insert_position + new apply_renames_to_lines pure transformer; rename_labels() and show_sub_labels() file-IO deferred |
|
102 |
102 |
102 |
112 |
Trivial diffs (project-name strings); TUBE has 24 extra |
✅ done — verify_round_trip() returns VerifyResult dataclass; BeebasmNotFoundError raised |
|
417 |
401 |
445 |
358 |
All diverge — Click sub-commands |
⏳ in progress — |
|
– |
235 |
235 |
– |
ADFS+EBR identical; not in NFS or TUBE |
⚠️ partial — analyze_labels + load_and_analyze_labels ported; format_promote_report deferred to CLI |
|
– |
– |
254 |
– |
EBR only |
⚠️ partial — sweep_opcodes / find_matching_spans / parse_rom_spec / load_rom ported; report_matches + argparse main deferred |
|
299 |
– |
– |
– |
NFS only |
✅ done — primary + supplementary opcode mapping; rom_base parameterised |
|
112 |
– |
– |
– |
NFS only |
✅ done — opcode_fingerprint, fingerprint_blocks, find_duplicate_blocks |
Porting strategy that emerged
For each ported module the same shape recurs: lift the pure-logic surface
into fantasm.api.<topic> with type hints, frozen dataclasses for results,
typed exceptions instead of sys.exit/stderr-print, and warnings.warn
for soft diagnostics. Tests are characterisation tests against
hand-crafted in-memory data — small enough to read, complete enough to
pin behaviour for refactors.
The format_* and file-reading top-level entry functions (the CLI side)
are intentionally deferred for each module. They will land alongside the
fantasm <topic> Click sub-commands in a follow-up pass, where the
project-specific strings and rom_prefix(version_dirpath) calls can be
threaded through a ProjectContext once.
Legend: NFS = acorn-nfs, ADFS = acorn-adfs, EBR = acorn-econet-bridge,
TUBE = acorn-6502-tube-client. Em-dash (–) means the module is absent
in that fork.
Cross-cutting refactors
A handful of concerns appear in multiple modules and need to be lifted out during consolidation:
Project layout assumptions.
paths.pyknows the directory naming convention ({PREFIX}-{version_id}/) and the ROM-name prefix. fantasm expresses these infantasm.tomlinstead of hardcoded module constants.ROM bank constants.
ROM_BASEandROM_SIZElive inmos6502.pytoday, but they are properties of how a ROM was banked, not of the 6502. They move intofantasm.toml(and a futurefantasm.api.rommodule) so the same disassembly tools can target the BBC’s 16K sideways ROMs, the 8K NFS sideways “half-bank”, and other layouts.SystemExitfrom library code. Several siblings callsys.exit(1)on error inside library functions (e.g.paths.resolve_version_dirpath). The fantasm port raises a typed exception (e.g.VersionNotFound) and the CLI layer translates it to a clean exit code with a useful message.Console-script names. Sibling code references the project-specific
acorn-{x}-disasm-toolconsole-script name in error messages. fantasm usesfantasm.
Porting order
Foundational first, so later modules can build on a stable base:
mos6502(no deps; opcode tables are the bedrock)paths(refactored againstProjectContext+fantasm.toml)labels(used by many)comment_checkcompareaudit,lint,verifycfg,context,insert_pointrename_labels,asm_extract,backfillSpecialised:
blockmatch,fingerprint,promote,find_shared
CLI integration happens alongside each module: a fantasm <topic> group is
added with the relevant sub-commands, and the public surface is re-exported
from fantasm.api.__init__ so callers can either from fantasm.api import … or reach into fantasm.api.<topic>.
Tests are characterisation tests: small hand-crafted inputs whose expected
output is captured from the working code, plus round-trip tests against
beebasm for any module that emits assembly source.