Magic Disk 64

home to index to text: MD9104-KURSE-CIA-KURS_TEIL_6-3.txt

Dritter Teil:
Als Nächstes wird die absolute Anfangsadresse eines Textes, den ich im Speicher abgelegt habe, in LO/ HI-Darstellung in A/ Y geladen und der Wert 0 in das X-Register. Dies dient der Parameterübergabe für die Routine " SETIT", die anschließend aufgerufen wird. Sie gibt den Text, dessen Anfangsadresse in A/ Y steht aus und liest anschließend eine Uhrzeit ein, die sie in den Uhrregistern von CIA1 speichert. Zuvor schreibt sie den übergebenen Wert des X-Registers in CRB und setzt somit den Alarmoder Uhzeit-Setzen- Modus. Der erste Aufruf von SETIT setzt die aktuelle Uhrzeit, der zweite die Alarmzeit.
Anschließend wird der neue Interrupt eingestellt - alle IRQs werden gesperrt und der IRQ-Zeiger des Betriebssysems wird auf unsere neue Interruptroutine mit Namen " NEWIRQ" verbogen.
Nun folgen zwei Schleifen, die die Spri- tes, die wir benutzen wollen um die Uhrzeit auszugeben vorbereiten. Die erste Schleife kopiert eine Liste, die ich etwas weiter hinten im Source-Code abgelegt habe in den Bereich von $ D000 bis $ D00 F. Diese Register des VIC sind für die Koordinaten der Sprites verantworlich, die nun entsprechend gesetzt sind.
Die zweite Schleife schreibt in die VIC-Register 39 bis 46 den Wert 1, und setzt somit die Farbe für alle Sprites auf Weiß.
Nun müssen wir die CIA1 noch darauf vorbereiten, daß Echtzeituhr-Alarm- IRQs ausgelöst werden sollen. Dies geschieht, indem wir den Wert $85 in das ICR ( Reg.
13) von CIA schreiben. Damit lassen wir zum Einen die immer noch gültigen Timer-IRQs zu die von Timer A erzeugt werden zu ( für den System-IRQ), zum Anderen haben wir mit dem Wert $85 auch noch das 2 . Bit gesetzt, das Alarm-IRQs als Interruptquelle festlegt. Bit 7 muß wie immer gesetzt sein, damit die übrigen Bits als IRQ-Quelle übernommen werden.
Nun müssen wir noch den SID darauf vorbereiten, einen Piepton auszugeben, wenn ein IRQ auftritt. Deshalb wird das HI-Frequenzregister von Stimme1( Reg.1) mit dem Wert $ C0 geladen und eine Hüllkurve in Reg.5 des SID geschrieben.
Register 6, das ja ebenfalls Attribute der Hüllkurve angibt, wird nicht neu beschrieben, da es in der Regel den Wert 0 enthalten sollte, den ich dort auch haben wollte.
Zum Abschluß folgen nun noch 5 Befehle, die den Anfang des BASIC-Speichers höhersetzen. Dies ist erforderlich, da ich nämlich am normalen Anfang die Sprites und den Code von CLOCK untergebracht habe. Würden Sie nun ein BASIC-Programm eingeben, so würden Sie CLOCK überschreiben, was nicht sein sollte. In den Adressen $2 B und $2 C hat das Betriebssystem die Adresse des BASIC-Starts gespeichert. Wir setzen diese Adressen nun einfach auf die Endadresse von CLOCK und rufen anschließend die Routine bei $ A642 auf. Dort steht die BASIC-Routine für den Befehl " NEW" . Dies ist notwendig, damit die neue Anfangsadresse des BA-SIC- Speichers auch vom Betriebssystem angenommen wird.
Die Initialisierungsroutine gibt nun die IRQs wieder frei und springt zurück.
Kommen wir zu der neuen IRQ-Routine, die die Uhr steuert. Sie muß zunächst prüfen, ob der ausgelöste Interrupt ein Timer-, oder ein Alarm-IRQ war und dementsprechend reagieren. Bei Alarm gibt sie einen Piepton aus, bei einem Timer-IRQ wird nur die aktuelle Zeit aus CIA1 ausgelesen und mit Sprites auf dem Bildschirm dargestellt. Hierbei muß sie unterscheiden, ob die Zeit nun in 24 hoder AM/ PM-Darstellung auf dem Bildschirm erscheinen soll. Werfen wir doch einfach einmal einen Blick auf diese Routine:

========================================
NEWIRQ ist die IRQ-Routine von CLOCK.   
Hier wird zunächst einmal die vom Dar-  
stellungsmodus abhängige Spriteanzahl   
eingeschaltet.                          
========================================
newirq  lda #$7f       Wert für Sprites 
                       0-6 einschalten  
                       (für 24h)        
        ldx mode       Uhr-Modus prüfen.
        bne l5         ungleich 0, also 
                       24h              
        lda #$ff       Sonst AM/PM, des-
                       halb Wert für    
                       "Sprites 0-7 ein-
                       schalten" laden  
l5      sta v+21       und einschalten  
===                                     
Hier wird geprüft ob ein Alarm-IRQ (Bit2
von ICR=1) Auslöser war. Wenn ja, so wir
ein Piepton ausgegeben.                 
===                                     
        lda cia1+13    ICR auslesen     
        and #$04       Bit2 isolieren   
        beq timeref    Wenn =0, dann kei
                       Alarm und weiter 
        lda #15        Sonst Lautstärke 
        sta sid+24     einschalten      
        lda #33        Stimme 1 als "Sä-
                       gezahn"          
        sta sid+4      einschalten      
        ldx #$ff       Und warten...    
loop5   dey            (dies...         
        bne loop5      ...ist...        
        dex            ...eine...       
        bne loop5      ...Warteschleife)
        lda #00        Ton gespielt,    
                       deshalb          
        sta sid+4      Stimme1 aus      
        sta sid+24     Lautstärke aus   
========================================
Dies ist der Teil von NEWIRQ, der die   
Zeit neu ausgibt.                       
========================================
timeref ldx #43        Spriteblock "AM" 
                       in X laden       
        lda cia1+11    Stunden in Akku  
        bmi l6         Wenn 7.Bit=1 habe
                       wir "PM", dehalb 
                       weiter           
        cmp #$12       Akku=12 (in BCD)?
        bne l2         Nein, also weiter
        lda #00        12 Uhr AM gibts  
                       nicht, deshalb   
                       00 Uhr AM        
        beq l2         Unbedingter Sprun
===                                     
Hier wird hinverzweigt, wenn PM ist.    
===                                     
l6      inx            X-Reg enthält    
                       Spriteblock für  
                       "AM" - jetzt für 
                       "PM"             
        and #$7f       Bit7 (=PM) der   
                       Stunden löschen  
        ldy mode       Modus prüfen     
        beq l2         Wenn AM/PM dann  
                       weiter           
        cmp #$12       Akku = 12?       
        beq l3         Ja, dann nicht 12
                       addieren         
        sed            BCD-Mode an      
        clc            Weil PM, 12 ad-  
        adc #$12       dieren (für 24h) 
        cld            BCD-Mode aus     
l2      stx sprpoi+7   AM/PM-Sprite     
                       schalten         

======================================== Nun folgt der Teil von NEWIRQ der die aktuelle Zeit ausgibt.
======================================== l3 jsr getnum Akkuinhalt in Spritepointer umwandeln stx sprpoi+0 Sprites für Stunsta sprpoi+1 den setzen

        lda cia1+10    Minuten laden    
        jsr getnum     ...wandeln       
        stx sprpoi+2   ...und           
        sta sprpoi+3   ...setzen        
        lda cia1+9     Sekunden laden   
        jsr getnum     ...wandeln       
        stx sprpoi+4   ...und           
        sta sprpoi+5   ...setzen        
        lda cia1+8     Zehtelsek. laden 
        clc            Spritepointer der
        adc #sprbas    Ziffer 0 addiern 
        sta sprpoi+6   und setzen       
        jmp $ea31      IRQ beenden      
========================================

Zunächst einmal möchte ich Ihnen die In halte und die Bedeutung verschiedene Labels in diesem Teil des Listings erläu tern:

* MODE enthält den Wert 3 und steht fü die Speicherzelle 3, in der wir j festgelegt hatten in welchem Darstel lungsmodus CLOCK arbeiten soll.

* SPRPOI enthält den Wert 2040, die Basi sadresse der Spritepointer. In diese Pointern wird angegeben, welcher Spri teblock in einem Sprite dargestell werden soll.

* SPRBAS enthät den Wert 33 und steht fü den ersten Spriteblock, den wir verwen den. In ihm steht die Ziffer 0 al Sprite. Addieren wir zu einem Wert i Akku ( zwischen 0 und 9) den Wert SPRBA hinzu, so erhalten wir den Zeiger au den Spriteblock mit der entsprechende Ziffer des Wertes, den wir im Akku ste hen hatten.

* GETNUM ist eine Routine, die eine BCD Zahl im Akku in die zwei Ziffernwert aufspaltet und SPRBAS zu diesem Wer hinzuaddiert. In X-Register und Akk werden die Spritepointer der beide Ziffern zurückgegeben.
( Endgültig Schluß ist erst bei Teil vier. . .)

Valid HTML 4.0 Transitional Valid CSS!