]>
Commit | Line | Data |
---|---|---|
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 | */ | |
42 | typedef 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 |
81 | static short vga_idx_reg = 0; /* location of VGA index register */ |
82 | static short vga_io_reg = 0; /* 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 = 0; /* current character attribute */ | |
86 | static char vga_attr_rev = 0; /* current reverse attribute */ | |
87 | static char vga_cursor_start = 0; /* cached cursor start scan line */ | |
88 | static char * vram_start = 0; /* VM start of VGA frame buffer */ | |
1c79356b A |
89 | |
90 | /* | |
91 | * Functions in kdasm.s. | |
92 | */ | |
55e303ae A |
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); | |
1c79356b A |
96 | |
97 | /* | |
98 | * move_up | |
99 | * | |
100 | * Block move up for VGA. | |
101 | */ | |
102 | static void | |
103 | move_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 | */ | |
115 | static void | |
116 | move_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 | */ | |
128 | static void | |
129 | clear_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 | */ | |
143 | static void | |
144 | set_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 | */ | |
162 | static void | |
163 | set_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 | */ | |
175 | static void | |
176 | display_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 | */ | |
189 | static void | |
190 | vga_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 | */ | |
213 | void | |
91447636 | 214 | tc_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 | */ | |
237 | void | |
91447636 | 238 | tc_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 */ | |
257 | enum { | |
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 | */ | |
281 | void | |
282 | tc_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 | */ | |
316 | void | |
317 | tc_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 | */ | |
328 | void | |
91447636 | 329 | tc_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 | */ | |
340 | void | |
91447636 A |
341 | tc_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 | */ | |
372 | void | |
91447636 A |
373 | tc_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 | */ | |
388 | void | |
91447636 | 389 | tc_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 | */ | |
399 | void | |
400 | tc_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 | } |