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