Magic Disk 64

home to index to text: MD9011-KURSE-CIA-KURS_TEIL_1-2.txt
MD9011-KURSE-CIA-KURS_TEIL_1-2.koala.png

CIA-Kurs Teil 2 Wie man leicht erkennen kann sind zur Timerprogrammierung sechs Register notwendig:

* TA-LO (Reg.4)                         
* TA-HI (Reg.5)                         
* TB-LO (Reg.6)                         
* TB-HI (Reg.7)                         
* CRA   (Reg.14)                        
* CRB   (Reg.15)                        

Desweiteren brauchen wir auch noch das Interrupt-Control- Register ( Reg.13) .
Ohne dieses Register läuft interruptmäßig überhaupt nichts mit dem CIA.
Der System-IRQ benutzt nun Timer A, der für ihn den Auslöser darstellt. Deshalb können wir die Register TB-LO, TB-HI und CRB vorläufig einmal ausschließen und uns nur den Registern für Timer A zuwenden.
Zunächst möchte ich jedoch den Begriff " Timer" definieren. Ein Timer, so wie er pro CIA ja zweimal vorhanden ist, ist nichts anderes als ein spezielles Zählregister, das ständig, nach ganz bestimmten Regeln von einem Maximalwert in Einerschritten heruntergezählt wird. Ist der Timer bei Null angelangt, so wird ein Interrupt ausgelöst.
Den schon angesprochenen Maximalwert müssen wir, wie Sie sicher schon vermuten in LO/ HI-Byte aufgespaltet in TA-LO und TA-HI schreiben. Diese Timerregister haben quasi ein " Doppelleben" . Sie bestehen nämlich zum Einen aus einem Speicherregister, dem sogenannten " LATCH" und einem Zählregister oder auch " COUN-TER" . Schreiben wir nun einen Wert in die Timerregister, so wird dieser zunächst im Latch abgelegt und gleichzeitig in den Counter geladen. Starten wir anschließend den Timer, so beginnt der CIA damit, den Counter herabzuzählen. Hierzu kann man verschiedene Signalquellen wählen, die ein Herabzählen veranlassen. Diese Signalquellen, können im Control-Register für Timer A festge- legt werden. Jedes der acht Bits in diesem Register steuert eine ganz bestimmte Funktion. Desweiteren kann von hier auch der Timer gestartet und gestoppt werden, sowie einige bestimmte Zählmodi eingestellt werden. Zur Erläuterung habe ich Ihnen einmal eine Tabelle erstellt:

Bit0 (START/STOP):                      

Durch Löschen dieses Bits wird der Timer gestoppt. Setzt man es, so wird begonnen, den Counter herabzuzählen.
Bit1( PB ON/ OFF) :
Dieses Bit eignet sich besonders für Hardware-Erweiterungen. Ist es gesetzt, so wird beim Unterlauf des Timers ein Signal auf die Portleitung PB6( Bit 6 an Port B) gelegt. Ist es gelöscht, so werden keine Signale ausgegeben.

Bit2 (TOGGLE-PULSE):                    

Dieses Bit arbeitet nur in Zusammenhang mit " PB ON/ OFF" . Ist dieses gesetzt, so gelten folgende Bestimmungen für " TOG-GLE- PULSE" :

* Wenn gelöscht, so werden wie bei " PB-ON/ OFF" beschrieben Signale auf die Leitung PB 7 gelegt. Diese sind übrigens genau einen Prozessortaktzyklus lang.

* Wenn gesetzt, so wird der Zustand von PB6 bei jedem Unterlauf des Counters in den jeweils anderen Zusand gekippt, das heißt von Gesetzt auf Gelöscht und umgekehrt. Damit läßt sich also ganz einfach ein Rechtecksignal erzeugen, wobei die Pulsbreite von der Laufzeit des Counters abhängt.
Wie Sie sehen, sind die Bits 1 und 2 für ganz spezifische Aufgaben verwendbar und haben leider sehr wenig mit Interrupts zu tun, zumal kein Interruptsignal an den Prozessor gesand wird. Für manche Harwareerweiterungen sind Sie jedoch bestimmt sinnvoll einzusetzen, da man so sehr einfach beliebige Taktfrequenzen für irgendewelche Schaltungen am User-Port des C64 erzeugen kann, da die Leitung PB6 an selbigem herausgeführt ist.
Hierzu jedoch in einem späteren Kursteil mehr.

Bit3 (ONE-SHOT/CONTINOUS):              

Ist dieses Bit gelöscht, so befindet sich der Timer im CONTINOUS-Modus. Das heißt, daß der Counter bis 0 heruntergezählt, wieder mit dem Wert im Latch geladen wird und von neuem beginnt zu zählen.
Bei gesetztem Bit ist der ONE-SHOT- Modus aktiv - es wird bis 0 gezählt und neu geladen, jedoch stoppt der Timer jetzt automatisch, solange bis man ihn wieder mit Bit0 des Controlregisters in Gang setzt.
Bit4( FORCE-LOAD) :
Wird dieses Bit gesetzt, so wird der Counter, egal ob der Timer im Moment läuft oder nicht, mit dem Wert im Latch neu geladen.
Bit5( IN MODE) :
Hier wird die Quelle des " Timer-Triggers" festgelegt. Der Timer-Trigger ist die Einrichtung, die den CIA dazu veranlaßt den Counter einmal herunterzuzählen.
Ist dieses Bit gelöscht ( was bei uns eigentlich immer der Fall ist), so wird der Systemtakt als Trigger herangezogen ( das werden wir im nächsten Abschitt ganz genau behandeln) . Ist es gelöscht, so ist die CNT-Leitung des CIA der Trigger. Diese ist an den Userport herausgeführt, so daß somit auch Hardware-Erweiterungen in der Lage sind die Interrupts im 64 er extern zu steuern.

Bit6 (SP-DIRECTION):                    

Dieses Bit hat etwas mit Register 12 der CIA zu tun ( SDR) . Dieses Register ist für die serielle Datenübertragung sehr nützlich. Hier kann ein 8- Bit-Wert ge- speichert werden, der zyklisch aus dem Register heraus, an den Pin SP des CIA ( mit dem Userport verbunden) gerollt wird, beziehungsweise ein Wert kann über den Pin SP hereingerollt werden ( auch dazu in einem späteren Kursteil mehr) .
Bit6 von CRA steuert nun die Datenrichtung von SDR. Ist es gelöscht, so ist SDR auf Eingang geschaltet ( Bits werden hereingerollt), ist es gesetzt, so wird SDR als Ausgang benutzt ( Bits werden herausgerollt) .

Bit7 (POWER FREQUENCY):                 

Dieses Bit wird benötigt um den Triggerfrequenz für die Echtzeituhr des CIAs zu bestimmen. Je nach dem, in welchem Land wir unseren 64 er angeschlossen haben, beträgt die Netzfrequenz des Wechselstroms aus der Steckdose nämlich 50 oder 60 Hertz ( man spricht hier vom sogenannten " technischen Strom") . Diese Frequenz wird nun benutzt um die Zeiteinheiten der Echtzeituhr festzustellen. Ist die- ses Bit nun gesetzt, so gilt eine Frequenz von 50 Hz als Trigger, ist es gelöscht, eine von 60 Hz. Da wir in der Bundesrepublik Deutschland ja die von 50 Hz haben, sollte bei Uhr-Betrieb dieses Bit also immer gesetzt sein, da andernfalls unsere Uhr schnell " nachgehen" könnte.
Na das ist doch schon eine ganze Menge an Information. Doch keine Angst, die Bits 1 und 2, die etwas komplizierter erscheinen mögen, wollen wir vorläufig erst einmal wegfallen lassen. Von ihnen wird, ebenso wie von Bit 6 und 7, in einer späteren Folge dieses Kurses mehr die Rede sein.
Nun zum Systemtakt, der - in aller Regelals Timer-Trigger dient. Er stellt wohl einen der wichtigsten Grundbausteine in unserem ( wie auch in jedem anderen) Rechner dar. Ein Rechensystem, so wie es von einem Computer verkörpert wird, braucht schlichtweg IMMER einen Grundtakt, den alle miteinander verknüpften Bausteine benutzen können um synchron miteinander zu arbeiten. Er dient sozusagen als " Zeitmaß" für die Geschäftswelt in einem Rechner. Ein Taktzyklus stellt die elementare Zeiteinheit innerhalb eines Rechner dar, an den sich alle Bausteine halten müssen um mit ihren Signalen nicht zu kollidieren. Solche Takte werden von Quarz-Bausteinen erzeugt, die, je nach chemischer Zusammensetzung, eine ganz bestimmte Eigenfrequenz haben, die extrem genau ist ( wie von Quartz-Uhren her ja allgemein bekannt) .
Ein Systemtakt ist von Rechner zu Rechner verschieden. Beim AMIGA beträgt er zum Beispiel 7 .16 MHz ( Megahertz), beim ATARI ST 8 MHz, bei PCs mittlerweile zwischen 4 .77 und 33 MHz ( und mehr) . Je höher ein Rechner " getaktet" ist, desto mehr Befehle kann er pro Sekunde abarbeiten und desto schneller ist er; wes- halb die Taktfrequenz häufig auch als ein Maß für die Rechengeschwindigkeit eines Rechners herangezogen wird.
Der C64 schneidet hier, aufgrund seiner schon etwas älteren Entwicklung und dem Fakt, daß er halt einfach nur ein Homecomputer ( der für jeden erschwindlich sein soll) ist, relativ schlecht ab. Mit etwa 1 MHz ist er vergleichsmäßig langsam, was jedoch immer noch affenschnell ist! Um genau zu sein sind es 985248 .4 Hz ( also knapp ein Mhz) . So zumindest bei der europäischen Version, die Sie ja alle haben sollten. Die amerikanischen 64 er sind sogar noch ein wenig schneller ( nämlich 1022727 .1 Hz), was für uns jedoch unerheblich ist.
Doch was bedeutet diese Zahl nun eigentlich für uns. Sie bedeutet schlichtweg, daß wir pro Sekunde genau 985248 .4 Taktzyklen haben; und die brauchen wir ja als Timer-Trigger. Damit wird es einfach, die Dauer zwischen zwei Counter-Unterläufen zu berechnen. Angenommen, Sie wollten ( aus welchem Grund auch immer), daß jede 1/16- Sekunde ein Interrupt ausgelöst würde. Demnach müßten Sie den Systemtakt einfach durch 16 dividieren und das Ergebnis in LO/ HI-Byte aufgespalten in die Register TA-LO und TA-HI schreiben. Konkret wäre das:

985248.4 / 16 = 61578.025 (dez.)        
                $F08A     (hex.)        
                LO: $8A = 138           
                HI: $F0 = 240           

Schreiben Sie diese beiden Werte nun in die Register 4 und 5 des CIA1, so wird der Systeminterrupt, der ja durch Timer A der CIA1 gesteuert wird, eindeutig verlangsamt ( normalerweise tritt er nämlich jede 1/60- Sekunde auf) . Erkennen können Sie dies am langsameren Cursorblinken, da auch das vom Systeminterrupt erledigt wird. Probieren Sie es doch einfach einmal, also:

POKE 56320+4,138:POKE 56320+5,240       
(56320 ist die Basisadresse von CIA1!)  

So. Nun wissen Sie also, wie man den Timer A eines CIA programmiert. Da dieser für IRQs jedoch schon vom Betriebsystem benutzt wird, und es da möglicherweise Timing-Probleme gibt, wenn wir eine eigene IRQ-Routine schreiben wollen, die zwar parallel zum Betriebsystem- IRQ läuft, aber öfter oder weniger oft als dieser auftreten soll, so gibt es für uns auch die Möglichkeit auf Timer B auszuweichen. Dieser ist absolut analog zu bedienen, nur, daß wir die Timerwerte diesmal in die Register 6 und 7 der CIA schreiben müssen ( TB-LO und TB-HI) . Desweiteren wird er vom Control-Register- Timer-B ( CRB) gesteuert - Register 15 der CIA also. Bis auf kleinere Unterschiede, ist der Aufbau der Register CRA und CRB identisch. Hier die Unterschiede:
1) Grundsätzlich sind die Funktionen der Bits 0 bis 4 gleich, jedoch mit dem Unterschied, daß sich die Bits 1 und 2 nicht mehr auf PB6 sondern auf PB7 beziehen.
2) Bit 5 und 6 steuern den IN-MODE von Timer B ( bei CRA war das NUR Bit 5) .
Hierzu ergeben sich 4 verschiedene Timer-Trigger- Modi:

   Bit 5 6  Funktion                    
   
       0 0  Zähle Systemtakt            
       0 1  Zähle CNT-Flanken           
       1 0  Zähle Unterläufe von Timer A
       1 1  Zähle Unterläufe  von  Timer
            A, wenn CNT=1               

Somit kann Timer B bei Steuerung durch Hardware bestens eingesetzt werden, da mehr externe Steuermöglichkeiten ( durch CNT) vorhanden sind.
3) Bit 7 steuert die Alarmfunktion der Echtzeituhr. Ist es gesetzt, so werden die Werte, die man in die Register der Echtzeituhr schreibt ( dazu auch in einem späteren Kursteil) als Alarmzeit genommen. Ist es gelöscht, so kann die normale Uhrzeit eingestellt werden.
Da die beiden Register CRA und CRB ebenfalls eine sehr wichtige Funktion bei den vielseitigsten Anwendungen erfüllen, habe ich Ihnen einmal eine grafische Öbersicht angefertigt:

Valid HTML 4.0 Transitional Valid CSS!