Magic Disk 64

home to index to text: MD9310-KURSE-FLOPPY_INTERN_6.txt
           Floppy Intern                
           

( Teil 6) Herzlich willkommen zum letzten Teil unseres Floppykurses.
Nach harter Vorarbeit, ist es endlich soweit, sich als letzte Hürde den Floppyspeeder 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 geschiet.
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 Zustä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 zuzunä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=$0 b, 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 Ladezeiten 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 erklä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 Zyklenausgleich 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 Einund Ausgänge geschaltet, so daß jedes vollständig übertragene Bit softwaremä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 Fastloader, der sich bei genauerem Betrachten 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 entwickelt. 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 anderen noch offen sind.
Die im Code verwendete Adresse $1 c07 steht ursprünglich auf $3 a.
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 $1 c01 ließt Bytes von der Diskette.
Da diese Daten noch GCR codiert sind, reicht ein Puffer nicht aus und der Bereich $01 ba-$0200 wird mitbenutzt. Mit der Routine $ f8 e0 wird das ganze dann in Normalcode umgewandelt.
Nun sind wir am Ende unseres Floppykurses angelangt und ich hoffe es hat Ihnen Spass und Freude bereit, in die Wunderwelt der Floppyprogrammierung einzutauchen.

           Es verabschiedet sich,       
                          Frank Boldewin

Valid HTML 4.0 Transitional Valid CSS!