Lecteur/Écrivain de disquettes Amiga sur Arduino – Version 2.2
Composants et fournitures
- 1 × Arduino UNO
- 1 × Arduino Pro Mini 328 – 5V/16MHz (SparkFun)
- 1 × Résistance 1 kΩ
- 1 × Plaque d'essai (breadboard)
- 1 × Fils de connexion (générique)
- 1 × Convertisseur FTDI Basic Breakout – 5V (SparkFun)
Applications et services en ligne
- Arduino IDE
À propos de ce projet
Ce projet prolonge mon précédent lecteur de disquettes : Projet original.
Plus d'informations : amiga.robsmithdev.co.uk
- Objectif : Créer une solution simple, peu coûteuse et open source pour lire et réécrire des disquettes Amiga DD (Double Density) depuis Windows 10.
- Solution : Un sketch Arduino + une application Windows (portable sur d'autres OS) qui fonctionne réellement !
- Pourquoi : Préserver les données de ces disquettes pour l'avenir. Un PC standard ne peut pas lire/écrire les disquettes Amiga à cause de leur encodage spécifique.
Écriture des données – Tentative 1
Après avoir réussi la lecture, j'ai voulu permettre la réécriture. J'ai commencé par le logiciel : conversion de fichiers ADF (images disque Amiga) en données MFM pour l'interface d'écriture.
J'ai ajouté des classes pour lire un ADF et encoder toutes les pistes. En testant l'encodage via le décodeur, j'ai profité pour réparer mon Amiga A500+ : batterie horloge qui avait fui, nettoyage complet, Retr0brite pour le jaunissement, ressoudure d'une connexion lâche près du connecteur d'alimentation.
Côté code, la lecture de la ligne /WRITE_PROTECT ne fonctionnait qu'après avoir mis /WRITE_GATE à LOW avant de faire tourner le moteur. Une piste Amiga fait 11 × 512 octets (5632 octets), mais après encodage MFM et format AmigaDOS : 14 848 octets – impossible à stocker dans la RAM (2 Ko) ou l'EEPROM (1 Ko) de l'Arduino.
J'ai tenté l'envoi octet par octet via un thread haute priorité (baud 2M) avec acquittement. Échec total : cycle lecture/écriture trop long, bien au-delà d'une révolution du disque. Le côté Arduino était assez rapide, mais l'OS (Windows) n'était pas assez réactif.
Écriture des données – Tentative 2
Contrôle de flux logiciel trop lent. J'ai exploré le contrôle de flux matériel via les broches CTS/DTR du FTDI. La broche CTS, reliée à GND par la carte Arduino, peut être pilotée par l'Arduino pour réguler le flux depuis le PC.


L'Arduino met CTS à '1' pour stopper le flux, '0' pour l'autoriser. J'ai espéré que l'envoi en bloc par l'OS soit géré au niveau noyau sans interruption. J'ai déroulé la boucle d'écriture de 8 bits en 8 instructions distinctes pour le timing. Échec : sans écriture disque, tous les octets sont reçus ; avec l'écriture, des octets sont perdus. Le changement d'état de CTS n'arrête pas instantanément le flux – l'ordinateur envoie encore 1-2 octets.
Écriture des données – Tentative 3
Pas d'interruption série (pour ne pas perturber le timing). J'ai vérifié entre chaque bit si un octet supplémentaire était arrivé depuis la montée de CTS, et je le stockais. Théorie : quand CTS monte, l'ordinateur est déjà en train d'émettre l'octet suivant – on ne peut l'arrêter qu'après. Il suffit donc de vérifier un seul octet supplémentaire par boucle.
Ça a marché : l'Arduino termine l'écriture sans perte. Mais les données écrites sont-elles valides ? J'ai encodé les 80 pistes. Problème : la tête ne bougeait pas en écriture (alors qu'elle bougeait en lecture). J'ai découvert qu'il faut relever /WRITE_GATE avant de déplacer la tête – mesure de sécurité contre l'écriture accidentelle pendant le déplacement.
J'ai écrit une image disque, puis tenté de la relire : rien de détectable. Soit les données écrites sont invalides, soit la méthode d'écriture est fautive. J'ai validé l'encodage MFM via mon algorithme de décodage : il est correct. Le problème vient de l'écriture physique.
Écriture des données – Tentative 4
Comment piloter la broche /WRITE_DATA ? Impulsion ? Bascule ? Valeur brute ? Mon implémentation pulsait la broche. J'ai testé : valeur directe du bit → échec. Bascule d'état → échec. Il faut trouver la bonne méthode.
J'ai utilisé l'oscilloscope : écriture du motif MFM 0xAA (binaire 10101010) sur toute une piste → devrait donner une onde carrée parfaite à 500 kHz. Les timings étaient parfaits, mais en mode « mag » x10, j'ai vu une période « haute » toutes les ~12 bits. 12 bits est étrange (8 bits/octet).

Problème de contrôle de flux ? Ma boucle récupérait les octets parasites mais n'évitait pas l'attente tous les deux octets. Deux solutions : interruption ou correction de la boucle. J'ai corrigé la boucle : après avoir utilisé le second octet reçu, l'Arduino abaisse puis relève brièvement CTS pour autoriser l'envoi du suivant. Ainsi, au tour suivant, l'octet est déjà là – plus d'attente.
Résultat : onde carrée parfaite !

Le timing est bon, reste les données réelles. J'ai écrit quelques pistes avec /WRITE_DATA = valeur du bit. Lecture : rien sur la face 0, mais le motif apparaît sur la face 1. Pourquoi une seule face ?
Hypothèse : /WRITE_GATE active la tête d'effacement. Si on le maintient bas pendant la rotation, on efface la piste en créant du bruit. J'ai modifié le code : /WRITE_GATE bas uniquement au démarrage du moteur et pendant la boucle d'écriture effective. Ça marche ! Écriture sur les deux faces.
Test avec une vraie image ADF : écriture terminée, lecture via le lecteur → fonctionne ! Mais lecture lente, difficulté à trouver tous les secteurs (pas d'erreurs MFM). Deux pistes : écriture pas assez précise, ou disque incompatible avec un vrai Amiga.
Test sur l'A500+ réparé : le disque démarre puis affiche l'erreur de checksum célèbre. J'écris quelque chose de valide mais pas cohérent. Inutile d'écrire si la relecture n'est pas fiable.
Relecture des données (amélioration)
L'implémentation actuelle manquait de tolérance sur le timing des impulsions. Nouvelle approche : synchronisation sur l'impulsion /INDEX (non requis par l'Amiga mais utile pour les tests).
Suggestion des commentaires : enregistrer les intervalles entre impulsions au lieu de ma méthode. Problème : envoyer un octet par bit dépasse le baud 2M. Solution : faire un peu de traitement sur l'Arduino. Laisser le compteur tourner librement jusqu'à 255, attendre une impulsion, lire le compteur.
- Minimum théorique : 32 (2 µs)
- Maximum MFM (trois zéros max) : 128
- 4 combinaisons possibles
Échantillonnage sur plusieurs disques : majorité autour de 52, 89, 120 (spécifique à mon lecteur). Formule adoptée : value = (COUNTER - 16) / 32, borné entre 0 et 3. Tous les 4 valeurs → 1 octet envoyé.
En MFM, deux '1' ne peuvent pas se suivre. Donc une première valeur '1' est invalide → traitée comme '01'. Dépaquetage côté PC : 01 → '01', 10 → '001', 11 → '0001'. Résultat : 100 % de succès sur plusieurs disques. Lecteur très fiable, peu de retentatives. Analyse statistique des erreurs : 99 % des données corrompues sont méconnaissables, peu utiles pour la réparation.
Écriture des données – Tentative 5
Avec une lecture fiable, test de l'écriture facilité. J'ai écrit 0x55 sur une piste complète et relu : décalage occasionnel d'un bit → problème de timing.
Causes : gestion du port série + utilisation du timer. J'attendais que le timer atteigne 32, écrivais le bit, puis le remettais à zéro. Modification : écrire le 1er bit à 16, le suivant à 48 (16+32), puis 80, etc. Timer2 (8 bits) reboucle à 0 après le 8e bit – exactement au bon moment. Ainsi, tant qu'on écrit au bon compteur, on a exactement 500 kbps.
Optimisation de la lecture série entre les bits (bloc le plus court possible). Après modification du code Windows pour supporter la vérification : ~95 % des pistes passent la vérification du premier coup, 5 % réécrites une fois. Disque testé sur l'Amiga : fonctionne parfaitement !
Écriture des données – Tentative 6
Retours utilisateurs : même avec vérification, certains disques lisibles par le logiciel donnent des erreurs de checksum sur l'Amiga. Problème de timing ? Interruptions impossibles (temps insuffisant entre bits pour sauver les registres).
Analyse du code : après l'écriture d'un octet complet, la boucle pouvait repartir avant que le timer ne revienne à 0, écrivant le premier bit du prochain octet trop tôt. Ajout d'une petite boucle d'attente pour empêcher cela. Espère corriger le problème.
Écriture des données – Tentative 7
Nombreux rapports d'erreurs de checksum. Je pensais devoir analyser les données MFM brutes, mais le problème était plus simple.
XCopy Pro signalait codes 4 et 6 (checksum en-têtes et données). Si seulement données → dernier bits de piste. Mais les deux sont touchés.
J'ai regardé le padding entre pistes : je l'ai réduit de 256 à 8 octets → la vérification a rejeté massivement. Donc le problème n'est pas « trop de padding » mais pas assez de données écrites.
Ajout d'une commande « Effacement de piste » : écriture du motif 0xAA sur toute la piste, puis écriture de ma piste. Résultat : XCopy donne 100 % OK. Problème résolu.
Diagnostics
Beaucoup de retours (succès et échecs). Ajout d'un module de diagnostic dans le code : commandes supplémentaires pour l'Arduino + séquence de tests pour vérifier le câblage.
Et maintenant ?
Projet entièrement libre et open source (GPL v3). Pour préserver l'Amiga, pas de guerre commerciale. Je veux rendre à la meilleure plateforme sur laquelle j'ai travaillé. J'espère que d'autres le feront évoluer et partageront.
- L'écriture sur Arduino UNO nécessite un FTDI/série séparé. Prochaine étape : le faire fonctionner sur UNO seul (peut-être avec un buffer 23K256 pour stocker la piste avant écriture).
- Autres formats : ADF ne gère que l'AmicaDOS. Beaucoup de titres ont des protections copies/format non standard. Infos reçues, mais peu de disques de test.
- Format FDI (Wikipedia) : format universel bien documenté, stocke les données au plus près de l'original → pourrait résoudre les problèmes. Préoccupation : intégrité des données (pas de checksums). Idées en cours.
- Société de Préservation Logicielle / CAPS / format IPF : tout est fermé, semble servir à vendre du matériel. Je me concentre sur FDI.
Code
Sketch Arduino et application Windows
GitHub : ArduinoFloppyDiskReader
Schémas
Circuit pour Arduino Pro Mini
Circuit pour Arduino UNO
Processus de fabrication
- L'Évolution et l'Art de l'Animation
- L'Évolution des Disquettes : Du Support Magnétique au Stockage Optique
- Affichage LED Interactif Gyroscopique avec Anneau NeoPixel et Arduino
- Construire un Spybot Arduino piloté par Bluetooth
- FlickMote : Télécommande IR à gestes pour maison connectée
- TV-B-Gone DIY Arduino : Télécommande universelle pour toutes les TV
- Manette de jeu USB Arduino DIY – Construisez votre propre gamepad haute performance
- Costume nuage DIY : Bandeau LED, Arduino Nano et pièces SparkFun
- Lecteur de disquettes Amiga basé sur Arduino : Récupération de données open-source et abordable