#include #include #include #include #include "klog.h" #include "kfont.h" #include "fb.h" #include "fb_text.h" #include "stream.h" #include "hos_printf.h" #include "mem.h" static struct { size_t console_width; size_t console_height; size_t x; size_t y; bool need_shift; } klog; static void shift_line(void) { uint32_t * fb = fb_addr(); uint32_t w = fb_width(); size_t console_fb_line_words = w * kfont.line_height; for (size_t row = 0u; row < klog.console_height; row++) { memcpy32(fb, fb + console_fb_line_words, console_fb_line_words); fb += console_fb_line_words; } fb_fill(0, kfont.line_height * (klog.console_height - 1u), w, kfont.line_height, 0u, 0x2Cu, 0x55u); } static void klog_fb_write1(char c) { if (klog.need_shift) { shift_line(); klog.need_shift = false; } if (c == '\n') { if (klog.y == (klog.console_height - 1u)) { klog.need_shift = true; } else { klog.y++; } klog.x = 0u; } else { int px = klog.x * kfont.advance; int py = klog.y * kfont.line_height; fb_text_render_char(c, px, py, 0xFFu, 0x80u, 0u); klog.x++; if (klog.x == klog.console_width) { if (klog.y == (klog.console_height - 1u)) { klog.need_shift = true; } else { klog.y++; } klog.x = 0u; } } } static void klog_fb_write(const char * src, size_t length) { for (size_t i = 0u; i < length; i++) { klog_fb_write1(src[i]); } } static const stream_t klog_fb_stream = { klog_fb_write, klog_fb_write1, }; void klog_init(void) { klog.console_width = fb_width() / kfont.advance; klog.console_height = fb_height() / kfont.line_height; klog.x = 0u; klog.y = 0u; klog.need_shift = false; fb_fill(0, 0, fb_width(), fb_height(), 0u, 0x2Cu, 0x55u); } void klog_printf(const char * fmt, ...) { va_list va; va_start(va, fmt); hos_vprintf(&klog_fb_stream, fmt, va); va_end(va); }