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