Magic Disk 64

home to index to text: MD9301-KURSE-FLOPPY-KURS_8.1.txt
----------------------------------------
              Floppy-Kurs:              
      "Es rappelt in der Kiste..."      
                (Teil 8)                
----------------------------------------

Herzlich Willkommen zum achten Teil des Floppy-Kurses. In diesem Monat wollen wir noch etwas weiter in die Floppyprogrammierung in Assembler einsteigen. Im letzten Monat hatten wir ja schon angesprochen, wie man ein File öffnet und mit ihm kommuniziert, sowie man Files lädt und speichert. Diesmal will ich Ihnen eine andere, effektiviere Methode zeigen, mit der man die Floppy ansprechen kann.
DIE ALTE METHODE In der letzten Ausgabe des Floppy-Kurses hatten wir gelernt, wie man ein File öffnet, es zur Datenübertragung bereitmacht, Daten an es sendet und von ihm empfängt, und es anschließend wieder schließt. Die dort behandelte Arbeitsweise war die einfachste, die man zum reinen Lesen oder Schreiben eines Files anwendet. Es gibt jedoch eine weitere Methode Files anzusprechen. Diese ist zwar ein wenig umständlicher, dafür aber schneller und weitaus flexibler.
Rekapitulieren wir: Nach der ersten Methode gingen wir immer folgendermaßen vor:
1)" SETNAM" mit den Parametern für den Filenamen aufrufen.
2)" SETPAR" mit den Datenkanalparametern aufrufen.
3) Mit " OPEN" das File öffnen 4 a) War das File eine Ausgabedatei, so mussten wir " CKOUT" aufrufen.
4 b) War das File eine Eingabedatei, so mussten wir " CHKIN" aufrufen.
5 a) War das File eine Ausgabedatei, so wurden die Daten mit Hilfe von " B-SOUT" geschrieben.
5 b) War das File eine Eingabedatei, so wurden die Daten mit Hilfe von " BA-SIN" gelesen.
6) Abschließend wurde mittels " CLRCH" die Standardausgabe wieder zurückgestellt.
7) Das File wurde mit " CLOSE" geschlossen.
Wie gesagt, ist diese Methode die einfachste, wenn Sie ein einziges File lediglich Lesen oder Schreiben wollen.
Wenn Sie nun aber mehrere Files offenhalten und ansprechen wollen, oder aber auf einem Kanal Lesen und Schreiben wollen ( so wie das beim Befehlskanal unter Mitbenutzung von Pufferkanälen oft der Fall ist), so versagt diese Methode. Das liegt daran, daß Sie mit der einfachen Methode eigentlich nicht wirklich mit den Dateien kommunizieren. Dies geschieht dann nämlich mit einem Umweg über das Betriebssystem. Das Aufrufen von " CKOUT" entspricht zum Beispiel dem Basic-Befehl " CMD" . Sie leiten damit die Daten, die normalerweise auf dem Bildschirm ausgegeben werden, auf den Floppykanal um. Nun ist es aber wiederum nicht so einfach, einen zum Ausgabekanal erklärten Filekanal, als Eingabekanal zu benutzen. Ein folgendes " CHKIN" zeigt nämlich keine Wirkung. Auch wenn Sie zwei Files offenhalten, so funktioniert das Umschalten zwischen diesen beiden Files nicht immer. Der Grund dafür liegt in der Art und Weise wie die Standard-Ein/ Ausgabefiles im C64 verwaltet werden.

DIE NEUE METHODE                        

Um nun effizienter mit der Floppy zu kommunizieren, müssen wir auf spezielle Betriebssystemroutinen zurückgreifen, die eigens für die Datenkommunikation mit der Floppy ( bzw. dem IEC-Bus, an dem Floppy und Drucker angeschlossen sind), dienen. Diese Routinen werden im Prinzip auch bei Verwendung der ersten Methode vom Betriebssystem benutzt, jedoch muß ein Standard-Kanal eben auch andere, virtuelle, Geräte ( wie Bildschirm, Tastatur, etc.) ansprechen können, weshalb die Restriktionen dort etwas umständlicher sind. Deshalb ist eine Ausgabe über BASOUT, oder die Eingabe über BASIN, auch immer langsamer, als wenn Sie die entsprechenden I/ O-Routinen für den IEC-Bus benutzen, da bei den beiden ersten Routinen erst einmal entschieden werden muß, welche effektiven Ein-/ Ausgaberoutinen nun wirklich benutzt werden müssen ( in unserem Fall nämlich die IEC-Busroutinen) .
Kommen wir nun jedoch endlich zu den neuen Routinen und deren Funktionsprin- zip. Hierzu müssen wir uns zunächst noch einmal verdeutlichen, daß die Floppy im Prinzip ein eigenständiger Computer ist, der nichts anderes tut, als darauf zu warten, daß Befehle über den IEC-Bus kommen, um sie auszuführen. Hierbei meine ich nicht die Floppy-Befehle, wie wir sie bisher kennengelernt haben. Diese stellen wiederum eine höhere Ebene von Befehlen dar. Da der IEC-Bus als Kommunikationsschnittstelle zwischen C64 und Floppy dient, werden auf Ihm Daten entweder vom Rechner zur Floppy oder umgekehrt hinund herbewegt. Die Verarbeitung dieser Daten ist dann dem jeweiligen Gegengerät überlassen, daß die Daten empfangen hat. Noch dazu kann es vorkommen, daß sich bis zu 7 Geräte ( der C64, max.2 Drucker und max. vier Floppys) über ein und denselben Bus miteinander unterhalten müssen. In dem Fall muß vor einer Datenübertragung natürlich festgelegt werden welches der Geräte nun mit welchem ( im Normalfall dem 64 er) kommu- nizieren soll. Hierzu dienen nun insgesamt sechs Betriebssystemroutinen.
Als erstes müssen wir wieder einmal ein File auf die gewohnte Art und Weise öffnen. Zunächst übergeben wir die Filenamenparameter mit Hilfe von " SETNAM"( Akku= Länge des Namens, X/ Y= Zeiger auf Namensstring) . Anschließend muß " SETPAR" aufgerufen werden. Hierbei kommen Filenummer und Geräteadresse, wie gewohnt, in Akku und X-Register. Im Y-Register wird die Sekundäradresse abgelegt. Jedoch müssen wir hier, anders als sonst, die gewünschte Sekundäradresse plus $60(= dez.96) übergeben. Dies hat Floppyinterne Gründe. Möchten wir also den Befehlskanal ansprechen, so muß die Sekundäradresse $6 F ( dez.111) übergeben werden. Möchten wir ein PRG-File lesen, so müssten wir den Wert $60 übergeben, etc. Zuletzt wird wieder wie üblich das File mittels " OPEN" geöffnet.
Soweit also nichts Neues. Nun müssen wir uns, wie vorher auch, verdeutlichen, ob die Floppy senden, oder empfangen soll.
Anstelle von " CHKIN" oder " CKOUT" müssen diesmal jedoch andere Routinen benutzt werden. Möchten wir Daten empfangen, so soll die Floppy mit uns " reden" . Deshalb heißt die entsprechende Routine, die sie dazu auffordert uns Daten zuzusenden " TALK"( engl." reden") . Wollen wir Daten senden soll die Floppy uns " zuhören" .
Die hierfür gedachte Unterroutine heißt " LISTEN"( engl." hören") . Da es, wie oben schon einmal beschrieben, bis zu 6 Geräte geben kann, die uns zuhören oder mit uns reden sollen, muß mit " TALK" oder " LISTEN" auch mitgeteilt werden, welches der Geräte nun für uns bereit sein soll. Hierzu müssen Sie vor Aufruf der Routinen die Geräteadresse des gewünschten Gerätes im Akku ablegen.
Als nächstes muß dem Gerät an der anderen Seite mitgeteilt werden, welcher seiner offenen Kanäle senden oder empfangen soll. Hierzu muß die Sekundär- adresse an das Gerät übermittelt werden.
Dies geschieht über die Routinen " SECTLK" und " SECLST" . Beide verlangen die gewünschte Sekundäradresse ( wieder plus $60) als Parameter im Akku.
" SECTLK" müssen Sie nach einem " TALK" aufrufen," SECLST" nach einem " LISTEN" .
Nun ist alles vorbereitet, um Daten zu lesen oder zu schreiben. Dies erledigen Sie nun am besten mit den beiden speziellen IEC-Ein-/ Ausgaberoutinen, die ich oben schon ansprach. Sie können sie genauso wie " BASIN" und " BASOUT" benutzen. Zum Lesen von Daten benutzen Sie die Routine " IECIN", die das gelesene Byte im Akku zurückgibt. Zum Schreiben benutzen Sie " IECOUT", der das zu schreibende Byte im Akku übergeben werdeb muß.
Haben Sie die Einoder Ausgabe beendet, so müssen Sie das entsprechende Empfangs-, bzw. Sendegerät wieder in den Wartezustand zurückbringen. Dies geschieht über die Routinen " UNTALK" und" UNLIST" . Die erstere müssen Sie nach dem Empfang, die letztere nach dem Senden von Daten benutzen. Dies müssen Sie auch immer dann tun, wenn Sie anschließend auf dem selben Kanal eine andere Operation ausführen wollen ( z. B. Befehl an Befehlskanal senden und anschließend Floppystatus auslesen) .
Wenn Sie mit Ihrer Operation nun fertig sind, so können Sie den zuvor geöffneten Filekanal wieder schließen.
Wie Sie sehen ist diese Methode etwas aufwendiger. Dafür aber können Sie nun problemlos den Befehlskanal öffnen und z. B. den " Memory-Read"- Befehl (" M-R") benutzen. Hierbei öffnen Sie einen Filekanal und teilen der Floppy mit, daß sie Daten empfangen soll (" LISTEN" und " SECLST" aufrufen) . Nun senden Sie mittels " IECOUT" den Befehlsstring. Anschließend setzen Sie die Floppy wieder in der Normalstatus zurück, indem Sie " UNLIST" aufrufen. Hiernach können Sie nun die zuvor verlangten Daten vom Befehlskanal abholen. Senden Sie einfach ein " TALK" und " SECTLK" und lesen Sie die Daten mit " IECIN" ein. Abschließend muß die Floppy wieder mit " UNTALK" in den Wartezustand geschickt werden und wir können das File schließen.
Desweiteren ist das Bedienen von zwei offenen Files nun weitaus besser möglich. Bevor Sie eines dieser Files ansprechen, müssen Sie einfach den entsprechenden Öbertragungsmodus festlegen und seine Sekundäradresse an die Floppy schicken. Denken Sie immer daran, daß Sie nach jeder Leseoder Schreiboperation ein " UNTALK" oder " UNLIST" senden müssen, damit die Floppy auf weitere Befehle reagiert.
Hier nun noch die Einsprung-Adressen der neuen I/ O-Routinen:

LISTEN: $FFB1                           
  TALK: $FFB4                           
SECLST: $FF93                           
SECTLK: $FF96                           
UNLIST: $FFAE                           
UNTALK: $FFAB                           
IECOUT: $FFA8                           
 IECIN: $FFA5                           
PROGRAMM-BEISPIELE                      

Kommen wir nun noch zu einigen Programmbeispielen, die Ihnen die Benutzung der neuen I/ O-Routinen erläutern sollen.
Die Routinen aus Beispiel 1 und 2 finden Sie, als Hypra-Ass Quellcode, auf dieser MD unter dem Namen " FK. IO2 . S" . Der Quellcode für Beispiel 3 steht im File " FK. SHOWBAM. S" . Da es sich dabei um ein eigenständiges Programm handelt, existiert hierzu auch noch ein, durch ' RUN' startbares, File namens " FK. SHOW-BAM" .
1) LESEN UND SCHREIBEN EINES FILES Zunächst einmal möchte ich Ihnen zeigen, wie die beiden Routinen " READFILE" und " WRITEFILE" aus dem letzten Kursteil in der neuen Methode aussehen. Hierbei müssen wir lediglich den Aufruf von " CH-KIN/ CKOUT" mit dem von " TALK/ SECTALK" oder " LISTEN/ SECLIST" ersetzen. Der Aufruf von " CLRCH" am Ende der Öbertragung muß mit einem " UNTALK" bzw." UNLIST" ersetzt werden. Desweiteren muß den Sekundäradressen beim Üffnen der Wert $60 hinzuaddiert werden ('$60' bei ReadFile,'$61' bei WriteFile) .
Der Rest des Programms sollte sich von selbst erklären. Damit man die alte und neue Version der Routinen nicht miteinander verwechselt, heißen die neuen Versionen " IECREAD" und " IECWRITE" . Die Parameter, die beim Aufruf übergeben werden müssen, sind dieselben wie bei den alten Versionen:
IECREAD stx $ fb ; Startadresse in sty $ fc ; Zeiger ablegen.

          ldx #$34   ;Zeiger auf        
          ldy #$03   ; Filenamen        
          jsr setnam ; setzen.          
          lda #01    ;Fileparameter     
          ldx #08    ; setzen           
          ldy #$60   ; ($60=PRG Lesen)  
          jsr setpar                    
          jsr open   ;File öffnen       
          lda #08    ;"Gerät Nr. 8:     
          jsr talk   ; rede bitte!"     
          lda #$60   ;"Und zwar auf Se- 
          jsr sectlk ; kundäradr. $60)!"
          ldy #00    ;Offset=0          
loop1     jsr iecin  ;Zeichen lesen     
          sta ($fb),y; und ablegen      
          inc $fb    ;Zeiger            
          bne l1     ; um 1             
          inc $fc    ; erhöhen          
l1        lda $90    ;Ende erreicht?    
          beq loop1  ;Nein, dann weiter!

lda #08 ; Sonst:" Gerät jsr untalk ; Nr.8 : Ruhe bitte!" lda #01 ; File jmp close ; schließen ;*************************************** IECWRITE stx $ fb ; Startadresse in sty $ fc ; Zeiger ablegen

          ldx #$34   ;Filenamen         
          ldy #$03   ; setzen           
          jsr setnam                    
          lda #01    ;Fileparameter     
          ldx #08    ; setzen           
          ldy #$61   ; ($61=PRG schr.)  
          jsr setpar                    
          jsr open   ;File öffnen       
          lda #08    ;"Gerät Nr8: Hör'  
          jsr listen ; mir bitte zu!'   
          lda #$61   ;"Und zwar auf Sek.

jsr seclst ; Adr.$61 !")

          ldy #00    ;Offset=0          
loop2     lda ($fb),y;Zeichen holen     
          jsr iecout ; und abschicken   
          inc $fb    ;Zeiger            
          bne l2     ; um 1             
          inc $fc    ; erhöhen          
l2        lda $fe    ;Und mit           
          cmp $fc    ; Endadresse       
          bne loop2  ; vergleichen      
          lda $fd    ;Wenn ungleich     
          cmp $fb    ; dann weiter      
          bne loop2                     
          lda #08    ;"Gerät Nr.8:      
          jsr unlist ; Bin fertig!"     
          lda #01    ;File              
          jmp close  ; schließen        
2) FLOPPYSTATUS ANZEIGEN                

Ein weiterer Vorteil, der sich aus der Benutzung der direkten IEC-Routinen ergibt, ist, daß Sie nun problemlos, während des Arbeitens mit einem File, Statusmeldungen auf dem Bildschirm ausgeben können. Da die Standard Ein-/ Ausgabe ja nicht verändert wurde, erscheinen Texte, die mit BSOUT ausgegeben werden sollen, auch weiterhin auf dem Bildschirm. Umgekehrt wird bei BASIN von der Tastatur, und nicht etwa aus dem offenen File gelesen.
Als Beispiel für eine solche Anwendung möchte Ich Ihnen das Auslesen des Fehlerkanals der Floppy zeigen. Hierzu muß lediglich der Befehlskanal geöffnet, und die Fehlermeldung, die im ASCII-Code von der Floppy generiert und übermittelt wird, Zeichen für Zeichen ausgelesen und auf dem Bildschirm ausgegeben werden.
Ich denke, die Routine erklärt sich von selbst:

ERRCHN    lda #00    ;Länge Filename=0  
          jsr setnam ; für "Kein Name"  
          lda #01    ;Fileparameter     
          ldx #08    ; setzen           
          ldy #$6f   ; (=Befehlskanal)  
          jsr setpar                    
          jsr open   ;Filekanal öffnen  
          lda #08    ;Floppy Nr.8 zum   
          jsr talk   ; Senden auffordern
          lda #$6f   ;Und zwar auf Kanal
          jsr sectlk ; mit Sek.Adr. $6F 
ecloop1   jsr iecin  ;Zeichen lesen     
          jsr bsout  ;Und auf dem Bild- 
                      schirm ausgeben   
          lda $90    ;Fileende erreicht?
          beq ecloop1; Nein, also weiter
          lda #08    ;Floppy Nr.8       
          jsr untalk ; zurücksetzen     
          lda #01    ;Und Befehlskanal  
          jmp close  ; schließen        

3) BAM ANZEIGEN Als Nächstes wollen wir ein Programm schreiben, daß uns anzeigt, welche Blocks einer Diskette belegt sind, und welche nicht. Hierzu müssen wir die BAM (" Block Availability Map"), die im Disk-Header- Block ( Track 18 Sektor 0) zu finden ist, auslesen und zu einer grafikschen Anzeige dekodieren. Dies ist ein hervorragendes Beispiel um die Benutzung der neuen I/ O-Routinen zu demonstrieren und gleichzeitig zu zeigen, wie man mit der BAM umgeht. Sie erinnern sich vielleicht noch an deren Aufbau.
Ich hatte ihn in Teil 5 dieses Kurses besprochen:
Im Disk-Header- Block sind die Bytes 4 bis einschließlich 143 für die BAM reserviert. Hierbei zeigen jeweils 4 Bytes in Folge die Blockbelegung für einen Track an. Im ersten Byte steht dabei die Gesamtanzahl der freien Blocks dieses Tracks. Die Bits des zweiten Bytes ko- dieren die Belegung der Sektoren 0-7, die Bits des dritten Bytes die Belegung der Sektoren 8-15 und die Bits des vierten Bytes die Belegung der Sektoren 16-23 . Hat ein Track weniger Sektoren, als im vierten Byte angezeigt werden, so sind die restlichen Bits dieses Bytes unbenutzt ( so z. B. immer die letzten zwei Bits, da es ja nie mehr als 21 Tracks gibt) . Ein gesetztes Bit bedeutet, daß der entsprechende Sektor frei ist, ein gelöschtes Bit, daß er belegt ist.
Wollen wir einmal klären, welche Dinge zur Lösung des obigen Problems notwendig sind. Zunächst müssen wir den Befehlskanal und anschließend einen Pufferkanal öffnen. Nun muß der Befehl zur Floppy gesandt werden, der den Block 18/0 in den geöffneten Puffer liest. Ist dies geschehen, müssen wir nur noch auf das vierte Byte des Puffers positionieren ( dort beginnt ja die BAM) und die vier Belegungs-Bytes für jeden Track einlesen und darstellen.
Bitte Teil 2 des Kurses laden!

Valid HTML 4.0 Transitional Valid CSS!