diff options
Diffstat (limited to '')
| -rw-r--r-- | kernel/kprintf.c | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/kernel/kprintf.c b/kernel/kprintf.c new file mode 100644 index 0000000..20769ea --- /dev/null +++ b/kernel/kprintf.c @@ -0,0 +1,259 @@ +#include <stdbool.h> + +#include "kprintf.h" + +#include "asm_inline.h" + +// #define KDEBUG + +int check_transmission() { + return inb(COM1 + 5) & 0x20; +} + +void write_serial_char(char a) { + while (check_transmission() == 0); + outb(COM1,a); +} + +void write_serial_string(const char* str) +{ + while(*str != '\0') + { + if(*str == '\n') + { + write_serial_char('\r'); + } + write_serial_char(*str); + str++; + } +} + +char* convert_U_integer(uint64_t n, uint16_t base, bool caps) +{ + static char* format = "0123456789abcdef"; + static char* C_format = "0123456789ABCDEF"; + + static char buffer[50]; + char *ptr; + + ptr = &buffer[49]; + *ptr = '\0'; + + do + { + if(caps) + { + *--ptr = C_format[n%base]; + } + else + { + *--ptr = format[n%base]; + } + n /= base; + } while(n != 0); + + return ptr; +} + +void kprintf(const char* str, ...) +{ + va_list args; + + va_start(args, str); + + while(*str) + { + if(*str == '%') + { + #ifdef KDEBUG + write_serial_string("{stradv}"); + #endif + str++; + if(*str == 'i' || *str == 'd') + { + #ifdef KDEBUG + write_serial_string("[INT]"); + #endif + int32_t n = va_arg(args, int32_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'u') + { + #ifdef KDEBUG + write_serial_string("[UINT]"); + #endif + uint32_t n = va_arg(args, uint32_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'x') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint32_t n = va_arg(args, uint32_t); + char* s = convert_U_integer(n, 16, false); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'X') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint32_t n = va_arg(args, uint32_t); + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'l') + { + #ifdef KDEBUG + write_serial_string("[LONG]"); + write_serial_string("{ladv}"); + #endif + str++; + if(*str == 'i' || *str == 'd') + { + #ifdef KDEBUG + write_serial_string("[INT]"); + #endif + int64_t n = va_arg(args, int64_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'u') + { + #ifdef KDEBUG + write_serial_string("[UINT]"); + #endif + uint64_t n = va_arg(args, uint64_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'x') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint64_t n = va_arg(args, uint64_t); + char* s = convert_U_integer(n, 16, false); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'X') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint64_t n = va_arg(args, uint64_t); + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + } + else if(*str == 'h') + { + #ifdef KDEBUG + write_serial_string("[SHORT]"); + write_serial_string("{ladv}"); + #endif + str++; + if(*str == 'i' || *str == 'd') + { + #ifdef KDEBUG + write_serial_string("[INT]"); + #endif + int16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'u') + { + #ifdef KDEBUG + write_serial_string("[UINT]"); + #endif + uint16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'x') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 16, false); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'X') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + } + else if(*str == 'p') + { + #ifdef KDEBUG + write_serial_string("[PTR]"); + #endif + void* p = va_arg(args, void*); + uint64_t n = (uint64_t)p; + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'c') + { + #ifdef KDEBUG + write_serial_string("[CHAR]"); + #endif + char c = va_arg(args, int); + write_serial_char(c); + } + else if(*str == 's') + { + #ifdef KDEBUG + write_serial_string("[STR]"); + #endif + char* s = va_arg(args, char*); + write_serial_string(s); + } + else + { + write_serial_string("\nFailed to write malformed kprintf: "); + write_serial_char(*str); + write_serial_string("\n"); + va_end(args); + return; + } + #ifdef KDEBUG + write_serial_string("{pend}"); + #endif + } + else if(*str == '\n') + { + write_serial_char('\r'); + write_serial_char('\n'); + } + else + { + write_serial_char(*str); + } + #ifdef KDEBUG + write_serial_string("{oadv}"); + #endif + str++; + } + + //write_serial_string(str); + + va_end(args); +} |
