Mercurial > lcfOS
diff cos/kernel/video.c @ 9:92ace1ca50a8
64 bits kernel without interrupts but with printf in C
author | windel |
---|---|
date | Sun, 13 Nov 2011 12:47:47 +0100 |
parents | |
children | 6129643f5c34 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cos/kernel/video.c Sun Nov 13 12:47:47 2011 +0100 @@ -0,0 +1,101 @@ +#include "kernel.h" + +#define VIDMEM 0xB8000 + +#define NUM_COLS 80 +#define NUM_ROWS 25 +#define SCREEN_SIZE (NUM_COLS * NUM_ROWS) + +#define SCREEN_ATTR 0x0F + +static int row, col; + +void +clear_screen() +{ + unsigned char *vidmem = (unsigned char *) VIDMEM; + int loop; + + for (loop = 0; loop < SCREEN_SIZE; loop++) { + *vidmem++ = 0x20; + *vidmem++ = SCREEN_ATTR; + } +} + +void +init_screen() +{ + row = col = 0; + clear_screen(); +} + + +static void +scroll_screen() +{ + unsigned short* v; + int i; + int n = SCREEN_SIZE; + + for (v = (unsigned short*) VIDMEM, i = 0; i < n; i++ ) { + *v = *(v + NUM_COLS); + ++v; + } + + for (v = (unsigned short*) VIDMEM + n, i = 0; i < NUM_COLS; i++) { + *v++ = SCREEN_ATTR & (0x20 << 8); + } +} + +static void +new_line() +{ + ++row; + col = 0; + if (row == NUM_ROWS) { + scroll_screen(); + row = NUM_ROWS - 1; + } +} + +static void +clear_to_EOL() +{ + int loop; + unsigned char *v = (unsigned char *) ((uint64_t)(VIDMEM + row * NUM_COLS * 2 + col * 2)); + + for (loop = col; loop < NUM_COLS; loop++) { + *v++ = ' '; + *v++ = SCREEN_ATTR; + } +} + +static void +print_char(int c) +{ + unsigned char *v = (unsigned char *) ((uint64_t)(VIDMEM + row * NUM_COLS * 2 + col * 2)); + + switch(c) { + case '\n': + clear_to_EOL(); + new_line(); + break; + default: + *v++ = (unsigned char) c; + *v = SCREEN_ATTR; + + if (col < NUM_COLS - 1) + ++col; + else + new_line(); + } +} + +void +print_string(const char *s) +{ + while (*s != '\0') { + print_char(*s++); + } +} +