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: