Aller au contenu
Eliott65wiki
Sommaire

Les fichiers : FAT12, FAT16 et FAT32

Lire et écrire les fichiers d’une clé USB, ou d’une disquette demain, avec un module écrit pour le projet : 7 Kio de code et un seul tampon de 512 octets.

Dans cette page

Un module, trois formats

Les clés USB sont presque toujours formatées en FAT32, les disquettes en FAT12. Eliott65 gère les trois variantes (FAT12, FAT16, FAT32) avec un seul module, écrit en C portable pour le projet. Il occupe environ 7 Kio de code et travaille avec un seul secteur en mémoire (512 octets).

Le type est déterminé comme le prescrit Microsoft, par le nombre de clusters : moins de 4 085, c’est du FAT12 ; moins de 65 525, du FAT16 ; au-delà, du FAT32. Le module reconnaît une table de partitions, ou un disque sans partition, comme une disquette.

Lancer un programme depuis la clé

Le service FICHIERS sait lister un répertoire, lire un fichier directement dans la mémoire de la 6502, et surtout EXECUTER un programme .E65 :

  1. la 6502 est gelée ;
  2. le programme est chargé à sa place, dans la mémoire de la 6502 ;
  3. la 6502 redémarre dessus.

Aucun chargeur ne reste en mémoire. En cas d’échec avant le chargement (fichier absent, mauvais format), la 6502 reprend simplement avec un code d’erreur.

Premier aller-retour réussi, entièrement depuis la clé : le shell lance BONJOUR.E65, qui affiche « B O N J O U R ! », puis relance le shell sur une touche.

Les noms longs, et un algorithme quadratique

Sur une clé, un fichier comme late.neo6502 est rangé sous deux formes : un nom long, découpé en morceaux de 13 caractères, et un nom court au format 8.3, généré (d’où les noms en ~1 qu’on croise parfois). Eliott65 reconstitue les noms longs jusqu’à 64 caractères, en vérifiant leur ordre et leur somme de contrôle, et accepte l’une ou l’autre forme, sans tenir compte des majuscules.

Sur la carte, une mauvaise surprise : lancer un programme prenait plus de 5 secondes. La recherche d’un nom relisait le répertoire depuis le début pour chaque entrée ; avec 427 entrées et un seul secteur en mémoire, cela faisait des milliers de lectures USB. Un curseur de parcours, qui lit chaque secteur une seule fois, ramène la recherche à 50 ms.

Écrire, prudemment

La 6502 peut créer, remplacer et supprimer des fichiers (fonctions ECRIRE et SUPPRIMER). Le module alloue les clusters, met à jour toutes les copies de la FAT, agrandit un répertoire plein d’un cluster, et suit un ordre d’écriture prudent :

  1. les données ;
  2. la FAT ;
  3. l’entrée de répertoire ;
  4. la libération de l’ancienne chaîne (en cas de remplacement) ;
  5. les informations d’espace libre.

L’intérêt de cet ordre s’est vu dans l’émulateur : en arrachant la clé pendant une écriture, à de nombreux instants, on n’obtient au pire que des dégâts bénins (un cluster perdu, des copies de FAT différentes), jamais deux fichiers qui se partagent un cluster. Le même essai a révélé un vrai défaut, corrigé : une lecture de FAT en échec était prise pour un disque plein.

Premier fichier écrit par la 6502 sur la vraie clé : JOURNAL.TXT, « ECRIT PAR LA 6502 A T=$01D1226E US », relu à l’identique et vérifié indépendamment depuis le PC.

Vérifié par des outils indépendants

Les tests ne font pas confiance au module lui-même. Les images de disque sont créées par mkfs.fat, contrôlées par fsck.fat, et relues par un lecteur FAT écrit à part, en Python. On y met des cas difficiles : fichier fragmenté, sous-répertoire, nom long, entrée supprimée, répertoire rempli jusqu’au refus, entrées FAT12 à cheval sur deux secteurs.

Et les disquettes ?

Le FAT12 est prêt, testé sur des images de disquettes de 1,44 Mo. Reste le matériel : beaucoup de lecteurs de disquettes USB parlent un autre protocole que les clés (UFI sur CBI au lieu de Bulk-Only). Il faudra brancher le lecteur pour le savoir.

Pour aller plus loin : L’hibernation, qui écrit toute la mémoire de la 6502 dans un fichier.

Sources dans le dépôt : docs/journal/10-fichiers.md, docs/adr/ADR-0010-fat32-et-execution.md, docs/adr/ADR-0012-ecriture-fat32.md, docs/adr/ADR-0013-fat12-fat16.md.