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