Magic Disk 64

home to index to html: MD9301-KURSE-FLOPPY-KURS_8.1.html
----------------------------------------
              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  Floppypro-
grammierung  in Assembler einsteigen. Im
letzten Monat hatten wir ja schon  ange-
sprochen,  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 anspre-
chen kann.                              
DIE ALTE METHODE                        
In der letzten Ausgabe des Floppy-Kurses
hatten  wir  gelernt,  wie  man ein File
öffnet, es zur Datenübertragung  bereit-
macht,  Daten  an  es sendet und von ihm
empfängt,  und  es  anschließend  wieder
schließt.  Die  dort behandelte Arbeits-
weise 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 Me-
thode gingen  wir  immer  folgendermaßen
vor:                                    
1 ) "SETNAM"  mit den Parametern für den
    Filenamen aufrufen.                 
2 ) "SETPAR"  mit  den Datenkanalparame-
    tern aufrufen.                      
3 ) Mit "OPEN" das File öffnen          
4a) War das File eine  Ausgabedatei,  so
    mussten wir "CKOUT" aufrufen.       
4b) War das File eine  Eingabedatei,  so
    mussten wir "CHKIN" aufrufen.       
5a) War das File eine  Ausgabedatei,  so
    wurden  die  Daten mit Hilfe von "B-
    SOUT" geschrieben.                  
5b) 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ückge-
    stellt.                             
7 ) Das File wurde mit "CLOSE" geschlos-
    sen.                                
Wie gesagt, ist diese Methode  die  ein-
fachste,  wenn Sie ein einziges File le-
diglich  Lesen  oder  Schreiben  wollen.
Wenn  Sie  nun aber mehrere Files offen-
halten und ansprechen wollen, oder  aber
auf einem Kanal Lesen und Schreiben wol-
len (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   ge-
schieht  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  Bild-
schirm   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 wer-
den.                                    
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, Ta-
statur, etc.) ansprechen können, weshalb
die Restriktionen dort etwas  umständli-
cher 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  er-
sten  Routinen  erst  einmal entschieden
werden muß, welche effektiven  Ein-/Aus-
gaberoutinen 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 mei-
ne 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 Kommu-
nikationsschnittstelle zwischen C64  und
Floppy  dient, werden auf Ihm Daten ent-
weder vom Rechner zur Floppy oder  umge-
kehrt  hin- und herbewegt. Die Verarbei-
tung dieser Daten ist dann dem  jeweili-
gen Gegengerät überlassen, daß die Daten
empfangen hat. Noch dazu kann es vorkom-
men, 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 festge-
legt  werden  welches der Geräte nun mit
welchem (im Normalfall dem 64er)  kommu-
nizieren  soll. Hierzu dienen nun insge-
samt sechs Betriebssystemroutinen.      
Als erstes müssen wir wieder einmal  ein
File auf die gewohnte Art und Weise öff-
nen. Zunächst übergeben wir die  Filena-
menparameter mit Hilfe von "SETNAM" (Ak-
ku=Länge des Namens, X/Y=Zeiger auf  Na-
mensstring).  Anschließend  muß "SETPAR"
aufgerufen werden. Hierbei kommen  File-
nummer  und  Geräteadresse, wie gewohnt,
in Akku und  X-Register.  Im  Y-Register
wird  die  Sekundäradresse abgelegt. Je-
doch müssen wir hier, anders als  sonst,
die  gewünschte Sekundäradresse plus $60
(=dez. 96) übergeben. Dies hat Floppyin-
terne  Gründe.  Möchten wir also den Be-
fehlskanal ansprechen, so  muß  die  Se-
kundäradresse  $6F  (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  ge-
wünschten Gerätes im Akku ablegen.      
Als  nächstes muß dem Gerät an der ande-
ren  Seite  mitgeteilt  werden,  welcher
seiner  offenen  Kanäle senden oder emp-
fangen 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  spe-
ziellen   IEC-Ein-/Ausgaberoutinen,  die
ich oben schon ansprach. Sie können  sie
genauso  wie "BASIN" und "BASOUT" benut-
zen. 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  wer-
deb muß.                                
Haben Sie die Ein- oder Ausgabe beendet,
so müssen  Sie  das  entsprechende  Emp-
fangs-,  bzw.  Sendegerät  wieder in den
Wartezustand  zurückbringen.  Dies   ge-
schieht  über  die Routinen "UNTALK" und
"UNLIST". Die erstere  müssen  Sie  nach
dem  Empfang, die letztere nach dem Sen-
den 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 File-
kanal und teilen der Floppy mit, daß sie
Daten  empfangen  soll   ("LISTEN"   und
"SECLST"  aufrufen). Nun senden Sie mit-
tels  "IECOUT"  den  Befehlsstring.  An-
schließ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  Be-
fehlskanal  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 ans-
prechen, müssen Sie einfach den entspre-
chenden Öbertragungsmodus festlegen  und
seine   Sekundäradresse  an  die  Floppy
schicken. Denken Sie  immer  daran,  daß
Sie  nach jeder Lese- oder Schreibopera-
tion 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 Programm-
beispielen, 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üs-
sen  wir  lediglich  den Aufruf von "CH-
KIN/CKOUT" mit  dem  von  "TALK/SECTALK"
oder  "LISTEN/SECLIST" ersetzen. Der Au-
fruf von "CLRCH" am Ende der Öbertragung
muß mit  einem  "UNTALK"  bzw.  "UNLIST"
ersetzt  werden. Desweiteren muß den Se-
kundä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 mitei-
nander  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 er-
gibt, ist, daß Sie nun problemlos,  wäh-
rend  des Arbeitens mit einem File, Sta-
tusmeldungen 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. Umge-
kehrt  wird  bei BASIN von der Tastatur,
und nicht etwa aus dem offenen File  ge-
lesen.                                  
Als Beispiel für eine  solche  Anwendung
möchte  Ich  Ihnen das Auslesen des Feh-
lerkanals 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 gra-
fikschen Anzeige  dekodieren.  Dies  ist
ein  hervorragendes  Beispiel um die Be-
nutzung der neuen  I/O-Routinen  zu  de-
monstrieren  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  re-
serviert. 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 vier-
ten  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 bedeu-
tet, 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 Befehlska-
nal 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!