The following article was printed in March 1985 of the magazine „MC".
A Turbo-Pascal programm for direct disc access.
Gerhard Strube

Direkter Diskettenzugriff unter CP/M-Plus

Was macht der Benutzer eines Computers mit dem Betriebssystem CP/M-3.0, wenn er das Inhaltsverzeichnis seiner Diskette oder Harddisk reparieren muß? Wie spricht man unter CP/M-Plus die Disketten an? Hier steht es, samt einem in Turbo-Pascal geschriebenen Programm.

Wer einen Computer mit Z80 (8080, 8085) und mehr als 64 KByte RAM besitzt und von CP/M-2.2 auf die neue Version 3.0, auch CP/M-Plus genannt, umgestiegen ist, lernt bald die Vorteile des neuen Betriebssystems von Digital Research schätzen. Der Diskettenzugriff erfolgt (wegen verbesserter Durchsuchung des Inhaltsverzeichnisses) schneller, das System zeigt sich beim Diskettenwechsel gutmütig, und es bietet Komfort wie Datumsmarkierung der Dateien oder die Möglichkeit, eine eingegebene Kommandozeile mit einem Tastendruck zu wiederholen und gegebenenfalls zu korrigieren. Natürlich ist CP/M-Plus kompatibel zum alten CP/M-2.2, so daß die gewohnten Programme anstandslos laufen - fast alle! Die herbe Ausnahme von der Regel stellen gerade die „Disk Utilities" dar, jene Programme also, die einem aus der Patsche helfen, wenn man eben aus Versehen eine wichtige Datei gelöscht hat. Mit solchen Programmen kann man nämlich direkt auf die Sektoren einer Diskette zugreifen und durch Ändern der von CP/M benutzten Löschmarkierung $E5 vor dem Dateinamen in der Directory (zu $00 oder der gewünschten Benutzernummer) die unersetzliche Datei wieder zum Leben erwecken.

Die Komplikationen bei CP/M-Plus

Wie kommt es, daß viele dieser Programme unter CP/M-Plus abstürzen? Dazu ist zu sagen, daß das BDOS (Basic Disk Operating System, der Kern von CP/M), nur Dateien kennt, aber keine Spuren und Sektoren. Die Betriebssystem-Funktionen, die es Anwenderprogrammen anbietet, umfassen nicht die Ansteuerung des Directory-Bereichs und der für CP/M selbst reservierten Spuren. Entsprechende Funktionen sind hingegen im maschinenspezifischen Teil von CP/M, dem BIOS (Basic Input-Output System), implementiert: Spur wählen (Funktion Nr. 10), Sektor wählen (Nr. 11), Sektor lesen (Nr. 13) und Sektor schreiben (Nr. 14) sind einige dieser im BIOS verfügbaren Diskettenfunktionen. Unter CP/M-2.2 können diese Funktionen direkt aufgerufen werden (durch Anspringen ihrer Anfangsadressen), und die diversen Utility-Programme (z.B. DUU von Ward Christensen) tun dies auch. CP/M-3.0 hingegen unterstützt diese Art des Zugriffs nur noch für einige wenige BIOS-Funktionen (im wesentlichen die Bedienung von Konsole und Drucker). Gerade die diskettenspezifischen BIOS-Funktionen befinden sich bei Systemen mit mehr als 64 KByte meist nicht in der dem Benutzer zugänglichen Speicherbank. Die Folge: Wenn ein Programm die (nur für eine andere Speicherbank gültige) Adresse einer BIOS-Funktion zur Diskettensteuerung anspringt, stürzt es ab und das Betriebssystem mit ihm. Nur der Reset-Knopf kann noch helfen.

Der Weg zu den Bits

Natürlich versperrt das neue CP/M dem Benutzer nicht den Weg zum BIOS. Im Gegenteil können alle, auch die zahlreichen neuen BIOS-Funktionen von jedem Anwenderprogramm aus angesprochen werden, nur eben auf eine andere Art: An die Stelle direkter Sprungbefehle tritt der Aufruf einer neugeschaffenen BDOS-Funktion (Nr. 50), wobei die Adresse eines vom Anwenderprogramm festgelegten Parameterblocks übergeben wird. Dort findet das Anwenderprogramm auch Rückgaben (z.B. Fehlercodes) aus dem BIOS. Bild 1 zeigt eine entsprechende Pascal-Funktion (in dem für solche Aufgaben besonders geeigneten Turbo-Dialekt; sie ersetzt die dort verfügbaren Funktionen Bios und BiosHL), die diesen Parameterblock vom Hauptprogramm abschirmt und stattdessen die Parameter in der bei Pascal gewohnten Form übernimmt und zurückgibt. Was dabei ans aufrufende Hauptprogramm zurückgegeben werden muß (meist Akku oder HL-Register), wird anhand der Funktionsnummer entschieden. Der Ablauf der Diskettensteuerung gestaltet sich in CP/M-Plus und in CP/M-2.2 weitgehend identisch: zuerst die Auswahl des Laufwerks (BIOS-Funktion Nr. 9), dann Spur und Sektor vorwählen (Funktionen 10 und 11), Zieladresse für zu lesende Daten bzw. Adresse der zu schreibenden Daten angeben (Funktion Nr. 12), sowie für CP/M-Systeme mit mehreren Speicherbänken die Angabe der Bank-Adresse (Funktion 28). Nachdem alle diese Vorbereitungen getroffen sind, kann eine der beiden Bios-Funktionen 13 (Sektor lesen) oder 14 (Sektor schreiben) aufgerufen werden. Noch einen wichtigen Unterschied zwischen CP/M-2.2 und CP/M-3.0 gilt es zu berücksichtigen. Grundsätzlich nehmen alle Versionen von CP/M an, daß ein Sektor 128 Bytes Daten enthält (wie dies in den alten Zeiten, also so um 1972, bei 8-Zoll-Single-Sided-Single-Density-Laufwerken Standard war). CP/M-2.2 und ältere Versionen kennen nur diese sog. logischen Sektoren. Selbst wenn also die tatsächliche Sektorgröße ein Vielfaches (üblicherweise 256, 512, oder 1024 Bytes) beträgt - man nennt dies die physische Sektorgröße - mußte dies vor dem Betriebssystemkern (d.h. dem BDOS) verborgen werden. Ins BIOS eingebaute Routinen hatten dafür zu sorgen, daß größere physische Sektoren beim Lesen zerlegt und beim Schreiben mehrere logische Sektoren zu einem physischen Sektor zusammengefügt wurden. In CP/M-3.0 dagegen übernimmt das BDOS selbst dieses Sektor-Deblocking und Blocking. Die Konsequenz davon ist, daß die BIOS-Funktionen 13 und 14 (Sektor lesen bzw. schreiben) physische Sektorengrößen verarbeiten. (Anm.: Wenn ein BIOS benützt wird, das ursprünglich für CP/M-2.2 geschrieben wurde, kann es vorkommen, daß das Deblocking noch intern gehandhabt wird. Dies ist z. B. beim Wavemate Bullet der Fall, wo die Disketten ohne Rücksicht auf deren tatsächliche physische Sektorgröße stets die scheinbare Sektorgröße 128 haben, während für die Harddisk die Blocking/Deblocking-Routinen des BDOS benutzt und vom BIOS tatsächlich 512 Bytes übergeben werden.)

DoDisk: ein kenntnisreicher Disk-Doktor

In CP/M-Plus entspricht ein logischer Sektor also in der Regel einem Teil eines physischen Sektors. Da die Zuordnung beider durch das BDOS erfolgt, muß jedes Anwenderprogramm, das am BDOS vorbei direkt vom BIOS Gebrauch macht, diese Zuordnung selbst leisten. Außerdem muß eine etwaige Übersetzung der Sektornummer (neue BIOS-Funktion 16) vorgenommen werden. Dies alles wird von der Pascal-Prozedur DoDisk (im Listing aus Bild 2) berücksichtigt, der das Hauptprogramm je ein Array für den jeweils bearbeiteten logischen Sektor und eines für den meist größeren physischen Sektor zur Verfügung stellt.
Das Programm DISK3 (Bild 2) gestattet es, beliebige Sektoren von Diskette oder Harddisk zu lesen, zu verändern, und an dieselbe oder eine andere Stelle zu schreiben. Die Bildschirmdarstellung (Bild 3) ist ausführlich genug, um eine Gebrauchsanweisung entbehrlich zu machen. Hingewiesen sei noch darauf, daß dem Benutzer auch genaue Informationen über Organisation und Kapazität des von ihm gerade bearbeiteten Laufwerks mitgeteilt werden. Die dazu nötigen Informationen entnimmt die Prozedur UserFrame einer über das BDOS (Funktion 31) zugänglichen Tabelle (Disk Parameter Block).
Außerdem zeigt das Programm einige der in Turbo-Pascal steckenden Möglichkeiten: Include-Files, Variablen mit absoluter Adresse (so daß beispielsweise eine Integervariable adressengleich ist mit einem Pointer). Vor allem macht das Programm von der in Turbo-Pascal möglichen Installation terminalspezifischer Funktionen Gebrauch, wie z.B. Cursoradressierung (GotoXY) oder Hervorhebung (LowVideo und HighVideo). Deutlich wird auch der Vorteil von Pascal, komplexe Datenstrukturen (wie den Disk Parameter Block DPB) ohne Verrenkungen darstellen zu können. Die Zeiten sind wohl vorbei, als man Utilities wie diese noch in Assembler schreiben mußte.

[Find here the sources for the main program DISK3.PAS and the include files UBIOS.PAS and HEXIO.PAS]

Scanned by Werner Cirsovius
September 2002
© Franzis' Verlag