Tips und Tricks
In der Februarausgabe wollen wir Ihnen wieder einmal
die Rubrik " Tips und Tricks" anbieten. Heute beschäftigen wir uns darin mit der Uhrzeit, d. h. mit einer
Möglichkeit, eine Uhr auf dem C64 zu programmieren.
" Ein alter Hut, TI$, kenne ich schon", werden jetzt
vielleicht einige von Ihnen denken. Aber gerade diese
Uhr meine ich nicht. Denn wenn Sie sich schon einmal
mit dieser " TI$- Uhr" beschäftigt haben, wird Ihnen
aufgefallen sein, daß diese Uhr nicht gerade durch
Genauigkeit glänzt. So kann es durchaus vorkommen, daß diese Uhr in einem Tag gut eine halbe Stunde
falsch geht - ein Ding der Unmöglichkeit für Computerenthusiasten, denn Zeit ist bekanntlich Geld.
Der Grund, warum oftmals doch diese TI$- Uhr verwendet
wird, liegt in der Tatsache begründet, daß sie sich
leicht programmieren läßt. Einfach in einer Programmzeile INPUT TI$ eingeben und dann die Uhr mit PRINT
TI$ aufrufen ist wirklich nicht sonderlich kompliziert.
Für Spiele, in denen Zeiten im Sekundenoder Minutenbereich gemessen werden müssen ist dies durchaus
eine akzeptable und einfache Lösung. Was aber, wenn
Sie sich zum Beispiel im Urlaub befinden und den C64 als Zeitschaltuhr benutzen? Eine größere Ungenauigkeit der Uhr würde einen solchen Einsatz des C64 unmöglich machen. Es gibt aber noch eine andere Möglichkeit, eine Uhr zu programmieren:
Der C64( und natürlich auch der C128) enthält zwei
Bausteine, die auf das Kürzel CIA hören. CIA steht
hier nicht für das Kürzel des amerikanischen Geheimdienstes, sondern für " Complex Interface Adapter" .
Die CIAs übernehmen beispielsweise die Einund Ausgabesteuerung des gesamten Computers: Tastatur, Userport und Joystick werden von Ihnen genauso behandelt
wie die serielle Schnittstelle.
Außerdem - und das ist jetzt wichtig für uns - beinhaltet jeder CIA noch eine 24- Stunden-Echtzeituhr mit
einer Auflösing von 1/10 Sekunden. Vier Register
( Stunden, Minuten, Sekunden und Zehntelsekunden) hält
jeder CIA dafür bereit.
Die Basisadresse des CIA1 ist dezimal 56320($ DC00), die " Uhr" beginnt bei $ DC08( dezimal 56328) . Wir
haben ein kleines Programm für Sie vorbereitet, daß
die Funktion der CIA-Uhr verdeutlicht. Es heißt
" CIA-UHR" und Sie finden es auf der Rückseite der
Magic Disk oder im Game-Menü. Im Folgenden beziehe
ich mich auf dieses Programm.
Die Zeilen 10 bis 130 sind für die Eingabe der Uhrzeit zuständig. Als Basisadresse wird in Zeile 20 die
Variable c mit 56328 belegt.
Zunächst muß in der Speicherzelle c+7 das siebte Bit
auf 0 gesetzt werden. Das ist das Zeichen für den
CIA, daß nun die Uhrzeit gestellt werden soll.
Während die TI$- Uhr vom internen Interupt gesteuert
wird, stellt sich die CIA-Uhr direkt aus der Frequenz
des Wechselstroms nach. Wie Sie ja vielleicht wissen, beträgt diese Frequenz bei uns 50 Hertz. Wenn die
Polarität des Wechselstroms sich also 50 mal geändert
hat, weiß der CIA, daß er die Uhr um eine Sekunde
weiterstellen muß.
Diese Frequenz von 50 Hertz ist auf lange Sicht recht
exakt, da sie vom Elektrizitätswerk nachgestellt
wird. Die meisten elektrischen Wecker funktionieren
übrigens, auch im Zeitalter der Quarzuhren, immer
noch nach diesem Prinzip, da es Genauigkeit auch über
Jahre hinweg sichert.
Nun ist diese Netzfrequenz nicht in der ganzen Welt
gleich. In Amerika - dem Geburtsland des C64- beträgt sie 60 Hertz. Wir müssen dem CIA also mitteilen, mit welcher Frequenz er arbeiten soll. Dies
geschieht in Zeile 40 : Das Bit 7 in c+6 wird gesetzt
und somit wird der CIA auf 50 Hertz eingestellt. Ein
gelöschtes Bit 7 in dieser Speicherzelle hätte ein
Arbeiten mit 60 Hertz zur Folge.
Nun, da wir alle Voreinstellungen vorgenommen haben, ist es an der Zeit, die Uhrzeit einzugeben. Die Zeile
50 ist dafür zuständig. Die Zeit speichern wir in
TI$, also in der normalen Zeitvariablen ab. Somit
haben wir später auch gleich einen Vergleich darüber, wie ungenau TI$ funktioniert.
Die Entwicklungsingenieure des CIA waren anscheinend
Maschinenspracheenthusiasten. Der CIA speichert seine
Uhrzeit nämlich im Hexadezimalformat. Das heißt, wenn
in einem Zeitregister der dezimale Wert 16 steht, meint der CIA nicht 16, sondern eigentlich 10, denn
dezimal 16 ist hexadezimal 10 . Dieses Format erfordert deshalb einige Umrechnungen, sowohl beim Setzen
der Uhrzeit als auch beim späteren Auslesen. Damit
erklären sich auch die vielleicht etwas kompliziert
geschriebenen Zeilen 80,100 und 120 : Unsere gewohnte
Dezimaldarstellung wird ins Hexadezimale übersetzt
und so auch für den CIA verständlich.
Interessant ist vielleicht noch die Zeile 70 :
if h>11 then h= h+68
Nun, setzen Sie einmal einen Wert für h>11 ein, z. B.
h=12 .12+68=80 . Der kleinste Wert von h, der 11 gerade übersteigt, setzt also ( hexadezimal gelesen) gerade das siebte Bit. Damit wird dem CIA mitgeteilt, daß es nun Nachmittag ist.
In Zeile 120 werden nun noch die Zehntelsekunden auf
0 gesetzt. Das ist das Zeichen für den CIA, daß er ab
jetzt die Uhr starten soll.
So, das wäre geschafft. Die Zeit hätten wir glücklich
eingegeben und hoffen nun, daß die Uhr läuft. Überprüfen wir dies gleich im zweiten Programmteil, den
Zeilen 160 bis 300 .
Dieser Teil enthält noch eine kleine Maschinenroutine, aber keine Angst, es wird nicht sonderlich kompliziert. Das kleine Maschinenprogramm, das in den
Zeilen 170 bis 190 aus den DATA-Zeilen ausgelesen und
nach 49152($ C000) gePOKEd wird, liest nur die vier
Register des CIA aus ( Stunden, Minuten, Sekunden und
Zehntel) und schreibt sie an eine andere Stelle, nämlich an die Adressen 850 bis 852 . Die Zehntelsekunden
brauchen wir nicht, sie werden also auch nicht mit
abgespeichert.
Die Maschinenroutine hat folgenden Sinn: Würden wir
im langsamen Basic die Zeitregister lesen, so wäre es
theoretisch möglich, daß wir gerade die Sekunden auslesen während die Zeit weiter verstreicht und uns unbemerkt die Stunden oder Minuten weiterstellt. Durch
die schnelle Maschinenroutine wird dieses Risiko
verhindert. Hier zunächst für Assemblerprogrammierer
die Maschinenroutine:
.C000 LDA $DC08 ;Zehntelsekunden lesen .C003 LDA $DC09 ;Sekunden lesen .C006 STA $0352 ;und abspeichern .C009 LDA $DC0A ;Minuten lesen .C00C STA $0353 ;und abspeichern .C00F LDA $DC0B ;Stunden lesen .C012 STA $0354 ;und abspeichern .C015 RTS ;zurück zu Basic
Es handelt sich also wirklich nur um eine " Umverteilung" der Zeitdaten. Die Zehntelsekunden MÜSSEN übrigens immer mit ausgelesen werden, sonst kann es passieren, daß die Uhr stehen bleibt! Bitte merken Sie
sich das gut für eigene Programme.
Ein SYS49152 ruft diese Routine in Zeile 210 auf.
Danach stehen in den Speicherzellen
850 die Sekunden 851 die Minuten und 852 die Stunden
und warten auf weitere Bearbeitung. Nach dem SYS-Be- fehl werden diese Daten dann mit PEEK in die Basic-Variablen h ( für Stunden), m ( für Minuten) und s ( für
Sekunden) eingelesen.
Damit haben wir aber die Uhrzeit noch nicht wieder.
Wir müssen ja erst die Zeit, die der CIA im Hexadezimalformat zurückgegeben hat in unser gebräuchliches
Dezimalformat umwandeln.
So wie wir uns in Zeile 70 für Vormittag oder Nachmittag entschieden haben, genau so müssen wir jetzt
wieder nachprüfen, ob das Bit 7 des Stundenregisters
gesetzt ist. Ist das der Fall, dann ist es bereits
Nachmittag, ansonsten noch Vormittag. Die Abfrage
nehmen wir in Zeile 220 vor.
Nun werden noch h, m und s in Hexadezimalschreibweise umgewandelt. Damit wir diesen Vorgang nur einmal
programmieren müssen, wird er als Subroutine gehalten, die Sie in den Zeilen 270 bis 300 finden.
Damit sind wir mit unserem Ausflug in den CIA am Ende
angelangt. Ich hoffe, Ihnen mit dieser Rubrik und dem
Programm einige Anregungen für eigene Programme gegeben zu haben.
Zum Schluß aber noch ein Tip:
Bevor Sie heute Abend zu Bett gehen, schalten Sie
doch einfach einmal Ihren C64 ein und lassen das
Programm CIA-UHR laufen. Am nächsten Morgen vergleichen Sie die Zeit der CIA-Uhr mit der einer handelsüblichen Uhr. Sie werden feststellen, daß die Zeit
allenfalls einige Sekunden abweicht.
Nun drücken Sie die Taste RUN/ STOP und geben PRINT
TI$ ein. Sie können sich nun davon überzeugen, wie
ungenau die interuptgesteuerte TI$- Uhr läuft.