Magic Disk 64

home to index to text: MD9104-KURSE-CIA-KURS_TEIL_6-1_:_DIE_GEHEIMNISSE_DES_SECRET_SERVICE_(TEIL_6).txt
                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 Echtzeituhren der CIAs programmieren. Hierbei handelt 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 Uhren der CIA so gut wie nie falsch!
Zudem haben wir die Möglichkeit, eine Alarmzeit zu programmieren. Stimmt irgendwann 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 geschrieben, daß sich auf dieser MD befindet. 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 einem 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 relativ einfach. In den Registern 8-11 einer jeden CIA werden Zehntelsekunden, Sekunden, Minuten und Stunden abgelegt. Aus diesen Registern kann ebenso die aktuelle 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 Darstellungsformat für Zahlen, das uns die Umwandlung der Ziffern für eine Bildschirmausgabe 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 erlaubt, mit diesen Zahlen zu rechnen.
Vielleicht kennen Sie ja die Assemblerbefehle SED und CLD. Mit ihnen kann man das Dezimal-Flag des Prozessorstatusregisters 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                         

10010011 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 einmal 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 Dezimalziffer 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, weshalb die BCD-Zahl 93 lautet! So kann nun jede Zahl zwischen 0 und 99 kodiert werden. Die sonst 256 verschienden Binärzahlen werden auf 100 Kombinationen reduziert. Zahlen wie 11001010 gibt es im BCD-Format nicht. Hier wäre die Wertigkeit 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 Timerprogrammierung? Nun aufgrund der einzelnen Nibble- codierung können wir sehr leicht die Ziffern der Minuten, Stunden, etc. herausfinden. 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 Assembler- Befehl SED. Hiernach verhalten sich die Befehle ADC und SBC so, daß sie immer 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 Hexadezimalzahlen verwendet, weil mit Ihnen BCD-Zahlen einfacher anzuzeigen sind. Hexzahlen stellen ja ebenfalls die zwei Nibbles eines Bytes dar, nur daß man alle Möglichkeiten eines Nibbles berücksichtigt ( von 0 bis F) . Beachten wir nun, daß Zahlen wie $1 C gar keine BCD-Zahlen sind, und verwenden wir sie auch nicht, so können durch das Hexadezimalsystem sehr einfach BCD-Zahlen dargestellt 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 erhalten wir aus der Addition 12+19 das Ergebnis 31, was auch richtig ist. Bei abgeschaltetem BCD-Modus wäre $12+$19- gleich $2 B! Beispiel 2 dient als Gegenbeispiel für eine BCD-Rechung. Weil wir hier mit $0 C 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 einzustellen. 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 zugegriffen, so hält die entsprechende CIA die komplette Uhr an. Dies ist deshalb 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ährend 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 immer gleich die komplette Uhrzeit setzen, 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 Zwischenspeichern der Uhrzeit in den 4 Uhrregistern zum Zeitpunkt des Zugriffs.
Intern läuft die Uhr allerdings weiter, 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, auslesen. Auch hier muß das Zehntelsekundenregister als letztes ausgelesen werden, damit die tatsächliche Uhrzeit wieder in die 4 Uhrregister übertragen wird.
( Weiter geht' s im zweiten Teil. . .)

Valid HTML 4.0 Transitional Valid CSS!