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