Add kprintf with decimal support
This commit is contained in:
parent
fa87fe8950
commit
81c07553e6
102
kernel/kernel.c
102
kernel/kernel.c
|
@ -1,6 +1,7 @@
|
|||
#include "multiboot.h"
|
||||
#include "psf.h"
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue