blob: 120828a849768462c8f05b0fcd47a41c5358d7d6 [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
2 *
3 * modified from original freebios code
4 * by Steve M. Gehlbach <steve@kesa.com>
5 *
6 */
7
8#include <arch/io.h>
9#include <string.h>
10#include <pc80/vga.h>
11#include <console/console.h>
12
Li-Ta Lobec039c2005-01-19 23:19:26 +000013/* The video buffer, should be replaced by symbol in ldscript.ld */
14static char *vidmem;
15
Eric Biederman8ca8d762003-04-22 19:02:15 +000016int vga_line, vga_col;
17
Stefan Reinauer7ce8c542005-12-02 21:52:30 +000018int vga_inited = 0; // it will be changed in pci_rom.c
Yinghai Lu688238a2005-01-14 21:54:16 +000019
20static int vga_console_inited = 0;
21
Eric Biederman8ca8d762003-04-22 19:02:15 +000022#define VIDBUFFER 0xB8000;
23
24static void memsetw(void *s, int c, unsigned int n)
25{
26 int i;
27 u16 *ss = (u16 *) s;
28
29 for (i = 0; i < n; i++) {
30 ss[i] = ( u16 ) c;
31 }
32}
33
34static void vga_init(void)
35{
Eric Biederman8ca8d762003-04-22 19:02:15 +000036 // these are globals
37 vga_line = 0;
38 vga_col = 0;
Stefan Reinauer749c05e2008-08-01 11:38:23 +000039 vidmem = (char *) VIDBUFFER;
Eric Biederman8ca8d762003-04-22 19:02:15 +000040
41 // mainboard or chip specific init routines
42 // also loads font
43 vga_hardware_fixup();
44
45 // set attributes, char for entire screen
46 // font should be previously loaded in
47 // device specific code (vga_hardware_fixup)
48 memsetw(vidmem, VGA_ATTR_CLR_WHT, 2*1024); //
49}
50
51static void vga_scroll(void)
52{
53 int i;
54
55 memcpy(vidmem, vidmem + COLS * 2, (LINES - 1) * COLS * 2);
56 for (i = (LINES - 1) * COLS * 2; i < LINES * COLS * 2; i += 2)
57 vidmem[i] = ' ';
58}
59
60static void vga_tx_byte(unsigned char byte)
61{
Yinghai Lu688238a2005-01-14 21:54:16 +000062 if (!vga_inited) {
63 return;
64 }
65
66 if(!vga_console_inited) {
67 vga_init();
68 vga_console_inited = 1;
69 }
70
Eric Biederman8ca8d762003-04-22 19:02:15 +000071 if (byte == '\n') {
72 vga_line++;
73 vga_col = 0;
74
75 } else if (byte == '\r') {
76 vga_col = 0;
77
78 } else if (byte == '\b') {
79 vga_col--;
80
81 } else if (byte == '\t') {
82 vga_col += 4;
83
84 } else if (byte == '\a') {
85 //beep
Yinghai Lu688238a2005-01-14 21:54:16 +000086// beep(500);
87 ;
Eric Biederman8ca8d762003-04-22 19:02:15 +000088 } else {
89 vidmem[((vga_col + (vga_line *COLS)) * 2)] = byte;
90 vidmem[((vga_col + (vga_line *COLS)) * 2) +1] = VGA_ATTR_CLR_WHT;
91 vga_col++;
92 }
93 if (vga_col < 0) {
94 vga_col = 0;
95 }
96 if (vga_col >= COLS) {
97 vga_line++;
98 vga_col = 0;
99 }
100 if (vga_line >= LINES) {
101 vga_scroll();
102 vga_line--;
103 }
104 // move the cursor
105 write_crtc((vga_col + (vga_line *COLS)) >> 8, CRTC_CURSOR_HI);
106 write_crtc((vga_col + (vga_line *COLS)) & 0x0ff, CRTC_CURSOR_LO);
107}
108
Stefan Reinauerbf873e42007-10-24 14:42:12 +0000109static const struct console_driver vga_console __console ={
Yinghai Lu688238a2005-01-14 21:54:16 +0000110 .init = 0,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000111 .tx_byte = vga_tx_byte,
Greg Watsone54d55b2004-03-13 03:40:51 +0000112 .rx_byte = 0,
113 .tst_byte = 0,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000114};