Skip to main content

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.

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.

The annotation cycle

1

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.
9900dis --rom console.bin --listing console.asm
2

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.
      	DATA    >83e0            ; pc:>0000 w:>83e0
      	DATA    >0030            ; pc:>0002 w:>0030
3

Add annotations

Edit the listing in any text editor. You can:
  • Add a label before the tab on any instruction line
  • Insert SYMBOL EQU >XXXX lines for memory-mapped addresses
  • Append f:data to the comment field to force a word to be treated as DATA
  • Add a human-readable comment after a second ; on any line
4

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.
9900dis --rom console.bin --listing console.asm
5

Repeat

Continue studying, annotating, and re-running until the listing is as fully documented as you need. Each iteration substitutes more symbols and reveals more structure, particularly as jump targets and BLWP destinations gain meaningful names.

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:
ElementHow it appears in the listing
LabelsFirst token before the tab on a line, e.g. RESET
EquatesStandalone lines matching SYMBOL EQU >XXXX
Format hintsf:data in the comment field, e.g. ; pc:>0000 w:>f0a0 f:data
Inline commentsText after the second ; on any line

Understanding the comment field

Every instruction line that 9900dis generates ends with a structured comment:
LABEL 	MNEMONIC  operand(s)        ; pc:>XXXX w:>XXXX [f:hint]  [; user comment]
The fields between the first ; 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 address
  • f:hint — an optional format hint; currently only f:data is supported
Anything after the second ; is treated as a user-supplied inline comment and is captured verbatim on every subsequent run.

Tips for efficient annotation

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.
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.
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 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.
The listing file is overwritten on every run. However, all annotations you have embedded in it — labels, equates, format hints, and inline comments — are parsed before the file is overwritten and are re-emitted in the new output. Do not add content outside of these annotation conventions (e.g. free-form prose blocks), as such content will be lost.

Build docs developers (and LLMs) love