From 94de87ef867f85656af76eb6932605be1d55ccba Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Tue, 24 Apr 2018 09:32:57 -0700 Subject: [PATCH] Refactor screen ouput from main console code --- Makefile | 3 +- src/kernel/console.cpp | 363 ++++++++++++++++++++---------------- src/kernel/console.h | 41 ++-- src/kernel/main.cpp | 10 +- src/modules/kutil/cpprt.cpp | 3 + 5 files changed, 224 insertions(+), 196 deletions(-) create mode 100644 src/modules/kutil/cpprt.cpp diff --git a/Makefile b/Makefile index abfc641..31b94c7 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,6 @@ WARNFLAGS += -Wno-attributes -Wno-sign-compare -Wno-multichar WARNFLAGS += -Wno-div-by-zero -Wno-endif-labels -Wno-pragmas WARNFLAGS += -Wno-format-extra-args -Wno-unused-result WARNFLAGS += -Wno-deprecated-declarations -Wno-unused-function -WARNFLAGS += -Wno-unused-but-set-parameter ASFLAGS ?= ASFLAGS += -p $(BUILD_D)/versions.s @@ -62,7 +61,7 @@ CFLAGS += -std=c11 -mcmodel=large CXXFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS) CXXFLAGS += -DGIT_VERSION="\"$(VERSION)\"" -CXXFLAGS += -std=c++14 -mcmodel=large +CXXFLAGS += -std=c++14 -mcmodel=large -fno-rtti BOOT_CFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS) BOOT_CFLAGS += -std=c11 -I src/boot -fPIC -fshort-wchar diff --git a/src/kernel/console.cpp b/src/kernel/console.cpp index 1a5c9eb..b8767a6 100644 --- a/src/kernel/console.cpp +++ b/src/kernel/console.cpp @@ -2,85 +2,216 @@ #include "io.h" const char digits[] = "0123456789abcdef"; +console g_console; -console *console::default_console = nullptr; -console::console(const font &f, const screen &s, void *scratch, size_t len) : - m_font(f), - m_screen(s), - m_size(s.width() / f.width(), s.height() / f.height()), - m_fg(0xffffff), - m_bg(0), - m_first(0), - m_length(len), - m_data(nullptr), - m_attrs(nullptr), - m_palette(nullptr) +class console_out_screen { - const unsigned count = m_size.size(); - const size_t palette_size = sizeof(screen::pixel_t) * 256; - const size_t attrs_size = 2 * count; +public: + console_out_screen(const font &f, const screen &s, void *scratch, size_t len) : + m_font(f), + m_screen(s), + m_size(s.width() / f.width(), s.height() / f.height()), + m_fg(0xffffff), + m_bg(0), + m_first(0), + m_length(len), + m_data(nullptr), + m_attrs(nullptr), + m_palette(nullptr) + { + const unsigned count = m_size.size(); + const size_t palette_size = sizeof(screen::pixel_t) * 256; + const size_t attrs_size = 2 * count; - if (len >= count) { - // We have enough scratch space to keep the contents of the screen - m_data = static_cast(scratch); - for (unsigned i = 0; i < count; ++i) - m_data[i] = 0; + if (len >= count) { + // We have enough scratch space to keep the contents of the screen + m_data = static_cast(scratch); + for (unsigned i = 0; i < count; ++i) + m_data[i] = 0; + } + + if (len >= count + palette_size + attrs_size) { + // We have enough scratch space to also keep the colors of the text + m_palette = reinterpret_cast(m_data + count); + + unsigned index = 0; + + // Manually add the 16 basic ANSI colors + m_palette[index++] = m_screen.color(0x00, 0x00, 0x00); + m_palette[index++] = m_screen.color(0xcd, 0x00, 0x00); + m_palette[index++] = m_screen.color(0x00, 0xcd, 0x00); + m_palette[index++] = m_screen.color(0xcd, 0xcd, 0x00); + m_palette[index++] = m_screen.color(0x00, 0x00, 0xee); + m_palette[index++] = m_screen.color(0xcd, 0x00, 0xcd); + m_palette[index++] = m_screen.color(0x00, 0xcd, 0xcd); + m_palette[index++] = m_screen.color(0xe5, 0xe5, 0xe5); + m_palette[index++] = m_screen.color(0x7f, 0x7f, 0x7f); + m_palette[index++] = m_screen.color(0xff, 0x00, 0x00); + m_palette[index++] = m_screen.color(0x00, 0xff, 0x00); + m_palette[index++] = m_screen.color(0xff, 0xff, 0x00); + m_palette[index++] = m_screen.color(0x00, 0x50, 0xff); + m_palette[index++] = m_screen.color(0xff, 0x00, 0xff); + m_palette[index++] = m_screen.color(0x00, 0xff, 0xff); + m_palette[index++] = m_screen.color(0xff, 0xff, 0xff); + + // Build the high-color portion of the table + const uint32_t intensity[] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}; + const uint32_t intensities = sizeof(intensity) / sizeof(uint32_t); + + for (uint32_t r = 0; r < intensities; ++r) { + for (uint32_t g = 0; g < intensities; ++g) { + for (uint32_t b = 0; b < intensities; ++b) { + m_palette[index++] = m_screen.color( + intensity[r], intensity[g], intensity[b]); + } + } + } + + // Build the greyscale portion of the table + for (uint8_t i = 0x08; i <= 0xee; i += 10) + m_palette[index++] = m_screen.color(i, i, i); + + set_color(7, 0); // Grey on black default + m_attrs = reinterpret_cast(m_data + count + palette_size); + for (unsigned i = 0; i < count; ++i) + m_attrs[i] = m_attr; + } + + repaint(); } - if (len >= count + palette_size + attrs_size) { - // We have enough scratch space to also keep the colors of the text - m_palette = reinterpret_cast(m_data + count); + void repaint() + { + m_screen.fill(m_bg); + if (!m_data) return; - unsigned index = 0; + for (unsigned y = 0; y < m_size.y; ++y) { + const char *line = line_pointer(y); + const uint16_t *attrs = attr_pointer(y); + for (unsigned x = 0; x < m_size.x; ++x) { + const uint16_t attr = attrs[x]; - // Manually add the 16 basic ANSI colors - m_palette[index++] = m_screen.color(0x00, 0x00, 0x00); - m_palette[index++] = m_screen.color(0xcd, 0x00, 0x00); - m_palette[index++] = m_screen.color(0x00, 0xcd, 0x00); - m_palette[index++] = m_screen.color(0xcd, 0xcd, 0x00); - m_palette[index++] = m_screen.color(0x00, 0x00, 0xee); - m_palette[index++] = m_screen.color(0xcd, 0x00, 0xcd); - m_palette[index++] = m_screen.color(0x00, 0xcd, 0xcd); - m_palette[index++] = m_screen.color(0xe5, 0xe5, 0xe5); - m_palette[index++] = m_screen.color(0x7f, 0x7f, 0x7f); - m_palette[index++] = m_screen.color(0xff, 0x00, 0x00); - m_palette[index++] = m_screen.color(0x00, 0xff, 0x00); - m_palette[index++] = m_screen.color(0xff, 0xff, 0x00); - m_palette[index++] = m_screen.color(0x00, 0x50, 0xff); - m_palette[index++] = m_screen.color(0xff, 0x00, 0xff); - m_palette[index++] = m_screen.color(0x00, 0xff, 0xff); - m_palette[index++] = m_screen.color(0xff, 0xff, 0xff); + set_color(static_cast(attr), + static_cast(attr >> 8)); - // Build the high-color portion of the table - const uint32_t intensity[] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}; - const uint32_t intensities = sizeof(intensity) / sizeof(uint32_t); + m_font.draw_glyph( + m_screen, + line[x] ? line[x] : ' ', + m_fg, + m_bg, + x * m_font.width(), + y * m_font.height()); + } + } + } - for (uint32_t r = 0; r < intensities; ++r) { - for (uint32_t g = 0; g < intensities; ++g) { - for (uint32_t b = 0; b < intensities; ++b) { - m_palette[index++] = m_screen.color( - intensity[r], intensity[g], intensity[b]); - } + void scroll(unsigned lines) + { + if (!m_data) { + m_pos.x = 0; + m_pos.y = 0; + } else { + unsigned bytes = lines * m_size.x; + char *line = line_pointer(0); + for (unsigned i = 0; i < bytes; ++i) + *line++ = 0; + + m_first = (m_first + lines) % m_size.y; + m_pos.y -= lines; + } + repaint(); + } + + void set_color(uint8_t fg, uint8_t bg) + { + if (!m_palette) return; + + m_bg = m_palette[bg]; + m_fg = m_palette[fg]; + m_attr = (bg << 8) | fg; + } + + void putc(char c) + { + char *line = line_pointer(m_pos.y); + uint16_t *attrs = attr_pointer(m_pos.y); + + + switch (c) { + case '\t': + m_pos.x = (m_pos.x + 4) / 4 * 4; + break; + + case '\r': + m_pos.x = 0; + break; + + case '\n': + m_pos.x = 0; + m_pos.y++; + break; + + default: { + if (line) line[m_pos.x] = c; + if (attrs) attrs[m_pos.x] = m_attr; + + const unsigned x = m_pos.x * m_font.width(); + const unsigned y = m_pos.y * m_font.height(); + m_font.draw_glyph(m_screen, c, m_fg, m_bg, x, y); + + m_pos.x++; } } - // Build the greyscale portion of the table - for (uint8_t i = 0x08; i <= 0xee; i += 10) - m_palette[index++] = m_screen.color(i, i, i); + if (m_pos.x >= m_size.x) { + m_pos.x = m_pos.x % m_size.x; + m_pos.y++; + } - set_color(7, 0); // Grey on black default - m_attrs = reinterpret_cast(m_data + count + palette_size); - for (unsigned i = 0; i < count; ++i) - m_attrs[i] = m_attr; + if (m_pos.y >= m_size.y) { + scroll(1); + line = line_pointer(m_pos.y); + } } - repaint(); +private: + char * line_pointer(unsigned line) + { + if (!m_data) return nullptr; + return m_data + ((m_first + line) % m_size.y) * m_size.x; + } - if (default_console == nullptr) - default_console = this; + uint16_t * attr_pointer(unsigned line) + { + if (!m_attrs) return nullptr; + return m_attrs + ((m_first + line) % m_size.y) * m_size.x; + } + + font m_font; + screen m_screen; + + kutil::coord m_size; + kutil::coord m_pos; + screen::pixel_t m_fg, m_bg; + uint16_t m_attr; + + size_t m_first; + size_t m_length; + + char *m_data; + uint16_t *m_attrs; + screen::pixel_t *m_palette; +}; + +console_out_screen * +console_get_screen_out(const font &f, const screen &s, void *scratch, size_t len) +{ + return nullptr; + //return new console_out_screen(f, s, scratch, len); } + static bool serial_ready() { @@ -93,122 +224,26 @@ serial_write(char c) { outb(COM1, c); } -char * -console::line_pointer(unsigned line) + +console::console() : + m_screen(nullptr) { - if (!m_data) return nullptr; - return m_data + ((m_first + line) % m_size.y) * m_size.x; -} - -uint16_t * -console::attr_pointer(unsigned line) -{ - if (!m_attrs) return nullptr; - return m_attrs + ((m_first + line) % m_size.y) * m_size.x; -} - -void -console::repaint() -{ - m_screen.fill(m_bg); - if (!m_data) return; - - for (unsigned y = 0; y < m_size.y; ++y) { - const char *line = line_pointer(y); - const uint16_t *attrs = attr_pointer(y); - for (unsigned x = 0; x < m_size.x; ++x) { - const uint16_t attr = attrs[x]; - - set_color(static_cast(attr), - static_cast(attr >> 8)); - - m_font.draw_glyph( - m_screen, - line[x] ? line[x] : ' ', - m_fg, - m_bg, - x * m_font.width(), - y * m_font.height()); - } - } } void console::set_color(uint8_t fg, uint8_t bg) { - if (!m_palette) return; - - m_bg = m_palette[bg]; - m_fg = m_palette[fg]; - m_attr = (bg << 8) | fg; + if (m_screen) + m_screen->set_color(fg, bg); } void -console::scroll(unsigned lines) -{ - if (!m_data) { - m_pos.x = 0; - m_pos.y = 0; - } else { - unsigned bytes = lines * m_size.x; - char *line = line_pointer(0); - for (unsigned i = 0; i < bytes; ++i) - *line++ = 0; - - m_first = (m_first + lines) % m_size.y; - m_pos.y -= lines; - } - repaint(); -} - -size_t console::puts(const char *message) { - char *line = line_pointer(m_pos.y); - uint16_t *attrs = attr_pointer(m_pos.y); - size_t count = 0; - while (message && *message) { - const unsigned x = m_pos.x * m_font.width(); - const unsigned y = m_pos.y * m_font.height(); - const char c = *message++; - ++count; - - switch (c) { - case '\t': - m_pos.x = (m_pos.x + 4) / 4 * 4; - break; - - case '\r': - m_pos.x = 0; - break; - - case '\n': - serial_write('\r'); - m_pos.x = 0; - m_pos.y++; - break; - - default: - if (line) line[m_pos.x] = c; - if (attrs) attrs[m_pos.x] = m_attr; - m_font.draw_glyph(m_screen, c, m_fg, m_bg, x, y); - m_pos.x++; - } - - if (m_pos.x >= m_size.x) { - m_pos.x = m_pos.x % m_size.x; - m_pos.y++; - } - - if (m_pos.y >= m_size.y) { - scroll(1); - line = line_pointer(m_pos.y); - } + char c = *message++; + if (m_screen) m_screen->putc(c); serial_write(c); + if (c == '\n') serial_write('\r'); } - - return count; } - - diff --git a/src/kernel/console.h b/src/kernel/console.h index 0efbe9e..ced19ff 100644 --- a/src/kernel/console.h +++ b/src/kernel/console.h @@ -4,20 +4,17 @@ #include "font.h" #include "screen.h" -struct console_data; +class console_out_screen; class console { public: - console(const font &f, const screen &s, void *scratch, size_t len); - - void repaint(); - void scroll(unsigned lines); + console(); void set_color(uint8_t fg, uint8_t bg); - size_t puts(const char *message); - size_t printf(const char *fmt, ...); + void puts(const char *message); + void printf(const char *fmt, ...); template void put_hex(T x); @@ -25,30 +22,20 @@ public: template void put_dec(T x); - static console * get() { return default_console; } + static console * get(); private: - char * line_pointer(unsigned line); - uint16_t * attr_pointer(unsigned line); - - font m_font; - screen m_screen; - - kutil::coord m_size; - kutil::coord m_pos; - screen::pixel_t m_fg, m_bg; - uint16_t m_attr; - - size_t m_first; - size_t m_length; - - char *m_data; - uint16_t *m_attrs; - screen::pixel_t *m_palette; - - static console *default_console; + console_out_screen *m_screen; }; +extern console g_console; +inline console * console::get() { return &g_console; } + + +console_out_screen * console_get_screen_out( + const font &f, const screen &s, void *scratch, size_t len); + + extern const char digits[]; template diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index 3e6ff73..aa8fbf2 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -14,6 +14,9 @@ extern "C" { void kernel_main(popcorn_data *header); } +inline void * operator new (size_t, void *p) throw() { return p; } + +/* console load_console(const popcorn_data *header) { @@ -36,11 +39,12 @@ load_console(const popcorn_data *header) return cons; } +*/ void kernel_main(popcorn_data *header) { - console cons = load_console(header); + console *cons = new (&g_console) console(); memory_initialize_managers( header->memory_map, @@ -50,13 +54,13 @@ kernel_main(popcorn_data *header) interrupts_init(); interrupts_enable(); - cons.puts("Interrupts initialized.\n"); + g_console.puts("Interrupts initialized.\n"); device_manager devices(header->acpi_table); // int x = 1 / 0; // __asm__ __volatile__("int $15"); - cons.puts("boogity!"); + g_console.puts("boogity!"); do_the_set_registers(header); } diff --git a/src/modules/kutil/cpprt.cpp b/src/modules/kutil/cpprt.cpp new file mode 100644 index 0000000..a67495d --- /dev/null +++ b/src/modules/kutil/cpprt.cpp @@ -0,0 +1,3 @@ +extern "C" { + void __cxa_pure_virtual() { while(1); } +}