From d726c9e50a096d9f87affae5ebabfd34dae23333 Mon Sep 17 00:00:00 2001 From: Bensong Liu <bensl@microsoft.com> Date: Mon, 2 Nov 2020 18:18:55 +0800 Subject: [PATCH] println working --- kernel/include/stdlib.hpp | 22 +++++++++++++++++ kernel/include/vga.hpp | 52 ++++++++++++++++++++++++++++++++------- kernel/kernel.cc | 5 ++++ 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 kernel/include/stdlib.hpp diff --git a/kernel/include/stdlib.hpp b/kernel/include/stdlib.hpp new file mode 100644 index 0000000..dfeffc2 --- /dev/null +++ b/kernel/include/stdlib.hpp @@ -0,0 +1,22 @@ +#ifndef ROS_KERN_STDLIB_HPP +#define ROS_KERN_STDLIB_HPP + +#include "stdint.hpp" + +template <typename T> +inline void memcpy(T *dst, const T *src, size_t count) { + for(auto i = 0; i < count; ++i) { + dst[i] = src[i]; + } +} +template <typename T> +inline void memset(T *dst, const T &data_to_set, size_t count) { + char *cdst = reinterpret_cast<char *>(dst); + + for(auto i = 0; i < count; ++i) { + cdst[i] = data_to_set; + } +} + + +#endif diff --git a/kernel/include/vga.hpp b/kernel/include/vga.hpp index b6925ed..ffebbc3 100644 --- a/kernel/include/vga.hpp +++ b/kernel/include/vga.hpp @@ -1,17 +1,51 @@ #ifndef ROS_KERN_VGA_HPP #define ROS_KERN_VGA_HPP -inline char *vga_begin = (char *)0xb8000; -void push_char(char c, char color) { - static int pos = 0; - vga_begin[pos++] = c; - vga_begin[pos++] = color; +#include "stdint.hpp" +#include "stdlib.hpp" + +#define VGA_BEGIN_ADDR ((uint16_t *)0xb8000) +constexpr uint16_t VGA_WIDTH = 80; +constexpr uint16_t VGA_HEIGHT = 25; +constexpr uint16_t VGA_MAKE_CHAR(char c, uint8_t color) { + return (color << 8) + uint8_t(c); +} +constexpr uint8_t default_color = 0x0f; + + +inline void trigger_scroll(uint16_t *pos) { + for(uint16_t row = 1; row < VGA_HEIGHT; ++row) { + memcpy(VGA_BEGIN_ADDR + (row-1)*VGA_WIDTH, VGA_BEGIN_ADDR + row*VGA_WIDTH, VGA_WIDTH); + } + memset(VGA_BEGIN_ADDR + (VGA_HEIGHT-1)*VGA_WIDTH, VGA_MAKE_CHAR(0, 0), VGA_WIDTH); + (*pos) -= VGA_WIDTH; +} + +inline void set_char(uint16_t x, uint16_t y, char c, char color) { + VGA_BEGIN_ADDR[y*VGA_WIDTH + x] = VGA_MAKE_CHAR(c, color); +} + +inline void put_char(char c, uint8_t color) { + static uint16_t pos = 0; + if(pos >= VGA_WIDTH * VGA_HEIGHT) + trigger_scroll(&pos); + + switch(c) { + case '\n': + pos += VGA_WIDTH; + [[fallthrough]]; // unix \n implies \r. + case '\r': + pos -= pos % VGA_WIDTH; + break; + default: + VGA_BEGIN_ADDR[pos++] = VGA_MAKE_CHAR(c, color); + } } -void set_char(int x, int y, char c, char color) { - auto pos = x + 80 * y; - vga_begin[pos*2] = c; - vga_begin[pos*2+1] = color; +inline void print(const char *cstr, uint8_t color = default_color) { + while(*cstr != '\0') { + put_char(*(cstr++), color); + } } #endif \ No newline at end of file diff --git a/kernel/kernel.cc b/kernel/kernel.cc index d1c4e40..5419de6 100644 --- a/kernel/kernel.cc +++ b/kernel/kernel.cc @@ -17,5 +17,10 @@ void main() { set_char(x, y, c, color); } } + print("Hello world!\n"); + print("Hello world!\n", 0xb1); + print("Hello world!\n", 0xae); + print("Hello world!\n", 0x5c); + print("Hello world!\n"); } -- GitLab