Daraus ergibt sich nun die folgende Sek- torenverteilung:
Spuren Sektoren-pro-Spur -------------------------
1-17 21 18-24 19 25-30 18 30-35 17
Wichtig ist, daß Sie wissen, wieviele Sektoren ein bestimmter Track hat, da wir diese Information bei den Direktzu- griffsbefehlen benötigen, um einen spe- ziellen Block anzusprechen. Versuchen Sie nun aber Sektor 19 von Spur 35 zu lesen, so erhalten Sie natürlich eine Fehlermeldung von der Floppy zurück (ob- wohl es einen Sektor 19 bei den Tracks 1-24 gibt!).
DIE FLOPPY - EIN EIGENSTÄNDIGER COMPUTER
Wie ich vielleicht schon einmal erwähnte stellt die 1541 einen vollblütigen, unabhängen Computer dar. Sie verfügt über einen eigenen 8-Bit-Prozessor (den 6502, der Vorgänger des 6510 aus dem 64er, der auch im VC20 Verwendung fand), zwei I/O Bausteine, die man auch VIA nennt (Typ 6522, das Vorläufermodell des 6526-CIA-Chips, wie er auch zweimal im C64 vorhanden ist, und ebenfalls im VC20 eingesetzt war), einem 16-KB-ROM mit dem Betriebssystem (DOS) und 2KB RAM als Arbeitsspeicher für letzeres und Zwi- schenspeicher für Diskettenblocks. Die VIA-Bausteine übernehmen dabei den Da- tentransfer mit dem 64er, sowie die Be- dienung der Floppymechanik. Natürlich können Sie dem Floppyprozessor auch ein Programm geben, das er abarbeiten soll. Dieses muß in Maschinensprache geschrie- ben sein, wobei der Befehlssatz des 6502 identisch mit dem des 6510 (aus dem 64er) ist. Die Speicheraufteilung der Floppy sieht folgendermaßen aus:
Adresse Belegung ----------------------------------------
$0000-$0800 2KB RAM ab $1800 VIA1 (serieller Bus) ab $1C00 VIA2 (Laufwerkssteuerung) $C000-$FFFF Betriebssystem-ROM (16 KB) Alle übrigen Bereiche sind unbelegt. Wie beim C64 auch, können Sie mit einem Pro- gramm, daß sich im Floppy-RAM befindet die Betriebssystemroutinen der Floppy aufrufen (so funktionieren z.B. einige Software-Floppyspeeder). Kommen wir nun zum RAM der Floppy, denn das soll uns eigentlich interessieren. Ein Datenblock auf einer Diskette ist, wie Sie wissen 256 Bytes lang. Diese Datenlänge wird auch als Einheit für das Floppy-RAM benutzt: 256 Byte entsprechen einer sogenannten "Page" (engl. "Seite" - den Assemblerprogrammierern unter Ih- nen sicherlich ein geläufiger Begriff). Das Floppy-RAM wird nun in acht Pages unterteilt, die von 0 bis 7 durchnumme- riert sind. Die Pages 0, 1 und 2 sollten wir dabei außer Acht lassen, da sie für die Zeropage, den Stack und den Be- fehls-puffer der Floppy vorreserviert sind. Die Pages 3-7 sind Datenpuffer für Diskettenblöcke. Wir werden sie von nun an "Puffer" nennen.
DIE DIREKTZUGRIFFSBEFEHLE
Kommen wir nun endlich zu den Blockbe- fehlen selbst. Eigentlich gibt es drei Gruppen, von Befehlen, mit denen wir Abläufe innerhalb des "Floppy-Computers" steuern können: die Blockbefehle zum lesen, schreiben, belegen und freigeben von Blocks, die Memorybefehle, mit denen wir den Floppy-Speicher manipulieren können und die User-Befehle, die eine Verkürzung von Block- und Memorybefehlen darstellen. Bevor wir nun einen dieser Befehle be- nutzen können, müssen wir natürlich den Floppybefehlskanal öffnen. Da wir aber immer auch einen Arbeitspuffer im Floppy-RAM benötigen, um die Direktzu- griffsbefehle (einige Blockbefehle und zwei Userbefehle) anwenden zu können, müssen wir gleichzeitig auch einen Puf- fer für uns vorreservieren. Entweder überlassen wir dabei die Wahl des Puf- fers der Floppy, oder aber wir bestimmen die Puffernummer selbst. Letztes wird wohl nur in ganz besonderen Fällen vonnöten sein, weshalb wir uns auf die erste Methode festlegen wollen. Das Üff- nen des Befehlskanals mit der Zuweisung eines Arbeitspuffers geschieht über das Üffnen eines eigenen Datenkanals, der für den Datentransfer mit dem Puffer herangezogen wird. Dies geschieht fol- gendermaßen:
OPEN 1,8,15 :REM Befehlskanal öffnen OPEN 2,8,2,"#" :REM Pufferkanal öffnen
Hier öffnen wir also wie gewohnt den Befehlskanal, dem wir die logische File- nummer 1 zuordnen. Der zweite OPEN- Befehl öffnet einen Kanal zur Floppy, den wir zum Auslesen und Schreiben unse- res Datenpuffers verwenden werden. Das Doppelkreuz ("#") zeigt der Floppy an, daß wir mit einem Datenpuffer arbeiten möchten. Welche Nummer dieser hat, sei der Floppy überlassen. Sie sucht nun einfach einen freien Puffer aus, und ordnet ihm unserem Kanal zu. Möchten wir wissen, welcher Puffer ausgewählt wurde, so können wir seine Nummer direkt nach dem Üffnen durch Lesen des Pufferkanals erfahren:
GET#2,PN$ PRINT ASC(PN$)
Hierbei ist es wichtig, daß Sie den GET-Befehl innerhalb eines Programms benutzen, da er vom Direktmodus aus nicht verwendbar ist. Wenn wir gleich einen bestimmten Puffer für uns reservieren möchten, so müssen wir beim OPEN-Befehl einfach die Puffer- nummer mit übergeben. Folgender Befehl reserviert den Puffer Nummer 3 (Floppy- Adressbereich $0300-$03FF) für uns: OPEN 2,8,2,"#3" Wichtig ist, daß wir uns die Sekundära- dresse merken, mit der wir den Pufferka- nal geöffnet hatten. Sie wird später dazu verwendet, um der Floppy mitzutei- len auf welchem Datenkanal Sie Daten für uns bereitzustellen hat, bzw. von uns empfangen wird (ähnlich den Befehlen für die RELative Dateiverwaltung). Wie üblich wählen wir bei der Sekundäradres- se eine der freien Nummern von 2-14. DIE BLOCKBEFEHLE Nachdem wir nun einen Datenpuffer reser- viert haben und einen Filekanal für die- sen Puffer offen halten, können wir uns jetzt mit den Befehlen beschäftigen, die wir der Floppy geben können. Die erste Gruppe dieser Befehle sind die Blockbe- fehle. Mit ihnen können wir die einzel- nen Blocks einer Diskette "hardwaremä- ßig" ansprechen. Aufgrund eines Blockbe- fehls wird physisch auf den Block zuge- griffen und in den Puffer eingelesen, bzw. aus ihm heraus geschrieben. Für die Beispiele innerhalb der Befehlsbeschrei- bungen gelten die obig definierten logi- schen Filenummern (Befehlskanal=1, Puf- ferkanal=2), sowie die Sekundärdresse 2 für den Pufferkanal. 1) BLOCK-READ ("B-R") Mit diesem Blockbefehl lesen wir einen Diskettenblock in unseren Datenpuffer ein. Hierbei müssen wir die Sekundära- dresse unseres Pufferkanals, die Drive- nummer (immer 0), den Track und den Sek- tor als Parameter übergeben. Hier die allgemeine Syntax:
PRINT#BFN,"B-R";SA;DN;TR;SE
Hierbei gilt:
BFN = logische Filenummer des Befehlska- nals SA = Sekundäradresse des Pufferkanals DN = Drivenummer (immer 0) TR = Tacknummer SE = Sektornummer
(Diese Variablennamen und Abkürzungen werde ich auch im Folgenden weiterver- wenden.) Mit der folgenden Anweisung wird also Sektor 1 von Track 18 in unseren Puffer eingelesen. Von dort aus können Sie Ihn nun mittels einer GET-Schleife auslesen:
... 100 PRINT#1,"B-R 2 0 18 1" 110 FOR I=0 TO255 120 GET#2,a$: PRINT ASC(a$) 130 NEXT
... 2) BLOCK-WRITE ("B-W") Mit diesem Blockbefehl schreiben wir einen Block aus unserem Datenpuffer auf die Diskette. Seine Syntax ist analog der von "B-R", nur daß diesmal der Block geschrieben wird:
PRINT#BFN,"B-W";SA;DN;TR;SE
3) BUFFER-POINTER ("B-P") Für jeden Datenpuffer der Floppy exi- stiert ein Zeiger, der auf das aktuelle Byte im Puffer zeigt. Möchte man nun ein ganz spezielles Byte aus dem Puffer aus- lesen, so muß nicht unbedingt der ganze Puffer gelesen werden, um das gewünschte Byte zu erhalten. Sie können mit dem "B-P"-Befehl den Pointer auf selbiges positionieren und anschließend auslesen. Als Parameter benutzen Sie ganz einfach die Sekundäradresse des Pufferkanals und die Nummer des gewünschten Bytes minus 1. Möchten Sie z.B. das 200. Byte ausle- sen, so gehen Sie bitte wiefolgt vor:
PRINT#1,"B-P 2 199" GET#2,A$: A=ASC(A$)
Die zweite, oben angeführte Zeile liest nun das 200. Byte in eine Stringvariable und speichert es als Zahl in der Varia- blen "A". 4) BLOCK-ALLOCATE ("B-A") Mit diesem Floppybefehl können Sie ge- zielt einzelne Disketten-Blocks als "be- legt" kennzeichnen. Das ist dann notwen- dig, wenn Sie Daten mittels "B-W" auf einer Diskette speichern, zusätzlich aber noch normale DOS-Files darauf able- gen wollen. Wird ein Block nämlich nicht als belegt gekennzeichnet, so wird er beim Speichern eines DOS-Files unter Umständen überschrieben. Die belegten Blocks sind in der "Block-Allocation- Map" (BAM) einer Diskette gespeichert, die sich in Block 18,0 befindet. Mit dem Block-Allocate-Befehl wird hier dann der entsprechende Block als belegt eingetra- gen. Mehr zum Aufbau der BAM werden wir im nächsten Teil des Floppy-Kurses ler- nen. Die allgemeine Syntax des "B-A"- Befehls lautet:
PRINT#BFN,"B-A"; DN; TR; SE
Möchten Sie also z.B. den Block 5 von Spur 34 als belegt kennzeichnen, so müs- sen Sie folgenden Befehl benutzen:
PRINT#1,"B-A 0 34 5"
5) BLOCK-FREE ("B-F") Dieser Befehl ist das Gegenstück zu Block-Allocate. Mit ihm geben Sie einen belegten Block wieder zur Benutzung frei. Die Syntax ist dabei identisch zu "B-A":
PRINT#BFN,"B-F"; DN; TR; SE
Um den obig belegten Block wieder frei- zugeben senden Sie den folgenden Befehl an die Floppy:
PRINT#1,"B-F 0 34 5"
6) BLOCK-EXECUTE (B-E) Dieser Befehl ist identisch mit Block- Read. Er beinhaltet jedoch zusätzlich, daß der Diskettenblock, der in den Puf- fer geladen werden soll, ein ausführba- res Floppy-Programm ist, das nach dem Laden direkt angesprungen wird. DIE MEMORYBEFEHLE Diese Floppybefehle beziehen sich auf die Floppy selbst und haben mit dem Di- rektzugriff nur indirekt zu tun. Trotz- dem sind sie nützlich zum Auswerten von Daten, weshalb sie hier aufgeführt sind: 1) MEMORY-READ ("M-R") Dieser Befehl enstspricht dem PEEK- Befehl von BASIC. Mit ihm können Sie gezielt einzelne, oder mehrere Speicher- adressen der Floppy auslesen. Die allge- meine Syntax lautet dabei wiefolgt: PRINT#BFN,"M-R"; CHR$(LO); CHR$(HI); CHR$(N) Hierbei stehen "LO" und "HI" für Low- und Highbyte der Adresse die gelesen werden soll und "N" für die Anzahl Bytes (0-255), die ab dort übertragen werden sollen. Das Low- und Highbyte einer Adresse ermitteln Sie mit folgenden For- meln: HI=INT(Adresse/256) LO=Adresse-256*HI Alle Parameter müssen als CHR$-Codes, also dirket, übertragen werden, und dür- fen nicht als ASCII-Codes (wie in den bisherigen Befehlen) erscheinen. Die zu lesenden Bytes werden ebenfalls als ab- soluter CHR$-Code auf dem BEFEHLSKANAL (!) bereitgestellt (nicht etwa auf dem Pufferkanal, da der interne Floppyspei- cher nichts mit Datenblocks zu tun hat). Als Beispiel für die Verwendung von "M-R" sei folgendes Programm aufgeführt. Es liest den ASCII-Code der ID der zu- letzt initialisierten Diskette aus dem Floppyspeicher aus. Dieser wird vom Floppy-Betriebssystem automatisch in den Speicherstellen 18 und 19 gespeichert (LO=18; HI=0; N=2):
10 OPEN 1,8,15 20 PRINT#1,"M-R"; CHR$(18); CHR$(0); CHR$(2) 30 GET#1,I1$: GET#1,I2$ 40 CLOSE 1 50 PRINT "ID DER ZULETZT BENUTZTEN DIS KETTE: ";I1$;I2$
2) MEMORY-WRITE Mit diesem Befehl schreiben Sie Daten in den Floppy-Speicher. Er entpricht dem POKE-Befehl von BASIC. Auch hier über- tragen Sie zunächst die Adresse in Low- und Highbytedarstellung, sowie die An- zahl der zu schreibenden Bytes. Letztere hieraufhin gesandt. Hier die allgemeine Syntax: PRINT#BFN,"M-W"; CHR$(LO); CHR$(HI); CHR$(N); CHR$(W1); CHR$(W2); ...; CHR$(Wn-1); CHR$(Wn) 3) MEMORY-EXECUTE Dieser Befehl dient dem Ausführen eines Assembler-Programms innerhalb der Floppy. Damit hat auch er einen Verwand- ten in BASIC: den SYS-Befehl. Als Para- meter übergeben Sie hier einfach nur die Startadresse des aufzurufenden Assem- bler-Programms:
PRINT#BFN,"M-E"; CHR$(LO); CHR$(HI) DIE USERBEFEHLE
Die dritte Gruppe der Floppy-Direkt- Befehle sind die Userbefehle. Sie stel- len eine Abkürzung von einigen Befehlen aus den anderen beiden Gruppen dar. Die Userbefehle beginnen alle mit einem "U", gefolgt von einer Zahl zwischen 1 und 9. Die ersten beiden Userbefehle sind wohl die wichtigsten: 1) "U1" Der U1-Befehl ersetzt den Block-Read- Befehl. In der Praxis wird er öfter ver- wendet, da er gegenüber "B-R" einen Vor- teil bietet. Wird mit "B-R" ein Block eingelesen und anschließend der Inhalt des Puffers vom 64er aus ausgelesen, so wird das erste Byte nicht mitgesandt. Möchten wir dieses nun aber auch lesen, so müssen wir den "U1"-Befehl benutzen. Er sendet es zusätzlich mit - im Prinzip ist der U1-Befehl also besser als "B-R". Die Syntax ist identisch mit der von "B-R": PRINT#BFN,"U1"; SA; DN; TR; SE Ansonsten verhält sich alles so, wie auch bei "B-R". 2) "U2" Der zweite Userbefehl ist der U2-Befehl (Ähnlichkeiten mit dem Namen einer be- kannten Rock-Band sind rein zufällig). Er ersetzt den "B-W" Befehl. Auch hier ist der Vorteil des ersten Bytes gege- ben. Sie benutzen den U2-Befehl, wie den "B-W"-Befehl:
PRINT#LFB,"U2"; SA; DN; TR; SE
3) "U3-U8" Diese sechs Userbefehle ersetzen ganz bestimmte "M-E"-Kommandos. Wird einer dieser Befehle gesandt, so springt die Floppy in eine Sprungtabelle ab Adresse $0500 und führt das dort stehende Pro- gramm aus. In der Regel besteht selbiges aus einer Reihe von "JMP $XXXX"- Anweisungen, mit denen Sie nun auf ein- fache Weise, vom 64er aus, selbstdefi- nierte Programme in der Floppy aktivie- ren können. Die Userbefehle 3-8 benöti- gen keine Parameter. Bei Benutzung der Befehle werden folgende Adressen jeweils angesprungen:
Befehl Springt an Adresse --------------------------
U3 $0500 U4 $0503 U5 $0506 U6 $0509 U7 $050C U8 $050F
Damit ersetzen diese Userbefehle also "M-E"-Befehle wie z.B.:
PRINT#BFN,"M-E";CHR$(9);CHR$(5);
Wenn Sie den obigen Befehl abkürzen wol- len, so genügt auch ein einfaches: PRINT#BFN,"U6" 4) "U9" Der "U9"-Befehl wurde eingebaut, um die Kompatibilität der 1541 zum VC20, dem Vorgänger des C64, zu wahren. Mit ihm können Sie die Floppy in den Modus des entsprechenden Rechners schalten. Dies geschieht über folgende Kombinationen des "U9"-Befehls:
PRINT#BFN,"U9+"; schaltet in C64-Modus PRINT#BFN,"U9-"; schaltet in VC20-Modus
5) "U:" Mit diesem Userbefehl lösen Sie einen RESET in der Floppy aus. Das Floppysy- stem wird dann wieder in den Einschalt- zustand zurückversetzt. Der "U:"-Befehl entspricht einem "SYS 64738" beim C64. Auch er benötigt keine Parameter. Das war es dann wieder für diese Ausga- be. In der nächsten Magic-Disk werden wir uns dann mit dem Aufbau von Files, der BAM und des Directorys beschäftigen. In diesem Zusammenhang werden wir dann die hier erlernten Floppy-Befehle in praktische Beispiele umsetzen.
(ub)