Arduino-basierter Amiga Floppy Disk Reader & Writer – Version 2.2
Komponenten und Zubehör
| Arduino UNO | × | 1 |
| SparkFun Arduino Pro Mini 328 - 5V/16MHz | × | 1 |
| Widerstand 1k Ohm | × | 1 |
| Steckbrett (generic) | × | 1 |
| Jumper Kabel (generic) | × | 1 |
| SparkFun FTDI Basic Breakout - 5V | × | 1 |
Apps und Online-Dienste
- Arduino IDE
Projektbeschreibung
Dieses Projekt setzt die Arbeit meines vorherigen Disk-Reader-Projekts fort: Projekt-Link
Weitere Informationen: https://amiga.robsmithdev.co.uk
- Ziel: Eine einfache, günstige und Open-Source-Methode, um Daten von und auf Amiga DD-Disketten unter Windows 10 zu lesen und zu schreiben.
- Lösung: Ein Arduino-Sketch + eine Windows-Anwendung (portierbar auf andere OS), die tatsächlich funktioniert!
- Grund: Daten dieser Disketten für die Zukunft bewahren. Normale PCs können Amiga-Disketten nicht lesen/schreiben, wegen des speziellen Schreibverfahrens.
Daten schreiben – Versuch 1
Nach erfolgreichem Lesen wollte ich Disketten auch wieder beschreiben, um das Originalmedium zu erhalten. Ich begann umgekehrt: Software-seitig ADF-Disk-Images in MFM-Daten umwandeln, die das Interface irgendwie schreiben kann.
Zuerst Klassen zum Lesen von ADF-Disks und Kodieren aller Sektoren als eine Spur hinzugefügt. Da ich die erzeugten Daten durch Rückführung in den Decoder testen konnte, begann ich damit. Parallel untersuchte ich, was mit meinem Amiga nicht stimmte – ohne echte Hardware lassen sich erstellte Disks nicht testen.
Mein A500+ auseinandergebaut: Die Pufferbatterie war ausgelaufen. Diese ausgelötet, Platine gereinigt, 20 Jahre Staub entfernt, sogar das Laufwerk zerlegt und gereinigt. Vergilbung mit Retr0brite behandelt. Alle Lötstellen geprüft – lose Verbindung am Stromanschluss gefunden und nachgelötet. Nach Abschluss der Retr0brite-Behandlung wieder zusammengebaut.
Parallel am Schreib-Code gearbeitet. Schreibschutz-Status auslesen wollte ich, aber die Spannung änderte sich nie. Laufwerk zerlegt, Leiterbahnen vom Schreibschutz-Schalter zu einem IC verfolgt. Vermutung: Output nur verfügbar, wenn tatsächlich geschrieben wird.
Nach viel Experimentieren: /WRITE_GATE Pin auf LOW ziehen bevor das Laufwerk hochfährt, um Schreiben zu aktivieren. Erst dann war der Schreibschutz-Status auslesbar. Auch: Solange /WRITE_GATE LOW ist, schaltet das Laufwerk nicht ab wie sonst.
Der Amiga schreibt eine ganze Spur auf einmal. Eine Spur im Speicher: 11×512 Bytes (5638 Bytes), nach MFM-Kodierung und AmigaDOS-Format: 14848 Bytes. Passt nicht in Arduinos 2k RAM noch 1k EEPROM. Alternative nötig.
Versuch: Daten Byte für Byte in High-Priority-Thread senden, auf Antwort-Byte warten. Baudrate auf 2M erhöht. Ca. 5,5 µs pro Zeichen senden/empfangen. Arduino muss 8 Bit bei 500 kHz schreiben → neues Byte alle 16 µs. Theoretisch machbar, wenn Code-Schleife eng genug und OS nicht zu sehr verzögert.
Völliger Fehlschlag. Ganzer Lese/Schreib-Zyklus dauerte viel zu lange, weit über einer Diskettenumdrehung. Arduino-Seite war schnell genug, aber OS nicht responsiv genug. Lesen funktioniert, weil OS eingehende Daten puffert. Schreiben: Windows sendet alles auf einmal, aber Rate ist schneller als Arduino verträgt → Datenverlust. Daher Zwei-Wege-Bestätigung.
Daten schreiben – Versuch 2
Software-Flowcontrol zu langsam. Hardware-Flowcontrol untersucht. Auf FTDI-Breakout: CTS und DTR Pins (Clear To Send, Data Terminal Ready). CTS war mit GND verbunden.


CTS-Pin kann vom Arduino signalisiert und vom PC zur Flowcontrol genutzt werden. Normalerweise Ringpuffer, aber hier: CTS auf '1' wenn keine Daten gewünscht, '0' während Daten erwünscht.
Nun konnte OS Bytes als Block senden, hoffentlich auf Kernel-Ebene ohne Unterbrechung.
Innerste Schleife gab jedes Bit aus 8 Bits aus, aber Timing-besser: In 8 Befehlssätze auflösen.
Funktionierte nicht. Ohne Schreib-Code liefen alle Bytes korrekt durch, mit Schreib-Code gingen Bytes verloren.
Verdacht: CTS-Statusänderung stoppt Datenfluss nicht sofort – PC sendet noch 1-2 Zeichen. Möglicherweise war beim Signalisieren bereits nächstes Zeichen im Versand.
Daten schreiben – Versuch 3
Kein Serial-Interrupt gewollt (Timing-Verzerrung). Zwischen jedem Bit-Schreiben auf Diskette CPU-Zyklen in Warteschleife. Idee: Prüfen, ob nach CTS-High ein weiteres Byte empfangen wurde, und zwischenspeichern.
Theorie: Wenn CTS high geht, war PC vermutlich mitten in der Übertragung des nächsten Bytes – kann nicht mittendrin stoppen. Also nur ein Extra-Byte pro Schleife prüfen und falls vorhanden nutzen statt Serial-Port erneut abzufragen.
Funktionierte – Arduino schrieb ohne Datenverlust. Frage: Wurde tatsächlich geschrieben? Und falls ja, sind Daten valide?
Bisher nur eine Spur kodiert. Gesamten Algorithmus für alle 80 Spuren laufen lassen. Merkwürdig: Laufwerkskopf bewegte sich gar nicht. Beim Lesen schon, beim Schreiben nicht.
Gefunden: Um Kopf zu bewegen, muss /WRITE_GATE Pin erst auf HIGH gehen. Vermutlich auch für Seitenwechsel nötig. Code ergänzt → Kopf bewegt sich wie erwartet. Verhindert versehentliches Schreiben während Kopfbewegung.
Vorher erstelltes Disk-Image geschrieben, dann zurückgelesen. Nichts detektiert! Entweder Daten ungültig oder Schreibverfahren falsch.
Erzeugte MFM-Sektordaten in Decoder-Algorithmus des Readers eingespeist zur Validierung – Daten waren korrekt. Problem lag also am physischen Schreiben.
Daten schreiben – Versuch 4
Keine Daten korrekt lesbar → verschiedene Ansätze getestet. Unklar: Soll /WRITE_DATA gepulst (wie lange?), getoggled oder auf Rohdatenwert gesetzt? Aktuelle Implementation pulsierte den Pin.
Keine Info online gefunden, wie Write-Pin physikalisch beim Schreiben manipuliert werden soll.
Lesekopf sendet Puls bei jedem Flusswechsel. Implementation geändert: WRITE_DATA auf Bitwert setzen. Nicht funktioniert. Dann: Pin-Zustand togglen. Auch kein Erfolg.
Einer muss richtig sein. Oszilloskop rausgeholt. MFM-Muster 0xAA (Binär B10101010) auf ganze Spur kontinuierlich geschrieben → perfekte Rechteckwelle zum Frequenz-Check.

Timings waren perfekt. Aber altes Oszilloskop zeigte nur wenige Pulse. x10 "Mag"-Modus: Zeitbasis ×10, Daten durchscrollbar wie modernes Digital-Oszilloskop.
Alle ~12 Bit eine Periode nur "High". 12 ist merkwürdig (8 Bit pro Byte).
Überlegung: Flowcontrol-Problem? Schleife fing verlorene Bytes nach Wait auf, aber nicht intelligent genug, Wait jedes 2. Byte zu verhindern. Zwei Optionen: Was in Interrupt verschieben, oder Schleife patchen.
Erst Schleife korrigieren versucht. Problem: Delay durch Warten auf nächstes Byte vom PC. Wenn CTS low und auf Byte gewartet, war beim CTS-high schon nächstes Byte unterwegs.
Schleife geändert: Nachdem 2. empfangenes Byte genutzt wurde, Arduino CTS kurz low dann high ziehen → nächstes Zeichen darf gesendet werden. Nächste Schleife: Byte schon da, kein Warten nötig.
Test → perfekte Rechteckwelle:

Timing für Spur-Schreiben perfekt. Nur noch eigentliche Daten.
Ein paar Spuren und Seiten laufen lassen, zurücklesen. /WRITE_DATA auf Bitwert gesetzt.
Beim Zurücklesen: Nichts kodiert. Andere Disk-Seite prüfen → Muster da! Warum nur eine Seite?
Nachdenken: /WRITE_GATE funktioniert anders als gedacht. Pin LOW ziehen könnte Radierkopf aktivieren. Wenn ja: Nur beim tatsächlichen Schreiben nutzen, sonst Rauschen beim Drehen.
Code geändert: /WRITE_GATE nur beim Starten des Laufwerks und buchstäblich nur während der Schreib-Schleife. Funktionierte! Jetzt auf beiden Seiten geschrieben.
Echtes ADF-Disk-Image schreiben lassen, fertig. Reader-Teil zum Zurücklesen genutzt. Funktionierte! Aber Lesen dauerte lange. Keine MFM-Fehler, aber Sektoren schwer zu finden.
Zwei Möglichkeiten: 1) Daten timely genug geschrieben? 2) Funktioniert Disk in echtem Amiga?
Repariertes A500+ gebootet, Disk eingelegt. Disk bootete, dann berühmte Checksum-Fehlermeldung. Etwas Valides geschrieben, aber nicht konsistent.
Entscheidung: Solange Daten nicht mit viel höherer Genauigkeit zurücklesbar, ist Schreiben sinnlos.
Daten lesen (erneut)
Lesequalität verbessern – aktuelle Implementation nicht flexibel genug für leicht versetzte Pulsankunft. Neuer Ansatz nötig.
- Lesen an /INDEX-Puls synchronisieren. Nicht von Amiga gefordert, aber hilfreich für Test/Write/Read.
- Kommentare zum ersten Projektteil schlugen vor: Zeitabstände zwischen Pulsen aufzeichnen statt bisheriger Methode. Problem: Daten schnell genug zum PC. Wenn Byte pro Bit → 2M Baud leicht überschritten.
- Daten etwas verstehen lassen. Counter frei laufen lassen bis 255. In Schleife auf Puls warten, dann vergangene Zeit prüfen.
- Ideal: Minimum 32 (2 µs). MFM: max drei 0er hintereinander → Maximum 128. Max 4 Kombinationen hintereinander.
- Mehrere Disks gesampelt, Frequenzverteilung:

Mehrheit Punkte bei Counter 52, 89, 120 – laufwerks-spezifisch, keine gute Richtlinie. Nach Experimenten Formel: value = (COUNTER - 16) / 32. Geklippt zwischen 0 und 3 → gewünschter Output. Je 4 Werte → 1 Byte.
Da MFM keine zwei '1' hintereinander erlaubt: Erster Wert ungültig → als weiteres '01' behandeln. Entpacken auf PC: 00 unmöglich, 01 → '01', 10 → '001', 11 → '0001'. Ausprobiert → 100% Erfolg! Mehrere Disks: 100%! Sehr zuverlässiger Disk-Reader.
Neuer Ansatz toleranter → keine Phasenanalyse, weniger Retries nötig. Meiste Disks perfekt, manche paar Retries. Letzter Teil: Statistische Analyse zur Reparatur, aber 99% schlechter Daten völlig unerkennbar → wenig Hilfe.
Daten schreiben – Versuch 5
Mit hochgenauer Verifikation Writer testen.
Code analysiert: 0x55 auf ganze Spur schreiben, zurücklesen. Ab und zu Bit verschoben → Timing-Problem beim Schreiben.
Teilweise durch Serial-Handling, teilweise durch Timer-Nutzung. Warte auf Timer-Wert 32, schreibe Bit, setze Timer zurück. Geändert: Timer-Counter nicht modifizieren.
Erstes Bit bei Counter 16, nächstes bei 48 (16+32), nächstes bei 80 (16+32+32)… Timer2 8-bit → Überlauf nach 8. Bit genau bei 0, genau 500 kbps. Solange Bit bei erforderlichem Timer-Wert geschrieben → exakt.
Serial-Port-Auslesen zwischen Bits → so kurz wie möglich. Nach Experimenten kürzester funktionsfähiger Block.
Windows-Code für Verify erweitert. Bereit für neuen Versuch. Wenn Disk Verify besteht → sollte im Amiga funktionieren.
Noch eine Disk geschrieben. Mit Verify länger. Neuer Algorithmus: ~95% Spuren bestanden Verify beim 1. Mal, restliche 5% einmal neu schreiben. Zufrieden. Disk in Amiga → funktionierte perfekt!
Daten schreiben – Versuch 6
Feedback: Auch mit Verify nicht immer vollständig lesbare Disks. Software liest perfekt zurück, Amiga meldet paar Checksum-Fehler.
Code geprüft: Timing-Problem? Interrupt-getrieben? Leider nicht genug Zeit zwischen Bits für Interrupts mit Register-Erhalt.
Schreib-Code angeschaut: Kleine Chance, dass nach vollem Byte Code zur nächsten Byte-Schleife zurückspringt bevor Timer auf 0 überlief → erstes Bit zu früh.
Kleine Schleife ergänzt, um dies zu verhindern → hoffentlich Fix für Betroffene.
Daten schreiben – Versuch 7
Viele Berichte über Checksum-Fehler bei geschriebenen Disks. Untersuchung gestartet. Erst MFM-Daten vom Laufwerk vermutet, aber Problem simpler.
XCopy Pro Checksum-Fehler: Codes 4 und 6 → Sektor-Header und Datenbereiche. Nur Datenbereich → letztes Bit der Spur. Aber beide Bereiche betroffen.
Schreib-Code und Padding um jede Spur geprüft – Überschreibe ich Spur-Anfang? Post-Track-Padding drastisch reduziert: 256 Bytes → 8 Bytes. Überraschung: Verify spuckte massenhaft Fehler.
Verdacht: Nicht genug Daten geschrieben. Track Erase Command für Arduino: 0xAA-Muster auf ganze Spur schreiben, dann eigene Spur. XCopy: 100% Daumen hoch! Problem hoffentlich gelöst.
Diagnose
Viel Feedback von Leuten, die Projekt nachbauten – teils fully working, teils nicht. Diagnose-Modul in Code integriert.
Diagnose-Option: Zusätzliche Befehle für Arduino + Event-Serie zur Prüfung der Verkabelung.
Was kommt als Nächstes?
Gesamtes Projekt frei und Open Source unter GNU GPL V3. Amiga-Erhaltung: Nicht gegenseitig ausnehmen. Zurückgeben an beste Plattform, an der je gearbeitet. Hoffe auf Weiterentwicklung und Sharing.
Aktuelle Schreib-Lösung auf Arduino UNO nur mit separatem FTDI/Serial-Breakout möglich. Nächste Aufgaben: Auf UNO lauffähig machen (evtl. 23K256 IC als Spur-Puffer vor Schreiben).
Andere Formate prüfen. ADF nur für AmigaDOS-formatierte Disks. Viele Titel mit Custom-Copy-Protection und non-standard Sektoren → ADF nicht unterstützbar. Infos erhalten, aber wenige Test-Disks.
Wikipedia: FDI-Format – universelles, gut dokumentiertes Format. Vorteil: Spurdaten so nah wie möglich am Original → löst obige Probleme!
Software Preservation Society / CAPS / IPF-Format kennengelernt. Enttäuschend: Alles closed, Format dient zum Verkauf ihrer Hardware.
Fokus auf FDI-Format. Sorge: Datenintegrität ohne Checksums. Aber Ideen dazu vorhanden!
Code
Sketch und Windows Application Source
Arduino Sketch und Beispiel-Windows-Anwendung Quellcode: GitHub Repository
Schaltpläne
Schaltung für Arduino Pro Mini:

Schaltung für Arduino UNO:

Herstellungsprozess
- Die Entwicklung und Kunst der Animation
- Die Entwicklung der Disketten: Von magnetischen Medien zu optischer Speicherung
- Interaktives Gyroskop-LED-Display mit NeoPixel-Ring & Arduino
- Bluetooth-gesteuerter Arduino-Spybot bauen – Überwachungsroboter mit IP-Kamera
- FlickMote: Gestensteuerung per Ultraschall & IR für Smart Home (Arduino 101)
- DIY Arduino TV-B-Gone: Universelle TV-Aus-Fernbedienung
- DIY Arduino USB Gaming Controller – Bauen Sie Ihren eigenen High-Performance Gamepad
- DIY Wolken-Kostüm: LED-Streifen, Arduino Nano & SparkFun Teile
- Einen eigenen LED-Master-Clock mit Alarm bauen – aus 12 Metern Entfernung ablesbar
- Arduino-basierter Amiga-Floppy-Lesegerät: Günstige Open-Source-Datenrettung