OOStuBS/MPStuBS
Aufgabe 1: Ausgabefunktionen und Tastaturansteuerung

Lernziele

  • Auffrischen der Programmiersprache C++
  • Kennenlernen der Entwicklungsumgebung
  • Implementieren von Ausgabe (CGA-Bildschirm) und Eingabe (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

Die Vorgabe bootet in den StuBS-Kern, kann aber keinerlei Ausgaben machen oder Eingaben annehmen. Für sinnvolles Debugging sind das allerdings zwei wichtige Mechaniken um dem Betriebssystem Signale zu geben, oder Signale vom Betriebssystem bzw. dessen Anwendungen zu erhalten.

Daher soll in Aufgabe 1 die Ausgabe über den CGA-Bildschirm und eine Eingabe über die Tastatur implementiert werden. In Aufgabe 0 wurde dafür bereits die Grundlage gelegt, indem die Klassen O_Stream und Stringbuffer vorbereitet wurden. Als Backend soll nun anstelle der Konsole oder der Datei, der CGA-Bildschirm verwendet werden.

Für die Tastatur wird ein rudimentärer Treiber für den Tastaturcontroller entwickelt. Dabei werden die entsprechenden I/O-Ports derart verwendet, dass Eingaben über die Tastatur möglich sind. Weiter sollen auch die Kontrollleuchten an der Tastatur angesteuert werden.

CGA-Bildschirm und Text-Ausgabe

Die Funktionsweise der CGA-Hardware wird in CGA-Bildschirm erklärt.

Die Klassen O_Stream und Stringbuffer sind bereits in Aufgabe 0 vorbereitet worden und können direkt weiter verwendet werden. Anstelle der ConsoleOut und FileOut-Klassen, wird nun allerdings CGA_Screen verwendet, welche die Ausgaben auf dem CGA-Bildschirm tätigen soll. Es soll dabei möglich sein mehrere Viewports oder Bereiche festzulegen, in denen die die Ausgabe bspw. für die verschiedenen Prozessoren geschehen soll. Pro Bereich soll es ein CGA_Screen-Objekt geben.

Mehrere globale Objekte sollen erstellt werden, damit die Ausgabefunktionalität überall im StuBS verfügbar wird:

  • 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 MPStuBS für jede CPU ein eigenes, globales Objekt dout_CPUx erstellt werden. In OOStuBS reicht entsprechend ein einzelnes globales Objekt mit dem Namen dout.

Es ist bereits ein Macro DBG vorbereitet (in debug/output.h), welches Debugausgaben tätigt. Bei MPStuBS wird darin die ausführende CPU ermittelt um die Ausgabe im dafür vorgesehenen Bereich vornimmt.

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

Funktionstest der Ausgabe

Die Funktionsfähigkeit der Ausgabe-Klassen soll mit folgendem Code gezeigt werden:

kout << "Test <stream result> -> <expected>" << endl;
kout << "bool: " << true << " -> true" << 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; // a heart

Tastatur-Eingabe

Neben der Ausgabe von Text soll auch die Eingabe über die Tastatur unterstützt werden. Dazu soll die Klasse Keyboard_Controller vervollständigt werden, die neben Key und Key_Decoder in der Vorgabe enthalten ist. Der Key_Decoder nimmt Codes der Tastatur entgegen und gibt ungültige Key-Objekte zurück, wenn bislang kein Zeichen oder gültiger Tastendruck vollständig verarbeitet werden konnte. Alternativ wird ein gültiges Key-Objekt zurückgeliefert, welches einen ASCII-Wert hat, bzw. bei dem der Scancode überprüft werden kann.

Für die Eingabe ist ein Keyboard_Controller-Objekt zu instanziieren. In einer Schleife werden dann Zeichen von von der Tastatur abgefragt und mittels der Ausgaberoutine von kout ausgeben. In MPStuBS genügt es, die Testanwendung lediglich auf dem Bootprozessor ablaufen zu lassen. Die Applikationsprozessoren verwenden das Debug-Makro für Testausgaben um dessen Funktionsweise zu verifizieren.

Optional: Serielle Konsole

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

Klassenübersicht für Aufgabe 1

dot_a1.png
Klassenübersicht für Aufgabe 1

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.

Hilfen und Dokumentation

Für die serielle Schnittstelle (Zusatzaufgabe)

hex
O_Stream & hex(O_Stream &os)
Wählt das hexadezimale Zahlensystem aus.
Definition: o_stream.cc:163
bin
O_Stream & bin(O_Stream &os)
Wählt das binäre Zahlensystem aus.
Definition: o_stream.cc:145
dec
O_Stream & dec(O_Stream &os)
Wählt das dezimale Zahlensystem aus.
Definition: o_stream.cc:157
endl
O_Stream & endl(O_Stream &os)
Fügt einen Zeilenumbruch in die Ausgabe ein und löst ein Leeren (Flush) des Puffers aus.
Definition: o_stream.cc:139
oct
O_Stream & oct(O_Stream &os)
Wählt das oktale Zahlensystem aus.
Definition: o_stream.cc:151