The TMS9995 is an enhanced version of the TMS9900. When you passDocumentation 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.
--cpu 9995, 9900dis enables decoding of four additional instructions not present in the TMS9900: MPYS and DIVS for signed multiplication and division, and LST and LWP for direct loading of the status and workspace pointer registers from a workspace register.
Enabling TMS9995 mode
Pass--cpu 9995 on the command line alongside your usual --rom and --listing arguments:
is9995=True in the ROM class constructor (rom.py:124). The two TMS9995-specific handlers, handle_9995_453() and handle_9995_4512(), check this flag at the top of their function bodies and immediately return False when it is not set — meaning no TMS9995 opcodes are ever recognised in the default --cpu 9900 mode.
Additional instructions
MPYS — Multiply signed
MPYS — Multiply signed
MPYS performs a signed 16×16-bit multiply. The source operand is multiplied by the signed value in r0, and the 32-bit signed result is stored in r0:r1.| Field | Value |
|---|---|
| Opcode bits 15–6 | 0b0000000111 (decimal 7) |
| Format handler | handle_9995_453() in rom.py:344 |
| Operand | Single source — same addressing modes as format 3.5.4 |
"{:8}{}" template used by format 3.5.4 single-operand instructions.DIVS — Divide signed
DIVS — Divide signed
DIVS performs a signed 32÷16-bit division. The 32-bit signed dividend is taken from r0:r1; the source operand is the 16-bit signed divisor. The quotient is placed in r0 and the remainder in r1.| Field | Value |
|---|---|
| Opcode bits 15–6 | 0b0000000110 (decimal 6) |
| Format handler | handle_9995_453() in rom.py:344 |
| Operand | Single source — same addressing modes as format 3.5.4 |
MPYS and DIVS are decoded by the same handler (handle_9995_453) via the mne_9995_453 dictionary, which maps opcode 7 to "MPYS" and opcode 6 to "DIVS".LST — Load status register
LST — Load status register
LST loads the status register directly from a workspace register. This is more efficient than the TMS9900 LIMI/STST pair for context-switching code.| Field | Value |
|---|---|
| Opcode bits 15–4 | 0b000000001000 (decimal 8) |
| Format handler | handle_9995_4512() in rom.py:357 |
| Operand | Workspace register rN (bits 3–0) |
deconstruct9995_4512() method extracts a 12-bit opcode from bits 15–4 (word & 0xFFF0) >> 4) and a 4-bit register index from bits 3–0.LWP — Load workspace pointer
LWP — Load workspace pointer
LWP loads the workspace pointer register directly from a workspace register, providing a fast register-to-WP transfer without needing LWPI followed by a memory indirection.| Field | Value |
|---|---|
| Opcode bits 15–4 | 0b000000001001 (decimal 9) |
| Format handler | handle_9995_4512() in rom.py:357 |
| Operand | Workspace register rN (bits 3–0) |
LST and LWP are decoded by the same handler (handle_9995_4512) via the mne_9995_4512 dictionary, which maps opcode 8 to "LST" and opcode 9 to "LWP".Instruction priority
Thedisassemble() method in rom.py:379 iterates a fixed handler list for every instruction word, stopping at the first handler that returns a non-False value:
handleData fallback. Because handle_9995_453() and handle_9995_4512() return False immediately when is9995 is False, there is no performance penalty in default mode — the fallback handleData is reached in the same number of iterations as it would be without the TMS9995 handlers present.
Before and after: --cpu 9900 vs --cpu 9995
The following example shows how the same binary word >01C3 is decoded differently depending on the --cpu flag.
The word >01C3 breaks down as:
- Bits 15–6:
0b0000000111= 7 →MPYSopcode inmne_9995_453 - Bits 5–4 (
ts):0b00→ mode 0 (register direct) - Bits 3–0 (
s):0b0011= 3 →r3
False for this opcode (none of the standard format dictionaries contain key 7 with the right bit-field width), so handleData is reached and the word is emitted as a raw DATA pseudo-op. In TMS9995 mode, handle_9995_453() matches opcode 7 in mne_9995_453 and emits MPYS r3 instead.
The TMS9995 differs from the TMS9900 in several other respects that 9900dis does not model: it has 256 bytes of on-chip RAM mapped at
>F000–>F0FF and >FFFA–>FFFF, an on-chip 16-bit timer, a different interrupt structure, and a modified memory map for I/O. 9900dis only models the additional instruction encodings introduced by the TMS9995. If you are disassembling TMS9995 ROMs you may need to add appropriate EQU definitions in your hints file to account for the differing memory-mapped I/O addresses.