Magic Disk 64

home to index to html: MD9211-KURSE-FLOPPY-KURS_6.2.html
          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)



Valid HTML 4.0 Transitional Valid CSS!