1 /* hercules.c - hercules console interface */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2001,2002 Free Software Foundation, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #ifdef SUPPORT_HERCULES
22
23 #include <shared.h>
24 #include <hercules.h>
25 #include <term.h>
26
27 /* The position of the cursor. */
28 static int herc_x;
29 static int herc_y;
30
31 static int herc_standard_color = A_NORMAL;
32 static int herc_normal_color = A_NORMAL;
33 static int herc_highlight_color = A_REVERSE;
34 static int herc_current_color = A_NORMAL;
35 static color_state herc_color_state = COLOR_STATE_STANDARD;
36 static int herc_cursor_state = 1;
37
38 /* Write a byte to a port. */
39 static inline void
outb(unsigned short port,unsigned char value)40 outb (unsigned short port, unsigned char value)
41 {
42 asm volatile ("outb %b0, %w1" : : "a" (value), "Nd" (port));
43 }
44
45 static void
herc_set_cursor(void)46 herc_set_cursor (void)
47 {
48 unsigned offset = herc_y * HERCULES_WIDTH + herc_x;
49
50 outb (HERCULES_INDEX_REG, 0x0f);
51 outb (0x80, 0);
52 outb (HERCULES_DATA_REG, offset & 0xFF);
53 outb (0x80, 0);
54
55 outb (HERCULES_INDEX_REG, 0x0e);
56 outb (0x80, 0);
57 outb (HERCULES_DATA_REG, offset >> 8);
58 outb (0x80, 0);
59 }
60
61 void
hercules_putchar(int c)62 hercules_putchar (int c)
63 {
64 switch (c)
65 {
66 case '\b':
67 if (herc_x > 0)
68 herc_x--;
69 break;
70
71 case '\n':
72 herc_y++;
73 break;
74
75 case '\r':
76 herc_x = 0;
77 break;
78
79 case '\a':
80 break;
81
82 default:
83 {
84 volatile unsigned short *video
85 = (unsigned short *) HERCULES_VIDEO_ADDR;
86
87 video[herc_y * HERCULES_WIDTH + herc_x]
88 = (herc_current_color << 8) | c;
89 herc_x++;
90 if (herc_x >= HERCULES_WIDTH)
91 {
92 herc_x = 0;
93 herc_y++;
94 }
95 }
96 break;
97 }
98
99 if (herc_y >= HERCULES_HEIGHT)
100 {
101 volatile unsigned long *video = (unsigned long *) HERCULES_VIDEO_ADDR;
102 int i;
103
104 herc_y = HERCULES_HEIGHT - 1;
105 grub_memmove ((char *) HERCULES_VIDEO_ADDR,
106 (char *) HERCULES_VIDEO_ADDR + HERCULES_WIDTH * 2,
107 HERCULES_WIDTH * (HERCULES_HEIGHT - 1) * 2);
108 for (i = HERCULES_WIDTH * (HERCULES_HEIGHT - 1) / 2;
109 i < HERCULES_WIDTH * HERCULES_HEIGHT / 2;
110 i++)
111 video[i] = 0x07200720;
112 }
113 }
114
115 void
hercules_cls(void)116 hercules_cls (void)
117 {
118 int i;
119 volatile unsigned long *video = (unsigned long *) HERCULES_VIDEO_ADDR;
120
121 for (i = 0; i < HERCULES_WIDTH * HERCULES_HEIGHT / 2; i++)
122 video[i] = 0x07200720;
123
124 herc_x = herc_y = 0;
125 herc_set_cursor ();
126 }
127
128 int
hercules_getxy(void)129 hercules_getxy (void)
130 {
131 return (herc_x << 8) | herc_y;
132 }
133
134 void
hercules_gotoxy(int x,int y)135 hercules_gotoxy (int x, int y)
136 {
137 herc_x = x;
138 herc_y = y;
139 herc_set_cursor ();
140 }
141
142 void
hercules_setcolorstate(color_state state)143 hercules_setcolorstate (color_state state)
144 {
145 switch (state) {
146 case COLOR_STATE_STANDARD:
147 herc_current_color = herc_standard_color;
148 break;
149 case COLOR_STATE_NORMAL:
150 herc_current_color = herc_normal_color;
151 break;
152 case COLOR_STATE_HIGHLIGHT:
153 herc_current_color = herc_highlight_color;
154 break;
155 default:
156 herc_current_color = herc_standard_color;
157 break;
158 }
159
160 herc_color_state = state;
161 }
162
163 void
hercules_setcolor(int normal_color,int highlight_color)164 hercules_setcolor (int normal_color, int highlight_color)
165 {
166 herc_normal_color = normal_color;
167 herc_highlight_color = highlight_color;
168
169 hercules_setcolorstate (herc_color_state);
170 }
171
172 int
hercules_setcursor(int on)173 hercules_setcursor (int on)
174 {
175 int old_state = herc_cursor_state;
176
177 outb (HERCULES_INDEX_REG, 0x0a);
178 outb (0x80, 0);
179 outb (HERCULES_DATA_REG, on ? 0 : (1 << 5));
180 outb (0x80, 0);
181 herc_cursor_state = on;
182
183 return old_state;
184 }
185
186 #endif /* SUPPORT_HERCULES */
187