Teil 2 Floppy-Kurs 6
Nun wird eine Schleife durchlaufen, die
die acht Fileeinträge dieses Directoryblocks in den entsprechenden Feldern
ablegt. Zur Information geben ich Ihnen
hier nocheinmal den Aufbau eines Directoryeintrags 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-01816 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 Lowund 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 Schleifenanfang zurück verzweigt. Ist die
Schleife 8 Mal durchlaufen 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 Folgetrack 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 nochmals wiederholt werden und es wird zu
Zeile 300 zurückverzweigt. Im anderen
Fall sind wir beim letzten Directoryblock angelangt und können die Filekanä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 enthalten, ist der Filename bei solchen
Einträgen 16 Mal der Wert CHR $(0), was
einem Leerstring ("") entspricht.
Abschließend wird in das aufrufende Programm zurückverzweigt. In unseren Feldvariablen befinden sich nun alle Informationen 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 enthalten ist." q" bezeichnet lediglich die
Nummer des letzten Eintrags) . Nun wissen
wir also schon, wie wir die Directoryinformationen 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 deshalb auf die unteren 3 Bits beschränken, da in den Bits 7 und 6 ja auch noch Informationen über das File gespeichert
sind. In den Zeilen 1100-1120 des Hauptprogramms werden diese Einträge nun herausgesucht 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 interessieren. Das ganze Programm können Sie
sich ja einmal auf dieser MD anschauen.
Hier nun die Zeilen 1100-1120 :
1100 z=0
1105 fori=0 toq 1110 if( ty( i) and7)=0 thenli( z)= i: z= z+11120 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 Filetyps 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 addieren des Wertes 128 . Nun müssen wir nur
noch den neuen Wert für den Filetyp in
die Feldvariable " ty" übernehmen. Als
nächstes muß der neue Filetyp im Directory 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 zunächst den Variablen TR und SE die Werte für den Directoryblock, in dem der
Eintrag steht zugewiesen. Als nächstes
öffnen wir einen Befehlsund einen
Pufferkanal mit den logischen Filenummern 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 Trackund
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 Typenbyte 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
Trackund Sektornummer wird nun in den
Zeilen 1510 und 1520 in TR und SE eingelesen 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 ausgehen, 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)