NG-atariATR
Tools for Atari 8-bit disk images: 16 MB MyDOS and SpartaDOS support, plus a Total Commander packer plugin
- Active · last change 7-30-2026
- ★ 1 on GitHub
README
atariATR
Tools for Atari 8-bit disk images — including 16 MB images (65535 × 256 B) in MyDOS and SpartaDOS format, with full subdirectory support.
Polish version / wersja polska
Downloads
Ready-made binaries are attached to every release:
| File | What it is |
|---|---|
atrtool-X.Y-windows-x64.exe |
command line tool, 64-bit Windows |
atrtool-X.Y-macos-arm64 |
command line tool, Apple Silicon |
AtrWcx-X.Y.zip |
Total Commander packer plugin — drag onto TC to install |
AtrWfx-X.Y.zip |
Total Commander file system plugin — same, separate package |
AtrWcx-X.Y-macos-arm64.wcx |
Double Commander packer plugin, Apple Silicon |
AtrWfx-X.Y-macos-arm64.wfx |
Double Commander file system plugin, Apple Silicon |
AtrWcx-X.Y-linux-x86_64.wcx, AtrWfx-X.Y-linux-x86_64.wfx |
the same two for Linux |
Releases are built per platform by GitHub Actions, so the Intel Mac and Linux
artifacts come from native builds. A 32-bit .wcx is not among them — see
Building.
macOS refuses to run unsigned downloads; clear the quarantine flag once:
xattr -d com.apple.quarantine atrtool-*-macos-arm64
chmod +x atrtool-*-macos-arm64What's inside
Two things share one engine:
atrtool— a command line tool to create, inspect and modify ATR/XFD images: format them, add and remove files, make subdirectories, and turn an image into a bootable disk by transplanting a DOS from a template image.- Two plugins for Total Commander and Double Commander (Windows, macOS,
Linux):
- a packer plugin (WCX) — open an
.atrlike an archive: browse the directory tree, copy files in and out, create directories, delete; - a file system plugin (WFX) — everything above plus what the archive interface has no functions for: renaming, moving inside the image, attributes, file dates and extra panel columns.
- a packer plugin (WCX) — open an
The engine is plain Object Pascal with no GUI dependencies, so the same code compiles under Free Pascal (macOS, Linux, Windows) and Delphi.
Why
Large Atari disk images are where most tools stop. Existing ones read a MyDOS image but don't walk its subdirectories, or write only in the root directory of a SpartaDOS disk, or create images without being able to modify them afterwards. This project handles the full matrix: read and write, subdirectories included, up to the 16 MB ceiling of the 8-bit world, and it is checked against real disks rather than against its own assumptions — see How it is verified.
Supported formats
| Container | Notes |
|---|---|
| ATR | 128, 256 and 512 byte sectors; up to 65535 sectors (~16 MB) |
| XFD | headerless, geometry inferred from file size |
| File system | Read | Write | Notes |
|---|---|---|---|
| Atari DOS 2.0S | yes | yes | 720 sectors, 10-bit sector links |
| Atari DOS 2.5 | yes | yes | enhanced density, second VTOC at sector 1024 |
| MyDOS | yes | yes | subdirectories, 16-bit links, multi-sector VTOC, up to 16 MB |
| SpartaDOS / SDFS | yes | yes | sector maps, nested subdirectories, timestamps, up to 16 MB |
| BW-DOS, SpartaDOS X, RealDOS | yes | yes | all use SDFS, so they are covered by the above |
Above 1023 sectors only MyDOS and the SDFS family exist — Atari DOS 2.0S stops at 720 sectors and DOS 2.5 at 1040. That is a limit of the platform, not of these tools.
Standard geometries: sd (90K), ed (130K), dd (180K), qd (360K),
512k, 1m, 2m, 4m, 8m, 16m, plus free-form sizes such as
65535x256, 1040s or 180K.
atrtool
atrtool info image.atr # geometry, header, warnings
atrtool list image.atr -r # contents, recursively
atrtool create new.atr 16m # empty 16 MB image
atrtool format new.atr mydos # mydos | dos2 | dos25
atrtool format new.atr sparta MYDISK # SpartaDOS with a volume name
atrtool add image.atr game.xex GAME.XEX # add a file (name is optional)
atrtool extract image.atr GAME.XEX out.xex
atrtool del image.atr GAME.XEX
atrtool mkdir image.atr GAMES # subdirectory (MyDOS / SpartaDOS)
atrtool rmdir image.atr GAMES
atrtool installdos new.atr template.atr # make the image bootable
atrtool dump image.atr 360 # hex dump of a sector
atrtool roundtrip image.atr # verify write fidelityMaking a bootable 16 MB MyDOS disk from scratch:
atrtool create hd.atr 16m
atrtool format hd.atr mydos
atrtool installdos hd.atr "Mydos 4.50.atr" # copies boot code + DOS.SYS/DUP.SYS
atrtool add hd.atr mygame.xexNo DOS binaries are shipped with this project. installdos takes the boot
sectors and system files from an image you already have, and patches the fields
that depend on the target disk: the DOS.SYS start sector, the density flag,
the link field offset, and — crucially for large disks — the sector link mask,
which MyDOS switches from AND #$03 to AND #$FF when a disk uses 16-bit links.
Without that patch a boot loader copied from a floppy stops at the first sector
above 1023.
Host file names are converted to 8.3 using the rules of the target file system, with Polish letters transliterated:
| On disk | MyDOS | SpartaDOS |
|---|---|---|
my-file v2.txt |
MYFILEV2.TXT |
MYFILEV2.TXT |
2ndfile.dat |
X2NDFILE.DAT |
2NDFILE.DAT |
moj_plik-2.dat |
MOJPLIK2.DAT |
MOJ_PLI2.DAT |
ŻÓŁW.TXT |
ZOLW.TXT |
ZOLW.TXT |
zmienne_01.wav |
ZMIENN01.WAV |
ZMIENN01.WAV |
file_1234567890.wav |
FILE7890.WAV |
FILE7890.WAV |
bardzo dluga nazwa pliku.dokument |
BARDZOD8.DOK |
BARDZOD8.DOK |
DOS 2 requires a letter in the first position and allows no underscore, which is why the MyDOS column differs.
Shortening never throws away the digits at the end of a name, because those are
what tell a series apart: zmienne_01, zmienne_02, zmienne_03 would all
collapse to ZMIENNE0 if the name were simply cut at eight characters. Letters
give way instead, so the numbering survives and copying a whole series asks
nothing.
When there are no digits to keep, the last character becomes a hexadecimal index
derived from the source name — BARDZOD8 above. It looks arbitrary, and it is:
bardzo dluga nazwa pliku.dokument and bardzo dluga nazwa pliku bo czemu nie.dokument are identical for their first eight characters, so no algorithm can
squeeze the difference into an 8.3 name. What the index buys is that the 8.3
name is a pure function of the name on disk: the same file always lands in the
same place, so copying it again overwrites its own file instead of a neighbour
with a similar name. Directory names follow the same rule, which keeps two long
directories from silently merging into one.
Both plugins report every conversion, so you can see which file became what:
the file system plugin writes it to the file manager's log window, the packer
plugin to its own log, and atrtool add prints it.
File manager plugins
Two plugins share the engine, and they answer different needs:
| Packer (WCX) | File system (WFX) | |
|---|---|---|
Enter an .atr clicked in the panel |
yes | no — images come from a list |
| Browse, copy in and out, delete | yes | yes |
| Create directory | yes | yes |
Rename (F2) |
no | yes |
| Move within the image | no | yes |
| Attributes (Atari lock ↔ read-only) | no | yes |
| File dates (SpartaDOS) | no | yes |
| Extra panel columns | no | yes |
If you only want to look inside an .atr you clicked, install the packer plugin.
If you want to manage image contents like a drive, add the file system plugin too
— they coexist without conflict.
Packer plugin
Grab AtrWcx-X.Y.zip from the Releases page (or build it
yourself — see Building) and drag it onto a Total Commander
window: the bundled pluginst.inf makes TC offer to install it. Then
Ctrl+PgDn on an .atr file enters the image, F5/F6 copy files in and out,
F7 creates a directory and F8 deletes — a directory is removed with
everything inside it.
Copying a whole directory into an image preserves its structure: every path
component is converted to a valid 8.3 name for the target file system
(Moje Gry/Level 1/dane.dat becomes MOJEGRY/LEVEL1/DANE.DAT), and missing
directories are created along the way — empty ones included.
The plugin browses the full subdirectory tree of MyDOS and SpartaDOS images,
extracts and adds files (including into subdirectories), deletes them, and
recognises images by content, not by extension — so an .atr file that is
really a raw-sector disk is not shown as an empty archive.
It does not create images: a new image needs decisions about geometry, file
system and DOS that belong in atrtool, not in a packer dialog. Total Commander
does list .atr in its pack dialog, because withholding PK_CAPS_NEW also stops
it from adding files to an existing image — so creation is refused with a clear
error instead.
If something does not work as expected, create an empty file named AtrWcx.log
in the same directory as the .atr. The plugin then appends a line for every
operation it is asked to perform, which answers the first question worth asking:
whether the file manager called the plugin at all.
Requires 64-bit Total Commander. The 32-bit version does not load
.wcx64files at all, so the package is not recognised as a plugin — TC just opens the ZIP. BuildAtrWcx.wcxon Windows (see below), add it to the same package and pointfile=at it; a 64-bit TC then picks the.wcx64from the same archive by itself.
File system plugin
Install AtrWfx-X.Y.zip the same way as the packer package (it carries its own
pluginst.inf; for Double Commander take the native AtrWfx-*.wfx). It then
appears as Atari ATR among network connections, not tied to any single file.
The extra panel columns show what a fixed archive listing has no room for: starting sector, sector count, the image's file system, the 16-bit link flag and Atari attributes — sortable, like any other column.
File dates work only where the format has them: SpartaDOS stores a date and time per file, so copying into such an image preserves the date from disk. MyDOS has no date field at all and the plugin reports that instead of pretending it worked.
Because a file system plugin is not tied to a clicked file, it needs to know
which images to show. Enter it and you will find one file, _LISTA-OBRAZOW.TXT:
press F3 to read it (its first line tells you where it lives on disk) or F4
to edit it, then refresh the panel. One entry per line — either an image file or
a directory, in which case every .atr/.xfd inside is listed:
C:\Atari\images
C:\Atari\games\labyrinth.atrATRWFX_CONFIG overrides the location of that list if you prefer to keep it
elsewhere.
You do not have to type paths by hand. Copy an .atr onto the plugin root with
F5 and its path is appended to the list — the file stays where it is, only a
reference is recorded, so nothing is duplicated. Repeating it changes nothing, and
anything that is not a disk image is refused. F6 (move) is refused too: nothing
was copied, so "moving" could only mean deleting your image.
F8 on an image in the root removes it from the list and leaves both the file
and its contents alone. This needs care, because a file manager has no recursive
delete in the API: before removing something that looks like a directory, it
deletes the contents itself, file by file. Left unguarded, that gesture empties
the disk image, DOS included — measured in Double Commander. The plugin therefore
watches FsStatusInfo, which reports the directory an operation started in:
- delete started in the image list, target inside an image → skipped without
touching anything, and the closing
FsRemoveDirremoves the list entry instead. The skip is reported as success on purpose: the image disappears from the panel a moment later, so nothing can show a state that contradicts it, and reporting failure meant one error dialog per file — on an image with a dozen files the gesture turned into clicking "skip all"; - delete started inside an image → passed through, so deleting files and non-empty directories from a disk works as before.
If a file manager does not report that context, nothing switches on: deletion
behaves as it always did and removing an entry is refused with a message pointing
at F4. The convenience only appears where the guard actually protects you.
An image shown by a directory entry has no line of its own, so F8 refuses it
rather than removing the directory entry — that entry serves other images too.
Set AtrWfx.log next to the list file and the plugin appends the call sequence it
receives; useful for checking what a particular file manager does.
Directories are moved by the file manager itself (create, move contents, remove), so moving a whole directory in one call reports "not supported" — the end result is the same.
Double Commander (macOS, Linux)
The same plugin works in Double Commander, which implements the same plugin interface and — verified in its source — calls the Unicode entry points on every platform, converting its UTF-8 strings to UTF-16. So no separate code is needed, only a native build:
build/build-wcx-native.sh # -> bin/AtrWcx.wcx (native shared library)Then in Double Commander: Configuration → Options → Plugins → Packer plugins →
Add, pick AtrWcx.wcx and associate the extension atr (and xfd if you want).
Double Commander keeps native plugins under plugins/wcx/<name>/<name>.wcx, so
copying it there fits its layout.
One catch worth knowing if you write plugins yourself. On macOS the loader resolves symbols with
dlsym, which prepends an underscore to the name per the C convention, while Free Pascal exportsOpenArchiveWrather than_OpenArchiveW. The failure is quiet: the library loads fine and not a single function is found. This project exports underscore-prefixed names under{$IFDEF DARWIN}andtests/wcx-loadcheckguards it by loading the built plugin exactly the way a file manager does.
Building
Engine and atrtool (macOS, Linux, Windows)
brew install fpc # or your distribution's fpc package
./build/build.sh # -> bin/atrtoolThe plugins
On Windows, Free Pascal or Lazarus is enough:
build/build-wcx.sh win64 # packer plugin -> AtrWcx.wcx64
build/build-wfx.sh win64 # file system plugin -> AtrWfx.wfx64On macOS and Linux the native builds for Double Commander are:
build/build-wcx-native.sh # -> bin/AtrWcx.wcx
build/build-wfx-native.sh # -> bin/AtrWfx.wfxOn macOS or Linux you need an FPC cross-compiler for Windows. Build it once:
curl -LO https://sourceforge.net/projects/freepascal/files/Source/3.2.2/fpc-3.2.2.source.tar.gz/download
tar xzf fpc-3.2.2.source.tar.gz && cd fpc-3.2.2
SDK=$(xcrun --show-sdk-path) # macOS only
make -j8 crossall CPU_TARGET=x86_64 OS_TARGET=win64 \
OPT="-XR$SDK -Fl$SDK/usr/lib" CROSSOPT="-O2"
make crossinstall CPU_TARGET=x86_64 OS_TARGET=win64 INSTALL_PREFIX=~/fpc-cross
FPC_CROSS_ROOT=~/fpc-cross build/build-wcx.sh win64
FPC_CROSS_ROOT=~/fpc-cross build/build-wfx.sh win64The -XR/-Fl flags are required on macOS because make invokes the compiler
with -n, which skips fpc.cfg and with it the SDK paths.
A 32-bit .wcx/.wfx cannot be cross-compiled on an ARM Mac: FPC refuses to target
i386 from a host without an 80-bit extended floating point type. It is also not
built by CI — the Windows runner's Free Pascal only targets x86_64. If you need it,
build it on Windows with a 32-bit FPC or Lazarus installation:
build/build-wcx.sh win32.
Tests
tools/fetch-dos-images.sh # reference DOS images from AtariWiki (once)
tests/make-boot-images.sh # bootable images for emulator testing
tests/run-tests.sh [image-dir]run-tests.sh scans a directory of real .atr files (~/Downloads by default)
and reports round-trip fidelity, then exercises both file systems and the plugin.
Whether an Atari actually boots from a generated image is the one thing no test
can answer — docs/EMULATOR-TESTING.md lists what to
check in an emulator and how to tell the failure modes apart.
make-boot-images.sh needs a MyDOS image with DOS.SYS on it as a template for
the MyDOS set; AtariWiki publishes MyDOS sources but no ready boot disk, so point
it at your own: MYDOS_TEMPLATE=/path/to/mydos.atr tests/make-boot-images.sh.
Without it only the SpartaDOS set is generated.
How it is verified
Correctness here is not self-reported: every claim below is produced by
tests/run-tests.sh or by an independent implementation.
- Round-trip on 1705 real images: 1689 are written back byte-for-byte identically. 14 have headers inconsistent with their file size (reported as such — we pad to the full geometry, which repairs the header), 2 are corrupt or not ATR files at all.
- Reading the same corpus: 943 images are read as file systems, with their complete subdirectory trees and no exceptions. The other 760 have no file system at all — see non-filesystem images.
- Cross-validation both ways: 16 MB images created and filled by this code —
MyDOS and SpartaDOS alike — are read, listed and byte-exactly extracted by an
independent implementation,
lsatrfrom mkatr (C), with free sector counts matching exactly. In the other direction we read images written by real MyDOS and real SpartaDOS, subdirectories included. - Writing into a real SpartaDOS X 4.48 image: after adding a 300 KB file and a subdirectory, exactly 5 bytes of the boot sectors changed — the free sector count, the allocation hint and the sequence number. The boot code is untouched, so the disk still boots, and both independent readers accept the result.
- Agreement with original documentation: MyDOS formatting parameters match
TECH.DOCfrom the MyDOS 4.51 sources, down to details like 708 free sectors on an empty single density disk — MyDOS includes sector 720 in its file system, plain DOS 2 leaves 707. - A 16-bit-link image actually boots: an 8 MB MyDOS image created by this code (17 VTOC sectors, patched link mask) boots on real MyDOS in an emulator, with its subdirectory visible in the DOS menu.
- Both plugins are tested without Windows:
tests/wcx-harness(67 checks) andtests/wfx-harness(57 checks) call the plugin functions in exactly the order a file manager uses, on MyDOS and SpartaDOS 16 MB images — including the operations only the file system plugin can do: renaming, moving inside the image, attributes, dates and custom columns.tests/wcx-loadcheckandtests/wfx-loadcheckverify every entry point resolves throughdlopen/dlsym, the check that caught the macOS symbol-underscore trap. - File system writes are checked on SD, DD, 8 MB and 16 MB geometries in both file systems: extracted data is byte-identical, and the free sector count returns exactly to its post-format value after everything is deleted. For SDFS this also covers files spanning 10 chained sector maps, directories growing across sector boundaries, and reuse of deleted directory entries.
Non-filesystem images
Roughly 45% of the test corpus (760 of 1705 images) contains no file system: the boot sectors hold a custom loader that reads data straight off sectors. This is normal for demos, games and cartridge-oriented images, and such images cannot be browsed as files by any tool.
The engine reports this as a distinct condition (EAtariFsNoFileSystem) rather
than as a read error, and both front ends make use of that instead of turning the
user away:
atrtool listprints what is known about the image — geometry, whether the header agrees with the file size, and a decoded Atari boot record (how many sectors the loader reads, its load and init addresses).- the plugin opens the image anyway and shows a single read-only virtual file,
INFO-DYSK.TXT, containing that same description. So entering such an.atrin Total Commander or Double Commander explains what the image is instead of failing. Writing to these images is refused — there is no directory and no free sector map, so any write would overwrite the loader.
Project layout
src/core/ engine ??? plain Pascal, no GUI dependencies
Atari.Atr.pas ATR/XFD container, sector access
Atari.Geometry.pas standard geometries, size parsing
Atari.FileSystem.pas file system interface, 8.3 names, ATASCII, paths
Atari.Fs.Dos2.pas Atari DOS 2.0S / 2.5 / MyDOS
Atari.Fs.Sparta.pas SpartaDOS / SDFS
Atari.Fs.Detect.pas file system detection, boot sector disambiguation
Atari.RawInfo.pas description of images that have no file system
Atari.DosInstall.pas transplanting a DOS from a template image
src/cli/atrtool.dpr command line tool
src/plugin/ plugins for Total Commander / Double Commander
WcxHead.pas, AtrWcxImpl.pas, AtrWcx.lpr packer plugin
WfxHead.pas, AtrWfxImpl.pas, AtrWfx.lpr file system plugin
docs/FORMATS.md format notes gathered from specs and measurements (Polish)
build/ build scripts, including make-release.sh
.github/workflows/ CI and per-platform release builds
tests/ test suite, WCX harness and dynamic load check
tools/fetch-dos-images.sh downloads reference DOS images from AtariWikidocs/FORMATS.md is worth a look if you work with these
formats yourself: it documents the ATR boot-sector ambiguity with measurements
from a 1705-image corpus, the MyDOS VTOC layout and link rules, the DOS 2 boot
record fields, and the SDFS structures — with the reasoning behind each.
Current limitations
- SDFS writing supports 128 and 256 byte sectors; 512 byte sectors (which would allow 32 MB images under SpartaDOS X) are read but not written, because the meaning of one superblock field for that case is undocumented and could not be verified here.
- The 32-bit
.wcxhas to be built on Windows or x86 (see above). - No GUI yet — a Lazarus front end is the next step.
Credits and references
Specifications used, with the implementations consulted, are listed in
docs/FORMATS.md. The main ones:
- ATR format specification (Jindroush)
- SpartaDOS disk format
- MyDOS 4.51 sources with the original
TECH.DOC(AtariWiki) - atarisio / dir2atr by Matthias Reichl — MyDOS creation reference
- mkatr by Daniel Serpell — SDFS creation reference,
and its
lsatrused for cross-validating the images produced here
The reference tools are GPL-2 licensed. This implementation was written from the specifications and from observations of real disk images; no code was copied.

