]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
43866e37 | 6 | * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. |
1c79356b | 7 | * |
43866e37 A |
8 | * This file contains Original Code and/or Modifications of Original Code |
9 | * as defined in and that are subject to the Apple Public Source License | |
10 | * Version 2.0 (the 'License'). You may not use this file except in | |
11 | * compliance with the License. Please obtain a copy of the License at | |
12 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
13 | * file. | |
14 | * | |
15 | * The Original Code and all software distributed under the License are | |
16 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
1c79356b A |
17 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
18 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
43866e37 A |
19 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
20 | * Please see the License for the specific language governing rights and | |
21 | * limitations under the License. | |
1c79356b A |
22 | * |
23 | * @APPLE_LICENSE_HEADER_END@ | |
24 | */ | |
25 | ||
26 | /* | |
27 | * text_console.c | |
28 | * | |
29 | * VGA text console support. | |
30 | */ | |
31 | ||
55e303ae A |
32 | #include <i386/pio.h> |
33 | #include <console/video_console.h> | |
1c79356b A |
34 | |
35 | /* | |
36 | * Macros and typedefs. | |
37 | */ | |
38 | typedef short csrpos_t; /* cursor position, ONE_SPACE bytes per char */ | |
39 | ||
40 | #define ONE_SPACE 2 /* bytes per character */ | |
41 | #define ONE_LINE (vga_cols * ONE_SPACE) /* number of bytes in line */ | |
42 | #define ONE_PAGE (vga_rows * ONE_LINE) /* number of bytes in page */ | |
43 | #define SPACE_CHAR 0x20 | |
44 | ||
45 | #define VGA_FB_START 0x0b8000 | |
46 | #define VGA_FB_SIZE 0x8000 | |
47 | #define VGA_IDX_REG 0x3d4 | |
48 | #define VGA_IO_REG 0x3d5 | |
49 | ||
50 | /* | |
51 | * Commands sent to graphics adapter. | |
52 | */ | |
53 | #define VGA_C_LOW 0x0f /* return low byte of cursor addr */ | |
54 | #define VGA_C_HIGH 0x0e /* high byte */ | |
55 | ||
56 | /* | |
57 | * Attributes for character sent to display. | |
58 | */ | |
59 | #define VGA_ATTR_NORMAL 0x07 | |
60 | #define VGA_ATTR_REVERSE 0x70 | |
61 | ||
62 | /* | |
63 | * Convert from XY coordinate to a location in display memory. | |
64 | */ | |
65 | #define XY_TO_CSRPOS(x, y) (((y) * vga_cols + (x)) * ONE_SPACE) | |
66 | ||
67 | /* | |
68 | * Globals. | |
69 | */ | |
70 | static short vga_idx_reg = 0; /* location of VGA index register */ | |
71 | static short vga_io_reg = 0; /* location of VGA data register */ | |
72 | static short vga_cols = 80; /* number of columns */ | |
73 | static short vga_rows = 25; /* number of rows */ | |
74 | static char vga_attr = 0; /* current character attribute */ | |
75 | static char vga_attr_rev = 0; /* current reverse attribute */ | |
76 | static char * vram_start = 0; /* VM start of VGA frame buffer */ | |
77 | ||
78 | /* | |
79 | * Functions in kdasm.s. | |
80 | */ | |
55e303ae A |
81 | extern void kd_slmwd(unsigned char * pos, int count, unsigned short val); |
82 | extern void kd_slmscu(unsigned char * from, unsigned char * to, int count); | |
83 | extern void kd_slmscd(unsigned char * from, unsigned char * to, int count); | |
1c79356b A |
84 | |
85 | /* | |
86 | * move_up | |
87 | * | |
88 | * Block move up for VGA. | |
89 | */ | |
90 | static void | |
91 | move_up( csrpos_t from, | |
92 | csrpos_t to, | |
93 | int count) | |
94 | { | |
95 | kd_slmscu( vram_start + from, vram_start + to, count ); | |
96 | } | |
97 | ||
98 | /* | |
99 | * move_down | |
100 | * | |
101 | * Block move down for VGA. | |
102 | */ | |
103 | static void | |
104 | move_down( csrpos_t from, | |
105 | csrpos_t to, | |
106 | int count ) | |
107 | { | |
108 | kd_slmscd( vram_start + from, vram_start + to, count ); | |
109 | } | |
110 | ||
111 | /* | |
112 | * clear_block | |
113 | * | |
114 | * Fast clear for VGA. | |
115 | */ | |
116 | static void | |
117 | clear_block( csrpos_t start, | |
118 | int size, | |
119 | char attr) | |
120 | { | |
121 | kd_slmwd( vram_start + start, size, | |
122 | ((unsigned short) attr << 8) + SPACE_CHAR); | |
123 | } | |
124 | ||
125 | /* | |
126 | * set_cursor_position | |
127 | * | |
128 | * This function sets the hardware cursor position | |
129 | * on the screen. | |
130 | */ | |
131 | static void | |
132 | set_cursor_position( csrpos_t newpos ) | |
133 | { | |
134 | short curpos; /* position, not scaled for attribute byte */ | |
135 | ||
136 | curpos = newpos / ONE_SPACE; | |
137 | ||
138 | outb(vga_idx_reg, VGA_C_HIGH); | |
55e303ae | 139 | outb(vga_io_reg, (unsigned char)(curpos >> 8)); |
1c79356b A |
140 | |
141 | outb(vga_idx_reg, VGA_C_LOW); | |
55e303ae | 142 | outb(vga_io_reg, (unsigned char)(curpos & 0xff)); |
1c79356b A |
143 | } |
144 | ||
145 | /* | |
146 | * display_char | |
147 | * | |
148 | * Display attributed character for VGA (mode 3). | |
149 | */ | |
150 | static void | |
151 | display_char( csrpos_t pos, /* where to put it */ | |
152 | char ch, /* the character */ | |
153 | char attr ) /* its attribute */ | |
154 | { | |
155 | *(vram_start + pos) = ch; | |
156 | *(vram_start + pos + 1) = attr; | |
157 | } | |
158 | ||
159 | /* | |
160 | * vga_init | |
161 | * | |
162 | * Initialize the VGA text console. | |
163 | */ | |
164 | static void | |
165 | vga_init(int cols, int rows, unsigned char * addr) | |
166 | { | |
167 | vram_start = addr; | |
168 | vga_idx_reg = VGA_IDX_REG; | |
169 | vga_io_reg = VGA_IO_REG; | |
170 | vga_rows = rows; | |
171 | vga_cols = cols; | |
172 | vga_attr = VGA_ATTR_NORMAL; | |
173 | vga_attr_rev = VGA_ATTR_REVERSE; | |
174 | ||
175 | set_cursor_position(0); | |
176 | } | |
177 | ||
178 | /* | |
55e303ae | 179 | * tc_scroll_up |
1c79356b A |
180 | * |
181 | * Scroll the screen up 'n' character lines. | |
182 | */ | |
183 | void | |
55e303ae | 184 | tc_scroll_up( int lines, int top, int bottom ) |
1c79356b A |
185 | { |
186 | csrpos_t to; | |
187 | csrpos_t from; | |
188 | int size; | |
189 | ||
190 | /* scroll up */ | |
191 | to = 0; | |
192 | from = ONE_LINE * lines; | |
193 | size = ( ONE_PAGE - ( ONE_LINE * lines ) ) / ONE_SPACE; | |
194 | move_up(from, to, size); | |
195 | ||
196 | /* clear bottom line */ | |
197 | to = ( ( vga_rows - lines) * ONE_LINE ); | |
198 | size = ( ONE_LINE * lines ) / ONE_SPACE; | |
199 | clear_block(to, size, vga_attr); | |
200 | } | |
201 | ||
202 | /* | |
55e303ae | 203 | * tc_scroll_down |
1c79356b A |
204 | * |
205 | * Scrolls the screen down 'n' character lines. | |
206 | */ | |
207 | void | |
55e303ae | 208 | tc_scroll_down( int lines, int top, int bottom ) |
1c79356b A |
209 | { |
210 | csrpos_t to; | |
211 | csrpos_t from; | |
212 | int size; | |
213 | ||
214 | /* move down */ | |
215 | to = ONE_PAGE - ONE_SPACE; | |
216 | from = ONE_PAGE - ( ONE_LINE * lines ) - ONE_SPACE; | |
217 | size = ( ONE_PAGE - ( ONE_LINE * lines ) ) / ONE_SPACE; | |
218 | move_down(from, to, size); | |
219 | ||
220 | /* clear top line */ | |
221 | to = 0; | |
222 | size = ( ONE_LINE * lines ) / ONE_SPACE; | |
223 | clear_block(to, size, vga_attr); | |
224 | } | |
225 | ||
226 | /* Default colors for 16-color palette */ | |
227 | enum { | |
228 | kVGAColorBlack = 0, | |
229 | kVGAColorBlue, | |
230 | kVGAColorGreen, | |
231 | kVGAColorCyan, | |
232 | kVGAColorRed, | |
233 | kVGAColorMagenta, | |
234 | kVGAColorBrown, | |
235 | kVGAColorWhite, | |
236 | kVGAColorGray, | |
237 | kVGAColorLightBlue, | |
238 | kVGAColorLightGreen, | |
239 | kVGAColorLightCyan, | |
240 | kVGAColorLightRed, | |
241 | kVGAColorLightMagenta, | |
242 | kVGAColorLightBrown, | |
243 | kVGAColorBrightWhite | |
244 | }; | |
245 | ||
246 | /* | |
247 | * tc_update_color | |
248 | * | |
249 | * Update the foreground / background color. | |
250 | */ | |
251 | void | |
252 | tc_update_color( int color, int fore ) | |
253 | { | |
254 | unsigned char mask_on, mask_off; | |
255 | ||
256 | switch ( color ) | |
257 | { | |
258 | case 1: mask_on = kVGAColorRed; break; | |
259 | case 3: mask_on = kVGAColorLightBrown; break; | |
260 | case 4: mask_on = kVGAColorBlue; break; | |
261 | case 6: mask_on = kVGAColorCyan; break; | |
262 | default: mask_on = color; break; | |
263 | } | |
264 | ||
265 | if ( fore ) | |
266 | { | |
267 | mask_off = 0x0f; | |
268 | } | |
269 | else | |
270 | { | |
271 | mask_off = 0xf0; | |
272 | mask_on <<= 4; | |
273 | } | |
274 | ||
275 | vga_attr = (vga_attr & ~mask_off) | mask_on; | |
276 | ||
277 | vga_attr_rev = ( ((vga_attr << 4) & 0xf0) | | |
278 | ((vga_attr >> 4) & 0x0f) ); | |
279 | } | |
280 | ||
281 | /* | |
282 | * tc_show_cursor | |
283 | * | |
284 | * Show the hardware cursor. | |
285 | */ | |
286 | void | |
287 | tc_show_cursor( int x, int y ) | |
288 | { | |
289 | set_cursor_position( XY_TO_CSRPOS(x, y) ); | |
290 | } | |
291 | ||
292 | /* | |
293 | * tc_hide_cursor | |
294 | * | |
295 | * Hide the hardware cursor. | |
296 | */ | |
297 | void | |
298 | tc_hide_cursor( int x, int y ) | |
299 | { | |
300 | return; | |
301 | } | |
302 | ||
303 | /* | |
304 | * tc_clear_screen | |
305 | * | |
306 | * Clear the entire screen, or a portion of the screen | |
307 | * relative to the current cursor position. | |
308 | */ | |
309 | void | |
55e303ae | 310 | tc_clear_screen(int x, int y, int top, int bottom, int operation) |
1c79356b A |
311 | { |
312 | csrpos_t start; | |
313 | int count; | |
314 | ||
315 | switch ( operation ) | |
316 | { | |
317 | case 0: /* To end of screen */ | |
318 | start = XY_TO_CSRPOS(x, y); | |
319 | count = ONE_PAGE - start; | |
320 | break; | |
321 | case 1: /* To start of screen */ | |
322 | start = 0; | |
323 | count = XY_TO_CSRPOS(x, y) + ONE_SPACE; | |
324 | break; | |
325 | default: | |
326 | case 2: /* Whole screen */ | |
327 | start = 0; | |
328 | count = ONE_PAGE; | |
329 | break; | |
330 | } | |
331 | clear_block(start, count, vga_attr); | |
332 | } | |
333 | ||
334 | /* | |
55e303ae | 335 | * tc_paint_char |
1c79356b A |
336 | * |
337 | * Display a character on screen with the given coordinates, | |
338 | * and attributes. | |
339 | */ | |
340 | void | |
55e303ae | 341 | tc_paint_char( int x, int y, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous ) |
1c79356b A |
342 | { |
343 | char my_attr = vga_attr; | |
344 | ||
345 | if ( attrs & 4 ) my_attr = vga_attr_rev; | |
346 | ||
347 | display_char( XY_TO_CSRPOS(x, y), ch, vga_attr ); | |
348 | } | |
349 | ||
55e303ae A |
350 | /* |
351 | * tc_enable | |
352 | * | |
353 | * Enable / disable the console. | |
354 | */ | |
355 | void | |
356 | tc_enable(boolean_t enable) | |
357 | { | |
358 | ||
359 | } | |
360 | ||
1c79356b A |
361 | /* |
362 | * tc_initialize | |
363 | * | |
364 | * Must be called before any other exported functions. | |
365 | */ | |
366 | void | |
367 | tc_initialize(struct vc_info * vinfo_p) | |
368 | { | |
369 | vinfo_p->v_rows = vinfo_p->v_height; | |
370 | vinfo_p->v_columns = vinfo_p->v_width; | |
371 | ||
372 | vga_init( vinfo_p->v_columns, | |
373 | vinfo_p->v_rows, | |
374 | (unsigned char *) vinfo_p->v_baseaddr); | |
375 | } |