Floppy — the disk tool, and where its pieces live
A real-floppy copier and inspector for AntOS, modelled on Amiga X-Copy so it is familiar on sight. The X-Copy source is a specification and a data source, not a codebase — none of its 68000 is portable, and the parts worth having are the mode taxonomy, the workflow decisions, and a 74-entry virus signature table.
Status: design. The drive-letter and auto-mount half is already settled in filesystem; this page is the tool on top and the library placement underneath.
Back to filesystem · libraries: antos_data · antos_fs
What the X-Copy source actually yields
Read for what it is — 10,149 lines of 68000 assembler, German comments, X-Copy 5.3 / September 92 — it divides sharply.
| Verdict | |
|---|---|
Disk I/O — Paula DMA, CIA-B timers at $BFD400, MFM sync hunting, KILLSYS |
Useless to us. No Paula, no CIA. We work at flux level through a Greaseweazle, which is a strictly better vantage point |
| Copper lists, IFF images, bitmap font, gadget renderer | Useless. AntOS is ImGui on GLES |
| Mode taxonomy and workflow | Valuable. A decade of decisions about what a disk copier should offer |
| The virus signature table | Directly portable, and it is data rather than code |
| The changelog | Valuable. A record of what goes wrong with real disks |
Licence position. The source was released deliberately — Christian Bartsch, on behalf of Anguilla Software International, December 2011 — but with no stated terms. Released is not licensed. Reading it to decide what to build is fine; shipping a derivative in a product for sale is not covered by anything. Since it was a deliberate release, ask for an explicit grant before writing code against it. The signature table is the weakest exposure of anything here (see below) and the copier code is the strongest, which happens to align with what is worth taking.
The mode taxonomy, decoded
From xcopy.i and the gadget tables in xio.s, the interface is two windows.
COPY
| Mode | What it did | Modern equivalent |
|---|---|---|
DOSCOPY |
Decode every track to sectors, re-encode to the destination | Decode to filesystem, re-encode — the auto-mount path |
DOSCOPY+ |
As above with harder error handling and different buffering | A retry/severity policy, not a separate mode |
BAMCOPY+ |
Filesystem-aware — walk the directory hash tables (ScanDir) and copy only allocated blocks |
Same idea; needs a filesystem reader per format |
NIBBLE |
Raw MFM, no decode — the protected-disk mode | Subsumed by flux. See below |
TOOLS — OPTIMIZE, FORMAT, QFORMAT, ERASE, INSTALL (write a clean bootblock), SPEEDCHK (drive speed), DRIVES ON, KILLSYS. Plus CHECK, NAME and DIR in the equates.
The one that changes
NIBBLE exists because Paula could not do better. Nibble copying reads the MFM bitstream without decoding it, preserving what a sector-level copy would destroy — but it is still the disk controller's view, already quantised and clock-recovered by hardware built for one encoding.
A Greaseweazle captures actual flux transition timings. Weak bits, long tracks, non-standard sync marks, deliberate timing anomalies — all of it survives, and none of it depends on a controller agreeing to see it. So the mechanism behind NIBBLE is obsolete, and better.
But keep the name. The user-facing point of the X-Copy layout is that someone who used it in 1992 knows what the buttons do. NIBBLE should still be the button for "copy this disk without understanding it"; it just becomes a flux copy underneath. Keep the menu, replace the mechanism — that is the whole strategy on one line.
KILLSYS has no equivalent and should not acquire one. It existed to take the Amiga away from its OS for timing reasons; DeMon is a Linux machine and the Greaseweazle owns its own timing.
The virus table — the one thing to take almost verbatim
virustab in xcop.s holds 74 signatures, and the entire detection algorithm is one comparison:
DC.W offset ; byte offset into the decoded bootblock
DC.L matchlong ; 32-bit value expected there
...
cmp.l (a1,d0.w),d1 ; that is the whole test
with a parallel NUL-separated name table indexed by position. Two spellings appear in the source — DC.W off,hi,lo early and DC.W off / DC.L val later — which assemble to the identical flat (u16, u32) array. A port must preserve that, not the spelling.
Named entries include SCA (and the LSD/AEK/DAG/Ice/Graffiti family sharing its signature), Byte Bandit 1 and 2, Obelisk, Disk Doktors, Warhawk, North Star old and new, Pentagon Slayer, Joshua, Scarface, Disk Herpes, Lamer 1–5, CCCP, Termigator, Saddam Hussein, Paradox, Icebreakers.
Why this is the cleanest thing to lift. It is a table of offsets and magic numbers — facts about 1990s malware, independently discoverable by anyone holding the samples — and a four-byte compare at an offset is not expressive code. That is a very different proposition from porting a copier. Still worth naming in the permission request; but the exposure is close to nil, and the historical value is high, because these samples are getting harder to find every year.
The workflow around it is worth keeping too
The routine reads cylinder 0, decodes it, walks the table, and on a hit calls ShowVirus — an ASCII dump of the bootblock with KILL and CONTINUE. It checks write-protect before offering to kill, and killing writes a clean bootblock rather than zeroing anything.
Three decisions there, all correct, all worth inheriting:
- Never silently modify the user's disk. Show what was found and let them choose.
- Offer CONTINUE, because a signature match on a harmless custom bootblock is a real possibility and the tool should not be the authority.
- Check write-protect before offering an action that needs it, rather than failing halfway through.
And the trick from the manual: setting endtrack to 00 turns the copier into a standalone bootblock scanner. The mode list was general enough to be repurposed by a user who understood it — a good sign about the design, and worth preserving as a property rather than adding a "virus scan" button.
Where the pieces live
Three placements. Two of the proposed ones stand; one moves.
Flux operations → a floppy library, not fs
filesystem already names this: "a floppy library over the Greaseweazle protocol, running on DeMon". That is the right home and it should stay separate from fs.
fs is metadata, structure and search — dir, stat, tags, catalogue queries — and antos_fs is explicit that the whole reason it exists as its own namespace is to keep os/io standard. Hanging read_flux, write_track and detect_format off fs would undo that in the other direction: fs would stop being "the filesystem extras" and become "filesystem extras plus one device driver".
The relationship is already correct as designed and does not need changing:
floppy— flux read/write, format detection and override,.scp/.hfearchiving, image read/write, feeding a core.fs— sees the result: a mounted volume atE:with a directory tree, catalogued like anything else.
Same device at two levels, which is what filesystem already says. The tool on this page is a floppy client.
Codecs → data, but only the stateless half
This is the placement worth splitting rather than accepting whole. antos_data defines data as "pure byte-in / byte-out C with no Luau dependency", reused by net, DBFS and firmware. Some of a disk codec fits that exactly, and some of it does not fit at all.
Belongs in data |
Does not |
|---|---|
| MFM bit-cell encode — the pure transform | Clock recovery / PLL — stateful, and its parameters are per-drive and per-disk |
| GCR 4-and-4 / 5-and-3 / 6-and-2 table encode and decode | Sync-mark hunting across a bitstream |
| Amiga sector checksum, CBM GCR checksum | Track segmentation — finding where sectors start on a real, wowing disk |
| CRC-16/CCITT — the IBM MFM sector CRC | Weak-bit and unformatted-area detection |
Note that data.crc16 already exists and is already the right algorithm for IBM MFM sectors. That is a real hook, not a coincidence — it is the same checksum.
The dividing line is purity. data.base64.decode is a function of its input; decoding a real track is a function of its input and a recovered clock and a tolerance policy. Putting the second kind in data would make data the first library in AntOS with a device-shaped API, and net, DBFS and firmware all link it.
Recommendation: stateless codecs and checksums go in data; the stateful decoder goes in floppy and calls them. There is precedent for the alternative if the codec family grows — crypto was already split out of data on exactly this reasoning, so a codec library is available if it comes to that. Do not pre-emptively create one for four functions.
Protection and virus knowledge → floppy, as data
The signature table is a data file, not code — ship it as a table floppy reads, so it can be updated without a rebuild, and so the provenance of each entry can be recorded next to it.
What not to take
- The 68000. All of it. There is no path from Paula DMA to a Greaseweazle.
- The German comments. Translate the findings into this doc; do not carry the source's commentary into a new codebase.
KILLSYS.- Anything before the licence question is answered, if the answer matters to shipping.
Related
- filesystem — drive letters, the Greaseweazle auto-mount, and the flux API this tool sits on
- antos_data / luau_data — where the codecs go
- antos_fs / luau_fs — what stays out of them, and why
- demon — the Linux compute module the Greaseweazle host tooling runs on