From 81c07553e62efdc5de61f72b388878d50b8dbba9 Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Tue, 3 May 2022 00:59:24 +0300 Subject: [PATCH] Add kprintf with decimal support --- kernel/kernel.c | 102 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 9 deletions(-) diff --git a/kernel/kernel.c b/kernel/kernel.c index 374400a..110e3cf 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,6 +1,7 @@ #include "multiboot.h" #include "psf.h" #include +#include #if defined (__linux__) #error "You are not using a cross-compiler, you will most certainly run into trouble" @@ -22,6 +23,9 @@ multiboot_info_t *mbi; uint32_t console_y; uint32_t console_x; +uint32_t console_max_y; +uint32_t console_max_x; + #define PIXEL uint32_t #define CONSOLE_BG 0 @@ -52,30 +56,110 @@ void putchar (uint16_t c, int32_t cx, int32_t cy, uint32_t fg, uint32_t bg) } +void console_push() +{ + // TODO: implement console pushing +} + +void console_puts(uint16_t ch) +{ + if (ch == '\n' || console_x > console_max_x) { + console_x = 0; + console_y++; + return; + } + + if (console_y > console_max_y) + console_push(); + + putchar((uint16_t) ch, console_x, console_y, CONSOLE_FG, CONSOLE_BG); + console_x++; +} + void console_write(char *str) { for (int idx = 0; str[idx] != '\0'; idx++ ) { - if (str[idx] == '\n') { - console_x = 0; - console_y++; - continue; - } - putchar((uint16_t) str[idx], console_x, console_y, CONSOLE_FG, CONSOLE_BG); - console_x++; + console_puts(str[idx]); } } -void console_init() +void console_init(multiboot_info_t *mbi) { + psf_font_t *font = (psf_font_t *)&consolefonts_binary__start; + + console_max_y = mbi->framebuffer_height / font->height - 1; + console_max_x = mbi->framebuffer_width / font->width - 1; + console_x = 0; console_y = 0; } +void convert(int num, int base, char *buf, int bufsize) +{ + int idx = 0; + buf[idx] = '\0'; + + do { + /* Avoid buffer overrun */ + if (idx == bufsize - 1) + break; + + buf[idx] = (num % base) + '0'; + num /= base; + idx++; + } while(num != 0); + + buf[idx] = '\0'; + + for (int i = 0; i < idx / 2; i++) { + int tmp = buf[i]; + buf[i] = buf[idx-1]; + buf[idx-1] = tmp; + } +} + +void kprintf(char *format, ...) +{ + va_list arg; + va_start(arg, format); + + char buffer[50]; + int i; + + for (int idx = 0; format[idx] != '\0'; idx++) { + while (format[idx] != '%') { + if (format[idx] == '\0') + break; + + console_puts(format[idx]); + idx++; + } + idx++; + switch (format[idx]) { + case 'd': + i = va_arg(arg, int); + if (i < 0) { + i = -i; + console_puts('-'); + } + + convert(i, 10, buffer, 50); + console_write(buffer); + break; + } + } + + va_end(arg); +} + void kernel_main (uint32_t multiboot_struct_addr) { mbi = (multiboot_info_t *)multiboot_struct_addr; fb = (char *)mbi->framebuffer_addr; scanline = mbi->framebuffer_pitch; - console_write("Hello World!"); + console_init(mbi); + kprintf("Console width is %d\n", mbi->framebuffer_width); + // TODO: Test line wrapping + //console_write("Hello World! 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890"); }