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...)