Magic Disk 64

home to index to text: MD9210-KURSE-FLOPPY-KURS_5.txt
----------------------------------------
               Floppy-Kurs              
      "Es rappelt in der Kiste..."      
                (Teil 5)                
----------------------------------------

Herzlich Willkommen zum 5 . Teil unseres Floppykurses. In diesem Monat wollen wir die Kenntnisse, die wir bisher über die Floppy erfahren haben in die Praxis umsetzen. Das heißt, daß wir in diesem Kursteil einige nützliche Anwendungen zum bisher Erlernten programmieren werden. Diese werden zunächst in BASIC behandelt. Im nächsten Kursteil wollen wir dann auf die Programmierung in Assembler eingehen.

1) DISKETTE SCHREIBSCHÖTZEN             

Kommen wir zu unserem ersten Programm- beispiel. Wie ich im dritten Teil dieses Kurses schon erwähnte ist es ganz einfach möglich, eine Diskette softwaremäßig schreibzuschützen. Sie können anschließend weder etwas auf die Diskette schreiben, noch etwas von ihr löschen.
Das Laden von Programmen funktiert jedoch nach wie vor. Einzige Möglichkeit die Diskette wieder beschreibbar zu machen ist dann das Formatieren ( oder nochmaliges Behandeln mit unserem Programm) .
Wie realisieren wir nun einen solchen Schreibschutz? Nun, wie wir mittlerweile ja wissen, legt die Floppy beim Formatieren einer Diskette im Diskheaderblock einige wichtige Informationen über die Diskette ab. Hier steht unter anderem auch das Formatkennzeichen, das bei der 1541 den Buchstaben " A" darstellt. Andere Commodorelaufwerke ( z. B. das eines alten CBM4040) haben dort ein anderes Zeichen stehen. Da Commodore bei den alten Laufwerkstypen ähnliche Aufzeich- nugsformate benutzte, sind die Disketten von Commodorelaufwerken bis zu gewissen Grenzen untereinander kompatibel. Meist unterscheiden sie sich nur in der Aufzeichnungsdichte ( mehr Tracks auf einer Diskette) . Um nun zu vermeiden, das Laufwerke von verschiedenen Rechnern die Daten einer Diskette eines anderen Laufwerks zerstören, wurde eine Sicherung in die 1541 eingebaut. Sie beschreibt ausschließlich nur Disketten, die ein " A" als Formatkennzeichen tragen. Andere werden nicht verändert, wohl aber kann von Ihnen gelesen werden. Es genügt nun also, das Formatkennzeichen in ein anderes Zeichen umzuwandeln, und die 1541 wird keine Daten mehr darauf schreiben.
Dies geschieht im Prinzip ganz einfach.
Wir müssen lediglich den Diskheaderblock einlesen, das 3 . Byte ( hier steht nämlich das Formatkennzeichen) in ein anderes Zeichen als " A" abwandeln und den Block wieder auf die Diskette zurückschreiben. Abschließend muß die Diskette noch initialisiert werden, damit das Betriebssystem der Floppy, das DOS, die neue Formatkennung auch in den Floppyspeicher übernimmt.
Ein Programm, das eine Diskette mit Schreibschutz versieht und ihn wieder entfernt finden Sie auf dieser MD unter dem Namen " FK. SCHREIBSCHUTZ" . Die Unterroutine, mit der eine Diskette geschützt wird, steht in den Zeilen 400 bis 470 dieses Programms. Hier sind sie nochmals aufgelistet:
Unterroutine " Diskette sichern" :

400 OPEN 1,8,15,"I": OPEN 2,8,2,"#"     
410 PRINT#1,"U1 2 0 18 0"               
430 PRINT#1,"B-P 2 2"                   
440 PRINT#2,"B";                        
450 PRINT#1,"U2 2 0 18 0"               
460 PRINT#1,"I"                         
470 CLOSE1:CLOSE2:RETURN                

Zunächst einmal öffnen wir hier den Befehlskanal und übergeben gleichzeitig einen Initialisierungsbefehl an ihn. Mit letzterem werden alle Grunddaten der eingelegten Diskette ( z. B. ID, Formatkennung, etc.) in den Speicher der Floppy übertragen. Man sollte vor einer direkten Manipulation des Diskheaderblocks diesen Befehl aufrufen. Desweiteren öffnen wir einen Pufferkanal mit der Kanalnummer 2( also Sekundäradresse 2) um Blockoperationen durchführen zu können. In Zeile 410 wird nun Spur 0 von Track 18 in den Puffer, dem Kanal 2 zugeordnet ist, eingelesen. Dies tun wir mit dem " U1"- Befehl, der besser ist als " Block-Read"(" B-R") . Hiernach folgt die Positionierung des Pufferzeigers auf das 2 . Byte ( mit dem 0 . Byte eigentlich das dritte Byte) des Puffers. In Zeile 440 wird nun der Buchstabe " B" an diese Position geschrieben. Wichtig ist hierbei das Semikolon (" ;") nach dem PRINT-Befehl, da letzterer ohne Semikolon noch ein CHR$(13) nachsenden würde, womit wir einen Teil der BAM überschreiben würden!
Nun muß der geänderte Block nur noch mit Hilfe des " U2"- Befehls auf die Diskette zurückgeschrieben werden. Damit unsere Änderung auch in den Floppyspeicher übernommen wird muß abschließend die Diskette wieder initialisiert werden. In Zeile 470 werden die beiden Filekanäle wieder geschlossen und zum Hauptprogramm zurückgekehrt.
Nun soll unser Programm den Diskettenschutz ja auch wieder rückgängig machen können. Dies geschieht im Prinzip wieder genauso. Wir müssen lediglich die fremde Formatkennung wieder in ein " A" umwandeln. Jedoch ergibt sich hierbei ein kleineres Problem. Dadurch, daß die Diskette ja schreibgeschützt ist, können wir den modifizierten Disk-Header ja nicht mehr auf die Diskette zurückschreiben! Hier behilft man sich mit einem kleinen Trick. In der Speicherstelle $0101( dez.257) des Floppy-RAMs " merkt" sich das DOS das Formatkennzei- chen der eingelegten Diskette. Es wird bei jedem Initialisierungsbefehl wieder aktualisiert. Ändern wir nun diese Speicherstelle so um, daß in ihr der Wert " A" steht, so können wir dem DOS vorgaukeln, es hätte eine Diskette mit korrekter Formatkennung vor sich. Erst jetzt ist es wieder möglich auf die Diskette zu schreiben. Auch hier möchte ich Ihnen die Unterroutine, die entsprechendes tut auflisten. Sie steht im oben erwähnten Programm in den Zeilen 300-370 :
Unterroutine " Diskette entsichern" :

300 OPEN 1,8,15,"I": OPEN 2,8,2,"#"     
310 PRINT#1,"U1 2 0 18 0"               
320 PRINT#1,"M-W";CHR$(1);CHR$(1);      
    CHR$(1);CHR$(65);                   
330 PRINT#1,"B-P 2 2"                   
340 PRINT#2,"A";                        
350 PRINT#1,"U2 2 0 18 0"               
360 PRINT#1,"I"                         
370 CLOSE1:CLOSE2:RETURN                

In den Zeilen 300 und 310 öffnen wir, wie gewohnt, unsere beiden Filekanäle und lesen den Diskheaderblock in den Puffer ein. Anschließend jedoch benutzen wir den Memory-Write- befehl der Floppy um den Inhalt von $0101 zu in " A" abzuändern. Die Adresse $0101 wird durch das Low-Byte 1 und das High-Byte 1 dargestellt. Desweiteren wollen wir nur ein Byte übertragen. Selbiges hat den AS-CII- Code 65, was dem Buchstaben " A" entspricht. In dieser Reihenfolge werden die Parameter nun an den String " M-W" angehängt. Nach dieser Operation können wir nun den Buffer-Pointer auf das Formatkennzeichen positionieren und über den Pufferkanal den Buchstaben " A" heinschreiben. Da die Floppy seit dem " M-W"- Befehl glaubt, es läge eine Diskette mit korrekter Formatkennung vor, können wir in Zeile 350 auch erfolgreich den Diskheaderblock zurückschreiben. Eine Abschließende Initialisierung macht die Diskette ab nun wieder beschreibbar.
Nun soll unser Programm aber auch in der Lage sein, zu erkennen, ob eine Diskette schreibgeschützt ist, oder nicht. Auch dies ist sehr einfach zu realisieren.
Wir gehen dabei wieder den Weg über die Speicherstelle $0101 des Floppy-RAMs.
Hier die Unterroutine die in den Zeilen 200 bis 260 zu finden ist:

Unterroutine "Formatkennung prüfen:"    
200 OPEN 1,8,15,"I"                     
210 PRINT#1,"M-R";CHR$(1);CHR$(1);      
    CHR$(1)                             
220 GET#1,A$                            
230 PRINT "DISKETTE IST ";              
240 IF A$="A" THEN PRINT "NICHT";       
250 PRINT "GESCHUETZT!"                 
260 CLOSE1:RETURN                       

Hier wird zunächst nur der Befehlskanal geöffnet. Einen Puffer benötigen wir nicht. Gleichzeitig wird die Diskette initialisiert und somit ihr Formatkenn- zeichen in die Speicherstelle $0101 übertragen. In Zeile 210 greifen wir diesmal mit Hilfe des Memory-Read- Befehls (" M-R") auf selbige zu. Wieder werden Lowund High-Byte 1, sowie die Länge 1 als CHR$- Codes übergeben. Anschließend können wir das Zeichen aus dem Befehlskanal auslesen. Es folgt nun eine Prüfung, ob es dem Buchstaben " A" entspricht. Wenn ja, so wird zuerst der Text " nicht" ausgegeben und anschließend der Text " geschuetzt!" . Andernfalls gibt das Programm nur " geschuetzt" aus. Zum Schluß schließen wir den Befehlskanal wieder und kehren zum Hauptprogramm zurück.

2) ÄNDERN DES DISKETTENNAMENS UND DER ID

Sicherlich haben Sie schon einmal ein Programm benutzt, das den Namen und die ID einer Diskette nachträglich verändert, ohne Daten zu zerstören. Wollen wir nun einmal selbst so etwas schreiben.
Zunächst möchten wir den Diskettennamen verändern. Wie Sie aus dem letzten Kurs bestimmt noch wissen, steht der Name einer Diskette in den Bytes 144-159 des Dir-Header- Blocks. Um ihn zu ändern brauchen wir lediglich diesen Block in einen Pufferspeicher einzulesen und den neuen Namen an dieser Position hineinzuschreiben. Dabei müssen wir noch auf zwei Dinge achten: Ist der neue Name kürzer als 16 Zeichen, so müssen die restlichen Zeichen mit dem ASCII-Code 160 aufgefüllt werden. Das ist der Code für ' SHIFT-SPACE' der von der Floppy automatisch an kürzere Namen angefügt wird. Desweiteren darf der neue Name natürlich nicht länger als 16 Zeichen sein, da wir sonst ja weitere Daten im Diskheaderblock überschreiben würden.
Das Programm mit dem Sie Disknamen und - ID ändern können, finden Sie auf dieser MD unter dem Namen " FK. NAMECHANGE" . Hier nun ein Auszug mit der Namensänderungsroutine bei Zeile 200 :
Unterroutine " Diskname ändern" :

200 OPEN 1,8,15,"I": OPEN 2,8,2,"#"     
210 PRINT#1,"U1 2 0 18 0"               
220 PRINT#1,"B-P 2 144"                 
230 NA$=""                              
240 FOR I=1 TO 16                       
250 GET#1,A$: NA$=NA$+A$                
260 NEXT                                
270 PRINT "AKTUELLER NAME: ";NA$        
280 INPUT "    NEUER NAME";NA$          
285 IF LEN(NA$)>16 THEN NA$=            
    LEFT$(NA$,16)                       
290 IF LEN(NA$)<16 THEN NA$=NA$+        
    CHR$(160): GOTO290                  
300 PRINT#1,"B-P 2 144"                 
310 PRINT#2,NA$;                        
320 PRINT#1,"U2 2 0 18 0"               
330 PRINT#1,"I"                         
340 CLOSE1:CLOSE2:RETURN                

In den Zeilen 200 und 210 öffnen wir, wie gewohnt, unsere Kanäle und lesen den Diskheaderblock in den Floppypuffer.
Anschließend wird der Pufferzeiger auf das 144 . Byte des Puffers positioniert.
In den Zeilen 230-260 werden nun die 16 Bytes des Diskettennamens mit Hilfe einer Schleife ausgelesen und in der Variablen NA$ abgelegt. Diese wird anschließend ausgegeben um den aktuellen Diskettennamen anzuzeigen. Es wird daraufhin nach dem neuen Namen gefragt, der nun seinerseits in die Variable NA$ kommt. In der Zeile 285 wird zunächst geprüft, ob der neue Name zu lang ist.
Wenn ja, so wird er auf die ersten 16 Zeichen gekürzt. In Zeile 290 wird abgefragt, ob der eingegebene Name nicht zu kurz ist. Wäre das der Fall, so würde beim Schreibvorgang der alte Name nicht ganz überschrieben werden und wäre dann noch sichtbar. In diesem Fall füllt die Schleife in Zeile 290 den Rest des Strings NA$ mit ' SHIFT-SPACES' auf. Erst jetzt kann wieder auf das erste Byte des Namens ( Byte 144 des Diskheaderblocks) positioniert werden und der String NA$ dorthin geschrieben werden. Abschließend wird die Änderung mittels " U2" auf der Diskette aktualisiert, letztere nochmmals initialisiert und alle Kanäle werden geschlossen.
Wollen wir die ID einer Diskette verändern, so müssen wir ähnlich arbeiten.
Hierbei wollen wir berücksichtigen, daß wir für die Directoryanzeige sogar fünf Zeichen ( anstelle von 2) zur Verfügung haben. Sie sicherlich ist Ihnen aufgefallen, daß in den letzten drei Zeichen der ID im Directory ( rechts oben) immer der Text "2 A" steht, was eine Formatkennung darstellt. Diese Formatkennung hat jedoch keinerlei Einfluß auf die, die im dritten Byte des Diskheaderblocks zu finden ist. Sie wird lediglich zur Anzeige beim Laden des Diretorys benötigt und kann im Prinzip beliebig geändert werden. Die drei Formatkennzei- chenbytes liegen glücklicherweise auch direkt hinter den beiden Bytes für die Disketten-ID, nämlich in den Bytes 162-166 des Diskheaderblocks. Hier nun der Programmteil, der die ID einer Diskette ändert:

Unterroutine "ID ändern"                
400 OPEN 1,8,15,"I": OPEN 2,8,2,"#"     
410 PRINT#1,"U1 2 0 18 0"               
420 PRINT#1,"B-P 2 162"                 
430 ID$=""                              
440 FOR I=1 TO 5                        
450 GET#1,A$: ID$=ID$+A$                
460 NEXT                                
470 PRINT "AKTUELLE ID: ";ID$           
480 INPUT "    NEUE ID";ID$             
490 IF LEN(ID$)>5 THEN ID$=LEFT$(ID$,5) 
500 PRINT#1,"B-P 2 162"                 
510 PRINT#2,ID$;                        
520 PRINT#1,"U2 2 0 18 0"               
530 PRINT#1,"I"                         
540 CLOSE1: CLOSE2: RETURN              

Im Prinzip arbeitet diese Unterroutine genauso wie die, die den Namen ändert.
Nur daß diesmal nicht 16, sondern nur 5 Zeichen für die ID eingelesen werden müssen. Desweiteren kann eine ID auch kürzer sein, als 5 Zeichen, nämlich dann, wenn Sie wirklich nur die beiden ID-Zeichen ändern wollen, das Formatkennzeichen aber gleich bleiben soll.
Deshalb wird in Zeile 490 der String ID$ nur auf 5 Zeichen gekürzt, falls er länger sein sollte. Ein kürzerer Text wird als solcher übernommen und an die Entsprechende Position ( nämlich 162) geschrieben. Auch hier wird die Änderung dann mittels " U2" gespeichert und die Diskette initialisiert.
Das soll es dann wieder einmal gewesen sein für diesen Monat. Ich hoffe ich habe Sie zum " Spielen" mit den Blockbefehlen animiert. Nächsten Monat wollen wir uns mit einer weiteren Anwendung der Blockbefehle beschäftigen und dann die Programmierung der Floppy in Maschinensprache angehen.

                                    (ub)

Valid HTML 4.0 Transitional Valid CSS!