Added an 80*25 text display to the x86 HAL

This commit is contained in:
Morten Delenk 2015-10-10 18:03:53 +02:00
parent d1f5c188bb
commit 3645036ee9
7 changed files with 204 additions and 34 deletions

View file

@ -17,5 +17,5 @@ _stop:
hlt
jmp _stop
.section .bss
.space 65536
.space 8192
kernel_stack:

View file

@ -0,0 +1,14 @@
#ifndef _BASE_HPP
#define _BASE_HPP
#include <stdint.h>
namespace MTGosHAL {
class Output;
class Serial;
class Screen;
enum class BG_color: uint16_t;
enum class FG_color: uint16_t;
extern Serial* debug;
extern Screen* out;
extern Screen* err;
}
#endif

View file

@ -1,6 +1,9 @@
#ifndef _OUTPUT_HPP
#define _OUTPUT_HPP
#include <base.hpp>
#include <stdint.h>
namespace MTGosHAL {
enum class Base : int {
BINARY=2,
TERNARY,
@ -20,12 +23,8 @@ namespace MTGosHAL {
};
/* abstract */ class Output {
private:
virtual void putChar(char c) { /*ignore*/ };
auto puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
virtual auto putChar(char c) -> void = 0;
auto puts(const char* s) -> void;
int base=10;
public:
template <typename T>
@ -36,32 +35,12 @@ namespace MTGosHAL {
};
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
auto Output::operator<<<Base>(Base output) -> Output &;
template <>
auto Output::operator<<<int>(int output) -> Output & {
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
auto Output::operator<<<int>(int output) -> Output &;
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
auto Output::operator<<<char>(char output) -> Output &;
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
auto Output::operator<<<char*>(char* output) -> Output &;
}
#endif

View file

@ -0,0 +1,71 @@
#ifndef _TEXTDISP_H
#define _TEXTDISP_H
#include <stdint.h>
#include <output.hpp>
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 24
namespace MTGosHAL {
enum class BG_color : uint16_t {
BLACK=0x0000,
BLUE=0x1000,
GREEN=0x2000,
CYAN=0x3000,
RED=0x4000,
MAGENTA=0x5000,
BROWN=0x6000,
LIGHT_GREY=0x7000,
GREY=0x8000,
LIGHT_BLUE=0x9000,
LIGHT_GREEN=0xA000,
LIGHT_CYAN=0xB000,
LIGHT_RED=0xC000,
LIGHT_MAGENTA=0xD000,
YELLOW=0xE000,
WHITE=0xF000
};
enum class FG_color : uint16_t {
BLACK=0x000,
BLUE=0x100,
GREEN=0x200,
CYAN=0x300,
RED=0x400,
MAGENTA=0x500,
BROWN=0x600,
LIGHT_GREY=0x700,
GREY=0x800,
LIGHT_BLUE=0x900,
LIGHT_GREEN=0xA00,
LIGHT_CYAN=0xB00,
LIGHT_RED=0xC00,
LIGHT_MAGENTA=0xD00,
YELLOW=0xE00,
WHITE=0xF00
};
class Screen: public Output {
private:
FG_color fg;
BG_color bg;
int x,y;
uint16_t* vmem=(uint16_t*)0xB8000;
auto putChar(char c) -> void;
public:
Screen() {
clrscr();
}
template <typename T>
auto operator<< (T output) -> Screen & {
Output::operator<<<T>(output);
return *this;
}
auto clrscr() -> void;
auto scroll() -> void;
auto setColor(FG_color fg) -> Screen &;
auto setColor(BG_color bg) -> Screen &;
auto setColor(FG_color fg, BG_color bg) -> Screen &;
};
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &;
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &;
}
#endif

View file

@ -1,15 +1,26 @@
#include <base.hpp>
#include <output.hpp>
#include <serial.hpp>
namespace MTGosHAL {
#include <textDISP.hpp>
namespace MTGosHAL {
Serial* debug;
Screen* out;
Screen* err;
void main() {
Serial serialOUT(115200);
serialOUT << "This is the debug output of MTGos\n";
Screen display;
debug=&serialOUT;
err=&display;
out=&display;
*out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
*debug << "Hello debugger! This is MTGos version 0.0\nThese logs are probably very long, so please redirect the output to a file.\n";
for(;;);
}
}
extern "C" void init() {
MTGosHAL::main();
}
extern "C" void __cxa_pure_virtual() {
for(;;);
*MTGosHAL::debug << "A pure virtual function just got called.\n";
}

View file

@ -0,0 +1,39 @@
#include <base.hpp>
#include <output.hpp>
#include <serial.hpp>
#include <textDISP.hpp>
namespace MTGosHAL {
auto Output::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Output::operator<<<int>(int output) -> Output & {
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
}

View file

@ -0,0 +1,56 @@
#include <base.hpp>
#include <textDISP.hpp>
namespace MTGosHAL {
auto Screen::putChar(char c) -> void {
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
break;
case '\0':
break;
default:
vmem[y*SCREEN_WIDTH+(x++)]=((uint16_t)fg) | ((uint16_t)bg) | ((uint16_t)c);
if(x==SCREEN_WIDTH) {
x=0; y++;
}
break;
}
if(y>SCREEN_HEIGHT)
scroll();
}
auto Screen::clrscr() -> void {
for(int p=0; p<SCREEN_HEIGHT*SCREEN_WIDTH+SCREEN_WIDTH; p++)
vmem[p]=((uint16_t)fg) | ((uint16_t)bg) | ((uint16_t)' ');
}
auto Screen::scroll() -> void {
for(int p=0; p<SCREEN_HEIGHT*SCREEN_WIDTH; p++)
vmem[p]=vmem[p+SCREEN_WIDTH];
for(int p=SCREEN_HEIGHT*SCREEN_WIDTH; p<(SCREEN_HEIGHT+1)*SCREEN_WIDTH; p++)
vmem[p]=((uint16_t)fg) | ((uint16_t)bg) | ((uint16_t)' ');
y--;
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
}