Magic Disk 64

home to index to html: MD9310-KURSE-FLOPPY_INTERN_6.html
           Floppy Intern                
           -------------                
              (Teil 6)                  
Herzlich willkommen zum letzten Teil un-
seres Floppykurses.                     
 Nach harter Vorarbeit,  ist  es endlich
soweit,sich als letzte Hürde den Floppy-
speeder zu setzen.Dies ist ein Programm,
welches es dem User ermöglich Daten  mit
vielfacher Geschwindigkeit zu laden.    
 Ich werde dazu zunächst den Vorgang der
seriellen  Programmierung  erklären, was
mit  Hilfe  von bestimmten Registern ge-
schiet.                                 
 Danach  werden  wir  genaustens auf den
"Floppyspeeder" eigehen,  der  sich  als
Objectcode auf Seite 1 dieser Magic Disk
befindet.                               
 Zunächst  die  Tabelle über die CIA Zu-
stände.                                 
C64:   Bit: Signal: Richtung: 1541: Bit:
----------------------------------------
$dd00  3    ATN       =>      $1800 7   
----------------------------------------
$dd00  5    DATA      =>      $1800 0   
$dd00  7              <=      $1800 1   
----------------------------------------
$d000  4    CLK       =>      $1800 2   
$dd00  6              <=      $1800 3   
----------------------------------------
  Bei der Übertragung von Bytes wird zu-
zunächst die ATN (Attention) Leitung auf
High geschaltet.Im C64 müssen zusätzlich
noch  Bit  0+1  auf  1  und  Bit 2 auf 0
stehen. Daraus ergibt sich also der Wert
11=$0b,  der in $dd00 geschrieben werden
muß,  um dem C64 mitzuteilen, daß gleich
Daten folgen.                           
 Im C64 gibt es nur eine ATN-Leitung die
Ein -und Ausgang steuert.               
 In  der  Floppy  hingegen ist Bit 4 für
den Ausgang und  Bit 7  für  den Eingang
des ATN Signals verantwortlich.         
 Da Daten von der Floppy zum C64 fließen
müssen  wir  also  Bit 4  (Ausgang)  auf
High schalten.                          
In Port $1800 steht demnach der Wert $10
Dadurch  weiß  die  Floppy,  daß  gleich
Daten herausgeschickt werden.           
 Wie  Sie vieleicht schon bemerkt haben,
lassen  sich  leider  keine ganzen Bytes
übertragen,   sondern jedes einzelne Bit
muß mühevoll durch die Leitung geschoben
werden.  Daß  dieser Vorgang lange Lade-
zeiten beschert,  brauche ich wohl nicht
näher zu erklären.                      
  Um nun die Daten sauber über die Data-
Leitung zu bekommen,  müssen  diese  auf
die Mikrosekunde genau getaktet werden. 
Dieser Vorgang geschieht durch die Clock
Leitung.   Hierdurch  erspart  man  sich
komplizierte Zyklenausgleiche.          
 Ohne  diese  Leitung  wäre beim zweiten
Bit die Übertragung beendet,  da der VIC
die  Arbeit  des  C64  regelmäßig für 40
Zyklen  unterbricht,  um  den Bildschirm
aufzufrischen.                          
 Dadurch  würden C64 und 1541 nicht mehr
synchron  arbeiten  und  die Chance, die
gewünschten  Daten  zu  bekommen, dahin.
Um den  Bildschirmaufbau  zu verhindern,
schreibt  man  einfach  eine 0 in $d011.
Danach sperrt man noch  schnell  den IRQ
mit SEI.                                
Durch diesen Trick ist die Clock-Leitung
frei  geworden  und  sie kann zusätzlich
zur Übertragung genutzt werden.         
 Das Timing zwischen C64 und 1541 bleibt
nun uns selbst überlassen.              
Gesagt sei noch,   daß in der Floppy die
Bits 1+3 (Data+Clock Ausgang) und im C64
die  Bits 6+7  (Data+Clock Eingang)  den
Datenverkehr regeln.                    
Im folgenden werde ich die  C64 und 1541
Routine  zur Übertragung eines Bytes er-
klären.                                 
1541 Routine: (Beispiel Byte $EA)       
    lda   #$ea  ;Byte                   
    sta   $c1   ;merken                 
m01 lda   $1800 ;auf Attention          
    bpl   m01   ;warten                 
    lda   #$10  ;Data                   
    sta   $1800 ;setzen                 
m02 lda   $1800 ;auf C64                
    bmi   m02   ;warten                 
    lda   #$00                          
    rol   $c1                           
    rol                                 
    rol                                 
    rol   $c1                           
    rol                                 
    rol                                 
    sta   $1800 ;Bits 5 und 7           
    lda   #$00                          
    rol   $c1                           
    rol                                 
    rol                                 
    rol   $c1                           
    rol                                 
    rol                                 
    sta   $1800 ;Bits 4 und 6           
    lda   #$00                          
    rol   $c1                           
    rol                                 
    rol                                 
    rol   $c1                           
    rol                                 
    rol                                 
    sta   $1800 ;Bits 1 und 3           
    lda   #$00                          
    rol   $c1                           
    rol                                 
    rol                                 
    rol   $c1                           
    rol                                 
    rol                                 
    sta   $1800 ;Bits 0 und 2 übertragen
    nop         ;durch                  
    nop         ;6 Taktzyklen           
    nop         ;ausgleichen            
    lda   #$0f  ;ATN                    
    sta   $1800 ;zurücksetzen           
    rts         ;Ende                   
Wie Sie vieleicht bemerkt haben, muß man
diese Routine sehr sorgfältig entwickeln
da die  Clock Leitung ihrer eigentlichen
Aufgabe  entmächtigt  wurde  und nun als
zusätzliches Übertragungsbit dient.     
Auch bei der C64 Routine ist der Zyklen-
ausgleich  nötig  wie  Sie  gleich sehen
werden.                                 
    lda  #$0b   ;ATN                    
    sta  $dd00  ;setzen                 
m01 lda  $dd00  ;auf Data Leitung       
    bpl  m01    ;warten                 
    lda  #$03   ;ATN                    
    sta  $dd00  ;zurücksetzen           
    inc  $d020  ;mit                    
    jsr  m02    ;30                     
    nop         ;Takt-                  
    nop         ;zyklen                 
    nop         ;aus-                   
    dec  $d020  ;gleichen               
    lda  $dd00                          
    rol                                 
    php                                 
    rol                                 
    rol  $08                            
    plp                                 
    rol  $08    ;Bits 5 und 7           
    lda  $dd00                          
    rol                                 
    php                                 
    rol                                 
    rol  $08                            
    plp                                 
    rol  $08    ;Bits 4 und 6           
    lda  $dd00                          
    rol                                 
    php                                 
    rol                                 
    rol  $08                            
    plp                                 
    rol  $08    ;Bits 1 und 3           
    lda  $dd00                          
    rol                                 
    php                                 
    rol                                 
    rol  $08                            
    plp                                 
    rol  $08    ;Bits 0 und 2 übertragen
    lda  $08    ;Byte                   
    eor  #$ff   ;invertieren            
m02 rts         ;Ende                   
Sie werden sich vieleicht wundern, warum
zum  Schluss  der Routine der ganze Wert
invertiert wird.                        
Die Ursache liegt in der Hardware!   Die
Entwickler haben keine Inverter vor  die
Ein- und Ausgänge geschaltet, so daß je-
des  vollständig  übertragene  Bit soft-
waremässig invertiert werden muß.       
Diese  Routinen  sind  eigenständig  und
können in der 1541 bzw. im  C64  mit JSR
angesprungen werden.                    
Auf der Diskette befindet sich ein Fast-
loader,  der sich bei genauerem Betrach-
ten in 5 Teile aufteilen läßt.          
1.Eine Routine die das Floppyprogramm   
  in die 1541 verfrachtet.              
2.Eine Routine die sich das File vom    
  ersten bis zum letzten Byte in den    
  C64 Speicher holt.                    
3.Die eben beschriebene Routine zur     
  Uebertragung eines Bytes              
  (1541-Routine).                       
4.Und die eben beschriebene Routine zur 
  Uebertragung eines Bytes              
  (C64-Routine).                        
5.Eine Routine die sich das File in den 
  1541 Speicher holt.                   
 Die  Routinen  1 und 2  können  wir uns
getrost  sparen,  denn  solche  Routinen
wurden schon in früheren Kursteilen ent-
wickelt. Nummer 3 und 4 haben wir oben  
schon besprochen.                       
 Lediglich Routine 5 bedarf einer kurzen
Erlaeuterung.                           
    lda #$12    ;Zähler=0?              
    sta $1c07   ;nächster Stepperschritt
    lda #$03    ;aktueller              
    sta $31     ;Puffer 0 ($0300)       
    jsr $f50a   ;Datenblockanfang suchen
m01 bvc m01     ;Ready?                 
    clv         ;Flag loeschen          
    lda $1c01   ;1 Byte lesen           
    sta ($30),y ;und ab $0300 speichern 
    iny         ;Zaehler erhoehen       
    bne m01     ;Puffer schon voll?     
    ldy #$ba    ;Überlaufpuffer benutzen
m02 bvc m02     ;Ready?                 
    clv         ;Flag löschen           
    lda $1c01   ;1 Byte lesen           
    sta $0100,y ;und ab $01ba speichern 
    iny         ;Zähler erhoehen        
    bne m02     ;schon letztes Byte?    
    jsr $f8e0   ;GCR-Code umwandeln     
    rts         ;Ende                   
 Diese  Routine  macht eigentlich nichts
anderes als der Jobcode $80, der für das
Lesen von Sektoren verantwortlich ist.  
Ich habe diese Routine deshalb verwendet
weil ein Blick hinter die  Kulissen sehr
Lehrreich sein kann, wie  Sie  vieleicht
bemerkt haben.                          
Doch nun möchte ich noch ein paar Fragen
beanworten, die bei dem einen oder ande-
ren noch offen sind.                    
Die  im  Code  verwendete  Adresse $1c07
steht ursprünglich auf $3a.             
Dadurch,  daß sie auf $12 gesetzt wurde,
wird  bewirkt,  daß   der   Steppermotor
schneller reagiert, beim   Trackwechsel.
Dieser  Trick  ist  sehr  nützlich  bei 
vollen Disketten.                       
Die Zeropage-Adressen $30/$31  geben den
aktuellen Puffer an,  mit dem gearbeitet
werden soll.                            
Die  Port-Adresse  $1c01 ließt Bytes von
der Diskette.                           
Da  diese  Daten  noch GCR codiert sind,
reicht ein Puffer nicht  aus und der Be-
reich $01ba-$0200 wird mitbenutzt.   Mit
der Routine $f8e0 wird das ganze dann in
Normalcode umgewandelt.                 
Nun  sind  wir  am  Ende unseres Floppy-
kurses angelangt  und  ich  hoffe es hat
Ihnen  Spass  und  Freude bereit, in die
Wunderwelt der Floppyprogrammierung ein-
zutauchen.                              
           Es verabschiedet sich,       
                          Frank Boldewin



Valid HTML 4.0 Transitional Valid CSS!