9900dis is designed around an iterative loop: the listing file it produces is also valid input for the next run. Instead of requiring all your knowledge upfront, you annotate the output incrementally — marking entry points, naming registers, flagging data words — and re-run the tool to fold those annotations back into a cleaner listing. Each pass reveals more structure until the ROM is fully documented.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/caljer1/9900dis/llms.txt
Use this file to discover all available pages before exploring further.
The annotation cycle
Initial pass
Run 9900dis with a listing file path that does not yet exist. Every word in the ROM is decoded as a raw instruction (or falls back to
DATA) and emitted with hex addresses. No symbols are substituted at this stage.Study the output
Open the generated listing. The
; pc:>XXXX comment on every line tells you the exact address of that instruction in the CPU’s address space. For TMS9900 ROMs, the first few words are typically a workspace-pointer / program-counter pair — the reset vector — followed by additional interrupt vectors.Add annotations
Edit the listing in any text editor. You can:
- Add a label before the tab on any instruction line
- Insert
SYMBOL EQU >XXXXlines for memory-mapped addresses - Append
f:datato the comment field to force a word to be treated asDATA - Add a human-readable comment after a second
;on any line
Re-run
Run the same command again, pointing at the same listing file. 9900dis reads all your annotations from the existing file, then overwrites it with a freshly generated listing that substitutes label names and equate symbols wherever the corresponding addresses appear as operands.
What gets preserved across runs
Every annotation you add to the listing is parsed by 9900dis and re-emitted in the regenerated output. The following elements survive each re-run:| Element | How it appears in the listing |
|---|---|
| Labels | First token before the tab on a line, e.g. RESET |
| Equates | Standalone lines matching SYMBOL EQU >XXXX |
| Format hints | f:data in the comment field, e.g. ; pc:>0000 w:>f0a0 f:data |
| Inline comments | Text after the second ; on any line |
Understanding the comment field
Every instruction line that 9900dis generates ends with a structured comment:; and the optional second ; are space-delimited tokens:
pc:>XXXX— the program counter value at this instruction (the address in CPU address space)w:>XXXX— the raw 16-bit word read from the ROM at this addressf:hint— an optional format hint; currently onlyf:datais supported
; is treated as a user-supplied inline comment and is captured verbatim on every subsequent run.
Tips for efficient annotation
Start with the reset vector and interrupt table
Start with the reset vector and interrupt table
For TMS9900 ROMs, address
>0000 holds the workspace pointer and >0002 holds the program counter for the reset handler. Mark both with f:data, then label the reset PC address. The interrupt vector table (addresses >0004 through >001F) follows the same two-word pattern. Labelling these first gives 9900dis a set of entry points from which to substitute symbols throughout the rest of the listing.Use equates for all memory-mapped I/O addresses
Use equates for all memory-mapped I/O addresses
Hardware registers appear as raw hex constants in operands (
@>8800, @>E000, etc.) until you define equates for them. Add lines such as VDPIO EQU >E000 near the top of the listing. On the next run, every occurrence of @>E000 in an operand is replaced with @VDPIO, making the code substantially more readable.Mark known data tables with f:data
Mark known data tables with f:data
When the disassembler encounters a word that does not correspond to a valid instruction, it falls back to
DATA. However, a valid instruction encoding can still be data — lookup tables, vector tables, and string buffers are common examples. Adding f:data to the comment field of the first word of such a region forces it to DATA and frees the following words to be decoded independently, preventing incorrect multi-word instruction decoding from consuming table entries.The listing reassembles with xas99 — use it to verify
The listing reassembles with xas99 — use it to verify
The output format is designed to assemble cleanly with
xas99.py from the xdt99 tool suite. After an annotation pass, reassembling the listing and comparing the resulting binary to the original ROM is an effective way to catch any labelling mistakes or misidentified data regions.