2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * VGA text console support.
35 #include <architecture/i386/pio.h>
36 #include <console/video_console.h>
37 #include "text_console.h"
40 * Macros and typedefs.
42 typedef short csrpos_t
; /* cursor position, ONE_SPACE bytes per char */
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
49 #define VGA_FB_START 0x0b8000
50 #define VGA_FB_SIZE 0x8000
51 #define VGA_IDX_REG 0x3d4
52 #define VGA_IO_REG 0x3d5
55 * Commands sent to graphics adapter.
57 #define VGA_C_START 0x0a /* cursor start position, on/off bit */
58 #define VGA_C_LOW 0x0f /* return low byte of cursor addr */
59 #define VGA_C_HIGH 0x0e /* high byte */
62 * Attributes for character sent to display.
64 #define VGA_ATTR_NORMAL 0x07
65 #define VGA_ATTR_REVERSE 0x70
68 * Cursor Start Register bit fields.
70 #define VGA_CURSOR_CS 0x1F
71 #define VGA_CURSOR_ON 0x20
74 * Convert from XY coordinate to a location in display memory.
76 #define XY_TO_CSRPOS(x, y) (((y) * vga_cols + (x)) * ONE_SPACE)
81 static short vga_idx_reg
; /* location of VGA index register */
82 static short vga_io_reg
; /* location of VGA data register */
83 static short vga_cols
= 80; /* number of columns */
84 static short vga_rows
= 25; /* number of rows */
85 static char vga_attr
; /* current character attribute */
86 static char vga_attr_rev
; /* current reverse attribute */
87 static char vga_cursor_start
; /* cached cursor start scan line */
88 static unsigned char *vram_start
; /* VM start of VGA frame buffer */
91 * Functions in kdasm.s.
93 extern void kd_slmwd(unsigned char * pos
, int count
, unsigned short val
);
94 extern void kd_slmscu(unsigned char * from
, unsigned char * to
, int count
);
95 extern void kd_slmscd(unsigned char * from
, unsigned char * to
, int count
);
100 * Block move up for VGA.
103 move_up( csrpos_t from
,
107 if (vram_start
== 0) return;
108 kd_slmscu( vram_start
+ from
, vram_start
+ to
, count
);
114 * Block move down for VGA.
117 move_down( csrpos_t from
,
121 if (vram_start
== 0) return;
122 kd_slmscd( vram_start
+ from
, vram_start
+ to
, count
);
128 * Fast clear for VGA.
131 clear_block( csrpos_t start
,
135 if (vram_start
== 0) return;
136 kd_slmwd( vram_start
+ start
, size
,
137 ((unsigned short) attr
<< 8) + SPACE_CHAR
);
141 * set_cursor_position
143 * This function sets the hardware cursor position
147 set_cursor_position( csrpos_t newpos
)
149 short curpos
; /* position, not scaled for attribute byte */
151 curpos
= newpos
/ ONE_SPACE
;
153 outb(vga_idx_reg
, VGA_C_HIGH
);
154 outb(vga_io_reg
, (unsigned char)(curpos
>> 8));
156 outb(vga_idx_reg
, VGA_C_LOW
);
157 outb(vga_io_reg
, (unsigned char)(curpos
& 0xff));
163 * Allow the cursor to be turned on or off.
166 set_cursor_enable( boolean_t enable
)
168 outb(vga_idx_reg
, VGA_C_START
);
169 outb(vga_io_reg
, vga_cursor_start
|
170 (enable
== TRUE
? VGA_CURSOR_ON
: 0));
176 * Display attributed character for VGA (mode 3).
179 display_char( csrpos_t pos
, /* where to put it */
180 char ch
, /* the character */
181 char attr
) /* its attribute */
183 if (vram_start
== 0) return;
184 *(vram_start
+ pos
) = ch
;
185 *(vram_start
+ pos
+ 1) = attr
;
191 * Initialize the VGA text console.
194 vga_init(int cols
, int rows
, unsigned char * addr
)
197 vga_idx_reg
= VGA_IDX_REG
;
198 vga_io_reg
= VGA_IO_REG
;
201 vga_attr
= VGA_ATTR_NORMAL
;
202 vga_attr_rev
= VGA_ATTR_REVERSE
;
204 /* cache cursor start position */
205 outb(vga_idx_reg
, VGA_C_START
);
206 vga_cursor_start
= inb(vga_io_reg
) & VGA_CURSOR_CS
;
208 /* defaults to a hidden hw cursor */
209 set_cursor_enable( FALSE
);
215 * Scroll the screen up 'n' character lines.
218 tc_scroll_up(int lines
, __unused
unsigned int top
, __unused
unsigned int bottom
)
226 from
= ONE_LINE
* lines
;
227 size
= ( ONE_PAGE
- ( ONE_LINE
* lines
) ) / ONE_SPACE
;
228 move_up(from
, to
, size
);
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
);
239 * Scrolls the screen down 'n' character lines.
242 tc_scroll_down(int lines
, __unused
unsigned int top
,
243 __unused
unsigned int bottom
)
250 to
= ONE_PAGE
- ONE_SPACE
;
251 from
= ONE_PAGE
- ( ONE_LINE
* lines
) - ONE_SPACE
;
252 size
= ( ONE_PAGE
- ( ONE_LINE
* lines
) ) / ONE_SPACE
;
253 move_down(from
, to
, size
);
257 size
= ( ONE_LINE
* lines
) / ONE_SPACE
;
258 clear_block(to
, size
, vga_attr
);
261 /* Default colors for 16-color palette */
276 kVGAColorLightMagenta
,
284 * Update the foreground / background color.
287 tc_update_color( int color
, int fore
)
289 unsigned char mask_on
, mask_off
;
293 case 1: mask_on
= kVGAColorRed
; break;
294 case 3: mask_on
= kVGAColorLightBrown
; break;
295 case 4: mask_on
= kVGAColorBlue
; break;
296 case 6: mask_on
= kVGAColorCyan
; break;
297 default: mask_on
= color
; break;
310 vga_attr
= (vga_attr
& ~mask_off
) | mask_on
;
312 vga_attr_rev
= ( ((vga_attr
<< 4) & 0xf0) |
313 ((vga_attr
>> 4) & 0x0f) );
319 * Show the hardware cursor.
322 tc_show_cursor(unsigned int x
, unsigned int y
)
324 set_cursor_position( XY_TO_CSRPOS(x
, y
) );
325 set_cursor_enable( TRUE
);
331 * Hide the hardware cursor.
334 tc_hide_cursor(__unused
unsigned int x
, __unused
unsigned int y
)
336 set_cursor_enable( FALSE
);
342 * Clear the entire screen, or a portion of the screen
343 * relative to the current cursor position.
346 tc_clear_screen(unsigned int x
, unsigned int y
, __unused
unsigned int top
,
347 __unused
unsigned int bottom
, int operation
)
354 case 0: /* To end of screen */
355 start
= XY_TO_CSRPOS(x
, y
);
356 count
= ONE_PAGE
- start
;
358 case 1: /* To start of screen */
360 count
= XY_TO_CSRPOS(x
, y
) + ONE_SPACE
;
363 case 2: /* Whole screen */
368 clear_block(start
, count
, vga_attr
);
374 * Display a character on screen with the given coordinates,
378 tc_paint_char(unsigned int x
, unsigned int y
, unsigned char ch
, int attrs
,
379 __unused
unsigned char ch_previous
, __unused
int attrs_previous
)
381 char my_attr
= vga_attr
;
383 if ( attrs
& 4 ) my_attr
= vga_attr_rev
;
385 display_char( XY_TO_CSRPOS(x
, y
), ch
, vga_attr
);
391 * Enable / disable the console.
394 tc_enable(__unused boolean_t enable
)
402 * Must be called before any other exported functions.
405 tc_initialize(struct vc_info
* vinfo_p
)
407 vinfo_p
->v_rows
= vinfo_p
->v_height
;
408 vinfo_p
->v_columns
= vinfo_p
->v_width
;
410 vga_init( vinfo_p
->v_columns
,
412 (unsigned char *) vinfo_p
->v_baseaddr
);