Tips und Tricks ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
In der Februarausgabe wollen wir Ihnen wieder einmal die Rubrik "Tips und Tricks" anbieten. Heute beschäf- tigen 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 Compu- terenthusiasten, 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 Programm- zeile INPUT TI$ eingeben und dann die Uhr mit PRINT TI$ aufrufen ist wirklich nicht sonderlich kompli- ziert. Für Spiele, in denen Zeiten im Sekunden- oder Minu- tenbereich 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 Ungenauig- keit der Uhr würde einen solchen Einsatz des C64 un- möglich machen. Es gibt aber noch eine andere Mög- lichkeit, 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 Geheim- dienstes, sondern für "Complex Interface Adapter". Die CIAs übernehmen beispielsweise die Ein- und Aus- gabesteuerung des gesamten Computers: Tastatur, User- port und Joystick werden von Ihnen genauso behandelt wie die serielle Schnittstelle. Außerdem - und das ist jetzt wichtig für uns - bein- haltet 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 Uhr- zeit 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 mittei- len, 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 erfor- dert 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. Über- prüfen wir dies gleich im zweiten Programmteil, den Zeilen 160 bis 300. Dieser Teil enthält noch eine kleine Maschinenrou- tine, aber keine Angst, es wird nicht sonderlich kom- pliziert. 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äm- lich 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 aus- lesen während die Zeit weiter verstreicht und uns un- bemerkt 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 "Umvertei- lung" der Zeitdaten. Die Zehntelsekunden MÜSSEN übri- gens immer mit ausgelesen werden, sonst kann es pas- sieren, 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 Hexadezi- malformat zurückgegeben hat in unser gebräuchliches Dezimalformat umwandeln. So wie wir uns in Zeile 70 für Vormittag oder Nach- mittag 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 Hexadezimalschreibwei- se umgewandelt. Damit wir diesen Vorgang nur einmal programmieren müssen, wird er als Subroutine gehal- ten, 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 gege- ben 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 verglei- chen 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.