Spannung ist spannend…

Gestern lief alles und heute geht nichts mehr. Beim Lesen und Schreiben fing der Schreib/Lese Kopf einfach mittendrin an in die falsche Richtung zu wandern, d.h. wenn er einen Track richtung Innen fahren sollte fuhr er einen Schritt richtung Außen, oder bewegte sich mehrere Schritte anstatt einem, wtf?

Nach stundenlanger Suche nach Timing Problemen bei der Ansteuerung des Schrittmotors, oder ob mir irgendwas in die Serielle Kommunikation spuckt fiel mir ein das ich das Netzteil für die Floppy über Nacht angelassen hatte und kontrollierte mal die Spannung. Ich hatte es auf 5V eingestellt, nun zeigte es 4,96V an, sollte eigentlich kein Problem sein… oder? Die Spannung wird über ein Poti eingestellt, ist halt ein billiges Labornetzteil, wird wohl das Poti über Nacht etwas gedriftet sein wegen Wärme, Wetter oder einer Fischschwarmwanderung im Pazifik. Hab es dann auf 5,01V gestellt und hossa, keine Probleme mehr!

Das Laufwerk scheint eine echte Diva zu sein das 0,05V soviel ausmachen. Meine Vermutung mittlerweile ist das das billige Labornetzteil kurz in der Spannung einknickt wenn der Schrittmotor einen Step macht, laut Datasheet eines Samsung Laufwerks zieht sowas 0,7A, und das es mit den 0,05V Unterschied dann genau unterhalb der zulässigen Grenze sinkt. Nun steht es auf 5,2V, das sollte genug Luft sein.

 

Nur eine handvoll Bits

Ich hab mich in den letzten Tagen damit beschäftigt den Schreibmodus zum laufen zu bringen… mit einigen Hürden.

Da auf der Magnetscheibe einer Floppy die Daten ja im MFM Format gespeichert sind muss man die Daten die da rauf sollen vorher in MFM codieren.
Zur Decodierung hab ich einige Beispiele im Netz gefunden, das war nicht so schwierig, aber für die Encodierung findet sich sehr wenig. Irgendwann bin ich dann auf eine MFM Codierungroutine des Win Fellows Amiga Emulators gestoßen, hab diese dann auch ausprobiert und es kam nur Grütze bei raus 🙁

Nachdem ich mich dann doch durch mehrere Kapitel im Buch „Amiga Disk Drives: inside & Out“ von Grote Gelfland Abraham erschienen bei Abacus/Data Becker 1988 gekämpft habe (wer schon mal ein Hardware Buch von Data Becker in der Hand hatte weiß das die schwierig zu lesen waren, und dazu kam noch das hier in Englisch war) hab ich festgestellt das die Routine nicht vollständig MFM codierung implementiert hatte, sondern nur soweit das der Amiga Emulator das als MFM gefressen hat, es waren also die Clock Bits nicht korrekt berechnet. Auch bei der Checksummenberechnung stimmte auch irgendwas nicht.
Hab also das meiste über Bord geworfen und selbst geschrieben. Nach vielen Versuchen lief dann die Codierung eines Sektors.

Ein Sektor mit 512 Datenbytes wird zu 1024 MFM codierten Bytes, dazu kommen noch Informationen über die Nummer des Sektors, Track, Abstand zum Gap, zwei Checksummen und ein ungenutzter 16 Byte Bereich, am Ende sind es dann 1088 MFM Bytes. 11 Sektoren passen auch einen Track und dann kommt die Track Gap, ein Bereich einer Spur in den kein kompletter Sektor mehr passen würde, der aber gefüllt sein muss um alte Daten auf der Spur zu überschreiben.

In der Routine des Emulators wird die GAP nach den Sektoren geschrieben, das kam mit aber unlogisch vor da man ja nicht genau wissen kann wie lang die Spur wirklich ist, da ein Laufwerk ja auch gewissen Schwankungen unterliegt. Also schreibe ich zuerst eine etwas längere Gap und dann die Sektoren sodaß der letzte Sektor etwas von der Gap überschreibt und ich sicher gehen kann das keine alten Daten überleben und kein Sektor einer vorherigen beschreibung auch nur teilweise überlebt. Weil ein Sektor wird zu beginn durch eine reihe von MFM Bytes (4x 0xAA gefolgt von 2x 0x4489) gekennzeichnet die durch die Kodierung von Datenbytes niemals zustanden kommen können, somit eindeutig sind. Und wenn sowas von einer vorherigen beschreibung der Spur überlebt würde man plötzlich 12 Sektoren finden und wüsste nicht welches die richtigen 11 sind, oder müsste mehr Aufwand beim Lesen betreiben.

Bei einer späteren Analyse eines Logikanalysatormitschnitts eines Schreibzugriffes an einem echten Amiga stellte ich fest das die es genauso machen, darüber haben sich natürlich die Bücher ausgeschwiegen, aber egal, ging ja auch mit nachdenken 🙂

Irgendwann lief dann auch die Schreibroutine und ich konnte ADF Images auf Disketten schreiben, Eureka! Nur gab es eine Menge unslesbare Tracks, aber je nach Image mal mehr mal weniger, und wie ich feststellte immer an den selben Stellen. Komisch gelle? Ich zweifelte erstmal meine MFM codier routine an. Hab da aber nichts finden können. Später stellte ich dann fest das immer beim letzten Sektor das letzte Byte fehlerhaft war… Lange rede kurzer Sinn: Denkfehler in der Schreibroutine.

void diskWrite()
{
 if (writeActive == false) return;
 digitalWriteFast(_writedata, !(dataByte >> 7));
 dataByte = dataByte << 1;
 writeBitCnt++;
 if (writeBitCnt == 8) {
 writePtr++;
 dataByte = stream[writePtr];
 writeBitCnt = 0;
 }
 if (writePtr >= writeSize) {
 writeActive = false;
 digitalWriteFast(_writedata, HIGH);
 }
}

Hier meine Schreibroutine, wird im 2µs Takt aufgerufen und shiftet die Bits aus dem MFM Puffer an die Schreibleitung der Floppy. Ich habe den Fehler mal rot markiert… Ich hab den Schreibvorgang beendet bevor das letzte Byte rausgeshifted wurde… Narf! Es fehlten also von letzten Byte die 4 ungeraden Bits, das erklärte auch warum manche Tracks in Ordnung waren und viele nicht.

richtig lautet die Zeile:
if (writePtr > writeSize) { … usw}

Anfängerfehler 😛

Frontend für den PC

 

Nachdem es nun eine Wochen ruhig waren hier ein weiteres Update, ich war ja nicht untätig, nur zu faul zum bloggen 😉frontend01

Da ich mich irgendwie mit keiner IDE für C++ anfreunden konnte und ich unter Windows eigentlich noch nie was mit C++ und GUI gemacht habe hab ich zu Processing 3.0 gegriffen, damit hatte ich schon mal ein Frontend für ein Projekt geschrieben und Erfahrungen gesammelt. Processing ist ein Java Dialekt mit kompletter IDE, vielen Grafikbefehlen und einer großen Library Base. Ich bin zwar kein JAVA Spezialist, aber passt schon, Google ist mein Freund, und während meines Studiums hatte ich viel mit Modula zu tun und irgendwie sind sich ja alle Imperativen Programmiersprachen sehr ähnlich 🙂

Das Interface brauch noch ein bischen Liebe, aber für erste Ergebnisse reichts.

  • „getName“ liest den Volumename der Diskette
  • „Save As“ öffnet einen Requester um den Speicherort und Namen festzulegen
  • „Dump“ liest von Start Track bis End Track eine Amigadisk ein und speichert sie als .adf
  • „Abort“ bricht den Lesevorgang ab.
  • „Read“ liest einen Track und zeigt im Infofenster an wieviel Sektoren gefunden wurden, ist noch zu Debugzwecken drinne
  • Im Infofenster wird angezeigt bei welchem Track gerade gelesen wird, Fehler usw.

Unten wird die Häufung der Transitionen angezeigt, je heller desto mehr, hier kann man sehen das die Transitionen in der Regel etwas kürzer sind, bzw. die alte Flinte ganz schön streut. Ob ich da irgendwo einen Rechenfehler gemacht habe, sodaß die Transitionen oft kürzer als die Norm sind, keine Ahnung, vielleicht kümmer ich mich später nochmal darum. Man sieht hier auch viele Streubits, ich vermute das das Murks aus dem Trackgap ist.

Die Einstufung der Transitionen mache ich momentan wie folgt:

  • unter 1,5µs wird verworfen
  • 1,51µs bis 4,83µs ist eine ’10‘
  • 4,84µs bis 6,70µs ist eine ‚100‘
  • 6,71µs bis 8,58µs ist eine ‚1000‘
  • alles darüber wird verworfen

Die magenta Linien im Graph zeigen an das mehrere Leseversuche nötig waren um den Track zu lesen, ich prüfe ob ein Track 11 Sektoren enthält, dann ob die beiden Checksummen stimmen. Wenn etwas davon nicht stimmt wird der Track nochmal gelesen. Maximal macht der Mikrocontroller bisher 10 Versuche einen Track zu lesen, wenn der 10te auch fehlschlägt wird der Track so übertragen wie er ist und dem Frontend gemeldet in welchen Sektoren welche Checksummen nicht stimmen.

Wie man sieht ist diese Diskette ziemlich an der Grenze und besitzt schon einige Weak Tracks, wurde aber noch „korrekt“ ausgelesen. Da die Checksummen aus den MFM Daten per XOR generiert werden können sich hier natürlich Fehler einschleichen die nicht erkannt werden, von daher ist das „korrekt“ mit Vorsicht zu geniessen. Auf DOS Ebene gibt es noch mehr Checksummen, aber viele Spiele benutzen gar keine Filesystemfunktionen sondern benutzen das Trackdisk.device direkt. Damals gab es Kopierschutzverfahren die die Checksummen absichtlich falsch geschrieben haben, in den ungenutzten 16 Bytes im Header Informationen speicherten oder sonstwie am Header manipuliert haben, ein normales Copytool oder die Workbench konnte so eine Disk nicht kopieren. Ebenso gab es Spiele die ein andere Syncword benutzten, Sachen in die Trackgap schrieben, in GCR codiert waren, Laserlock benutzten, Track 80-82 benutzten usw., es gab ne Menge was sie machen konnten um die Piraten auf Abstand zu halten. Irgendwann wurde alles irgendwie geknackt, aber nicht jeder Normalo konnte mal eben ein Spiel im Laden kaufen und zig Kopien an seine Freunde auf dem Schulhof verteilen.

Aber ich will eh kein Kopierprogramm für geschützte Software schreiben sondern nur für Disketten die ohne Kopierschutz daher kommen, selbst nach 20 Jahren könnte das Eis dünn sein auf dem man sich da bewegt da es in Deutschland ja mittlerweile Strafbar ist einen Kopierschutz zu umgehen. Das war die subtile Maßnahme unserer Regierung das Recht auf Privatkopie im Urhebergesetz  § 53 Absatz 1 Satz 1 auszuhebeln ohne es anzufassen. Sie haben einfach ein neues geschaffen was die Umgehung technischer Schutzmaßnahmen §§ 95a ff. UrhG (DE) unter Strafe stellt. Allerdings lässt sich über die Formulierung „Wirksame technische Maßnahmen“ streiten 🙂 Naja, sie treiben die Kohle ja eh über GEMA und ZPÜ ein, darüber kann man sich aber auch den Mund fusselig reden wenn man für die Digicam eine SD-Karte kauft und ZPÜ abdrücken muss weil man damit ja Urheberrechtlich geschütztes Material kopieren könnte, auf wiedersehen Unschuldsverdacht. 😛

Spielkrams

Mittlerweile hab ich in mein Programm noch ein paar Features eingebaut, unter anderem eine Analyse des Timings der Transitionen auf dem gerade gelesenen Track, so etwas sieht dann in der Ascii Ausgabe so aus:

Transitions: 47166 Real Bits: 110011
0.25:0-146+
1.83:38-1
2.33:50-1
3.58:80-3
3.63:81-11
3.67:82-75
3.71:83-1134++++++++
3.75:84-5063+++++++++++++++++++++++++++++++++++++++
3.79:85-8495++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.83:86-8020++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.88:87-5470++++++++++++++++++++++++++++++++++++++++++
3.92:88-2809+++++++++++++++++++++
3.96:89-1693+++++++++++++
4.00:90-749+++++
4.04:91-360++
4.08:92-60
4.13:93-4
5.38:123-3
5.42:124-18
5.46:125-105
5.50:126-288++
5.54:127-638++++
5.58:128-1097++++++++
5.63:129-1500+++++++++++
5.67:130-1788+++++++++++++
5.71:131-1662++++++++++++
5.75:132-1343++++++++++
5.79:133-1066++++++++
5.83:134-624++++
5.88:135-389+++
5.92:136-179+
5.96:137-52
6.00:138-7
6.04:139-2
7.38:171-3
7.42:172-20
7.46:173-65
7.50:174-102
7.54:175-211+
7.58:176-271++
7.63:177-395+++
7.67:178-413+++
7.71:179-326++
7.75:180-260++
7.79:181-202+
7.83:182-118
7.88:183-61
7.92:184-11
7.96:185-1
8.42:196-1
OK

Wo die 146 Transitionen mit einer länge von 0,25µs herkommen hab ich keine Ahnung, kommen vielleicht aus dem Trackgap weil da in der Regel nur Müll steht bzw. die Diskette dort nicht formatiert ist, soll mir aber egal sein, ich werte nur Transitionen aus die länger als 1,5µs sind 😉
Da der Controller des Amiga mit maximal 500kbit/s arbeitet besitzt er eh nur eine Auflösung von 2µs, würde sowas also überhaupt nicht mitbekommen, bzw. falls er auch Filter vorgeschaltet hat sowas als Leitungsrauschen wegfiltern.

 

Erste Versuche mit dem Teensy 3.2

adf_01
Versuchsaufbau

So sieht der Versuchsaufbau mit dem Teensy aus, ich konnte die Floppy direkt mit einem Steckbrett und ein paar Dingsdakabeln verdrahten, keine lästigen Spannungsteiler oder Levelshifter da der Teensy 3.2 direkt TTL Pegel auf den Eingängen frisst.

#define _redwc 2     //2 density select IN 
#define _index 3     //8 index OUT
#define _drivesel 4  //12 drive select 1 IN
#define _motor 5     //16 motor1 on IN
#define _dir 6       //18 direction IN
#define _step 7      //20 step IN
#define _writedata 8 //22 write data IN
#define _writeen 9   //24 write enable IN
#define _track0 10   //26 track 0 OUT
#define _wprot 11    //28 write protect OUT
#define _readdata 22 //30 read data OUT (FTM0)
#define _side 14     //32 head select IN
#define _ready 15    //34 ready / disk change OUT

Die ganzen Floppy Pins gehen von oben nach unten an die Pins vom Teensy, bis auf die Read Data Leitung, die habe ich nach Studium des Datenblatt an GPIO 22 gelegt, dieser GPIO lässt sich nämlich als Input Capture Trigger für das FlexTimer Module 0 benutzen.

Der FTM0 ist ein 16 Bit Timer der mit maximal Bus Clock läuft, Bus Clock ist beim Teensy der halbe Coreclock, da ich auf 96 MHz takte sind das 48 MHz. Über den Prescaler halbiere ich den Takt nochmal auf 24 MHz, d.h. alle 41,6 Nanosekunden zählt der Timer einen Schritt hoch. Für den Eingang habe ich noch einen Filter im Timer eingestellt sodaß das Signal am Input Trigger für mindestens 12 Taktzyklen Busclock (250ns) stabil sein muss damit es erkannt wird. Wird nun über den GPIO 22, welches der Input Capture Trigger für FlexTimer Modul 0 ist, ein Flankenwechsel (in meinem Falle Falling Edge) detektiert findet folgendes statt:

  • der Inhalt des Counters (FTM0_CNT) wird in ein extra Register (FTM0_C0V) kopiert
  • der Interrupt Vector (ftm0_isr) des FTM0 wird angesprungen
  • die von mir geschriebene Interruptroutine setzt den Counter auf Null
  • der Inhalt des Registers FTM0_C0V wird ausgewertet wie lang die Transition dauerte, 4,6 oder 8 µs
  • entsprechende schreibe ich in eine Puffervariable eine ’10‘, ‚100‘ oder ‚1000‘, ich benutze dafür ein Longword (32bit) in dem ich die Bits sammel und wenn ich 8 Bit oder mehr komplett habe schreibe ich sie in den Steambuffer.
  • On the Fly prüfe ich ob das Longword den Inhalt 0xA4489448 enthält, das ist nämlich der Anfang des Syncwords eine Amiga Sektors und kann ensprechend dem Stream entsprechend ausrichten das genau ein Byte anfängt. Ebenso vermerke ich in einer Tabelle einen Pointer auf den Sektoranfang im Speicher, das macht das decodieren später einfacher.
  • wenn der Streambuffer voll ist oder ich 11 Sektoren gefunden habe schalte ich die Interrupt Generierung aus.
  • der Interrupt benötigt etwa 0,9 µs pro Transition, d.h. sie ist lange fertig bevor die nächste Transition kommt (4µs oder länger)

Währenddessen wartet meine Hauptroutine nur darauf das der Lesevorgang beendet ist und startet danach die decodierung des Tracks.

Der ganze Spass läuft mittlerweile recht zuverlässig, hat zwar bisher kaum Fehlerüberprüfungen aber spuckt erste brauchbare Ergebnisse aus:

Reading Track 0
Sectors start at: 172, 2067, 3155, 4243, 5331, 6419, 7507, 8595, 9683, 10771, 11859
Decode took 1631
Sectors found: 11 Errors found: 0
OK
Format Type: 255 Track: 0 Sector: 0 NumSec2Gap: 3 Data Chk: 4410155 Header Chk: 0
44 4F 53 00 C0 20 0F 19 00 00 03 70 43 FA 00 18 4E AE FF A0 4A 80 67 0A 20 40 20 68 00 16 70 00 DOS.. .....pC...N...J.g. @ h..p.
4E 75 70 FF 60 FA 64 6F 73 2E 6C 69 62 72 61 72 79 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Nup.`.dos.library...............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................

Oben sieht man den Bootsektor einer Amiga Diskette, in den ersten vier Bytes steht „DOS“,0 für eine normale Diskette, dann folgt eine kurze Assemblerroutine die über die dos.library den Boot der Disk startet.

Got it!

Nach ein wenig rumsuchen bin ich auf den Teensy 3.2 gestoßen:

  • 32 Bit Arm Cortex M4 Kern mit 72 MHz, übertaktbar bis 96 MHz
  • 256kb Flash Speicher für Code
  • 64kb RAM
  • 34 Pins IO
  • sehr schnelle Serielle Schnittstelle über USB (1 Mbps ohne Fehler)
  • 5V tolerant auf den IO Pins

Perfekt! Warten auf den Postboten 😉

Amigafloppy, erste Versuche

Für erste Versuche habe ich einen Arduino Mega benutzt. Ansteuerung der Floppy Mechanik funktionierte recht schnell, das Lesen gestalte sich Problematisch und ich hab schnell festgestellt das der Mega einfach zu wenig RAM hat um einen kompletten Track zu puffern. Ein Track einer Amiga Diskette besteht aus 11 Sektoren á 512 Bytes, klingt erstmal wenig, zu den 512 Bytes pro Sektor kommen noch 28 Bytes an Verwaltungsinformationen hinzu. Ein Sektor ist folgendermaßen aufgebaut:

struct Sector
{
 unsigned char format_type; // Beim Amiga immer 0xff
 unsigned char track; // Zu welchem logischen Track dieser Sektor gehört (0-159)
 unsigned char sector; //Sektor Nummer (0-10)
 unsigned char toGap; //Wieviel Sektoren noch kommen bevor der Trackgap kommt
 unsigned char os_recovery[16];// 16 Bytes die der Amiga nie benutzt hat, sind i.d.R mit Null gefüllt, außer bei Kopiergeschützten Sachen
 unsigned long header_chksum; // Checksumme der Daten im Header, wird mit Exklusiv Oder der MFM Daten generiert
 unsigned long data_chksum; // Checksumme der Daten im Datenblock, auch XOR der MFM Daten.
 unsigned char data[512]; // 512 Bytes Nutzdaten
};

Vor dem eigentlichen Sektor kommt noch das Syncword, das ist eine Reihenfolge von Bytes in MFM Stream der niemals durch normale Kodierung entstehen kann, beim Amiga sind das mehrfach „10“ bzw 0xA hintereinander, gefolgt von 0x44894489. Daran erkennt der Controller im Amiga das nun ein Sektor anfängt.

Da ein wechsel der Magnetisierung, auch Transition genannt zu einer unterschiedlichen länge von Bits entschlüsselt wird muss man auf Bitebene prüfen ob man gerade einen Sync gefunden hat, erst wenn man den Sync hat weiß man wo im Bitstream ein Byte anfängt.

8 µs -> 1000
6 µs -> 100
4 µs -> 10

Bei MFM codierung ist jedes zweite Bit ein Clock Bit damit der Controller nicht den Takt verliert, d.h. es ist eine 2:1 codierung, das bedeutet die hälfte der Bits wird beim decodieren weggeschmissen. Da aber die Checksummen mit den MFM Daten arbeiten muss man den MFM codierten Track bzw. Sektor im Speicher vorliegen haben. Und hier war der Arduino Mega am Ende mit seinen 8k Ram, das reicht zwar für einen Track im decodierten Zustand (5632 Bytes), aber nicht für die MFM Daten (11968 Bytes ohne Trackgap). On the Fly Decodierung und Checksummen berechnen geht leider auch nicht mit 16 MHz.
Es hätte vermutlich funktioniert jeweils nur immer einen Sektor zu lesen, decodieren und über die Serielle Schnittstelle an den PC zu schicken, aber das würde dann ewig brauchen um einen Track zu lesen.

Es muss also was neues her.

Lesegerät für Amiga Floppies

Da ich letztens mal wieder meinen Amiga aktiviert habe kam mir die Idee mal ein paar Daten vom meine Amiga Disketten zu retten. Ich hatte damals ein paar Sachen programmiert, Unterlagen aus meiner Studienzeit und so weiter. Prinzipiell gibts da ja verschiedene Möglichkeiten, aber ich fand es interessant mit einem Handelsüblichen PC Laufwerk und einem Mikrocontroller Amiga Disketten zu lesen, und später vielleicht auch zu schreiben.

Es gibt halb kommerzielle Produkte dafür zu kaufen, z.B. das KryoFlux, das kost so um die 100€, aber irgendwie macht das selber bauen mehr Spass. Und wenn ich sehe wie voll die Platine des KryoFlux ist, denke ich mir das geht einfacher mit modernen Microcontrollern, man muss nur den richtigen finden.

Im Netz findet man einige Informationen zum Interface von Floppy Laufwerken, dem Shugart Bus, der Bus arbeitet mit TTL Pegeln, also 0-5V. Da ich aber Sachen besser begreife wenn ich sie „sehe“ hab ich mal meinen Logikanalysator an den Floppy Port des Amiga gehangen und eine Diskette formatiert:

logik01

In der Grafik hab ich leider die Signale WD (Write Data) und WE (Write Enable) verkehrt bezeichnet. Hier sieht man schön wie die Signale zusammenspielen. Mit einem kurzen Impuls auf /STEP wird zur nächsten Spur gesprungen. Quasi gleichzeitig wird die Seite der Floppy eingestellt auf der gearbeitet werden soll, das wird vom Ready Signal jeweils kurz quittiert. Nach einer gewissen Zeit wird dann wd (WE) auf low gezogen um einen schreibzugriff einzuleiten. Daraufhin wird eine Seite geschrieben we (WD), dann die Seite (SIDE) gewechselt und diese dann geschrieben. Später werden dann beide Seiten eingelesen und verglichen ob der Schreibzugriff fehlerfrei war.

Gut, das Schreiben ist mir erstmal egal, wichtig ist die Grundlagen wie MFM codierung und die Ansteuerung des Laufwerks zu programmieren.

 

Da die Informationen auf einer Floppy und anderen Magnetischen Medien durch eine änderung der Magnetisierungsrichtung gespeichert werden kann man da nicht einfach Nullen und Einsen raufschreiben. Der Floppy Controller würde irgendwann den Takt verlieren wenn zuviele Nullen oder Einsen hintereinander kommen. Deshalb wird die Information durch unterschiedliche Abstände zwischen der änderung der Magnetisierung gespeichert.logik02 Hier sieht man drei Unterschiedliche lange Abstände: 8 µs, 6 µs und 4 µs. Bei einer HD Floppy mit 1,440MB wären das 2,3,4 µs Abstände. Da der Amiga aber in der Regel nur DD Floppylaufwerke verbaut hatte interessiert mich nur DD Disketten zu lesen.