OOStuBS/MPStuBS
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_Screen, Stringbuffer, O_Stream und CGA_Stream implementiert werden. Dabei wird die Klasse IO_Port von uns vorgegeben.

Die Klasse CGA_Screen 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 für jede CPU ein eigenes, globales Objekt dout_CPUx erstellt werden.

In der Datei object/debug.h ist das Macro DBG definiert, über das die Debugausgaben getätigt werden sollen. In der Version für MPStuBS wird zusätzlich für jede CPU ein eigenes dout Objekt verwendet, 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 << "zero: " << 0 << " -> 0" << endl;
kout << "ten: " << (10) << " -> 10" << endl;
kout << "uint max: " << ~((unsigned int)0) << " -> 4294967295" << endl;
kout << "int max: " << ~(1<<31) << " -> 2147483647" << endl;
kout << "int min: " << (1<<31) << " -> -2147483648" << endl;
kout << "some int: " << (-123456789) << " -> -123456789" << endl;
kout << "some int: " << (123456789) << " -> 123456789" << endl;
kout << "binary: " << bin << 42 << dec << " -> 0b101010" << endl;
kout << "octal: " << oct << 42 << dec << " -> 052" << endl;
kout << "hex: " << hex << 42 << dec << " -> 0x2a" << endl;
kout << "pointer: " << ((void*)(3735928559u)) << " -> 0xdeadbeef" << endl;
kout << "smiley: " << ((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

Vorgabe

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

Hilfestellung