Added an 80*25 text display to the x86 HAL
This commit is contained in:
parent
d1f5c188bb
commit
3645036ee9
7 changed files with 204 additions and 34 deletions
|
@ -17,5 +17,5 @@ _stop:
|
|||
hlt
|
||||
jmp _stop
|
||||
.section .bss
|
||||
.space 65536
|
||||
.space 8192
|
||||
kernel_stack:
|
||||
|
|
14
kernel/hal/x86/include/base.hpp
Normal file
14
kernel/hal/x86/include/base.hpp
Normal 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
|
|
@ -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
|
||||
|
|
71
kernel/hal/x86/include/textDISP.hpp
Normal file
71
kernel/hal/x86/include/textDISP.hpp
Normal 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
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
39
kernel/hal/x86/output/output.cpp
Normal file
39
kernel/hal/x86/output/output.cpp
Normal 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;
|
||||
}
|
||||
}
|
56
kernel/hal/x86/output/textDISP.cpp
Normal file
56
kernel/hal/x86/output/textDISP.cpp
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue