view cos/kernel/video.c @ 280:02385f62f250

Rework from str interface to Instruction interface
author Windel Bouwman
date Sat, 02 Nov 2013 10:03:26 +0100
parents d8627924d40d
children
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)

static int row, col;
uint8_t video_color = 0x1F;

void move_cursor()
{
   uint16_t cursorLocation = row * 80 + col;
   outb(0x3D4, 14);
   outb(0x3D5, cursorLocation >> 8);
   outb(0x3D4, 15);
   outb(0x3D5, cursorLocation & 0xFF);
}

void set_cursor(int newrow, int newcol)
{
   row = newrow;
   col = newcol;
   move_cursor();
}

void get_cursor(int *therow, int *thecol)
{
   *therow = row;
   *thecol = col;
}

void set_color(int forecolor, int backcolor)
{
   video_color = forecolor | (backcolor << 4);
}

void clear_screen()
{
	unsigned char *vidmem = (unsigned char *) VIDMEM;
	int loop;

	for (loop = 0; loop < SCREEN_SIZE; loop++) {
		*vidmem++ = 0x20;
		*vidmem++ = video_color;
	}
}

void init_screen()
{
	clear_screen();
   set_cursor(0, 0);
}

static void scroll_screen()
{
	uint8_t* v;
	int i;
	
   // Shift all lines one up:
	v = (uint8_t*)VIDMEM;
	for (i = 0; i < SCREEN_SIZE; i++ )
   {
		*v = *(v + NUM_COLS*2);
		++v;
		*v = *(v + NUM_COLS*2);
		++v;
	}

   // Clear new line:
   v = (uint8_t*)VIDMEM + SCREEN_SIZE * 2 - NUM_COLS * 2;
	for (i = 0; i < NUM_COLS; i++) 
   {
      *v++ = ' ';
		*v++ = video_color;
	}
}

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++ = video_color;
	}
}

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   = video_color;
		
		if (col < NUM_COLS - 1)
			++col;
		else
			new_line();
	}
   move_cursor();
}

void print_string(const char *s)
{
	while (*s != '\0') 
   {
		print_char(*s++);
	}
}