Aufzeichnungsformat der Datassette
Bit-Kodierung[Bearbeiten | Quelltext bearbeiten]
Im Gegensatz zu vielen Homecomputern um 1980, welche die Bits als Frequenzen codieren (FSK, Frequency-Shift Keying)[1], zeichnet die Commodore Datassette die Daten als Folge von Impulsen unterschiedlicher Länge auf.
Es gibt prinzipiell drei unterschiedliche Impulsfolgen, die jeweils aus einer positiven und einer negativen Halbwelle (Tastverhältnis 50 %) bestehen:
- Kurz: Zweimal 176 µs/eine Periode 2840 Hz
- Mittel: Zweimal 256 µs/eine Periode 1953 Hz
- Lang: Zweimal 336 µs/eine Periode 1488 Hz
- Ein Bitwert "0" ist kodiert als Folge Kurz-Mittel
- Ein Bitwert "1" ist kodiert als Folge Mittel-Kurz
- Der Byte Marker ist kodiert als Folge Lang-Mittel
- Der (optionale) End-of-data Marker ist kodiert als Folge Lang-Kurz
Die obigen Angaben beziehen sich auf NTSC-Systeme. Da die Taktfrequenz von PAL-Systemen etwa 3,8 % langsamer ist, müssen die angegebenen Impulslängen um diesen Faktor erhöht werden.
Somit ergeben sich für PAL folgende Impulslängen:
- Kurz: Zweimal 182,7 µs/2737 Hz
- Mittel: Zweimal 265,7 µs/1882 Hz
- Lang: Zweimal 348,8 µs/1434 Hz
Für die Länge des Bytemarkers in einem PAL-System ergeben sich also 1229 µs. Beim Vermessen des Oszillogramms des PAL Bytemarker wurden 1240 µs ermittelt, was den obigen Berechnungen hinreichend genau entspricht.
Die Bits "0" und "1" sind beim PAL-System 897 µs lang.
Auf der Write-Leitung wird die Impulslänge zwischen den steigenden Flanken gemessen. Auf der Read-Leitung ist dies invertiert, es wird also zwischen den fallenden Flanken des Signals gemessen.
Byte-Format[Bearbeiten | Quelltext bearbeiten]
Die Datenbytes werden wie folgt abgespeichert:
- Bytemarker
- 8 Datenbits (das niederwertigtes Bit/LSB voran)
- Paritätsbit (ungerade Parität)
Somit hat jedes Byte eine Länge von 8,96 ms.
Die ungerade Parität bedeutet, dass die Summer aller "1" Bits, inklusive dem Paritätsbit ungerade ist.
Datenblock-Format[Bearbeiten | Quelltext bearbeiten]
Ein Datenblock enthält eine Nutzlast von 192 Bytes. Dies entspricht der Länge des/der Kassettenpuffers im C64 (RAM-Adresse 828 ... 1019 beim C64 oder Tape-I/O-Buffer #1 634-825 und Tape-I/O-Buffer #2 826-1017 beim CBM 8032).
Abgesehen vom Paritätsbit bei der Byte-Kodierung gibt es noch weitere Datensicherungsmechanismen:
- Es wird eine Prüfsumme über den Datenblock gebildet.
- Der Datenblock wird doppelt aufgezeichnet.
Über die 192 Bytes Nutzlast (engl. pay load) wird eine Prüfsumme (1 Byte) gebildet, indem $00 und dann nacheinander alle Bytes XOR-verknüpft werden. Diese Prüfsumme wird nach den Daten abgelegt.
Vor bzw. zwischen den Nutzlastdaten wird ein Synchronisationssignal (kurze Impulse/2840 Hz) gefolgt von einem Countdown aufgezeichnet. Dieser dient dazu, dass der Bandlaufmotor seine Drehzahl erreichen kann und dass abweichende Bandgeschwindigkeiten erkannt und ausgeglichen werden können. Der KERNAL berechnet hierzu während der Synchronisation einen Korrekturfaktor. Außerdem wird die Abtastung der Bits auf diese Weise mit der Aufzeichnung synchronisiert. Das Synchronisationssignal wird jeweils von einem langen Impuls eingeleitet.
Der Countdown besteht aus jeweils 9 Bytes. Vor der ersten Aufzeichnung der Nutzlastdaten wird von $89 auf $81 herunter gezählt, vor der zweiten von $09 auf $01.
Header-Block[Bearbeiten | Quelltext bearbeiten]
Das allgemeine Format der Header-Blocks[Bearbeiten | Quelltext bearbeiten]
Der Header-Block ist der erste Datenblock einer Datei. Er ist wie ein regulärer Datenblock aufgezeichnet, die Nutzlastdaten enthalten aber die Informationen zum Dateityp, den Speicheradressen (falls relevant) und den Dateinamen.
Byte | Inhalt |
---|---|
1 | Header-Typ |
2 | Startadresse (Low-Byte) |
3 | Startadresse (High-Byte) |
4 | Endadresse (Low-Byte) |
5 | Endadresse (High-Byte) |
6 - 21 | Teil des Dateinamens, der bei der FOUND-Meldung ausgegeben wird. |
22 - 192 | Teil des Dateinamens, der bei der FOUND-Meldung nicht ausgegeben wird. |
Ist der Dateiname kürzer als 16 Zeichen (in Byte 6 - 21), wird der Name mit Leerzeichen ($20) aufgefüllt. Die Bytes 22-192 sind im allgemeinen auch mit Leerzeichen belegt.
Header-Typen[Bearbeiten | Quelltext bearbeiten]
Wert | Header-Typ |
---|---|
$01 | Nicht-adressgebundenes Programm (reines BASIC-Programm) |
$02 | Datenblock für ASCII-Datei |
$03 | Adressgebundenens Programm |
$04 | ASCII-Datei Header |
$05 | End-of-tape Marker (EOT) |
Header-Typ $01[Bearbeiten | Quelltext bearbeiten]
Hier handelt es sich um BASIC-Programme, die verschiebbar sind und nicht darauf angewiesen sind, an eine definierte RAM Adresse geladen zu werden, wie Maschinenprogramme im Allgemeinen. Diese Programmdateien werden an den Anfang des BASIC-Speichers (beim C64 ist das $0801) geladen.
Header-Typ $02[Bearbeiten | Quelltext bearbeiten]
Dieser Typ kennzeichnet einen Datenblock einer ASCII-Datei. Es werden weder Start- noch Endadresse benutzt, der Dateiname entfällt ebenfalls. Die Bytes 2-192 (also 191 Bytes) stehen für die Nutzlastdaten zur Verfügung.
Header-Typ $03[Bearbeiten | Quelltext bearbeiten]
Diese Art von Programmdatei wird an die im Header definierte Startadresse geladen. Dies ist bei Maschinenprogrammen und Programmen mit einem Maschinensprache-Block üblich.
Header-Typ $04[Bearbeiten | Quelltext bearbeiten]
Dieser Dateityp kennzeichnet den Header einer ASCII-Datei (mit Dateinamen).
Header-Typ $05[Bearbeiten | Quelltext bearbeiten]
Dieser Typ kennzeichnet den End-of-tape (EOT) Block. Wird ein solcher Datenblock gefunden bevor eine Datei mit dem im LOAD- oder OPEN-Befehl angegebenen Namen gefunden wurde, wird ein ?DEVICE NOT PRESENT ERROR ausgegeben, da angenommen werden kann, dass danach keine Datei mehr folgt.
Dateinamen[Bearbeiten | Quelltext bearbeiten]
Wird beim Schreiben einer Programm- oder ASCII-Datei ein Dateiname verwendet, welcher länger ist, als 16 Zeichen, so werden die überschüssigen Zeichen durchaus abgespeichert, werden aber beim Laden nicht mehr nach der "FOUND ..." Meldung angezeigt. Diese Zeichen können jedoch mit dem PEEK-Befehl aus dem Puffer ausgelesen werden.
Header-Typen und Sekundäradressen[Bearbeiten | Quelltext bearbeiten]
Die verwendete Sekundäradresse hat einen Einfluss darauf, welcher Header-Typ in den Header-Daten hinterlegt wird.
Programme[Bearbeiten | Quelltext bearbeiten]
Laden[Bearbeiten | Quelltext bearbeiten]
LOAD"Name",1 |
Lädt ein Programm mit Typ $01 (BASIC Programm) an die Startadresse des BASIC-Speichers, der Typ $03 wird an die aufgezeichnete Startadresse geladen. |
LOAD"Name",1,1 |
Lädt das Programm immer an die aufgezeichnete Adresse. |
Speichern[Bearbeiten | Quelltext bearbeiten]
SAVE"Name",1 |
Speichert ein Programm als Typ $01 (BASIC-) Programm ab. |
SAVE"Name",1,1 |
Speichert ein Programm als Typ $03 (Maschinen-) Programm ab. |
SAVE"Name",1,2 |
Speichert ein Programm als Typ $01 Programm mit einem zusätzlichen EOT-Block ab. |
SAVE"Name",1,3 |
Speichert ein Programm als Typ $03 (Maschinen-) Programm mit einem zusätzlichen EOT-Block ab. |
Öffnen einer ASCII-Datei[Bearbeiten | Quelltext bearbeiten]
OPEN1,1,0,"Name" |
Öffnet eine Datei zum Lesen. |
OPEN1,1,1,"Name" |
Öffnet eine Datei zum Schreiben. |
OPEN1,1,2,"Name" |
Öffnet eine Datei zum Schreiben mit zusätzlichem EOT-Block. |
Medien[Bearbeiten | Quelltext bearbeiten]
- Dirk Paulissen: Das Cassettenbuch zu Commodore 64 und VC-20, 1984; Data Becker, Seite 52f.
- Said Baloui et al.: Das neue Commodore 64 Intern Buch, 1990; Data Becker, Seite 420f.
Weblinks[Bearbeiten | Quelltext bearbeiten]
- Nick Hampshire: "The PET Revealed", 1980 , Seite 135-142
- Marcel Timm: Ordered Tape to CBM content
- github - ikorb: tapecart/main.c
- Dan Heeb: Compute!'s VIC-20 and Commodore 64 tool kit: Kernal, 1985; COMPUTE! Publication, Inc. Seite 269f.
- "Simon’s Mostly Reliable Guide to the Commodore Tape Format"
Quellen[Bearbeiten | Quelltext bearbeiten]
- ↑ Nick Hampshire: "The PET Revealed", 1980 , Seite 135-142