Friedrich-Alexander-Universität Erlangen-Nürnberg  /   Technische Fakultät  /   Department Informatik
Aufgabe 1: Ausgabefunktionen und Tastaturansteuerung

Lernziele

  • Kennenlernen der Entwicklungsumgebung
  • Auffrischen der Programmiersprache C++
  • Hardwarenahe Programmierung (CGA-Bildschirm und Tastatur)

Allgemeine Bemerkungen

GrundsÀtzlich gibt es zwei verschiedene AusprÀgungen von OOStuBS:

  • OOStuBS als Uniprozessorvariante
  • MPStuBS als Multiprozessorvariante

FĂŒr beide Varianten gibt es getrennte Vorgaben, die sich jedoch nur an einigen wenigen Stellen unterscheiden. So ist es relativ einfach möglich auch zu einem spĂ€teren Zeitpunkt die Variante zu wechseln.

Aufgabenbeschreibung

FĂŒr Testausgaben und zur Erleichterung der Fehlersuche soll das Übungsbetriebssystem OOStuBS bzw. MPStuBS als erstes Ausgabefunktionen erhalten. Diese sollen Ă€hnlich wie bei der C++-I/O-Streams-Bibliothek verwendet werden können und mit Hilfe der Klassen IO_Port, CGA_Window, Stringbuffer, O_Stream und CGA_Stream implementiert werden. Dabei wird die Klasse IO_Port von uns vorgegeben und Lösungen der (freiwilligen) Aufgabe 0 können natĂŒrlich verwendet werden.

Die Klasse CGA_Window ist dabei die zentrale Abstraktion fĂŒr die Darstellung von Zeichen auf dem Bildschirm. Sie soll ĂŒber den Konstruktor so parametrierbar sein, dass sie ihre Ausgaben auf einem einstellbaren rechteckigen Ausschnitt des Bildschrims ausgibt. Dadurch ist der Bildschirm aufteilbar und fĂŒr die Ausgaben in den einzelnen Teilbereichen ist dann jeweils eine eigene Instanz verantwortlich. DarĂŒberhinaus soll man auf dieselbe Weise festlegen können, ob der Hardwarecursor verwendet werden soll oder nicht.

Damit diese Ausgabefunktionen ĂŒberall in OOStuBS/MPStuBS nutzbar sind, sollen mehrere globale CGA_Stream Objekte erzeugt werden:

  • FĂŒr die Ausgaben der Anwendung soll ein globales Objekt kout dienen. Dieses sollte so eingestellt werden, dass es den Hardware-Cursor verwendet.
  • FĂŒr Debugausgaben soll in OOStuBS ein globales Objekt mit dem Namen dout erstellt werden, in MPStuBS entsprechend ein globale Array (ebenfalls mit dem Namen dout) mit Objekten fĂŒr jede CPU.

In der Datei debug/output.h ist das Macro DBG definiert, ĂŒber das die Debugausgaben getĂ€tigt werden sollen. In der Version fĂŒr MPStuBS wird darin das Objekt fĂŒr die entsprechende CPU gewĂ€hlt, so dass die Debugausgaben fĂŒr jede CPU getrennt zu sehen sind.

SĂ€mtliche Instanzen der Klasse CGA_Stream sollen ihre Ausgaben in miteinander disjunkten Bereichen des Bildschirms ausgeben, um Überlappungen bei der Ausgabe zu vermeiden.

Neben der Ausgabe von Text soll auch die Eingabe ĂŒber die Tastatur unterstĂŒtzt werden. Dazu sollt ihr die Klasse Keyboard_Controller vervollstĂ€ndigen, die neben Key in der Vorgabe enthalten ist.

dot_a1.png
KlassenĂŒbersicht fĂŒr Aufgabe 1
Die FunktionsfÀhigkeit der genannten Klassen soll mit folgendem Code gezeigt werden:

kout << "Test <stream result> -> <expected>" << endl;
kout << "bool: " << true << " -> true" << endl;
kout << "zero: " << 0 << " -> 0" << endl;
kout << "uint64_t max: " << ~((uint64_t)0) << " -> 18446744073709551615" << endl;
kout << "int64_t max: " << ~(1ll<<63) << " -> 9223372036854775807" << endl;
kout << "int64_t min: " << (1ll<<63) << " -> -9223372036854775808" << endl;
kout << "some int64_t: " << (-1234567890123456789) << " -> -1234567890123456789" << endl;
kout << "some int64_t: " << (1234567890123456789) << " -> 1234567890123456789" << endl;
kout << "binary: " << bin << 42 << dec << " -> 0b101010" << endl;
kout << "octal: " << oct << 42 << dec << " -> 052" << endl;
kout << "hex: " << hex << 42 << dec << " -> 0x2a" << endl;
kout << "pointer: " << reinterpret_cast<void*>(1994473406541717165ull)
<< " -> 0x1badcafefee1dead" << endl;
kout << "smiley: " << static_cast<char>(1) << endl;

FĂŒr den Test der Tastatureingabe ist ein Keyboard_Controller Objekt zu instanziieren. In einer Schleife sind dann Zeichen von der Tastatur abzufragen und mittels kout auszugeben.

FĂŒr MPStuBS soll das Testprogramm Ă€hnlich wie fĂŒr OOStuBS aussehen. Dazu reicht es die Testapplikation nur auf dem Bootprozessor ablaufen zu lassen (Könnte es Probleme geben, wenn mehrere Prozessoren diese Schleife parallel ausfĂŒhren, und warum?). Die Applikationsprozessoren sollen nur Ausgaben mit Hilfe des Debugmacros tĂ€tigen, um dessen Funktionsweise zu verifizieren.

Hinweis: In spĂ€teren Aufgaben soll Anwendungs- und Testcode in der Klasse Application (aus der Vorgabe) und nicht in main() implementiert werden. Wer möchte, kann dies natĂŒrlich auch bei Aufgabe 1 schon so handhaben.

Implementierungshinweise

Die Aufgabe besteht im Wesentlichen aus den zwei Teilen "Ausgaben" und "Eingaben", wobei der Test der "Eingaben" ohne "Ausgaben" nicht möglich ist. Die Teilaufgabe "Ausgaben" kann zudem in drei voneinander unabhÀngige Teile gegliedert werden, die sehr gut einzeln gelöst und getestet werden können. Daher empfehlen wir folgende Bearbeitungsreihenfolge:

Ausgaben

Eingaben

Optional: Serielle Konsole

Als freiwillige Zusatzaufgabe kann in der Klasse Serial eine serielle Schnittstelle implementiert werden. Mittels der Klasse Serial_Stream wird damit eine weitere Ausgabe ermöglicht – in einem VT100-kompatiblen Terminal.

Vorgabe

Die Einrichtung der Entwicklungsumgebung und eine ErklÀrung, welche Vorgaben ihr jeweils benötigt, findet ihr hier.

Hilfestellung

FĂŒr die freiwillige Zusatzaufgabe