2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * @OSF_FREE_COPYRIGHT@
30 * @APPLE_FREE_COPYRIGHT@
32 /* MACH PPC - video_console.c
34 * Original based on NetBSD's mac68k/dev/ite.c driver
36 * This driver differs in
38 * - Uses phys_copy and flush_cache to in several places
39 * for performance optimizations
41 * - Black background and white (character) foreground
42 * - Assumes 6100/7100/8100 class of machine
44 * The original header follows...
47 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
49 * Copyright (c) 1988 University of Utah.
50 * Copyright (c) 1990, 1993
51 * The Regents of the University of California. All rights reserved.
53 * This code is derived from software contributed to Berkeley by
54 * the Systems Programming Group of the University of Utah Computer
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. All advertising materials mentioning features or use of this software
66 * must display the following acknowledgement:
67 * This product includes software developed by the University of
68 * California, Berkeley and its contributors.
69 * 4. Neither the name of the University nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
73 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85 * from: Utah $Hdr: ite.c 1.28 92/12/20$
87 * @(#)ite.c 8.2 (Berkeley) 1/12/94
93 * The ite module handles the system console; that is, stuff printed
94 * by the kernel and by user programs while "desktop" and X aren't
95 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
96 * hence the above copyright.
98 * -- Brad and Lawrence, June 26th, 1994
101 #include <kern/spl.h>
102 #include <machine/machparam.h> /* spl definitions */
103 #include "iso_scan_font.h"
104 #include <pexpert/pexpert.h>
105 #include <pexpert/i386/boot.h>
106 #include <kern/time_out.h>
107 #include <kern/lock.h>
108 #include "video_console.h"
111 #define CHARHEIGHT 16
116 #define ATTR_REVERSE 4
119 ESnormal
, /* Nothing yet */
121 ESsquare
, /* Got ESC [ */
122 ESgetpars
, /* About to get or getting the parameters */
123 ESgotpars
, /* Finished getting the parameters */
124 ESfunckey
, /* Function key */
125 EShash
, /* DEC-specific stuff (screen align, etc.) */
126 ESsetG0
, /* Specify the G0 character set */
127 ESsetG1
, /* Specify the G1 character set */
130 ESignore
/* Ignore this sequence */
131 } vt100state
= ESnormal
;
133 static struct vc_info vinfo
;
134 #define IS_TEXT_MODE (vinfo.v_type == TEXT_MODE)
136 /* Calculated in vccninit(): */
137 static int vc_wrap_mode
= 1, vc_relative_origin
= 0;
138 static int vc_charset_select
= 0, vc_save_charset_s
= 0;
139 static int vc_charset
[2] = { 0, 0 };
140 static int vc_charset_save
[2] = { 0, 0 };
144 static int x
= 0, y
= 0, savex
, savey
;
145 static int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
147 /* VT100 tab stops & scroll region */
148 static char tab_stops
[255];
149 static int scrreg_top
, scrreg_bottom
;
152 void vc_flush_forward_buffer(void);
153 void vc_store_char(unsigned char);
156 * For the color support (Michel Pollet)
158 unsigned char vc_color_index_table
[33] =
159 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
162 unsigned long vc_color_depth_masks
[4] =
163 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
165 unsigned long vc_colors
[8][3] = {
166 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
167 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
168 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
169 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
170 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
171 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
172 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
173 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
174 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
177 unsigned long vc_color_mask
= 0;
178 unsigned long vc_color_fore
= 0;
179 unsigned long vc_color_back
= 0;
180 int vc_normal_background
= 1;
183 * For the jump scroll and buffering (Michel Pollet)
184 * 80*22 means on a 80*24 screen, the screen will
185 * scroll jump almost a full screen
186 * keeping only what's necessary for you to be able to read ;-)
188 #define VC_MAX_FORWARD_SIZE (80*22)
191 * Delay between console updates in clock hz units, the larger the
192 * delay the fuller the jump-scroll buffer will be and so the faster the
193 * (scrolling) output. The smaller the delay, the less jerky the
194 * display. Heuristics show that at 10 touch-typists (Mike!) complain
196 #define VC_CONSOLE_UPDATE_TIMEOUT 5
198 static unsigned char vc_forward_buffer
[VC_MAX_FORWARD_SIZE
];
199 static long vc_forward_buffer_size
= 0;
200 decl_simple_lock_data(,vc_forward_lock
)
202 /* Set to 1 by initialize_screen() */
203 static int vc_initialized
= 0;
205 /* Function pointers initialized via initialize_screen() */
207 void (*initialize
)(struct vc_info
* vinfo_p
);
208 void (*paintchar
)(unsigned char c
, int x
, int y
, int attrs
);
209 void (*scrolldown
)(int num
);
210 void (*scrollup
)(int num
);
211 void (*clear_screen
)(int xx
, int yy
, int which
);
212 void (*show_cursor
)(int x
, int y
);
213 void (*hide_cursor
)(int x
, int y
);
214 void (*update_color
)(int color
, int fore
);
218 * New Rendering code from Michel Pollet
221 #define REN_MAX_DEPTH 32
222 /* that's the size for a 32 bits buffer... */
223 #define REN_MAX_SIZE (128L*1024)
224 unsigned char renderedFont
[REN_MAX_SIZE
];
226 /* Rendered Font Size */
227 unsigned long vc_rendered_font_size
= REN_MAX_SIZE
;
228 long vc_rendered_error
= 0;
230 /* If the one bit table was reversed */
231 short vc_one_bit_reversed
= 0;
233 /* Size of a character in the table (bytes) */
234 int vc_rendered_char_size
= 0;
238 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
240 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
241 # Background color codes:
242 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
245 #define VC_RESET_BACKGROUND 40
246 #define VC_RESET_FOREGROUND 37
248 static void vc_color_set(int color
)
250 if (vinfo
.v_depth
< 8)
252 if (color
>= 30 && color
<= 37) {
253 vc_color_fore
= vc_colors
[color
-30][vc_color_index_table
[vinfo
.v_depth
]];
254 if ( vc_ops
.update_color
) vc_ops
.update_color(color
- 30, 1);
256 if (color
>= 40 && color
<= 47) {
257 vc_color_back
= vc_colors
[color
-40][vc_color_index_table
[vinfo
.v_depth
]];
258 if ( vc_ops
.update_color
) vc_ops
.update_color(color
- 40, 0);
259 vc_normal_background
= color
== 40;
263 static void vc_render_font(short olddepth
, short newdepth
)
265 int charIndex
; /* index in ISO font */
267 unsigned char *charptr
;
268 unsigned short *shortptr
;
269 unsigned long *longptr
;
270 } current
; /* current place in rendered font, multiple types. */
272 unsigned char *theChar
; /* current char in iso_font */
274 if (olddepth
== newdepth
)
275 return; /* nothing to do */
277 vc_rendered_font_size
= REN_MAX_SIZE
;
279 vc_rendered_char_size
= 16;
280 if (!vc_one_bit_reversed
) { /* reverse the font for the blitter */
282 for (i
= 0; i
< ((ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
); i
++) {
284 unsigned char mask1
= 0x80;
285 unsigned char mask2
= 0x01;
286 unsigned char val
= 0;
288 if (iso_font
[i
] & mask1
)
293 renderedFont
[i
] = ~val
;
294 } else renderedFont
[i
] = 0xff;
296 vc_one_bit_reversed
= 1;
301 long csize
= newdepth
/ 8; /* bytes per pixel */
302 vc_rendered_char_size
= csize
? CHARHEIGHT
* (csize
* CHARWIDTH
) :
303 /* for 2 & 4 */ CHARHEIGHT
* (CHARWIDTH
/(6-newdepth
));
304 csize
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
;
305 if (csize
> vc_rendered_font_size
) {
306 vc_rendered_error
= csize
;
309 vc_rendered_font_size
= csize
;
312 current
.charptr
= renderedFont
;
314 for (charIndex
= ISO_CHAR_MIN
; charIndex
<= ISO_CHAR_MAX
; charIndex
++) {
316 for (line
= 0; line
< CHARHEIGHT
; line
++) {
317 unsigned char mask
= 1;
321 unsigned char value
= 0;
322 if (*theChar
& mask
) value
|= 0xC0; mask
<<= 1;
323 if (*theChar
& mask
) value
|= 0x30; mask
<<= 1;
324 if (*theChar
& mask
) value
|= 0x0C; mask
<<= 1;
325 if (*theChar
& mask
) value
|= 0x03;
327 *current
.charptr
++ = value
;
332 unsigned char value
= 0;
333 if (*theChar
& mask
) value
|= 0xF0; mask
<<= 1;
334 if (*theChar
& mask
) value
|= 0x0F;
336 *current
.charptr
++ = value
;
340 *current
.charptr
++ = (*theChar
& mask
) ? 0xff : 0;
343 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
347 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
351 } while (mask
); /* while the single bit drops to the right */
357 static void vc_paint_char1(unsigned char ch
, int xx
, int yy
, int attrs
)
359 unsigned char *theChar
;
360 unsigned char *where
;
363 theChar
= (unsigned char*)(renderedFont
+ (ch
* vc_rendered_char_size
));
364 where
= (unsigned char*)(vinfo
.v_baseaddr
+
365 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
368 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
371 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
372 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
373 unsigned char val
= *theChar
++, save
= val
;
374 if (attrs
& ATTR_BOLD
) { /* bold support */
375 unsigned char mask1
= 0xC0, mask2
= 0x40;
377 for (bit
= 0; bit
< 7; bit
++) {
378 if ((save
& mask1
) == mask2
)
384 if (attrs
& ATTR_REVERSE
) val
= ~val
;
385 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
388 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
393 static void vc_paint_char2(unsigned char ch
, int xx
, int yy
, int attrs
)
395 unsigned short *theChar
;
396 unsigned short *where
;
399 theChar
= (unsigned short*)(renderedFont
+ (ch
* vc_rendered_char_size
));
400 where
= (unsigned short*)(vinfo
.v_baseaddr
+
401 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
403 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
406 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
407 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
408 unsigned short val
= *theChar
++, save
= val
;
409 if (attrs
& ATTR_BOLD
) { /* bold support */
410 unsigned short mask1
= 0xF000, mask2
= 0x3000;
412 for (bit
= 0; bit
< 7; bit
++) {
413 if ((save
& mask1
) == mask2
)
419 if (attrs
& ATTR_REVERSE
) val
= ~val
;
420 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
423 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
428 static void vc_paint_char4(unsigned char ch
, int xx
, int yy
, int attrs
)
430 unsigned long *theChar
;
431 unsigned long *where
;
434 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
435 where
= (unsigned long*)(vinfo
.v_baseaddr
+
436 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
439 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
442 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
443 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
444 unsigned long val
= *theChar
++, save
= val
;
445 if (attrs
& ATTR_BOLD
) { /* bold support */
446 unsigned long mask1
= 0xff000000, mask2
= 0x0F000000;
448 for (bit
= 0; bit
< 7; bit
++) {
449 if ((save
& mask1
) == mask2
)
455 if (attrs
& ATTR_REVERSE
) val
= ~val
;
456 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
459 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
464 static void vc_paint_char8c(unsigned char ch
, int xx
, int yy
, int attrs
)
466 unsigned long *theChar
;
467 unsigned long *where
;
470 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
471 where
= (unsigned long*)(vinfo
.v_baseaddr
+
472 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
475 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attr? FLY !*/
476 unsigned long *store
= where
;
478 for (x
= 0; x
< 2; x
++) {
479 unsigned long val
= *theChar
++;
480 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
484 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
485 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
486 unsigned long *store
= where
, lastpixel
= 0;
488 for (x
= 0 ; x
< 2; x
++) {
489 unsigned long val
= *theChar
++, save
= val
;
490 if (attrs
& ATTR_BOLD
) { /* bold support */
491 if (lastpixel
&& !(save
& 0xFF000000))
493 if ((save
& 0xFFFF0000) == 0xFF000000)
495 if ((save
& 0x00FFFF00) == 0x00FF0000)
497 if ((save
& 0x0000FFFF) == 0x0000FF00)
500 if (attrs
& ATTR_REVERSE
) val
= ~val
;
501 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
503 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
505 lastpixel
= save
& 0xff;
508 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
512 static void vc_paint_char16c(unsigned char ch
, int xx
, int yy
, int attrs
)
514 unsigned long *theChar
;
515 unsigned long *where
;
518 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
519 where
= (unsigned long*)(vinfo
.v_baseaddr
+
520 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
521 (xx
* CHARWIDTH
* 2));
523 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
524 unsigned long *store
= where
;
526 for (x
= 0; x
< 4; x
++) {
527 unsigned long val
= *theChar
++;
528 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
532 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
533 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
534 unsigned long *store
= where
, lastpixel
= 0;
536 for (x
= 0 ; x
< 4; x
++) {
537 unsigned long val
= *theChar
++, save
= val
;
538 if (attrs
& ATTR_BOLD
) { /* bold support */
539 if (save
== 0xFFFF0000) val
|= 0xFFFF;
540 else if (lastpixel
&& !(save
& 0xFFFF0000))
543 if (attrs
& ATTR_REVERSE
) val
= ~val
;
544 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
546 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
549 lastpixel
= save
& 0x7fff;
552 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
556 static void vc_paint_char32c(unsigned char ch
, int xx
, int yy
, int attrs
)
558 unsigned long *theChar
;
559 unsigned long *where
;
562 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
563 where
= (unsigned long*)(vinfo
.v_baseaddr
+
564 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
565 (xx
* CHARWIDTH
* 4));
567 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
568 unsigned long *store
= where
;
570 for (x
= 0; x
< 8; x
++) {
571 unsigned long val
= *theChar
++;
572 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
576 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
577 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
578 unsigned long *store
= where
, lastpixel
= 0;
580 for (x
= 0 ; x
< 8; x
++) {
581 unsigned long val
= *theChar
++, save
= val
;
582 if (attrs
& ATTR_BOLD
) { /* bold support */
583 if (lastpixel
&& !save
)
586 if (attrs
& ATTR_REVERSE
) val
= ~val
;
587 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
589 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
594 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
600 * That's a plain dumb reverse of the cursor position
601 * It do a binary reverse, so it will not looks good when we have
602 * color support. we'll see that later
604 static void reversecursor(int xx
, int yy
)
607 unsigned char *charptr
;
608 unsigned short *shortptr
;
609 unsigned long *longptr
;
613 where
.longptr
= (unsigned long*)(vinfo
.v_baseaddr
+
614 (y
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
615 (x
/** CHARWIDTH*/ * vinfo
.v_depth
));
616 for (line
= 0; line
< CHARHEIGHT
; line
++) {
617 switch (vinfo
.v_depth
) {
619 *where
.charptr
= ~*where
.charptr
;
622 *where
.shortptr
= ~*where
.shortptr
;
625 *where
.longptr
= ~*where
.longptr
;
627 /* that code still exists because since characters on the screen are
628 * of different colors that reverse function may not work if the
629 * cursor is on a character that is in a different color that the
630 * current one. When we have buffering, things will work better. MP
632 #if 1 /*VC_BINARY_REVERSE*/
634 where
.longptr
[0] = ~where
.longptr
[0];
635 where
.longptr
[1] = ~where
.longptr
[1];
638 for (col
= 0; col
< 4; col
++)
639 where
.longptr
[col
] = ~where
.longptr
[col
];
642 for (col
= 0; col
< 8; col
++)
643 where
.longptr
[col
] = ~where
.longptr
[col
];
647 for (col
= 0; col
< 8; col
++)
648 where
.charptr
[col
] = where
.charptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
649 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
652 for (col
= 0; col
< 8; col
++)
653 where
.shortptr
[col
] = where
.shortptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
654 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
657 for (col
= 0; col
< 8; col
++)
658 where
.longptr
[col
] = where
.longptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
659 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
663 where
.charptr
+= vinfo
.v_rowbytes
;
671 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
673 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
674 rowline
= vinfo
.v_rowbytes
/ 4;
675 rowscanline
= vinfo
.v_rowscanbytes
/ 4;
677 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
678 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
680 i
= (scrreg_bottom
- scrreg_top
) - num
;
683 for (line
= 0; line
< CHARHEIGHT
; line
++) {
685 * Only copy what is displayed
688 bcopy((unsigned int) from
, (unsigned int) to
,
689 vinfo
.v_rowscanbytes
);
691 video_scroll_up((unsigned int) from
,
692 (unsigned int) (from
+(vinfo
.v_rowscanbytes
/4)),
701 /* Now set the freed up lines to the background colour */
704 to
= ((unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
))
705 + ((scrreg_bottom
- scrreg_top
- num
) * linelongs
);
707 for (linelongs
= CHARHEIGHT
* num
; linelongs
-- > 0;) {
709 for (i
= 0; i
< rowscanline
; i
++)
710 *to
++ = vc_color_back
;
720 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
722 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
723 rowline
= vinfo
.v_rowbytes
/ 4;
724 rowscanline
= vinfo
.v_rowscanbytes
/ 4;
727 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
728 - (rowline
- rowscanline
);
729 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
731 i
= (scrreg_bottom
- scrreg_top
) - num
;
734 for (line
= 0; line
< CHARHEIGHT
; line
++) {
736 * Only copy what is displayed
739 bcopy(from
-(vinfo
.v_rowscanbytes
/4), to
,
740 vinfo
.v_rowscanbytes
);
743 video_scroll_down((unsigned int) from
,
744 (unsigned int) (from
-(vinfo
.v_rowscanbytes
/4)),
753 /* Now set the freed up lines to the background colour */
755 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_top
);
757 for (line
= CHARHEIGHT
* num
; line
> 0; line
--) {
760 for (i
= 0; i
< rowscanline
; i
++)
761 *(to
++) = vc_color_back
;
770 clear_line(int which
)
775 * This routine runs extremely slowly. I don't think it's
776 * used all that often, except for To end of line. I'll go
777 * back and speed this up when I speed up the whole vc
782 case 0: /* To end of line */
784 end
= vinfo
.v_columns
-1;
786 case 1: /* To start of line */
791 case 2: /* Whole line */
793 end
= vinfo
.v_columns
-1;
797 for (i
= start
; i
<= end
; i
++) {
798 vc_ops
.paintchar(' ', i
, y
, ATTR_NONE
);
804 clear_screen(int xx
, int yy
, int which
)
806 unsigned long *p
, *endp
, *row
;
808 int rowline
, rowlongs
;
810 rowline
= vinfo
.v_rowscanbytes
/ 4;
811 rowlongs
= vinfo
.v_rowbytes
/ 4;
813 p
= (unsigned long*) vinfo
.v_baseaddr
;;
814 endp
= (unsigned long*) vinfo
.v_baseaddr
;
816 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
819 case 0: /* To end of screen */
821 if (y
< vinfo
.v_rows
- 1) {
822 p
+= (y
+ 1) * linelongs
;
823 endp
+= rowlongs
* vinfo
.v_height
;
826 case 1: /* To start of screen */
829 endp
+= (y
+ 1) * linelongs
;
832 case 2: /* Whole screen */
833 endp
+= rowlongs
* vinfo
.v_height
;
837 for (row
= p
; row
< endp
; row
+= rowlongs
) {
838 for (col
= 0; col
< rowline
; col
++)
839 *(row
+col
) = vc_color_back
;
849 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
850 tab_stops
[i
] = ((i
% 8) == 0);
860 scrreg_bottom
= vinfo
.v_rows
;
862 vc_charset
[0] = vc_charset
[1] = 0;
863 vc_charset_select
= 0;
865 vc_relative_origin
= 0;
866 vc_color_set(VC_RESET_BACKGROUND
);
867 vc_color_set(VC_RESET_FOREGROUND
);
872 putc_normal(unsigned char ch
)
875 case '\a': /* Beep */
877 if ( FALSE
&& !IS_TEXT_MODE
) {
879 * No sound hardware, invert the screen twice instead
883 /* XOR the screen twice */
884 for (i
= 0; i
< 2 ; i
++) {
885 /* For each row, xor the scanbytes */
886 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
887 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
888 (vinfo
.v_height
* vinfo
.v_rowbytes
));
889 ptr
+= (vinfo
.v_rowbytes
/
890 sizeof (unsigned long*)))
892 j
< vinfo
.v_rowscanbytes
/
893 sizeof (unsigned long*);
901 case 127: /* Delete */
902 case '\b': /* Backspace */
903 if (hanging_cursor
) {
911 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
912 if (x
>= vinfo
.v_columns
)
913 x
= vinfo
.v_columns
-1;
917 case '\n': /* Line feed */
918 if (y
>= scrreg_bottom
-1 ) {
920 y
= scrreg_bottom
- 1;
924 /*break; Pass thru */
925 case '\r': /* Carriage return */
929 case 0x0e: /* Select G1 charset (Control-N) */
930 vc_charset_select
= 1;
932 case 0x0f: /* Select G0 charset (Control-O) */
933 vc_charset_select
= 0;
935 case 0x18 : /* CAN : cancel */
936 case 0x1A : /* like cancel */
937 /* well, i do nothing here, may be later */
939 case '\033': /* Escape */
945 if (hanging_cursor
) {
947 if (y
>= scrreg_bottom
-1 ) {
949 y
= scrreg_bottom
- 1;
955 vc_ops
.paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
957 if (x
== vinfo
.v_columns
- 1) {
958 hanging_cursor
= vc_wrap_mode
;
969 putc_esc(unsigned char ch
)
971 vt100state
= ESnormal
;
975 vt100state
= ESsquare
;
977 case 'c': /* Reset terminal */
979 vc_ops
.clear_screen(x
, y
, 2);
982 case 'D': /* Line feed */
984 if (y
>= scrreg_bottom
-1) {
986 y
= scrreg_bottom
- 1;
990 if (ch
== 'E') x
= 0;
992 case 'H': /* Set tab stop */
995 case 'M': /* Cursor up */
996 if (y
<= scrreg_top
) {
997 vc_ops
.scrolldown(1);
1006 case '7': /* Save cursor */
1010 vc_save_charset_s
= vc_charset_select
;
1011 vc_charset_save
[0] = vc_charset
[0];
1012 vc_charset_save
[1] = vc_charset
[1];
1014 case '8': /* Restore cursor */
1018 vc_charset_select
= vc_save_charset_s
;
1019 vc_charset
[0] = vc_charset_save
[0];
1020 vc_charset
[1] = vc_charset_save
[1];
1022 case 'Z': /* return terminal ID */
1024 case '#': /* change characters height */
1025 vt100state
= EScharsize
;
1028 vt100state
= ESsetG0
;
1030 case ')': /* character set sequence */
1031 vt100state
= ESsetG1
;
1036 /* Rest not supported */
1043 putc_askcmd(unsigned char ch
)
1045 if (ch
>= '0' && ch
<= '9') {
1046 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1049 vt100state
= ESnormal
;
1053 vc_relative_origin
= ch
== 'h';
1055 case 7: /* wrap around mode h=1, l=0*/
1056 vc_wrap_mode
= ch
== 'h';
1065 putc_charsizecmd(unsigned char ch
)
1067 vt100state
= ESnormal
;
1075 case '8' : /* fill 'E's */
1078 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1079 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1080 vc_ops
.paintchar('E', xx
, yy
, ATTR_NONE
);
1088 putc_charsetcmd(int charset
, unsigned char ch
)
1090 vt100state
= ESnormal
;
1096 vc_charset
[charset
] = 0;
1098 case '0' : /* Graphic characters */
1100 vc_charset
[charset
] = 0x21;
1107 putc_gotpars(unsigned char ch
)
1112 /* special case for vttest for handling cursor
1113 movement in escape sequences */
1115 vt100state
= ESgotpars
;
1118 vt100state
= ESnormal
;
1121 y
-= par
[0] ? par
[0] : 1;
1125 case 'B': /* Down */
1126 y
+= par
[0] ? par
[0] : 1;
1127 if (y
>= scrreg_bottom
)
1128 y
= scrreg_bottom
- 1;
1130 case 'C': /* Right */
1131 x
+= par
[0] ? par
[0] : 1;
1132 if (x
>= vinfo
.v_columns
)
1133 x
= vinfo
.v_columns
-1;
1135 case 'D': /* Left */
1136 x
-= par
[0] ? par
[0] : 1;
1140 case 'H': /* Set cursor position */
1142 x
= par
[1] ? par
[1] - 1 : 0;
1143 y
= par
[0] ? par
[0] - 1 : 0;
1144 if (vc_relative_origin
)
1148 case 'X': /* clear p1 characters */
1151 for (i
= x
; i
< x
+ par
[0]; i
++)
1152 vc_ops
.paintchar(' ', i
, y
, ATTR_NONE
);
1155 case 'J': /* Clear part of screen */
1156 vc_ops
.clear_screen(x
, y
, par
[0]);
1158 case 'K': /* Clear part of line */
1161 case 'g': /* tab stops */
1164 case 2: /* reset tab stops */
1167 case 3: /* Clear every tabs */
1171 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1180 case 'm': /* Set attribute */
1181 for (i
= 0; i
< numpars
; i
++) {
1185 vc_color_set(VC_RESET_BACKGROUND
);
1186 vc_color_set(VC_RESET_FOREGROUND
);
1195 attr
|= ATTR_REVERSE
;
1201 attr
&= ~ATTR_UNDER
;
1204 attr
&= ~ATTR_REVERSE
;
1207 case 25: /* blink/no blink */
1210 vc_color_set(par
[i
]);
1215 case 'r': /* Set scroll region */
1217 /* ensure top < bottom, and both within limits */
1218 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1219 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1225 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1226 scrreg_bottom
= par
[1];
1227 if (scrreg_bottom
> vinfo
.v_rows
)
1228 scrreg_bottom
= vinfo
.v_rows
;
1230 scrreg_bottom
= vinfo
.v_rows
;
1232 if (vc_relative_origin
)
1240 putc_getpars(unsigned char ch
)
1247 vt100state
= ESnormal
;
1251 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1254 if (ch
>= '0' && ch
<= '9') {
1256 par
[numpars
] += ch
- '0';
1259 vt100state
= ESgotpars
;
1265 putc_square(unsigned char ch
)
1269 for (i
= 0; i
< MAXPARS
; i
++) {
1274 vt100state
= ESgetpars
;
1284 return; /* ignore null characters */
1287 switch (vt100state
) {
1288 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1308 putc_charsizecmd(ch
);
1311 putc_charsetcmd(0, ch
);
1314 putc_charsetcmd(1, ch
);
1318 if (x
>= vinfo
.v_columns
) {
1319 x
= vinfo
.v_columns
- 1;
1324 if (y
>= vinfo
.v_rows
) {
1325 y
= vinfo
.v_rows
- 1;
1334 * Actually draws the buffer, handle the jump scroll
1336 void vc_flush_forward_buffer(void)
1338 if (vc_forward_buffer_size
) {
1340 vc_ops
.hide_cursor(x
, y
);
1344 int drawlen
= start
;
1346 int param
= 0, changebackground
= 0;
1347 enum vt100state_e vtState
= vt100state
;
1349 * In simple words, here we're pre-parsing the text to look for
1350 * + Newlines, for computing jump scroll
1351 * + /\033\[[0-9;]*]m/ to continue on
1352 * any other sequence will stop. We don't want to have cursor
1353 * movement escape sequences while we're trying to pre-scroll
1355 * We have to be extra carefull about the sequences that changes
1356 * the background color to prevent scrolling in those
1358 * That parsing was added to speed up 'man' and 'color-ls' a
1359 * zillion time (at least). It's worth it, trust me.
1360 * (mail Nick Stephen for a True Performance Graph)
1363 for (i
= start
; i
< vc_forward_buffer_size
&& plaintext
; i
++) {
1367 switch (vc_forward_buffer
[i
]) {
1377 switch (vc_forward_buffer
[i
]) {
1379 vtState
= ESgetpars
;
1381 changebackground
= 0;
1389 if ((vc_forward_buffer
[i
] >= '0' &&
1390 vc_forward_buffer
[i
] <= '9') ||
1391 vc_forward_buffer
[i
] == ';') {
1392 if (vc_forward_buffer
[i
] >= '0' &&
1393 vc_forward_buffer
[i
] <= '9')
1394 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1396 if (param
>= 40 && param
<= 47)
1397 changebackground
= 1;
1398 if (!vc_normal_background
&&
1400 changebackground
= 1;
1403 break; /* continue on */
1405 vtState
= ESgotpars
;
1408 switch (vc_forward_buffer
[i
]) {
1411 if (param
>= 40 && param
<= 47)
1412 changebackground
= 1;
1413 if (!vc_normal_background
&&
1415 changebackground
= 1;
1416 if (changebackground
) {
1419 /* REALLY don't jump */
1421 /* Yup ! we've got it */
1436 * Then we look if it would be appropriate to forward jump
1437 * the screen before drawing
1439 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1440 jump
-= scrreg_bottom
- y
- 1;
1442 if (jump
>= scrreg_bottom
- scrreg_top
)
1443 jump
= scrreg_bottom
- scrreg_top
-1;
1445 vc_ops
.scrollup(jump
);
1449 * and we draw what we've found to the parser
1451 for (i
= start
; i
< drawlen
; i
++)
1452 vc_putchar(vc_forward_buffer
[start
++]);
1454 * Continue sending characters to the parser until we're sure we're
1455 * back on normal characters.
1457 for (i
= start
; i
< vc_forward_buffer_size
&&
1458 vt100state
!= ESnormal
; i
++)
1459 vc_putchar(vc_forward_buffer
[start
++]);
1460 /* Then loop again if there still things to draw */
1461 } while (start
< vc_forward_buffer_size
);
1462 vc_forward_buffer_size
= 0;
1463 vc_ops
.show_cursor(x
, y
);
1468 vcputc(int l
, int u
, int c
)
1470 if ( vc_initialized
)
1473 vc_flush_forward_buffer();
1479 * Immediate character display.. kernel printf uses this. Make sure
1480 * pre-clock printfs get flushed and that panics get fully displayed.
1483 void cnputc(char ch
)
1489 * Store characters to be drawn 'later', handle overflows
1493 vc_store_char(unsigned char c
)
1496 /* Either we're really buffering stuff or we're not yet because
1497 * the probe hasn't been done. If we're not, then we can only
1498 * ever have a maximum of one character in the buffer waiting to
1502 vc_forward_buffer
[vc_forward_buffer_size
++] = (unsigned char)c
;
1504 switch (vc_forward_buffer_size
) {
1506 /* If we're adding the first character to the buffer,
1507 * start the timer, otherwise it is already running.
1510 case VC_MAX_FORWARD_SIZE
:
1511 vc_flush_forward_buffer();
1515 * the character will be flushed on timeout
1522 vc_initialize(struct vc_info
* vinfo_p
)
1524 vinfo
.v_rows
= vinfo
.v_height
/ CHARHEIGHT
;
1525 vinfo
.v_columns
= vinfo
.v_width
/ CHARWIDTH
;
1527 if (vinfo
.v_depth
>= 8) {
1528 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1530 vinfo
.v_rowscanbytes
= vinfo
.v_width
/ (8 / vinfo
.v_depth
);
1533 vc_render_font(1, vinfo
.v_depth
);
1534 vc_color_mask
= vc_color_depth_masks
[vc_color_index_table
[vinfo
.v_depth
]];
1536 switch (vinfo
.v_depth
) {
1539 vc_ops
.paintchar
= vc_paint_char1
;
1542 vc_ops
.paintchar
= vc_paint_char2
;
1545 vc_ops
.paintchar
= vc_paint_char4
;
1548 vc_ops
.paintchar
= vc_paint_char8c
;
1551 vc_ops
.paintchar
= vc_paint_char16c
;
1554 vc_ops
.paintchar
= vc_paint_char32c
;
1562 if (vinfo
.v_depth
>= 8)
1563 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1564 printf("video console at 0x%lx (%ldx%ldx%ld)\n", vinfo
.v_baseaddr
,
1565 vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_depth
);
1567 #if 0 // XXX - FIXME
1569 * Added for the buffering and jump scrolling
1572 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1574 vc_forward_buffer_enabled
= 1;
1575 #else // FIXME TOO!!!
1577 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1582 struct vc_progress_element
{
1583 unsigned int version
;
1586 unsigned char count
;
1587 unsigned char res
[3];
1593 unsigned int res2
[3];
1594 unsigned char data
[0];
1596 typedef struct vc_progress_element vc_progress_element
;
1598 static vc_progress_element
* vc_progress
;
1599 static const unsigned char * vc_progress_data
;
1600 static const unsigned char * vc_progress_alpha
;
1601 static boolean_t vc_progress_enable
;
1602 static const unsigned char * vc_clut
;
1603 static const unsigned char * vc_clut8
;
1604 static unsigned int vc_progress_tick
;
1605 static boolean_t vc_graphics_mode
;
1606 static boolean_t vc_acquired
;
1607 static boolean_t vc_need_clear
;
1608 static boolean_t vc_needsave
;
1609 static vm_address_t vc_saveunder
;
1610 static vm_size_t vc_saveunder_len
;
1612 void vc_blit_rect_8c( int x
, int y
,
1613 int width
, int height
,
1614 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1615 unsigned char * backPtr
, boolean_t save
)
1617 volatile unsigned char * dst
;
1621 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1622 (y
* vinfo
.v_rowbytes
) +
1625 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1626 (y
* vinfo
.v_rowbytes
) +
1629 for( line
= 0; line
< height
; line
++) {
1630 for( col
= 0; col
< width
; col
++)
1631 *(dst
+ col
) = *dataPtr
++;
1632 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1636 void vc_blit_rect_16( int x
, int y
,
1637 int width
, int height
,
1638 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1639 unsigned short * backPtr
, boolean_t save
)
1641 volatile unsigned short * dst
;
1643 unsigned int data
, index
, alpha
, back
;
1645 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
1646 (y
* vinfo
.v_rowbytes
) +
1649 for( line
= 0; line
< height
; line
++) {
1650 for( col
= 0; col
< width
; col
++) {
1654 if( alphaPtr
&& backPtr
&& (alpha
= *alphaPtr
++)) {
1657 if( vc_clut
[index
+ 0] > alpha
)
1658 data
|= (((vc_clut
[index
+ 0] - alpha
) & 0xf8) << 7);
1659 if( vc_clut
[index
+ 1] > alpha
)
1660 data
|= (((vc_clut
[index
+ 1] - alpha
) & 0xf8) << 2);
1661 if( vc_clut
[index
+ 2] > alpha
)
1662 data
|= (((vc_clut
[index
+ 2] - alpha
) & 0xf8) >> 3);
1665 back
= *(dst
+ col
);
1667 back
= (((((back
& 0x7c1f) * alpha
) + 0x7c1f) >> 5) & 0x7c1f)
1668 | (((((back
& 0x03e0) * alpha
) + 0x03e0) >> 5) & 0x03e0);
1676 data
= ( (0xf8 & (vc_clut
[index
+ 0])) << 7)
1677 | ( (0xf8 & (vc_clut
[index
+ 1])) << 2)
1678 | ( (0xf8 & (vc_clut
[index
+ 2])) >> 3);
1680 *(dst
+ col
) = data
;
1682 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
1686 void vc_blit_rect_32( unsigned int x
, unsigned int y
,
1687 unsigned int width
, unsigned int height
,
1688 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1689 unsigned int * backPtr
, boolean_t save
)
1691 volatile unsigned int * dst
;
1693 unsigned int data
, index
, alpha
, back
;
1695 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
1696 (y
* vinfo
.v_rowbytes
) +
1699 for( line
= 0; line
< height
; line
++) {
1700 for( col
= 0; col
< width
; col
++) {
1703 if( alphaPtr
&& backPtr
&& (alpha
= *alphaPtr
++)) {
1706 if( vc_clut
[index
+ 0] > alpha
)
1707 data
|= ((vc_clut
[index
+ 0] - alpha
) << 16);
1708 if( vc_clut
[index
+ 1] > alpha
)
1709 data
|= ((vc_clut
[index
+ 1] - alpha
) << 8);
1710 if( vc_clut
[index
+ 2] > alpha
)
1711 data
|= ((vc_clut
[index
+ 2] - alpha
));
1714 back
= *(dst
+ col
);
1715 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
1716 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
1724 data
= (vc_clut
[index
+ 0] << 16)
1725 | (vc_clut
[index
+ 1] << 8)
1726 | (vc_clut
[index
+ 2]);
1728 *(dst
+ col
) = data
;
1730 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
1734 void vc_blit_rect( unsigned int x
, unsigned int y
,
1735 unsigned int width
, unsigned int height
,
1736 const unsigned char * dataPtr
, const unsigned char * alphaPtr
,
1737 vm_address_t backBuffer
, boolean_t save
)
1739 if(!vinfo
.v_baseaddr
)
1742 switch( vinfo
.v_depth
) {
1744 if( vc_clut8
== vc_clut
)
1745 vc_blit_rect_8c( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned char *) backBuffer
, save
);
1748 vc_blit_rect_16( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned short *) backBuffer
, save
);
1751 vc_blit_rect_32( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned int *) backBuffer
, save
);
1756 void vc_progress_task( void * arg
)
1759 int count
= (int) arg
;
1760 int x
, y
, width
, height
;
1761 const unsigned char * data
;
1764 simple_lock(&vc_forward_lock
);
1766 if( vc_progress_enable
) {
1769 if( count
>= vc_progress
->count
)
1772 width
= vc_progress
->width
;
1773 height
= vc_progress
->height
;
1774 x
= vc_progress
->dx
;
1775 y
= vc_progress
->dy
;
1776 data
= vc_progress_data
;
1777 data
+= count
* width
* height
;
1778 if( 1 & vc_progress
->flags
) {
1779 x
+= ((vinfo
.v_width
- width
) / 2);
1780 y
+= ((vinfo
.v_height
- height
) / 2);
1782 vc_blit_rect( x
, y
, width
, height
,
1783 data
, vc_progress_alpha
, vc_saveunder
, vc_needsave
);
1784 vc_needsave
= FALSE
;
1786 timeout( vc_progress_task
, (void *) count
,
1789 simple_unlock(&vc_forward_lock
);
1793 void vc_display_icon( vc_progress_element
* desc
,
1794 const unsigned char * data
)
1796 int x
, y
, width
, height
;
1798 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
1800 width
= desc
->width
;
1801 height
= desc
->height
;
1804 if( 1 & desc
->flags
) {
1805 x
+= ((vinfo
.v_width
- width
) / 2);
1806 y
+= ((vinfo
.v_height
- height
) / 2);
1808 vc_blit_rect( x
, y
, width
, height
, data
, NULL
, (vm_address_t
) NULL
, FALSE
);
1813 vc_progress_set( boolean_t enable
, unsigned int initial_tick
)
1816 vm_address_t saveBuf
= 0;
1817 vm_size_t saveLen
= 0;
1823 saveLen
= vc_progress
->width
* vc_progress
->height
* vinfo
.v_depth
/ 8;
1824 saveBuf
= kalloc( saveLen
);
1828 simple_lock(&vc_forward_lock
);
1830 if( vc_progress_enable
!= enable
) {
1831 vc_progress_enable
= enable
;
1834 vc_saveunder
= saveBuf
;
1835 vc_saveunder_len
= saveLen
;
1838 timeout(vc_progress_task
, (void *) 0,
1843 saveBuf
= vc_saveunder
;
1844 saveLen
= vc_saveunder_len
;
1846 vc_saveunder_len
= 0;
1848 untimeout( vc_progress_task
, (void *) 0 );
1852 simple_unlock(&vc_forward_lock
);
1856 kfree( saveBuf
, saveLen
);
1863 vc_progress_initialize( vc_progress_element
* desc
,
1864 const unsigned char * data
,
1865 const unsigned char * clut
)
1867 if( (!clut
) || (!desc
) || (!data
))
1873 vc_progress_data
= data
;
1874 if( 2 & vc_progress
->flags
)
1875 vc_progress_alpha
= vc_progress_data
1876 + vc_progress
->count
* vc_progress
->width
* vc_progress
->height
;
1878 vc_progress_alpha
= NULL
;
1879 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
1884 extern int disableConsoleOutput
;
1886 void vc_clear_screen( void )
1888 vc_ops
.hide_cursor(x
, y
);
1891 vc_ops
.clear_screen(x
, y
, 2);
1892 vc_ops
.show_cursor(x
, y
);
1896 initialize_screen(Boot_Video
* boot_vinfo
, int op
)
1900 vinfo
.v_width
= boot_vinfo
->v_width
;
1901 vinfo
.v_height
= boot_vinfo
->v_height
;
1902 vinfo
.v_depth
= boot_vinfo
->v_depth
;
1903 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
1904 vinfo
.v_baseaddr
= boot_vinfo
->v_baseAddr
;
1905 vinfo
.v_type
= boot_vinfo
->v_display
;
1909 // Text mode setup by the booter.
1911 vc_ops
.initialize
= tc_initialize
;
1912 vc_ops
.paintchar
= tc_putchar
;
1913 vc_ops
.scrolldown
= tc_scrolldown
;
1914 vc_ops
.scrollup
= tc_scrollup
;
1915 vc_ops
.clear_screen
= tc_clear_screen
;
1916 vc_ops
.hide_cursor
= tc_hide_cursor
;
1917 vc_ops
.show_cursor
= tc_show_cursor
;
1918 vc_ops
.update_color
= tc_update_color
;
1922 // Graphics mode setup by the booter.
1924 vc_ops
.initialize
= vc_initialize
;
1925 vc_ops
.paintchar
= 0;
1926 vc_ops
.scrolldown
= scrolldown
;
1927 vc_ops
.scrollup
= scrollup
;
1928 vc_ops
.clear_screen
= clear_screen
;
1929 vc_ops
.hide_cursor
= reversecursor
;
1930 vc_ops
.show_cursor
= reversecursor
;
1931 vc_ops
.update_color
= 0;
1934 vc_ops
.initialize(&vinfo
);
1936 // vc_clear_screen();
1943 case kPEGraphicsMode
:
1944 vc_graphics_mode
= TRUE
;
1945 disableConsoleOutput
= TRUE
;
1950 vc_graphics_mode
= FALSE
;
1951 disableConsoleOutput
= FALSE
;
1957 vc_progress_set( FALSE
, 0 );
1958 disableConsoleOutput
= FALSE
;
1959 if( vc_need_clear
) {
1960 vc_need_clear
= FALSE
;
1965 case kPEEnableScreen
:
1967 if( vc_graphics_mode
)
1968 vc_progress_set( TRUE
, vc_progress_tick
);
1974 case kPEDisableScreen
:
1975 vc_progress_set( FALSE
, 0 );
1978 case kPEAcquireScreen
:
1979 vc_need_clear
= (FALSE
== vc_acquired
);
1981 vc_progress_set( vc_graphics_mode
, vc_need_clear
? 2 * hz
: 0 );
1982 disableConsoleOutput
= vc_graphics_mode
;
1983 if( vc_need_clear
&& !vc_graphics_mode
) {
1984 vc_need_clear
= FALSE
;
1989 case kPEReleaseScreen
:
1990 vc_acquired
= FALSE
;
1991 vc_progress_set( FALSE
, 0 );
1993 disableConsoleOutput
= TRUE
;