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 $f1ca ;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 über- tragen 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 Ko- pierschutz 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 Com- puter auf ihrem Schreibtisch stehen. Im Normalbetrieb muß die Floppy drei verschiedenen Aufgaben gleichzeitig er- ledigen. Dazu gehören: 1-Durchführung der Datenübertragung von und zum C64. 2-die Interpretation der Befehle und die Verwaltung von Dateinen,der zugeordne- ten Übertragungskanäle und der Block- buffer. 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 bei- den Kursen auf den Aufbau der Diskette eingegangen sind, wollen wir uns einmal ansehen, wie das DOS seine Aufgaben er- ledigt. Selbverstündlich darf man beim Schreiben von eigenen Routinen im Floppybuffer auch die vorhandenen Betetriebsystem- routinen 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 End- losschleife läuft. Von diesem Teil aus wird Hauptsächlich der serielle Bus ver- waltet. 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 Lese- und Schreiboperationen auf und von Diskette. Bei jedem Interrupt werden die Speicher- stellen $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 Speicherbe- reich. 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 ver- stehen, erkläre ich Ihnen kurz noch ein- mal wie ich vorgegangen bin. 1. initialisieren der Floppy. 2. in Puffer 2 ($0500),wird die Floppy- routine 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 Assemb- ler für Sie kein Problem mehr darstellen Mit diesen Grundlagen müßten Sie eigent- lich auch mit den anderen Job-Codes zu- recht kommen. Beim Tüfteln wünsche ich Ihnen viel Spass und verabschiede mich bis zum nächsten Mal! (FB)