Merge branch 'main' into feature-03-memory-management
This commit is contained in:
@ -73,11 +73,14 @@ void CGA::show(int x, int y, char character, unsigned char attrib) {
|
||||
|
||||
/* Hier muess Code eingefuegt werden */
|
||||
|
||||
if (x > 80 || y > 25) {
|
||||
// Out of bounds
|
||||
return;
|
||||
}
|
||||
|
||||
char* pos = (char*)(CGA_START + 2 * (x + y * 80)); // cast to char* to make writable
|
||||
*pos = character;
|
||||
*(pos + 1) = attrib;
|
||||
|
||||
// TODO: screen border check
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -95,28 +98,44 @@ void CGA::print(char* string, int n, unsigned char attrib) {
|
||||
|
||||
/* Hier muess Code eingefuegt werden */
|
||||
|
||||
int cursor_x, cursor_y;
|
||||
int cursor_x, cursor_y; // Don't poll registers every stroke
|
||||
this->getpos(cursor_x, cursor_y);
|
||||
|
||||
for (unsigned short byte = 0; byte < n; ++byte) {
|
||||
|
||||
char current = *(string + byte);
|
||||
if (current == '\n') {
|
||||
// TODO: Screen bounds
|
||||
cursor_x = 0;
|
||||
cursor_y = cursor_y + 1;
|
||||
|
||||
if (cursor_y > 24) {
|
||||
// Bottom of screen reached
|
||||
this->scrollup();
|
||||
cursor_y = cursor_y - 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if (current == '\0') {
|
||||
// Don't need to run to end if null terminated
|
||||
break;
|
||||
}
|
||||
|
||||
this->show(cursor_x, cursor_y, current, attrib);
|
||||
cursor_x = cursor_x + 1;
|
||||
|
||||
if (cursor_x > 79) {
|
||||
// Right of screen reached
|
||||
cursor_x = 0;
|
||||
cursor_y = cursor_y + 1;
|
||||
|
||||
if (cursor_y > 24) {
|
||||
// Bottom of screen reached
|
||||
this->scrollup();
|
||||
cursor_y = cursor_y - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->setpos(cursor_x, cursor_y);
|
||||
|
||||
// TODO: automatic line breaking, automatic scrolling
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -175,5 +194,5 @@ unsigned char CGA::attribute(CGA::color bg, CGA::color fg, bool blink) {
|
||||
|
||||
return blink << 7 // B0000000
|
||||
| (bg & 0x7) << 4 // 0HHH0000
|
||||
| (fg & 0xF); // 0000VVVV
|
||||
| (fg & 0xF); // 0000VVVV
|
||||
}
|
||||
|
@ -25,16 +25,22 @@
|
||||
*****************************************************************************/
|
||||
void CGA_Stream::flush() {
|
||||
print(buffer, pos, attribute(this->color_bg, this->color_fg, this->blink));
|
||||
|
||||
// TODO: Should not be reset like this
|
||||
// Flushing resets attributes
|
||||
this->blink = false;
|
||||
this->color_bg = CGA::BLACK;
|
||||
this->color_fg = CGA::LIGHT_GREY;
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
// NOTE: I added this
|
||||
// TODO
|
||||
// CGA_Stream& CGA_Stream::operator<<(const fgc& fg) {
|
||||
// this->color_fg = fg.fg;
|
||||
// return *this;
|
||||
// }
|
||||
// CGA_Stream& CGA_Stream::operator<<(const bgc& bg) {
|
||||
// this->color_bg = bg.bg;
|
||||
// return *this;
|
||||
// Alternative way to write the templates which keeps definition separated
|
||||
// Usable for our case but somehow defeats the purpose of templates
|
||||
// template<typename T>
|
||||
// T& operator<<(T& os, const fgc& fg) {
|
||||
// os.color_fg = fg.fg;
|
||||
// return os;
|
||||
// }
|
||||
|
||||
// template CGA_Stream& operator<<<CGA_Stream>(CGA_Stream&, const fgc&);
|
||||
|
@ -53,9 +53,19 @@ public:
|
||||
void flush() override;
|
||||
|
||||
// NOTE: I added this
|
||||
// TODO: Problem: Implementing this here breaks the << chaining
|
||||
// CGA_Stream& operator<<(const fgc&);
|
||||
// CGA_Stream& operator<<(const bgc&);
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, const fgc& fg) {
|
||||
os.flush();
|
||||
os.color_fg = fg.fg;
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, const bgc& bg) {
|
||||
os.flush();
|
||||
os.color_fg = bg.bg;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -22,16 +22,6 @@
|
||||
|
||||
#include "lib/OutStream.h"
|
||||
|
||||
// NOTE: I added this, stream manipulators with arg
|
||||
OutStream& OutStream::operator<<(const fillw& w) {
|
||||
this->fill_width = w.w;
|
||||
return *this;
|
||||
}
|
||||
OutStream& OutStream::operator<<(const fillc& c) {
|
||||
this->fill_char = c.c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NOTE: I added this, fixed width printing
|
||||
void OutStream::put(char c) {
|
||||
if (this->fill_width == 0) {
|
||||
@ -66,109 +56,19 @@ void OutStream::fill_use_char() {
|
||||
}
|
||||
this->fill_used++;
|
||||
}
|
||||
void OutStream::flush() {
|
||||
// TODO: Should not be reset like this
|
||||
// Flushing resets fixed width
|
||||
this->base = 10;
|
||||
this->fill_char = ' ';
|
||||
this->fill_width = 0;
|
||||
this->fill_used = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Zeichen und Zeichenketten in Stream ausgeben
|
||||
//
|
||||
OutStream& OutStream::operator<<(char c) {
|
||||
put(c);
|
||||
if (c != '\n') {
|
||||
// endl() doesn't has access to StringBuffer::put(), so ignore \n here
|
||||
this->fill_finalize(); // NOTE: I added this
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: shouldn't this be printed as number?
|
||||
OutStream& OutStream::operator<<(unsigned char c) {
|
||||
return *this << (char)c;
|
||||
}
|
||||
|
||||
OutStream& OutStream::operator<<(char* string) {
|
||||
char* pos = string;
|
||||
while (*pos) {
|
||||
put(*pos);
|
||||
pos++;
|
||||
}
|
||||
this->fill_finalize(); // NOTE: I added this
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// Ganzer Zahlen im Zahlensystem zur Basis base in Stream ausgeveb
|
||||
// Alle vorzeichenbehafteten Datentypen werden als long dargestellt,
|
||||
// Alle vorzeichenlosen als unsigned long.
|
||||
OutStream& OutStream::operator<<(short ival) {
|
||||
return *this << (long)ival;
|
||||
}
|
||||
|
||||
OutStream& OutStream::operator<<(unsigned short ival) {
|
||||
return *this << (unsigned long)ival;
|
||||
}
|
||||
|
||||
OutStream& OutStream::operator<<(int ival) {
|
||||
return *this << (long)ival;
|
||||
}
|
||||
|
||||
OutStream& OutStream::operator<<(unsigned int ival) {
|
||||
return *this << (unsigned long)ival;
|
||||
}
|
||||
|
||||
// Darstellung eine vorzeichenbehafteten ganzen Zahl.
|
||||
OutStream& OutStream::operator<<(long ival) {
|
||||
// Bei negativen Werten wird ein Minuszeichen ausgegeben.
|
||||
if (ival < 0) {
|
||||
put('-');
|
||||
ival = -ival;
|
||||
}
|
||||
// Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben.
|
||||
return *this << (unsigned long)ival;
|
||||
}
|
||||
|
||||
// Darstellung einer vorzeichenlosen ganzen Zahl.
|
||||
OutStream& OutStream::operator<<(unsigned long ival) {
|
||||
unsigned long div;
|
||||
char digit;
|
||||
|
||||
if (base == 8) {
|
||||
put('0'); // oktale Zahlen erhalten eine fuehrende Null
|
||||
} else if (base == 16) {
|
||||
put('0'); // hexadezimale Zahlen ein "0x"
|
||||
put('x');
|
||||
}
|
||||
|
||||
// Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die
|
||||
// noch kleiner als die darzustellende Zahl ist.
|
||||
for (div = 1; ival / div >= (unsigned long)base; div *= base)
|
||||
;
|
||||
|
||||
// ziffernweise Ausgabe der Zahl
|
||||
for (; div > 0; div /= (unsigned long)base) {
|
||||
digit = ival / div;
|
||||
if (digit < 10) {
|
||||
put('0' + digit);
|
||||
} else {
|
||||
put('a' + digit - 10);
|
||||
}
|
||||
ival %= div;
|
||||
}
|
||||
this->fill_finalize(); // NOTE: I added this
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Darstellung eines Zeigers als hexadezimale ganze Zahl
|
||||
OutStream& OutStream::operator<<(void* ptr) {
|
||||
int oldbase = base;
|
||||
base = 16;
|
||||
*this << (unsigned long)ptr;
|
||||
base = oldbase;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Aufruf einer Manipulatorfunktion
|
||||
OutStream& OutStream::operator<<(OutStream& (*f)(OutStream&)) {
|
||||
return f(*this);
|
||||
}
|
||||
// NOTE: The implementations now resides in the OutStream.h as I switched them to templated functions
|
||||
|
||||
//
|
||||
// Manipulatorfunktionen
|
||||
@ -180,33 +80,4 @@ OutStream& OutStream::operator<<(OutStream& (*f)(OutStream&)) {
|
||||
// Aufgabe der Manipulatoren ist, die Darstellung der nachfolgenden Ausgaben
|
||||
// zu beeinflussen, z.B durch die Wahl des Zahlensystems.
|
||||
|
||||
// Fuege einen Zeilenumbruch in die Ausgabe ein.
|
||||
OutStream& endl(OutStream& os) {
|
||||
os << '\n';
|
||||
os.flush();
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehlt das binaere Zahlensystem aus.
|
||||
OutStream& bin(OutStream& os) {
|
||||
os.base = 2;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehlt das oktale Zahlensystem aus.
|
||||
OutStream& oct(OutStream& os) {
|
||||
os.base = 8;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehlt das dezimale Zahlensystem aus.
|
||||
OutStream& dec(OutStream& os) {
|
||||
os.base = 10;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehlt das hexadezimale Zahlensystem aus.
|
||||
OutStream& hex(OutStream& os) {
|
||||
os.base = 16;
|
||||
return os;
|
||||
}
|
||||
// NOTE: The implementations now resides in the OutStream.h as I switched them to templated functions
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include "lib/StringBuffer.h"
|
||||
|
||||
// NOTE: I added this
|
||||
// TODO: I should probably put this inside some FormatStream or sth...
|
||||
// TODO: Should this only work for the next << ?
|
||||
class fillw {
|
||||
public:
|
||||
fillw() : w(0) {};
|
||||
@ -41,7 +39,6 @@ public:
|
||||
};
|
||||
|
||||
class OutStream : public StringBuffer {
|
||||
|
||||
private:
|
||||
OutStream(const OutStream& copy); // Verhindere Kopieren
|
||||
|
||||
@ -65,7 +62,8 @@ public:
|
||||
fill_used = 0;
|
||||
}
|
||||
|
||||
void flush() override = 0; // weiterhin undefiniert aber public
|
||||
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
|
||||
void flush() override;
|
||||
|
||||
// NOTE: I added this, override put for fixed width
|
||||
void put(char c) override;
|
||||
@ -73,30 +71,131 @@ public:
|
||||
// OPERATOR << : Umwandlung des angegebenen Datentypes in eine
|
||||
// Zeichenkette.
|
||||
|
||||
// NOTE: I changed the stream manipulators to templates to be usable with different streams
|
||||
// Needed because I added manipulators to the CGA_Stream class
|
||||
|
||||
// Darstellung eines Zeichens (trivial)
|
||||
OutStream& operator<<(char c);
|
||||
OutStream& operator<<(unsigned char c);
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, char c) {
|
||||
os.put(c);
|
||||
if (c != '\n') {
|
||||
// endl() doesn't has access to StringBuffer::put(), so ignore \n here
|
||||
os.fill_finalize(); // NOTE: I added this
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned char c) {
|
||||
return os << (char)c;
|
||||
}
|
||||
|
||||
// Darstellung einer nullterminierten Zeichenkette
|
||||
OutStream& operator<<(char* string);
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, char* string) {
|
||||
|
||||
// Darstellung ganzer Zahlen im Zahlensystem zur Basis base
|
||||
OutStream& operator<<(short ival);
|
||||
OutStream& operator<<(unsigned short ival);
|
||||
OutStream& operator<<(int ival);
|
||||
OutStream& operator<<(unsigned int ival);
|
||||
OutStream& operator<<(long ival);
|
||||
OutStream& operator<<(unsigned long ival);
|
||||
char* pos = string;
|
||||
while (*pos) {
|
||||
os.put(*pos);
|
||||
pos++;
|
||||
}
|
||||
os.fill_finalize(); // NOTE: I added this
|
||||
return os;
|
||||
}
|
||||
|
||||
// Darstellung ganzer Zahlen im Zahlensystem zur Basis base
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, short ival) {
|
||||
return os << (long)ival;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned short ival) {
|
||||
return os << (unsigned long)ival;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, int ival) {
|
||||
return os << (long)ival;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned int ival) {
|
||||
return os << (unsigned long)ival;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, long ival) {
|
||||
// Bei negativen Werten wird ein Minuszeichen ausgegeben.
|
||||
if (ival < 0) {
|
||||
os.put('-');
|
||||
ival = -ival;
|
||||
}
|
||||
// Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben.
|
||||
return os << (unsigned long)ival;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, unsigned long ival) {
|
||||
unsigned long div;
|
||||
char digit;
|
||||
|
||||
if (os.base == 8) {
|
||||
os.put('0'); // oktale Zahlen erhalten eine fuehrende Null
|
||||
} else if (os.base == 16) {
|
||||
os.put('0'); // hexadezimale Zahlen ein "0x"
|
||||
os.put('x');
|
||||
}
|
||||
|
||||
// Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die
|
||||
// noch kleiner als die darzustellende Zahl ist.
|
||||
for (div = 1; ival / div >= (unsigned long)os.base; div *= os.base) {};
|
||||
|
||||
// ziffernweise Ausgabe der Zahl
|
||||
for (; div > 0; div /= (unsigned long)os.base) {
|
||||
digit = ival / div;
|
||||
if (digit < 10) {
|
||||
os.put('0' + digit);
|
||||
} else {
|
||||
os.put('a' + digit - 10);
|
||||
}
|
||||
ival %= div;
|
||||
}
|
||||
os.fill_finalize(); // NOTE: I added this
|
||||
return os;
|
||||
}
|
||||
|
||||
// Darstellung eines Zeigers als hexadezimale ganze Zahl
|
||||
OutStream& operator<<(void* ptr);
|
||||
|
||||
// NOTE: I added this
|
||||
OutStream& operator<<(const fillw&);
|
||||
OutStream& operator<<(const fillc&);
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, void* ptr) {
|
||||
int oldbase = os.base;
|
||||
os.base = 16;
|
||||
os << (unsigned long)ptr;
|
||||
os.base = oldbase;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Aufruf einer Manipulatorfunktion
|
||||
OutStream& operator<<(OutStream& (*f)(OutStream&));
|
||||
// NOTE: Changed the function pointer type including the manipulator functions
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, T& (*f)(T&)) {
|
||||
return f(os);
|
||||
}
|
||||
|
||||
// NOTE: I added this
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, const fillw& w) {
|
||||
os.flush(); // Flush the buffer to not modify previous output
|
||||
os.fill_width = w.w;
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend T& operator<<(T& os, const fillc& c) {
|
||||
os.flush();
|
||||
os.fill_char = c.c;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@ -110,18 +209,39 @@ public:
|
||||
// zu beeinflussen, z.B durch die Wahl des Zahlensystems.
|
||||
|
||||
// Zeilenumbruch in Ausgabe einfuegen.
|
||||
OutStream& endl(OutStream& os);
|
||||
template<typename T>
|
||||
T& endl(T& os) {
|
||||
os << '\n';
|
||||
os.flush();
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehle binaeres Zahlensystem aus.
|
||||
OutStream& bin(OutStream& os);
|
||||
template<typename T>
|
||||
T& bin(T& os) {
|
||||
os.base = 2;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehle oktales Zahlensystem aus.
|
||||
OutStream& oct(OutStream& os);
|
||||
template<typename T>
|
||||
T& oct(T& os) {
|
||||
os.base = 8;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehle dezimales Zahlensystem aus.
|
||||
OutStream& dec(OutStream& os);
|
||||
template<typename T>
|
||||
T& dec(T& os) {
|
||||
os.base = 10;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Waehle hexadezimales Zahlensystem aus.
|
||||
OutStream& hex(OutStream& os);
|
||||
template<typename T>
|
||||
T& hex(T& os) {
|
||||
os.base = 16;
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
10
c_os/main.cc
10
c_os/main.cc
@ -22,12 +22,10 @@ int main() {
|
||||
// Bildschirm loeschen.
|
||||
kout.clear();
|
||||
|
||||
// Startmeldung ausgeben
|
||||
kout << "Yo it's booting" << endl;
|
||||
text_demo();
|
||||
// sound_demo();
|
||||
keyboard_demo();
|
||||
|
||||
heap_demo();
|
||||
|
||||
while (1)
|
||||
;
|
||||
while (1) {};
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ void keyboard_demo() {
|
||||
|
||||
/* Hier muess Code eingefuegt werden */
|
||||
|
||||
kout << "Keyboard Demo: " << endl;
|
||||
|
||||
while (true) {
|
||||
kout << kb.key_hit();
|
||||
kout.flush();
|
||||
|
@ -13,14 +13,12 @@
|
||||
void text_demo() {
|
||||
|
||||
/* Hier muess Code eingefuegt werden */
|
||||
kout << "Attribut (GREEN on WHITE, blinking): "
|
||||
<< (unsigned short)kout.attribute(CGA::WHITE, CGA::GREEN, true) << endl
|
||||
<< "Attribut (WHITE on BLACK, no blink): "
|
||||
<< (unsigned short)kout.attribute(CGA::BLACK, CGA::WHITE, false) << endl
|
||||
<< endl;
|
||||
kout << "Attribut (GREEN on WHITE): "
|
||||
<< bgc(CGA::WHITE) << fgc(CGA::GREEN) << "GREEN on WHITE" << endl
|
||||
<< "Attribut (WHITE on BLACK): "
|
||||
<< bgc(CGA::BLACK) << fgc(CGA::WHITE) << "WHITE on BLACK" << endl;
|
||||
|
||||
kout << "Test der Zahlenausgabefunktion:" << endl
|
||||
<< endl
|
||||
<< "| dec | hex | bin |" << endl
|
||||
<< "+-------+-------+-------+" << endl;
|
||||
|
||||
|
Reference in New Issue
Block a user