CIA-Kurs:
"Die Geheimnisse des Secret Service..."
(Teil 6)
----------------------------------------
Willkommen zum 6. Teil unseres CIA-
Kurses. Diesmal wollen wir, wie letzten
Monat schon versprochen, die Echtzeituh-
ren der CIAs programmieren. Hierbei han-
delt es sich pro CIA um je eine 24-
Stunden-Uhr, die weitaus genauer als die
von BASIC bekannte TI$-Uhr gehen. Sie
werden nämlich über die Frequenz des
Wechselstroms der aus der Steckdose
kommt getriggert. Da diese Frequenz in
der Regel immer 50 Hertz beträgt (dafür
sorgt das Elektrizitätswerk, das ihn in
das Stromnetz einspeist), gehen die Uh-
ren der CIA so gut wie nie falsch!
Zudem haben wir die Möglichkeit, eine
Alarmzeit zu programmieren. Stimmt ir-
gendwann die aktuelle Uhrzeit mit der
angegebenen Alarmzeit überein, so löst
die jeweilige CIA einen Interrupt aus.
Dieser wird uns im ICR dann auch ge-
trennt als Alarm-Interrupt angezeigt.
Auch dieses Mal habe ich Ihnen bezüglich
unseres Schwerpunktes ein Programm ge-
schrieben, daß sich auf dieser MD befin-
det. Es heißt "CLOCK" und wird mit RUN
gestartet. Desweiteren finden Sie wie
immer auch den Source-Code von CLOCK
unter dem Namen "CLOCK.SRC" im Hypra-
Ass-Format auf dieser Diskette. Mit ei-
nem Laden an den BASIC-Anfang (",8")
können Sie ihn sich mit LIST anschauen.
Kommen wir nun jedoch erst einmal zur
Theorie. Wie programmiert man denn einen
CIA-Timer?
Das gestaltet sich eigentlich als rela-
tiv einfach. In den Registern 8-11 einer
jeden CIA werden Zehntelsekunden, Sekun-
den, Minuten und Stunden abgelegt. Aus
diesen Registern kann ebenso die aktuel-
le Uhrzeit ausgelesen werden. Dennoch
gibt es einige Besonderheiten, die wir
beachten müssen. Hier zunächst einmal
eine Auflistung der besagten Register
mit ihrer Funktion:
Register Funktion
----------------------------------------
8 Zehntelsekunden
9 Sekunden
10 Minuten
11 Stunden
Erfreulicherweise sind die Uhren der
CIAs so ausgelegt, daß sie im BCD-Format
arbeiten. Dies ist ein spezielles Dar-
stellungsformat für Zahlen, das uns die
Umwandlung der Ziffern für eine Bild-
schirmausgabe erheblich vereinfacht. BCD
steht für "Binary Coded Decimal", was
übersetzt "Binär kodierte Dezimalzahl"
bedeutet. Dieser Code ist unter anderem
auch deshalb so vorteilhaft, weil der
Prozessor des C64, der 6510, es uns er-
laubt, mit diesen Zahlen zu rechnen.
Vielleicht kennen Sie ja die Assembler-
befehle SED und CLD. Mit ihnen kann man
das Dezimal-Flag des Prozessorstatusre-
gisters setzen oder löschen, um dem 6510
mitzuteilen, daß man nun mit BCD-Zahlen
rechnen möchte.
Ich will Ihnen das einmal anhand einiger
Beispiele erläutern. Kommen wir zunächst
zu dem Zahlenformat selbst. Im BCD-
Format wird ein Byte nicht wie sonst
anhand seiner gesetzten, oder gelöschten
Bits codiert, sondern ein Byte wird in
zwei 4-Bit Bereiche aufgepalten. Einen
solchen 4-Bit Abschnitt bezeichnet man
im Fachjargon als Nibble. Hier einmal
eine keine Verdeutlichung:
Nibble1 Nibble2
---------------
1001 0011
Nibble1 ist hierbei das höherwertige,
Nibble2 das niederwertige Nibble eines
Bytes. Im BCD-Format stellt nun jedes
Nibble eine Zahl zwischen 0 und 9 dar,
die dem normalen Binärformat entspricht
(deshlb auch "binär kodiert"). Hier ein-
mal eine Tabelle mit den Werten für die
Ziffern:
Wert Binär
-----------
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
Sie sehen, die Werte entsprechen also
denselben Werten die sie im Binärformat
haben. Die Besonderheit des BCD-Formates
ist nun, daß, wie oben schon erwähnt,
jedes Nibble eines Bytes eine Dezimal-
ziffer kodiert. Die Binärzahl aus dem
obigen Beipiel kann also folgendermaßen
interpretiert werden:
Binär : 1001 0011
BCD-Format : 9 3 = 93
Dezimal umgewandelt: 147
Das höherwertige Nibble der Zahl hat den
Binärwert 9, das niederwertige 3, wes-
halb die BCD-Zahl 93 lautet! So kann nun
jede Zahl zwischen 0 und 99 kodiert wer-
den. Die sonst 256 verschienden Binär-
zahlen werden auf 100 Kombinationen re-
duziert. Zahlen wie 11001010 gibt es im
BCD-Format nicht. Hier wäre die Wertig-
keit der Nibbles 12 und 10. Im BCD-
Format gibt dies jedoch keinen Sinn,
weshalb Bytewerte wie diese wegfallen.
In der Informatik spricht man dann von
einem "redundanten Code" - man kann mit
ihm weniger Elemente kodieren, als es
Möglichkeiten gibt.
Welchen Vorteil gibt uns nun das BCD-
Format in Bezug auf die Timerprogrammie-
rung? Nun aufgrund der einzelnen Nibble-
codierung können wir sehr leicht die
Ziffern der Minuten, Stunden, etc. he-
rausfinden. Eine komplizierte Binär-
Dezimal-Umwandlung fällt weg.
Desweiteren können wir mit dem Prozessor
im BCD-Format rechnen. Hierzu setzt man
zunächst das Dezimal-Flag mit dem Assem-
bler-Befehl SED. Hiernach verhalten sich
die Befehle ADC und SBC so, daß sie im-
mer BCD-Werte liefern, vorausgesetzt,
man addiert auch BCD-Werte miteinander.
Hierzu drei kleine Beispiele:
1) $11 + $12 = $23
2) $11 + $0C = $1D
3) $12 + $19 = $31
Ich habe in den Beispielen Hexadezimal-
zahlen verwendet, weil mit Ihnen BCD-
Zahlen einfacher anzuzeigen sind. Hex-
zahlen stellen ja ebenfalls die zwei
Nibbles eines Bytes dar, nur daß man
alle Möglichkeiten eines Nibbles berück-
sichtigt (von 0 bis F). Beachten wir
nun, daß Zahlen wie $1C gar keine BCD-
Zahlen sind, und verwenden wir sie auch
nicht, so können durch das Hexadezi-
malsystem sehr einfach BCD-Zahlen darge-
stellt werden. Hierbei entspricht die
Zahl $12 nicht wie sonst dem Dezimalwert
18, sondern tatsächlich dem Wert 12!!!
Das erste und dritte Beispiel soll Ihnen
nun verdeutlichen, wie im BCD-Format
gerechnet wird. 11+12 ergibt tatsächlich
23. Das wäre nun jedoch nichts neues, da
$11+$12 auch $23 ergäbe. Deshalb zeigt
Beispiel 3 das Aufreten eines Öberlaufs.
Ist der BCD-Modus eingeschaltet, so er-
halten wir aus der Addition 12+19 das
Ergebnis 31, was auch richtig ist. Bei
abgeschaltetem BCD-Modus wäre $12+$19-
gleich $2B! Beispiel 2 dient als Gegen-
beispiel für eine BCD-Rechung. Weil wir
hier mit $0C addierten, was ja keine
BCD-Zahl ist, kommt auch keine BCD-Zahl
als Ergebnis heraus.
Soviel zum BCD-Format. Kommen wir nun
zurück zu den Uhren der CIAs. Um die Uhr
einer CIA zu Setzen müssen wir also nur
BCD-Zahlen in die jeweiligen Register
schreiben um die aktuelle Zeit einzu-
stellen. Hierbei müssen wir jedoch noch
einige Dinge beachten:
1) Beim Setzen der Uhrzeit sollte IMMER
zunächst das Register für die Stunden
(Reg. 11) beschrieben werden. Wird
nämlich auf dieses Register zugegrif-
fen, so hält die entsprechende CIA
die komplette Uhr an. Dies ist des-
halb so wichtig, da die Uhr ja gerade
in dem Moment, in dem wir schreiben
auf die nächste Stunde umspringen
könnte. Würden wir eine 10 in das
Stundenregister schreiben und die
restlichen Register stünden auf der
Zeit ":59:59.9", so würde noch wäh-
rend wir die Minuten schreiben die
Uhr die volle Stunde erreichen und
unsere 10 wäre eine 11, und das
ist nicht die aktuelle Uhrzeit!
Umgekehrt verhält es sich mit dem
Register für die Zehntelsekunden
(Reg. 8). Erst, wenn es beschrieben
wurde, wird die Uhr wieder in Gang
gesetzt. Deshalb müssen wir also im-
mer gleich die komplette Uhrzeit set-
zen, damit die Uhr auch wirklich
läuft!
Ahnlich verhält es sich auch beim
Lesen. Hier sollten wir ebenfalls
IMMER zuerst die Stundenzahl lesen.
Dies veranlaßt die CIA zum Zwischens-
peichern der Uhrzeit in den 4 Uhrre-
gistern zum Zeitpunkt des Zugriffs.
Intern läuft die Uhr allerdings wei-
ter, sie wird also NICHT angehalten.
So können wir immer die richtige
Zeit, nämlich die, die zum Zeitpunkt
des Zugriffs in der Uhr stand, ausle-
sen. Auch hier muß das Zehntelsekun-
denregister als letztes ausgelesen
werden, damit die tatsächliche Uhr-
zeit wieder in die 4 Uhrregister
übertragen wird.
(Weiter geht's im zweiten Teil...)