#include "prekern.h"
extern vaddr_t atdevbase;
#define CONS_WID 80
#define CONS_HEI 25
static char *cons_start;
static size_t cons_x, cons_y;
static char cons_buffer[CONS_WID * 2 * CONS_HEI];
void init_cons(void)
{
cons_start = (char *)atdevbase + (0xB8000 - IOM_BEGIN);
cons_x = 0;
cons_y = 0;
}
static void check_scroll(void)
{
char *src, *dst;
size_t i;
if (cons_y != CONS_HEI)
return;
for (i = 0; i < CONS_HEI-1; i++) {
dst = &cons_buffer[0] + i * (CONS_WID * 2);
src = &cons_buffer[0] + (i + 1) * (CONS_WID * 2);
memcpy(dst, src, (CONS_WID * 2));
}
memset(&cons_buffer[0] + (CONS_WID * 2) * (CONS_HEI-1), 0,
(CONS_WID * 2));
cons_y--;
memcpy(cons_start, &cons_buffer[0], CONS_WID * 2 * CONS_HEI);
}
static void putc(int color, char c)
{
char *ptr, *scr;
if (c == '\n') {
cons_x = 0;
cons_y++;
check_scroll();
} else {
if (cons_x + 1 == CONS_WID) {
cons_x = 0;
cons_y++;
check_scroll();
}
ptr = (cons_start + 2 * cons_x + 160 * cons_y);
scr = (cons_buffer + 2 * cons_x + 160 * cons_y);
ptr[0] = scr[0] = c;
ptr[1] = scr[1] = color;
cons_x++;
}
}
void print_ext(int color, char *buf)
{
size_t i;
for (i = 0; buf[i] != '\0'; i++) {
putc(color, buf[i]);
}
}
void print(char *buf)
{
print_ext(WHITE_ON_BLACK, buf);
}
void print_state(state_t state, char *buf)
{
print("[");
switch (state)
{
case STATE_NORMAL:
print_ext(GREEN_ON_BLACK, "+");
break;
case STATE_ERROR:
print_ext(RED_ON_BLACK, "!");
break;
case STATE_WARNING:
print_ext(YELLOW_ON_BLACK, "*");
break;
default:
print_ext(WHITE_ON_BLACK, "?");
break;
}
print("] ");
print(buf);
print("\n");
}
void print_banner(void)
{
char *banner =
" __________ __ \n"
" \\______ \\_______ ____ | | __ ___________ ____ \n"
" | ___/\\_ __ \\_/ __ \\| |/ // __ \\_ __ \\/ \\ \n"
" | | | | \\/\\ ___/| <\\ ___/| | \\/ | \\\n"
" |____| |__| \\___ >__|_ \\\\___ >__| |___| /\n"
" \\/ \\/ \\/ \\/ Version 1.0\n"
;
print(banner);
}