summaryrefslogtreecommitdiff
path: root/laden/output-vga.c
diff options
context:
space:
mode:
authormarcus <marcus>2003-07-26 17:26:09 +0000
committermarcus <marcus>2003-07-26 17:26:09 +0000
commit35c35373d1f6ee353b67fc2e596b01d9b49f4be8 (patch)
treed425cc345ca97b36996e91345fdc4b2bdbb223fa /laden/output-vga.c
Initial check-in.
Diffstat (limited to 'laden/output-vga.c')
-rw-r--r--laden/output-vga.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/laden/output-vga.c b/laden/output-vga.c
new file mode 100644
index 0000000..251316d
--- /dev/null
+++ b/laden/output-vga.c
@@ -0,0 +1,139 @@
+/* output-vga.c - A VGA output driver.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include "laden.h"
+
+#include <sys/io.h>
+
+#define VGA_VIDEO_MEM_BASE_ADDR 0x0B8000
+#define VGA_VIDEO_MEM_LENGTH 0x004000
+
+/* The default attribute is light grey on black. */
+#define VGA_DEF_ATTRIBUTE 7
+
+#define VGA_COLUMNS 80
+#define VGA_ROWS 25
+
+/* The CRTC Registers. XXX Depends on the I/O Address Select field.
+ However, the only need to use the other values is for compatibility
+ with monochrome adapters. */
+#define VGA_CRT_ADDR_REG 0x3d4
+#define VGA_CRT_DATA_REG 0x3d5
+
+/* The cursor position subregisters. */
+#define VGA_CRT_CURSOR_HIGH 0x0e
+#define VGA_CRT_CURSOR_LOW 0x0f
+
+
+/* Set the cursor position to POS, which is (x_pos + y_pos * width). */
+static void
+vga_set_cursor_pos (unsigned int pos)
+{
+ outb (VGA_CRT_CURSOR_HIGH, VGA_CRT_ADDR_REG);
+ outb (pos >> 8, VGA_CRT_DATA_REG);
+ outb (VGA_CRT_CURSOR_LOW, VGA_CRT_ADDR_REG);
+ outb (pos & 0xff, VGA_CRT_DATA_REG);
+}
+
+
+/* Set the cursor position to POS, which is (x_pos + y_pos * width). */
+static unsigned int
+vga_get_cursor_pos (void)
+{
+ unsigned int pos;
+
+ outb (VGA_CRT_CURSOR_HIGH, VGA_CRT_ADDR_REG);
+ pos = inb (VGA_CRT_DATA_REG) << 8;
+ outb (VGA_CRT_CURSOR_LOW, VGA_CRT_ADDR_REG);
+ pos |= inb (VGA_CRT_DATA_REG) & 0xff;
+
+ return pos;
+}
+
+
+/* Global variables. */
+
+static int col;
+static int row;
+static char *video;
+
+
+static void
+vga_init (void)
+{
+ unsigned int pos = vga_get_cursor_pos ();
+ col = pos % VGA_COLUMNS;
+ row = pos / VGA_COLUMNS;
+ video = (char *) VGA_VIDEO_MEM_BASE_ADDR;
+}
+
+
+static void
+vga_putchar (int chr)
+{
+ unsigned int pos;
+
+ if (chr == '\n')
+ {
+ col = 0;
+ row++;
+ }
+ else
+ {
+ pos = row * VGA_COLUMNS + col;
+ video[2 * pos] = chr & 0xff;
+ video[2 * pos + 1] = VGA_DEF_ATTRIBUTE;
+ col++;
+ if (col == VGA_COLUMNS)
+ {
+ col = 0;
+ row++;
+ }
+ }
+
+ if (row == VGA_ROWS)
+ {
+ int i;
+
+ row--;
+ for (i = 0; i < VGA_COLUMNS * row; i++)
+ {
+ video[2 * i] = video[2 * (i + VGA_COLUMNS)];
+ video[2 * i + 1] = video[2 * (i + VGA_COLUMNS) + 1];
+ }
+ for (i = VGA_COLUMNS * row; i < VGA_COLUMNS * VGA_ROWS; i++)
+ {
+ video[2 * i] = ' ';
+ video[2 * i + 1] = VGA_DEF_ATTRIBUTE;
+ }
+ }
+
+ pos = row * VGA_COLUMNS + col;
+ vga_set_cursor_pos (pos);
+}
+
+
+struct output_driver vga_output =
+ {
+ "vga",
+ vga_init,
+ 0, /* deinit */
+ vga_putchar
+ };