Daraus ergibt sich nun die folgende Sektorenverteilung:
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 Direktzugriffsbefehlen benötigen, um einen speziellen 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 ( obwohl 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
64 er, 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 2 KB RAM als
Arbeitsspeicher für letzeres und Zwischenspeicher für Diskettenblocks. Die
VIA-Bausteine übernehmen dabei den Datentransfer mit dem 64 er, sowie die Bedienung der Floppymechanik. Natürlich
können Sie dem Floppyprozessor auch ein
Programm geben, das er abarbeiten soll.
Dieses muß in Maschinensprache geschrieben sein, wobei der Befehlssatz des 6502
identisch mit dem des 6510( aus dem
64 er) ist. Die Speicheraufteilung der
Floppy sieht folgendermaßen aus:
Adresse Belegung
$0000-$08002 KB RAM ab $1800 VIA1( serieller Bus) ab $1 C00 VIA2( Laufwerkssteuerung)$ C000-$ FFFF Betriebssystem-ROM (16 KB)
Alle übrigen Bereiche sind unbelegt. Wie
beim C64 auch, können Sie mit einem Programm, 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 Ihnen sicherlich ein geläufiger Begriff) .
Das Floppy-RAM wird nun in acht Pages
unterteilt, die von 0 bis 7 durchnummeriert sind. Die Pages 0,1 und 2 sollten
wir dabei außer Acht lassen, da sie für
die Zeropage, den Stack und den Befehls- 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 Blockbefehlen 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 Blockund Memorybefehlen
darstellen.
Bevor wir nun einen dieser Befehle benutzen können, müssen wir natürlich den
Floppybefehlskanal öffnen. Da wir aber
immer auch einen Arbeitspuffer im
Floppy-RAM benötigen, um die Direktzugriffsbefehle ( einige Blockbefehle und
zwei Userbefehle) anwenden zu können, müssen wir gleichzeitig auch einen Puffer für uns vorreservieren. Entweder
überlassen wir dabei die Wahl des Puffers 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 Üffnen 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 folgendermaß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 Filenummer 1 zuordnen. Der zweite OPEN-Befehl öffnet einen Kanal zur Floppy, den wir zum Auslesen und Schreiben unseres 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 Puffernummer mit übergeben. Folgender Befehl
reserviert den Puffer Nummer 3( Floppy-Adressbereich $0300-$03 FF) für uns:
OPEN 2,8,2,"#3"
Wichtig ist, daß wir uns die Sekundäradresse merken, mit der wir den Pufferkanal geöffnet hatten. Sie wird später
dazu verwendet, um der Floppy mitzuteilen 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äradresse eine der freien Nummern von 2-14 .
DIE BLOCKBEFEHLE Nachdem wir nun einen Datenpuffer reserviert haben und einen Filekanal für diesen 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 Blockbefehle. Mit ihnen können wir die einzelnen Blocks einer Diskette " hardwaremäßig" ansprechen. Aufgrund eines Blockbefehls wird physisch auf den Block zugegriffen und in den Puffer eingelesen, bzw. aus ihm heraus geschrieben. Für die
Beispiele innerhalb der Befehlsbeschreibungen gelten die obig definierten logischen Filenummern ( Befehlskanal=1, Pufferkanal=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äradresse unseres Pufferkanals, die Drive- nummer ( immer 0), den Track und den Sektor 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 weiterverwenden.)
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 existiert ein Zeiger, der auf das aktuelle
Byte im Puffer zeigt. Möchte man nun ein
ganz spezielles Byte aus dem Puffer auslesen, 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 auslesen, 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 Variablen " A" .
4) BLOCK-ALLOCATE (" B-A") Mit diesem Floppybefehl können Sie gezielt einzelne Disketten-Blocks als " belegt" kennzeichnen. Das ist dann notwendig, wenn Sie Daten mittels " B-W" auf
einer Diskette speichern, zusätzlich
aber noch normale DOS-Files darauf ablegen 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 eingetragen. Mehr zum Aufbau der BAM werden wir
im nächsten Teil des Floppy-Kurses lernen. 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üssen 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 freizugeben 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 Puffer geladen werden soll, ein ausführbares Floppy-Programm ist, das nach dem
Laden direkt angesprungen wird.
DIE MEMORYBEFEHLE
Diese Floppybefehle beziehen sich auf
die Floppy selbst und haben mit dem Direktzugriff nur indirekt zu tun. Trotzdem 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 Speicheradressen der Floppy auslesen. Die allgemeine Syntax lautet dabei wiefolgt:
PRINT# BFN," M-R" ; CHR$( LO) ; CHR$( HI) ;
CHR$( N)
Hierbei stehen " LO" und " HI" für Lowund Highbyte der Adresse die gelesen
werden soll und " N" für die Anzahl Bytes
(0-255), die ab dort übertragen werden
sollen. Das Lowund Highbyte einer
Adresse ermitteln Sie mit folgenden Formeln:
HI= INT( Adresse/256) LO= Adresse-256* HI
Alle Parameter müssen als CHR$- Codes, also dirket, übertragen werden, und dürfen nicht als ASCII-Codes ( wie in den
bisherigen Befehlen) erscheinen. Die zu
lesenden Bytes werden ebenfalls als absoluter CHR$- Code auf dem BEFEHLSKANAL
( !) bereitgestellt ( nicht etwa auf dem Pufferkanal, da der interne Floppyspeicher 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 zuletzt 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 Lowund Highbytedarstellung, sowie die Anzahl 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 Verwandten in BASIC: den SYS-Befehl. Als Parameter übergeben Sie hier einfach nur die
Startadresse des aufzurufenden Assembler- 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 verwendet, da er gegenüber " B-R" einen Vorteil bietet. Wird mit " B-R" ein Block
eingelesen und anschließend der Inhalt
des Puffers vom 64 er 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 bekannten Rock-Band sind rein zufällig) .
Er ersetzt den " B-W" Befehl. Auch hier
ist der Vorteil des ersten Bytes gegeben. 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 Programm aus. In der Regel besteht selbiges
aus einer Reihe von " JMP $ XXXX"- Anweisungen, mit denen Sie nun auf einfache Weise, vom 64 er aus, selbstdefinierte Programme in der Floppy aktivieren können. Die Userbefehle 3-8 benötigen 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 wollen, 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 Floppysystem wird dann wieder in den Einschaltzustand 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 Ausgabe. 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)