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