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