Add support for VESA console

This commit is contained in:
Baptiste Wicht 2014-01-14 21:19:23 +01:00
parent 0a6637db7f
commit c81fcfbabc
9 changed files with 257 additions and 69 deletions

View File

@ -12,6 +12,8 @@
#include "stl/enable_if.hpp"
#include "stl/string.hpp"
void init_console();
void set_column(long column);
long get_column();

View File

@ -0,0 +1,22 @@
//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#ifndef TEXT_CONSOLE_H
#define TEXT_CONSOLE_H
#include "stl/types.hpp"
struct text_console {
void init();
size_t lines();
size_t columns();
void clear();
void scroll_up();
void print_char(size_t line, size_t column, char c);
};
#endif

View File

@ -0,0 +1,23 @@
//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#ifndef VESA_CONSOLE_H
#define VESA_CONSOLE_H
#include "stl/types.hpp"
struct vesa_console {
void init();
size_t lines();
size_t columns();
void clear();
void scroll_up();
void print_char(size_t line, size_t column, char c);
};
#endif

View File

@ -7,45 +7,64 @@
#include <stdarg.h>
#include "console.hpp"
#include "stl/types.hpp"
#include "stl/string.hpp"
#include "console.hpp"
#include "vesa.hpp"
#include "text_console.hpp"
#include "vesa_console.hpp"
namespace {
text_console t_console;
vesa_console v_console;
bool text = true;
size_t lines(){
if(text){
return t_console.lines();
} else {
return v_console.lines();
}
}
size_t columns(){
if(text){
return t_console.columns();
} else {
return v_console.columns();
}
}
void clear(){
if(text){
t_console.clear();
} else {
v_console.clear();
}
}
void scroll_up(){
if(text){
t_console.scroll_up();
} else {
v_console.scroll_up();
}
}
void print_char(size_t line, size_t column, char c){
if(text){
t_console.print_char(line, column, c);
} else {
v_console.print_char(line, column, c);
}
}
long current_line = 0;
long current_column = 0;
enum vga_color {
BLACK = 0,
BLUE = 1,
GREEN = 2,
CYAN = 3,
RED = 4,
MAGENTA = 5,
BROWN = 6,
LIGHT_GREY = 7,
DARK_GREY = 8,
LIGHT_BLUE = 9,
LIGHT_GREEN = 10,
LIGHT_CYAN = 11,
LIGHT_RED = 12,
LIGHT_MAGENTA = 13,
LIGHT_BROWN = 14,
WHITE = 15,
};
uint8_t make_color(vga_color fg, vga_color bg){
return fg | bg << 4;
}
uint16_t make_vga_entry(char c, uint8_t color){
uint16_t c16 = c;
uint16_t color16 = color;
return c16 | color16 << 8;
}
template<typename N>
uint64_t digits(N number){
if(number < 10){
@ -96,6 +115,16 @@ void print_signed(D number){
} //end of anonymous namespace
void init_console(){
text = !vesa::vesa_enabled;
if(text){
t_console.init();
} else {
v_console.init();
}
}
void set_column(long column){
current_column = column;
}
@ -147,19 +176,10 @@ void k_print(int64_t number){
void next_line(){
++current_line;
if(current_line == 25){
auto vga_buffer_fast = reinterpret_cast<uint64_t*>(0x0B8000);
auto destination = vga_buffer_fast;
auto source = &vga_buffer_fast[20];
if(current_line == lines()){
scroll_up();
std::copy_n(destination, source, 24 * 20);
auto vga_buffer = reinterpret_cast<uint16_t*>(0x0B8000);
for(uint64_t i = 0; i < 80; ++i){
vga_buffer[24 * 80 + i] = make_vga_entry(' ', make_color(WHITE, BLACK));
}
current_line = 24;
--current_line;
}
current_column = 0;
@ -175,13 +195,11 @@ void k_print(char key){
} else if(key == '\t'){
k_print(" ");
} else {
uint16_t* vga_buffer = reinterpret_cast<uint16_t*>(0x0B8000);
vga_buffer[current_line * 80 + current_column] = make_vga_entry(key, make_color(WHITE, BLACK));
print_char(current_line, current_column, key);
++current_column;
if(current_column == 80){
if(current_column == columns()){
next_line();
}
}
@ -206,14 +224,7 @@ void k_print(const char* str, uint64_t end){
}
void wipeout(){
current_line = 0;
current_column = 0;
for(int line = 0; line < 25; ++line){
for(uint64_t column = 0; column < 80; ++column){
k_print(' ');
}
}
clear();
current_line = 0;
current_column = 0;

View File

@ -16,6 +16,7 @@
#include "arch.hpp"
#include "e820.hpp"
#include "vesa.hpp"
#include "console.hpp"
extern "C" {
@ -40,21 +41,10 @@ void kernel_main(){
disks::detect_disks();
vesa::init();
//Call global cosntructors
//Call global constructors
_init();
vesa::draw_hline(10, 10, 1004, 0, 255, 0);
vesa::draw_hline(10, 40, 1004, 0, 255, 0);
vesa::draw_hline(10, 758, 1004, 0, 255, 0);
vesa::draw_vline(10, 10, 748, 0, 255, 0);
vesa::draw_vline(1014, 10, 748, 0, 255, 0);
vesa::draw_char(500, 500, 'h', 0, 255, 0);
vesa::draw_char(508, 500, 'e', 0, 255, 0);
vesa::draw_char(516, 500, 'l', 0, 255, 0);
vesa::draw_char(524, 500, 'l', 0, 255, 0);
vesa::draw_char(532, 500, 'o', 0, 255, 0);
init_console();
//Launch the shell
init_shell();

View File

@ -876,7 +876,7 @@ void shutdown_command(const std::vector<std::string>&){
} //end of anonymous namespace
void init_shell(){
// wipeout();
wipeout();
k_print("thor> ");

View File

@ -0,0 +1,81 @@
//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include "text_console.hpp"
#include "stl/algorithms.hpp"
namespace {
enum vga_color {
BLACK = 0,
BLUE = 1,
GREEN = 2,
CYAN = 3,
RED = 4,
MAGENTA = 5,
BROWN = 6,
LIGHT_GREY = 7,
DARK_GREY = 8,
LIGHT_BLUE = 9,
LIGHT_GREEN = 10,
LIGHT_CYAN = 11,
LIGHT_RED = 12,
LIGHT_MAGENTA = 13,
LIGHT_BROWN = 14,
WHITE = 15,
};
uint8_t make_color(vga_color fg, vga_color bg){
return fg | bg << 4;
}
uint16_t make_vga_entry(char c, uint8_t color){
uint16_t c16 = c;
uint16_t color16 = color;
return c16 | color16 << 8;
}
} //end of anonymous namespace
void text_console::init(){
//Nothing special to init
}
size_t text_console::lines(){
return 25;
}
size_t text_console::columns(){
return 80;
}
void text_console::clear(){
for(int line = 0; line < 25; ++line){
for(uint64_t column = 0; column < 80; ++column){
print_char(line, column, ' ');
}
}
}
void text_console::scroll_up(){
auto vga_buffer_fast = reinterpret_cast<uint64_t*>(0x0B8000);
auto destination = vga_buffer_fast;
auto source = &vga_buffer_fast[20];
std::copy_n(destination, source, 24 * 20);
auto vga_buffer = reinterpret_cast<uint16_t*>(0x0B8000);
for(uint64_t i = 0; i < 80; ++i){
vga_buffer[24 * 80 + i] = make_vga_entry(' ', make_color(WHITE, BLACK));
}
}
void text_console::print_char(size_t line, size_t column, char c){
uint16_t* vga_buffer = reinterpret_cast<uint16_t*>(0x0B8000);
vga_buffer[line * 80 + column] = make_vga_entry(c, make_color(WHITE, BLACK));
}

View File

@ -120,6 +120,8 @@ void vesa::draw_char(size_t x, size_t y, char c, uint32_t color){
for(size_t j = 0; j < 8; ++j){
if(font_char[i] & (1 << (8 - j))){
screen[where+j] = color;
} else {
screen[where+j] = 0;
}
}

View File

@ -0,0 +1,57 @@
//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include "vesa_console.hpp"
#include "vesa.hpp"
namespace {
constexpr const size_t MARGIN = 10;
constexpr const size_t PADDING = 5;
constexpr const size_t LEFT = MARGIN + PADDING;
constexpr const size_t TOP = 50;
size_t _lines;
size_t _columns;
uint32_t _color;
} //end of anonymous namespace
void vesa_console::init(){
auto& block = vesa::mode_info_block;
_columns = (block.width - (MARGIN + PADDING) * 2) / 8;
_lines = (block.height - TOP - MARGIN - PADDING) / 16;
_color = vesa::make_color(0, 255, 0);
vesa::draw_hline(10, 10, 1004, _color);
vesa::draw_hline(10, 40, 1004, _color);
vesa::draw_hline(10, 758, 1004, _color);
vesa::draw_vline(10, 10, 748, _color);
vesa::draw_vline(1014, 10, 748, _color);
}
size_t vesa_console::lines(){
return _lines;
}
size_t vesa_console::columns(){
return _columns;
}
void vesa_console::clear(){
}
void vesa_console::scroll_up(){
}
void vesa_console::print_char(size_t line, size_t column, char c){
vesa::draw_char(LEFT + 8 * column, TOP + 16 * line, c, _color);
}