Magic Disk 64

home to index to text: MD9211-KURSE-FLOPPY-KURS_6.2.txt

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)

Valid HTML 4.0 Transitional Valid CSS!