]>
Commit | Line | Data |
---|---|---|
ca25d8f0 | 1 | /* |
2 | * GRUB -- GRand Unified Bootloader | |
4e7db17b | 3 | * Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc. |
ca25d8f0 | 4 | * |
5 | * GRUB is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * GRUB is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
76679cd3 | 19 | #include <grub/dl.h> |
93c06ff9 | 20 | #include <grub/cpu/io.h> |
ca25d8f0 | 21 | #include <grub/types.h> |
967828eb | 22 | #include <grub/vga.h> |
c35fc5bd VS |
23 | #include <grub/term.h> |
24 | ||
25 | /* MODESET is used for testing to force monochrome or colour mode. | |
26 | You shouldn't use mda_text on vga. | |
27 | */ | |
28 | #ifdef MODESET | |
29 | #include <grub/machine/int.h> | |
30 | #endif | |
ca25d8f0 | 31 | |
7acd2ae1 | 32 | #if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) |
036985b8 VS |
33 | #include <grub/machine/console.h> |
34 | #endif | |
35 | ||
e745cf0c VS |
36 | GRUB_MOD_LICENSE ("GPLv3+"); |
37 | ||
ca25d8f0 | 38 | #define COLS 80 |
39 | #define ROWS 25 | |
40 | ||
41 | static int grub_curr_x, grub_curr_y; | |
42 | ||
93c06ff9 VS |
43 | #ifdef __mips__ |
44 | #define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb00b8000) | |
c35fc5bd VS |
45 | #define cr_read grub_vga_cr_read |
46 | #define cr_write grub_vga_cr_write | |
47 | #elif defined (MODE_MDA) | |
48 | #define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb0000) | |
49 | #define cr_read grub_vga_cr_bw_read | |
50 | #define cr_write grub_vga_cr_bw_write | |
51 | static grub_uint8_t cur_color; | |
93c06ff9 | 52 | #else |
4e7db17b | 53 | #define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb8000) |
c35fc5bd VS |
54 | #define cr_read grub_vga_cr_read |
55 | #define cr_write grub_vga_cr_write | |
93c06ff9 | 56 | #endif |
ca25d8f0 | 57 | |
c35fc5bd VS |
58 | static grub_uint8_t cur_color = 0x7; |
59 | ||
ca25d8f0 | 60 | static void |
61 | screen_write_char (int x, int y, short c) | |
62 | { | |
5e3535ae | 63 | VGA_TEXT_SCREEN[y * COLS + x] = grub_cpu_to_le16 (c); |
ca25d8f0 | 64 | } |
65 | ||
66 | static short | |
67 | screen_read_char (int x, int y) | |
68 | { | |
5e3535ae | 69 | return grub_le_to_cpu16 (VGA_TEXT_SCREEN[y * COLS + x]); |
ca25d8f0 | 70 | } |
71 | ||
be7ac41e | 72 | static void |
73 | update_cursor (void) | |
74 | { | |
75 | unsigned int pos = grub_curr_y * COLS + grub_curr_x; | |
c35fc5bd VS |
76 | cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH); |
77 | cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW); | |
be7ac41e | 78 | } |
79 | ||
ca25d8f0 | 80 | static void |
97eab917 | 81 | inc_y (void) |
ca25d8f0 | 82 | { |
83 | grub_curr_x = 0; | |
84 | if (grub_curr_y < ROWS - 1) | |
85 | grub_curr_y++; | |
86 | else | |
87 | { | |
88 | int x, y; | |
5410ebd1 | 89 | for (y = 0; y < ROWS - 1; y++) |
ca25d8f0 | 90 | for (x = 0; x < COLS; x++) |
91 | screen_write_char (x, y, screen_read_char (x, y + 1)); | |
5410ebd1 | 92 | for (x = 0; x < COLS; x++) |
c35fc5bd | 93 | screen_write_char (x, ROWS - 1, ' ' | (cur_color << 8)); |
ca25d8f0 | 94 | } |
95 | } | |
96 | ||
97 | static void | |
97eab917 | 98 | inc_x (void) |
ca25d8f0 | 99 | { |
ffa8e3d2 | 100 | if (grub_curr_x >= COLS - 1) |
ca25d8f0 | 101 | inc_y (); |
102 | else | |
103 | grub_curr_x++; | |
104 | } | |
105 | ||
34fac099 | 106 | static void |
58664b94 VS |
107 | grub_vga_text_putchar (struct grub_term_output *term __attribute__ ((unused)), |
108 | const struct grub_unicode_glyph *c) | |
ca25d8f0 | 109 | { |
34fac099 | 110 | switch (c->base) |
ca25d8f0 | 111 | { |
112 | case '\b': | |
113 | if (grub_curr_x != 0) | |
114 | screen_write_char (grub_curr_x--, grub_curr_y, ' '); | |
115 | break; | |
116 | case '\n': | |
117 | inc_y (); | |
118 | break; | |
119 | case '\r': | |
120 | grub_curr_x = 0; | |
121 | break; | |
122 | default: | |
34fac099 | 123 | screen_write_char (grub_curr_x, grub_curr_y, |
c35fc5bd | 124 | c->base | (cur_color << 8)); |
ca25d8f0 | 125 | inc_x (); |
126 | } | |
be7ac41e | 127 | |
128 | update_cursor (); | |
ca25d8f0 | 129 | } |
130 | ||
76679cd3 | 131 | static grub_uint16_t |
58664b94 | 132 | grub_vga_text_getxy (struct grub_term_output *term __attribute__ ((unused))) |
ca25d8f0 | 133 | { |
134 | return (grub_curr_x << 8) | grub_curr_y; | |
135 | } | |
136 | ||
76679cd3 | 137 | static void |
58664b94 VS |
138 | grub_vga_text_gotoxy (struct grub_term_output *term __attribute__ ((unused)), |
139 | grub_uint8_t x, grub_uint8_t y) | |
ca25d8f0 | 140 | { |
141 | grub_curr_x = x; | |
142 | grub_curr_y = y; | |
be7ac41e | 143 | update_cursor (); |
ca25d8f0 | 144 | } |
145 | ||
76679cd3 | 146 | static void |
58664b94 | 147 | grub_vga_text_cls (struct grub_term_output *term) |
ca25d8f0 | 148 | { |
149 | int i; | |
150 | for (i = 0; i < ROWS * COLS; i++) | |
c35fc5bd | 151 | VGA_TEXT_SCREEN[i] = grub_cpu_to_le16 (' ' | (cur_color << 8)); |
58664b94 | 152 | grub_vga_text_gotoxy (term, 0, 0); |
ca25d8f0 | 153 | } |
154 | ||
76679cd3 | 155 | static void |
58664b94 VS |
156 | grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)), |
157 | int on) | |
ca25d8f0 | 158 | { |
be7ac41e | 159 | grub_uint8_t old; |
c35fc5bd | 160 | old = cr_read (GRUB_VGA_CR_CURSOR_START); |
e14a6184 | 161 | if (on) |
c35fc5bd VS |
162 | cr_write (old & ~GRUB_VGA_CR_CURSOR_START_DISABLE, |
163 | GRUB_VGA_CR_CURSOR_START); | |
e14a6184 | 164 | else |
c35fc5bd VS |
165 | cr_write (old | GRUB_VGA_CR_CURSOR_START_DISABLE, |
166 | GRUB_VGA_CR_CURSOR_START); | |
ca25d8f0 | 167 | } |
76679cd3 | 168 | |
bc3a2f31 | 169 | static grub_err_t |
d187a1c3 | 170 | grub_vga_text_init_real (struct grub_term_output *term) |
bc3a2f31 | 171 | { |
c35fc5bd VS |
172 | #ifdef MODESET |
173 | struct grub_bios_int_registers regs; | |
174 | regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; | |
175 | ||
176 | #ifdef MODE_MDA | |
177 | regs.eax = 7; | |
178 | #else | |
179 | regs.eax = 3; | |
180 | #endif | |
181 | regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; | |
182 | grub_bios_interrupt (0x10, ®s); | |
183 | #endif | |
58664b94 | 184 | grub_vga_text_cls (term); |
bc3a2f31 | 185 | return 0; |
186 | } | |
187 | ||
c35fc5bd | 188 | static grub_err_t |
d187a1c3 | 189 | grub_vga_text_fini_real (struct grub_term_output *term) |
c35fc5bd VS |
190 | { |
191 | #ifdef MODESET | |
192 | struct grub_bios_int_registers regs; | |
193 | regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; | |
194 | ||
195 | regs.eax = 3; | |
196 | regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; | |
197 | grub_bios_interrupt (0x10, ®s); | |
198 | #endif | |
199 | grub_vga_text_cls (term); | |
200 | return 0; | |
201 | } | |
202 | ||
203 | static grub_uint16_t | |
204 | grub_vga_text_getwh (struct grub_term_output *term __attribute__ ((unused))) | |
205 | { | |
206 | return (80 << 8) | 25; | |
207 | } | |
208 | ||
209 | #ifndef MODE_MDA | |
210 | ||
211 | static void | |
bc136973 VS |
212 | grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), |
213 | grub_term_color_state state) | |
c35fc5bd VS |
214 | { |
215 | switch (state) { | |
216 | case GRUB_TERM_COLOR_STANDARD: | |
217 | cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; | |
218 | break; | |
219 | case GRUB_TERM_COLOR_NORMAL: | |
bc136973 | 220 | cur_color = grub_term_normal_color & 0x7f; |
c35fc5bd VS |
221 | break; |
222 | case GRUB_TERM_COLOR_HIGHLIGHT: | |
bc136973 | 223 | cur_color = grub_term_highlight_color & 0x7f; |
c35fc5bd VS |
224 | break; |
225 | default: | |
226 | break; | |
227 | } | |
228 | } | |
229 | ||
230 | #else | |
231 | static void | |
232 | grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), | |
233 | grub_term_color_state state) | |
234 | { | |
235 | switch (state) { | |
236 | case GRUB_TERM_COLOR_STANDARD: | |
237 | cur_color = 0x07; | |
238 | break; | |
239 | case GRUB_TERM_COLOR_NORMAL: | |
240 | cur_color = 0x07; | |
241 | break; | |
242 | case GRUB_TERM_COLOR_HIGHLIGHT: | |
243 | cur_color = 0x70; | |
244 | break; | |
245 | default: | |
246 | break; | |
247 | } | |
248 | } | |
249 | #endif | |
250 | ||
76679cd3 | 251 | static struct grub_term_output grub_vga_text_term = |
252 | { | |
c35fc5bd VS |
253 | #ifdef MODE_MDA |
254 | .name = "mda_text", | |
255 | #else | |
76679cd3 | 256 | .name = "vga_text", |
c35fc5bd | 257 | #endif |
d187a1c3 VS |
258 | .init = grub_vga_text_init_real, |
259 | .fini = grub_vga_text_fini_real, | |
34fac099 | 260 | .putchar = grub_vga_text_putchar, |
c35fc5bd | 261 | .getwh = grub_vga_text_getwh, |
76679cd3 | 262 | .getxy = grub_vga_text_getxy, |
263 | .gotoxy = grub_vga_text_gotoxy, | |
264 | .cls = grub_vga_text_cls, | |
c35fc5bd | 265 | .setcolorstate = grub_vga_text_setcolorstate, |
76679cd3 | 266 | .setcursor = grub_vga_text_setcursor, |
232dbbe5 | 267 | .flags = GRUB_TERM_CODE_TYPE_CP437, |
76679cd3 | 268 | }; |
269 | ||
c35fc5bd VS |
270 | #ifdef MODE_MDA |
271 | GRUB_MOD_INIT(mda_text) | |
272 | #elif defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) | |
036985b8 VS |
273 | void grub_vga_text_init (void) |
274 | #else | |
76679cd3 | 275 | GRUB_MOD_INIT(vga_text) |
036985b8 | 276 | #endif |
76679cd3 | 277 | { |
c35fc5bd VS |
278 | #ifdef MODE_MDA |
279 | grub_term_register_output ("mda_text", &grub_vga_text_term); | |
280 | #else | |
d05f0df3 | 281 | grub_term_register_output ("vga_text", &grub_vga_text_term); |
c35fc5bd | 282 | #endif |
76679cd3 | 283 | } |
284 | ||
c35fc5bd VS |
285 | #ifdef MODE_MDA |
286 | GRUB_MOD_FINI(mda_text) | |
287 | #elif defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) | |
036985b8 VS |
288 | void grub_vga_text_fini (void) |
289 | #else | |
76679cd3 | 290 | GRUB_MOD_FINI(vga_text) |
036985b8 | 291 | #endif |
76679cd3 | 292 | { |
293 | grub_term_unregister_output (&grub_vga_text_term); | |
294 | } |