---------------------------------------- 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 um- setzen. Das heißt, daß wir in diesem Kursteil einige nützliche Anwendungen zum bisher Erlernten programmieren wer- den. Diese werden zunächst in BASIC be- handelt. 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 ein- fach möglich, eine Diskette softwaremä- ßig schreibzuschützen. Sie können an- schließend weder etwas auf die Diskette schreiben, noch etwas von ihr löschen. Das Laden von Programmen funktiert je- doch nach wie vor. Einzige Möglichkeit die Diskette wieder beschreibbar zu ma- chen ist dann das Formatieren (oder nochmaliges Behandeln mit unserem Pro- gramm). Wie realisieren wir nun einen solchen Schreibschutz? Nun, wie wir mittlerweile ja wissen, legt die Floppy beim Forma- tieren 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. Ande- re 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 Auf- zeichnungsdichte (mehr Tracks auf einer Diskette). Um nun zu vermeiden, das Laufwerke von verschiedenen Rechnern die Daten einer Diskette eines anderen Lauf- werks zerstören, wurde eine Sicherung in die 1541 eingebaut. Sie beschreibt aus- schließ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 ande- res 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äm- lich das Formatkennzeichen) in ein ande- res Zeichen als "A" abwandeln und den Block wieder auf die Diskette zurück- schreiben. Abschließend muß die Diskette noch initialisiert werden, damit das Betriebssystem der Floppy, das DOS, die neue Formatkennung auch in den Floppy- speicher übernimmt. Ein Programm, das eine Diskette mit Schreibschutz versieht und ihn wieder entfernt finden Sie auf dieser MD unter dem Namen "FK.SCHREIBSCHUTZ". Die Unter- routine, 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 Be- fehlskanal und übergeben gleichzeitig einen Initialisierungsbefehl an ihn. Mit letzterem werden alle Grunddaten der eingelegten Diskette (z.B. ID, Format- kennung, etc.) in den Speicher der Floppy übertragen. Man sollte vor einer direkten Manipulation des Diskheader- blocks diesen Befehl aufrufen. Desweite- ren öffnen wir einen Pufferkanal mit der Kanalnummer 2 (also Sekundäradresse 2) um Blockoperationen durchführen zu kön- nen. In Zeile 410 wird nun Spur 0 von Track 18 in den Puffer, dem Kanal 2 zu- geordnet 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 Po- sition 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 Disketten- schutz 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" umwan- deln. Jedoch ergibt sich hierbei ein kleineres Problem. Dadurch, daß die Dis- kette ja schreibgeschützt ist, können wir den modifizierten Disk-Header ja nicht mehr auf die Diskette zurück- schreiben! Hier behilft man sich mit einem kleinen Trick. In der Speicher- stelle $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 Spei- cherstelle so um, daß in ihr der Wert "A" steht, so können wir dem DOS vorgau- keln, es hätte eine Diskette mit korrek- ter 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" ab- zuändern. Die Adresse $0101 wird durch das Low-Byte 1 und das High-Byte 1 dar- gestellt. Desweiteren wollen wir nur ein Byte übertragen. Selbiges hat den AS- CII-Code 65, was dem Buchstaben "A" ent- spricht. 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 For- matkennzeichen positionieren und über den Pufferkanal den Buchstaben "A" hein- schreiben. 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 Low- und High-Byte 1, sowie die Länge 1 als CHR$-Codes übergeben. An- schließ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än- dert, ohne Daten zu zerstören. Wollen wir nun einmal selbst so etwas schrei- ben. 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 hineinzu- schreiben. 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änderungs- routine 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 ei- ner Schleife ausgelesen und in der Va- riablen NA$ abgelegt. Diese wird an- schließend ausgegeben um den aktuellen Diskettennamen anzuzeigen. Es wird da- raufhin 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 abge- fragt, 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 nochm- mals initialisiert und alle Kanäle wer- den geschlossen. Wollen wir die ID einer Diskette verän- dern, 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 aufge- fallen, daß in den letzten drei Zeichen der ID im Directory (rechts oben) immer der Text " 2A" steht, was eine Format- kennung 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än- dert 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 Format- kennzeichen aber gleich bleiben soll. Deshalb wird in Zeile 490 der String ID$ nur auf 5 Zeichen gekürzt, falls er län- ger sein sollte. Ein kürzerer Text wird als solcher übernommen und an die Ent- sprechende Position (nämlich 162) ge- schrieben. 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 Blockbe- fehlen animiert. Nächsten Monat wollen wir uns mit einer weiteren Anwendung der Blockbefehle beschäftigen und dann die Programmierung der Floppy in Maschinens- prache angehen.
(ub)