Diskettenoperationen

Aufbau des Volume Labels

Spur 0 Seite 0 Sektor 7 enthält auf jeder IBM-formattierten Diskette den Volume Label (dt. Diskettenkennsatz). Vor dem ersten Zugriff auf eine Diskette muß mittels des Sense-Kommandos dieser Kennsatz gelesen werden. In ihm steht der Aufbau des Rests der Diskette beschrieben. Zu bemerken ist, daß alle Texte und numerische Größen als EBCDIC-String eingetragen sind, damit die Diskette zwischen verschiedenen (IBM-)Systemen austauschbar ist.
Offset  Name                        Beschreibung/Inhalt
------------------------------------------------------------------------------
00-03   Volume Label ID and Number  Kennzeichnet diesen Sektor als Volume
                                    Label; enthält Text 'VOL1'
04-09   Volume Identifier           Name der Diskette; Standard 'VOLID '
0A      Accessibility               Wenn ungleich Blank, darf auf die Diskette
                                    nicht zugegriffen werden
0B-0F   (reserviert)
10-17   (reserviert)
18-24   System Identification       Kennung des Systems, das die Diskette
                                    initialisiert hat, z.B. 'IBM5100' bei der
                                    IBM 5110/5120.
25-32   Owner Identification        Optionaler Name des Eigentümers;
                                    Standard 'OWNERID       '
33-3F   (reserviert)
40      Extended Label Area         Gibt bei einer Diskette 2D die Anzahl der
                                    zusätzlichen Spuren für das Inhaltsver-
                                    zeichnis an (Blank, 0-9)
41-46   (reserviert)
47      Volume Surface Indicator    Blank=Diskette 1, '2'=Diskette 2,
                                    'M'=Diskette 2D
48      Extended Arrangement Ind.   unbenutzt, muß Blank sein
49      Special Requirements Ind.   unbenutzt, muß Blank sein
4A      (reserviert)
4B      Physical Sector Length      Blank=128, '1'=256, '2'=512, '3'=1024
4C-4D   Phys. Record Sequence Code  Gibt den optionalen Interleave-Faktor an;
                                    Blank,'01'=Interleave 1:1
4E      (reserviert)
4F      Label Standard Version      muß 'W' sein
50-7F   (unbenutzt)

Aufbau eines Verzeichniseintrags

Das Inhaltsverzeichnis beginnt bei Spur 0 Seite 0 Sektor 8, jeder Eintrag hat eine Größe von 128 Bytes. Auf einer Diskette 2D enthalten die zusätzlichen Sektoren aufgrund der Größe von 256 Bytes jeweils zwei Einträge. Auch in den Einträgen sind alle Angaben in EBCDIC.
Offset  Name                        Beschreibung/Inhalt
------------------------------------------------------------------------------
00-03   Header Label ID and Number  Enthält 'HDR1' bei benutzten Einträgen;
                                    unbenutzte haben ein 'D' in der ersten
                                    Stelle
04      (reserviert)
05-15   Data Set Identifier         Dateiname; darf nicht doppelt vorkommen
16-1A   Block Length                Größe eines logischen Dateiblocks; z.B.
                                    '  128', '00256' etc.
1B      Record Attribute            muß Blank sein
1C-20   Beginning of Extent (BOE)1  Erster Sektor der Datei in der Form CCHSS
                                    CC=Spur, H=Seite, SS=Sektor
21      Physical Record Length      Sektorgröße, muß gleich sein wie im
                                    Volume Label
22-26   End of Extent (EOE)1        Letzter Sektor, der für die Datei markiert
                                    ist
27      Record Block Format         Angabe, ob Daten in FM oder MFM vorliegen
28      Bypass Indicator            unbenutzt; muß Blank sein
29      Data Set Security           muß Blank sein
2A      Write Protect Indicator     Blank=Schreiben erlaubt;
                                    'P'=Datei schreibgeschützt
2B      Exchange Type Indicator     Austauschdatentyp, abhängig vom Disketten-
                                    format; i.d.R. Blank, 'E' oder 'H'
2C      Multivolume Data Set Ind.   unbenutzt
2D-2E   Volume Sequence Indicator   unbenutzt
2F-34   Creation Date               unbenutzt; Format 'JJMMTT'
35-38   Record Length               Größe eines Datensatzes innerhalb der
                                    Datei; abhängig von Dateityp
39-3D   Offset to Next Record Space unbenutzt; muß Blanks enthalten
3E-41   (reserviert)
42-47   Expiration Date             unbenutzt; muß Blanks enthalten
48      Verify/Copy Indicator       unbenutzt
49      Data Set Organization       i.d.R. Blank
4A-4E   End of Data (EOD)1          Adresse des ersten Sektors hinter den
                                    Daten
4F-5E   (reserviert)
5F-6B   System Code                 Kennung des Systems, das die Datei erzeugt
                                    hat, z.B. 'IBM5100      '
6C-6D   File Application Type       Dateityp; zweistellige Zahl
6E-7F   (unbenutzt)
1 Zusammenhang zwischen BOE, EOE und EOD graphisch dargestellt:
     /------ markierter Platz auf Diskette ----------\
    /                                                 \

...-----------------------------------------------------...
   |                                   |               |
   |     benutzter Platz der Datei     |   (frei)      |
...-----------------------------------------------------...
   ^                                    ^              ^
   |                                    |              |
  BOE                                  EOD            EOE
BOE gibt den ersten Sektor der markierten Datei an, EOE den letzten. Innerhalb dieser Grenzen kann die Datei beliebige Größe annehmen (in Vielfachen der Sektorgröße), der erste Sektor des freien Bereichs wird in EOD angegeben. Bei einer leeren Datei, wie sie mit dem MARK-Befehl erzeugt wird, ist EOD=BOE. Wenn die Datei keinen freien Platz enthält, zeigt EOD auf den ersten Sektor hinter EOE. Man muß sich über dieses Schema im Klaren sein, wenn man Dateioperationen durchführen will.

Aufbau des Arbeitsbereiches (Work Area)

Offset  Größe     Beschreibung/Inhalt
------------------------------------------------------------------------------
00      2         Track (Bits 0-7), Seite (Bit 8), Sektor (Bits 9-15)                                                                      
02      2         Größe des benutzten Platzes in Anzahl Sektoren (EOD-BOE)
04      2         Größe der markierten Datei in Anzahl Sektoren (EOE-BOE)
06      2         Dateinummer nach Find-Operation
08      1         Physical record size (0=128 Bytes, 1=256 Bytes, ...)
09      1         [Letzte I/O Funktionsnummer]

Öffnen bzw. Auffinden einer Datei

Ein Öffnen mit einer Art "Open"-Befehl gibt es in dem Sinne nicht. Es geht vielmehr darum, vor der Benutzung einer Datei sie auf Diskette aufzufinden. Dazu muß zuerst die Diskette selber dem System bekannt sein. Dies wird mit dem Sense-Kommando erledigt. Danach muß der Verzeichniseintrag der gewünschten Datei gefunden werden, welches mit dem Find-Kommando erfolgt. Dabei gibt es zwei Möglichkeiten, einen bestimmten Eintrag zu finden. Zum einen kann man direkt die Dateinummer angeben, welche identisch mit der Nummer des Verzeichniseintrags ist. Zum anderen kann man den Dateinamen der gesuchten Datei benutzen, um den Eintrag zu finden.

Auf jeden Fall muß als erste Operation ein Sense stattfinden. Dabei wird der I/O Supervisor wie im Kapitel über den IOCB aufgerufen. Der IOCB für ein Sense muß folgende Werte enthalten (zusätzlich zu denen für die Geräteadressierung):

Nach dem Sense steht in IOCB_BS die Größe eines Sektors in Bytes.
In IOCB_CI1 steht die Größe des benutzen Arbeitsbereichs, also 10 Bytes.
In IOCB_Stat1 steht der String '1D'.

Direkt danach kann die gewünschte Datei mittels Find gesucht werden, dabei wird unterschieden zwischen:
Dateiname als Parameter
Dateinummer als Parameter

Wichtig: Während allen Operationen, die dieselbe Datei betreffen, muß IOCB_WA immer auf denselben Puffer zeigen. Die I/O-Routinen speichern darin Informationen über die aktuelle Datei.

Wenn die Datei gefunden werden konnte, enthält IOCB_Ret den Wert 0. Wenn sie nicht gefunden werden konnte (und kein anderer Fehler auftrat), wird $F4F1 = '41' als Fehlercode zurückgeliefert.
Bei Erfolg steht im Puffer der entsprechende Verzeichniseintrag, in IOCB_CI2 steht der Zeiger darauf. Der Aufbau des Eintrags wurde schon weiter oben erklärt. Es gibt jedoch zwei Ausnahmen:

Offset  Name                        Beschreibung/Inhalt
------------------------------------------------------------------------------
25-26   End of Extent               Hier steht jetzt eine 16-Bit Integerzahl,
                                    die die Größe des markierten Bereichs der
                                    Datei in Anzahl Sektoren angibt.

4D-4E   End of Data                 16-Bit Integerzahl, die die Größe des
                                    benutzen Bereichs in Anzahl Sektoren
                                    angibt.
Auf diese Weise muß man sich nicht selber mit dem Diskettenlayout herumschlagen, um die Größe einer Datei in Erfahrung zu bringen.

Lesen oder Schreiben eines Blocks

Das Lesen bzw. Schreiben einer Datei kann nur in Vielfachen der Sektorgröße, auch Block genannt, geschehen. Der IOCB dazu:

Über den Offset läßt sich ein bestimmer Bereich innerhalb einer Datei lesen oder beschreiben, da keine explizite "File Seek"-Operation existiert.

Erzeugen einer neuen Datei

Um eine neue Datei zu erzeugen, muß zuerst ein unbenutzter Verzeichniseintrag gefunden werden. Dies geschieht am einfachsten, indem man mittels Find alle Dateinummern durchgeht, bis entweder Fehler '41' oder '36' zurückgeliefert wird. Bei '41' wurde ein unbenutzter Eintrag gefunden, der zur Erzeugung einer neuen Datei benutzt werden kann. Bei '36' wurde das Ende des Inhaltsverzeichnisses erreicht, demnach existiert kein freier Eintrag mehr.
Mit dem leeren Eintrag wird jetzt ein Mark-Kommando ausgeführt. Die benötigten IOCB-Parameter sind wie folgt:

Damit wurde das gleiche erreicht wie beim MARK-Befehl in BASIC, bzw. )MARK in APL. Um jedoch mit dieser Datei arbeiten zu können, muß noch ein Find-Kommando mit der Dateinummer dieser Datei folgen. Dann kann beliebig innerhalb dieser Datei geschrieben und gelesen werden.
Allerdings muß die aktuelle Dateigröße im Verzeichniseintrag angepaßt werden, evtl. möchte man auch den Dateinamen von standardmäßig 'SYSxxxx' mit xxxx=Dateinummer dieser Datei gegen einen anderen tauschen. Dazu lädt man mittels Find den Verzeichniseintrag in einen Puffer. Dort kann der Dateiname, und vor allem die aktuelle Dateigröße bei Offset $4D (EOD) geändert werden. Die Änderungen werden mit dem Kommando Write Header zurückgeschrieben.

Freigeben oder Löschen einer Datei

Das Freigeben einer Datei bewirkt, daß der gesamte markierte Bereich zur Verfügung steht, die Datei also für neue Zwecke verwendet werden kann. Dies erreicht man, indem man mit Find und anschließendem Write Header die aktuelle Dateigröße (EOD) auf Null setzt.

Im Unterschied dazu wird beim Löschen einer Datei der entsprechende Verzeichniseintrag als unbenutzt gekennzeichnet. Dazu markiert man diese Datei neu, und zwar mit einer Größe von 0 kB (in IOCB_CI1).

Absolutes Lesen oder Schreiben eines Sektors

Beim absoluten Lesen oder Schreiben wird unter Umgehung der Dateistrukturen direkt auf einen Sektor der Diskette zugegriffen. Nach dem obligatorischen Sense-Kommando muß daher kein Find folgen. Der Aufbau des IOCB für den Zugriff auf einen Sektor sieht wie folgt aus:

Nötige Spurwechsel werden automatisch ausgeführt.

Weitere Befehle

Bei gesetztem Bit für den absoluten Sektorzugriff sind nur folgende Befehle erlaubt: Read, Write, Find ID und Initialize Head, alle anderen werden mit dem Fehlercode 02 zurückgewiesen.