view 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 source

#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++);
	}
}