#include "hos_types.h" #include "hos_defines.h" #include "kio.h" #include "string.h" #include "portio.h" #include #include /* va_*() */ static void fmt_d2a(char * buf, int val); static void fmt_u2a(char * buf, unsigned int val); static void fmt_ll2a(char * buf, long long val); static void fmt_ull2a(char * buf, unsigned long long val); static void fmt_x2a(char * buf, unsigned int val); static void fmt_xl2a(char * buf, unsigned long long val); static void fmt_o2a(char * buf, unsigned int val); static int cursor_x, cursor_y; static void writeCursorPosition(int x, int y) { u16_t pos = 80 * y + x; outportb(0x3D4, 0x0E); outportb(0x3D5, pos >> 8); outportb(0x3D4, 0x0F); outportb(0x3D5, pos); } extern "C" { void kio_bootstrap() { cursor_x = 0; cursor_y = 9; writeCursorPosition(cursor_x, cursor_y); } void kprintf(const char * fmt, ...) { va_list args; va_start(args, fmt); kvprintf(fmt, args); va_end(args); } void kvprintf(const char * fmt, va_list args) { char tmpbuf[25]; for ( ; *fmt; fmt++) { if (*fmt == '%') { fmt++; if (*fmt) { int width = 0; char pad = ' '; if (*fmt == '0') { pad = '0'; fmt++; } if ('1' <= *fmt && *fmt <= '9') { width = *fmt - '0'; /* TODO: finish */ } switch (*fmt) { case 'c': kputc(va_arg(args, int)); break; case 'd': fmt_d2a(tmpbuf, va_arg(args, int)); kputs(tmpbuf); break; case 'l': fmt_ll2a(tmpbuf, va_arg(args, long long)); kputs(tmpbuf); break; case 'L': fmt_ull2a(tmpbuf, va_arg(args, unsigned long long)); kputs(tmpbuf); break; case 'o': fmt_o2a(tmpbuf, va_arg(args, unsigned int)); kputs(tmpbuf); break; case 's': kputs(va_arg(args, char *)); break; case 'u': fmt_u2a(tmpbuf, va_arg(args, unsigned int)); kputs(tmpbuf); break; case 'x': fmt_x2a(tmpbuf, va_arg(args, unsigned int)); kputs(tmpbuf); break; case 'X': fmt_xl2a(tmpbuf, va_arg(args, unsigned long long)); kputs(tmpbuf); break; case '%': kputc('%'); break; } } } else { kputc(*fmt); } if (!*fmt) { break; } } } void kputc(char c) { u16_t * console_memory = (u16_t *) CONSOLE_MEMORY; console_memory += 80 * cursor_y + cursor_x; switch (c) { case '\t': { int to_advance = 8 - (cursor_x & 0x3); while (to_advance--) { *console_memory++ = 0x0720; } } break; case '\n': cursor_x = 0; cursor_y++; break; default: *console_memory = 0x0700 | (c & 0xFF); cursor_x++; break; } if (cursor_x >= 80) { cursor_x = 0; cursor_y++; } if (cursor_y >= 25) { memcpy((u8_t *) CONSOLE_MEMORY, (u8_t *) (CONSOLE_MEMORY + 80 * 2), 2 * 80 * 24); memsetw((u16_t *) (CONSOLE_MEMORY + 2 * 80 * 24), 0x0720, 80); cursor_y = 24; } writeCursorPosition(cursor_x, cursor_y); } void kputs(const char * s) { while (*s) { kputc(*s); s++; } } } /* extern "C" */ static void fmt_d2a(char * buf, int val) { if (val == INT_MIN) { strcpy(buf, "-2147483648"); } else { if (val < 0) { *buf++ = '-'; val = -val; } fmt_u2a(buf, (unsigned int) val); } } static void fmt_u2a(char * buf, unsigned int val) { bool printing = false; for (unsigned int div = 1000000000; div >= 1; div /= 10) { unsigned int n = val / div; if (n) { printing = true; } if (printing) { *buf++ = '0' + n; } val -= n * div; } *buf = '\0'; } static void fmt_ll2a(char * buf, long long val) { if (val == LONG_LONG_MIN) { strcpy(buf, "-9223372036854775808"); } else { if (val < 0) { *buf++ = '-'; val = -val; } fmt_ull2a(buf, (unsigned long long) val); } } static void fmt_ull2a(char * buf, unsigned long long val) { bool printing = false; for (unsigned long long div = 10000000000000000000ull; div >= 1; div /= 10) { unsigned long long n = val / div; if (n) { printing = true; } if (printing) { *buf++ = '0' + n; } val -= n * div; } *buf = '\0'; } static void fmt_x2a(char * buf, unsigned int val) { bool printing = false; for (int s = 28; s >= 0; s -= 4) { unsigned int n = (val >> s) & 0xF; if (n) { printing = true; } if (printing) { *buf++ = "0123456789abcdef"[n]; } } *buf = '\0'; } static void fmt_xl2a(char * buf, unsigned long long val) { fmt_x2a(buf, val >> 32); buf += strlen(buf); bool printing = ( (val >> 32) != 0 ); for (int s = 28; s >= 0; s -= 4) { unsigned int n = (val >> s) & 0xF; if (n) { printing = true; } if (printing) { *buf++ = "0123456789abcdef"[n]; } } *buf = '\0'; } static void fmt_o2a(char * buf, unsigned int val) { bool printing = false; for (int s = 30; s >= 0; s -= 3) { unsigned int n = (val >> s) & 0x7; if (n) { printing = true; } if (printing) { *buf++ = "01234567"[n]; } } *buf = '\0'; }