gehacktes /// noniq.at

0010Audiokassetten als Datenspeicher

Das Diskettenlaufwerk für den C64 war anfangs noch sehr teuer. Als günstige Alternative gab’s die „Datasette“ – einen Kassettenrekorder mit C64-Anschluss. Aber wie funktioniert das Speichern von Daten auf Audiokassetten eigentlich genau?

Audio C128 C64 In-depth Explanations Retrocomputing Talks

„DR 1535“ von noris, eine der zahlreichen Nachbauten der originalen Commodore-Datasette.

Während das Diskettenlaufwerk 1541 in den 1980ern um die $400 kostete, gabs Datasetten schon um $70. Kein Wunder – technisch ist eine Datasette nicht viel mehr als ein normaler Kassettenrekorder, der über ein spezielles Kabel mit dem C64 verbunden werden kann1.

Speichern und Laden von Programmen

Wenn man ein BASIC-Programm geschrieben hat und es auf Kassette speichern möchte, geht das so:

Das Laden funktioniert analog mit LOAD "MEIN PROGRAMM" – vorausgesetzt, man hat die Kassette vorher an den Anfang zurückgespult.

Auf einer Kassette können auch mehrere Programme gespeichert sein (deswegen vergibt man beim Speichern einen Dateinamen), es gibt aber kein Inhaltsverzeichnis. Um ein bestimmtes Programm zu laden, muss der C64 daher das komplette Band einlesen und durchsuchen – so lange, bis er das Programm gefunden hat oder das Ende des Bandes erreicht ist.3

Wegen des fehlenden Inhaltsverzeichnisses sollte man sich tunlichst händisch notieren, welche Programme auf einer Kassette gespeichert sind. Auch das nachträgliche Ändern (Überschreiben) eines gespeicherten Programms ist eigentlich nur möglich, wenn es das letzte Programm auf der Kassette ist – ansonsten werden nachfolgende Daten überschrieben, falls sich die Länge des Programms geändert hat.

Alles in allem ist so eine Datasette also verdammt unpraktisch.

Aber irgendwie cool.

Audio-Kodierung der Daten

Wie sind die Daten eigentlich physisch auf der Kassette gespeichert?

Als Töne! Wenn man eine vom C64 bespielte Kassette in einem normalen Kassettenrekorder abspielt, hört sich das so an:

Mit einem Audioeditor wie Audacity digitalisiert erkennt man folgende Struktur:

Überblick über die Anordnung der Daten auf einer vom C64 bespielten Kassette

Die Daten sind in einzelne Blöcke aufgeteilt. Jeder Block beginnt mit einem „Leader“, der noch keine Daten enthält, aber dem C64 erlaubt, sich mit dem Laufwerk zu synchronisieren. Anschließend folgen die eigentlichen Daten und eine kurze Pause, bevor der nächste Block folgt.

Wo in diesen Tönen stecken jetzt die eigentlichen Daten? Beim Schreiben erzeugt der C64 Rechteckwellen – sogenannte „Pulses“ – in drei unterschiedlichen Dauern bzw. Frequenzen4

Bei entsprechender hoher Zoomstufe sieht man diese Pulses im Audioeditor – die theoretischen Rechteckwellen sind in der Praxis ziemlich abgerundet, aber noch klar erkennbar:

Hohe Zoomstufe zeigt die einzelnen Pulses

Misst man die Zeit zwischen zwei Nulldurchgängen (fallende Flanke, also wenn das Signal „von oben“ durch die Nulllinie geht), dann ergeben sich die oben beschriebenen Pulsdauern5. Im folgenden Bild hab ich die ersten paar Pulses am Übergang von Leader zu Daten entsprechend beschriftet:

Je nach Dauer ist ein Pulse entweder ein Short, Medium oder Long Pulse

Der Leader besteht ausschließlich aus Short Pulses. Die eigentlichen Daten verwenden dann alle drei Varianten, wobei immer zwei aufeinanderfolgende Pulses gemeinsam betrachtet werden müssen:

Mit diesem Wissen lässt sich dann das erste Byte dekodieren:

Jeweils 2 Pulse paarweise interpretiert ergeben die eigentlichen Bits bzw. Steuerinformationen

Konkret ist dieses Byte (und auch jedes weitere) so aufgebaut:

In unserem Beispiel ergeben sich also die Bits 10010001 und das zugehörige korrekte Prüfbit 0 (die Anzahl der 1-Bits ist ungerade). Wegen der LSB-0-Reihenfolge muss man die Bits von hinten lesen, die gewohnte Darstellung wäre also 10001001, was dezimal 137 bzw. hexadezimal 0x89 entspricht.

Dass das erste Byte diesen Wert hat, ist kein Zufall: Der erste Datenblock beginnt mit der Bytefolge 0x89 0x88 0x87 0x86 0x85 0x84 0x83 0x82 0x81, bevor die „wirklichen“ Daten kommen (auch hier gehts wieder um Synchronisation).

Andere Formate und Schnelllader

Zum Abschluss bleibt noch zu sagen, dass ich hier nur das vom C64 verwendete Standard-Format für Daten auf Kassette beschrieben habe. Dieses Format ist recht fehlertolerant, aber auch ziemlich ineffizient7. Fast alle kommerziell erhältlichen Kassetten haben daher eigene, effizientere Formate verwendet und dafür eigene Laderoutinen („Loaders“) mitgebracht. Eine ausführliche Übersicht dazu gibt es auf c64tapes.org, ebenso wie eine detaillierte Beschreibung des Standard-Formats.

Update 20.10.2016: Lightning Talk

Auf der EuRuKo 2016 hab ich einen Lightning Talk dazu gehalten:

Slides (PDF, 5 MB)


  1. Über das Kabel kann der C64 abfragen, ob gerade eine der Laufwerkstasten gedrückt ist (allerdings nicht, welche), und den Laufwerksmotor starten8 und stoppen. 

  2. Außerdem schaltet der C64 seinen Bildschirm ab: Die Routinen für das Laden/Speichern auf Kassette sind so zeitkritisch, dass zu Beginn alle Interrupts deaktiviert werden – und damit auch die Bildschirmausgabe. 

  3. Mit kluger Verwendung des mechanischen Zählwerks lässt sich das zumindest ein bisschen optimieren: Hat man sich die Anfangsposition eines gespeicherten Programms notiert, kann man das Band zunächst an diese Position spulen und den Ladevorgang gleich von dort beginnen. 

  4. Diese Modulationstechnik nennt sich Frequency Shift Keying (Frequenzumtastung) und wird z.B. auch von Faxgeräten benutzt (die sich daher auch ganz ähnlich anhören). 

  5. Die tatsächlichen Dauern können mehr oder weniger stark abweichen, in meinem Beispiel sind alle Pulse etwa um etwa 12% zu lang, Short Pulses dauern also 390 µs statt 350 µs usw. Grund für die Abweichungen sind Toleranzen der Mechanik in den Laufwerken – insbesondere, wenn Kassetten mit einem anderen Laufwerk gelesen werden, als ursprünglich zum Bespielen verwendet wurde. Aber genau deswegen existiert der „Leader“ am Beginn der Aufnahme – nachdem der ausschließlich aus Short Pulses besteht, kann der C64 hier die tatsächliche Länge dieser Pulse ermitteln und einen entsprechenden Korrekturfaktor berechnen, um anschließend alle 3 Puls-Typen verlässlich erkennen zu können9

  6. Es gibt auch noch einen „End-Data-Marker“ (Long + Short) nach dem letzten Byte kommt – frühere C64-Versionen haben diesen Marker allerdings nicht geschrieben, und auch sonst ist er nicht wirklich wichtig (das letzte Byte lässt sich auch daran erkennen, dass danach keine weiteren Pulse mehr folgen). 

  7. Die effektive Übertragungsgeschwindigkeit lag im Bereich von 60–70 Bytes pro Sekunde. 

  8. Die „Play“-Taste muss man trotzdem manuell drücken: Damit startet man ja nicht nur den Laufwerksmotor, sondern bewegt über ein Gestänge auch den Schreib-/Lesekopf an die entsprechende Position. Und diese Bewegung kann der C64 nicht fernsteuern. 

  9. Diese ganze schöne Synchronisation hilft natürlich nicht, wenn sich die Geschwindigkeit der Kassette (und damit die Länge der Pulse) während dem Abspielen ändert (auf gut deutsch: wenn das Band eiert). Falls diese Schwankungen zu groß werden, können die Daten einfach nicht mehr gelesen werden. 

Kommentare

genial, herzlichen Dank für die ausführlichen Infos!
Sowas habe ich gesucht:-).


Kommentieren

Bitte sei höflich und konstruktiv. Kommentare werden manuell überprüft und freigeschaltet.

Kommentar konnte nicht abgeschickt werden. Bitte fülle alle Felder aus.
Ein technisches Problem ist aufgetreten. Bitte versuche es später nochmal.
Vielen Dank! Wir informieren dich, sobald dein Kommentar freigeschaltet wurde.

0009Mikroschalter-Upgrade für einen kaputten FeuerknopfA Foldable Dymaxion Globe0011