From c81fcfbabc7238ffb48a770192644fbbef5832b4 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Tue, 14 Jan 2014 21:19:23 +0100 Subject: [PATCH] Add support for VESA console --- kernel/include/console.hpp | 2 + kernel/include/text_console.hpp | 22 ++++++ kernel/include/vesa_console.hpp | 23 ++++++ kernel/src/console.cpp | 121 +++++++++++++++++--------------- kernel/src/kernel.cpp | 16 +---- kernel/src/shell.cpp | 2 +- kernel/src/text_console.cpp | 81 +++++++++++++++++++++ kernel/src/vesa.cpp | 2 + kernel/src/vesa_console.cpp | 57 +++++++++++++++ 9 files changed, 257 insertions(+), 69 deletions(-) create mode 100644 kernel/include/text_console.hpp create mode 100644 kernel/include/vesa_console.hpp create mode 100644 kernel/src/text_console.cpp create mode 100644 kernel/src/vesa_console.cpp diff --git a/kernel/include/console.hpp b/kernel/include/console.hpp index 8e701998..b6210558 100644 --- a/kernel/include/console.hpp +++ b/kernel/include/console.hpp @@ -12,6 +12,8 @@ #include "stl/enable_if.hpp" #include "stl/string.hpp" +void init_console(); + void set_column(long column); long get_column(); diff --git a/kernel/include/text_console.hpp b/kernel/include/text_console.hpp new file mode 100644 index 00000000..0ee87c25 --- /dev/null +++ b/kernel/include/text_console.hpp @@ -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 diff --git a/kernel/include/vesa_console.hpp b/kernel/include/vesa_console.hpp new file mode 100644 index 00000000..23975014 --- /dev/null +++ b/kernel/include/vesa_console.hpp @@ -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 + diff --git a/kernel/src/console.cpp b/kernel/src/console.cpp index 310f79b8..b941a19d 100644 --- a/kernel/src/console.cpp +++ b/kernel/src/console.cpp @@ -7,45 +7,64 @@ #include -#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 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(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(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(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; diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 301d7062..c1399993 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -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(); diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index a25cd14c..42098316 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -876,7 +876,7 @@ void shutdown_command(const std::vector&){ } //end of anonymous namespace void init_shell(){ -// wipeout(); + wipeout(); k_print("thor> "); diff --git a/kernel/src/text_console.cpp b/kernel/src/text_console.cpp new file mode 100644 index 00000000..6d73dfbb --- /dev/null +++ b/kernel/src/text_console.cpp @@ -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(0x0B8000); + auto destination = vga_buffer_fast; + auto source = &vga_buffer_fast[20]; + + std::copy_n(destination, source, 24 * 20); + + auto vga_buffer = reinterpret_cast(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(0x0B8000); + + vga_buffer[line * 80 + column] = make_vga_entry(c, make_color(WHITE, BLACK)); +} diff --git a/kernel/src/vesa.cpp b/kernel/src/vesa.cpp index da899801..50dfce0a 100644 --- a/kernel/src/vesa.cpp +++ b/kernel/src/vesa.cpp @@ -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; } } diff --git a/kernel/src/vesa_console.cpp b/kernel/src/vesa_console.cpp new file mode 100644 index 00000000..a49cad43 --- /dev/null +++ b/kernel/src/vesa_console.cpp @@ -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); +}