FLOPPY-INTERN (Teil 3)
Willkommen zur dritten Runde unseres
Floppykurses.
Nachdem wir im letzten Teil das Status-Flag und seine Belegung angesprochen
haben, möchten wir Ihnen diesmal ein
Programm vorstellen, daß den Fehlerkanal
ausließt.
lda #$00 ;Status-Flag sta $90 ;auf 0 setzen lda #$01 ;Filenummer ldx #$08 ;Geräteadresse ldy #$6f ;Sekundäradresse jsr $fe00 ;Fileparameterjump lda #$00 ;Länge des jsr $fdf9 ;Filenamens=0 jsr $f34a ;Open lda #$08 ;Geräteadresse jsr $ed09 ;auf Senden einstellen lda #$6f ;Sekundäradresse jsr $edc7 ;übertragen
m01 jsr $ ee13 ; Byte empfangen jsr $ f1 ca ; ausgeben bit $90 ; wenn Bit6=0 bvc $ m01 ; dann nächstes Byte lda #$08 ; Senden durch jsr $ edef ; Untalk beenden lda #$01 ; Filenummer auf 1 jsr $ f291 ; und Close rts Beim Starten dieser Routine, gibt Ihnen
die Floppy entweder den entsprechenden
Fehler aus oder meldet, daß alles ' ok' ist. Über die Subroutine " JSR $ EE13" wird
der die Fehlermeldung Byte für Byte von der Floppy zum Computer übertragen und
auf dem Bildschirm ausgegeben.
Über Bit 6 kann geprüft werden, wann das
Ende der Fehlermeldung erreicht ist. Ist
Bit 6=0, so bedeutet dies, daß noch
nicht alle Bytes der Fehlermeldung übertragen wurden. Es wird also solange zu
" JSR $ EE31" zurückgesprungen, bis die
die Floppy mit einem gesetzten Bit 6 das
Ende der Übertragung signalisiert.
Interne-Programmausführung
In dem folgenden Abschnitt wollen wir
uns mit der ganz besonderen Fähigkeit
der Floopy befassen, kleinere Routinen
" intern" auszuführen.
In den vorangegangenen Beispielen haben
wir immer nur einfache Floppy-Routinen
vom C64 aus gestartet. Doch damit sind
die Möglichkeiten der Floppy noch lange
nicht erschöpft. Man kann zB auch ganze
Programme in die Floppy transportieren, die diese dann selbständig ausführt. Dies
ist besonders dann wichtig, wenn man
einen eigenen Schnellader oder einen Kopierschutz schreiben will
Wie sie vieleicht wissen, handelt es
sich bei der VC1541 um ein intelligentes
Diskettenlaufwerk mit eigenem Prozessor
(6502), Speicherplatz ( RAM und ROM) und
Betriebsystem ( DOS) . Dadurch wird kein
Speicherplatz und keine Rechenzeit vom angeschlossenen C64 benötigt. Der C64 braucht der Floppy lediglich Befehle zu
übermitteln, die diese dann selbständig
ausführt. Im Grunde genommen, ist ihre
VC1541 nichts weiter als eine zweiter
Computer neben ihrem C64 . Sie haben also
nicht nur einen sondern gleich zwei Computer auf ihrem Schreibtisch stehen.
Im Normalbetrieb muß die Floppy drei
verschiedenen Aufgaben gleichzeitig erledigen. Dazu gehören:
1- Durchführung der Datenübertragung von
und zum C64 .
2- die Interpretation der Befehle und die
Verwaltung von Dateinen, der zugeordneten Übertragungskanäle und der Blockbuffer.
3- die hardwaremäßige Ansteuerung der Diskette.
Mit Hilfe einer ausgereiften IRQ-Technik
kann die Floppy diese drei Aufgaben
praktisch gleichzeitig ausführen.
Nachdem wir bereits in den letzten beiden Kursen auf den Aufbau der Diskette
eingegangen sind, wollen wir uns einmal
ansehen, wie das DOS seine Aufgaben erledigt.
Selbverstündlich darf man beim Schreiben
von eigenen Routinen im Floppybuffer
auch die vorhandenen Betetriebsystemroutinen verwenden. Ganz so einfach wie
im C64, geht es bei der Floppy jedoch
nicht.
Das Betriebssystem der Floppy kann man
in zwei Teile unterteilen. Der erste Teil
ist das Hauptprogramm, das in einer Endlosschleife läuft. Von diesem Teil aus
wird Hauptsächlich der serielle Bus verwaltet. Fast alle Unterprogrammaufrufe
werden mit absoluten Sprüngen ausgeführt
und müssen somit mit einem JMP-Befehl
zurück ins Hauptprogramm abgeschlossen
werden. Diese Routinen können nicht in
eigenen Programmen verwendet werden.
Der zweite Teil des Betriebsystems, ist
daher um so besser für eigene Programme
zu verwenden, denn es handelt sich dabei
um ein IRQ-Programm, welches auch als
" Jobschleife" bezeichnet wird.
Dieses Programm übernimmt die Leseund
Schreiboperationen auf und von Diskette.
Bei jedem Interrupt werden die Speicherstellen $0 bis $5 der ( Floopy) Zeropage, die die Schnittstelle, zwischen dem
Hauptprogramm herstellen, auf ihre Werte
überprüft. Alle Werte, die gleich oder
größer $80 sind werden als Befehle( Jobs) behandelt und ausgeführt. Jede dieser
Speicherstellen ( Job-Speicher) bezieht
sich auf einen bestimmten Speicherbereich. Zusätzlich gehören zu jedem Job-Speicher noch zwei Speicherstellen, die
den Track und den Sektor angeben, auf
die sich der Job( Befehl) bezieht.
Die nachfolgende Tabelle, verdeutlicht
den Zusammenhang zwischen Job( Adresse) Track-Sektorangabe und Speicherbereich.
-----+-------+--------+----------------- JOB | TRACK | SEKTOR | SPEICHERBEREICH | | | (Buffer) $00 | $06 | $07 | $0300-$03ff $01 | $08 | $09 | $0400-$04ff $02 | $0a | $0b | $0500-$05ff $03 | $0c | $0d | $0600-$06ff $04 | $0e | $0f | $0700-$07ff $05 | $10 | $11 | kein RAM -----+-------+--------+----------------- Die nächste Tabelle zeigt die Bedeutung der einzelnen Job-Codes. --------+------------------------------- JOB-CODE| AUFGABE $80 |Sektor lesen $90 |Sektor schreiben $a0 |Sektor verifizieren $b0 |Sektor suchen $c0 |Kopfanschlag $d0 |Programm im Puffer ausführen $e0 |Programm im Puffer ausführen, |vorher Laufwerksmotor ein- |schalten und Kopf positionieren --------+-------------------------------
Was man mit den Job-Codes anfangen, wollen wir anhand von einem Beispiel
zeigen.
Das nachfolgende Floppyprogramm soll
Sektor $00 von Track $12 in den Buffer 0 laden.
FLOPPYCODE: lda #$12 ;Tracknummer sta $06 ;übergeben) lda #$00 ;Sektornummer sta $07 ;übergeben) lda #$80 ;Jobcode lesen sta $00 ;in Jobspeicher EndSignal: lda $00 ;Rückmeldung bmi EndSignal;abwarten) rts
Dieses Programm muß natürlich erst in
die Floppy transportiert werden, damit es
ausgeführt werden kann. Diese Aufgabe
erledigt unser nächstes Programm.
lda #$01 ;FLOOPY INITIALISIEREN ldx #$08 ldy #$6f jsr $fe00 (Filparmeter übergeben) lda #$00 jsr $fdf9 (Filename=0) jsr $f34a (Open) lda #$08 jsr $ed0c (Listen) lda #$6f jsr $edb9 (Seclst) lda #"I" jsr $eddd (Init Floppy) lda #$08 jsr $edfe (Unlisten) ************************************** lda #$08 ;FCODE IN FBUFFER jsr $ed0c (Listen) lda #$6f jsr $edb9 (Seclst) lda #"M" jsr $eddd lda #"-" jsr $eddd lda #"W" jsr $eddd lda #$00 ;ADRESSE LO jsr $eddd lda #$05 ;ADRESSE HI jsr $eddd lda #$11 ;$11 Bytes kpieren jsr $eddd (m-w,nach $0500 ldy #$00 m01 lda FCODE,y jsr $eddd iny cpy #$11 bne $m01 (Floppyrout.in def. Puff lda #$08 jsr $edfe (Unlisten) ;*************************************** lda #$08 jsr $ed0c (Listen) lda #$6f jsr $edb9 (Seclst) lda #"M" jsr $eddd lda #"-" jsr $eddd lda #"E" jsr $eddd lda #$00 ;STARTADRESSE LO jsr $eddd lda #$05 ;SRARTADRESSE HI jsr $eddd (m-e,start $0500) lda #$08 jsr $edfe (Unlisten) ;*************************************** lda #$08 jsr $ed0c (Listen) lda #$6f jsr $edb9 (Seclst) lda #"M" jsr $eddd lda #"-" jsr $eddd lda #"R" jsr $eddd lda #$00 ;BUFFER ADRESSE jsr $eddd lda #$03 ;BUFFER ADRESSE jsr $eddd lda #$00 ;$00 = $0100 jsr $eddd (M-R,nach$0300 lda #$08 jsr $edfe (Unlisten) lda #$08 jsr $ed09 (Talk) lda #$6f jsr $edc7 (Sectlk) ldy #$00 m02 jsr $ee13 sta $0400,y iny bne $m02 (Sektor a.Screen ausgebe lda #$08 jsr $edef (Untalk) lda #$01 jsr $f291 (Close) rts FCode: lda #$12 sta $06 lda #$00 sta $07 lda #$80 sta $00 m03: lda $00 bmi $m03 rts
Was noch zu beachten wäre, ist daß Sie
immer nur $20 Hex-Bytes mit einem Schlag
in die Floppy übertragen können. Ist ihr
Floppyprogramm also länger, müssen sie es
schrittweise hineinschreiben.
Der Buffer für den Programmcode und der
Buffer für die Daten, dürfen nie gleich
sein, weil der Programmcode sich wärend
der Ausführung selbst überschreiben würde. Die Folge wäre ein Absturz der
Floppy.
Um die Routine nun noch besser zu verstehen, erkläre ich Ihnen kurz noch einmal wie ich vorgegangen bin.
1 . initialisieren der Floppy.
2 . in Puffer 2($0500), wird die Floppyroutine zum Lesen eines Blocks geschrieben.
3 . Start des Progamms in der Floppy.
4 . Einlesen des Blocks in P.0($0300) .
Von dort aus abholen und auf dem Bildschirm ausgeben.
Sie werden sich sicherlich gefragt haben
warum ich beim M-R $00 als Anzahl der
zu lesenden Bytes angegeben habe. Weil
die Angabe null Bytes zu lesen praktisch
gesehen einen sinnlose Aufgabe ist, wird
der Wert $00 intern in $100 umgewandelt.
Es werden also $0100 Bytes aus dem
Floppybuffer geladen.
Da mit diesem Beispiel die Grundstein zu
Job-Code Programmierung gelegt wurde, dürfte auch der Direktzugriff in Assembler für Sie kein Problem mehr darstellen
Mit diesen Grundlagen müßten Sie eigentlich auch mit den anderen Job-Codes zurecht kommen.
Beim Tüfteln wünsche ich Ihnen viel
Spass und verabschiede mich bis zum
nächsten Mal!( FB)