Commodore DOS
Commodore DOS ist der Name des Disketten-Betriebssystems der Firma Commodore, das in den Diskettenlaufwerken der Commodore-8-Bit-Reihe eingesetzt wurde, z. B. CBM 3040, CBM 4040, CBM 8050, CBM 8250, VC1540, VC1541, VC1570/71, VC1581, SFD1001, SFD1002.
Hardware der Diskettenlaufwerke
Ausführliche Erläuterungen zur Hardware siehe im eigenen Artikel CBM-Diskettenlaufwerke.
Bei typischen Computersystemen jener Zeit, und im Prinzip bis heute, waren Diskettenlaufwerke fast direkt über den Prozessorbus angebunden. Um das Kodieren der Daten kümmerte sich entweder ein einfacher Controllerchip oder die Software des Betriebssystems, und auch das Dateisystem wurde vom Betriebssystem des Computers verwaltet.
Bei den Computern der Commodore-8-Bit-Reihe wählte man einen anderen Weg. Um die Kosten für den Computer, der anfangs häufig ohne Diskettenlaufwerk eingesetzt wurde, zu minimieren und die Anbindung von Laufwerken so flexibel wie möglich zu halten, verfügte der Computer nur über sehr einfache und allgemein gehaltene, zeichenorientierte (nicht blockorientierte) Software- und Hardware-Schnittstellen zu externen Geräten, während die vollständige Logik zum Kodieren/Dekodieren von Sektoren sowie die Dateisystem- und DOS-Befehlslogik im Diskettenlaufwerk realisiert war.
Commodore-8-Bit-Diskettenlaufwerkseinheiten (Units) waren deshalb eigenständige Computer mit einem oder zwei vom eigentlichen Computer unabhängigen Prozessoren. Eine Unit verfügte über ein oder mehr Laufwerke (Drives). Es konnten mehrere Units an einen Computer angeschlossen werden. Das Betriebssystem, das in diesen Laufwerken zum Einsatz kam, war Commodore DOS. Im Gegensatz zu den DOSen der meisten anderen damaligen Firmen war es nicht auf einer Diskette gespeichert, sondern in ROM-Chips (Firmware) innerhalb des Laufwerks.
Die ursprünglichen Modelle für die Commodore-PET-Reihe besaßen zwei symmetrische CPUs, 2 KiB RAM und 16 KiB ROM. CPU 1 realisierte die Logik, um Sektoren zu lesen und zu schreiben, während CPU 2 sich um die Dateisystemlogik sowie um die Kommunikation mit dem Computer kümmerte. Die Kommunikation zwischen den beiden Prozessoren fand über den Hauptspeicher statt: CPU 2 schrieb Befehls-Tupel (Aktion, Drive, Spur, Sektor, Speicheradresse) in einen definierten Speicherbereich, die CPU 1 auslas, ausführte und das Befehls-Tupel mit dem Ergebniscode überschrieb. Die beiden CPUs konnten dabei gleichzeitig denselben Speicher verwenden, indem man sich eine spezielle Eigenschaft der 6502-Prozessoren zunutzemachte – diese greifen nur in einer der beiden Hälften jedes Taktzyklus auf den Systembus zu. Die CPUs wurden nun so verschaltet, dass CPU 1 jeweils in der ersten Takthälfte und CPU 2 in der zweiten Takthälfte den Bus benutzte, ganz genauso wie sich in den Commodore-Computern selbst der Prozessor und der Videochip den Bus teilten.
Grundsätzlich gelten alle diese Angaben auch für die Festplatten CBM 9060 und CBM 9090.
Spätere Geräte verfügten über nur ein Laufwerk, und die zweite CPU wurde aus Kostengründen eingespart. Die einzelne CPU übernahm beide Aufgaben, die ursprüngliche Konzeption des Systems blieb dabei allerdings bestehen: Die Aufgaben der CPU 2 (Dateisystem) liefen als Hauptprogramm ab, während die Aufgaben der CPU 1 (Hardwaresteuerung) in einer Interruptroutine erledigt wurden.
Eigenschaften von Commodore DOS
Aktionen wie das Formatieren von Disketten, das Umbenennen, Löschen oder Kopieren von Dateien werden also von Commodore DOS ausgeführt und laufen vollständig in der Laufwerkseinheit ab. Das DOS bietet ein flaches Dateisystem (ein paar Details siehe unter SFD100x) ohne Unterverzeichnisse und mit einer festen, limitierten Anzahl von Einträgen, also Dateien, je Datenträger (Diskette bzw. Festplatte).
Jedes Laufwerk kann über die Schnittstelle zum Computer 15 virtuelle Kanäle oder Dateien (0–14) unterhalten, d. h. der Computer kann auf einem Laufwerk bis zu 15 Dateien zum Lesen bzw. Schreiben offen halten. (Die tatsächliche Anzahl offener Dateien wird dabei in der Praxis vom RAM des Laufwerks begrenzt, üblicherweise können 3–4 Dateien und der Befehlskanal offen gehalten werden.)
Andererseits arbeitet der Computer seinerseits mit eigenen virtuellen Kanälen, die durch ihre Nummer identifiziert und den Geräten bei der Eröffnung zugeteilt werden; bei der Eröffnung des Kanals wird dem Gerät (z. B. Diskettenlaufwerk) auch mitgeteilt, welchen virtuellen Kanal es für diese Verbindung verwenden soll. Die Nummern sind dabei beliebige „Namen“, über die reale Puffer im Computer und den Geräten adressiert werden.
Kanal 15 („Befehlskanal“) hat für ein Diskettenlaufwerk eine Sonderbedeutung: Über ihn laufen Befehle vom Computer an Commodore DOS sowie Statusmeldungen in die andere Richtung. Auf Computerseite wird der Befehlskanal allerdings genau wie eine normale Datei behandelt.
Kanal 0 ist für Leseoperationen vorgesehen und Kanal 1 für Schreiboperationen (insb. dem Laden und Speichern von Programmen), so dass bei Benutzen dieser Kanäle die Art des Zugriffs nicht mehr spezifiziert werden muss.
Empfangen und Senden von Daten und Befehlen
Der Datenaustausch zwischen Computer und Laufwerk wird ermöglicht über die erwähnten virtuellen Kanäle ("Sekundäradressen") im Laufwerk. Bei Commodore-Computern (z. B. C64) existieren analoge virtuelle Kanäle ("Dateinummern") auch auf Computerseite, verwaltet durch Routinen im ROM-basierten Betriebssystem (Kernal). Diese werden vom BASIC-Interpreter bei Eingabe von bestimmten BASIC-Befehlen aufgerufen oder direkt von Programmen, vor allem Assembler-Programmen. Die Computerseitigen virtuellen Kanalnummern ("Dateinummern") werden dabei dem Laufwerk nie mitgeteilt, sondern nur innerhalb des Rechners selbst verwendet. Die Laufwerke identifizieren Dateien ausschließlich über die "Sekundäradressen".
Die folgenden Beispiele illustrieren somit eher die Ansprache des DOS von der BASIC-Ebene aus und die Abhängigkeit der Benutzerfreundlichkeit von der Implementation von letzterer. „Gerät“ meint dabei in diesem Zusammenhang ausdrücklich eine Commodore-Diskettenstation und wird verwendet, um begrifflich eine solche von einem „Laufwerk“ zu unterscheiden, da manche Stationen ja aus zwei Laufwerken bestehen.
Beispiel 1: Umbenennen einer Datei
OPEN 1,10,15: PRINT#1,"R:NEUNAME=ALTNAME": CLOSE 1
oder abgekürzt OPEN 1,10,15,"R:NEUNAME=ALTNAME": CLOSE 1
Dies öffnet den virtuellen Kanal ("Dateinummer") 1 auf Computerseite, weist ihn Gerät 10 am seriellen Bus zu und schickt diesem Gerät die Information, seinerseits den virtuellen Kanal ("Sekundäradresse") mit Nummer 15 zu verwenden (d. h. einen Pufferbereich zu reservieren und ihn „15“ zu nennen); Anhand dieser Nummer 15 weiß das Gerät, dass über diesen Kanal keine Daten für eine Datei, sondern DOS-Befehl gesendet werden, die es ausführen soll. Der zweite Befehl schickt den Befehl „R“ (kann auch RENAME ausgeschrieben werden) an Kanal 1 mit dem neuen und alten Dateinamen. Der dritte Befehl schließt den virtuellen Kanal.
Beispiel 2: Öffnen einer Datei und Hineinschreiben eines Textes
OPEN 1,8,13,"TESTDATEI,S,W"
oder OPEN 1,8,1,"TESTDATEI,S"
oder DOPEN#1,"TESTDATEI,W"
PRINT#1,"WIKIPEDIA, DIE FREIE ENZYKLOPAEDIE"
CLOSE 1
Der erste OPEN-Befehl öffnet virtuellen Kanal 1 auf Computerseite und weist ihn Gerät 8 zu. Diesem Gerät wird zunächst mitgeteilt, dass eine Datei zu öffnen sei, die fortan über die Nummer 13 anzusprechen ist. Da es sich um eine echte Datei handelt und diese einen Namen braucht, wird das folgende als Name der Datei interpretiert (bis zum Komma). Danach folgt „S“ als Angabe, dass es eine Datei vom Typ SEQ (sequentielles lesen/schreiben) werden soll, und „W“ für WRITE (Schreibzugriff). Andere Zugriffsmodi sind „R“ (Read) und „M“ (Modify).
Der darunterstehende Befehl erfüllt genau dieselbe Funktion, aber da der laufwerksseitige virtuelle Kanal Nummer 1 benutzt wird und diese standardmäßig für Schreiboperationen reserviert ist, entfällt die Angabe für den Schreibzugriff. Der nächste Befehl setzt BASIC 4.0 oder höher voraus und erfüllt den gleichen Zweck, ohne dass der Benutzer sich um weitere Parameter kümmern muss.
Der nächste Befehl schickt den Text an den virtuellen Kanal (Puffer im RAM des Laufwerks), bevor der letzte ihn schließt. Erst ein Überlaufen des Puffers oder der CLOSE-Befehl veranlasst das Schreiben des Textes auf die Diskette. CLOSE gibt zugleich den Puffers für andere Zwecke frei.
Während dieses Vorgehen mit je einer Ebene von virtuellen Kanälen auf Computer- und Laufwerksseite für Programme Möglichkeiten des geräteunabhängigen Zugriffs bietet (Ansprechen von Laufwerken in der selben Form wie von Druckern, Modems, Tastatur, Bildschirm etc.), ist es für simple Laufwerksoperationen unhandlich. Commodore integrierte daher in spätere Versionen von BASIC Befehle zum einfacheren Zugriff auf Disketteninhalte:
Beispiel 3: Umbenennen einer Datei in BASIC 4.0 oder 7.0 (z. B. C128)
RENAME"alt"TO"neu"
Technisch betrachtet arbeitet dieser Befehl wie Beispiel 1 (außer dass er Gerät 8 anstelle von 10 anspricht).
Auch integrieren BASIC-Erweiterungen für CBM-Rechner häufig einen Befehl (meist „@“), der das direkte Senden von Befehlen auf dem Befehlskanal eines Laufwerks ermöglicht, ohne dass der Benutzer sich um die Ebene von Dateien und Kanälen zu kümmern braucht:
Beispiel 4: Umbenennen einer Datei mit DOS-Wedge oder z. B. JiffyDOS
@R:neu=alt
Insbesondere die Abfrage des Befehlskanals von Seiten des Computers wird hierdurch stark erleichtert, denn auf diesem Weg meldet sich ja das DOS beim Computer:
Beispiel 5: Abfragen des Status des Geräts mit DOS-Wedge oder z. B. JiffyDOS
@
Ausgabe z. B.: 00, OK, 00, 00
Commodore-Disketteneinheiten melden ihren Status in der o.g. Form als CBM-ASCII-String an den Computer. Die erste Zahl gibt die Nummer des aufgetretenen Ereignisses (i. A. Fehler, aber auch z. B. bei der 1581 das vorgenommene Auswählen einer Partition) an, 0 bedeutet hier keiner. Nach einem Komma folgt der Fehler als Klartext (jedoch weniger differenziert als die Nummer, so werden Lesefehler aus verschiedenen Gründen als „READ ERROR“ gemeldet und sind anhand ihrer Nummer genauer einzugrenzen), dann zwei Zahlen, die für gewöhnlich (aber nicht bei allen Meldungen) Spur und Sektor des Ereignisses angeben. Der Status ist auch ab BASIC 4.0 als Textstring mittels der Systemvariablen DS$ (für "Disk Status") und die Ereignisnummer mittels DS abrufbar.
Befehle
Folgende unvollständige Liste stellt einige wichtige Commodore-DOS-Befehle dar, auch um den mitunter durchaus elaborierten Charakter der Befehle zu illustrieren. Die Befehle können auch mit den ebenfalls aufgeführten vollständigen Namen gesandt werden, da das erste Zeichen zur Unterscheidung dient, auf das sie i. A. verkürzt werden.
Die meisten Befehle können die Wildcards ? und * verarbeiten. Je nach Befehl wird dann entweder mit der ersten oder mit allen passenden Dateien gearbeitet. Der Dateiname $ (Dollarzeichen) ist reserviert für das Verzeichnis einer Diskette, welches in Form eines nicht ausführbaren, aber LIST
-baren Commodore-BASIC-Programms zurückgegeben wird.
- N[d]:name,id – NEW: Formatieren einer Diskette in Laufwerk d (0 oder 1) des Gerätes, bei fehlender Angabe wird 0 angenommen. Angabe des Laufwerks natürlich nur bei Geräten mit zwei Laufwerken möglich, z. B. "N1:name,id" – Formatiert die Diskette in Laufwerk 1 (zweites Laufwerk).
- N[d]:name – NEW: Löschen einer Diskette ohne Neuformatierung
- V[d] – VALIDATE: Überprüfung des Dateisystems und Korrektur fehlerhafter Einträge, Berichtigung des freien Speicherplatzes; ähnlich dem Scandisk von MS Windows
- I[d] – INIT, INITIALIZE: Initialisieren der Diskette (Aktualisieren des Directorys im Laufwerks-Cache)
- R[d]:neu=alt – RENAME: Umbenennen einer Datei
- C[d]:neu=alt – COPY: Kopieren einer Datei auf derselben Diskette
- C[x]:neu=[y]:alt – COPY: Kopieren einer Datei von Laufwerk y (0 oder 1) auf Laufwerk x (1 oder 0), ggf. unter dem neuen Namen neu; nur möglich innerhalb von Geräten mit zwei Laufwerken
- S[d]:name – SCRATCH: Löschen einer oder mehrerer Datei
- D:[x]=[y] – DUPLICATE: Kopieren einer ganzen Diskette von Laufwerk y (0 oder 1) auf Laufwerk x (1 oder 0); nur möglich innerhalb von Geräten mit zwei Laufwerken
- L,kanalnummer position – LOCATE: Aufsuchen einer bestimmten Position in einer Datei
- B-R Kanal Spur Sektor – BLOCK-READ (Abkürzung obligatorisch): Lesen eines Sektors und Übermittlung des Inhalts an den angegebenen logischen Kanal. Aufgrund von Beschwerden über die eher gewöhnungsbedürftige Funktionsweise des Kommandos (das erste Byte des Blocks bestimmt die Anzahl der gelesenen Bytes) um die folgende "intuitiv" funktionierende Variante ergänzt:
- U1 Kanal Spur Sektor – Ersatz für Block-Read, liest immer den ganzen Block, auch als "UA" schreibbar
- B-W Kanal Spur Sektor – BLOCK-WRITE (Abkürzung obligatorisch): Schreiben eines Sektors, das erste Byte bestimmt die Anzahl der zu schreibenden Bytes
- U2 Kanal Spur Sektor – Ersatz für Block-Write, schreibt immer den ganzen Block, auch als "UB" schreibbar
Wird bei "B-R" und "B-W" der zweite Buchstabe groß geschrieben bzw. durch ein entsprechendes Grafikzeichen ersetzt (Bit 7 im Code des eingestellten CBM-ASCII-Zeichensatzes gesetzt) unterbleibt eine Prüfung auf zulässige Werte für Spuren und Sektoren, etwa um Bereiche außerhalb des normalen Diskettenformats zu manipulieren.
- U3-U7 – User-Befehle: Anspringen eigener Software im Laufwerks-RAM durch Sprungtabelle, auch als "UC"-"UH" schreibbar
- U8 – Zurücksetzen des Geräts in den Wartezustand und Initialisieren der Diskette (Reset), auch "UI"
- U9 – Zurücksetzen des Geräts in den Einschaltzustand und Inititalisieren der Diskette („Harter“ Reset), auch "UJ"
- U0>PETSCII-Zeichen Nr. x – Zuordnen einer neuen Gerätenummer x an das Laufwerk (nur 157x und neuer)
- M-W AdrL AdrH Anzahl Datenbytes – MEMORY-WRITE: Schreiben in das RAM des Diskettenlaufwerks
- M-R AdrL AdrH Anzahl – MEMORY-READ: Lesen aus dem RAM des Diskettenlaufwerks
- M-E AdrL AdrH – MEMORY-EXECUTE: Starten eines Maschinenprogramms im RAM des Diskettenlaufwerks
Mit den Memory- und den U-Befehlen kann man also eigene Software in das Diskettenlaufwerk übertragen, sie dort laufen lassen und schließlich im RAM abgelegte Ergebnisse wieder auslesen. Anwendungen dazu:
- Man kann den Datenzugriff optimieren, als praktisches Beispiel wurden zeitkritische Suchen in einer Datenbank komplett innerhalb des Diskettenlaufwerks vorgenommen.
- Man kann die Übertragung zwischen Diskettenlaufwerk und Rechner beschleunigen, indem man die sehr suboptimalen Übertragungsroutinen durch stärker optimierte Varianten ersetzt. Dies wurde vor allem beim seriellen CBM-Bus zwischen dem C64 und seinen Laufwerken angewendet.
- Man kann die Diskettenstation als Sklavenrechner verwenden, der im Multiprocessing Teilaufgaben übernimmt, so dass insgesamt mehr Datendurchsatz erreicht wird. Theoretisches Beispiel: Fraktalberechnung (Mandelbrotmenge). Praktisches Beispiel: Erste Stufe einer Datenbanksuche für einen Universitätsbibliothekskatalog.
Diese Möglichkeiten waren zwar oft praktisch nützlich, verhinderten aber einen sinnvollen Upgrade-Pfad ohne aufwändige und teure Maßnahmen zur Wahrung der Kompatibilität. Entsprechend bieten heutige (Festplatten-)Laufwerke solche Möglichkeiten nicht mehr, obwohl sie auch über hochgradige Eigenintelligenz in ihrer Firmware und viel internes RAM verfügen.
Verwendung der Laufwerke an Fremdcomputern
Aufgrund dieses Klartextcharakters der Befehle war es auch relativ leicht möglich, Commodore-Laufwerke (zumindest die mit parallelem IEEE-488-Bus) auch an IEEE-488-Bus-fähigen Rechnern anderer Hersteller (z. B. Tektronix) zu betreiben. Die Befehle ließen sich mühelos in deren eigenem BASIC-Dialekt als Ausgabeanweisungen formulieren und an die Geräte senden. Nur bei der Interpretierung der zurückgesendeten Ergebnisse (z. B. Directory-Listing in Form eines Commodore-Basic-Programms) waren Kenntnisse über die Struktur dieser Daten nötig.