Arduino-gebaseerde Amiga-floppylezer: Goedkope open-source dataherstel
Onderdelen en benodigdheden
| Weerstand 1kΩ | 1 |
| Breadboard | 1 |
| Draadjes (jumper wires) | 1 set |
| Breadboard voeding 5V/3.3V (SparkFun) | 1 |
| Arduino UNO (of Pro Mini) | 1 |
Apps en online services
- Arduino IDE
Over dit project
Doel: Een eenvoudige, goedkope en open-source manier om data van Amiga DD-floppies (double density) uit te lezen onder Windows 10 en andere besturingssystemen.
Oplossing: Een Arduino gecombineerd met een Windows-applicatie.
Waarom: Om data van deze schijven te bewaren voor de toekomst. Een standaard PC kan Amiga-schijven niet lezen vanwege de unieke schrijfwijze (MFM-codering, 80 tracks, 11 sectoren per track, 512 bytes/sector). Commerciële oplossingen als KryoFlux of Catweasel zijn duur en vaak closed-source.
Amiga-ervaringen
Mijn carrière moet ik danken aan de Amiga, specifiek de A500+ die mijn ouders me gaven op mijn 10e verjaardag. Ik begon met spelletjes, maar ontdekte snel Deluxe Paint III en Workbench. Ik won ooit een wedstrijd van Amiga Format met een spel geschreven in AMOS Professional.
Achtergrond
Jaren later had ik dozen vol schijven en een defecte A500+. Ik wilde de schijven back-uppen voor preservatie en nostalgie. Bestaande hardware-oplossingen waren niet compatibel met moderne hardware of te duur. Toen ik ontdekte hoe makkelijk Arduino is (dankzij GreatScott), vroeg ik me af of het mogelijk was. Er bestond toen geen Arduino-oplossing voor het uitlezen van floppies – alleen projecten die drives misbruikten om muziek te spelen. Dus bouwde ik het zelf.
Onderzoek
Belangrijke bronnen:
- techtravels.org
- .ADF-formaat FAQ (Laurent Clévy)
- Amiga Forever
- Wikipedia – Amiga Disk File
- English Amiga Board
- QEEWiki – Counters op ATmega168/328
- Floppy drive pinout
- Lijst van floppy-formaten
Aannames en berekeningen
Een DD-schijf draait op 300 RPM. Data is opgeslagen als 80 tracks × 11 sectoren × 512 bytes, gecodeerd met MFM. Om de data accuraat te samplen had ik een sample-frequentie van 500 kHz nodig – uitdagend voor een 16 MHz Arduino.
Poging 1: Shift registers (SN74HC594N)
Eerste idee: twee 8-bit shift registers om de sample-frequentie met factor 8 te verlagen. Een Pro Mini (ATmega328) buffert de parallele data en stuurt het via USART (2 Mbps) naar de PC. De code werkte, maar de ontvangen data was niet betekenisvol. Ik had een oscilloscope nodig om het signaal te analyseren.
Poging 2: Interrupt-gebaseerd uitlezen
Shift registers verwijderd, direct uitlezen via interrupt (ISR) op 500 kHz. Maar de ISR was te langzaam – meer instructies dan de tijd tussen pulsen. digitalRead() was te traag; directe poorttoegang hielp niet genoeg. De oscilloscope (Gould OS300 20 MHz) toonde aan dat mijn 500 kHz klok perfect was, maar het floppy-signaal had drift en gaten (sector-gaps). Synchronisatie was het probleem.
Poging 3: Hardware counter (Timer0)
Gebruik de hardware counter van Timer0 om pulsen te tellen. De 500 kHz timer (Timer2) wordt gereset bij de eerste puls. Bij elke overflow check ik of er een puls was. Data kwam binnen, maar nog steeds onbetrouwbaar – checksum-fouten bleken.
Poging 4: Software Phase-Locked Loop (PLL)
Het signaal liep uit de fase. Een PLL past de klokfrequentie dynamisch aan. De timer-resolutie was te grof voor fijne aanpassingen. Oplossing: bij detectie van een puls, reset de timer-counter naar een vaste fase-positie (1 µs na de puls). Dit hield de synchronisatie stand – data werd nagenoeg perfect gelezen. Checksum-fouten werden opgelost door tracks herhaaldelijk te lezen tot alle 11 sectoren geldig waren.
Poging 5: Interrupt voor nauwkeurige re-sync
De re-sync in de main-loop had jitter. Oplossing: data-puls ook aan INT0-pin koppelen (hoogste interrupt-prioriteit). Een ISR_NAKED interrupt handler met inline assembly verkleinde de ISR tot 5 instructies (0,3125 µs). Dit verbeterde de betrouwbaarheid verder.
Poging 6: Schmitt-trigger (SN74HCT14N)
Een 1kΩ pull-up met Schmitt-trigger voor schoner signaal. Maakte geen merkbaar verschil – de methode van poging 5 absorbeerde ruis al voldoende.
Poging 7: MFM-foutdetectie
Regels van MFM-codering: geen twee '1-bits' naast elkaar, max drie '0-bits' achtereen. Fouten werden gedetecteerd en gecorrigeerd, maar sommige schijven bleken onleesbaar – waarschijnlijk magnetische degradatie na decennialang opbergen.
Decodering naar ADF
De drive levert raw MFM-pulsen (fase-overgangen), niet bits. Deze gaan direct in de decoder. Zoeken naar sync-word 0x4489 (of 0x2AAAAAAA44894489 met maskering) leverde de 11 sector-starts per track op. Headers en data werden gedecodeerd, checksums gecontroleerd. Geldige sectoren werden naar ADF-bestand geschreven (raw 512 bytes/sector, beide zijden, in volgorde). Sommige schijven gingen snel, anderen namen lang door herhaalde reads.
Wat komt er nu? (V2)
V2 is al beschikbaar met verbeterde lees- en schrijfondersteuning! Het project is volledig open-source (GPLv3). Doel: andere formaten ondersteunen (FDI – universeel, goed gedocumenteerd) en schrijffunctionaliteit toevoegen. IPF/CAPS is closed-source en gericht op hardware-verkoop – daarom focus op FDI.
Code
GitHub Repository: Arduino sketch en Windows broncode
Schema's
Zie bijgevoegde afbeeldingen voor breadboard-opstelling en schakelschema.
Productieproces
- De Evolutie en Vakmanschap van Animatie
- De Evolutie van Diskettes: Van Magnetische Media naar Optische Opslag
- Bluetooth-gecontroleerde Arduino Spybot bouwen
- FlickMote: Gebarengecontroleerde IR-afstandsbediening voor Slimme Huizen
- DIY Arduino TV-B-Gone: Universele TV-uit-schakelaar
- Bouw een Aangepaste LED Hoofdklok met Alarm – Zichtbaar vanaf 12 Meter
- Find Me: Slimme Item Locator met Arduino en Bluetooth
- Geoptimaliseerde Voedingsoplossingen voor Arduino Projecten
- Arduino Boter-Kaas-Eieren met MAX7219 LED Matrix en Kartonnen Behuizing
- Bouw een Slimme Arduino Vierpotige Robot: Stap-voor-Stap Handleiding
- Arduino-gebaseerde Amiga-floppylezer: Goedkope open-source dataherstel