#include #include namespace mercury::kernel::terminal { uint8_t *termfont; uint64_t termfont_len; int width; int height; int cursor_x; int cursor_y; framebuffer::color bg_color; framebuffer::color fg_color; static uint8_t glyph_height; void init_terminal() { //TODO - verify that termfont fits inside termfont_len (i.e. that no other // functions in this file will try to access memory outside termfont) //TODO - check magic header to verify that this is actually a font and to // see whether this is a psf1 font or a psf2 font. //TODO - support psf2 fonts. currently psf1 is assumed. //TODO - read unicode table if there is one. currently it is assumed that // all 256 codepoints have glyphs, and that they appear in order. glyph_height = termfont[3]; width = framebuffer::width / 8; height = framebuffer::height / glyph_height; cursor_x = 0; cursor_y = 0; bg_color = framebuffer::encode_color(0, 0, 0); fg_color = framebuffer::encode_color(255, 255, 255); } static void cursor_down() { if (++cursor_y == height) { --cursor_y; framebuffer::move_region( 0, glyph_height, width * 8, height * glyph_height, 0, 0); framebuffer::fill_region(0, (height - 1) * glyph_height, width * 8, height * glyph_height, bg_color); } } static void cursor_right() { if (++cursor_x == width) { cursor_x = 0; cursor_down(); } } void draw_char(char ch, int x, int y) { const uint8_t *glyph = termfont + 4 + glyph_height * (unsigned)ch; for (int i = 0; i < glyph_height; ++i) for (int j = 0; j < 8; ++j) framebuffer::set_pixel(x * 8 + j, y * glyph_height + i, ((glyph[i] << j) & 0x80) ? fg_color : bg_color); } void put_char(char ch) { switch (ch) { case '\n': cursor_x = 0; cursor_down(); break; default: draw_char(ch, cursor_x, cursor_y); cursor_right(); break; } } void put_string(const utility::string &str) { for (size_t i = 0; i < str.count; ++i) put_char(str.buffer[i]); } void put_string_sz(const char *str) { for (size_t i = 0; str[i]; ++i) put_char(str[i]); } void put_int_decimal(uint64_t n, bool with_commas) { if (n == 0) { put_char('0'); return; } uint64_t d = 1; int i = 0; while (d <= n / 10) { d *= 10; ++i; } while (d) { put_char('0' + ((n / d) % 10)); d /= 10; if (with_commas && (i % 3 == 0) && (i != 0)) put_char(','); --i; } } }