★ APPLICATIONS ★ DIVERS ★ Alles zu seiner Zeit - BASIC und Interrupts ★ |
Mini - Spiel (CPC Amstrad International) | Applications Divers |
Können Sie gleichzeitig ein Buch lesen, einen Brief schreiben und essen? Es gibt nicht viele Leute, die dazu fähig sind, mehrere Dinge zur gleichen Zeit zu tun. Aber eine besondere Spezies ist dazu in der Lage: der gute alte Kumpel CPC. Multitasking ist ein Wort, was zur Zeit in aller Munde ist. Viele Computertypen arbeiten nach dem Prinzip der scheinbar gleichzeitigen Ausführung mehrerer Programme. Was viele gar nicht wissen: Auf dem CPC ist so etwas auch möglich, sogar unter BASIC. Aber ganz so einfach ist die Sache nun auch wieder nicht, denn der BAS IC-Interpreter kann immernurein Programm auf einmal ausführen. Doch es gibt da eine Möglichkeit. Die verschiedenen Programme werden einfach in kleine Teile zerlegt. Dann führt das BASIC einmal etwas von diesem Programm, dann etwas von jenem aus. Grafisch veranschaulicht sieht das dann so aus: Programm1: **_**_**_**_**_** _ Hier bekommt Programm 1 zwei Drittel der Rechenzeit und Programm2 den Rest. Aber wie realisieren wir das nun mit unserem CPC? Erfreulicherweise bietet BASIC bereits die entsprechenden Befehle EVERY und AFTER. Diese Befehle dienen dazu, nach einer bestimmten Zeit ein Unterprogramm aufzurufen. Sie funktionieren im Prinzip wie ein GOSUB-Befeh I mit Zeitverzögerung. Als Parameter folgen die zu wartende Zeit in Fünfzigstelsekunden, der Zeitgeber und der Sprung in Form des bekannten GOSUB. Die Zeit und GOSUB sind klar, aber was verbirgt sich hinter dem Begriff Zeitgeber? Der CPC beinhaltet eine Uhr, die alle Dreihundertstelsekunden weitergestellt wird. Von ihr wird auch der Fünf-zigstelsekundentakt. der unter BASIC zur Verwendung kommt abgeleitet. Wenn der CPC nun zum Beispiel auf einen EVERY-Befehl trifft, mißt er von da ab die vergangene Zeit (in eben diesen Fünfzigstelsekunden) und vergleicht diese mit der gewünschten Verzögeruns. Ist diese erreicht, führt er den GOSUB-Befehl aus. Eigentlich wäre jetzt schon alles komplett. Aber was ist, wenn mehrere EVERY-Befehle hintereinander folgen? Wie wird entschieden, welches Unterprogramm jeweils ausgeführt werden soll? Zur Lösung haben sich die Entwickler des BASICs für einen eleganten Weg entschieden. Sie haben vier unabhängige Zeitgeber eingerichtet, wobei je ein Zeitgeber von einem EVERY- oder AFTER-Befehl benutzt werden kann. Eine Aktion pro Zeitgeber Der Vorteil dieses Verfahrens liegt auf der Hand: Der Programmierer kann bestimmen, welcher Zeitgeber benutzt wird, und vermeidet damit ein Chaos. Trotzdem ist diese Lösung noch nicht ideal. Angenommen, zwei AFTER-Befehle werden zur gleichen Zeil aktiv, dann gibt es das Problem, welche Routine aufgerufen wird. Deshalb gilt hier die Regel: DerZeitgeber mit der niedrigeren Nummer hat die höhere Priorität. Das unentbehrliche Gegenstück zu EVERY und AFTER heißt REMAIN. Dieser Funktion wird die Nummer eines Zeitgebers übergeben, woraufhin der Zeitgeber gestoppt und die noch verbl i e bene Zei t zurückgegebe n wird. Wenn Sie sich nun frisch ans Werk machen, werden Sie nach kurzer Zeit feststellen, daß es nicht immer von Vorteil ist, wenn die gerade laufende Routine einfach unterbrochen wird. Um das zu verbinden, gibt es den Befehl DI. Assembler-Programmierer werden den analogen Befehl auf der Maschinenebene kennen. Nur bezieht sich der BASIC-DI-Befehl lediglich auf die softwaremäßig gebildeten Interrupts der Timer 0 bis 3. Die hardwarebezogene Interruptbehandlung, wie beispielsweise die Tastaturabfrage, wird davon nicht betroffen. Freigeben kann man die mit DI gesperrte Unterbrechung mit dem Befehl El. 10 EVERY 50, 0 GOSUB 1000 Im Beispiel beteuert der CPC fortlaufend, daß er nichts tut. zeichnet nebenbei aber jede Sekunde 50 Punkte. Die DI- und EI-Anweisungen sind hier eigentlich überflüssig, da der momentan ausgeführte Interrupt sich nicht selbst unterbrechen kann und er außerdem die höchste Priorität hat. Zur Verdeutlichung ihrer Anwendung wurden sie aber an entsprechender Stelle im Programm gesetzt. Die Fähigkeit des CPC-BASICs, eventuelle Unterbrechungen durch Interrupts verhindern zu können, ermöglicht erst ein komfortables Debugging solcher Programme. Ein Nebeneffekt kann Ihnen nämlich beim Debugging übel mitspielen. DerCPC merkt sich alle Interruptaufrufe und führt sie auf Gedeih und Verderb aus, sobald er eine Möglichkeit dazu erhält. Wenn nun einmal eine längere Programmunterbrechung stattgefunden hat, führt das dazu, daß anschließend längere Zeil nur die Interrupts ausgeführt werden und das Hauptprogramm steht. Ein Ereignis, welches eine ziemliche Verwirrung im Programm stiften kann, ist das Drücken der Taste . Bei dem abgedruckten kleinen Spiel treten dabei auch sehr lustige Effekte auf. So kann es passieren, daß man, nachdem man vom Monster gefressen wurde, noch weiterlebt. Die Abfrage, ob man tot ist, befindet sich im Hauptprogramm, und das kommt ja erst einmal gar nicht zum Zuge. Welche Möglichkeiten hat man nun, solche "übersteuerten" Interrupts zu verhindern? Zum einen wäre es möglich, die Taste . abzuschalten. Der einfachste Weg dazu ist die Eingabe von POKE &BDEE,&C9. Wenn man die Unterbrechung wieder zulassen will, schreibt man den ursprünglichen Werl wieder in die Speicherstelle. Diese Möglichkeit sieht dann so aus: 10 AlterWert=PEEK(&BDEE) Achten Sie bitte darauf, eine Abbruchbedingung einzubauen, da durch die Manipulation mittels des POKEs das Programm nicht mehr abgebrochen werden kann. Abbruchmöglichkeit ist einzubauen Die zweite Möglichkeit ist, in der Interruptroutine die Zeit zu messen, die zwischen zwei Aufrufen vergangen ist. So läßt sich leicht feststellen, ob noch alles "im Lot" ist. Der notwendige Programmieraufwand läßt sich natürlich nur bei extremen Fällen rechtfertigen, wie zum Beispiel bei interruptgesteuerter Musik. Denn gerade da hört man es, wenn nach dem "Wiederanlaufen" des Programms erst einmal die 50 Noten der letzten Minute hintereinander kommen. Etwas anspruchsloser, als Zeit-piepsen. siehtdas so aus: 10 ALTEZEIT=TIME Dieser "Zeitpiepser" hat den Vorleil, daß er auch nach einer langen Pause nicht zu oft hintereinander aufgerufen wird. Eine kleine Anregung, wie man diese Zeitsteuerung effektiv einsetzt, finden Sie im Listing eines kleinen Spiels am Ende des Beitrags. Es geht darum, dem Monster, von dem man ununterbrochen verfolgt wird, zu entkommen. Das Männchen läßt sich mit den Cursortasten steuern. Der Spieler, das Monster und die Zeitanz.eige sind mit EVERY-Befehlen realisiert. CPCAI
|