Magic Disk 64

home to index to text: MD9306-KURSE-FLOPPY_INTERN_3.txt
              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)

Valid HTML 4.0 Transitional Valid CSS!