]>
Commit | Line | Data |
---|---|---|
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 | */ | |
36 | typedef 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 |
75 | static short vga_idx_reg = 0; /* location of VGA index register */ |
76 | static short vga_io_reg = 0; /* location of VGA data register */ | |
77 | static short vga_cols = 80; /* number of columns */ | |
78 | static short vga_rows = 25; /* number of rows */ | |
79 | static char vga_attr = 0; /* current character attribute */ | |
80 | static char vga_attr_rev = 0; /* current reverse attribute */ | |
81 | static char vga_cursor_start = 0; /* cached cursor start scan line */ | |
82 | static char * vram_start = 0; /* VM start of VGA frame buffer */ | |
1c79356b A |
83 | |
84 | /* | |
85 | * Functions in kdasm.s. | |
86 | */ | |
55e303ae A |
87 | extern void kd_slmwd(unsigned char * pos, int count, unsigned short val); |
88 | extern void kd_slmscu(unsigned char * from, unsigned char * to, int count); | |
89 | extern 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 | */ | |
96 | static void | |
97 | move_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 | */ | |
109 | static void | |
110 | move_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 | */ | |
122 | static void | |
123 | clear_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 | */ | |
137 | static void | |
138 | set_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 | */ | |
156 | static void | |
157 | set_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 | */ | |
169 | static void | |
170 | display_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 | */ | |
183 | static void | |
184 | vga_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 | */ | |
207 | void | |
91447636 | 208 | tc_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 | */ | |
231 | void | |
91447636 | 232 | tc_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 */ | |
251 | enum { | |
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 | */ | |
275 | void | |
276 | tc_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 | */ | |
310 | void | |
311 | tc_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 | */ | |
322 | void | |
91447636 | 323 | tc_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 | */ | |
334 | void | |
91447636 A |
335 | tc_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 | */ | |
366 | void | |
91447636 A |
367 | tc_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 | */ | |
382 | void | |
91447636 | 383 | tc_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 | */ | |
393 | void | |
394 | tc_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 | } |