248 lines
5.5 KiB
C++
248 lines
5.5 KiB
C++
|
|
#include "hos_types.h"
|
|
#include "hos_defines.h"
|
|
#include "kio.h"
|
|
#include "string.h"
|
|
|
|
#include <limits.h>
|
|
#include <stdarg.h> /* 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_o2a(char * buf, unsigned int val);
|
|
|
|
static int cursor_x, cursor_y;
|
|
|
|
extern "C" {
|
|
|
|
void kio_bootstrap()
|
|
{
|
|
cursor_x = 0;
|
|
cursor_y = 9;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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 '%':
|
|
kputc('%');
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
kputc(*fmt);
|
|
}
|
|
}
|
|
}
|
|
|
|
void kputc(char c)
|
|
{
|
|
u16_t * console_memory = (u16_t *) (CONSOLE_MEMORY + KERNEL_OFFSET);
|
|
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);
|
|
}
|
|
}
|
|
|
|
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_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';
|
|
}
|