diff options
author | marcus <marcus> | 2003-07-26 17:26:09 +0000 |
---|---|---|
committer | marcus <marcus> | 2003-07-26 17:26:09 +0000 |
commit | 35c35373d1f6ee353b67fc2e596b01d9b49f4be8 (patch) | |
tree | d425cc345ca97b36996e91345fdc4b2bdbb223fa /laden/output-vga.c |
Initial check-in.
Diffstat (limited to 'laden/output-vga.c')
-rw-r--r-- | laden/output-vga.c | 139 |
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 + }; |