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
104 #include <mach_kdb.h>
105 #include <kern/spl.h>
106 #include <machine/machparam.h> /* spl definitions */
108 #include <ppc/iso_font.h>
109 #include <ppc/Firmware.h>
111 #include <ppc/POWERMAC/video_console_entries.h>
112 #include <ppc/POWERMAC/video_console.h>
113 #include <pexpert/pexpert.h>
114 #include <kern/time_out.h>
115 #include <kern/lock.h>
116 #include <kern/debug.h>
117 #include <mach/vm_param.h>
118 #include <vm/vm_kern.h>
119 #include <vm/vm_map.h>
120 #include <vm/vm_page.h>
121 #include <ppc/pmap.h>
123 #include <kdp/kdp_udp.h>
125 #include "panic_image.c"
126 #include "rendered_numbers.c"
129 #define FAST_JUMP_SCROLL
132 #define CHARHEIGHT 16
137 #define ATTR_REVERSE 4
140 ESnormal
, /* Nothing yet */
142 ESsquare
, /* Got ESC [ */
143 ESgetpars
, /* About to get or getting the parameters */
144 ESgotpars
, /* Finished getting the parameters */
145 ESfunckey
, /* Function key */
146 EShash
, /* DEC-specific stuff (screen align, etc.) */
147 ESsetG0
, /* Specify the G0 character set */
148 ESsetG1
, /* Specify the G1 character set */
151 ESignore
/* Ignore this sequence */
152 } vt100state
= ESnormal
;
154 struct vc_info vinfo
;
156 /* Calculated in vccninit(): */
157 static int vc_wrap_mode
= 1, vc_relative_origin
= 0;
158 static int vc_charset_select
= 0, vc_save_charset_s
= 0;
159 static int vc_charset
[2] = { 0, 0 };
160 static int vc_charset_save
[2] = { 0, 0 };
164 static int x
= 0, y
= 0, savex
, savey
;
165 static int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
167 /* VT100 tab stops & scroll region */
168 static char tab_stops
[255];
169 static int scrreg_top
, scrreg_bottom
;
172 static void vc_initialize(void);
173 static void vc_flush_forward_buffer(void);
174 static void vc_store_char(unsigned char);
175 static void vc_putchar(char ch
);
179 /* panic dialog and info saving */
180 int mac_addr_digit_x
;
181 int mac_addr_digit_y
;
182 static void blit_digit( int digit
);
183 boolean_t panicDialogDrawn
= FALSE
;
186 panic_blit_rect( unsigned int x
, unsigned int y
,
187 unsigned int width
, unsigned int height
,
188 int transparent
, unsigned char * dataPtr
);
191 panic_blit_rect_8( unsigned int x
, unsigned int y
,
192 unsigned int width
, unsigned int height
,
193 int transparent
, unsigned char * dataPtr
);
196 panic_blit_rect_16( unsigned int x
, unsigned int y
,
197 unsigned int width
, unsigned int height
,
198 int transparent
, unsigned char * dataPtr
);
201 panic_blit_rect_32( unsigned int x
, unsigned int y
,
202 unsigned int width
, unsigned int height
,
203 int transparent
, unsigned char * dataPtr
);
206 blit_rect_of_size_and_color( unsigned int x
, unsigned int y
,
207 unsigned int width
, unsigned int height
,
208 unsigned int dataPtr
);
225 * For the color support (Michel Pollet)
227 static unsigned char vc_color_index_table
[33] =
228 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
231 static unsigned long vc_color_depth_masks
[4] =
232 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
234 static unsigned long vc_colors
[8][3] = {
235 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
236 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
237 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
238 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
239 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
240 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
241 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
242 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
243 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
246 static unsigned long vc_color_mask
= 0;
247 static unsigned long vc_color_fore
= 0;
248 static unsigned long vc_color_back
= 0;
249 static int vc_normal_background
= 1;
253 * For the jump scroll and buffering (Michel Pollet)
254 * 80*22 means on a 80*24 screen, the screen will
255 * scroll jump almost a full screen
256 * keeping only what's necessary for you to be able to read ;-)
258 #define VC_MAX_FORWARD_SIZE (100*36)
261 * Delay between console updates in clock hz units, the larger the
262 * delay the fuller the jump-scroll buffer will be and so the faster the
263 * (scrolling) output. The smaller the delay, the less jerky the
264 * display. Heuristics show that at 10 touch-typists (Mike!) complain
266 #define VC_CONSOLE_UPDATE_TIMEOUT 5
268 static unsigned char vc_forward_buffer
[VC_MAX_FORWARD_SIZE
];
269 static long vc_forward_buffer_size
= 0;
270 static int vc_forward_buffer_enabled
= 0;
271 static int vc_forward_buffer_busy
= 0;
272 decl_simple_lock_data(,vc_forward_lock
)
274 #ifdef FAST_JUMP_SCROLL
275 static void (*vc_forward_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
281 } vc_forward_preflight_mode
= PFoff
;
283 enum vt100state_e vt100state
;
285 int vc_wrap_mode
, vc_relative_origin
;
286 int vc_charset_select
, vc_save_charset_s
;
288 int vc_charset_save
[2];
290 int x
, y
, savex
, savey
;
291 int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
294 int scrreg_top
, scrreg_bottom
;
296 unsigned long vc_color_fore
;
297 unsigned long vc_color_back
;
298 } vc_forward_preflight_save
;
299 static int vc_forward_scroll
= 0;
300 #endif FAST_JUMP_SCROLL
303 * New Rendering code from Michel Pollet
306 /* That function will be called for drawing */
307 static void (*vc_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
309 #ifdef RENDERALLOCATE
310 static unsigned char *renderedFont
= NULL
; /* rendered font buffer */
312 #define REN_MAX_DEPTH 32
313 /* that's the size for a 32 bits buffer... */
314 #define REN_MAX_SIZE (128L*1024)
315 static unsigned char renderedFont
[REN_MAX_SIZE
];
318 /* Rendered Font Size */
319 static unsigned long vc_rendered_font_size
= REN_MAX_SIZE
;
320 static long vc_rendered_error
= 0;
322 /* If the one bit table was reversed */
323 static short vc_one_bit_reversed
= 0;
325 /* Size of a character in the table (bytes) */
326 static int vc_rendered_char_size
= 0;
330 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
332 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
333 # Background color codes:
334 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
337 #define VC_RESET_BACKGROUND 40
338 #define VC_RESET_FOREGROUND 37
340 static void vc_color_set(int color
)
342 if (vinfo
.v_depth
< 8)
344 if (color
>= 30 && color
<= 37)
345 vc_color_fore
= vc_colors
[color
-30][vc_color_index_table
[vinfo
.v_depth
]];
346 if (color
>= 40 && color
<= 47) {
347 vc_color_back
= vc_colors
[color
-40][vc_color_index_table
[vinfo
.v_depth
]];
348 vc_normal_background
= color
== 40;
353 static void vc_render_font(short olddepth
, short newdepth
)
355 int charIndex
; /* index in ISO font */
357 unsigned char *charptr
;
358 unsigned short *shortptr
;
359 unsigned long *longptr
;
360 } current
; /* current place in rendered font, multiple types. */
362 unsigned char *theChar
; /* current char in iso_font */
364 if (olddepth
== newdepth
&& renderedFont
) {
365 return; /* nothing to do */
368 if (olddepth
!= 1 && renderedFont
) {
369 #ifdef RENDERALLOCATE
370 (void) kmem_free(kernel_map
, (vm_offset_t
*)renderedFont
, vc_rendered_font_size
);
373 vc_rendered_font_size
= REN_MAX_SIZE
;
375 #ifdef RENDERALLOCATE
376 renderedFont
= iso_font
;
378 vc_rendered_char_size
= 16;
379 if (!vc_one_bit_reversed
) { /* reverse the font for the blitter */
381 for (i
= 0; i
< ((ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
); i
++) {
383 unsigned char mask1
= 0x80;
384 unsigned char mask2
= 0x01;
385 unsigned char val
= 0;
387 if (iso_font
[i
] & mask1
)
392 renderedFont
[i
] = ~val
;
393 } else renderedFont
[i
] = 0xff;
395 vc_one_bit_reversed
= 1;
400 long csize
= newdepth
/ 8; /* bytes per pixel */
401 vc_rendered_char_size
= csize
? CHARHEIGHT
* (csize
* CHARWIDTH
) :
402 /* for 2 & 4 */ CHARHEIGHT
* (CHARWIDTH
/(6-newdepth
));
403 csize
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
;
404 #ifndef RENDERALLOCATE
405 if (csize
> vc_rendered_font_size
) {
406 vc_rendered_error
= csize
;
409 vc_rendered_font_size
= csize
;
411 vc_rendered_font_size
= csize
;
415 #ifdef RENDERALLOCATE
416 if (kmem_alloc(kernel_map
,
417 (vm_offset_t
*)&renderedFont
,
418 vc_rendered_font_size
) != KERN_SUCCESS
) {
420 vc_rendered_error
= vc_rendered_font_size
;
424 current
.charptr
= renderedFont
;
426 for (charIndex
= ISO_CHAR_MIN
; charIndex
<= ISO_CHAR_MAX
; charIndex
++) {
428 for (line
= 0; line
< CHARHEIGHT
; line
++) {
429 unsigned char mask
= 1;
433 unsigned char value
= 0;
434 if (*theChar
& mask
) value
|= 0xC0; mask
<<= 1;
435 if (*theChar
& mask
) value
|= 0x30; mask
<<= 1;
436 if (*theChar
& mask
) value
|= 0x0C; mask
<<= 1;
437 if (*theChar
& mask
) value
|= 0x03;
439 *current
.charptr
++ = value
;
444 unsigned char value
= 0;
445 if (*theChar
& mask
) value
|= 0xF0; mask
<<= 1;
446 if (*theChar
& mask
) value
|= 0x0F;
448 *current
.charptr
++ = value
;
452 *current
.charptr
++ = (*theChar
& mask
) ? 0xff : 0;
455 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
459 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
463 } while (mask
); /* while the single bit drops to the right */
469 #ifdef FAST_JUMP_SCROLL
470 static void vc_paint_char(unsigned char ch
, int xx
, int yy
, int attrs
)
472 switch (vc_forward_preflight_mode
) {
474 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
481 if (yy
>= scrreg_top
&& yy
< scrreg_bottom
) {
482 yy
-= vc_forward_scroll
;
483 if (yy
< scrreg_top
|| yy
>= scrreg_bottom
)
486 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
490 #endif FAST_JUMP_SCROLL
492 static void vc_paint_char1(unsigned char ch
, int xx
, int yy
, int attrs
)
494 unsigned char *theChar
;
495 unsigned char *where
;
498 theChar
= (unsigned char*)(renderedFont
+ (ch
* vc_rendered_char_size
));
499 where
= (unsigned char*)(vinfo
.v_baseaddr
+
500 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
503 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
506 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
507 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
508 unsigned char val
= *theChar
++, save
= val
;
509 if (attrs
& ATTR_BOLD
) { /* bold support */
510 unsigned char mask1
= 0xC0, mask2
= 0x40;
512 for (bit
= 0; bit
< 7; bit
++) {
513 if ((save
& mask1
) == mask2
)
519 if (attrs
& ATTR_REVERSE
) val
= ~val
;
520 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
523 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
528 static void vc_paint_char2(unsigned char ch
, int xx
, int yy
, int attrs
)
530 unsigned short *theChar
;
531 unsigned short *where
;
534 theChar
= (unsigned short*)(renderedFont
+ (ch
* vc_rendered_char_size
));
535 where
= (unsigned short*)(vinfo
.v_baseaddr
+
536 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
538 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
541 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
542 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
543 unsigned short val
= *theChar
++, save
= val
;
544 if (attrs
& ATTR_BOLD
) { /* bold support */
545 unsigned short mask1
= 0xF000, mask2
= 0x3000;
547 for (bit
= 0; bit
< 7; bit
++) {
548 if ((save
& mask1
) == mask2
)
554 if (attrs
& ATTR_REVERSE
) val
= ~val
;
555 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
558 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
563 static void vc_paint_char4(unsigned char ch
, int xx
, int yy
, int attrs
)
565 unsigned long *theChar
;
566 unsigned long *where
;
569 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
570 where
= (unsigned long*)(vinfo
.v_baseaddr
+
571 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
574 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
577 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
578 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
579 unsigned long val
= *theChar
++, save
= val
;
580 if (attrs
& ATTR_BOLD
) { /* bold support */
581 unsigned long mask1
= 0xff000000, mask2
= 0x0F000000;
583 for (bit
= 0; bit
< 7; bit
++) {
584 if ((save
& mask1
) == mask2
)
590 if (attrs
& ATTR_REVERSE
) val
= ~val
;
591 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
594 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
599 static void vc_paint_char8c(unsigned char ch
, int xx
, int yy
, int attrs
)
601 unsigned long *theChar
;
602 unsigned long *where
;
605 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
606 where
= (unsigned long*)(vinfo
.v_baseaddr
+
607 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
610 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attr? FLY !*/
611 unsigned long *store
= where
;
613 for (x
= 0; x
< 2; x
++) {
614 unsigned long val
= *theChar
++;
615 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
619 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
620 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
621 unsigned long *store
= where
, lastpixel
= 0;
623 for (x
= 0 ; x
< 2; x
++) {
624 unsigned long val
= *theChar
++, save
= val
;
625 if (attrs
& ATTR_BOLD
) { /* bold support */
626 if (lastpixel
&& !(save
& 0xFF000000))
628 if ((save
& 0xFFFF0000) == 0xFF000000)
630 if ((save
& 0x00FFFF00) == 0x00FF0000)
632 if ((save
& 0x0000FFFF) == 0x0000FF00)
635 if (attrs
& ATTR_REVERSE
) val
= ~val
;
636 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
638 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
640 lastpixel
= save
& 0xff;
643 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
647 static void vc_paint_char16c(unsigned char ch
, int xx
, int yy
, int attrs
)
649 unsigned long *theChar
;
650 unsigned long *where
;
653 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
654 where
= (unsigned long*)(vinfo
.v_baseaddr
+
655 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
656 (xx
* CHARWIDTH
* 2));
658 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
659 unsigned long *store
= where
;
661 for (x
= 0; x
< 4; x
++) {
662 unsigned long val
= *theChar
++;
663 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
667 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
668 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
669 unsigned long *store
= where
, lastpixel
= 0;
671 for (x
= 0 ; x
< 4; x
++) {
672 unsigned long val
= *theChar
++, save
= val
;
673 if (attrs
& ATTR_BOLD
) { /* bold support */
674 if (save
== 0xFFFF0000) val
|= 0xFFFF;
675 else if (lastpixel
&& !(save
& 0xFFFF0000))
678 if (attrs
& ATTR_REVERSE
) val
= ~val
;
679 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
681 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
684 lastpixel
= save
& 0x7fff;
687 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
691 static void vc_paint_char32c(unsigned char ch
, int xx
, int yy
, int attrs
)
693 unsigned long *theChar
;
694 unsigned long *where
;
697 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
698 where
= (unsigned long*)(vinfo
.v_baseaddr
+
699 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
700 (xx
* CHARWIDTH
* 4));
702 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
703 unsigned long *store
= where
;
705 for (x
= 0; x
< 8; x
++) {
706 unsigned long val
= *theChar
++;
707 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
711 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
712 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
713 unsigned long *store
= where
, lastpixel
= 0;
715 for (x
= 0 ; x
< 8; x
++) {
716 unsigned long val
= *theChar
++, save
= val
;
717 if (attrs
& ATTR_BOLD
) { /* bold support */
718 if (lastpixel
&& !save
)
721 if (attrs
& ATTR_REVERSE
) val
= ~val
;
722 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
724 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
729 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
735 * That's a plain dumb reverse of the cursor position
736 * It do a binary reverse, so it will not looks good when we have
737 * color support. we'll see that later
739 static void reversecursor(void)
742 unsigned char *charptr
;
743 unsigned short *shortptr
;
744 unsigned long *longptr
;
748 where
.longptr
= (unsigned long*)(vinfo
.v_baseaddr
+
749 (y
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
750 (x
/** CHARWIDTH*/ * vinfo
.v_depth
));
751 for (line
= 0; line
< CHARHEIGHT
; line
++) {
752 switch (vinfo
.v_depth
) {
754 *where
.charptr
= ~*where
.charptr
;
757 *where
.shortptr
= ~*where
.shortptr
;
760 *where
.longptr
= ~*where
.longptr
;
762 /* that code still exists because since characters on the screen are
763 * of different colors that reverse function may not work if the
764 * cursor is on a character that is in a different color that the
765 * current one. When we have buffering, things will work better. MP
767 #ifdef VC_BINARY_REVERSE
769 where
.longptr
[0] = ~where
.longptr
[0];
770 where
.longptr
[1] = ~where
.longptr
[1];
773 for (col
= 0; col
< 4; col
++)
774 where
.longptr
[col
] = ~where
.longptr
[col
];
777 for (col
= 0; col
< 8; col
++)
778 where
.longptr
[col
] = ~where
.longptr
[col
];
782 for (col
= 0; col
< 8; col
++)
783 where
.charptr
[col
] = where
.charptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
784 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
787 for (col
= 0; col
< 8; col
++)
788 where
.shortptr
[col
] = where
.shortptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
789 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
792 for (col
= 0; col
< 8; col
++)
793 where
.longptr
[col
] = where
.longptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
794 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
798 where
.charptr
+= vinfo
.v_rowbytes
;
806 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
808 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
809 rowline
= (vinfo
.v_rowbytes
) >> 2;
810 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
812 #ifdef FAST_JUMP_SCROLL
813 if (vc_forward_preflight_mode
== PFwind
) {
814 vc_forward_scroll
+= num
;
817 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
818 #endif FAST_JUMP_SCROLL
820 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
821 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
823 i
= (scrreg_bottom
- scrreg_top
) - num
;
826 for (line
= 0; line
< CHARHEIGHT
; line
++) {
828 * Only copy what is displayed
830 video_scroll_up((unsigned int) from
,
831 (unsigned int) (from
+(vinfo
.v_rowscanbytes
/4)),
839 /* Now set the freed up lines to the background colour */
842 to
= ((unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
))
843 + ((scrreg_bottom
- scrreg_top
- num
) * linelongs
);
845 #ifdef FAST_JUMP_SCROLL
846 if (vc_forward_preflight_mode
== PFscroll
)
848 } else if (vc_forward_preflight_mode
== PFunwind
) {
849 long linestart
, linelast
;
850 vc_forward_scroll
-= num
;
852 linestart
= scrreg_bottom
- num
- vc_forward_scroll
;
853 linelast
= linestart
+ num
- 1;
855 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
858 if (linelast
>= scrreg_bottom
)
859 linelast
= scrreg_bottom
- 1;
860 if (linestart
< scrreg_top
)
861 linestart
= scrreg_top
;
863 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
864 num
= linelast
- linestart
+ 1;
866 #endif FAST_JUMP_SCROLL
868 for (linelongs
= CHARHEIGHT
* num
; linelongs
-- > 0;) {
870 for (i
= 0; i
< rowscanline
; i
++)
871 *to
++ = vc_color_back
;
881 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
883 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
884 rowline
= (vinfo
.v_rowbytes
) >> 2;
885 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
887 #ifdef FAST_JUMP_SCROLL
888 if (vc_forward_preflight_mode
== PFwind
) {
889 vc_forward_scroll
-= num
;
892 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
893 #endif FAST_JUMP_SCROLL
895 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
896 - (rowline
- rowscanline
);
897 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
899 i
= (scrreg_bottom
- scrreg_top
) - num
;
902 for (line
= 0; line
< CHARHEIGHT
; line
++) {
904 * Only copy what is displayed
906 video_scroll_down((unsigned int) from
,
907 (unsigned int) (from
-(vinfo
.v_rowscanbytes
/4)),
915 /* Now set the freed up lines to the background colour */
917 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_top
);
919 #ifdef FAST_JUMP_SCROLL
920 if (vc_forward_preflight_mode
== PFscroll
)
922 } else if (vc_forward_preflight_mode
== PFunwind
) {
923 long linestart
, linelast
;
924 vc_forward_scroll
+= num
;
926 linestart
= scrreg_top
- vc_forward_scroll
;
927 linelast
= linestart
+ num
- 1;
929 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
932 if (linelast
>= scrreg_bottom
)
933 linelast
= scrreg_bottom
- 1;
934 if (linestart
< scrreg_top
)
935 linestart
= scrreg_top
;
937 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
938 num
= linelast
- linestart
+ 1;
940 #endif FAST_JUMP_SCROLL
942 for (line
= CHARHEIGHT
* num
; line
> 0; line
--) {
945 for (i
= 0; i
< rowscanline
; i
++)
946 *(to
++) = vc_color_back
;
955 clear_line(int which
)
960 * This routine runs extremely slowly. I don't think it's
961 * used all that often, except for To end of line. I'll go
962 * back and speed this up when I speed up the whole vc
967 case 0: /* To end of line */
969 end
= vinfo
.v_columns
-1;
971 case 1: /* To start of line */
975 case 2: /* Whole line */
977 end
= vinfo
.v_columns
-1;
981 for (i
= start
; i
<= end
; i
++) {
982 vc_paintchar(' ', i
, y
, ATTR_NONE
);
988 clear_screen(int which
)
990 unsigned long *p
, *endp
, *row
;
992 int rowline
, rowlongs
;
994 rowline
= vinfo
.v_rowscanbytes
/ 4;
995 rowlongs
= vinfo
.v_rowbytes
/ 4;
997 p
= (unsigned long*) vinfo
.v_baseaddr
;;
998 endp
= (unsigned long*) vinfo
.v_baseaddr
;
1000 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
1003 case 0: /* To end of screen */
1005 if (y
< vinfo
.v_rows
- 1) {
1006 p
+= (y
+ 1) * linelongs
;
1007 endp
+= rowlongs
* vinfo
.v_height
;
1010 case 1: /* To start of screen */
1013 endp
+= (y
+ 1) * linelongs
;
1016 case 2: /* Whole screen */
1017 endp
+= rowlongs
* vinfo
.v_height
;
1021 for (row
= p
; row
< endp
; row
+= rowlongs
) {
1022 for (col
= 0; col
< rowline
; col
++)
1023 *(row
+col
) = vc_color_back
;
1033 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
1034 tab_stops
[i
] = ((i
% 8) == 0);
1044 scrreg_bottom
= vinfo
.v_rows
;
1046 vc_charset
[0] = vc_charset
[1] = 0;
1047 vc_charset_select
= 0;
1049 vc_relative_origin
= 0;
1050 vc_color_set(VC_RESET_BACKGROUND
);
1051 vc_color_set(VC_RESET_FOREGROUND
);
1056 putc_normal(unsigned char ch
)
1059 case '\a': /* Beep */
1065 * No sound hardware, invert the screen twice instead
1069 /* XOR the screen twice */
1070 for (i
= 0; i
< 2 ; i
++) {
1071 /* For each row, xor the scanbytes */
1072 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
1073 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
1074 (vinfo
.v_height
* vinfo
.v_rowbytes
));
1075 ptr
+= (vinfo
.v_rowbytes
/
1076 sizeof (unsigned long*)))
1078 j
< vinfo
.v_rowscanbytes
/
1079 sizeof (unsigned long*);
1081 *(ptr
+j
) =~*(ptr
+j
);
1087 case 127: /* Delete */
1088 case '\b': /* Backspace */
1089 if (hanging_cursor
) {
1096 case '\t': /* Tab */
1097 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
1098 if (x
>= vinfo
.v_columns
)
1099 x
= vinfo
.v_columns
-1;
1103 case '\n': /* Line feed */
1104 if (y
>= scrreg_bottom
-1 ) {
1106 y
= scrreg_bottom
- 1;
1111 case '\r': /* Carriage return */
1115 case 0x0e: /* Select G1 charset (Control-N) */
1116 vc_charset_select
= 1;
1118 case 0x0f: /* Select G0 charset (Control-O) */
1119 vc_charset_select
= 0;
1121 case 0x18 : /* CAN : cancel */
1122 case 0x1A : /* like cancel */
1123 /* well, i do nothing here, may be later */
1125 case '\033': /* Escape */
1131 if (hanging_cursor
) {
1133 if (y
>= scrreg_bottom
-1 ) {
1135 y
= scrreg_bottom
- 1;
1141 vc_paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
1143 if (x
== vinfo
.v_columns
- 1) {
1144 hanging_cursor
= vc_wrap_mode
;
1155 putc_esc(unsigned char ch
)
1157 vt100state
= ESnormal
;
1161 vt100state
= ESsquare
;
1163 case 'c': /* Reset terminal */
1168 case 'D': /* Line feed */
1170 if (y
>= scrreg_bottom
-1) {
1172 y
= scrreg_bottom
- 1;
1176 if (ch
== 'E') x
= 0;
1178 case 'H': /* Set tab stop */
1181 case 'M': /* Cursor up */
1182 if (y
<= scrreg_top
) {
1192 case '7': /* Save cursor */
1196 vc_save_charset_s
= vc_charset_select
;
1197 vc_charset_save
[0] = vc_charset
[0];
1198 vc_charset_save
[1] = vc_charset
[1];
1200 case '8': /* Restore cursor */
1204 vc_charset_select
= vc_save_charset_s
;
1205 vc_charset
[0] = vc_charset_save
[0];
1206 vc_charset
[1] = vc_charset_save
[1];
1208 case 'Z': /* return terminal ID */
1210 case '#': /* change characters height */
1211 vt100state
= EScharsize
;
1214 vt100state
= ESsetG0
;
1216 case ')': /* character set sequence */
1217 vt100state
= ESsetG1
;
1222 /* Rest not supported */
1229 putc_askcmd(unsigned char ch
)
1231 if (ch
>= '0' && ch
<= '9') {
1232 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1235 vt100state
= ESnormal
;
1239 vc_relative_origin
= ch
== 'h';
1241 case 7: /* wrap around mode h=1, l=0*/
1242 vc_wrap_mode
= ch
== 'h';
1251 putc_charsizecmd(unsigned char ch
)
1253 vt100state
= ESnormal
;
1261 case '8' : /* fill 'E's */
1264 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1265 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1266 vc_paintchar('E', xx
, yy
, ATTR_NONE
);
1274 putc_charsetcmd(int charset
, unsigned char ch
)
1276 vt100state
= ESnormal
;
1282 vc_charset
[charset
] = 0;
1284 case '0' : /* Graphic characters */
1286 vc_charset
[charset
] = 0x21;
1293 putc_gotpars(unsigned char ch
)
1298 /* special case for vttest for handling cursor
1299 movement in escape sequences */
1301 vt100state
= ESgotpars
;
1304 vt100state
= ESnormal
;
1307 y
-= par
[0] ? par
[0] : 1;
1311 case 'B': /* Down */
1312 y
+= par
[0] ? par
[0] : 1;
1313 if (y
>= scrreg_bottom
)
1314 y
= scrreg_bottom
- 1;
1316 case 'C': /* Right */
1317 x
+= par
[0] ? par
[0] : 1;
1318 if (x
>= vinfo
.v_columns
)
1319 x
= vinfo
.v_columns
-1;
1321 case 'D': /* Left */
1322 x
-= par
[0] ? par
[0] : 1;
1326 case 'H': /* Set cursor position */
1328 x
= par
[1] ? par
[1] - 1 : 0;
1329 y
= par
[0] ? par
[0] - 1 : 0;
1330 if (vc_relative_origin
)
1334 case 'X': /* clear p1 characters */
1337 for (i
= x
; i
< x
+ par
[0]; i
++)
1338 vc_paintchar(' ', i
, y
, ATTR_NONE
);
1341 case 'J': /* Clear part of screen */
1342 clear_screen(par
[0]);
1344 case 'K': /* Clear part of line */
1347 case 'g': /* tab stops */
1350 case 2: /* reset tab stops */
1353 case 3: /* Clear every tabs */
1357 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1366 case 'm': /* Set attribute */
1367 for (i
= 0; i
< numpars
; i
++) {
1371 vc_color_set(VC_RESET_BACKGROUND
);
1372 vc_color_set(VC_RESET_FOREGROUND
);
1381 attr
|= ATTR_REVERSE
;
1387 attr
&= ~ATTR_UNDER
;
1390 attr
&= ~ATTR_REVERSE
;
1393 case 25: /* blink/no blink */
1396 vc_color_set(par
[i
]);
1401 case 'r': /* Set scroll region */
1403 /* ensure top < bottom, and both within limits */
1404 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1405 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1411 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1412 scrreg_bottom
= par
[1];
1413 if (scrreg_bottom
> vinfo
.v_rows
)
1414 scrreg_bottom
= vinfo
.v_rows
;
1416 scrreg_bottom
= vinfo
.v_rows
;
1418 if (vc_relative_origin
)
1426 putc_getpars(unsigned char ch
)
1433 vt100state
= ESnormal
;
1437 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1440 if (ch
>= '0' && ch
<= '9') {
1442 par
[numpars
] += ch
- '0';
1445 vt100state
= ESgotpars
;
1451 putc_square(unsigned char ch
)
1455 for (i
= 0; i
< MAXPARS
; i
++) {
1460 vt100state
= ESgetpars
;
1470 return; /* ignore null characters */
1472 switch (vt100state
) {
1473 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1493 putc_charsizecmd(ch
);
1496 putc_charsetcmd(0, ch
);
1499 putc_charsetcmd(1, ch
);
1503 if (x
>= vinfo
.v_columns
) {
1504 x
= vinfo
.v_columns
- 1;
1509 if (y
>= vinfo
.v_rows
) {
1510 y
= vinfo
.v_rows
- 1;
1519 * Actually draws the buffer, handle the jump scroll
1521 static void vc_flush_forward_buffer(void)
1527 assert(vc_forward_buffer_enabled
);
1530 simple_lock(&vc_forward_lock
);
1532 if (vc_forward_buffer_busy
) {
1533 /* Bail out if we're already in the middle of a flush. */
1534 simple_unlock(&vc_forward_lock
);
1539 vc_forward_buffer_busy
= 1;
1541 while (todo
< vc_forward_buffer_size
) {
1542 todo
= vc_forward_buffer_size
;
1544 /* Drop the lock while we update the screen. */
1545 simple_unlock(&vc_forward_lock
);
1552 #ifdef FAST_JUMP_SCROLL
1553 if ((todo
- start
) < 2) {
1554 vc_putchar(vc_forward_buffer
[start
++]);
1556 assert(vc_forward_scroll
== 0);
1558 vc_forward_preflight_save
.vt100state
= vt100state
;
1559 vc_forward_preflight_save
.vc_wrap_mode
= vc_wrap_mode
;
1560 vc_forward_preflight_save
.vc_relative_origin
= vc_relative_origin
;
1561 vc_forward_preflight_save
.vc_charset_select
= vc_charset_select
;
1562 vc_forward_preflight_save
.vc_save_charset_s
= vc_save_charset_s
;
1563 vc_forward_preflight_save
.vc_charset
[0] = vc_charset
[0];
1564 vc_forward_preflight_save
.vc_charset
[1] = vc_charset
[1];
1565 vc_forward_preflight_save
.vc_charset_save
[0] = vc_charset_save
[0];
1566 vc_forward_preflight_save
.vc_charset_save
[1] = vc_charset_save
[1];
1567 vc_forward_preflight_save
.x
= x
;
1568 vc_forward_preflight_save
.y
= y
;
1569 vc_forward_preflight_save
.savex
= savex
;
1570 vc_forward_preflight_save
.savey
= savey
;
1571 vc_forward_preflight_save
.numpars
= numpars
;
1572 vc_forward_preflight_save
.hanging_cursor
= hanging_cursor
;
1573 vc_forward_preflight_save
.attr
= attr
;
1574 vc_forward_preflight_save
.saveattr
= saveattr
;
1575 vc_forward_preflight_save
.scrreg_top
= scrreg_top
;
1576 vc_forward_preflight_save
.scrreg_bottom
= scrreg_bottom
;
1577 vc_forward_preflight_save
.vc_color_fore
= vc_color_fore
;
1578 vc_forward_preflight_save
.vc_color_back
= vc_color_back
;
1579 bcopy( (const char *) par
,
1580 (char *) vc_forward_preflight_save
.par
,
1581 (vm_size_t
) sizeof(par
) );
1582 bcopy( (const char *) tab_stops
,
1583 (char *) vc_forward_preflight_save
.tab_stops
,
1584 (vm_size_t
) sizeof(tab_stops
) );
1586 vc_forward_preflight_mode
= PFwind
;
1590 vc_forward_preflight_save
.scrreg_top
== scrreg_top
&&
1591 vc_forward_preflight_save
.scrreg_bottom
== scrreg_bottom
;
1593 vc_putchar(vc_forward_buffer
[i
]);
1595 vt100state
= vc_forward_preflight_save
.vt100state
;
1596 vc_wrap_mode
= vc_forward_preflight_save
.vc_wrap_mode
;
1597 vc_relative_origin
= vc_forward_preflight_save
.vc_relative_origin
;
1598 vc_charset_select
= vc_forward_preflight_save
.vc_charset_select
;
1599 vc_save_charset_s
= vc_forward_preflight_save
.vc_save_charset_s
;
1600 vc_charset
[0] = vc_forward_preflight_save
.vc_charset
[0];
1601 vc_charset
[1] = vc_forward_preflight_save
.vc_charset
[1];
1602 vc_charset_save
[0] = vc_forward_preflight_save
.vc_charset_save
[0];
1603 vc_charset_save
[1] = vc_forward_preflight_save
.vc_charset_save
[1];
1604 x
= vc_forward_preflight_save
.x
;
1605 y
= vc_forward_preflight_save
.y
;
1606 savex
= vc_forward_preflight_save
.savex
;
1607 savey
= vc_forward_preflight_save
.savey
;
1608 numpars
= vc_forward_preflight_save
.numpars
;
1609 hanging_cursor
= vc_forward_preflight_save
.hanging_cursor
;
1610 attr
= vc_forward_preflight_save
.attr
;
1611 saveattr
= vc_forward_preflight_save
.saveattr
;
1612 scrreg_top
= vc_forward_preflight_save
.scrreg_top
;
1613 scrreg_bottom
= vc_forward_preflight_save
.scrreg_bottom
;
1614 vc_color_fore
= vc_forward_preflight_save
.vc_color_fore
;
1615 vc_color_back
= vc_forward_preflight_save
.vc_color_back
;
1616 bcopy( (const char *) vc_forward_preflight_save
.par
,
1618 (vm_size_t
) sizeof(par
) );
1619 bcopy( (const char *) vc_forward_preflight_save
.tab_stops
,
1621 (vm_size_t
) sizeof(tab_stops
) );
1623 vc_forward_preflight_mode
= PFscroll
;
1625 if (vc_forward_scroll
> 0)
1626 scrollup(vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1627 scrreg_bottom
- scrreg_top
: vc_forward_scroll
);
1628 else if (vc_forward_scroll
< 0)
1629 scrolldown(-vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1630 scrreg_bottom
- scrreg_top
: -vc_forward_scroll
);
1632 vc_forward_preflight_mode
= PFunwind
;
1634 for (; start
< i
; start
++)
1635 vc_putchar(vc_forward_buffer
[start
]);
1637 assert(vc_forward_scroll
== 0);
1639 vc_forward_preflight_mode
= PFoff
;
1641 #else !FAST_JUMP_SCROLL
1643 int drawlen
= start
;
1645 int param
= 0, changebackground
= 0;
1646 enum vt100state_e vtState
= vt100state
;
1648 * In simple words, here we're pre-parsing the text to look for
1649 * + Newlines, for computing jump scroll
1650 * + /\033\[[0-9;]*]m/ to continue on
1651 * any other sequence will stop. We don't want to have cursor
1652 * movement escape sequences while we're trying to pre-scroll
1654 * We have to be extra carefull about the sequences that changes
1655 * the background color to prevent scrolling in those
1657 * That parsing was added to speed up 'man' and 'color-ls' a
1658 * zillion time (at least). It's worth it, trust me.
1659 * (mail Nick Stephen for a True Performance Graph)
1662 for (i
= start
; i
< todo
&& plaintext
; i
++) {
1666 switch (vc_forward_buffer
[i
]) {
1676 switch (vc_forward_buffer
[i
]) {
1678 vtState
= ESgetpars
;
1680 changebackground
= 0;
1688 if ((vc_forward_buffer
[i
] >= '0' &&
1689 vc_forward_buffer
[i
] <= '9') ||
1690 vc_forward_buffer
[i
] == ';') {
1691 if (vc_forward_buffer
[i
] >= '0' &&
1692 vc_forward_buffer
[i
] <= '9')
1693 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1695 if (param
>= 40 && param
<= 47)
1696 changebackground
= 1;
1697 if (!vc_normal_background
&&
1699 changebackground
= 1;
1702 break; /* continue on */
1704 vtState
= ESgotpars
;
1707 switch (vc_forward_buffer
[i
]) {
1710 if (param
>= 40 && param
<= 47)
1711 changebackground
= 1;
1712 if (!vc_normal_background
&&
1714 changebackground
= 1;
1715 if (changebackground
) {
1718 /* REALLY don't jump */
1720 /* Yup ! we've got it */
1735 * Then we look if it would be appropriate to forward jump
1736 * the screen before drawing
1738 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1739 jump
-= scrreg_bottom
- y
- 1;
1741 if (jump
>= scrreg_bottom
- scrreg_top
)
1742 jump
= scrreg_bottom
- scrreg_top
-1;
1748 * and we draw what we've found to the parser
1750 for (i
= start
; i
< drawlen
; i
++)
1751 vc_putchar(vc_forward_buffer
[start
++]);
1753 * Continue sending characters to the parser until we're sure we're
1754 * back on normal characters.
1756 for (i
= start
; i
< todo
&&
1757 vt100state
!= ESnormal
; i
++)
1758 vc_putchar(vc_forward_buffer
[start
++]);
1759 #endif !FAST_JUMP_SCROLL
1760 /* Then loop again if there still things to draw */
1761 } while (start
< todo
);
1765 /* Re-acquire the lock while we check our state. */
1767 simple_lock(&vc_forward_lock
);
1770 vc_forward_buffer_busy
= 0;
1771 vc_forward_buffer_size
= 0;
1773 simple_unlock(&vc_forward_lock
);
1778 vcputc(int l
, int u
, int c
)
1780 if(!vinfo
.v_baseaddr
)
1784 * Either we're really buffering stuff or we're not yet because
1785 * the probe hasn't been done.
1787 if (vc_forward_buffer_enabled
)
1796 * Store characters to be drawn 'later', handle overflows
1800 vc_store_char(unsigned char c
)
1805 assert(vc_forward_buffer_enabled
);
1808 simple_lock(&vc_forward_lock
);
1810 /* Spin until the buffer has space for another character. */
1811 while (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
) {
1812 simple_unlock(&vc_forward_lock
);
1816 simple_lock(&vc_forward_lock
);
1819 assert(vc_forward_buffer_size
< VC_MAX_FORWARD_SIZE
);
1821 vc_forward_buffer
[vc_forward_buffer_size
++] = (unsigned char)c
;
1823 if (vc_forward_buffer_size
== 1) {
1824 /* If we're adding the first character to the buffer,
1825 * start the timer, otherwise it is already running.
1830 timeout((timeout_fcn_t
)vc_flush_forward_buffer
,
1832 VC_CONSOLE_UPDATE_TIMEOUT
);
1834 } else if (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
|| debug_mode
) {
1836 * If there is an overflow or this is an immediate character display
1837 * (eg. pre-clock printfs, panics), then we force a draw (take into
1838 * account that a flush might already be in progress).
1840 if (!vc_forward_buffer_busy
) {
1842 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
1846 simple_unlock(&vc_forward_lock
);
1851 * Immediate character display.. kernel printf uses this. Make sure
1852 * get flushed and that panics get fully displayed.
1854 vc_flush_forward_buffer();
1862 GratefulDebInit(); /* (TEST/DEBUG) */
1865 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1866 printf(" Video info: %d; video_board=%08X\n", i
, vboard
);
1867 printf(" Video name: %s\n", vinfo
.v_name
);
1868 printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
1869 vinfo
.v_height
, vinfo
.v_width
, vinfo
.v_depth
, vinfo
.v_rowbytes
, vinfo
.v_type
);
1870 printf(" physical address=%08X\n", vinfo
.v_physaddr
);
1873 vinfo
.v_rows
= vinfo
.v_height
/ CHARHEIGHT
;
1874 vinfo
.v_columns
= vinfo
.v_width
/ CHARWIDTH
;
1876 if (vinfo
.v_depth
>= 8) {
1877 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1879 vinfo
.v_rowscanbytes
= vinfo
.v_width
/ (8 / vinfo
.v_depth
);
1882 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1883 printf(" inited=%d\n", vc_initted
);
1887 vc_render_font(1, vinfo
.v_depth
);
1888 vc_color_mask
= vc_color_depth_masks
[vc_color_index_table
[vinfo
.v_depth
]];
1890 switch (vinfo
.v_depth
) {
1893 vc_paintchar
= vc_paint_char1
;
1896 vc_paintchar
= vc_paint_char2
;
1899 vc_paintchar
= vc_paint_char4
;
1902 vc_paintchar
= vc_paint_char8c
;
1905 vc_paintchar
= vc_paint_char16c
;
1908 vc_paintchar
= vc_paint_char32c
;
1912 #ifdef FAST_JUMP_SCROLL
1913 vc_forward_paintchar
= vc_paintchar
;
1914 vc_paintchar
= vc_paint_char
;
1915 #endif FAST_JUMP_SCROLL
1921 if (vinfo
.v_depth
>= 8)
1922 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1923 printf("video console at 0x%x (%dx%dx%d)\n", vinfo
.v_baseaddr
,
1924 vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_depth
);
1927 * Added for the buffering and jump scrolling
1930 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1932 vc_forward_buffer_enabled
= 1;
1937 struct vc_progress_element
{
1938 unsigned int version
;
1941 unsigned char count
;
1942 unsigned char res
[3];
1948 unsigned int res2
[3];
1949 unsigned char data
[0];
1951 typedef struct vc_progress_element vc_progress_element
;
1953 static vc_progress_element
* vc_progress
;
1954 static const unsigned char * vc_progress_data
;
1955 static const unsigned char * vc_progress_alpha
;
1956 static boolean_t vc_progress_enable
;
1957 static const unsigned char * vc_clut
;
1958 static const unsigned char * vc_clut8
;
1959 static unsigned char vc_revclut8
[256];
1960 static unsigned int vc_progress_tick
;
1961 static boolean_t vc_graphics_mode
;
1962 static boolean_t vc_acquired
;
1963 static boolean_t vc_need_clear
;
1964 static boolean_t vc_needsave
;
1965 static vm_address_t vc_saveunder
;
1966 static vm_size_t vc_saveunder_len
;
1968 static void vc_blit_rect_8c( int x
, int y
,
1969 int width
, int height
,
1970 const unsigned char * dataPtr
,
1971 const unsigned char * alphaPtr
,
1972 unsigned char * backPtr
,
1973 boolean_t save
, boolean_t static_alpha
)
1975 volatile unsigned char * dst
;
1978 unsigned char alpha
;
1980 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1981 (y
* vinfo
.v_rowbytes
) +
1984 for( line
= 0; line
< height
; line
++) {
1985 for( col
= 0; col
< width
; col
++) {
1987 if( dataPtr
!= 0) data
= *dataPtr
++;
1988 else if( alphaPtr
!= 0) data
= vc_revclut8
[*alphaPtr
++];
1989 *(dst
+ col
) = data
;
1991 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1996 static void vc_blit_rect_16( int x
, int y
,
1997 int width
, int height
,
1998 const unsigned char * dataPtr
,
1999 const unsigned char * alphaPtr
,
2000 unsigned short * backPtr
,
2001 boolean_t save
, boolean_t static_alpha
)
2003 volatile unsigned short * dst
;
2005 unsigned int data
, index
, alpha
, back
;
2007 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
2008 (y
* vinfo
.v_rowbytes
) +
2011 for( line
= 0; line
< height
; line
++) {
2012 for( col
= 0; col
< width
; col
++) {
2018 if( alphaPtr
&& backPtr
) {
2020 alpha
= *alphaPtr
++;
2023 if( vc_clut
[index
+ 0] > alpha
)
2024 data
|= (((vc_clut
[index
+ 0] - alpha
) & 0xf8) << 7);
2025 if( vc_clut
[index
+ 1] > alpha
)
2026 data
|= (((vc_clut
[index
+ 1] - alpha
) & 0xf8) << 2);
2027 if( vc_clut
[index
+ 2] > alpha
)
2028 data
|= (((vc_clut
[index
+ 2] - alpha
) & 0xf8) >> 3);
2032 back
= *(dst
+ col
);
2035 back
= (((((back
& 0x7c00) * alpha
) + 0x3fc00) >> 8) & 0x7c00)
2036 | (((((back
& 0x03e0) * alpha
) + 0x01fe0) >> 8) & 0x03e0)
2037 | (((((back
& 0x001f) * alpha
) + 0x000ff) >> 8) & 0x001f);
2042 if ( !static_alpha
) {
2043 back
= (((((back
& 0x7c00) * alpha
) + 0x3fc00) >> 8) & 0x7c00)
2044 | (((((back
& 0x03e0) * alpha
) + 0x01fe0) >> 8) & 0x03e0)
2045 | (((((back
& 0x001f) * alpha
) + 0x000ff) >> 8) & 0x001f);
2053 data
= ( (0xf8 & (vc_clut
[index
+ 0])) << 7)
2054 | ( (0xf8 & (vc_clut
[index
+ 1])) << 2)
2055 | ( (0xf8 & (vc_clut
[index
+ 2])) >> 3);
2058 *(dst
+ col
) = data
;
2060 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
2064 static void vc_blit_rect_32( unsigned int x
, unsigned int y
,
2065 unsigned int width
, unsigned int height
,
2066 const unsigned char * dataPtr
,
2067 const unsigned char * alphaPtr
,
2068 unsigned int * backPtr
,
2069 boolean_t save
, boolean_t static_alpha
)
2071 volatile unsigned int * dst
;
2073 unsigned int data
, index
, alpha
, back
;
2075 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2076 (y
* vinfo
.v_rowbytes
) +
2079 for( line
= 0; line
< height
; line
++) {
2080 for( col
= 0; col
< width
; col
++) {
2086 if( alphaPtr
&& backPtr
) {
2088 alpha
= *alphaPtr
++;
2091 if( vc_clut
[index
+ 0] > alpha
)
2092 data
|= ((vc_clut
[index
+ 0] - alpha
) << 16);
2093 if( vc_clut
[index
+ 1] > alpha
)
2094 data
|= ((vc_clut
[index
+ 1] - alpha
) << 8);
2095 if( vc_clut
[index
+ 2] > alpha
)
2096 data
|= ((vc_clut
[index
+ 2] - alpha
));
2100 back
= *(dst
+ col
);
2103 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2104 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2109 if ( !static_alpha
) {
2110 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2111 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2119 data
= (vc_clut
[index
+ 0] << 16)
2120 | (vc_clut
[index
+ 1] << 8)
2121 | (vc_clut
[index
+ 2]);
2124 *(dst
+ col
) = data
;
2126 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2131 draw_panic_dialog( void )
2133 int pd_x
,pd_y
, iconx
, icony
, tx_line
, tx_col
;
2135 int f1
, f2
, d1
, d2
, d3
, rem
;
2142 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
2143 unsigned int ip_addr
= kdp_get_ip_address();
2146 if (!panicDialogDrawn
)
2148 if ( !logPanicDataToScreen
)
2151 /* dim the screen 50% before putting up panic dialog */
2154 /* set up to draw background box */
2155 pd_x
= (vinfo
.v_width
/2) - panic_dialog
.pd_width
/2;
2156 pd_y
= (vinfo
.v_height
/2) - panic_dialog
.pd_height
/2;
2159 panic_blit_rect( pd_x
, pd_y
, panic_dialog
.pd_width
, panic_dialog
.pd_height
, 0, (unsigned char*) panic_dialog
.image_pixel_data
);
2161 /* offset for mac address text */
2162 mac_addr_digit_x
= (vinfo
.v_width
/2) - 130; /* use 62 if no ip */
2163 mac_addr_digit_y
= (vinfo
.v_height
/2) + panic_dialog
.pd_height
/2 - 20;
2165 if(kdp_mac_addr
.ether_addr_octet
[0] || kdp_mac_addr
.ether_addr_octet
[1]|| kdp_mac_addr
.ether_addr_octet
[2]
2166 || kdp_mac_addr
.ether_addr_octet
[3] || kdp_mac_addr
.ether_addr_octet
[4] || kdp_mac_addr
.ether_addr_octet
[5])
2168 /* blit the digits for mac address */
2169 for (count
= 0; count
< 6; count
++ )
2171 nibble
= (kdp_mac_addr
.ether_addr_octet
[count
] & 0xf0) >> 4;
2172 digit
= nibble
< 10 ? nibble
+ '0':nibble
- 10 + 'a';
2175 nibble
= kdp_mac_addr
.ether_addr_octet
[count
] & 0xf;
2176 digit
= nibble
< 10 ? nibble
+ '0':nibble
- 10 + 'a';
2179 blit_digit( colon
);
2182 else /* blit the ff's */
2184 for( count
= 0; count
< 6; count
++ )
2191 blit_digit( colon
);
2194 /* now print the ip address */
2195 mac_addr_digit_x
= (vinfo
.v_width
/2) + 10;
2198 /* blit the digits for ip address */
2199 for (count
= 0; count
< 4; count
++ )
2201 nibble
= (ip_addr
& 0xff000000 ) >> 24;
2203 d3
= (nibble
% 0xa) + '0';
2204 nibble
= nibble
/0xa;
2205 d2
= (nibble
% 0xa) + '0';
2206 nibble
= nibble
/0xa;
2207 d1
= (nibble
% 0xa) + '0';
2209 if( d1
) blit_digit(d1
);
2216 ip_addr
= ip_addr
<< 8;
2221 panicDialogDrawn
= TRUE
;
2227 blit_digit( int digit
)
2232 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_0
.num_w
, num_0
.num_h
, 255, (unsigned char*) num_0
.num_pixel_data
);
2233 mac_addr_digit_x
= mac_addr_digit_x
+ num_0
.num_w
- 1;
2237 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_1
.num_w
, num_1
.num_h
, 255, (unsigned char*) num_1
.num_pixel_data
);
2238 mac_addr_digit_x
= mac_addr_digit_x
+ num_1
.num_w
;
2242 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_2
.num_w
, num_2
.num_h
, 255, (unsigned char*) num_2
.num_pixel_data
);
2243 mac_addr_digit_x
= mac_addr_digit_x
+ num_2
.num_w
;
2247 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_3
.num_w
, num_3
.num_h
, 255, (unsigned char*) num_3
.num_pixel_data
);
2248 mac_addr_digit_x
= mac_addr_digit_x
+ num_3
.num_w
;
2252 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_4
.num_w
, num_4
.num_h
, 255, (unsigned char*) num_4
.num_pixel_data
);
2253 mac_addr_digit_x
= mac_addr_digit_x
+ num_4
.num_w
;
2257 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_5
.num_w
, num_5
.num_h
, 255, (unsigned char*) num_5
.num_pixel_data
);
2258 mac_addr_digit_x
= mac_addr_digit_x
+ num_5
.num_w
;
2262 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_6
.num_w
, num_6
.num_h
, 255, (unsigned char*) num_6
.num_pixel_data
);
2263 mac_addr_digit_x
= mac_addr_digit_x
+ num_6
.num_w
;
2267 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_7
.num_w
, num_7
.num_h
, 255, (unsigned char*) num_7
.num_pixel_data
);
2268 mac_addr_digit_x
= mac_addr_digit_x
+ num_7
.num_w
;
2272 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_8
.num_w
, num_8
.num_h
, 255, (unsigned char*) num_8
.num_pixel_data
);
2273 mac_addr_digit_x
= mac_addr_digit_x
+ num_8
.num_w
;
2277 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_9
.num_w
, num_9
.num_h
, 255, (unsigned char*) num_9
.num_pixel_data
);
2278 mac_addr_digit_x
= mac_addr_digit_x
+ num_9
.num_w
;
2282 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_a
.num_w
, num_a
.num_h
, 255, (unsigned char*) num_a
.num_pixel_data
);
2283 mac_addr_digit_x
= mac_addr_digit_x
+ num_a
.num_w
;
2287 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_b
.num_w
, num_b
.num_h
, 255, (unsigned char*) num_b
.num_pixel_data
);
2288 mac_addr_digit_x
= mac_addr_digit_x
+ num_b
.num_w
;
2292 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_c
.num_w
, num_c
.num_h
, 255, (unsigned char*) num_c
.num_pixel_data
);
2293 mac_addr_digit_x
= mac_addr_digit_x
+ num_c
.num_w
;
2297 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_d
.num_w
, num_d
.num_h
, 255, (unsigned char*) num_d
.num_pixel_data
);
2298 mac_addr_digit_x
= mac_addr_digit_x
+ num_d
.num_w
;
2302 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_e
.num_w
, num_e
.num_h
, 255, (unsigned char*) num_e
.num_pixel_data
);
2303 mac_addr_digit_x
= mac_addr_digit_x
+ num_e
.num_w
;
2307 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_f
.num_w
, num_f
.num_h
, 255, (unsigned char*) num_f
.num_pixel_data
);
2308 mac_addr_digit_x
= mac_addr_digit_x
+ num_f
.num_w
;
2312 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
, num_colon
.num_w
, num_colon
.num_h
, 255, (unsigned char*) num_colon
.num_pixel_data
);
2313 mac_addr_digit_x
= mac_addr_digit_x
+ num_colon
.num_w
;
2317 panic_blit_rect( mac_addr_digit_x
, mac_addr_digit_y
+ (num_colon
.num_h
/2), num_colon
.num_w
, num_colon
.num_h
/2, 255, (unsigned char*) num_colon
.num_pixel_data
);
2318 mac_addr_digit_x
= mac_addr_digit_x
+ num_colon
.num_w
;
2328 panic_blit_rect( unsigned int x
, unsigned int y
,
2329 unsigned int width
, unsigned int height
,
2330 int transparent
, unsigned char * dataPtr
)
2335 switch( vinfo
.v_depth
) {
2337 panic_blit_rect_8( x
, y
, width
, height
, transparent
, dataPtr
);
2340 panic_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
);
2343 panic_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
);
2348 /* panic_blit_rect_8 is not tested and probably doesn't draw correctly.
2349 it really needs a clut to use
2352 panic_blit_rect_8( unsigned int x
, unsigned int y
,
2353 unsigned int width
, unsigned int height
,
2354 int transparent
, unsigned char * dataPtr
)
2356 volatile unsigned int * dst
;
2358 unsigned int pixelR
, pixelG
, pixelB
;
2360 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2361 (y
* vinfo
.v_rowbytes
) +
2364 for( line
= 0; line
< height
; line
++) {
2365 for( col
= 0; col
< width
; col
++) {
2366 pixelR
= *dataPtr
++;
2367 pixelG
= *dataPtr
++;
2368 pixelB
= *dataPtr
++;
2369 if(( pixelR
!= transparent
) || (pixelG
!= transparent
) || (pixelB
!= transparent
))
2371 *(dst
+ col
) = ((19595 * pixelR
+
2373 7471 * pixelB
) / 65536);
2377 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2381 /* panic_blit_rect_16 draws adequately. It would be better if it had a clut
2382 to use instead of scaling the 32bpp color values.
2384 panic_blit_rect_16 decodes the RLE encoded image data on the fly, scales it down
2385 to 16bpp, and fills in each of the three pixel values (RGB) for each pixel
2386 and writes it to the screen.
2390 panic_blit_rect_16( unsigned int x
, unsigned int y
,
2391 unsigned int width
, unsigned int height
,
2392 int transparent
, unsigned char * dataPtr
)
2394 volatile unsigned int * dst
;
2395 int line
, value
, total
= 0;
2396 unsigned int quantity
, tmp
, pixel
;
2399 boolean_t secondTime
= 0;
2403 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2404 (y
* vinfo
.v_rowbytes
) +
2408 *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
2409 | ( (0xf8 & (vc_clut[data + 1])) << 2)
2410 | ( (0xf8 & (vc_clut[data + 2])) >> 3);
2413 for( line
= 0; line
< height
; line
++)
2415 while ( total
< width
)
2417 quantity
= *dataPtr
++;
2419 value
= (0x1f * value
)/255;
2420 while( quantity
> 0 )
2426 tmp
|= (value
<< 10) & 0x7c00;
2427 // tmp |= (value & 0xf8) << 7;
2434 tmp
|= (value
<< 5) & 0x3e0;
2435 // tmp |= (value & 0xf8) << 2;
2442 tmp
|= value
& 0x1f;
2443 // tmp |= (value & 0xf8) >> 3;
2451 *(dst
+ pix_incr
++) = pixel
;
2465 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2472 panic_blit_rect_32 decodes the RLE encoded image data on the fly, and fills
2473 in each of the three pixel values (RGB) for each pixel and writes it to the
2477 panic_blit_rect_32( unsigned int x
, unsigned int y
,
2478 unsigned int width
, unsigned int height
,
2479 int transparent
, unsigned char * dataPtr
)
2481 volatile unsigned int * dst
;
2482 int line
, total
= 0;
2483 unsigned int value
, quantity
, tmp
;
2486 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2487 (y
* vinfo
.v_rowbytes
) +
2490 for( line
= 0; line
< height
; line
++)
2492 while ( total
< width
)
2494 quantity
= *dataPtr
++;
2496 while( quantity
> 0 )
2517 *(dst
+ total
) = tmp
;
2528 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2539 switch( vinfo
.v_depth
) {
2556 unsigned long *p
, *endp
, *row
;
2558 int rowline
, rowlongs
;
2559 unsigned long value
, tmp
;
2561 rowline
= vinfo
.v_rowscanbytes
/ 4;
2562 rowlongs
= vinfo
.v_rowbytes
/ 4;
2564 p
= (unsigned long*) vinfo
.v_baseaddr
;;
2565 endp
= (unsigned long*) vinfo
.v_baseaddr
;
2567 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
2568 endp
+= rowlongs
* vinfo
.v_height
;
2570 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2571 for (col
= 0; col
< rowline
; col
++) {
2573 tmp
= ((value
& 0x7C007C00) >> 1) & 0x3C003C00;
2574 tmp
|= ((value
& 0x03E003E0) >> 1) & 0x01E001E0;
2575 tmp
|= ((value
& 0x001F001F) >> 1) & 0x000F000F;
2576 *(row
+col
) = tmp
; //half (dimmed)?
2586 unsigned long *p
, *endp
, *row
;
2588 int rowline
, rowlongs
;
2589 unsigned long value
, tmp
;
2591 rowline
= vinfo
.v_rowscanbytes
/ 4;
2592 rowlongs
= vinfo
.v_rowbytes
/ 4;
2594 p
= (unsigned long*) vinfo
.v_baseaddr
;;
2595 endp
= (unsigned long*) vinfo
.v_baseaddr
;
2597 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
2598 endp
+= rowlongs
* vinfo
.v_height
;
2600 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2601 for (col
= 0; col
< rowline
; col
++) {
2603 tmp
= ((value
& 0x00FF0000) >> 1) & 0x007F0000;
2604 tmp
|= ((value
& 0x0000FF00) >> 1) & 0x00007F00;
2605 tmp
|= (value
& 0x000000FF) >> 1;
2606 *(row
+col
) = tmp
; //half (dimmed)?
2613 static void vc_blit_rect( unsigned int x
, unsigned int y
,
2614 unsigned int width
, unsigned int height
,
2615 const unsigned char * dataPtr
,
2616 const unsigned char * alphaPtr
,
2617 vm_address_t backBuffer
,
2618 boolean_t save
, boolean_t static_alpha
)
2620 if(!vinfo
.v_baseaddr
)
2623 switch( vinfo
.v_depth
) {
2625 if( vc_clut8
== vc_clut
)
2626 vc_blit_rect_8c( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned char *) backBuffer
, save
, static_alpha
);
2629 vc_blit_rect_16( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned short *) backBuffer
, save
, static_alpha
);
2632 vc_blit_rect_32( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned int *) backBuffer
, save
, static_alpha
);
2637 static void vc_progress_task( void * arg
)
2640 int count
= (int) arg
;
2641 int x
, y
, width
, height
;
2642 const unsigned char * data
;
2645 simple_lock(&vc_forward_lock
);
2647 if( vc_progress_enable
) {
2650 if( count
>= vc_progress
->count
)
2653 width
= vc_progress
->width
;
2654 height
= vc_progress
->height
;
2655 x
= vc_progress
->dx
;
2656 y
= vc_progress
->dy
;
2657 data
= vc_progress_data
;
2658 data
+= count
* width
* height
;
2659 if( 1 & vc_progress
->flags
) {
2660 x
+= ((vinfo
.v_width
- width
) / 2);
2661 y
+= ((vinfo
.v_height
- height
) / 2);
2663 vc_blit_rect( x
, y
, width
, height
,
2664 NULL
, data
, vc_saveunder
,
2665 vc_needsave
, (0 == (4 & vc_progress
->flags
)) );
2666 vc_needsave
= FALSE
;
2668 timeout( vc_progress_task
, (void *) count
,
2671 simple_unlock(&vc_forward_lock
);
2675 void vc_display_icon( vc_progress_element
* desc
,
2676 const unsigned char * data
)
2678 int x
, y
, width
, height
;
2680 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
2682 width
= desc
->width
;
2683 height
= desc
->height
;
2686 if( 1 & desc
->flags
) {
2687 x
+= ((vinfo
.v_width
- width
) / 2);
2688 y
+= ((vinfo
.v_height
- height
) / 2);
2690 vc_blit_rect( x
, y
, width
, height
, data
, NULL
, (vm_address_t
) NULL
, FALSE
, TRUE
);
2694 static boolean_t ignore_first_enable
= TRUE
;
2697 vc_progress_set( boolean_t enable
, unsigned int initial_tick
)
2700 vm_address_t saveBuf
= 0;
2701 vm_size_t saveLen
= 0;
2704 unsigned char data8
;
2705 unsigned short data16
;
2706 unsigned short * buf16
;
2707 unsigned int data32
;
2708 unsigned int * buf32
;
2713 if( enable
& ignore_first_enable
) {
2715 ignore_first_enable
= FALSE
;
2719 saveLen
= vc_progress
->width
* vc_progress
->height
* vinfo
.v_depth
/ 8;
2720 saveBuf
= kalloc( saveLen
);
2722 if( !vc_need_clear
) switch( vinfo
.v_depth
) {
2724 for( count
= 0; count
< 256; count
++) {
2725 vc_revclut8
[count
] = vc_clut
[0x01 * 3];
2726 data8
= (vc_clut
[0x01 * 3] * count
+ 0x0ff) >> 8;
2727 for( index
= 0; index
< 256; index
++) {
2728 if( (data8
== vc_clut
[index
* 3 + 0]) &&
2729 (data8
== vc_clut
[index
* 3 + 1]) &&
2730 (data8
== vc_clut
[index
* 3 + 2])) {
2731 vc_revclut8
[count
] = index
;
2736 memset( (void *) saveBuf
, 0x01, saveLen
);
2740 buf16
= (unsigned short *) saveBuf
;
2741 data16
= ((vc_clut
[0x01 * 3 + 0] & 0xf8) << 7)
2742 | ((vc_clut
[0x01 * 3 + 0] & 0xf8) << 2)
2743 | ((vc_clut
[0x01 * 3 + 0] & 0xf8) >> 3);
2744 for( count
= 0; count
< saveLen
/ 2; count
++)
2745 buf16
[count
] = data16
;
2749 buf32
= (unsigned int *) saveBuf
;
2750 data32
= ((vc_clut
[0x01 * 3 + 0] & 0xff) << 16)
2751 | ((vc_clut
[0x01 * 3 + 1] & 0xff) << 8)
2752 | ((vc_clut
[0x01 * 3 + 2] & 0xff) << 0);
2753 for( count
= 0; count
< saveLen
/ 4; count
++)
2754 buf32
[count
] = data32
;
2760 simple_lock(&vc_forward_lock
);
2762 if( vc_progress_enable
!= enable
) {
2763 vc_progress_enable
= enable
;
2765 vc_needsave
= vc_need_clear
;
2766 vc_saveunder
= saveBuf
;
2767 vc_saveunder_len
= saveLen
;
2770 timeout(vc_progress_task
, (void *) 0,
2774 saveBuf
= vc_saveunder
;
2775 saveLen
= vc_saveunder_len
;
2777 vc_saveunder_len
= 0;
2779 untimeout( vc_progress_task
, (void *) 0 );
2784 vc_forward_buffer_size
= 0;
2785 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
2787 /* Spin if the flush is in progress */
2788 while (vc_forward_buffer_busy
) {
2789 simple_unlock(&vc_forward_lock
);
2793 simple_lock(&vc_forward_lock
);
2794 vc_forward_buffer_size
= 0;
2798 simple_unlock(&vc_forward_lock
);
2802 kfree( saveBuf
, saveLen
);
2809 vc_progress_initialize( vc_progress_element
* desc
,
2810 const unsigned char * data
,
2811 const unsigned char * clut
)
2813 if( (!clut
) || (!desc
) || (!data
))
2819 vc_progress_data
= data
;
2820 if( 2 & vc_progress
->flags
)
2821 vc_progress_alpha
= vc_progress_data
2822 + vc_progress
->count
* vc_progress
->width
* vc_progress
->height
;
2824 vc_progress_alpha
= NULL
;
2825 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
2830 // FirmwareC.c needs:
2831 Boot_Video boot_video_info
;
2833 extern int disableConsoleOutput
;
2835 static void vc_clear_screen( void )
2845 unsigned int lastVideoPhys
= 0;
2846 unsigned int lastVideoVirt
= 0;
2847 unsigned int lastVideoSize
= 0;
2850 initialize_screen(Boot_Video
* boot_vinfo
, unsigned int op
)
2853 unsigned int fbsize
;
2854 unsigned int newVideoVirt
;
2858 bcopy( (const void *) boot_vinfo
,
2859 (void *) &boot_video_info
,
2860 sizeof( boot_video_info
));
2862 * First, check if we are changing the size and/or location of the framebuffer
2866 vinfo
.v_name
[0] = 0;
2867 vinfo
.v_width
= boot_vinfo
->v_width
;
2868 vinfo
.v_height
= boot_vinfo
->v_height
;
2869 vinfo
.v_depth
= boot_vinfo
->v_depth
;
2870 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2871 vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
; /* Get the physical address */
2873 kprintf("initialize_screen: b=%08X, w=%08X, h=%08X, r=%08X\n", /* (BRINGUP) */
2874 vinfo
.v_physaddr
, vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_rowbytes
); /* (BRINGUP) */
2876 if(!vinfo
.v_physaddr
) { /* Check to see if we have a framebuffer */
2877 kprintf("initialize_screen: No video - forcing serial mode\n"); /* (BRINGUP) */
2878 (void)switch_to_serial_console(); /* Switch into serial mode */
2879 vc_graphics_mode
= FALSE
; /* Say we are not in graphics mode */
2880 disableConsoleOutput
= FALSE
; /* Allow printfs to happen */
2882 return; /* Nothing more to do here */
2886 /* Note that for the first time only, boot_vinfo->v_baseAddr is physical */
2888 if(kernel_map
!= VM_MAP_NULL
) { /* If VM is up, we are given a virtual address */
2889 fbppage
= pmap_find_phys(kernel_pmap
, boot_vinfo
->v_baseAddr
); /* Get the physical address of frame buffer */
2890 if(!fbppage
) { /* Did we find it? */
2891 panic("initialize_screen: Strange framebuffer - addr = %08X\n", boot_vinfo
->v_baseAddr
);
2893 vinfo
.v_physaddr
= fbppage
<< 12; /* Get the physical address */
2898 fbsize
= round_page_32(vinfo
.v_height
* vinfo
.v_rowbytes
); /* Remember size */
2900 if((lastVideoPhys
!= vinfo
.v_physaddr
) || (fbsize
> lastVideoSize
)) { /* Did framebuffer change location or get bigger? */
2902 newVideoVirt
= io_map_spec((vm_offset_t
)vinfo
.v_physaddr
, fbsize
); /* Allocate address space for framebuffer */
2904 if(lastVideoVirt
) { /* Was the framebuffer mapped before? */
2905 if(lastVideoVirt
> vm_last_addr
) { /* Was this a special pre-VM mapping? */
2906 pmap_remove(kernel_pmap
, (addr64_t
)lastVideoVirt
, (addr64_t
)(lastVideoVirt
+ lastVideoSize
)); /* Toss mappings */
2908 else { /* This was not special boot-time allocation */
2909 kmem_free(kernel_map
, lastVideoVirt
, lastVideoSize
); /* Toss kernel addresses */
2913 lastVideoPhys
= vinfo
.v_physaddr
; /* Remember the framebuffer address */
2914 lastVideoSize
= fbsize
; /* Remember the size */
2915 lastVideoVirt
= newVideoVirt
; /* Remember the virtual framebuffer address */
2918 vinfo
.v_baseaddr
= lastVideoVirt
; /* Set the new framebuffer address */
2922 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2928 case kPEGraphicsMode
:
2929 vc_graphics_mode
= TRUE
;
2930 disableConsoleOutput
= TRUE
;
2935 vc_graphics_mode
= FALSE
;
2936 disableConsoleOutput
= FALSE
;
2942 vc_progress_set( FALSE
, 0 );
2943 disableConsoleOutput
= FALSE
;
2944 if( vc_need_clear
) {
2945 vc_need_clear
= FALSE
;
2950 case kPEEnableScreen
:
2952 if( vc_graphics_mode
)
2953 vc_progress_set( TRUE
, vc_progress_tick
);
2959 case kPEDisableScreen
:
2960 vc_progress_set( FALSE
, 0 );
2963 case kPEAcquireScreen
:
2964 vc_need_clear
= (FALSE
== vc_acquired
);
2966 vc_progress_set( vc_graphics_mode
, vc_need_clear
? 2 * hz
: 0 );
2967 disableConsoleOutput
= vc_graphics_mode
;
2968 if( vc_need_clear
&& !vc_graphics_mode
) {
2969 vc_need_clear
= FALSE
;
2974 case kPEReleaseScreen
:
2975 vc_acquired
= FALSE
;
2976 vc_progress_set( FALSE
, 0 );
2978 disableConsoleOutput
= TRUE
;
2980 GratefulDebInit(0); /* Stop grateful debugger */
2985 if( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */