2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * @OSF_FREE_COPYRIGHT@
27 * @APPLE_FREE_COPYRIGHT@
29 /* MACH PPC - video_console.c
31 * Original based on NetBSD's mac68k/dev/ite.c driver
33 * This driver differs in
35 * - Uses phys_copy and flush_cache to in several places
36 * for performance optimizations
38 * - Black background and white (character) foreground
39 * - Assumes 6100/7100/8100 class of machine
41 * The original header follows...
44 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
46 * Copyright (c) 1988 University of Utah.
47 * Copyright (c) 1990, 1993
48 * The Regents of the University of California. All rights reserved.
50 * This code is derived from software contributed to Berkeley by
51 * the Systems Programming Group of the University of Utah Computer
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
57 * 1. Redistributions of source code must retain the above copyright
58 * notice, this list of conditions and the following disclaimer.
59 * 2. Redistributions in binary form must reproduce the above copyright
60 * notice, this list of conditions and the following disclaimer in the
61 * documentation and/or other materials provided with the distribution.
62 * 3. All advertising materials mentioning features or use of this software
63 * must display the following acknowledgement:
64 * This product includes software developed by the University of
65 * California, Berkeley and its contributors.
66 * 4. Neither the name of the University nor the names of its contributors
67 * may be used to endorse or promote products derived from this software
68 * without specific prior written permission.
70 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82 * from: Utah $Hdr: ite.c 1.28 92/12/20$
84 * @(#)ite.c 8.2 (Berkeley) 1/12/94
90 * The ite module handles the system console; that is, stuff printed
91 * by the kernel and by user programs while "desktop" and X aren't
92 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
93 * hence the above copyright.
95 * -- Brad and Lawrence, June 26th, 1994
101 #include <mach_kdb.h>
102 #include <kern/spl.h>
103 #include <machine/machparam.h> /* spl definitions */
105 #include <ppc/iso_font.h>
106 #include <ppc/Firmware.h>
108 #include <ppc/POWERMAC/video_console_entries.h>
109 #include <ppc/POWERMAC/video_console.h>
110 #include <pexpert/pexpert.h>
111 #include <kern/time_out.h>
112 #include <kern/lock.h>
113 #include <kern/debug.h>
115 #include <kdp/kdp_udp.h>
117 #include "panic_image.c"
118 #include "rendered_numbers.c"
121 #define FAST_JUMP_SCROLL
124 #define CHARHEIGHT 16
129 #define ATTR_REVERSE 4
132 ESnormal
, /* Nothing yet */
134 ESsquare
, /* Got ESC [ */
135 ESgetpars
, /* About to get or getting the parameters */
136 ESgotpars
, /* Finished getting the parameters */
137 ESfunckey
, /* Function key */
138 EShash
, /* DEC-specific stuff (screen align, etc.) */
139 ESsetG0
, /* Specify the G0 character set */
140 ESsetG1
, /* Specify the G1 character set */
143 ESignore
/* Ignore this sequence */
144 } vt100state
= ESnormal
;
146 struct vc_info vinfo
;
148 /* Calculated in vccninit(): */
149 static int vc_wrap_mode
= 1, vc_relative_origin
= 0;
150 static int vc_charset_select
= 0, vc_save_charset_s
= 0;
151 static int vc_charset
[2] = { 0, 0 };
152 static int vc_charset_save
[2] = { 0, 0 };
156 static int x
= 0, y
= 0, savex
, savey
;
157 static int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
159 /* VT100 tab stops & scroll region */
160 static char tab_stops
[255];
161 static int scrreg_top
, scrreg_bottom
;
164 static void vc_initialize(void);
165 static void vc_flush_forward_buffer(void);
166 static void vc_store_char(unsigned char);
167 static void vc_putchar(char ch
);
171 /* panic dialog and info saving */
172 int mac_addr_digit_x
;
173 int mac_addr_digit_y
;
174 static void blit_digit( int digit
);
175 boolean_t panicDialogDrawn
= FALSE
;
178 panic_blit_rect( unsigned int x
, unsigned int y
,
179 unsigned int width
, unsigned int height
,
180 int transparent
, unsigned char * dataPtr
);
183 panic_blit_rect_8( unsigned int x
, unsigned int y
,
184 unsigned int width
, unsigned int height
,
185 int transparent
, unsigned char * dataPtr
);
188 panic_blit_rect_16( unsigned int x
, unsigned int y
,
189 unsigned int width
, unsigned int height
,
190 int transparent
, unsigned char * dataPtr
);
193 panic_blit_rect_32( unsigned int x
, unsigned int y
,
194 unsigned int width
, unsigned int height
,
195 int transparent
, unsigned char * dataPtr
);
198 blit_rect_of_size_and_color( unsigned int x
, unsigned int y
,
199 unsigned int width
, unsigned int height
,
200 unsigned int dataPtr
);
217 * For the color support (Michel Pollet)
219 static unsigned char vc_color_index_table
[33] =
220 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
223 static unsigned long vc_color_depth_masks
[4] =
224 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
226 static unsigned long vc_colors
[8][3] = {
227 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
228 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
229 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
230 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
231 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
232 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
233 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
234 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
235 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
238 static unsigned long vc_color_mask
= 0;
239 static unsigned long vc_color_fore
= 0;
240 static unsigned long vc_color_back
= 0;
241 static int vc_normal_background
= 1;
245 * For the jump scroll and buffering (Michel Pollet)
246 * 80*22 means on a 80*24 screen, the screen will
247 * scroll jump almost a full screen
248 * keeping only what's necessary for you to be able to read ;-)
250 #define VC_MAX_FORWARD_SIZE (100*36)
253 * Delay between console updates in clock hz units, the larger the
254 * delay the fuller the jump-scroll buffer will be and so the faster the
255 * (scrolling) output. The smaller the delay, the less jerky the
256 * display. Heuristics show that at 10 touch-typists (Mike!) complain
258 #define VC_CONSOLE_UPDATE_TIMEOUT 5
260 static unsigned char vc_forward_buffer
[VC_MAX_FORWARD_SIZE
];
261 static long vc_forward_buffer_size
= 0;
262 static int vc_forward_buffer_enabled
= 0;
263 static int vc_forward_buffer_busy
= 0;
264 decl_simple_lock_data(,vc_forward_lock
)
266 #ifdef FAST_JUMP_SCROLL
267 static void (*vc_forward_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
273 } vc_forward_preflight_mode
= PFoff
;
275 enum vt100state_e vt100state
;
277 int vc_wrap_mode
, vc_relative_origin
;
278 int vc_charset_select
, vc_save_charset_s
;
280 int vc_charset_save
[2];
282 int x
, y
, savex
, savey
;
283 int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
286 int scrreg_top
, scrreg_bottom
;
288 unsigned long vc_color_fore
;
289 unsigned long vc_color_back
;
290 } vc_forward_preflight_save
;
291 static int vc_forward_scroll
= 0;
292 #endif FAST_JUMP_SCROLL
295 * New Rendering code from Michel Pollet
298 /* That function will be called for drawing */
299 static void (*vc_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
301 #ifdef RENDERALLOCATE
302 static unsigned char *renderedFont
= NULL
; /* rendered font buffer */
304 #define REN_MAX_DEPTH 32
305 /* that's the size for a 32 bits buffer... */
306 #define REN_MAX_SIZE (128L*1024)
307 static unsigned char renderedFont
[REN_MAX_SIZE
];
310 /* Rendered Font Size */
311 static unsigned long vc_rendered_font_size
= REN_MAX_SIZE
;
312 static long vc_rendered_error
= 0;
314 /* If the one bit table was reversed */
315 static short vc_one_bit_reversed
= 0;
317 /* Size of a character in the table (bytes) */
318 static int vc_rendered_char_size
= 0;
322 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
324 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
325 # Background color codes:
326 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
329 #define VC_RESET_BACKGROUND 40
330 #define VC_RESET_FOREGROUND 37
332 static void vc_color_set(int color
)
334 if (vinfo
.v_depth
< 8)
336 if (color
>= 30 && color
<= 37)
337 vc_color_fore
= vc_colors
[color
-30][vc_color_index_table
[vinfo
.v_depth
]];
338 if (color
>= 40 && color
<= 47) {
339 vc_color_back
= vc_colors
[color
-40][vc_color_index_table
[vinfo
.v_depth
]];
340 vc_normal_background
= color
== 40;
345 static void vc_render_font(short olddepth
, short newdepth
)
347 int charIndex
; /* index in ISO font */
349 unsigned char *charptr
;
350 unsigned short *shortptr
;
351 unsigned long *longptr
;
352 } current
; /* current place in rendered font, multiple types. */
354 unsigned char *theChar
; /* current char in iso_font */
356 if (olddepth
== newdepth
&& renderedFont
) {
357 return; /* nothing to do */
360 if (olddepth
!= 1 && renderedFont
) {
361 #ifdef RENDERALLOCATE
362 (void) kmem_free(kernel_map
, (vm_offset_t
*)renderedFont
, vc_rendered_font_size
);
365 vc_rendered_font_size
= REN_MAX_SIZE
;
367 #ifdef RENDERALLOCATE
368 renderedFont
= iso_font
;
370 vc_rendered_char_size
= 16;
371 if (!vc_one_bit_reversed
) { /* reverse the font for the blitter */
373 for (i
= 0; i
< ((ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
); i
++) {
375 unsigned char mask1
= 0x80;
376 unsigned char mask2
= 0x01;
377 unsigned char val
= 0;
379 if (iso_font
[i
] & mask1
)
384 renderedFont
[i
] = ~val
;
385 } else renderedFont
[i
] = 0xff;
387 vc_one_bit_reversed
= 1;
392 long csize
= newdepth
/ 8; /* bytes per pixel */
393 vc_rendered_char_size
= csize
? CHARHEIGHT
* (csize
* CHARWIDTH
) :
394 /* for 2 & 4 */ CHARHEIGHT
* (CHARWIDTH
/(6-newdepth
));
395 csize
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
;
396 #ifndef RENDERALLOCATE
397 if (csize
> vc_rendered_font_size
) {
398 vc_rendered_error
= csize
;
401 vc_rendered_font_size
= csize
;
403 vc_rendered_font_size
= csize
;
407 #ifdef RENDERALLOCATE
408 if (kmem_alloc(kernel_map
,
409 (vm_offset_t
*)&renderedFont
,
410 vc_rendered_font_size
) != KERN_SUCCESS
) {
412 vc_rendered_error
= vc_rendered_font_size
;
416 current
.charptr
= renderedFont
;
418 for (charIndex
= ISO_CHAR_MIN
; charIndex
<= ISO_CHAR_MAX
; charIndex
++) {
420 for (line
= 0; line
< CHARHEIGHT
; line
++) {
421 unsigned char mask
= 1;
425 unsigned char value
= 0;
426 if (*theChar
& mask
) value
|= 0xC0; mask
<<= 1;
427 if (*theChar
& mask
) value
|= 0x30; mask
<<= 1;
428 if (*theChar
& mask
) value
|= 0x0C; mask
<<= 1;
429 if (*theChar
& mask
) value
|= 0x03;
431 *current
.charptr
++ = value
;
436 unsigned char value
= 0;
437 if (*theChar
& mask
) value
|= 0xF0; mask
<<= 1;
438 if (*theChar
& mask
) value
|= 0x0F;
440 *current
.charptr
++ = value
;
444 *current
.charptr
++ = (*theChar
& mask
) ? 0xff : 0;
447 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
451 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
455 } while (mask
); /* while the single bit drops to the right */
461 #ifdef FAST_JUMP_SCROLL
462 static void vc_paint_char(unsigned char ch
, int xx
, int yy
, int attrs
)
464 switch (vc_forward_preflight_mode
) {
466 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
473 if (yy
>= scrreg_top
&& yy
< scrreg_bottom
) {
474 yy
-= vc_forward_scroll
;
475 if (yy
< scrreg_top
|| yy
>= scrreg_bottom
)
478 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
482 #endif FAST_JUMP_SCROLL
484 static void vc_paint_char1(unsigned char ch
, int xx
, int yy
, int attrs
)
486 unsigned char *theChar
;
487 unsigned char *where
;
490 theChar
= (unsigned char*)(renderedFont
+ (ch
* vc_rendered_char_size
));
491 where
= (unsigned char*)(vinfo
.v_baseaddr
+
492 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
495 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
498 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
499 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
500 unsigned char val
= *theChar
++, save
= val
;
501 if (attrs
& ATTR_BOLD
) { /* bold support */
502 unsigned char mask1
= 0xC0, mask2
= 0x40;
504 for (bit
= 0; bit
< 7; bit
++) {
505 if ((save
& mask1
) == mask2
)
511 if (attrs
& ATTR_REVERSE
) val
= ~val
;
512 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
515 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
520 static void vc_paint_char2(unsigned char ch
, int xx
, int yy
, int attrs
)
522 unsigned short *theChar
;
523 unsigned short *where
;
526 theChar
= (unsigned short*)(renderedFont
+ (ch
* vc_rendered_char_size
));
527 where
= (unsigned short*)(vinfo
.v_baseaddr
+
528 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
530 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
533 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
534 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
535 unsigned short val
= *theChar
++, save
= val
;
536 if (attrs
& ATTR_BOLD
) { /* bold support */
537 unsigned short mask1
= 0xF000, mask2
= 0x3000;
539 for (bit
= 0; bit
< 7; bit
++) {
540 if ((save
& mask1
) == mask2
)
546 if (attrs
& ATTR_REVERSE
) val
= ~val
;
547 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
550 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
555 static void vc_paint_char4(unsigned char ch
, int xx
, int yy
, int attrs
)
557 unsigned long *theChar
;
558 unsigned long *where
;
561 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
562 where
= (unsigned long*)(vinfo
.v_baseaddr
+
563 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
566 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
569 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
570 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
571 unsigned long val
= *theChar
++, save
= val
;
572 if (attrs
& ATTR_BOLD
) { /* bold support */
573 unsigned long mask1
= 0xff000000, mask2
= 0x0F000000;
575 for (bit
= 0; bit
< 7; bit
++) {
576 if ((save
& mask1
) == mask2
)
582 if (attrs
& ATTR_REVERSE
) val
= ~val
;
583 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
586 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
591 static void vc_paint_char8c(unsigned char ch
, int xx
, int yy
, int attrs
)
593 unsigned long *theChar
;
594 unsigned long *where
;
597 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
598 where
= (unsigned long*)(vinfo
.v_baseaddr
+
599 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
602 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attr? FLY !*/
603 unsigned long *store
= where
;
605 for (x
= 0; x
< 2; x
++) {
606 unsigned long val
= *theChar
++;
607 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
611 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
612 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
613 unsigned long *store
= where
, lastpixel
= 0;
615 for (x
= 0 ; x
< 2; x
++) {
616 unsigned long val
= *theChar
++, save
= val
;
617 if (attrs
& ATTR_BOLD
) { /* bold support */
618 if (lastpixel
&& !(save
& 0xFF000000))
620 if ((save
& 0xFFFF0000) == 0xFF000000)
622 if ((save
& 0x00FFFF00) == 0x00FF0000)
624 if ((save
& 0x0000FFFF) == 0x0000FF00)
627 if (attrs
& ATTR_REVERSE
) val
= ~val
;
628 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
630 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
632 lastpixel
= save
& 0xff;
635 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
639 static void vc_paint_char16c(unsigned char ch
, int xx
, int yy
, int attrs
)
641 unsigned long *theChar
;
642 unsigned long *where
;
645 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
646 where
= (unsigned long*)(vinfo
.v_baseaddr
+
647 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
648 (xx
* CHARWIDTH
* 2));
650 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
651 unsigned long *store
= where
;
653 for (x
= 0; x
< 4; x
++) {
654 unsigned long val
= *theChar
++;
655 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
659 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
660 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
661 unsigned long *store
= where
, lastpixel
= 0;
663 for (x
= 0 ; x
< 4; x
++) {
664 unsigned long val
= *theChar
++, save
= val
;
665 if (attrs
& ATTR_BOLD
) { /* bold support */
666 if (save
== 0xFFFF0000) val
|= 0xFFFF;
667 else if (lastpixel
&& !(save
& 0xFFFF0000))
670 if (attrs
& ATTR_REVERSE
) val
= ~val
;
671 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
673 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
676 lastpixel
= save
& 0x7fff;
679 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
683 static void vc_paint_char32c(unsigned char ch
, int xx
, int yy
, int attrs
)
685 unsigned long *theChar
;
686 unsigned long *where
;
689 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
690 where
= (unsigned long*)(vinfo
.v_baseaddr
+
691 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
692 (xx
* CHARWIDTH
* 4));
694 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
695 unsigned long *store
= where
;
697 for (x
= 0; x
< 8; x
++) {
698 unsigned long val
= *theChar
++;
699 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
703 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
704 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
705 unsigned long *store
= where
, lastpixel
= 0;
707 for (x
= 0 ; x
< 8; x
++) {
708 unsigned long val
= *theChar
++, save
= val
;
709 if (attrs
& ATTR_BOLD
) { /* bold support */
710 if (lastpixel
&& !save
)
713 if (attrs
& ATTR_REVERSE
) val
= ~val
;
714 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
716 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
721 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
727 * That's a plain dumb reverse of the cursor position
728 * It do a binary reverse, so it will not looks good when we have
729 * color support. we'll see that later
731 static void reversecursor(void)
734 unsigned char *charptr
;
735 unsigned short *shortptr
;
736 unsigned long *longptr
;
740 where
.longptr
= (unsigned long*)(vinfo
.v_baseaddr
+
741 (y
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
742 (x
/** CHARWIDTH*/ * vinfo
.v_depth
));
743 for (line
= 0; line
< CHARHEIGHT
; line
++) {
744 switch (vinfo
.v_depth
) {
746 *where
.charptr
= ~*where
.charptr
;
749 *where
.shortptr
= ~*where
.shortptr
;
752 *where
.longptr
= ~*where
.longptr
;
754 /* that code still exists because since characters on the screen are
755 * of different colors that reverse function may not work if the
756 * cursor is on a character that is in a different color that the
757 * current one. When we have buffering, things will work better. MP
759 #ifdef VC_BINARY_REVERSE
761 where
.longptr
[0] = ~where
.longptr
[0];
762 where
.longptr
[1] = ~where
.longptr
[1];
765 for (col
= 0; col
< 4; col
++)
766 where
.longptr
[col
] = ~where
.longptr
[col
];
769 for (col
= 0; col
< 8; col
++)
770 where
.longptr
[col
] = ~where
.longptr
[col
];
774 for (col
= 0; col
< 8; col
++)
775 where
.charptr
[col
] = where
.charptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
776 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
779 for (col
= 0; col
< 8; col
++)
780 where
.shortptr
[col
] = where
.shortptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
781 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
784 for (col
= 0; col
< 8; col
++)
785 where
.longptr
[col
] = where
.longptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
786 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
790 where
.charptr
+= vinfo
.v_rowbytes
;
798 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
800 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
801 rowline
= (vinfo
.v_rowbytes
) >> 2;
802 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
804 #ifdef FAST_JUMP_SCROLL
805 if (vc_forward_preflight_mode
== PFwind
) {
806 vc_forward_scroll
+= num
;
809 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
810 #endif FAST_JUMP_SCROLL
812 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
813 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
815 i
= (scrreg_bottom
- scrreg_top
) - num
;
818 for (line
= 0; line
< CHARHEIGHT
; line
++) {
820 * Only copy what is displayed
822 video_scroll_up((unsigned int) from
,
823 (unsigned int) (from
+(vinfo
.v_rowscanbytes
/4)),
831 /* Now set the freed up lines to the background colour */
834 to
= ((unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
))
835 + ((scrreg_bottom
- scrreg_top
- num
) * linelongs
);
837 #ifdef FAST_JUMP_SCROLL
838 if (vc_forward_preflight_mode
== PFscroll
)
840 } else if (vc_forward_preflight_mode
== PFunwind
) {
841 long linestart
, linelast
;
842 vc_forward_scroll
-= num
;
844 linestart
= scrreg_bottom
- num
- vc_forward_scroll
;
845 linelast
= linestart
+ num
- 1;
847 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
850 if (linelast
>= scrreg_bottom
)
851 linelast
= scrreg_bottom
- 1;
852 if (linestart
< scrreg_top
)
853 linestart
= scrreg_top
;
855 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
856 num
= linelast
- linestart
+ 1;
858 #endif FAST_JUMP_SCROLL
860 for (linelongs
= CHARHEIGHT
* num
; linelongs
-- > 0;) {
862 for (i
= 0; i
< rowscanline
; i
++)
863 *to
++ = vc_color_back
;
873 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
875 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
876 rowline
= (vinfo
.v_rowbytes
) >> 2;
877 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
879 #ifdef FAST_JUMP_SCROLL
880 if (vc_forward_preflight_mode
== PFwind
) {
881 vc_forward_scroll
-= num
;
884 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
885 #endif FAST_JUMP_SCROLL
887 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
888 - (rowline
- rowscanline
);
889 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
891 i
= (scrreg_bottom
- scrreg_top
) - num
;
894 for (line
= 0; line
< CHARHEIGHT
; line
++) {
896 * Only copy what is displayed
898 video_scroll_down((unsigned int) from
,
899 (unsigned int) (from
-(vinfo
.v_rowscanbytes
/4)),
907 /* Now set the freed up lines to the background colour */
909 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_top
);
911 #ifdef FAST_JUMP_SCROLL
912 if (vc_forward_preflight_mode
== PFscroll
)
914 } else if (vc_forward_preflight_mode
== PFunwind
) {
915 long linestart
, linelast
;
916 vc_forward_scroll
+= num
;
918 linestart
= scrreg_top
- vc_forward_scroll
;
919 linelast
= linestart
+ num
- 1;
921 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
924 if (linelast
>= scrreg_bottom
)
925 linelast
= scrreg_bottom
- 1;
926 if (linestart
< scrreg_top
)
927 linestart
= scrreg_top
;
929 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
930 num
= linelast
- linestart
+ 1;
932 #endif FAST_JUMP_SCROLL
934 for (line
= CHARHEIGHT
* num
; line
> 0; line
--) {
937 for (i
= 0; i
< rowscanline
; i
++)
938 *(to
++) = vc_color_back
;
947 clear_line(int which
)
952 * This routine runs extremely slowly. I don't think it's
953 * used all that often, except for To end of line. I'll go
954 * back and speed this up when I speed up the whole vc
959 case 0: /* To end of line */
961 end
= vinfo
.v_columns
-1;
963 case 1: /* To start of line */
967 case 2: /* Whole line */
969 end
= vinfo
.v_columns
-1;
973 for (i
= start
; i
<= end
; i
++) {
974 vc_paintchar(' ', i
, y
, ATTR_NONE
);
980 clear_screen(int which
)
982 unsigned long *p
, *endp
, *row
;
984 int rowline
, rowlongs
;
986 rowline
= vinfo
.v_rowscanbytes
/ 4;
987 rowlongs
= vinfo
.v_rowbytes
/ 4;
989 p
= (unsigned long*) vinfo
.v_baseaddr
;;
990 endp
= (unsigned long*) vinfo
.v_baseaddr
;
992 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
995 case 0: /* To end of screen */
997 if (y
< vinfo
.v_rows
- 1) {
998 p
+= (y
+ 1) * linelongs
;
999 endp
+= rowlongs
* vinfo
.v_height
;
1002 case 1: /* To start of screen */
1005 endp
+= (y
+ 1) * linelongs
;
1008 case 2: /* Whole screen */
1009 endp
+= rowlongs
* vinfo
.v_height
;
1013 for (row
= p
; row
< endp
; row
+= rowlongs
) {
1014 for (col
= 0; col
< rowline
; col
++)
1015 *(row
+col
) = vc_color_back
;
1025 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
1026 tab_stops
[i
] = ((i
% 8) == 0);
1036 scrreg_bottom
= vinfo
.v_rows
;
1038 vc_charset
[0] = vc_charset
[1] = 0;
1039 vc_charset_select
= 0;
1041 vc_relative_origin
= 0;
1042 vc_color_set(VC_RESET_BACKGROUND
);
1043 vc_color_set(VC_RESET_FOREGROUND
);
1048 putc_normal(unsigned char ch
)
1051 case '\a': /* Beep */
1057 * No sound hardware, invert the screen twice instead
1061 /* XOR the screen twice */
1062 for (i
= 0; i
< 2 ; i
++) {
1063 /* For each row, xor the scanbytes */
1064 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
1065 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
1066 (vinfo
.v_height
* vinfo
.v_rowbytes
));
1067 ptr
+= (vinfo
.v_rowbytes
/
1068 sizeof (unsigned long*)))
1070 j
< vinfo
.v_rowscanbytes
/
1071 sizeof (unsigned long*);
1073 *(ptr
+j
) =~*(ptr
+j
);
1079 case 127: /* Delete */
1080 case '\b': /* Backspace */
1081 if (hanging_cursor
) {
1088 case '\t': /* Tab */
1089 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
1090 if (x
>= vinfo
.v_columns
)
1091 x
= vinfo
.v_columns
-1;
1095 case '\n': /* Line feed */
1096 if (y
>= scrreg_bottom
-1 ) {
1098 y
= scrreg_bottom
- 1;
1103 case '\r': /* Carriage return */
1107 case 0x0e: /* Select G1 charset (Control-N) */
1108 vc_charset_select
= 1;
1110 case 0x0f: /* Select G0 charset (Control-O) */
1111 vc_charset_select
= 0;
1113 case 0x18 : /* CAN : cancel */
1114 case 0x1A : /* like cancel */
1115 /* well, i do nothing here, may be later */
1117 case '\033': /* Escape */
1123 if (hanging_cursor
) {
1125 if (y
>= scrreg_bottom
-1 ) {
1127 y
= scrreg_bottom
- 1;
1133 vc_paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
1135 if (x
== vinfo
.v_columns
- 1) {
1136 hanging_cursor
= vc_wrap_mode
;
1147 putc_esc(unsigned char ch
)
1149 vt100state
= ESnormal
;
1153 vt100state
= ESsquare
;
1155 case 'c': /* Reset terminal */
1160 case 'D': /* Line feed */
1162 if (y
>= scrreg_bottom
-1) {
1164 y
= scrreg_bottom
- 1;
1168 if (ch
== 'E') x
= 0;
1170 case 'H': /* Set tab stop */
1173 case 'M': /* Cursor up */
1174 if (y
<= scrreg_top
) {
1184 case '7': /* Save cursor */
1188 vc_save_charset_s
= vc_charset_select
;
1189 vc_charset_save
[0] = vc_charset
[0];
1190 vc_charset_save
[1] = vc_charset
[1];
1192 case '8': /* Restore cursor */
1196 vc_charset_select
= vc_save_charset_s
;
1197 vc_charset
[0] = vc_charset_save
[0];
1198 vc_charset
[1] = vc_charset_save
[1];
1200 case 'Z': /* return terminal ID */
1202 case '#': /* change characters height */
1203 vt100state
= EScharsize
;
1206 vt100state
= ESsetG0
;
1208 case ')': /* character set sequence */
1209 vt100state
= ESsetG1
;
1214 /* Rest not supported */
1221 putc_askcmd(unsigned char ch
)
1223 if (ch
>= '0' && ch
<= '9') {
1224 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1227 vt100state
= ESnormal
;
1231 vc_relative_origin
= ch
== 'h';
1233 case 7: /* wrap around mode h=1, l=0*/
1234 vc_wrap_mode
= ch
== 'h';
1243 putc_charsizecmd(unsigned char ch
)
1245 vt100state
= ESnormal
;
1253 case '8' : /* fill 'E's */
1256 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1257 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1258 vc_paintchar('E', xx
, yy
, ATTR_NONE
);
1266 putc_charsetcmd(int charset
, unsigned char ch
)
1268 vt100state
= ESnormal
;
1274 vc_charset
[charset
] = 0;
1276 case '0' : /* Graphic characters */
1278 vc_charset
[charset
] = 0x21;
1285 putc_gotpars(unsigned char ch
)
1290 /* special case for vttest for handling cursor
1291 movement in escape sequences */
1293 vt100state
= ESgotpars
;
1296 vt100state
= ESnormal
;
1299 y
-= par
[0] ? par
[0] : 1;
1303 case 'B': /* Down */
1304 y
+= par
[0] ? par
[0] : 1;
1305 if (y
>= scrreg_bottom
)
1306 y
= scrreg_bottom
- 1;
1308 case 'C': /* Right */
1309 x
+= par
[0] ? par
[0] : 1;
1310 if (x
>= vinfo
.v_columns
)
1311 x
= vinfo
.v_columns
-1;
1313 case 'D': /* Left */
1314 x
-= par
[0] ? par
[0] : 1;
1318 case 'H': /* Set cursor position */
1320 x
= par
[1] ? par
[1] - 1 : 0;
1321 y
= par
[0] ? par
[0] - 1 : 0;
1322 if (vc_relative_origin
)
1326 case 'X': /* clear p1 characters */
1329 for (i
= x
; i
< x
+ par
[0]; i
++)
1330 vc_paintchar(' ', i
, y
, ATTR_NONE
);
1333 case 'J': /* Clear part of screen */
1334 clear_screen(par
[0]);
1336 case 'K': /* Clear part of line */
1339 case 'g': /* tab stops */
1342 case 2: /* reset tab stops */
1345 case 3: /* Clear every tabs */
1349 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1358 case 'm': /* Set attribute */
1359 for (i
= 0; i
< numpars
; i
++) {
1363 vc_color_set(VC_RESET_BACKGROUND
);
1364 vc_color_set(VC_RESET_FOREGROUND
);
1373 attr
|= ATTR_REVERSE
;
1379 attr
&= ~ATTR_UNDER
;
1382 attr
&= ~ATTR_REVERSE
;
1385 case 25: /* blink/no blink */
1388 vc_color_set(par
[i
]);
1393 case 'r': /* Set scroll region */
1395 /* ensure top < bottom, and both within limits */
1396 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1397 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1403 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1404 scrreg_bottom
= par
[1];
1405 if (scrreg_bottom
> vinfo
.v_rows
)
1406 scrreg_bottom
= vinfo
.v_rows
;
1408 scrreg_bottom
= vinfo
.v_rows
;
1410 if (vc_relative_origin
)
1418 putc_getpars(unsigned char ch
)
1425 vt100state
= ESnormal
;
1429 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1432 if (ch
>= '0' && ch
<= '9') {
1434 par
[numpars
] += ch
- '0';
1437 vt100state
= ESgotpars
;
1443 putc_square(unsigned char ch
)
1447 for (i
= 0; i
< MAXPARS
; i
++) {
1452 vt100state
= ESgetpars
;
1462 return; /* ignore null characters */
1464 switch (vt100state
) {
1465 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1485 putc_charsizecmd(ch
);
1488 putc_charsetcmd(0, ch
);
1491 putc_charsetcmd(1, ch
);
1495 if (x
>= vinfo
.v_columns
) {
1496 x
= vinfo
.v_columns
- 1;
1501 if (y
>= vinfo
.v_rows
) {
1502 y
= vinfo
.v_rows
- 1;
1511 * Actually draws the buffer, handle the jump scroll
1513 static void vc_flush_forward_buffer(void)
1519 assert(vc_forward_buffer_enabled
);
1522 simple_lock(&vc_forward_lock
);
1524 if (vc_forward_buffer_busy
) {
1525 /* Bail out if we're already in the middle of a flush. */
1526 simple_unlock(&vc_forward_lock
);
1531 vc_forward_buffer_busy
= 1;
1533 while (todo
< vc_forward_buffer_size
) {
1534 todo
= vc_forward_buffer_size
;
1536 /* Drop the lock while we update the screen. */
1537 simple_unlock(&vc_forward_lock
);
1544 #ifdef FAST_JUMP_SCROLL
1545 if ((todo
- start
) < 2) {
1546 vc_putchar(vc_forward_buffer
[start
++]);
1548 assert(vc_forward_scroll
== 0);
1550 vc_forward_preflight_save
.vt100state
= vt100state
;
1551 vc_forward_preflight_save
.vc_wrap_mode
= vc_wrap_mode
;
1552 vc_forward_preflight_save
.vc_relative_origin
= vc_relative_origin
;
1553 vc_forward_preflight_save
.vc_charset_select
= vc_charset_select
;
1554 vc_forward_preflight_save
.vc_save_charset_s
= vc_save_charset_s
;
1555 vc_forward_preflight_save
.vc_charset
[0] = vc_charset
[0];
1556 vc_forward_preflight_save
.vc_charset
[1] = vc_charset
[1];
1557 vc_forward_preflight_save
.vc_charset_save
[0] = vc_charset_save
[0];
1558 vc_forward_preflight_save
.vc_charset_save
[1] = vc_charset_save
[1];
1559 vc_forward_preflight_save
.x
= x
;
1560 vc_forward_preflight_save
.y
= y
;
1561 vc_forward_preflight_save
.savex
= savex
;
1562 vc_forward_preflight_save
.savey
= savey
;
1563 vc_forward_preflight_save
.numpars
= numpars
;
1564 vc_forward_preflight_save
.hanging_cursor
= hanging_cursor
;
1565 vc_forward_preflight_save
.attr
= attr
;
1566 vc_forward_preflight_save
.saveattr
= saveattr
;
1567 vc_forward_preflight_save
.scrreg_top
= scrreg_top
;
1568 vc_forward_preflight_save
.scrreg_bottom
= scrreg_bottom
;
1569 vc_forward_preflight_save
.vc_color_fore
= vc_color_fore
;
1570 vc_forward_preflight_save
.vc_color_back
= vc_color_back
;
1571 bcopy( (const char *) par
,
1572 (char *) vc_forward_preflight_save
.par
,
1573 (vm_size_t
) sizeof(par
) );
1574 bcopy( (const char *) tab_stops
,
1575 (char *) vc_forward_preflight_save
.tab_stops
,
1576 (vm_size_t
) sizeof(tab_stops
) );
1578 vc_forward_preflight_mode
= PFwind
;
1582 vc_forward_preflight_save
.scrreg_top
== scrreg_top
&&
1583 vc_forward_preflight_save
.scrreg_bottom
== scrreg_bottom
;
1585 vc_putchar(vc_forward_buffer
[i
]);
1587 vt100state
= vc_forward_preflight_save
.vt100state
;
1588 vc_wrap_mode
= vc_forward_preflight_save
.vc_wrap_mode
;
1589 vc_relative_origin
= vc_forward_preflight_save
.vc_relative_origin
;
1590 vc_charset_select
= vc_forward_preflight_save
.vc_charset_select
;
1591 vc_save_charset_s
= vc_forward_preflight_save
.vc_save_charset_s
;
1592 vc_charset
[0] = vc_forward_preflight_save
.vc_charset
[0];
1593 vc_charset
[1] = vc_forward_preflight_save
.vc_charset
[1];
1594 vc_charset_save
[0] = vc_forward_preflight_save
.vc_charset_save
[0];
1595 vc_charset_save
[1] = vc_forward_preflight_save
.vc_charset_save
[1];
1596 x
= vc_forward_preflight_save
.x
;
1597 y
= vc_forward_preflight_save
.y
;
1598 savex
= vc_forward_preflight_save
.savex
;
1599 savey
= vc_forward_preflight_save
.savey
;
1600 numpars
= vc_forward_preflight_save
.numpars
;
1601 hanging_cursor
= vc_forward_preflight_save
.hanging_cursor
;
1602 attr
= vc_forward_preflight_save
.attr
;
1603 saveattr
= vc_forward_preflight_save
.saveattr
;
1604 scrreg_top
= vc_forward_preflight_save
.scrreg_top
;
1605 scrreg_bottom
= vc_forward_preflight_save
.scrreg_bottom
;
1606 vc_color_fore
= vc_forward_preflight_save
.vc_color_fore
;
1607 vc_color_back
= vc_forward_preflight_save
.vc_color_back
;
1608 bcopy( (const char *) vc_forward_preflight_save
.par
,
1610 (vm_size_t
) sizeof(par
) );
1611 bcopy( (const char *) vc_forward_preflight_save
.tab_stops
,
1613 (vm_size_t
) sizeof(tab_stops
) );
1615 vc_forward_preflight_mode
= PFscroll
;
1617 if (vc_forward_scroll
> 0)
1618 scrollup(vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1619 scrreg_bottom
- scrreg_top
: vc_forward_scroll
);
1620 else if (vc_forward_scroll
< 0)
1621 scrolldown(-vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1622 scrreg_bottom
- scrreg_top
: -vc_forward_scroll
);
1624 vc_forward_preflight_mode
= PFunwind
;
1626 for (; start
< i
; start
++)
1627 vc_putchar(vc_forward_buffer
[start
]);
1629 assert(vc_forward_scroll
== 0);
1631 vc_forward_preflight_mode
= PFoff
;
1633 #else !FAST_JUMP_SCROLL
1635 int drawlen
= start
;
1637 int param
= 0, changebackground
= 0;
1638 enum vt100state_e vtState
= vt100state
;
1640 * In simple words, here we're pre-parsing the text to look for
1641 * + Newlines, for computing jump scroll
1642 * + /\033\[[0-9;]*]m/ to continue on
1643 * any other sequence will stop. We don't want to have cursor
1644 * movement escape sequences while we're trying to pre-scroll
1646 * We have to be extra carefull about the sequences that changes
1647 * the background color to prevent scrolling in those
1649 * That parsing was added to speed up 'man' and 'color-ls' a
1650 * zillion time (at least). It's worth it, trust me.
1651 * (mail Nick Stephen for a True Performance Graph)
1654 for (i
= start
; i
< todo
&& plaintext
; i
++) {
1658 switch (vc_forward_buffer
[i
]) {
1668 switch (vc_forward_buffer
[i
]) {
1670 vtState
= ESgetpars
;
1672 changebackground
= 0;
1680 if ((vc_forward_buffer
[i
] >= '0' &&
1681 vc_forward_buffer
[i
] <= '9') ||
1682 vc_forward_buffer
[i
] == ';') {
1683 if (vc_forward_buffer
[i
] >= '0' &&
1684 vc_forward_buffer
[i
] <= '9')
1685 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1687 if (param
>= 40 && param
<= 47)
1688 changebackground
= 1;
1689 if (!vc_normal_background
&&
1691 changebackground
= 1;
1694 break; /* continue on */
1696 vtState
= ESgotpars
;
1699 switch (vc_forward_buffer
[i
]) {
1702 if (param
>= 40 && param
<= 47)
1703 changebackground
= 1;
1704 if (!vc_normal_background
&&
1706 changebackground
= 1;
1707 if (changebackground
) {
1710 /* REALLY don't jump */
1712 /* Yup ! we've got it */
1727 * Then we look if it would be appropriate to forward jump
1728 * the screen before drawing
1730 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1731 jump
-= scrreg_bottom
- y
- 1;
1733 if (jump
>= scrreg_bottom
- scrreg_top
)
1734 jump
= scrreg_bottom
- scrreg_top
-1;
1740 * and we draw what we've found to the parser
1742 for (i
= start
; i
< drawlen
; i
++)
1743 vc_putchar(vc_forward_buffer
[start
++]);
1745 * Continue sending characters to the parser until we're sure we're
1746 * back on normal characters.
1748 for (i
= start
; i
< todo
&&
1749 vt100state
!= ESnormal
; i
++)
1750 vc_putchar(vc_forward_buffer
[start
++]);
1751 #endif !FAST_JUMP_SCROLL
1752 /* Then loop again if there still things to draw */
1753 } while (start
< todo
);
1757 /* Re-acquire the lock while we check our state. */
1759 simple_lock(&vc_forward_lock
);
1762 vc_forward_buffer_busy
= 0;
1763 vc_forward_buffer_size
= 0;
1765 simple_unlock(&vc_forward_lock
);
1770 vcputc(int l
, int u
, int c
)
1772 if(!vinfo
.v_baseaddr
)
1776 * Either we're really buffering stuff or we're not yet because
1777 * the probe hasn't been done.
1779 if (vc_forward_buffer_enabled
)
1788 * Store characters to be drawn 'later', handle overflows
1792 vc_store_char(unsigned char c
)
1797 assert(vc_forward_buffer_enabled
);
1800 simple_lock(&vc_forward_lock
);
1802 /* Spin until the buffer has space for another character. */
1803 while (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
) {
1804 simple_unlock(&vc_forward_lock
);
1808 simple_lock(&vc_forward_lock
);
1811 assert(vc_forward_buffer_size
< VC_MAX_FORWARD_SIZE
);
1813 vc_forward_buffer
[vc_forward_buffer_size
++] = (unsigned char)c
;
1815 if (vc_forward_buffer_size
== 1) {
1816 /* If we're adding the first character to the buffer,
1817 * start the timer, otherwise it is already running.
1822 timeout((timeout_fcn_t
)vc_flush_forward_buffer
,
1824 VC_CONSOLE_UPDATE_TIMEOUT
);
1826 } else if (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
|| debug_mode
) {
1828 * If there is an overflow or this is an immediate character display
1829 * (eg. pre-clock printfs, panics), then we force a draw (take into
1830 * account that a flush might already be in progress).
1832 if (!vc_forward_buffer_busy
) {
1834 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
1838 simple_unlock(&vc_forward_lock
);
1843 * Immediate character display.. kernel printf uses this. Make sure
1844 * get flushed and that panics get fully displayed.
1846 vc_flush_forward_buffer();
1854 GratefulDebInit(); /* (TEST/DEBUG) */
1857 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1858 printf(" Video info: %d; video_board=%08X\n", i
, vboard
);
1859 printf(" Video name: %s\n", vinfo
.v_name
);
1860 printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
1861 vinfo
.v_height
, vinfo
.v_width
, vinfo
.v_depth
, vinfo
.v_rowbytes
, vinfo
.v_type
);
1862 printf(" physical address=%08X\n", vinfo
.v_physaddr
);
1865 vinfo
.v_rows
= vinfo
.v_height
/ CHARHEIGHT
;
1866 vinfo
.v_columns
= vinfo
.v_width
/ CHARWIDTH
;
1868 if (vinfo
.v_depth
>= 8) {
1869 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1871 vinfo
.v_rowscanbytes
= vinfo
.v_width
/ (8 / vinfo
.v_depth
);
1874 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1875 printf(" inited=%d\n", vc_initted
);
1879 vc_render_font(1, vinfo
.v_depth
);
1880 vc_color_mask
= vc_color_depth_masks
[vc_color_index_table
[vinfo
.v_depth
]];
1882 switch (vinfo
.v_depth
) {
1885 vc_paintchar
= vc_paint_char1
;
1888 vc_paintchar
= vc_paint_char2
;
1891 vc_paintchar
= vc_paint_char4
;
1894 vc_paintchar
= vc_paint_char8c
;
1897 vc_paintchar
= vc_paint_char16c
;
1900 vc_paintchar
= vc_paint_char32c
;
1904 #ifdef FAST_JUMP_SCROLL
1905 vc_forward_paintchar
= vc_paintchar
;
1906 vc_paintchar
= vc_paint_char
;
1907 #endif FAST_JUMP_SCROLL
1913 if (vinfo
.v_depth
>= 8)
1914 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1915 printf("video console at 0x%x (%dx%dx%d)\n", vinfo
.v_baseaddr
,
1916 vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_depth
);
1919 * Added for the buffering and jump scrolling
1922 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1924 vc_forward_buffer_enabled
= 1;
1929 struct vc_progress_element
{
1930 unsigned int version
;
1933 unsigned char count
;
1934 unsigned char res
[3];
1940 unsigned int res2
[3];
1941 unsigned char data
[0];
1943 typedef struct vc_progress_element vc_progress_element
;
1945 static vc_progress_element
* vc_progress
;
1946 static const unsigned char * vc_progress_data
;
1947 static const unsigned char * vc_progress_alpha
;
1948 static boolean_t vc_progress_enable
;
1949 static const unsigned char * vc_clut
;
1950 static const unsigned char * vc_clut8
;
1951 static unsigned char vc_revclut8
[256];
1952 static unsigned int vc_progress_tick
;
1953 static boolean_t vc_graphics_mode
;
1954 static boolean_t vc_acquired
;
1955 static boolean_t vc_need_clear
;
1956 static boolean_t vc_needsave
;
1957 static vm_address_t vc_saveunder
;
1958 static vm_size_t vc_saveunder_len
;
1960 static void vc_blit_rect_8c( int x
, int y
,
1961 int width
, int height
,
1962 const unsigned char * dataPtr
,
1963 const unsigned char * alphaPtr
,
1964 unsigned char * backPtr
,
1965 boolean_t save
, boolean_t static_alpha
)
1967 volatile unsigned char * dst
;
1970 unsigned char alpha
;
1972 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1973 (y
* vinfo
.v_rowbytes
) +
1976 for( line
= 0; line
< height
; line
++) {
1977 for( col
= 0; col
< width
; col
++) {
1979 if( dataPtr
!= 0) data
= *dataPtr
++;
1980 else if( alphaPtr
!= 0) data
= vc_revclut8
[*alphaPtr
++];
1981 *(dst
+ col
) = data
;
1983 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1988 static void vc_blit_rect_16( int x
, int y
,
1989 int width
, int height
,
1990 const unsigned char * dataPtr
,
1991 const unsigned char * alphaPtr
,
1992 unsigned short * backPtr
,
1993 boolean_t save
, boolean_t static_alpha
)
1995 volatile unsigned short * dst
;
1997 unsigned int data
, index
, alpha
, back
;
1999 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
2000 (y
* vinfo
.v_rowbytes
) +
2003 for( line
= 0; line
< height
; line
++) {
2004 for( col
= 0; col
< width
; col
++) {
2010 if( alphaPtr
&& backPtr
) {
2012 alpha
= *alphaPtr
++;
2015 if( vc_clut
[index
+ 0] > alpha
)
2016 data
|= (((vc_clut
[index
+ 0] - alpha
) & 0xf8) << 7);
2017 if( vc_clut
[index
+ 1] > alpha
)
2018 data
|= (((vc_clut
[index
+ 1] - alpha
) & 0xf8) << 2);
2019 if( vc_clut
[index
+ 2] > alpha
)
2020 data
|= (((vc_clut
[index
+ 2] - alpha
) & 0xf8) >> 3);
2024 back
= *(dst
+ col
);
2027 back
= (((((back
& 0x7c00) * alpha
) + 0x3fc00) >> 8) & 0x7c00)
2028 | (((((back
& 0x03e0) * alpha
) + 0x01fe0) >> 8) & 0x03e0)
2029 | (((((back
& 0x001f) * alpha
) + 0x000ff) >> 8) & 0x001f);
2034 if ( !static_alpha
) {
2035 back
= (((((back
& 0x7c00) * alpha
) + 0x3fc00) >> 8) & 0x7c00)
2036 | (((((back
& 0x03e0) * alpha
) + 0x01fe0) >> 8) & 0x03e0)
2037 | (((((back
& 0x001f) * alpha
) + 0x000ff) >> 8) & 0x001f);
2045 data
= ( (0xf8 & (vc_clut
[index
+ 0])) << 7)
2046 | ( (0xf8 & (vc_clut
[index
+ 1])) << 2)
2047 | ( (0xf8 & (vc_clut
[index
+ 2])) >> 3);
2050 *(dst
+ col
) = data
;
2052 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
2056 static void vc_blit_rect_32( unsigned int x
, unsigned int y
,
2057 unsigned int width
, unsigned int height
,
2058 const unsigned char * dataPtr
,
2059 const unsigned char * alphaPtr
,
2060 unsigned int * backPtr
,
2061 boolean_t save
, boolean_t static_alpha
)
2063 volatile unsigned int * dst
;
2065 unsigned int data
, index
, alpha
, back
;
2067 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2068 (y
* vinfo
.v_rowbytes
) +
2071 for( line
= 0; line
< height
; line
++) {
2072 for( col
= 0; col
< width
; col
++) {
2078 if( alphaPtr
&& backPtr
) {
2080 alpha
= *alphaPtr
++;
2083 if( vc_clut
[index
+ 0] > alpha
)
2084 data
|= ((vc_clut
[index
+ 0] - alpha
) << 16);
2085 if( vc_clut
[index
+ 1] > alpha
)
2086 data
|= ((vc_clut
[index
+ 1] - alpha
) << 8);
2087 if( vc_clut
[index
+ 2] > alpha
)
2088 data
|= ((vc_clut
[index
+ 2] - alpha
));
2092 back
= *(dst
+ col
);
2095 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2096 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2101 if ( !static_alpha
) {
2102 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2103 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2111 data
= (vc_clut
[index
+ 0] << 16)
2112 | (vc_clut
[index
+ 1] << 8)
2113 | (vc_clut
[index
+ 2]);
2116 *(dst
+ col
) = data
;
2118 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2123 draw_panic_dialog( void )
2125 int pd_x
,pd_y
, iconx
, icony
, tx_line
, tx_col
;
2127 int f1
, f2
, d1
, d2
, d3
, rem
;
2134 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
2135 unsigned int ip_addr
= kdp_get_ip_address();
2138 if (!panicDialogDrawn
)
2140 if ( !logPanicDataToScreen
)
2143 /* dim the screen 50% before putting up panic dialog */
2146 /* set up to draw background box */
2147 pd_x
= (vinfo
.v_width
/2) - panic_dialog
.pd_width
/2;
2148 pd_y
= (vinfo
.v_height
/2) - panic_dialog
.pd_height
/2;
2151 panic_blit_rect( pd_x
, pd_y
, panic_dialog
.pd_width
, panic_dialog
.pd_height
, 0, (unsigned char*) panic_dialog
.image_pixel_data
);
2153 /* offset for mac address text */
2154 mac_addr_digit_x
= (vinfo
.v_width
/2) - 130; /* use 62 if no ip */
2155 mac_addr_digit_y
= (vinfo
.v_height
/2) + panic_dialog
.pd_height
/2 - 20;
2157 if(kdp_mac_addr
.ether_addr_octet
[0] || kdp_mac_addr
.ether_addr_octet
[1]|| kdp_mac_addr
.ether_addr_octet
[2]
2158 || kdp_mac_addr
.ether_addr_octet
[3] || kdp_mac_addr
.ether_addr_octet
[4] || kdp_mac_addr
.ether_addr_octet
[5])
2160 /* blit the digits for mac address */
2161 for (count
= 0; count
< 6; count
++ )
2163 nibble
= (kdp_mac_addr
.ether_addr_octet
[count
] & 0xf0) >> 4;
2164 digit
= nibble
< 10 ? nibble
+ '0':nibble
- 10 + 'a';
2167 nibble
= kdp_mac_addr
.ether_addr_octet
[count
] & 0xf;
2168 digit
= nibble
< 10 ? nibble
+ '0':nibble
- 10 + 'a';
2171 blit_digit( colon
);
2174 else /* blit the ff's */
2176 for( count
= 0; count
< 6; count
++ )
2183 blit_digit( colon
);
2186 /* now print the ip address */
2187 mac_addr_digit_x
= (vinfo
.v_width
/2) + 10;
2190 /* blit the digits for ip address */
2191 for (count
= 0; count
< 4; count
++ )
2193 nibble
= (ip_addr
& 0xff000000 ) >> 24;
2195 d3
= (nibble
% 0xa) + '0';
2196 nibble
= nibble
/0xa;
2197 d2
= (nibble
% 0xa) + '0';
2198 nibble
= nibble
/0xa;
2199 d1
= (nibble
% 0xa) + '0';
2201 if( d1
) blit_digit(d1
);
2208 ip_addr
= ip_addr
<< 8;
2213 panicDialogDrawn
= TRUE
;
2219 blit_digit( int digit
)
2224 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
);
2225 mac_addr_digit_x
= mac_addr_digit_x
+ num_0
.num_w
- 1;
2229 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
);
2230 mac_addr_digit_x
= mac_addr_digit_x
+ num_1
.num_w
;
2234 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
);
2235 mac_addr_digit_x
= mac_addr_digit_x
+ num_2
.num_w
;
2239 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
);
2240 mac_addr_digit_x
= mac_addr_digit_x
+ num_3
.num_w
;
2244 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
);
2245 mac_addr_digit_x
= mac_addr_digit_x
+ num_4
.num_w
;
2249 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
);
2250 mac_addr_digit_x
= mac_addr_digit_x
+ num_5
.num_w
;
2254 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
);
2255 mac_addr_digit_x
= mac_addr_digit_x
+ num_6
.num_w
;
2259 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
);
2260 mac_addr_digit_x
= mac_addr_digit_x
+ num_7
.num_w
;
2264 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
);
2265 mac_addr_digit_x
= mac_addr_digit_x
+ num_8
.num_w
;
2269 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
);
2270 mac_addr_digit_x
= mac_addr_digit_x
+ num_9
.num_w
;
2274 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
);
2275 mac_addr_digit_x
= mac_addr_digit_x
+ num_a
.num_w
;
2279 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
);
2280 mac_addr_digit_x
= mac_addr_digit_x
+ num_b
.num_w
;
2284 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
);
2285 mac_addr_digit_x
= mac_addr_digit_x
+ num_c
.num_w
;
2289 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
);
2290 mac_addr_digit_x
= mac_addr_digit_x
+ num_d
.num_w
;
2294 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
);
2295 mac_addr_digit_x
= mac_addr_digit_x
+ num_e
.num_w
;
2299 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
);
2300 mac_addr_digit_x
= mac_addr_digit_x
+ num_f
.num_w
;
2304 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
);
2305 mac_addr_digit_x
= mac_addr_digit_x
+ num_colon
.num_w
;
2309 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
);
2310 mac_addr_digit_x
= mac_addr_digit_x
+ num_colon
.num_w
;
2320 panic_blit_rect( unsigned int x
, unsigned int y
,
2321 unsigned int width
, unsigned int height
,
2322 int transparent
, unsigned char * dataPtr
)
2327 switch( vinfo
.v_depth
) {
2329 panic_blit_rect_8( x
, y
, width
, height
, transparent
, dataPtr
);
2332 panic_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
);
2335 panic_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
);
2340 /* panic_blit_rect_8 is not tested and probably doesn't draw correctly.
2341 it really needs a clut to use
2344 panic_blit_rect_8( unsigned int x
, unsigned int y
,
2345 unsigned int width
, unsigned int height
,
2346 int transparent
, unsigned char * dataPtr
)
2348 volatile unsigned int * dst
;
2350 unsigned int pixelR
, pixelG
, pixelB
;
2352 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2353 (y
* vinfo
.v_rowbytes
) +
2356 for( line
= 0; line
< height
; line
++) {
2357 for( col
= 0; col
< width
; col
++) {
2358 pixelR
= *dataPtr
++;
2359 pixelG
= *dataPtr
++;
2360 pixelB
= *dataPtr
++;
2361 if(( pixelR
!= transparent
) || (pixelG
!= transparent
) || (pixelB
!= transparent
))
2363 *(dst
+ col
) = ((19595 * pixelR
+
2365 7471 * pixelB
) / 65536);
2369 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2373 /* panic_blit_rect_16 draws adequately. It would be better if it had a clut
2374 to use instead of scaling the 32bpp color values.
2376 panic_blit_rect_16 decodes the RLE encoded image data on the fly, scales it down
2377 to 16bpp, and fills in each of the three pixel values (RGB) for each pixel
2378 and writes it to the screen.
2382 panic_blit_rect_16( unsigned int x
, unsigned int y
,
2383 unsigned int width
, unsigned int height
,
2384 int transparent
, unsigned char * dataPtr
)
2386 volatile unsigned int * dst
;
2387 int line
, value
, total
= 0;
2388 unsigned int quantity
, tmp
, pixel
;
2391 boolean_t secondTime
= 0;
2395 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2396 (y
* vinfo
.v_rowbytes
) +
2400 *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
2401 | ( (0xf8 & (vc_clut[data + 1])) << 2)
2402 | ( (0xf8 & (vc_clut[data + 2])) >> 3);
2405 for( line
= 0; line
< height
; line
++)
2407 while ( total
< width
)
2409 quantity
= *dataPtr
++;
2411 value
= (0x1f * value
)/255;
2412 while( quantity
> 0 )
2418 tmp
|= (value
<< 10) & 0x7c00;
2419 // tmp |= (value & 0xf8) << 7;
2426 tmp
|= (value
<< 5) & 0x3e0;
2427 // tmp |= (value & 0xf8) << 2;
2434 tmp
|= value
& 0x1f;
2435 // tmp |= (value & 0xf8) >> 3;
2443 *(dst
+ pix_incr
++) = pixel
;
2457 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2464 panic_blit_rect_32 decodes the RLE encoded image data on the fly, and fills
2465 in each of the three pixel values (RGB) for each pixel and writes it to the
2469 panic_blit_rect_32( unsigned int x
, unsigned int y
,
2470 unsigned int width
, unsigned int height
,
2471 int transparent
, unsigned char * dataPtr
)
2473 volatile unsigned int * dst
;
2474 int line
, total
= 0;
2475 unsigned int value
, quantity
, tmp
;
2478 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2479 (y
* vinfo
.v_rowbytes
) +
2482 for( line
= 0; line
< height
; line
++)
2484 while ( total
< width
)
2486 quantity
= *dataPtr
++;
2488 while( quantity
> 0 )
2509 *(dst
+ total
) = tmp
;
2520 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2531 switch( vinfo
.v_depth
) {
2548 unsigned long *p
, *endp
, *row
;
2550 int rowline
, rowlongs
;
2551 unsigned long value
, tmp
;
2553 rowline
= vinfo
.v_rowscanbytes
/ 4;
2554 rowlongs
= vinfo
.v_rowbytes
/ 4;
2556 p
= (unsigned long*) vinfo
.v_baseaddr
;;
2557 endp
= (unsigned long*) vinfo
.v_baseaddr
;
2559 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
2560 endp
+= rowlongs
* vinfo
.v_height
;
2562 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2563 for (col
= 0; col
< rowline
; col
++) {
2565 tmp
= ((value
& 0x7C007C00) >> 1) & 0x3C003C00;
2566 tmp
|= ((value
& 0x03E003E0) >> 1) & 0x01E001E0;
2567 tmp
|= ((value
& 0x001F001F) >> 1) & 0x000F000F;
2568 *(row
+col
) = tmp
; //half (dimmed)?
2578 unsigned long *p
, *endp
, *row
;
2580 int rowline
, rowlongs
;
2581 unsigned long value
, tmp
;
2583 rowline
= vinfo
.v_rowscanbytes
/ 4;
2584 rowlongs
= vinfo
.v_rowbytes
/ 4;
2586 p
= (unsigned long*) vinfo
.v_baseaddr
;;
2587 endp
= (unsigned long*) vinfo
.v_baseaddr
;
2589 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
2590 endp
+= rowlongs
* vinfo
.v_height
;
2592 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2593 for (col
= 0; col
< rowline
; col
++) {
2595 tmp
= ((value
& 0x00FF0000) >> 1) & 0x007F0000;
2596 tmp
|= ((value
& 0x0000FF00) >> 1) & 0x00007F00;
2597 tmp
|= (value
& 0x000000FF) >> 1;
2598 *(row
+col
) = tmp
; //half (dimmed)?
2605 static void vc_blit_rect( unsigned int x
, unsigned int y
,
2606 unsigned int width
, unsigned int height
,
2607 const unsigned char * dataPtr
,
2608 const unsigned char * alphaPtr
,
2609 vm_address_t backBuffer
,
2610 boolean_t save
, boolean_t static_alpha
)
2612 if(!vinfo
.v_baseaddr
)
2615 switch( vinfo
.v_depth
) {
2617 if( vc_clut8
== vc_clut
)
2618 vc_blit_rect_8c( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned char *) backBuffer
, save
, static_alpha
);
2621 vc_blit_rect_16( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned short *) backBuffer
, save
, static_alpha
);
2624 vc_blit_rect_32( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned int *) backBuffer
, save
, static_alpha
);
2629 static void vc_progress_task( void * arg
)
2632 int count
= (int) arg
;
2633 int x
, y
, width
, height
;
2634 const unsigned char * data
;
2637 simple_lock(&vc_forward_lock
);
2639 if( vc_progress_enable
) {
2642 if( count
>= vc_progress
->count
)
2645 width
= vc_progress
->width
;
2646 height
= vc_progress
->height
;
2647 x
= vc_progress
->dx
;
2648 y
= vc_progress
->dy
;
2649 data
= vc_progress_data
;
2650 data
+= count
* width
* height
;
2651 if( 1 & vc_progress
->flags
) {
2652 x
+= ((vinfo
.v_width
- width
) / 2);
2653 y
+= ((vinfo
.v_height
- height
) / 2);
2655 vc_blit_rect( x
, y
, width
, height
,
2656 NULL
, data
, vc_saveunder
,
2657 vc_needsave
, (0 == (4 & vc_progress
->flags
)) );
2658 vc_needsave
= FALSE
;
2660 timeout( vc_progress_task
, (void *) count
,
2663 simple_unlock(&vc_forward_lock
);
2667 void vc_display_icon( vc_progress_element
* desc
,
2668 const unsigned char * data
)
2670 int x
, y
, width
, height
;
2672 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
2674 width
= desc
->width
;
2675 height
= desc
->height
;
2678 if( 1 & desc
->flags
) {
2679 x
+= ((vinfo
.v_width
- width
) / 2);
2680 y
+= ((vinfo
.v_height
- height
) / 2);
2682 vc_blit_rect( x
, y
, width
, height
, data
, NULL
, (vm_address_t
) NULL
, FALSE
, TRUE
);
2686 static boolean_t ignore_first_enable
= TRUE
;
2689 vc_progress_set( boolean_t enable
, unsigned int initial_tick
)
2692 vm_address_t saveBuf
= 0;
2693 vm_size_t saveLen
= 0;
2696 unsigned char data8
;
2697 unsigned short data16
;
2698 unsigned short * buf16
;
2699 unsigned int data32
;
2700 unsigned int * buf32
;
2705 if( enable
& ignore_first_enable
) {
2707 ignore_first_enable
= FALSE
;
2711 saveLen
= vc_progress
->width
* vc_progress
->height
* vinfo
.v_depth
/ 8;
2712 saveBuf
= kalloc( saveLen
);
2714 if( !vc_need_clear
) switch( vinfo
.v_depth
) {
2716 for( count
= 0; count
< 256; count
++) {
2717 vc_revclut8
[count
] = vc_clut
[0x01 * 3];
2718 data8
= (vc_clut
[0x01 * 3] * count
+ 0x0ff) >> 8;
2719 for( index
= 0; index
< 256; index
++) {
2720 if( (data8
== vc_clut
[index
* 3 + 0]) &&
2721 (data8
== vc_clut
[index
* 3 + 1]) &&
2722 (data8
== vc_clut
[index
* 3 + 2])) {
2723 vc_revclut8
[count
] = index
;
2728 memset( (void *) saveBuf
, 0x01, saveLen
);
2732 buf16
= (unsigned short *) saveBuf
;
2733 data16
= ((vc_clut
[0x01 * 3 + 0] & 0xf8) << 7)
2734 | ((vc_clut
[0x01 * 3 + 0] & 0xf8) << 2)
2735 | ((vc_clut
[0x01 * 3 + 0] & 0xf8) >> 3);
2736 for( count
= 0; count
< saveLen
/ 2; count
++)
2737 buf16
[count
] = data16
;
2741 buf32
= (unsigned int *) saveBuf
;
2742 data32
= ((vc_clut
[0x01 * 3 + 0] & 0xff) << 16)
2743 | ((vc_clut
[0x01 * 3 + 1] & 0xff) << 8)
2744 | ((vc_clut
[0x01 * 3 + 2] & 0xff) << 0);
2745 for( count
= 0; count
< saveLen
/ 4; count
++)
2746 buf32
[count
] = data32
;
2752 simple_lock(&vc_forward_lock
);
2754 if( vc_progress_enable
!= enable
) {
2755 vc_progress_enable
= enable
;
2757 vc_needsave
= vc_need_clear
;
2758 vc_saveunder
= saveBuf
;
2759 vc_saveunder_len
= saveLen
;
2762 timeout(vc_progress_task
, (void *) 0,
2766 saveBuf
= vc_saveunder
;
2767 saveLen
= vc_saveunder_len
;
2769 vc_saveunder_len
= 0;
2771 untimeout( vc_progress_task
, (void *) 0 );
2776 vc_forward_buffer_size
= 0;
2777 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
2779 /* Spin if the flush is in progress */
2780 while (vc_forward_buffer_busy
) {
2781 simple_unlock(&vc_forward_lock
);
2785 simple_lock(&vc_forward_lock
);
2786 vc_forward_buffer_size
= 0;
2790 simple_unlock(&vc_forward_lock
);
2794 kfree( saveBuf
, saveLen
);
2801 vc_progress_initialize( vc_progress_element
* desc
,
2802 const unsigned char * data
,
2803 const unsigned char * clut
)
2805 if( (!clut
) || (!desc
) || (!data
))
2811 vc_progress_data
= data
;
2812 if( 2 & vc_progress
->flags
)
2813 vc_progress_alpha
= vc_progress_data
2814 + vc_progress
->count
* vc_progress
->width
* vc_progress
->height
;
2816 vc_progress_alpha
= NULL
;
2817 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
2822 // FirmwareC.c needs:
2823 Boot_Video boot_video_info
;
2825 extern int disableConsoleOutput
;
2827 static void vc_clear_screen( void )
2837 initialize_screen(Boot_Video
* boot_vinfo
, unsigned int op
)
2840 bcopy( (const void *) boot_vinfo
,
2841 (void *) &boot_video_info
,
2842 sizeof( boot_video_info
));
2844 vinfo
.v_name
[0] = 0;
2845 vinfo
.v_width
= boot_vinfo
->v_width
;
2846 vinfo
.v_height
= boot_vinfo
->v_height
;
2847 vinfo
.v_depth
= boot_vinfo
->v_depth
;
2848 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2849 vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
;
2850 vinfo
.v_baseaddr
= vinfo
.v_physaddr
;
2855 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2861 case kPEGraphicsMode
:
2862 vc_graphics_mode
= TRUE
;
2863 disableConsoleOutput
= TRUE
;
2868 vc_graphics_mode
= FALSE
;
2869 disableConsoleOutput
= FALSE
;
2875 vc_progress_set( FALSE
, 0 );
2876 disableConsoleOutput
= FALSE
;
2877 if( vc_need_clear
) {
2878 vc_need_clear
= FALSE
;
2883 case kPEEnableScreen
:
2885 if( vc_graphics_mode
)
2886 vc_progress_set( TRUE
, vc_progress_tick
);
2892 case kPEDisableScreen
:
2893 vc_progress_set( FALSE
, 0 );
2896 case kPEAcquireScreen
:
2897 vc_need_clear
= (FALSE
== vc_acquired
);
2899 vc_progress_set( vc_graphics_mode
, vc_need_clear
? 2 * hz
: 0 );
2900 disableConsoleOutput
= vc_graphics_mode
;
2901 if( vc_need_clear
&& !vc_graphics_mode
) {
2902 vc_need_clear
= FALSE
;
2907 case kPEReleaseScreen
:
2908 vc_acquired
= FALSE
;
2909 vc_progress_set( FALSE
, 0 );
2911 disableConsoleOutput
= TRUE
;
2913 GratefulDebInit(0); /* Stop grateful debugger */
2918 if( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */