Teil 2 Floppy-Kurs 6
Nun wird eine Schleife durchlaufen, die
die acht Fileeinträge dieses Directory-
blocks in den entsprechenden Feldern
ablegt. Zur Information geben ich Ihnen
hier nocheinmal den Aufbau eines Direc-
toryeintrags an (sh. Floppy-Kurs, Teil
4):
ByteNr. Aufgabe
----------------------------------------
000 Byte für den Filetyp.
001-002 Track und Sektor des ersten
Datenblocks dieses Files.
003-018 16 Bytes für den Filenamen.
019-020 Bei relativen Files stehen hier
Track und Sektor des ersten Si-
Sektor-Blocks (sonst unbenutzt)
021 Bei relativen Files seht hier
die Länge eines Datensatzes
(sonst unbenutzt).
022-025 unbenutzt
026-027 Zwischenspeicher des Tracks und
Sektors beim Öberschreiben mit
dem Klammeraffen (" ") vor dem
Filenamen.
028-029 Hier steht die Länge des Files
in Blocks als 16-Bit-Lo/Hi-Zahl
030-031 unbenutzt
In den Zeilen 340-360 werden nun, obiger
Liste entsprechend, der Reihe nach das
Filetypenbyte, sowie Starttrack und
-sektor des Files in die entsprechenden
Felder eingelesen. Die anschließenden 16
Zeichen stellen den Filenamen dar und
werden als Text, mit Hilfe einer
Schleife in das Feld "na$" eingelesen.
In Zeile 400 überlesen wir nun 9 Zeichen
des Fileeintrags, die für uns nicht von
Nutzen sind. In den Zeilen 410 und 420
werden nun noch Low- und High-Byte der
Blockanzahl eingelesen und umgerechnet
im Feld "bl" abgelegt. Hiernach werden
noch die beiden letzten unbenutzten
Bytes überlesen, um den Pufferzeiger
auf den Anfang des nächsten Eintrags zu
positionieren. Nun wird die Laufvariable
q um eins erhöht und an den Schleifen-
anfang zurück verzweigt. Ist die
Schleife 8 Mal durch- laufen worden, so
haben wir alle Einträge dieses
Directoryblocks eingelesen und können
den nächsten Block laden. Da der letzte
Directoryblock immer Track 0 als Folge-
track beinhaltet können wir mit der IF-
THEN-Abfrage in Zeile 450 prüfen, ob der
letzte benutzte Directoryblock schon
eingelesen wurde, oder nicht. Ist "tr"
ungleich null, so muß die Schleife noch-
mals wiederholt werden und es wird zu
Zeile 300 zurückverzweigt. Im anderen
Fall sind wir beim letzten Directory-
block angelangt und können die File-
kanäle schließen. In Zeile 480 wird nun
die Laufvariable "q" um 1 erniedrigt, da
dieser Feldindex beim letzten Durchlauf
ja noch keine neue Zuweisung erhielt.
Zeile 500 dient nun dazu, den effektiv
letzten Eintrag in diesem Directoryblock
herauszusuchen, da ja nicht unbedingt
alle 8 Einträge in diesem Block benutzt
sein müssen. Dies geschieht einfach
darin, daß wir "q" solange herunerzählen
bis in der Variablen na$(q) ein Text
steht. Da Leereinträge nur Nullen ent-
halten, ist der Filename bei solchen
Einträgen 16 Mal der Wert CHR $(0), was
einem Leerstring ("") entspricht.
Abschließend wird in das aufrufende Pro-
gramm zurückverzweigt. In unseren Feld-
variablen befinden sich nun alle Infor-
mationen des Directorys, sowie der
Diskettenname in "dn$" und die ID in
"id$". In der Laufvariablen "q" steht
die Anzahl der vorhandenen Einträge
minus 1 (beachten Sie bitte, daß im
Indexfeld 0 ebenfalls ein Eintrag ent-
halten ist. "q" bezeichnet lediglich die
Nummer des letzten Eintrags). Nun wissen
wir also schon, wie wir die Directory-
informationen in den Computer bekommen.
Die Hauptroutine unseres UN-DEL-Progamms
muß jetzt also nur noch die Unterroutine
bei Zeile 200 aufrufen um sie zu
erhalten. Um jetzt alle DEL-Einträge
herauszusuchen, müssen wir lediglich
alle Einträge heraussuchen, die in den
unteren 3 Bits des Filetypenbytes den
Wert 0 stehen haben. Wir müssen uns des-
halb auf die unteren 3 Bits beschränken,
da in den Bits 7 und 6 ja auch noch In-
formationen über das File gespeichert
sind. In den Zeilen 1100-1120 des Haupt-
programms werden diese Einträge nun he-
rausgesucht und deren Feldindizes im
Feld "li" abgelegt. Das Hauptprogramm
von UNDEL beginnt übrigens bei Zeile
1000. Aus Platzgründen will ich Ihnen ab
jetzt nur noch die Zeilen auflisten, die
für uns interessant sind. Der Rest dient
hauptsächlich der Bildschirmformatierung
und soll uns hier deshalb nicht interes-
sieren. Das ganze Programm können Sie
sich ja einmal auf dieser MD anschauen.
Hier nun die Zeilen 1100-1120:
1100 z=0
1105 fori=0toq
1110 if(ty(i)and7)=0thenli(z)=i:z=z+1
1120 next
Wie Sie sehen, benutzen wir hier die
Laufvariable "z" als Indexvariable für
das Feld "li". Mit dem Ausdruck "ty(i)
and 7" isolieren wir die unteren drei
Bits des Typenbytes und löschen die
evtl. gesetzten Bits 7 und 6 für den
IF-THEN-Vergleich. Wenn "z" nun größer
Null ist, so wurden DEL-Files gefunden.
Selbige werden in den Zeilen 1190-1230
auf dem Bildschirm ausgegeben und es
wird gefragt, welches davon gerettet
werden soll. In den Zeilen 1240 bis 1350
wird nun nach dem Typ des Files gefragt
und ob es evtl. auch vor erneutem
Löschen geschützt werden soll. Hier
wieder ein Programmauszug:
1240 gosub100:print"Zu retten: ";na$(li(
1250 print"0 - DEL"
1260 print"1 - SEQ"
1270 print"2 - PRG"
1280 print"3 - USR"
1290 print"4 - REL"
1300 input"Welchen Filetyp soll ich
zuordne ";t1
1310 if(n<0)or(n>4)then1300
1320 print"File auch schuetzen (J/N) ?"
1330 geta$:ifa$=""then1330
1340 ifa$="j"thent1=t1+64
1350 t1=t1+128:ty(li(n))=t1
Wie Sie sehen, wird in die Variable "t1"
eine Zahl zwischen 0 und 4 eingelesen.
Die Zahlen, die die einzelnen Typen
zuordnen, entsprechen den Codes, die
auch die Floppy zur Erkennung des File-
typs benutzt. In den Zeilen 1320-1340
wird nun gefragt, ob das File auch vor
dem Löschen geschützt werden soll. Dies
regelt Bit 6 im Filetyp-Byte. Soll das
File geschützt werden, so wird zu der
Variablen "t1" der Wert 64 hinzuaddiert,
was dem Setzen des 6. Bits entspricht.
Zusätzlich müssen wir noch Bit 7 setzen,
das anzeigt, daß das File ein gültiges
File ist. Dies geschieht durch addie-
ren des Wertes 128. Nun müssen wir nur
noch den neuen Wert für den Filetyp in
die Feld- variable "ty" übernehmen. Als
nächstes muß der neue Filetyp im Direc-
tory eingetragen und die Datenblocks
des Files als 'belegt' gekennzeichnet
werden. Dies geschieht in den Zeilen
1370-1550. Hier wieder ein Auszug:
1370 gosub100:print"Schreibe neuen
Eintrag"
1380 bl=int(li(n)/8):ei=li(n)-bl*8
1390 tr=dt(bl):se=ds(bl)
1400 open1,8,15,"i":open2,8,2,"#"
1410 print#1,"u1 2 0";tr;se
1420 po=2+ei*32
1430 print#1,"b-p 2";po
1440 print#2,chr$(t1);
1450 print#1,"u2 2 0";tr;se
1460 :
In den Zeilen 1380-1390 wird nun zu-
nächst den Variablen TR und SE die Werte
für den Directoryblock, in dem der
Eintrag steht zugewiesen. Als nächstes
öffnen wir einen Befehls- und einen
Pufferkanal mit den logischen File-
nummern 1 und 2 (wie auch schon in der
Dir-Lese-Routine). In Zeile 1410 wird
der Block des Eintrags eingelesen.
Nun muß der Pufferzeiger auf den Anfang
des Eintrags positioniert werden. Da
jeder Fileeintrag 32 Bytes lang ist,
errechnet sich seine Anfangsposition aus
seiner Position im Block (steht in der
Variablen "ei", die in Zeile 1380
definiert wurde) multipliziert mit 32.
Zusätzlich müssen wir noch zwei Bytes
aufaddieren, in denen Track- und
Sektornummer des Folgeblocks stehen
(ganz am Anfang des Directoryblocks). In
Zeile 1430 wird nun auf die errechnete
Position positioniert. Nun müssen wir an
dieser Stelle nur noch das neue Typen-
byte eintragen (geschieht in Zeile 1440)
und den Directoryblock mittels "U2"
wieder auf die Diskette zurückschreiben.
Schon ist der Fileeintrag geändert!
Zum Schluß müssen wir noch alle vom File
belegten Blocks heraussuchen und wieder
neu belegen. Den ersten davon finden wir
in den Feldern "ft" und "fs". Hier
wieder ein Programmauszug:
1465 z=0
1470 print"Belege Blocks neu... "
1480 tr=ft(li(n)):se=fs(li(n))
1490 print#1,"b-a 0";tr;se
1500 print#1,"u1 2 0";tr;se
1505 z=z+1
1510 gosub600:tr=a
1520 gosub600:se=a
1530 iftr<>0then1490
1540 close1:close2
1550 printz;"Blocks gefunden."
Hier wird die Variable "z" dazu benutzt,
die gefundenen Blocks zu zählen. In
Zeile 1480 werden nun die Feldeinträge
in "ft" und "fs" in TR und SE Übertra-
gen. Zeile 1490 benutzt nun den Block-
Allocate-Befehl um diesen Block als
'belegt' zu kennzeichnen. In Zeile 1500
wird er dann in den Puffer gelesen, da
seine ersten beiden Bytes ja auf den
nächsten Block des Files zeigen. Dessen
Track- und Sektornummer wird nun in den
Zeilen 1510 und 1520 in TR und SE ein-
gelesen und für den nächsten Durchlauf
der Schleife verwendet. Sollte TR jedoch
den Wert 0 aufweisen, so sind wir beim
letzten Block angelangt und können die
Blockbelegung beenden. Dies regelt die
IF-THEN-Anweisung in Zeile 1530.
Somit wären alle wichtigen Teile des UN-
DEL-Programms besprochen. Um einen
Gesamtüberblick zu erhalten, rate ich
Ihnen, sich das Programm auf dieser MD
einmal auszudrucken und anzuschauen.
Öbrigens beinhaltet das Programm noch
einen kleinen Schönheitsfehler: Wenn Sie
nämlich z.B. 9 Files auf einer Diskette
haben, und das letzte davon löschen, so
findet es die Directory-Lese-Routine
nicht mehr. Das liegt daran, daß nach
dem Löschen des Eintrags der zweite
Directoryblock ja nicht mehr benötigt
wird und deshalb als Folgeblock Track 0,
Sektor 255 im ersten Directoryblock
eingetragen wird. Um diesen Fehler zu
beheben, können Sie ja eine Routine
schreiben, die alle Directoryblocks der
Reihe nach einliest. Das ist zwar sehr
zeitaufwendig, könnte jedoch den Fehler
beheben. Sie können dabei davon aus-
gehen, daß die Folgetracks und -sektoren
beim Directory immer gleich sind. Bei
einem vollen Directory (144 Einträge),
können Sie so diese Einträge mit Hilfe
eines Diskettenmonitors einfach
herausfinden.
Ich verabschiede mich hiermit von Ihnen
bis zur nächsten Ausgabe, wo wir uns an
die Floppyprogrammierung in Assembler
heranwagen möchten.
(ub)