Next: Arbeitsplan
Up: Spezifikation
Previous: Aufgabenstellung
Im PC gibt es prinzipiell zwei Möglichkeiten Zeit zu messen: Mit
dem Timerbaustein und mit der Echtzeituhr. Beide lassen sich
unter Betriebssystemen, die den Protected Mode verwenden, nicht ohne
weiteres ansprechen, da solche Betriebssysteme den Zugriff auf die Hardware
normalerweise verbieten und statt dessen Systemroutinen für solche Probleme
anbieten. Aus diesem Grund ist zur Implementierung ein Betriebssystem
nötig, das keinerlei Kontrolle über Anwenderprogramme ausübt, oder
zumindest eines, welches einen derartigen Emulationsmodus bietet.
Wir haben uns deshalb für MS-DOS entschieden.
Die Echtzeituhr hat den Vorteil, daß sie unter DOS im allgemeinen nicht
benutzt wird und deshalb zur freien Verfügung steht. Außerdem vefügt sie
bereits über einen Timeoutmechanismus, der sich gut verwenden ließe.
Leider ist dieser Timeout im ungünstigsten Fall mit 1s Fehler behaftet, was
im Sinne der Aufgabenstellung zu ungenau ist.
Der Timerbaustein löst unter DOS periodisch mit der Frequenz
18.2Hz den Interrupt 08h aus. Dieser Interrupt verzweigt in den
Interrupt 01Ch, der zur freien Benutzung gedacht ist. Mit diesem
Mechanismus liegt der Fehler bei höchstens 6%. Der Nachteil ist, das
diese Einrichtung von vielen Programmen genutzt wird und es
deshalb zu Störungen kommen kann. Achtet der Anwender aber auf die
Benutzung des Interrupts durch die Routine SET_TIMEOUT, lassen sich
solche Konflikte vermeiden.
Wir haben uns wegen der oben angeführten Gründe für die
Benutzung des Interrupt 01Ch entschieden.
Zur Realisierung verwenden wir drei Benutzerroutinen:
- INSTALL_TIMER: Sie muß beim Programmstart ausgeführt werden.
Sie verbiegt den Interrupt 01Ch auf eine noch inaktive
Zählroutine und speichert dabei die alte Interruptadresse.
Zur Sicherheit wird ein Flag im Speicher gesetzt, um anzuzeigen,
daß die Installation erfolgt ist.
- SET_TIMEOUT: Die Routine bekommt wie in der Aufgabenstellung angegeben
die Parameter DELAY und HANDLER übergeben. Ihre Aufgabe ist es die
Zählroutine mit dem richtigen Startwert für den Zähler und der
richtigen Sprungadresse zu initialisieren und zu aktivieren. Dabei wird
darauf geachtet, daß die Zählroutine bereits installiert ist. Trifft
das nicht zu, wird INSTALL_TIMER aufgerufen.
- REMOVE_TIMER: Sie muß vor Beendigung des Programmes ausgeführt
werden. Der Interrupt 01Ch wird durch sie auf die alte Adresse
zurückgesetzt, falls er von INSTALL_TIMER verbogen wurde.
Diese Aufteilung garantiert, daß das Programm sauber beendet wird, d.h.
daß zum Beispiel eine noch ausstehende Unterbrechung ignoriert wird, damit
sie nicht später zu einer Routine verzweigt, die längst nicht mehr im
Speicher steht.
Die Zählroutine ist das Kernstück dieser Aufgabe. Sie wird 18,2 mal pro
Sekunde aufgerufen und dekrementiert im aktivierten Zustand einen Zähler.
Ist dieser Zähler bei null angelangt, deaktiviert sich die Zählroutine und
die Handlerroutine wird als Unterprogramm
aufgerufen. Danach wird mit dem unterbrochenen Programm fortgefahren.
Als Test wird ein enfaches Assemblerprogramm benutzt, das am Anfang einen
Timeout setzt und dann eine längere Warteschleife durchläuft, während der
es ``Lebenszeichen'' auf den Bildschirm ausgibt.
Zur Kontrolle wird zu Beginn, zum Zeitpunkt der Unterbrechung und am Ende
die momentane Zeit auf Sekunden genau ausgegeben.
Next: Arbeitsplan
Up: Spezifikation
Previous: Aufgabenstellung
Ingo Rohloff
11/14/1997