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