Files: FAT12, FAT16 and FAT32
Reading and writing the files on a USB stick, or on a floppy disk tomorrow, with a module written for the project: 7 KiB of code and a single 512-byte buffer.
On this page
One module, three formats
USB sticks are almost always formatted as FAT32, floppy disks as FAT12. Eliott65 handles all three variants (FAT12, FAT16, FAT32) with a single module, written in portable C for the project. It takes about 7 KiB of code and works with a single sector in memory (512 bytes).
The type is determined as Microsoft prescribes, by the number of clusters: fewer than 4,085 is FAT12; fewer than 65,525, FAT16; above that, FAT32. The module recognises a partition table, or a disk without partitions, like a floppy disk.
Launching a program from the USB stick
The FICHIERS service can list a directory, read a file directly into the 6502’s memory, and
above all EXECUTER a .E65 program:
- the 6502 is frozen;
- the program is loaded in its place, into the 6502’s memory;
- the 6502 restarts on it.
No loader stays in memory. If something fails before loading (missing file, wrong format), the 6502 simply resumes with an error code.
First successful round trip, entirely from the USB stick: the shell launches BONJOUR.E65, which
displays “B O N J O U R !”, then relaunches the shell on a key press.
Long names, and a quadratic algorithm
On a USB stick, a file such as late.neo6502 is stored in two forms: a long name, split into
13-character pieces, and a generated short name in 8.3 format (hence the names with ~1 that one
sometimes comes across). Eliott65 reconstructs long names of up to 64 characters, checking their
order and their checksum, and accepts either form, regardless of case.
On the board, an unpleasant surprise: launching a program took more than 5 seconds. Looking up a name reread the directory from the start for every entry; with 427 entries and a single sector in memory, that meant thousands of USB reads. A traversal cursor, which reads each sector only once, brings the lookup down to 50 ms.
Writing, carefully
The 6502 can create, replace and delete files (the ECRIRE and SUPPRIMER functions). The module allocates clusters, updates all copies of the FAT, extends a full directory by one cluster, and follows a careful write order:
- the data;
- the FAT;
- the directory entry;
- freeing the old chain (when replacing);
- the free-space information.
The value of this order showed up in the emulator: by yanking out the stick during a write, at many different moments, the worst outcome is minor damage (a lost cluster, FAT copies that differ), never two files sharing a cluster. The same test revealed a real defect, now fixed: a failed FAT read was taken for a full disk.
First file written by the 6502 on the real stick: JOURNAL.TXT, “ECRIT PAR LA 6502 A
T=$01D1226E US”, read back identically and checked independently from the PC.
Checked by independent tools
The tests do not trust the module itself. The disk images are created by mkfs.fat, checked by
fsck.fat, and read back by a separate FAT reader written in Python. Difficult cases go in: a
fragmented file, a subdirectory, a long name, a deleted entry, a directory filled until it refuses
more, FAT12 entries straddling two sectors.
What about floppy disks?
FAT12 is ready, tested on 1.44 MB floppy disk images. The hardware remains: many USB floppy drives speak a different protocol from USB sticks (UFI over CBI instead of Bulk-Only). The drive will have to be plugged in to find out.
To go further: Hibernation, which writes the whole of the 6502’s memory to a file.