rg-dis
"dis gunna b gud!"
rg-dis is a 680x0 series disassembler for Atari binaries.
This is part of the Reservoir Gods cross-platform toolchain, and is a command-line tool that runs on Linux, macOS, and Windows.
When I first started learning how to program, the disassembler was my main teacher. I spent hours in mon st, stepping through programs, watching registers change, understanding memory access, getting familiar with system calls and the whole Atari memory map.
Easy Rider allowed me to convert that stream of hex bytes into readable, understandable assembly language. I pored over listings.
For anyone involved in the hacking scene - disassembling stuff is a large part of your life.
Once you know how to take things apart, you begin to understand how to put them together again. How to build things. How to build new things.
It all started with a disassembly. Wouldn't it be nice to have a new Atari disassembler, that would run on modern machines, be a simple single binary with no dependencies and have a raft of cool new features — that would be grand, wouldn't it?
Welcome to the wide world of rg-dis. Pull up a chair. Put the kettle on. Break out the biscuits. And get disassembling.
This is a command-line tool. No loading and playing with GUIs, emulators, or GEM. You simply launch the tool with input and output arguments. Being part of the Reservoir Gods cross-platform toolchain, this works natively on Linux, macOS, and Windows. You can disassemble your Atari programs at home, on a train OR ANYWHERE.
It also isn't limited to just PRG and TOS files. You can use this to peel apart object files like DRI and GST, ar archives and ELF executables.
You have a raw binary blob? No problem. rg-dis handles that too.
If your files exist in a zip file or other archive, rg-dis can automatically pull them out of there and work on them.
It also supports raw disk access, so it can disassemble boot sectors or arbitrary tracks/sectors of a floppy image.
It handles disassembly of the full range of 680x0 CPUs from the 68000–68060, and disassembles FPU instructions too.
It not only shows you the assembly code; rg-dis has deep knowledge of the full range of Atari TOS system calls - AES, BIOS, GEMDOS, VDI, XBIOS. It can annotate the system call name, all the input arguments and output arguments.
The full range of Atari hardware addresses is also annotated, including low memory vectors and system variables. It is immediately clear what any hardware access is doing.
You can also pull out all readable strings from an executable.
But one of the most powerful features is the smart labelling. As it understands the instruction set, hardware addresses and system calls, it can give meaningful names to function labels and variables, which makes the whole output disassembly a lot more readable.
Contents
- Quick start
- Target CPU, FPU & machine
- Binary formats & disk containers
- Smart labelling & annotations
- Inspection, strings & diffing
- Listing layout & options
- Command-line options reference
- JSON output
Part 1 — Command-line tool interface
Install
rg-dis is distributed as a single standalone executable with zero runtime dependencies. Prebuilt zip packages for macOS, Linux, and Windows are available from rg.atari.org.
Simply download the zip for your platform, extract the executable and place it somewhere on your PATH.
Quick start
rg-dis game.tos -o game.s # disassemble GEMDOS executable → .s
rg-dis game.tos --inspect # short summary (header, sections, counts)
rg-dis game.tos --cpu 68030 --fpu 68882 # target specific CPU and FPU models
rg-dis AUTO/GAME.PRG --container game.msa # extract & disassemble from inside disk/archive
rg-dis cuddly.msa --bootsector # extract & disassemble floppy boot sector
rg-dis game.st --disk 10/0/1..10/1/9 # disassemble floppy track & sector range
rg-dis tos.img --org 0xFC0000 --sym tos.sym # ROM dump with DRI/GST symbol map
rg-dis module.o # disassemble object file (ELF / DRI / GST / a.out)
Target CPU, FPU, and machine
By default, rg-dis operates in auto-target mode (--cpu auto, --fpu auto, or --auto-target). It decodes using the 68030 + 68882 superset (ensuring all ST, TT, and Falcon instructions are decoded faithfully), then inspects the decoded instructions to calculate and emit the minimal required CPU model (e.g. .cpu 68000 for plain ST code, .cpu 68020 for 68020+ code) and FPU requirement (omitting .fpu when no FPU instructions are present, or emitting .fpu M68882 when FPU instructions are used).
To force specific directives or override auto-detection, pass an explicit CPU/FPU model or --no-auto-target.
Target CPUs (-m, --cpu <MODEL>)
| Model | Aliases | Target / Notes |
|---|---|---|
auto | — | Default — decodes with 68030 capabilities; emits minimal required CPU directive |
68000 | m68000, 68k, 000 | Motorola 68000 baseline (ST/STe) |
68010 | m68010, 010 | Motorola 68010 |
68020 | m68020, 020 | Motorola 68020 (32-bit addresses, bitfields) |
68030 | m68030, 030 | Motorola 68030 (TT030 / Falcon030 / MMU) |
68040 | m68040, 040 | Motorola 68040 (integrated FPU) |
68060 | m68060, 060 | Motorola 68060 (integrated FPU) |
coldfire | cf, cfv4e, cf5208, cf548x | ColdFire architecture (ISA_A / ISA_B / ISA_C) |
Target FPUs (--fpu <MODEL>)
| Model | Aliases | Target / Notes |
|---|---|---|
auto | — | Default — decodes with 68882 capabilities; emits .fpu only if FPU instructions are found |
68882 | — | Motorola 68882 coprocessor (TT / Falcon math) |
68881 | — | Motorola 68881 coprocessor |
coldfire | cf | ColdFire on-chip FPU (default on ColdFire targets) |
none | — | Disable FPU disassembly (unsupported ops emit dc.w) |
Note: On 68040 and 68060 targets, integrated FPU instructions are decoded automatically.
Target machine (--machine <M>)
| Machine | Focus / Context |
|---|---|
st | Atari ST baseline (YM2149, Shifter, MFP 68901) |
ste | Atari STe (blitter, DMA sound, extended palette) |
mste | Atari Mega STe (cache, clock switch, VME) |
tt | Atari TT030 (TT Shifter, fast RAM, SCC, TT SCU) |
falcon | Atari Falcon030 (VIDEL, crossbar, DSP 56001, IDE) |
Passing --machine <M> focuses hardware register comments when disassembling memory-mapped I/O routines with --annotate-hw.
Binary input formats
Binary formats are auto-detected by inspecting file headers:
| Format | FMT | Detected by |
|---|---|---|
GEMDOS .TOS/.PRG | tos | 0x601A magic + GEMDOS header shape |
| CPX Control Panel Extension | cpx | 512-byte header + 0x601A magic at offset 512 |
DRI relocatable .o | dri | 0x601A magic + fixed-size reloc bitmap tail |
| ELF32-BE object/executable | elf | \x7fELF magic |
| a.out OMAGIC (VBCC) | aout | 0x0107 at bytes 2–3 |
| Devpac GST object | gst | leading $FB directive |
ar static archive | ar | !<arch> magic |
| Floppy disk image | disk | MSA $0E $0F / Pasti RSY\0 magic, or a .st/.msa/.stx name the image loads as |
| Raw binary image | raw | fallback when no structured header matches |
Override auto-detection anytime with --input-format <FMT> (auto, tos, elf, dri, gst, aout, ar, cpx, disk, raw) — an override is a request, not a hint, so raw disassembles a floppy container's bytes and disk insists on the floppy pipeline.
GEMDOS executables (.TOS / .PRG)
TOS executables disassemble to re-assemblable source, preserving program header flags (.prgflags $HEX) and symbolic pointer table relocations in .data. Feed the listing back to rg-asm and you get the executable's code and data back:
rg-dis game.tos -o game.s
rg-asm --prg --no-opt-size game.s -o game-rebuilt.tos
cmp game.tos game-rebuilt.tos # .text + .data identical for the corpus below
Byte-identical re-assembly of those two sections is the bar, and it is enforced rather than assumed.
A regression ratchet re-assembles a corpus of real binaries (dis → rg-asm → rg-link) and
byte-compares their text and data against a committed baseline manifest — 684 binaries pass
today. Two things the comparison deliberately does not cover: a reassembled binary carries no copy
of the original DRI symbol table, so the header's symbol-table size word and the trailing table
differ from an input that had one, and symbol names are normalized away for the same reason.
It is a ratchet on purpose: a recorded class may not grow, and a binary outside the corpus can
reassemble to equivalent rather than identical bytes. cmp your own binary before assuming
byte-identity — that is what the comparison above is for.
Control Panel Extensions (.CPX)
Atari CPX modules are auto-detected (or forced with --input-format cpx). rg-dis parses the 512-byte CPXHEAD header (ID, title, icon text, version, and execution flags such as set_only, boot_init, and resident), displays CPX header fields in --inspect, and disassembles the embedded GEMDOS executable payload starting at offset 512 (0x200):
rg-dis modem.cpx --inspect # inspect CPX header fields and embedded sections
rg-dis modem.cpx -o modem.s # disassemble embedded CPX executable
Raw images & ROM dumps
For headerless binaries (TOS ROMs, raw data, memory dumps):
rg-dis tos.img --org 0xFC0000 # set base address for absolute references
rg-dis slice.bin --offset 0x100 --len 0x400 # disassemble a byte slice
rg-dis tos.img --org 0xFC0000 --sym tos.sym # inject DRI/GST symbol table sidecar
PC-relative code (music drivers, depackers) re-assembles identically at any base because PC displacements are recomputed from labels.
Linkable object files & archives (.o / .a)
rg-dis decodes relocatable object files and static library archives:
rg-dis module.o # DRI, GST, ELF, or a.out object
rg-dis libvc.a --inspect # list member summary
rg-dis libvc.a --archive-member printf.o # disassemble one member
rg-dis libvc.a # disassemble all members
Containers & disk images
rg-dis can inspect, extract, and disassemble directly from container packages and floppy disk images without unpacking them first:
| Container | Type | Description |
|---|---|---|
.ST | Disk image | Flat raw sector dump of a FAT12 floppy disk |
.MSA | Disk image | Magic Shadow Archiver compressed sector floppy image |
.STX | Disk image | Pasti floppy disk image with preserved sector headers |
.ZIP | Archive | Standard ZIP archive container |
.LZH | Archive | LHA / LZH compressed archive |
Floppy disk images & bootsectors (.ST / .MSA / .STX)
Floppy images are routed to the disk pipeline by default: a .MSA/.STX proves itself from
its magic, and a .ST from its name once the image loads. Passing one used to decode every
512-byte sector as 68000 code — 96.7 s and 114,074 lines of nonsense for a 720 KiB .MSA, against
0.04 s for the sector listing. Use --input-format raw when you really do want the bytes treated as
one headerless image:
rg-dis cuddly.msa # whole floppy image (auto-routed)
rg-dis cuddly.msa --bootsector # 512-byte boot sector (track 0/side 0/sector 1)
rg-dis disk.stx --bootsector # boot sector from Pasti STX image
rg-dis game.st --disk # entire floppy disk image
rg-dis game.st --disk 10 # track 10 only (all sides & sectors)
rg-dis game.st --disk 10/0/1..10/1/9 # explicit track / side / sector CHS range
rg-dis cuddly.msa --input-format raw # opt out: the container's bytes as one image
Autodetect only ever adds a route, so it never turns a working command into an error: when a
floppy image cannot be loaded (unusual geometry, corrupt header), rg-dis says so on stderr and
falls back to the route it would have taken before. --disk, --bootsector and --input-format disk are requests: they refuse loudly instead.
Containers (--container)
Pass --container <FILE> to reach directly inside archives or FAT12 disk images:
rg-dis BIN/GAME.TOS --container demo.zip # file inside a ZIP
rg-dis GAME.TOS --container demo.lzh --input-format raw # file inside an LZH
rg-dis AUTO/GAME.PRG --container game.st # file inside a FAT12 .ST disk
rg-dis --container demo.zip # list container contents
Automatic depacking (--unpack)
Many Atari ST executables and data files are packed with heritage crunchers. rg-dis integrates rg-pack to detect and transparently decompress packed binaries on the fly when --unpack is specified:
- Ice Packer (1.1, 2.0, 2.4, 3.0)
- Atomik Packer (3.5, 3.6)
- Automation / Pompey Packer / SpeedPacker
- Fire Packer
rg-dis packed_game.prg --unpack -o game.s # decompress and disassemble
rg-dis packed_game.prg --unpack --inspect # inspect decompressed payload
Smart labelling
Instead of having to deal with obtuse machine generated labels like _L0012A4, rg-dis can analyse control flow, OS calls, vector writes, and string tables to generate meaningful semantic labels automatically:
| Synthetic labels (`--no-smart-labels`) | Smart labelling (`--smart-labels`) |
|---|---|
|
|
Smart labelling is enabled by default. Pass --no-smart-labels to restore raw address labels (_L12A4).
Semantic annotations
rg-dis includes built-in annotations for system calls, hardware registers, and object relocations.
rg-dis game.tos --annotate # enable all annotations
rg-dis game.tos --annotate-traps # GEMDOS/BIOS/XBIOS calls & arguments
rg-dis game.tos --annotate-vdi # VDI parameter blocks & array pointers
rg-dis game.tos --annotate-aes # AES parameter blocks & array pointers
rg-dis game.tos --annotate-embedded-executables # embedded GEMDOS PRG headers & jump tables
rg-dis game.tos --annotate-hw # hardware registers and system vectors
rg-dis game.tos --annotate-vt52 # VT-52 terminal escape sequences in strings
rg-dis game.tos --annotate-cycles --cpu 68000 # per-instruction CPU cycle costs (68000)
rg-dis game.tos --annotate-offsets # per-line memory addresses
rg-dis trap.o --annotate-externs # object external references & relocs
rg-dis game.tos --no-annotate # disable all annotations (plain listing)
rg-dis game.tos --annotate-hw --machine falcon # narrow hardware comments to Falcon
Instruction cycle costs (--annotate-cycles)
Annotate each instruction line with its right-aligned CPU cycle execution cost matching the target CPU architecture (configured via --cpu <model>, which defaults to 68030 for full instruction decoding).
For 68000 (rg-dis game.tos --annotate-cycles --cpu 68000):
NOP ; 4 |
MOVE.W #5,-(A7) ; 12 | Setscreen (XBIOS 5)
TRAP #14 ; 34 | XBIOS Setscreen
RTS ; 16 |
For the default 68030 target (rg-dis game.tos --annotate-cycles):
NOP ; 2 |
MOVE.W #5,-(A7) ; 7 | Setscreen (XBIOS 5)
TRAP #14 ; 20 | XBIOS Setscreen
RTS ; 4 |
Per-line memory addresses (--annotate-offsets)
Comment each line with its address in memory — the byte's position in the loaded image, so a TOS
executable's first .text byte is $000000 (its 28-byte header is not loaded) and a raw image
starts at its --org. The field is one width for the whole listing, sized from the highest address
printed, so a column of addresses reads straight down the page:
BRA.S _start ; $000000 |
dc.b "RGCC" ; $000002 |
MOVEA.L 4(A7),A5 ; $000006 |
MOVE.L D1,-(A7) ; $00002C | newsiz - new size in bytes
With --annotate-cycles the cycle field follows the address, separated by a bar so the two numbers
never run together:
MOVE.L D1,-(A7) ; $00002C | 5 | newsiz - new size in bytes
MOVE.W #74,-(A7) ; $000032 | 7 | Mshrink - shrink a memory block
TRAP #1 ; $000036 | 20 | GEMDOS #74 (Mshrink)
Lines that occupy no memory — blank lines, bare labels, equates — carry no field. Off by default;
--annotate turns it on, or pass --annotate-offsets.
Decoded OS trap calls (--annotate-traps)
TRAP #1, #13, and #14 calls inspect the stack to comment functions and parameters:
MOVE.W #1,-(A7) ; rez - screen resolution: ST medium
MOVE.L #$00078000,-(A7) ; physbase - physical screen base
MOVE.L #$00078000,-(A7) ; logbase - logical screen base
MOVE.W #5,-(A7) ; Setscreen (XBIOS 5)
TRAP #14 ; XBIOS Setscreen
VDI & AES parameter blocks (--annotate-vdi, --annotate-aes)
TRAP #2 calls for VDI (D0 = $0073) and AES (D0 = $00C8) inspect the D1 parameter block pointer. The instruction loading D1 is commented with the parameter block name (VDIPB / AESPB), and data tables defining the parameter blocks are formatted cleanly as pointer arrays with individual array labels (contrl, global, intin, ptsin, intout, ptsout, addrin, addrout):
MOVE.L #vdi_pb,D1 ; VDI parameter block (VDIPB)
MOVEQ #115,D0
TRAP #2 ; VDI call
...
vdi_pb:
.dc.l vdi_contrl ; contrl pointer
.dc.l vdi_intin ; intin pointer
.dc.l vdi_ptsin ; ptsin pointer
.dc.l vdi_intout ; intout pointer
.dc.l vdi_ptsout ; ptsout pointer
Embedded GEMDOS executables (--annotate-embedded-executables)
Embedded TOS/GEMDOS executables (such as sound drivers, tracker replays, and overlays with $601A magic headers) located inside .text or .data sections have their 28-byte header structured symbolically with detailed field comments, and their entry point jump vectors (BRA.W init, BRA.W stop, etc.) disassembled into clean code routines:
; Embedded GEMDOS executable header
dc.w $601A ; magic (BRA.B +$1C)
dc.l $00000FB0 ; .text size (4016 bytes)
dc.l $00001D30 ; .data size (7472 bytes)
dc.l $00000000 ; .bss size (0 bytes)
dc.l $00000000 ; symbol table size (0 bytes)
dc.l $00000000 ; reserved / format
dc.l $00000000 ; flags (PRGFLAGS)
dc.w $0001 ; relocation flag (1 = relocs present)
BRA.W _L0DDC ; init driver
BRA.W _L0F56 ; stop driver
BRA.W _L1012 ; replay tick
Hardware registers & vectors (--annotate-hw)
Accesses to memory-mapped I/O ($FF8000+), interrupt vectors ($0000..$03FF), and low-memory OS variables ($0400..$05FF) are all annotated:
MOVE.W ($00044C).W,-(A7) ; sshiftmod - Copy of $FF8260 shift mode
BTST.B #0,($FFFFFC00).W ; ikbd_ctrl - IKBD ACIA status / control
VT-52 terminal escape sequences (--annotate-vt52)
Strings containing VT-52 terminal escape codes (cursor positioning, screen clearing, inverse video, text wrapping) are decoded into human-readable summaries on data directives and string arguments:
; Clear screen and home cursor
VT52_CLEAR_SCREEN:
.dc.b $1B,"E",0 ; VT52: [Clear & home]
; Direct cursor positioning (row 10, col 20)
VT52_CURSOR_POS:
.dc.b $1B,"Y",42,52,"SCORE:",0 ; VT52: [Pos (10,20)] "SCORE:"
; Inverse video styling
VT52_STATUS:
.dc.b $1B,"p","PAUSED",$1B,"q",0 ; VT52: [Inverse on] "PAUSED" [Inverse off]
When passing VT-52 string buffers to GEMDOS console calls like Cconws, the call site argument is annotated as well:
PEA VT52_CLEAR_SCREEN(PC) ; buf -> VT52: [Clear & home]
MOVE.W #9,-(A7) ; Cconws (GEMDOS 9)
TRAP #1 ; GEMDOS Cconws
A/B diffing with --normalise
When comparing two object files, disassembly diffs get cluttered by compiler trivia: 16-bit vs 32-bit reloc representations, short vs word branches, and local label numbering.
--normalise eliminates that noise by generating a layout-invariant listing: operands become symbolic symbol+addend references, branch targets become logical labels, and width suffixes are stripped:
diff <(rg-dis --normalise a.o) <(rg-dis --normalise b.o)
| Default listing | Normalised (`--normalise`) |
|---|---|
|
|
Change ADDQ.W #1,D0 to ADDQ.W #2,D0, and diff highlights only that single instruction.
Metadata inspection & strings
Inspecting binary metadata (--inspect)
Quickly inspect binary headers, section metrics, symbol tables, function cycle counts, and CPU requirements without generating a full disassembly:
rg-dis game.tos --inspect # summary overview (header, sections, counts)
rg-dis game.tos --inspect symbols # symbol table listing
rg-dis game.tos --inspect relocs # relocation table listing
rg-dis game.tos --inspect functions,cycles # function sizes & M68000 cycle totals
rg-dis game.tos --inspect cpu # minimum CPU model & FPU requirement analysis
rg-dis game.tos --inspect strings # extracted human-readable text strings
rg-dis game.st --inspect disk # floppy filesystem summary and directory tree
rg-dis game.tos --inspect all # complete report across all metadata views
Interactive runs format metadata into aligned boxed tables (or ASCII borders with --ascii):
header · load base 0x00010000
┌──────────────┬──────────────────────────────────┐
│ field │ value │
├──────────────┼──────────────────────────────────┤
│ magic │ 0x601A (TOS executable) │
│ text │ 294,020 bytes │
│ data │ 136,672 bytes │
│ bss │ 34,404 bytes │
│ symbols │ 94,094 bytes (6,721 entries) │
│ flags │ 0x00000000 │
│ fastload │ no (clear heap on load) │
│ ttramload │ no (load into ST-RAM only) │
│ ttrammem │ no (malloc from ST-RAM) │
│ protect │ private (MiNT memory protection) │
│ relocation │ present │
└──────────────┴──────────────────────────────────┘
sections
┌─────────┬────────────┬────────────┬─────────┐
│ section │ start │ end │ bytes │
├─────────┼────────────┼────────────┼─────────┤
│ .text │ 0x00010000 │ 0x00057C84 │ 294,020 │
│ .data │ 0x00057C84 │ 0x00079264 │ 136,672 │
│ .bss │ 0x00079264 │ 0x000818C8 │ 34,404 │
└─────────┴────────────┴────────────┴─────────┘
Symbols and relocations (--inspect symbols, --inspect relocs)
Inspects DRI, GST, or object symbol tables and GEMDOS relocation fixups:
rg-dis game.tos --inspect symbols
rg-dis game.tos --inspect relocs
symbols · 3,035 entries
┌────────────┬──────┬────────┬───────────────────────────┐
│ address │ seg │ scope │ name │
├────────────┼──────┼────────┼───────────────────────────┤
│ 0x00010006 │ TEXT │ global │ _start │
│ 0x00010046 │ TEXT │ global │ _main │
│ 0x0001D9F6 │ TEXT │ global │ @AsciiToS32 │
│ 0x00047886 │ TEXT │ global │ @AsmSprite_Create │
│ 0x00057D94 │ DATA │ global │ _STR_TITLE │
└────────────┴──────┴────────┴───────────────────────────┘
relocs · 9,517 entries
┌────────────┬──────────────────────────────────────────┐
│ field │ target │
├────────────┼──────────────────────────────────────────┤
│ 0x0001000C │ __BasPag │
│ 0x0001003E │ ___main │
│ 0x00010048 │ @main │
│ 0x0001014E │ @GemDos_Super │
│ 0x000102AE │ 0x00079268 │
└────────────┴──────────────────────────────────────────┘
Functions and cycles (--inspect functions, --inspect cycles)
Lists function boundaries, byte extents, and estimated M68000 CPU cycle execution costs:
rg-dis game.tos --inspect functions,cycles
functions · 2,313 Text extents
┌────────────┬──────────────────────────────────────────┬────────┐
│ address │ name │ bytes │
├────────────┼──────────────────────────────────────────┼────────┤
│ 0x00010006 │ _start │ 60 │
│ 0x00010046 │ _main │ 260 │
│ 0x0001014A │ @GodLib_Game_Main │ 318 │
│ 0x00010820 │ @Board_TileGenerate │ 582 │
└────────────┴──────────────────────────────────────────┴────────┘
cycles · 2,313 Text extents · M68000
┌────────────┬──────────────────────────────────────────┬────────┐
│ address │ name │ cycles │
├────────────┼──────────────────────────────────────────┼────────┤
│ 0x00010006 │ _start │ 232 │
│ 0x00010046 │ _main │ 1,130 │
│ 0x0001014A │ @GodLib_Game_Main │ 1,322 │
│ 0x00010820 │ @Board_TileGenerate │ 2,450 │
└────────────┴──────────────────────────────────────────┴────────┘
Floppy disks (--inspect disk)
Inspects floppy disk images (.ST, .MSA, .STX) and archives directly from filesystem metadata without disassembling instructions:
- Disk geometry & boot sector: Reports track, side, and sector counts, media descriptor density, and executable boot sector status.
- FAT12 filesystem status: Summarises cluster allocation (used, free, bad, and reserved space), FAT table consistency, and filesystem health.
- Directory tree: Provides a recursive file listing with file sizes, timestamps, DOS attributes, and executable format detection.
rg-dis game.st --inspect disk # filesystem summary and file listing
rg-dis cuddly.msa --inspect disk,strings # filesystem inspection plus string table
rg-dis game.st --inspect disk --json # structured JSON disk report
disk image · ST · 80 tracks (0-79), 2 sides, 9 sectors/track
┌────────────┬──────────────────┐
│ property │ value │
├────────────┼──────────────────┤
│ container │ ST │
│ image size │ 737,280 bytes │
│ sectors │ 1,440 │
│ format │ TOS/FAT12 volume │
└────────────┴──────────────────┘
boot sector · checksum 0x1234 · executable
┌──────────┬─────────────────────────────────────┐
│ property │ value │
├──────────┼─────────────────────────────────────┤
│ checksum │ 0x1234 │
│ bootable │ yes (executable) │
│ media │ 0xF9 — 720 KB double-sided 3.5-inch │
│ serial │ 0x67183049 │
└──────────┴─────────────────────────────────────┘
files · 4 file(s) · 1 folder(s) · 0 deleted
┌──────────────┬─────────┬────────────┬──────┬─────────────────────┐
│ path │ size │ date │ attr │ notes │
├──────────────┼─────────┼────────────┼──────┼─────────────────────┤
│ AUTO/ │ │ 1991-04-12 │ D │ │
│ LOADER.PRG │ 48,120 │ 1991-04-12 │ - │ executable (GEMDOS) │
│ MAIN.PRG │ 117,170 │ 1991-04-12 │ - │ executable (GEMDOS) │
│ GRAPHICS.DAT │ 84,200 │ 1991-04-12 │ - │ │
│ README.TXT │ 2,450 │ 1991-04-12 │ - │ │
└──────────────┴─────────┴────────────┴──────┴─────────────────────┘
When an image contains structural defects (such as conflicting FAT tables or invalid geometry), rg-dis reports the specific defects as diagnostics. Non-disk containers and archives fall back to reporting their member tables.
CPU requirements (--inspect cpu)
Detect the minimum CPU architecture (68000, 68010, 68020, 68030, 68040, 68060, ColdFire) and FPU coprocessor requirements across executable code. rg-dis performs reachability traversal from program entry points, following branch targets, subroutine calls, jump tables, and vector table installations, ensuring embedded string literals and non-code data tables in .text do not corrupt architecture detection.
The report details the minimum CPU and FPU model, total instruction counts, and the reachable analysis scope:
rg-dis game.tos --inspect cpu # inspect minimum CPU & FPU requirements
rg-dis game.tos --inspect cpu --json # JSON output with non-68000 instruction list
cpu requirements · minimum 68000 · fpu: none
┌────────────────────────┬─────────────────────────────────────────────────────┐
│ property │ value │
├────────────────────────┼─────────────────────────────────────────────────────┤
│ minimum cpu │ 68000 │
│ fpu required │ no │
│ total instructions │ 17,833 │
│ non-68000 instructions │ 0 │
│ analysis scope │ reachable code only (57108 of 294020 section bytes) │
└────────────────────────┴─────────────────────────────────────────────────────┘
Strings (--inspect strings)
rg-dis scans binaries to find and extract human-readable text strings across loadable sections, disk images, and archives. Unlike raw byte-dump tools like strings(1), rg-dis leverages full disassembler context—mapping each string to its exact guest runtime address, segment (TEXT, DATA, or named section), associated symbol labels, and code vs data region classification.
How it works & Plausibility Scoring
On 68k platforms, basic ASCII scanning produces heavy instruction noise (e.g. NOP sleds decode as "NqNq..." and 68k opwords often fall into printable ranges). To filter out noise while preserving real game text and identifiers, rg-dis evaluates each candidate run with a plausibility score (0–100):
- Positive score signals (+10 to +25) include C-style NUL-terminators, high alphanumeric/space ratios, and natural vowel/word patterns.
- Penalties (-10 to -25) apply for heavy punctuation, repeated single-byte runs, unaligned non-NUL strings, or runs located inside decoded instruction regions.
- Runs inside decoded instruction regions are excluded by default. That is where the opcode noise lives:
NOP/RTSopwords land in the printable range asNq/Nu. Pass--strings-include-codeto report them anyway. - The default threshold is
--strings-min-score 40, which drops low-quality runs that survive the region filter. Passing--strings-min-score 0disables heuristic filtering — including the region filter — to extract all raw printable runs like traditionalstrings(1).
rg-dis game.tos --inspect strings # data-region strings (score >= 40)
rg-dis game.tos --inspect strings --strings-min-score 90 # high-confidence prose & dialogue only
rg-dis game.tos --inspect strings --strings-include-code # add decoded-instruction regions
rg-dis game.tos --inspect strings --strings-min-score 0 # unfiltered strings (like strings(1))
rg-dis game.tos --inspect strings --strings-charset atari # decode 8-bit Atari ST character set
strings · score >= 40 · data regions only
┌─────────────────────────┬────────────┬──────┬─────┬─────┬───────────────────┐
│ string │ addr │ seg │ len │ ref │ label │
├─────────────────────────┼────────────┼──────┼─────┼─────┼───────────────────┤
│ Reservoir Gods Superfly │ 0x00057D94 │ DATA │ 32 │ Y │ _STR_TITLE │
│ Press SPACE to start │ 0x00057E62 │ DATA │ 24 │ Y │ │
│ HIGH SCORE: 99999 │ 0x00057F81 │ DATA │ 16 │ Y │ │
└─────────────────────────┴────────────┴──────┴─────┴─────┴───────────────────┘
String Extraction Options
| Option | Values | Default | Purpose |
|---|---|---|---|
--strings-min-len <N> | integer (hex/dec) | 4 | Minimum consecutive character run length to extract |
--strings-min-score <N> | 0..100 | 40 | Minimum plausibility score threshold (0 disables every filter) |
--strings-charset <SET> | ascii, printable, atari | ascii | Character set: standard ASCII, whitespace-extended (printable), or 8-bit Atari ST |
--strings-include-code | flag | off | Report runs inside decoded instruction regions as well (--strings-min-score 0 implies it) |
Each extracted string is reported in a structured table (or JSON envelope with --json) showing decoded text contents, guest runtime address, segment, length in bytes, relocation reference status, and symbol labels.
Listing layout & output options
Customise the assembly syntax, numeric formats, indentation, and listing layout:
rg-dis game.tos --spaces 2 # 2-space indentation
rg-dis game.tos --tabs 1 # tab indentation
rg-dis game.tos --no-spacing # dense output without subroutine spacing
rg-dis game.tos --no-data-pack # single data item per line
rg-dis game.tos --data-width long # force 32-bit dc.l data directives
rg-dis game.tos --imm-format hex # force all integer immediates to hex
rg-dis game.tos --float-format raw # force raw IEEE hex for FPU constants
rg-dis game.tos --unused-equates # retain unreferenced equates in preamble
| Option | Values | Default | Purpose |
|---|---|---|---|
--imm-format <MODE> | auto, hex, dec | auto | Integer # immediate format: small values decimal, large/bitmask hex |
--float-format <MODE> | text (decimal, dec), raw (hex) | text | FPU # immediate format: decimal literal (#1.0) vs IEEE hex (#{$3F800000}) |
--data-width <WIDTH> | auto, byte, word, long | auto | Unit width for raw data directives (dc.b, dc.w, dc.l) |
--data-pack / --no-data-pack | flag | on | Pack multiple comma-separated data values per line |
--spacing / --no-spacing | flag | on | Insert blank lines around logical subroutines and system calls |
--spaces [N] | integer (optional) | 4 | Indent lines using spaces (default 4; e.g. --spaces=2) |
--tabs [N] | integer (optional) | 1 | Indent lines using tabs (default 1; e.g. --tabs=2) |
--unused-equates / --no-unused-equates | flag | off | Keep unreferenced equates in listing preamble |
Contextual subroutine spacing (--spacing, --no-spacing)
By default (--spacing), rg-dis analyses control flow to insert blank lines around logical subroutine boundaries, RTS/RTE exits, and system call argument blocks:
| Default spacing (`--spacing`) | Dense listing (`--no-spacing`) |
|---|---|
|
|
Indentation style (--spaces, --tabs)
Choose between space or tab indentation and configure indent width:
rg-dis game.tos --spaces 2 # 2-space column indentation
rg-dis game.tos --spaces 4 # 4-space column indentation (default)
rg-dis game.tos --tabs 1 # tab indentation (1 tab)
; --spaces 2
_start:
MOVE.L 4(A7),A5
RTS
; --spaces 4 (default)
_start:
MOVE.L 4(A7),A5
RTS
Data packing & width (--data-pack, --data-width)
Data regions default to packed, comma-separated values up to 80 columns (--data-pack). Use --no-data-pack to emit one directive per line, or --data-width to control element sizes:
rg-dis game.tos --no-data-pack # one element per line
rg-dis game.tos --data-width byte # force dc.b bytes
rg-dis game.tos --data-width word # force dc.w words
rg-dis game.tos --data-width long # force dc.l longwords
| Packed data (default) | Single-element (`--no-data-pack`) |
|---|---|
|
|
Integer immediate formatting (--imm-format)
Configure integer # immediate literal formatting:
rg-dis game.tos --imm-format auto # small values decimal, large/masks hex (default)
rg-dis game.tos --imm-format hex # all immediates in hex (#$000A, #$00FF)
rg-dis game.tos --imm-format dec # all immediates in decimal (#10, #255)
; --imm-format auto (default)
MOVEQ #0,D0
MOVE.W #10,D1
ANDI.W #$00FF,D1
; --imm-format hex
MOVEQ #$00,D0
MOVE.W #$000A,D1
ANDI.W #$00FF,D1
Floating-point formatting (--float-format)
Controls 68881/68882/68040 FPU constant formatting:
rg-dis math.tos --float-format text # decimal literals (e.g. #3.14159) [default]
rg-dis math.tos --float-format raw # IEEE-754 hex literals (e.g. #{$400921FB})
; --float-format text (default)
FMOVE.D #3.141592653589793,FP0
FMOVE.S #1.0,FP1
; --float-format raw
FMOVE.D #{$400921FB,$54442D18},FP0
FMOVE.S #{$3F800000},FP1
Equate preamble filtering (--unused-equates)
rg-dis automatically identifies Atari hardware registers, OS variables, and vector offsets. By default, unreferenced equates are pruned from the preamble to keep listings clean. Pass --unused-equates to retain the entire definition table in the header.
Options at a glance
| Group | Options |
|---|---|
| Input / output | [FILE] · -o / --output · --inspect [VIEW…] · --normalise · --json |
| Display | -q / --quiet · --color <WHEN> · --ascii · --banner <STYLE> |
| Listing layout | --[no-]smart-labels · --[no-]spacing · --spaces [N] · --tabs [N] · --[no-]data-pack · --data-width · --imm-format · --float-format · --[no-]unused-equates |
| Container & packing | --input-format · --container · --unpack · --bootsector · --disk · --sym |
| Target model | --cpu · --fpu · --machine |
| Disk images | --disk [RANGE] · --bootsector |
| Raw images | --org · --offset · --len |
| Object files & archives | --archive-member |
| Annotations | --[no-]annotate · --[no-]annotate-traps · --[no-]annotate-hw · --[no-]annotate-externs · --[no-]annotate-vt52 · --[no-]annotate-cycles · --[no-]annotate-offsets · --[no-]annotate-vdi · --[no-]annotate-aes · --[no-]annotate-embedded-executables |
Strings (with --inspect strings) | --strings-min-len · --strings-charset · --strings-min-score · --strings-include-code |
| Info | -h / --help · -V / --version |
Mutually exclusive: --inspect and --normalise; --bootsector with
--normalise (or --sym on a full disk image); --bootsector and --disk; --spaces and --tabs.
Reference
| Flag | Meaning |
|---|---|
-o, --output <FILE> | Write the artifact to FILE instead of stdout |
--inspect [VIEW…] | Metadata report: bare = summary; header/sections/symbols/functions/cycles/relocs/strings/cpu/all |
--normalise | Layout-invariant listing for A/B diffing (objects/archives; alias --normalize) |
--json | Machine-readable JSON envelope on stdout (all modes) |
-q, --quiet | Suppress all startup banners, progress spinners, and format-autodetect notes on stderr |
--color <WHEN> | When to colourise output (auto [default], always, never; honours NO_COLOR). --color=always forces pretty boxed tables and ANSI escapes even when piped |
--ascii | Draw inspect tables and banners with ASCII characters instead of Unicode box-drawing glyphs |
--banner <STYLE> | Startup masthead on stderr: logo (default on colour TTY), line, none (default when piped or quiet) |
--input-format <FMT> | Container format override: auto (default), tos, elf, dri, gst, aout, ar, cpx, disk, raw |
--smart-labels, --no-smart-labels | Contextual smart-labelling (on by default): replace opaque synthetic address labels with semantic names from strings, OS variables, trap returns, and vectors (--no-smart-labels restores synthetic _L12A4 labels) |
--spacing, --no-spacing | Insert contextual blank lines around logical code blocks (subroutine/ISR terminations and system calls; on by default, --no-spacing disables) |
--spaces [N] | Indent lines using spaces (default 4; optional count N, e.g. --spaces=2; conflicts with --tabs) |
--tabs [N] | Indent lines using tabs (default 1; optional count N, e.g. --tabs=2; conflicts with --spaces) |
--data-pack, --no-data-pack | Pack multiple comma-separated data values per line (up to 80 cols / 16 bytes; on by default, --no-data-pack emits one item per line) |
--data-width <WIDTH> | Unit width for data directives: auto (default), byte, word, long |
--strings-min-len <N> | Strings: shortest run to report (default 4; accepts hex or decimal) |
--strings-charset <SET> | Strings: ascii (default), printable (adds tab/CR/LF), atari (adds the ST high range) |
--strings-min-score <N> | Strings: drop runs scoring under N of 100 (default 40; 0 disables every filter) |
--strings-include-code | Strings: also report runs inside decoded instruction regions (default excludes them) |
--bootsector | Extract + disassemble floppy boot sector from .ST/.MSA/.STX (org $0) |
--disk [<RANGE>] | Disassemble floppy image (.ST, .MSA, .STX); optional RANGE: track (10), track range (10..12), sector range (0/0/1..0/1/9), or boot |
--container <FILE> | Resolve the positional FILE as a path inside a ZIP/LZH archive or FAT12 .ST/.MSA/.STX image |
--unpack | Automatically detect and decompress packed executables and data containers (Ice, Atomik, Automation, Pompey, SpeedPacker, Fire, etc.) before disassembling |
-m, --cpu <MODEL> | Target CPU model: auto (default; emits minimal required CPU directive), 68000, 68010, 68020, 68030, 68040, 68060, coldfire (aliases cf, cfv4e, cf5208, cf548x) |
--fpu <MODEL> | FPU model: auto (default; emits .fpu only if FPU ops are present), none, 68881, 68882, coldfire (alias cf) |
--auto-target, --no-auto-target | Enable (default) or disable minimal required CPU/FPU directive calculation and emission (--no-auto-target emits exact configured target) |
--machine <M> | Target Atari machine (st, ste, mste, tt, falcon) to focus hardware annotations (--annotate-hw) |
--org <ADDR> | Raw-image base address (hex 0x…/$… or decimal; default 0) |
--offset <N> | Skip the first N bytes (base advances with it; accepts hex or decimal) |
--len <N> | Disassemble only N bytes (accepts hex or decimal) |
--sym <FILE> | DRI/GST symbol sidecar for named labels (raw images and TOS executables) |
--archive-member <NAME|INDEX> | Archive: --inspect or disassemble one member (bare --inspect lists members) |
--float-format <MODE> | FPU # immediate formatting: text (default decimal literal #1.0) or raw (IEEE hex #{$3F800000}) |
--imm-format <MODE> | Integer # immediate formatting: auto (default), hex, or dec |
--unused-equates, --no-unused-equates | Keep unreferenced equates in the listing preamble (--no-unused-equates prunes them; default) |
--annotate, --no-annotate | Enable (default) or disable every annotation family (--annotate-traps, --annotate-hw, --annotate-externs, --annotate-vt52, --annotate-cycles, --annotate-offsets, --annotate-vdi, --annotate-aes, --annotate-embedded-executables) |
--annotate-traps, --no-annotate-traps | Comment GEMDOS/BIOS/XBIOS calls and stack arguments, AES/VDI selectors and Line-A entries (on by default; --no-annotate-traps disables) |
--annotate-hw, --no-annotate-hw | Comment accesses to documented Atari address meanings (memory-mapped I/O, vectors, low-memory state; on by default; --no-annotate-hw disables) |
--annotate-externs, --no-annotate-externs | Comment external symbol references and relocations in object files (on by default; --no-annotate-externs disables) |
--annotate-vt52, --no-annotate-vt52 | Comment VT-52 terminal escape sequences in string data (on by default; --no-annotate-vt52 disables) |
--annotate-cycles, --no-annotate-cycles | Comment each instruction line with its right-aligned CPU cycle execution cost (off by default; --annotate-cycles enables) |
--annotate-offsets, --no-annotate-offsets | Comment each line with its memory address, one uniform width for the listing; with --annotate-cycles the address leads and a bar separates it from the cycle cost (off by default; --annotate-offsets or --annotate enables) |
--annotate-vdi, --no-annotate-vdi | Comment and format VDI parameter blocks (VDIPB) and pointer tables (on by default; --no-annotate-vdi disables) |
--annotate-aes, --no-annotate-aes | Comment and format AES parameter blocks (AESPB) and pointer tables (on by default; --no-annotate-aes disables) |
--annotate-embedded-executables, --no-annotate-embedded-executables | Format embedded GEMDOS executable headers ($601A) symbolically and decode entry jump vectors into code (on by default; --no-annotate-embedded-executables disables) |
-V, --version | Print version (honours --json) |
-h, --help | Full usage (-h summary, --help long form) |
Errors & exit status
Diagnostics are plain text on stderr (rg-dis: error: <message>), or formatted inside the JSON envelope on stdout when --json is specified.
| Exit code | Meaning | Output stream | Notes |
|---|---|---|---|
0 | Success | stdout | Disassembly listing or inspect summary emitted successfully |
1 | Runtime error | stderr (or JSON stdout) | Missing input files, parse failures, unreadable images (rg-dis: error: …) |
2 | Usage error | stderr | Clap argument parsing errors, unknown flags, invalid values, incompatible options |
Part 2 — JSON output
Global --json mode
Passing --json outputs structured JSON on stdout instead of terminal text. Terminal banners, progress indicators, and decorative formatting are suppressed.
| Command | Normal output (stdout) | --json output (stdout) |
|---|---|---|
| Disassembly (default) | Assembly source listing | JSON envelope with listings[].text |
--inspect | Formatted summary table | JSON envelope with summaries[] metadata |
--inspect symbols / relocs / … | Formatted section table | JSON envelope with requested slices |
--version | Version text | JSON envelope with version info |
-o <FILE> | Writes assembly file; prints summary | Writes assembly file; outputs JSON envelope |
| Runtime error | Error message on stderr (exit 1) | JSON error envelope on stdout (exit 1) |
| Usage error | Usage message on stderr (exit 2) | Usage message on stderr (exit 2) |
# Disassemble to JSON and extract the listing text
rg-dis game.tos --json | jq -r '.listings[0].text'
# Inspect metadata and symbol counts
rg-dis game.tos --inspect --json | jq '.summaries[0].counts'
# Extract symbols
rg-dis game.tos --inspect symbols --json | jq '.summaries[0].symbols[].name'
# Disassemble to an output file while capturing JSON stats
rg-dis game.tos -o game.s --json | jq '.listings[0].source'
Envelope structure
Every --json response uses this top-level envelope:
{
"schema": 1,
"tool": "rg-dis",
"version": "0.7.3",
"status": "ok",
"command": { "input": "game.tos", "inspect": false },
"outputs": [],
"summaries": [{ "source": "game.tos", "kind": "disassembly", "layout": {} }],
"listings": [{ "source": "game.tos", "kind": "disassembly", "text": "…" }],
"diagnostics": []
}
| Field | Type | Description |
|---|---|---|
schema | number | Schema version (currently 1) |
tool | string | Always "rg-dis" |
version | string | rg-dis version string |
status | string | "ok" or "error" |
error | object? | Error details when status is "error" (code, message) |
command | object | Command-line options used for this run |
outputs | array | Output file details when -o is used |
summaries | array | Inspection metadata and section tables |
listings | array | Disassembly text and source identifiers |
diagnostics | array | Diagnostic messages, notes, and warnings |
When an error occurs (such as a missing or corrupt file), status is "error" and details are provided under error and diagnostics:
{
"schema": 1,
"tool": "rg-dis",
"version": "0.7.3",
"status": "error",
"error": { "code": "io", "message": "No such file or directory" },
"command": { "input": "missing.tos" },
"outputs": [],
"summaries": [],
"listings": [],
"diagnostics": [{ "severity": "error", "message": "missing.tos: No such file or directory" }]
}
Inspect views
When --inspect is used with --json, the results appear under summaries[]. Specific views can be requested individually or in combination (e.g. --inspect header,symbols):
| View | TOS / Raw binary | ELF / DRI / a.out / GST |
|---|---|---|
| (default) | header, layout, counts | header (if present), sections, counts |
header | header, prgflags | header |
sections | layout | sections[] |
symbols | symbols[] | symbols[] |
relocs | relocs[] | relocs[] |
functions | functions[] | functions[] |
cycles | cycles[] | cycles[] |
strings | strings[] | strings[] |
cpu | cpu | cpu |
disk | disk, geometry, selection, byte_span | — |
all | All available views | All available views |
Payload details
TOS / Raw binary
{
"input_kind": "Tos",
"header": { "text_size": 4096, "data_size": 256, "bss_size": 512, "sym_size": 140, "flags": 0, "has_relocs": true },
"prgflags": { "raw": 0, "fastload": false, "ttram_load": false, "ttram_mem": false, "shared_library": false, "mem_protect": "global", "shared_text": false, "tpa_nibble": 0, "tpa_bytes": 0, "has_reserved_bits": false },
"layout": { "text_start": 65536, "text_end": 69632, "data_start": 69632, "data_end": 69888, "bss_start": 69888, "bss_end": 70400 },
"symbols": [{ "name": "_main", "segment": "Text", "global": true, "value": 65540, "type_word": 0 }],
"relocs": [65544, 65548],
"functions": [{ "address": 65540, "name": "_main", "size": 128 }],
"cycles": [{ "address": 65540, "name": "_main", "cycles": 842 }],
"strings": [{ "file_off": 8192, "addr": 73728, "segment": "Data", "region": "Data", "bytes_len": 12, "term": "Nul", "score": 90, "label": null, "referenced": true, "text": "Hello\\x00" }],
"counts": { "symbols": 10, "relocs": 42, "functions": 8, "strings": 3 }
}
| Field | Description |
|---|---|
header.text_size / data_size / bss_size | Section sizes on disk and in memory |
header.sym_size | Embedded symbol table size in bytes |
header.flags | Raw GEMDOS PRGFLAGS longword |
prgflags.* | Decoded Atari TOS memory and load flags |
layout.*_start / *_end | Memory addresses for .text, .data, and .bss |
symbols[] | Symbol names, segments, visibility, and values |
relocs[] | Addresses of relocatable references |
functions[] | Function entry points, names, and byte sizes |
cycles[] | Estimated 68000 CPU cycle costs per function |
counts | Summary totals when full tables are omitted |
Object files (ELF / DRI / a.out / GST)
{
"input_kind": "Elf",
"header": { "e_type": 1, "type_name": "REL", "entry": 0 },
"sections": [{ "name": ".text", "kind": "Text", "addr": 0, "size": 128, "align": 4, "flags": 6 }],
"symbols": [{ "name": "_tick", "value": 0, "size": 0, "bind": "Global", "section": ".text" }],
"relocs": [{ "section": ".text", "offset": 4, "symbol": "_state", "rtype": "R_68K_32", "addend": 0 }],
"functions": [],
"cycles": [],
"strings": [],
"counts": { "symbols": 1, "relocs": 1, "functions": 0, "strings": 0 }
}
Floppy boot sector
{
"input_kind": "BootSector",
"disk": "MSA",
"org": 0,
"size": 512,
"checksum": 4660,
"executable": true,
"strings": []
}
Static library archives (.a)
{
"input_kind": "Archive",
"members": [{ "name": "libvc.o", "kind": "a.out OMAGIC object", "bytes": 4096 }],
"warnings": []
}
String scanner fields
When --json is requested with --inspect strings, the strings[] array preserves the full set of scanner metadata fields:
| Field | Type | Description | Terminal Table Mapping |
|---|---|---|---|
text | string | Extracted string content | string column |
addr | number | Guest address at run time | addr column |
segment | string | Section or segment name ("Text", "Data", etc.) | seg column |
bytes_len | number | Run length in bytes | len column |
referenced | boolean | Whether a relocated pointer or code reference targets this address | ref column (Y / -) |
label | string? | Symbol name defined at this address, if any | label column |
file_off | number | Raw byte offset in the input file on disk | Extended JSON metadata |
region | string | Lightweight classification ("Data", "Code", "Unclassified") | Extended JSON metadata |
term | string | Terminator type ("Nul", "Eol", "Boundary", "Truncated") | Extended JSON metadata |
score | number | Plausibility score (0–100%) | Extended JSON metadata |
Greetings
No comprehensive technical manual would be complete without a list of greetings.
So big shout outs to the folks still keeping the atari scene ticking over in the 2k26
Aggression · Avena · Cerebral Vortex · Cream · Defence Force · Dekadence · DHS
Dune · Effect · Ephidrena · Evolution · Extream · HMD · Holocaust · KÜA
Lamers · LineOut · LoUD · Marquee Design · MEC · MPS · MSB · New Beat · Newline
NoExtra · Omega · OVR · Oxygene · Paradox · PHF · Sector One · smfx · SYNC
TPT · XiA
Final Notes
This is an early release of rg-dis, so of course there are likely to be bugs and issues.
Please reach out and report any that you find or share any suggestions you have for improvements.
License
rg-dis is dual-licensed under the MIT License or the Apache License 2.0, at your option.
The full license texts ship with this release as LICENSE-MIT and LICENSE-APACHE. You may use,
copy, modify, and redistribute rg-dis under either license's terms. Contributions are accepted
under the same dual license unless stated otherwise.
Copyright (c) 1993–2026 Reservoir Gods
♥ made with love for the scene ♥