]> git.saurik.com Git - apple/xnu.git/blame - osfmk/console/i386/text_console.c
xnu-792.22.5.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
4452a7af 35#include <architecture/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{
4452a7af 107 if (vram_start == 0) return;
1c79356b
A
108 kd_slmscu( vram_start + from, vram_start + to, count );
109}
110
111/*
112 * move_down
113 *
114 * Block move down for VGA.
115 */
116static void
117move_down( csrpos_t from,
118 csrpos_t to,
119 int count )
120{
4452a7af 121 if (vram_start == 0) return;
1c79356b
A
122 kd_slmscd( vram_start + from, vram_start + to, count );
123}
124
125/*
126 * clear_block
127 *
128 * Fast clear for VGA.
129 */
130static void
131clear_block( csrpos_t start,
132 int size,
133 char attr)
134{
4452a7af 135 if (vram_start == 0) return;
1c79356b
A
136 kd_slmwd( vram_start + start, size,
137 ((unsigned short) attr << 8) + SPACE_CHAR);
138}
139
140/*
141 * set_cursor_position
142 *
143 * This function sets the hardware cursor position
144 * on the screen.
145 */
146static void
147set_cursor_position( csrpos_t newpos )
148{
149 short curpos; /* position, not scaled for attribute byte */
150
151 curpos = newpos / ONE_SPACE;
152
153 outb(vga_idx_reg, VGA_C_HIGH);
55e303ae 154 outb(vga_io_reg, (unsigned char)(curpos >> 8));
1c79356b
A
155
156 outb(vga_idx_reg, VGA_C_LOW);
55e303ae 157 outb(vga_io_reg, (unsigned char)(curpos & 0xff));
1c79356b
A
158}
159
91447636
A
160/*
161 * set_cursor_enable
162 *
163 * Allow the cursor to be turned on or off.
164 */
165static void
166set_cursor_enable( boolean_t enable )
167{
168 outb(vga_idx_reg, VGA_C_START);
169 outb(vga_io_reg, vga_cursor_start |
170 (enable == TRUE ? VGA_CURSOR_ON : 0));
171}
172
1c79356b
A
173/*
174 * display_char
175 *
176 * Display attributed character for VGA (mode 3).
177 */
178static void
179display_char( csrpos_t pos, /* where to put it */
180 char ch, /* the character */
181 char attr ) /* its attribute */
182{
4452a7af 183 if (vram_start == 0) return;
1c79356b
A
184 *(vram_start + pos) = ch;
185 *(vram_start + pos + 1) = attr;
186}
187
188/*
189 * vga_init
190 *
191 * Initialize the VGA text console.
192 */
193static void
194vga_init(int cols, int rows, unsigned char * addr)
195{
196 vram_start = addr;
197 vga_idx_reg = VGA_IDX_REG;
198 vga_io_reg = VGA_IO_REG;
199 vga_rows = rows;
200 vga_cols = cols;
201 vga_attr = VGA_ATTR_NORMAL;
202 vga_attr_rev = VGA_ATTR_REVERSE;
203
91447636
A
204 /* cache cursor start position */
205 outb(vga_idx_reg, VGA_C_START);
206 vga_cursor_start = inb(vga_io_reg) & VGA_CURSOR_CS;
207
208 /* defaults to a hidden hw cursor */
209 set_cursor_enable( FALSE );
1c79356b
A
210}
211
212/*
55e303ae 213 * tc_scroll_up
1c79356b
A
214 *
215 * Scroll the screen up 'n' character lines.
216 */
217void
91447636 218tc_scroll_up( int lines, __unused int top, __unused int bottom )
1c79356b
A
219{
220 csrpos_t to;
221 csrpos_t from;
222 int size;
223
224 /* scroll up */
225 to = 0;
226 from = ONE_LINE * lines;
227 size = ( ONE_PAGE - ( ONE_LINE * lines ) ) / ONE_SPACE;
228 move_up(from, to, size);
229
230 /* clear bottom line */
231 to = ( ( vga_rows - lines) * ONE_LINE );
232 size = ( ONE_LINE * lines ) / ONE_SPACE;
233 clear_block(to, size, vga_attr);
234}
235
236/*
55e303ae 237 * tc_scroll_down
1c79356b
A
238 *
239 * Scrolls the screen down 'n' character lines.
240 */
241void
91447636 242tc_scroll_down( int lines, __unused int top, __unused int bottom )
1c79356b
A
243{
244 csrpos_t to;
245 csrpos_t from;
246 int size;
247
248 /* move down */
249 to = ONE_PAGE - ONE_SPACE;
250 from = ONE_PAGE - ( ONE_LINE * lines ) - ONE_SPACE;
251 size = ( ONE_PAGE - ( ONE_LINE * lines ) ) / ONE_SPACE;
252 move_down(from, to, size);
253
254 /* clear top line */
255 to = 0;
256 size = ( ONE_LINE * lines ) / ONE_SPACE;
257 clear_block(to, size, vga_attr);
258}
259
260/* Default colors for 16-color palette */
261enum {
262 kVGAColorBlack = 0,
263 kVGAColorBlue,
264 kVGAColorGreen,
265 kVGAColorCyan,
266 kVGAColorRed,
267 kVGAColorMagenta,
268 kVGAColorBrown,
269 kVGAColorWhite,
270 kVGAColorGray,
271 kVGAColorLightBlue,
272 kVGAColorLightGreen,
273 kVGAColorLightCyan,
274 kVGAColorLightRed,
275 kVGAColorLightMagenta,
276 kVGAColorLightBrown,
277 kVGAColorBrightWhite
278};
279
280/*
281 * tc_update_color
282 *
283 * Update the foreground / background color.
284 */
285void
286tc_update_color( int color, int fore )
287{
288 unsigned char mask_on, mask_off;
289
290 switch ( color )
291 {
292 case 1: mask_on = kVGAColorRed; break;
293 case 3: mask_on = kVGAColorLightBrown; break;
294 case 4: mask_on = kVGAColorBlue; break;
295 case 6: mask_on = kVGAColorCyan; break;
296 default: mask_on = color; break;
297 }
298
299 if ( fore )
300 {
301 mask_off = 0x0f;
302 }
303 else
304 {
305 mask_off = 0xf0;
306 mask_on <<= 4;
307 }
308
309 vga_attr = (vga_attr & ~mask_off) | mask_on;
310
311 vga_attr_rev = ( ((vga_attr << 4) & 0xf0) |
312 ((vga_attr >> 4) & 0x0f) );
313}
314
315/*
316 * tc_show_cursor
317 *
318 * Show the hardware cursor.
319 */
320void
321tc_show_cursor( int x, int y )
322{
323 set_cursor_position( XY_TO_CSRPOS(x, y) );
91447636 324 set_cursor_enable( TRUE );
1c79356b
A
325}
326
327/*
328 * tc_hide_cursor
329 *
330 * Hide the hardware cursor.
331 */
332void
91447636 333tc_hide_cursor( __unused int x, __unused int y )
1c79356b 334{
91447636 335 set_cursor_enable( FALSE );
1c79356b
A
336}
337
338/*
339 * tc_clear_screen
340 *
341 * Clear the entire screen, or a portion of the screen
342 * relative to the current cursor position.
343 */
344void
91447636
A
345tc_clear_screen(int x, int y, __unused int top, __unused int bottom,
346 int operation)
1c79356b
A
347{
348 csrpos_t start;
349 int count;
350
351 switch ( operation )
352 {
353 case 0: /* To end of screen */
354 start = XY_TO_CSRPOS(x, y);
355 count = ONE_PAGE - start;
356 break;
357 case 1: /* To start of screen */
358 start = 0;
359 count = XY_TO_CSRPOS(x, y) + ONE_SPACE;
360 break;
361 default:
362 case 2: /* Whole screen */
363 start = 0;
364 count = ONE_PAGE;
365 break;
366 }
367 clear_block(start, count, vga_attr);
368}
369
370/*
55e303ae 371 * tc_paint_char
1c79356b
A
372 *
373 * Display a character on screen with the given coordinates,
374 * and attributes.
375 */
376void
91447636
A
377tc_paint_char(int x, int y, unsigned char ch, int attrs,
378 __unused unsigned char ch_previous, __unused int attrs_previous)
1c79356b
A
379{
380 char my_attr = vga_attr;
381
382 if ( attrs & 4 ) my_attr = vga_attr_rev;
383
384 display_char( XY_TO_CSRPOS(x, y), ch, vga_attr );
385}
386
55e303ae
A
387/*
388 * tc_enable
389 *
390 * Enable / disable the console.
391 */
392void
91447636 393tc_enable(__unused boolean_t enable)
55e303ae
A
394{
395
396}
397
1c79356b
A
398/*
399 * tc_initialize
400 *
401 * Must be called before any other exported functions.
402 */
403void
404tc_initialize(struct vc_info * vinfo_p)
405{
406 vinfo_p->v_rows = vinfo_p->v_height;
407 vinfo_p->v_columns = vinfo_p->v_width;
408
409 vga_init( vinfo_p->v_columns,
410 vinfo_p->v_rows,
411 (unsigned char *) vinfo_p->v_baseaddr);
412}