diff --git a/src/kernel/lib/havarie.c b/src/kernel/lib/havarie.c index ed3ffd6..bba30c7 100644 --- a/src/kernel/lib/havarie.c +++ b/src/kernel/lib/havarie.c @@ -30,8 +30,8 @@ void print_havarie_msg() { [esi]"=m" (esi), [edi]"=m" (edi), [esp]"=m" (esp), [ebp]"=m" (ebp) ); - tsprintf("eax=0x%x\t\tesi=0x%x\n", eax, esi); - tsprintf("ebx=0x%x\t\tedi=0x%x\n", ebx, edi); - tsprintf("ecx=0x%x\t\tesp=0x%x\n", ecx, esp); - tsprintf("edx=0x%x\t\tebp=0x%x\n", edx, ebp); + tsprintf("eax=0x%08x\t\tesi=0x%08x\n", eax, esi); + tsprintf("ebx=0x%08x\t\tedi=0x%08x\n", ebx, edi); + tsprintf("ecx=0x%08x\t\tesp=0x%08x\n", ecx, esp); + tsprintf("edx=0x%08x\t\tebp=0x%08x\n", edx, ebp); } diff --git a/src/kernel/lib/text_screen.c b/src/kernel/lib/text_screen.c index 3c033ec..4cc0df9 100644 --- a/src/kernel/lib/text_screen.c +++ b/src/kernel/lib/text_screen.c @@ -3,6 +3,7 @@ #include #include "internal/io.h" #include "stdlib.h" +#include "string.h" struct text_screen_char { char character; @@ -16,13 +17,20 @@ static uint8_t cursor_y = 0; #define SCREEN_WIDTH 80 #define SCREEN_HEIGHT 25 -enum printf_format_specifier { +enum printf_format_specifier_type { FORMAT_SPECIFIER_INT, FORMAT_SPECIFIER_UNSIGNED, FORMAT_SPECIFIER_HEXADECIMAL, FORMAT_SPEFICIER_UNKNOWN }; +struct printf_format_specifier { + enum printf_format_specifier_type type; + + int field_size; + char padding_char; +}; + void tsinit(void) { outb(0x3D4, 0x0A); outb(0x3D5, 0x20); @@ -90,50 +98,101 @@ void tsputs(const char* ch, uint8_t color) { } static -const char* decode_format_spefifier(const char* str, enum printf_format_specifier* data) { +const char* decode_format_specifier_flag(const char* str, struct printf_format_specifier* data) { + switch (*str) { + case '0': + data->padding_char = '0'; + return str+1; + } + + data->padding_char = '\0'; + return str; +} + +static +const char* decode_format_specifier_field_width(const char* str, struct printf_format_specifier* data) { + char tmp[16]; + + int i; + for(i = 0; i < 15; i++) { + if (*str < '0' || *str > '9') { + break; + } + + tmp[i] = *str++; + } + tmp[0] = '8'; + tmp[1] = 0; + tmp[i] = '\0'; + + data->field_size = atoi(tmp); + return str; +} + +static +const char* decode_format_spefifier(const char* str, struct printf_format_specifier* data) { switch (*str) { case 'd': case 'i': - *data = FORMAT_SPECIFIER_INT; + data->type = FORMAT_SPECIFIER_INT; return str+1; case 'o': case 'u': - *data = FORMAT_SPECIFIER_UNSIGNED; + data->type = FORMAT_SPECIFIER_UNSIGNED; return str+1; case 'x': case 'X': - *data = FORMAT_SPECIFIER_HEXADECIMAL; + data->type = FORMAT_SPECIFIER_HEXADECIMAL; return str+1; } - *data = FORMAT_SPEFICIER_UNKNOWN; + data->type = FORMAT_SPEFICIER_UNKNOWN; return str; } +static +void put_formated_string(const char* str, const struct printf_format_specifier* specifier) { + // Padding + if (specifier->padding_char != '\0') { + size_t length = strlen(str); + + while ((int)length < specifier->field_size) { + tsputch(specifier->padding_char, TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE); + length++; + } + } + + tsputs(str, TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE); +} + static const char* handle_format_specifier(const char* str, va_list* args) { str++; char tmp[16]; - enum printf_format_specifier specifier; + struct printf_format_specifier specifier; + + str = decode_format_specifier_flag(str, &specifier); + str = decode_format_specifier_field_width(str, &specifier); + str = decode_format_spefifier(str, &specifier); - switch (specifier) { + switch (specifier.type) { case FORMAT_SPECIFIER_INT: { int value = va_arg(*args, int); - tsputs(itoa(value, tmp, 10), TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE); + put_formated_string(itoa(value, tmp, 10), &specifier); } break; case FORMAT_SPECIFIER_UNSIGNED: { unsigned int value = va_arg(*args, unsigned int); - tsputs(utoa(value, tmp, 10), TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE); + put_formated_string(utoa(value, tmp, 10), &specifier); } break; case FORMAT_SPECIFIER_HEXADECIMAL: { unsigned int value = va_arg(*args, unsigned int); - tsputs(utoa(value, tmp, 16), TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE); + put_formated_string(utoa(value, tmp, 16), &specifier); } break; default: return str; }