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