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>
118 #include <kdp/kdp_udp.h>
120 #include "panic_image.c"
121 #include "rendered_numbers.c"
124 #define FAST_JUMP_SCROLL
127 #define CHARHEIGHT 16
132 #define ATTR_REVERSE 4
135 ESnormal
, /* Nothing yet */
137 ESsquare
, /* Got ESC [ */
138 ESgetpars
, /* About to get or getting the parameters */
139 ESgotpars
, /* Finished getting the parameters */
140 ESfunckey
, /* Function key */
141 EShash
, /* DEC-specific stuff (screen align, etc.) */
142 ESsetG0
, /* Specify the G0 character set */
143 ESsetG1
, /* Specify the G1 character set */
146 ESignore
/* Ignore this sequence */
147 } vt100state
= ESnormal
;
149 struct vc_info vinfo
;
151 /* Calculated in vccninit(): */
152 static int vc_wrap_mode
= 1, vc_relative_origin
= 0;
153 static int vc_charset_select
= 0, vc_save_charset_s
= 0;
154 static int vc_charset
[2] = { 0, 0 };
155 static int vc_charset_save
[2] = { 0, 0 };
159 static int x
= 0, y
= 0, savex
, savey
;
160 static int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
162 /* VT100 tab stops & scroll region */
163 static char tab_stops
[255];
164 static int scrreg_top
, scrreg_bottom
;
167 static void vc_initialize(void);
168 static void vc_flush_forward_buffer(void);
169 static void vc_store_char(unsigned char);
170 static void vc_putchar(char ch
);
174 /* panic dialog and info saving */
175 int mac_addr_digit_x
;
176 int mac_addr_digit_y
;
177 static void blit_digit( int digit
);
178 boolean_t panicDialogDrawn
= FALSE
;
181 panic_blit_rect( unsigned int x
, unsigned int y
,
182 unsigned int width
, unsigned int height
,
183 int transparent
, unsigned char * dataPtr
);
186 panic_blit_rect_8( unsigned int x
, unsigned int y
,
187 unsigned int width
, unsigned int height
,
188 int transparent
, unsigned char * dataPtr
);
191 panic_blit_rect_16( unsigned int x
, unsigned int y
,
192 unsigned int width
, unsigned int height
,
193 int transparent
, unsigned char * dataPtr
);
196 panic_blit_rect_32( unsigned int x
, unsigned int y
,
197 unsigned int width
, unsigned int height
,
198 int transparent
, unsigned char * dataPtr
);
201 blit_rect_of_size_and_color( unsigned int x
, unsigned int y
,
202 unsigned int width
, unsigned int height
,
203 unsigned int dataPtr
);
220 * For the color support (Michel Pollet)
222 static unsigned char vc_color_index_table
[33] =
223 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
226 static unsigned long vc_color_depth_masks
[4] =
227 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
229 static unsigned long vc_colors
[8][3] = {
230 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
231 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
232 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
233 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
234 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
235 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
236 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
237 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
238 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
241 static unsigned long vc_color_mask
= 0;
242 static unsigned long vc_color_fore
= 0;
243 static unsigned long vc_color_back
= 0;
244 static int vc_normal_background
= 1;
248 * For the jump scroll and buffering (Michel Pollet)
249 * 80*22 means on a 80*24 screen, the screen will
250 * scroll jump almost a full screen
251 * keeping only what's necessary for you to be able to read ;-)
253 #define VC_MAX_FORWARD_SIZE (100*36)
256 * Delay between console updates in clock hz units, the larger the
257 * delay the fuller the jump-scroll buffer will be and so the faster the
258 * (scrolling) output. The smaller the delay, the less jerky the
259 * display. Heuristics show that at 10 touch-typists (Mike!) complain
261 #define VC_CONSOLE_UPDATE_TIMEOUT 5
263 static unsigned char vc_forward_buffer
[VC_MAX_FORWARD_SIZE
];
264 static long vc_forward_buffer_size
= 0;
265 static int vc_forward_buffer_enabled
= 0;
266 static int vc_forward_buffer_busy
= 0;
267 decl_simple_lock_data(,vc_forward_lock
)
269 #ifdef FAST_JUMP_SCROLL
270 static void (*vc_forward_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
276 } vc_forward_preflight_mode
= PFoff
;
278 enum vt100state_e vt100state
;
280 int vc_wrap_mode
, vc_relative_origin
;
281 int vc_charset_select
, vc_save_charset_s
;
283 int vc_charset_save
[2];
285 int x
, y
, savex
, savey
;
286 int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
289 int scrreg_top
, scrreg_bottom
;
291 unsigned long vc_color_fore
;
292 unsigned long vc_color_back
;
293 } vc_forward_preflight_save
;
294 static int vc_forward_scroll
= 0;
295 #endif FAST_JUMP_SCROLL
298 * New Rendering code from Michel Pollet
301 /* That function will be called for drawing */
302 static void (*vc_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
304 #ifdef RENDERALLOCATE
305 static unsigned char *renderedFont
= NULL
; /* rendered font buffer */
307 #define REN_MAX_DEPTH 32
308 /* that's the size for a 32 bits buffer... */
309 #define REN_MAX_SIZE (128L*1024)
310 static unsigned char renderedFont
[REN_MAX_SIZE
];
313 /* Rendered Font Size */
314 static unsigned long vc_rendered_font_size
= REN_MAX_SIZE
;
315 static long vc_rendered_error
= 0;
317 /* If the one bit table was reversed */
318 static short vc_one_bit_reversed
= 0;
320 /* Size of a character in the table (bytes) */
321 static int vc_rendered_char_size
= 0;
325 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
327 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
328 # Background color codes:
329 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
332 #define VC_RESET_BACKGROUND 40
333 #define VC_RESET_FOREGROUND 37
335 static void vc_color_set(int color
)
337 if (vinfo
.v_depth
< 8)
339 if (color
>= 30 && color
<= 37)
340 vc_color_fore
= vc_colors
[color
-30][vc_color_index_table
[vinfo
.v_depth
]];
341 if (color
>= 40 && color
<= 47) {
342 vc_color_back
= vc_colors
[color
-40][vc_color_index_table
[vinfo
.v_depth
]];
343 vc_normal_background
= color
== 40;
348 static void vc_render_font(short olddepth
, short newdepth
)
350 int charIndex
; /* index in ISO font */
352 unsigned char *charptr
;
353 unsigned short *shortptr
;
354 unsigned long *longptr
;
355 } current
; /* current place in rendered font, multiple types. */
357 unsigned char *theChar
; /* current char in iso_font */
359 if (olddepth
== newdepth
&& renderedFont
) {
360 return; /* nothing to do */
363 if (olddepth
!= 1 && renderedFont
) {
364 #ifdef RENDERALLOCATE
365 (void) kmem_free(kernel_map
, (vm_offset_t
*)renderedFont
, vc_rendered_font_size
);
368 vc_rendered_font_size
= REN_MAX_SIZE
;
370 #ifdef RENDERALLOCATE
371 renderedFont
= iso_font
;
373 vc_rendered_char_size
= 16;
374 if (!vc_one_bit_reversed
) { /* reverse the font for the blitter */
376 for (i
= 0; i
< ((ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
); i
++) {
378 unsigned char mask1
= 0x80;
379 unsigned char mask2
= 0x01;
380 unsigned char val
= 0;
382 if (iso_font
[i
] & mask1
)
387 renderedFont
[i
] = ~val
;
388 } else renderedFont
[i
] = 0xff;
390 vc_one_bit_reversed
= 1;
395 long csize
= newdepth
/ 8; /* bytes per pixel */
396 vc_rendered_char_size
= csize
? CHARHEIGHT
* (csize
* CHARWIDTH
) :
397 /* for 2 & 4 */ CHARHEIGHT
* (CHARWIDTH
/(6-newdepth
));
398 csize
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
;
399 #ifndef RENDERALLOCATE
400 if (csize
> vc_rendered_font_size
) {
401 vc_rendered_error
= csize
;
404 vc_rendered_font_size
= csize
;
406 vc_rendered_font_size
= csize
;
410 #ifdef RENDERALLOCATE
411 if (kmem_alloc(kernel_map
,
412 (vm_offset_t
*)&renderedFont
,
413 vc_rendered_font_size
) != KERN_SUCCESS
) {
415 vc_rendered_error
= vc_rendered_font_size
;
419 current
.charptr
= renderedFont
;
421 for (charIndex
= ISO_CHAR_MIN
; charIndex
<= ISO_CHAR_MAX
; charIndex
++) {
423 for (line
= 0; line
< CHARHEIGHT
; line
++) {
424 unsigned char mask
= 1;
428 unsigned char value
= 0;
429 if (*theChar
& mask
) value
|= 0xC0; mask
<<= 1;
430 if (*theChar
& mask
) value
|= 0x30; mask
<<= 1;
431 if (*theChar
& mask
) value
|= 0x0C; mask
<<= 1;
432 if (*theChar
& mask
) value
|= 0x03;
434 *current
.charptr
++ = value
;
439 unsigned char value
= 0;
440 if (*theChar
& mask
) value
|= 0xF0; mask
<<= 1;
441 if (*theChar
& mask
) value
|= 0x0F;
443 *current
.charptr
++ = value
;
447 *current
.charptr
++ = (*theChar
& mask
) ? 0xff : 0;
450 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
454 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
458 } while (mask
); /* while the single bit drops to the right */
464 #ifdef FAST_JUMP_SCROLL
465 static void vc_paint_char(unsigned char ch
, int xx
, int yy
, int attrs
)
467 switch (vc_forward_preflight_mode
) {
469 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
476 if (yy
>= scrreg_top
&& yy
< scrreg_bottom
) {
477 yy
-= vc_forward_scroll
;
478 if (yy
< scrreg_top
|| yy
>= scrreg_bottom
)
481 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
485 #endif FAST_JUMP_SCROLL
487 static void vc_paint_char1(unsigned char ch
, int xx
, int yy
, int attrs
)
489 unsigned char *theChar
;
490 unsigned char *where
;
493 theChar
= (unsigned char*)(renderedFont
+ (ch
* vc_rendered_char_size
));
494 where
= (unsigned char*)(vinfo
.v_baseaddr
+
495 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
498 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
501 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
502 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
503 unsigned char val
= *theChar
++, save
= val
;
504 if (attrs
& ATTR_BOLD
) { /* bold support */
505 unsigned char mask1
= 0xC0, mask2
= 0x40;
507 for (bit
= 0; bit
< 7; bit
++) {
508 if ((save
& mask1
) == mask2
)
514 if (attrs
& ATTR_REVERSE
) val
= ~val
;
515 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
518 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
523 static void vc_paint_char2(unsigned char ch
, int xx
, int yy
, int attrs
)
525 unsigned short *theChar
;
526 unsigned short *where
;
529 theChar
= (unsigned short*)(renderedFont
+ (ch
* vc_rendered_char_size
));
530 where
= (unsigned short*)(vinfo
.v_baseaddr
+
531 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
533 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
536 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
537 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
538 unsigned short val
= *theChar
++, save
= val
;
539 if (attrs
& ATTR_BOLD
) { /* bold support */
540 unsigned short mask1
= 0xF000, mask2
= 0x3000;
542 for (bit
= 0; bit
< 7; bit
++) {
543 if ((save
& mask1
) == mask2
)
549 if (attrs
& ATTR_REVERSE
) val
= ~val
;
550 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
553 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
558 static void vc_paint_char4(unsigned char ch
, int xx
, int yy
, int attrs
)
560 unsigned long *theChar
;
561 unsigned long *where
;
564 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
565 where
= (unsigned long*)(vinfo
.v_baseaddr
+
566 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
569 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
572 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
573 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
574 unsigned long val
= *theChar
++, save
= val
;
575 if (attrs
& ATTR_BOLD
) { /* bold support */
576 unsigned long mask1
= 0xff000000, mask2
= 0x0F000000;
578 for (bit
= 0; bit
< 7; bit
++) {
579 if ((save
& mask1
) == mask2
)
585 if (attrs
& ATTR_REVERSE
) val
= ~val
;
586 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
589 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
594 static void vc_paint_char8c(unsigned char ch
, int xx
, int yy
, int attrs
)
596 unsigned long *theChar
;
597 unsigned long *where
;
600 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
601 where
= (unsigned long*)(vinfo
.v_baseaddr
+
602 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
605 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attr? FLY !*/
606 unsigned long *store
= where
;
608 for (x
= 0; x
< 2; x
++) {
609 unsigned long val
= *theChar
++;
610 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
614 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
615 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
616 unsigned long *store
= where
, lastpixel
= 0;
618 for (x
= 0 ; x
< 2; x
++) {
619 unsigned long val
= *theChar
++, save
= val
;
620 if (attrs
& ATTR_BOLD
) { /* bold support */
621 if (lastpixel
&& !(save
& 0xFF000000))
623 if ((save
& 0xFFFF0000) == 0xFF000000)
625 if ((save
& 0x00FFFF00) == 0x00FF0000)
627 if ((save
& 0x0000FFFF) == 0x0000FF00)
630 if (attrs
& ATTR_REVERSE
) val
= ~val
;
631 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
633 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
635 lastpixel
= save
& 0xff;
638 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
642 static void vc_paint_char16c(unsigned char ch
, int xx
, int yy
, int attrs
)
644 unsigned long *theChar
;
645 unsigned long *where
;
648 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
649 where
= (unsigned long*)(vinfo
.v_baseaddr
+
650 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
651 (xx
* CHARWIDTH
* 2));
653 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
654 unsigned long *store
= where
;
656 for (x
= 0; x
< 4; x
++) {
657 unsigned long val
= *theChar
++;
658 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
662 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
663 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
664 unsigned long *store
= where
, lastpixel
= 0;
666 for (x
= 0 ; x
< 4; x
++) {
667 unsigned long val
= *theChar
++, save
= val
;
668 if (attrs
& ATTR_BOLD
) { /* bold support */
669 if (save
== 0xFFFF0000) val
|= 0xFFFF;
670 else if (lastpixel
&& !(save
& 0xFFFF0000))
673 if (attrs
& ATTR_REVERSE
) val
= ~val
;
674 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
676 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
679 lastpixel
= save
& 0x7fff;
682 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
686 static void vc_paint_char32c(unsigned char ch
, int xx
, int yy
, int attrs
)
688 unsigned long *theChar
;
689 unsigned long *where
;
692 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
693 where
= (unsigned long*)(vinfo
.v_baseaddr
+
694 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
695 (xx
* CHARWIDTH
* 4));
697 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
698 unsigned long *store
= where
;
700 for (x
= 0; x
< 8; x
++) {
701 unsigned long val
= *theChar
++;
702 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
706 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
707 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
708 unsigned long *store
= where
, lastpixel
= 0;
710 for (x
= 0 ; x
< 8; x
++) {
711 unsigned long val
= *theChar
++, save
= val
;
712 if (attrs
& ATTR_BOLD
) { /* bold support */
713 if (lastpixel
&& !save
)
716 if (attrs
& ATTR_REVERSE
) val
= ~val
;
717 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
719 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
724 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
730 * That's a plain dumb reverse of the cursor position
731 * It do a binary reverse, so it will not looks good when we have
732 * color support. we'll see that later
734 static void reversecursor(void)
737 unsigned char *charptr
;
738 unsigned short *shortptr
;
739 unsigned long *longptr
;
743 where
.longptr
= (unsigned long*)(vinfo
.v_baseaddr
+
744 (y
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
745 (x
/** CHARWIDTH*/ * vinfo
.v_depth
));
746 for (line
= 0; line
< CHARHEIGHT
; line
++) {
747 switch (vinfo
.v_depth
) {
749 *where
.charptr
= ~*where
.charptr
;
752 *where
.shortptr
= ~*where
.shortptr
;
755 *where
.longptr
= ~*where
.longptr
;
757 /* that code still exists because since characters on the screen are
758 * of different colors that reverse function may not work if the
759 * cursor is on a character that is in a different color that the
760 * current one. When we have buffering, things will work better. MP
762 #ifdef VC_BINARY_REVERSE
764 where
.longptr
[0] = ~where
.longptr
[0];
765 where
.longptr
[1] = ~where
.longptr
[1];
768 for (col
= 0; col
< 4; col
++)
769 where
.longptr
[col
] = ~where
.longptr
[col
];
772 for (col
= 0; col
< 8; col
++)
773 where
.longptr
[col
] = ~where
.longptr
[col
];
777 for (col
= 0; col
< 8; col
++)
778 where
.charptr
[col
] = where
.charptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
779 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
782 for (col
= 0; col
< 8; col
++)
783 where
.shortptr
[col
] = where
.shortptr
[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
.longptr
[col
] = where
.longptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
789 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
793 where
.charptr
+= vinfo
.v_rowbytes
;
801 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
803 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
804 rowline
= (vinfo
.v_rowbytes
) >> 2;
805 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
807 #ifdef FAST_JUMP_SCROLL
808 if (vc_forward_preflight_mode
== PFwind
) {
809 vc_forward_scroll
+= num
;
812 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
813 #endif FAST_JUMP_SCROLL
815 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
816 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
818 i
= (scrreg_bottom
- scrreg_top
) - num
;
821 for (line
= 0; line
< CHARHEIGHT
; line
++) {
823 * Only copy what is displayed
825 video_scroll_up((unsigned int) from
,
826 (unsigned int) (from
+(vinfo
.v_rowscanbytes
/4)),
834 /* Now set the freed up lines to the background colour */
837 to
= ((unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
))
838 + ((scrreg_bottom
- scrreg_top
- num
) * linelongs
);
840 #ifdef FAST_JUMP_SCROLL
841 if (vc_forward_preflight_mode
== PFscroll
)
843 } else if (vc_forward_preflight_mode
== PFunwind
) {
844 long linestart
, linelast
;
845 vc_forward_scroll
-= num
;
847 linestart
= scrreg_bottom
- num
- vc_forward_scroll
;
848 linelast
= linestart
+ num
- 1;
850 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
853 if (linelast
>= scrreg_bottom
)
854 linelast
= scrreg_bottom
- 1;
855 if (linestart
< scrreg_top
)
856 linestart
= scrreg_top
;
858 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
859 num
= linelast
- linestart
+ 1;
861 #endif FAST_JUMP_SCROLL
863 for (linelongs
= CHARHEIGHT
* num
; linelongs
-- > 0;) {
865 for (i
= 0; i
< rowscanline
; i
++)
866 *to
++ = vc_color_back
;
876 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
878 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
879 rowline
= (vinfo
.v_rowbytes
) >> 2;
880 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
882 #ifdef FAST_JUMP_SCROLL
883 if (vc_forward_preflight_mode
== PFwind
) {
884 vc_forward_scroll
-= num
;
887 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
888 #endif FAST_JUMP_SCROLL
890 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
891 - (rowline
- rowscanline
);
892 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
894 i
= (scrreg_bottom
- scrreg_top
) - num
;
897 for (line
= 0; line
< CHARHEIGHT
; line
++) {
899 * Only copy what is displayed
901 video_scroll_down((unsigned int) from
,
902 (unsigned int) (from
-(vinfo
.v_rowscanbytes
/4)),
910 /* Now set the freed up lines to the background colour */
912 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_top
);
914 #ifdef FAST_JUMP_SCROLL
915 if (vc_forward_preflight_mode
== PFscroll
)
917 } else if (vc_forward_preflight_mode
== PFunwind
) {
918 long linestart
, linelast
;
919 vc_forward_scroll
+= num
;
921 linestart
= scrreg_top
- vc_forward_scroll
;
922 linelast
= linestart
+ num
- 1;
924 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
927 if (linelast
>= scrreg_bottom
)
928 linelast
= scrreg_bottom
- 1;
929 if (linestart
< scrreg_top
)
930 linestart
= scrreg_top
;
932 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
933 num
= linelast
- linestart
+ 1;
935 #endif FAST_JUMP_SCROLL
937 for (line
= CHARHEIGHT
* num
; line
> 0; line
--) {
940 for (i
= 0; i
< rowscanline
; i
++)
941 *(to
++) = vc_color_back
;
950 clear_line(int which
)
955 * This routine runs extremely slowly. I don't think it's
956 * used all that often, except for To end of line. I'll go
957 * back and speed this up when I speed up the whole vc
962 case 0: /* To end of line */
964 end
= vinfo
.v_columns
-1;
966 case 1: /* To start of line */
970 case 2: /* Whole line */
972 end
= vinfo
.v_columns
-1;
976 for (i
= start
; i
<= end
; i
++) {
977 vc_paintchar(' ', i
, y
, ATTR_NONE
);
983 clear_screen(int which
)
985 unsigned long *p
, *endp
, *row
;
987 int rowline
, rowlongs
;
989 rowline
= vinfo
.v_rowscanbytes
/ 4;
990 rowlongs
= vinfo
.v_rowbytes
/ 4;
992 p
= (unsigned long*) vinfo
.v_baseaddr
;;
993 endp
= (unsigned long*) vinfo
.v_baseaddr
;
995 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
998 case 0: /* To end of screen */
1000 if (y
< vinfo
.v_rows
- 1) {
1001 p
+= (y
+ 1) * linelongs
;
1002 endp
+= rowlongs
* vinfo
.v_height
;
1005 case 1: /* To start of screen */
1008 endp
+= (y
+ 1) * linelongs
;
1011 case 2: /* Whole screen */
1012 endp
+= rowlongs
* vinfo
.v_height
;
1016 for (row
= p
; row
< endp
; row
+= rowlongs
) {
1017 for (col
= 0; col
< rowline
; col
++)
1018 *(row
+col
) = vc_color_back
;
1028 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
1029 tab_stops
[i
] = ((i
% 8) == 0);
1039 scrreg_bottom
= vinfo
.v_rows
;
1041 vc_charset
[0] = vc_charset
[1] = 0;
1042 vc_charset_select
= 0;
1044 vc_relative_origin
= 0;
1045 vc_color_set(VC_RESET_BACKGROUND
);
1046 vc_color_set(VC_RESET_FOREGROUND
);
1051 putc_normal(unsigned char ch
)
1054 case '\a': /* Beep */
1060 * No sound hardware, invert the screen twice instead
1064 /* XOR the screen twice */
1065 for (i
= 0; i
< 2 ; i
++) {
1066 /* For each row, xor the scanbytes */
1067 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
1068 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
1069 (vinfo
.v_height
* vinfo
.v_rowbytes
));
1070 ptr
+= (vinfo
.v_rowbytes
/
1071 sizeof (unsigned long*)))
1073 j
< vinfo
.v_rowscanbytes
/
1074 sizeof (unsigned long*);
1076 *(ptr
+j
) =~*(ptr
+j
);
1082 case 127: /* Delete */
1083 case '\b': /* Backspace */
1084 if (hanging_cursor
) {
1091 case '\t': /* Tab */
1092 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
1093 if (x
>= vinfo
.v_columns
)
1094 x
= vinfo
.v_columns
-1;
1098 case '\n': /* Line feed */
1099 if (y
>= scrreg_bottom
-1 ) {
1101 y
= scrreg_bottom
- 1;
1106 case '\r': /* Carriage return */
1110 case 0x0e: /* Select G1 charset (Control-N) */
1111 vc_charset_select
= 1;
1113 case 0x0f: /* Select G0 charset (Control-O) */
1114 vc_charset_select
= 0;
1116 case 0x18 : /* CAN : cancel */
1117 case 0x1A : /* like cancel */
1118 /* well, i do nothing here, may be later */
1120 case '\033': /* Escape */
1126 if (hanging_cursor
) {
1128 if (y
>= scrreg_bottom
-1 ) {
1130 y
= scrreg_bottom
- 1;
1136 vc_paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
1138 if (x
== vinfo
.v_columns
- 1) {
1139 hanging_cursor
= vc_wrap_mode
;
1150 putc_esc(unsigned char ch
)
1152 vt100state
= ESnormal
;
1156 vt100state
= ESsquare
;
1158 case 'c': /* Reset terminal */
1163 case 'D': /* Line feed */
1165 if (y
>= scrreg_bottom
-1) {
1167 y
= scrreg_bottom
- 1;
1171 if (ch
== 'E') x
= 0;
1173 case 'H': /* Set tab stop */
1176 case 'M': /* Cursor up */
1177 if (y
<= scrreg_top
) {
1187 case '7': /* Save cursor */
1191 vc_save_charset_s
= vc_charset_select
;
1192 vc_charset_save
[0] = vc_charset
[0];
1193 vc_charset_save
[1] = vc_charset
[1];
1195 case '8': /* Restore cursor */
1199 vc_charset_select
= vc_save_charset_s
;
1200 vc_charset
[0] = vc_charset_save
[0];
1201 vc_charset
[1] = vc_charset_save
[1];
1203 case 'Z': /* return terminal ID */
1205 case '#': /* change characters height */
1206 vt100state
= EScharsize
;
1209 vt100state
= ESsetG0
;
1211 case ')': /* character set sequence */
1212 vt100state
= ESsetG1
;
1217 /* Rest not supported */
1224 putc_askcmd(unsigned char ch
)
1226 if (ch
>= '0' && ch
<= '9') {
1227 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1230 vt100state
= ESnormal
;
1234 vc_relative_origin
= ch
== 'h';
1236 case 7: /* wrap around mode h=1, l=0*/
1237 vc_wrap_mode
= ch
== 'h';
1246 putc_charsizecmd(unsigned char ch
)
1248 vt100state
= ESnormal
;
1256 case '8' : /* fill 'E's */
1259 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1260 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1261 vc_paintchar('E', xx
, yy
, ATTR_NONE
);
1269 putc_charsetcmd(int charset
, unsigned char ch
)
1271 vt100state
= ESnormal
;
1277 vc_charset
[charset
] = 0;
1279 case '0' : /* Graphic characters */
1281 vc_charset
[charset
] = 0x21;
1288 putc_gotpars(unsigned char ch
)
1293 /* special case for vttest for handling cursor
1294 movement in escape sequences */
1296 vt100state
= ESgotpars
;
1299 vt100state
= ESnormal
;
1302 y
-= par
[0] ? par
[0] : 1;
1306 case 'B': /* Down */
1307 y
+= par
[0] ? par
[0] : 1;
1308 if (y
>= scrreg_bottom
)
1309 y
= scrreg_bottom
- 1;
1311 case 'C': /* Right */
1312 x
+= par
[0] ? par
[0] : 1;
1313 if (x
>= vinfo
.v_columns
)
1314 x
= vinfo
.v_columns
-1;
1316 case 'D': /* Left */
1317 x
-= par
[0] ? par
[0] : 1;
1321 case 'H': /* Set cursor position */
1323 x
= par
[1] ? par
[1] - 1 : 0;
1324 y
= par
[0] ? par
[0] - 1 : 0;
1325 if (vc_relative_origin
)
1329 case 'X': /* clear p1 characters */
1332 for (i
= x
; i
< x
+ par
[0]; i
++)
1333 vc_paintchar(' ', i
, y
, ATTR_NONE
);
1336 case 'J': /* Clear part of screen */
1337 clear_screen(par
[0]);
1339 case 'K': /* Clear part of line */
1342 case 'g': /* tab stops */
1345 case 2: /* reset tab stops */
1348 case 3: /* Clear every tabs */
1352 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1361 case 'm': /* Set attribute */
1362 for (i
= 0; i
< numpars
; i
++) {
1366 vc_color_set(VC_RESET_BACKGROUND
);
1367 vc_color_set(VC_RESET_FOREGROUND
);
1376 attr
|= ATTR_REVERSE
;
1382 attr
&= ~ATTR_UNDER
;
1385 attr
&= ~ATTR_REVERSE
;
1388 case 25: /* blink/no blink */
1391 vc_color_set(par
[i
]);
1396 case 'r': /* Set scroll region */
1398 /* ensure top < bottom, and both within limits */
1399 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1400 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1406 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1407 scrreg_bottom
= par
[1];
1408 if (scrreg_bottom
> vinfo
.v_rows
)
1409 scrreg_bottom
= vinfo
.v_rows
;
1411 scrreg_bottom
= vinfo
.v_rows
;
1413 if (vc_relative_origin
)
1421 putc_getpars(unsigned char ch
)
1428 vt100state
= ESnormal
;
1432 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1435 if (ch
>= '0' && ch
<= '9') {
1437 par
[numpars
] += ch
- '0';
1440 vt100state
= ESgotpars
;
1446 putc_square(unsigned char ch
)
1450 for (i
= 0; i
< MAXPARS
; i
++) {
1455 vt100state
= ESgetpars
;
1465 return; /* ignore null characters */
1467 switch (vt100state
) {
1468 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1488 putc_charsizecmd(ch
);
1491 putc_charsetcmd(0, ch
);
1494 putc_charsetcmd(1, ch
);
1498 if (x
>= vinfo
.v_columns
) {
1499 x
= vinfo
.v_columns
- 1;
1504 if (y
>= vinfo
.v_rows
) {
1505 y
= vinfo
.v_rows
- 1;
1514 * Actually draws the buffer, handle the jump scroll
1516 static void vc_flush_forward_buffer(void)
1522 assert(vc_forward_buffer_enabled
);
1525 simple_lock(&vc_forward_lock
);
1527 if (vc_forward_buffer_busy
) {
1528 /* Bail out if we're already in the middle of a flush. */
1529 simple_unlock(&vc_forward_lock
);
1534 vc_forward_buffer_busy
= 1;
1536 while (todo
< vc_forward_buffer_size
) {
1537 todo
= vc_forward_buffer_size
;
1539 /* Drop the lock while we update the screen. */
1540 simple_unlock(&vc_forward_lock
);
1547 #ifdef FAST_JUMP_SCROLL
1548 if ((todo
- start
) < 2) {
1549 vc_putchar(vc_forward_buffer
[start
++]);
1551 assert(vc_forward_scroll
== 0);
1553 vc_forward_preflight_save
.vt100state
= vt100state
;
1554 vc_forward_preflight_save
.vc_wrap_mode
= vc_wrap_mode
;
1555 vc_forward_preflight_save
.vc_relative_origin
= vc_relative_origin
;
1556 vc_forward_preflight_save
.vc_charset_select
= vc_charset_select
;
1557 vc_forward_preflight_save
.vc_save_charset_s
= vc_save_charset_s
;
1558 vc_forward_preflight_save
.vc_charset
[0] = vc_charset
[0];
1559 vc_forward_preflight_save
.vc_charset
[1] = vc_charset
[1];
1560 vc_forward_preflight_save
.vc_charset_save
[0] = vc_charset_save
[0];
1561 vc_forward_preflight_save
.vc_charset_save
[1] = vc_charset_save
[1];
1562 vc_forward_preflight_save
.x
= x
;
1563 vc_forward_preflight_save
.y
= y
;
1564 vc_forward_preflight_save
.savex
= savex
;
1565 vc_forward_preflight_save
.savey
= savey
;
1566 vc_forward_preflight_save
.numpars
= numpars
;
1567 vc_forward_preflight_save
.hanging_cursor
= hanging_cursor
;
1568 vc_forward_preflight_save
.attr
= attr
;
1569 vc_forward_preflight_save
.saveattr
= saveattr
;
1570 vc_forward_preflight_save
.scrreg_top
= scrreg_top
;
1571 vc_forward_preflight_save
.scrreg_bottom
= scrreg_bottom
;
1572 vc_forward_preflight_save
.vc_color_fore
= vc_color_fore
;
1573 vc_forward_preflight_save
.vc_color_back
= vc_color_back
;
1574 bcopy( (const char *) par
,
1575 (char *) vc_forward_preflight_save
.par
,
1576 (vm_size_t
) sizeof(par
) );
1577 bcopy( (const char *) tab_stops
,
1578 (char *) vc_forward_preflight_save
.tab_stops
,
1579 (vm_size_t
) sizeof(tab_stops
) );
1581 vc_forward_preflight_mode
= PFwind
;
1585 vc_forward_preflight_save
.scrreg_top
== scrreg_top
&&
1586 vc_forward_preflight_save
.scrreg_bottom
== scrreg_bottom
;
1588 vc_putchar(vc_forward_buffer
[i
]);
1590 vt100state
= vc_forward_preflight_save
.vt100state
;
1591 vc_wrap_mode
= vc_forward_preflight_save
.vc_wrap_mode
;
1592 vc_relative_origin
= vc_forward_preflight_save
.vc_relative_origin
;
1593 vc_charset_select
= vc_forward_preflight_save
.vc_charset_select
;
1594 vc_save_charset_s
= vc_forward_preflight_save
.vc_save_charset_s
;
1595 vc_charset
[0] = vc_forward_preflight_save
.vc_charset
[0];
1596 vc_charset
[1] = vc_forward_preflight_save
.vc_charset
[1];
1597 vc_charset_save
[0] = vc_forward_preflight_save
.vc_charset_save
[0];
1598 vc_charset_save
[1] = vc_forward_preflight_save
.vc_charset_save
[1];
1599 x
= vc_forward_preflight_save
.x
;
1600 y
= vc_forward_preflight_save
.y
;
1601 savex
= vc_forward_preflight_save
.savex
;
1602 savey
= vc_forward_preflight_save
.savey
;
1603 numpars
= vc_forward_preflight_save
.numpars
;
1604 hanging_cursor
= vc_forward_preflight_save
.hanging_cursor
;
1605 attr
= vc_forward_preflight_save
.attr
;
1606 saveattr
= vc_forward_preflight_save
.saveattr
;
1607 scrreg_top
= vc_forward_preflight_save
.scrreg_top
;
1608 scrreg_bottom
= vc_forward_preflight_save
.scrreg_bottom
;
1609 vc_color_fore
= vc_forward_preflight_save
.vc_color_fore
;
1610 vc_color_back
= vc_forward_preflight_save
.vc_color_back
;
1611 bcopy( (const char *) vc_forward_preflight_save
.par
,
1613 (vm_size_t
) sizeof(par
) );
1614 bcopy( (const char *) vc_forward_preflight_save
.tab_stops
,
1616 (vm_size_t
) sizeof(tab_stops
) );
1618 vc_forward_preflight_mode
= PFscroll
;
1620 if (vc_forward_scroll
> 0)
1621 scrollup(vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1622 scrreg_bottom
- scrreg_top
: vc_forward_scroll
);
1623 else if (vc_forward_scroll
< 0)
1624 scrolldown(-vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1625 scrreg_bottom
- scrreg_top
: -vc_forward_scroll
);
1627 vc_forward_preflight_mode
= PFunwind
;
1629 for (; start
< i
; start
++)
1630 vc_putchar(vc_forward_buffer
[start
]);
1632 assert(vc_forward_scroll
== 0);
1634 vc_forward_preflight_mode
= PFoff
;
1636 #else !FAST_JUMP_SCROLL
1638 int drawlen
= start
;
1640 int param
= 0, changebackground
= 0;
1641 enum vt100state_e vtState
= vt100state
;
1643 * In simple words, here we're pre-parsing the text to look for
1644 * + Newlines, for computing jump scroll
1645 * + /\033\[[0-9;]*]m/ to continue on
1646 * any other sequence will stop. We don't want to have cursor
1647 * movement escape sequences while we're trying to pre-scroll
1649 * We have to be extra carefull about the sequences that changes
1650 * the background color to prevent scrolling in those
1652 * That parsing was added to speed up 'man' and 'color-ls' a
1653 * zillion time (at least). It's worth it, trust me.
1654 * (mail Nick Stephen for a True Performance Graph)
1657 for (i
= start
; i
< todo
&& plaintext
; i
++) {
1661 switch (vc_forward_buffer
[i
]) {
1671 switch (vc_forward_buffer
[i
]) {
1673 vtState
= ESgetpars
;
1675 changebackground
= 0;
1683 if ((vc_forward_buffer
[i
] >= '0' &&
1684 vc_forward_buffer
[i
] <= '9') ||
1685 vc_forward_buffer
[i
] == ';') {
1686 if (vc_forward_buffer
[i
] >= '0' &&
1687 vc_forward_buffer
[i
] <= '9')
1688 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1690 if (param
>= 40 && param
<= 47)
1691 changebackground
= 1;
1692 if (!vc_normal_background
&&
1694 changebackground
= 1;
1697 break; /* continue on */
1699 vtState
= ESgotpars
;
1702 switch (vc_forward_buffer
[i
]) {
1705 if (param
>= 40 && param
<= 47)
1706 changebackground
= 1;
1707 if (!vc_normal_background
&&
1709 changebackground
= 1;
1710 if (changebackground
) {
1713 /* REALLY don't jump */
1715 /* Yup ! we've got it */
1730 * Then we look if it would be appropriate to forward jump
1731 * the screen before drawing
1733 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1734 jump
-= scrreg_bottom
- y
- 1;
1736 if (jump
>= scrreg_bottom
- scrreg_top
)
1737 jump
= scrreg_bottom
- scrreg_top
-1;
1743 * and we draw what we've found to the parser
1745 for (i
= start
; i
< drawlen
; i
++)
1746 vc_putchar(vc_forward_buffer
[start
++]);
1748 * Continue sending characters to the parser until we're sure we're
1749 * back on normal characters.
1751 for (i
= start
; i
< todo
&&
1752 vt100state
!= ESnormal
; i
++)
1753 vc_putchar(vc_forward_buffer
[start
++]);
1754 #endif !FAST_JUMP_SCROLL
1755 /* Then loop again if there still things to draw */
1756 } while (start
< todo
);
1760 /* Re-acquire the lock while we check our state. */
1762 simple_lock(&vc_forward_lock
);
1765 vc_forward_buffer_busy
= 0;
1766 vc_forward_buffer_size
= 0;
1768 simple_unlock(&vc_forward_lock
);
1773 vcputc(int l
, int u
, int c
)
1775 if(!vinfo
.v_baseaddr
)
1779 * Either we're really buffering stuff or we're not yet because
1780 * the probe hasn't been done.
1782 if (vc_forward_buffer_enabled
)
1791 * Store characters to be drawn 'later', handle overflows
1795 vc_store_char(unsigned char c
)
1800 assert(vc_forward_buffer_enabled
);
1803 simple_lock(&vc_forward_lock
);
1805 /* Spin until the buffer has space for another character. */
1806 while (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
) {
1807 simple_unlock(&vc_forward_lock
);
1811 simple_lock(&vc_forward_lock
);
1814 assert(vc_forward_buffer_size
< VC_MAX_FORWARD_SIZE
);
1816 vc_forward_buffer
[vc_forward_buffer_size
++] = (unsigned char)c
;
1818 if (vc_forward_buffer_size
== 1) {
1819 /* If we're adding the first character to the buffer,
1820 * start the timer, otherwise it is already running.
1825 timeout((timeout_fcn_t
)vc_flush_forward_buffer
,
1827 VC_CONSOLE_UPDATE_TIMEOUT
);
1829 } else if (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
|| debug_mode
) {
1831 * If there is an overflow or this is an immediate character display
1832 * (eg. pre-clock printfs, panics), then we force a draw (take into
1833 * account that a flush might already be in progress).
1835 if (!vc_forward_buffer_busy
) {
1837 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
1841 simple_unlock(&vc_forward_lock
);
1846 * Immediate character display.. kernel printf uses this. Make sure
1847 * get flushed and that panics get fully displayed.
1849 vc_flush_forward_buffer();
1857 GratefulDebInit(); /* (TEST/DEBUG) */
1860 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1861 printf(" Video info: %d; video_board=%08X\n", i
, vboard
);
1862 printf(" Video name: %s\n", vinfo
.v_name
);
1863 printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
1864 vinfo
.v_height
, vinfo
.v_width
, vinfo
.v_depth
, vinfo
.v_rowbytes
, vinfo
.v_type
);
1865 printf(" physical address=%08X\n", vinfo
.v_physaddr
);
1868 vinfo
.v_rows
= vinfo
.v_height
/ CHARHEIGHT
;
1869 vinfo
.v_columns
= vinfo
.v_width
/ CHARWIDTH
;
1871 if (vinfo
.v_depth
>= 8) {
1872 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1874 vinfo
.v_rowscanbytes
= vinfo
.v_width
/ (8 / vinfo
.v_depth
);
1877 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1878 printf(" inited=%d\n", vc_initted
);
1882 vc_render_font(1, vinfo
.v_depth
);
1883 vc_color_mask
= vc_color_depth_masks
[vc_color_index_table
[vinfo
.v_depth
]];
1885 switch (vinfo
.v_depth
) {
1888 vc_paintchar
= vc_paint_char1
;
1891 vc_paintchar
= vc_paint_char2
;
1894 vc_paintchar
= vc_paint_char4
;
1897 vc_paintchar
= vc_paint_char8c
;
1900 vc_paintchar
= vc_paint_char16c
;
1903 vc_paintchar
= vc_paint_char32c
;
1907 #ifdef FAST_JUMP_SCROLL
1908 vc_forward_paintchar
= vc_paintchar
;
1909 vc_paintchar
= vc_paint_char
;
1910 #endif FAST_JUMP_SCROLL
1916 if (vinfo
.v_depth
>= 8)
1917 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1918 printf("video console at 0x%x (%dx%dx%d)\n", vinfo
.v_baseaddr
,
1919 vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_depth
);
1922 * Added for the buffering and jump scrolling
1925 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1927 vc_forward_buffer_enabled
= 1;
1932 struct vc_progress_element
{
1933 unsigned int version
;
1936 unsigned char count
;
1937 unsigned char res
[3];
1943 unsigned int res2
[3];
1944 unsigned char data
[0];
1946 typedef struct vc_progress_element vc_progress_element
;
1948 static vc_progress_element
* vc_progress
;
1949 static const unsigned char * vc_progress_data
;
1950 static const unsigned char * vc_progress_alpha
;
1951 static boolean_t vc_progress_enable
;
1952 static const unsigned char * vc_clut
;
1953 static const unsigned char * vc_clut8
;
1954 static unsigned char vc_revclut8
[256];
1955 static unsigned int vc_progress_tick
;
1956 static boolean_t vc_graphics_mode
;
1957 static boolean_t vc_acquired
;
1958 static boolean_t vc_need_clear
;
1959 static boolean_t vc_needsave
;
1960 static vm_address_t vc_saveunder
;
1961 static vm_size_t vc_saveunder_len
;
1963 static void vc_blit_rect_8c( int x
, int y
,
1964 int width
, int height
,
1965 const unsigned char * dataPtr
,
1966 const unsigned char * alphaPtr
,
1967 unsigned char * backPtr
,
1968 boolean_t save
, boolean_t static_alpha
)
1970 volatile unsigned char * dst
;
1973 unsigned char alpha
;
1975 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1976 (y
* vinfo
.v_rowbytes
) +
1979 for( line
= 0; line
< height
; line
++) {
1980 for( col
= 0; col
< width
; col
++) {
1982 if( dataPtr
!= 0) data
= *dataPtr
++;
1983 else if( alphaPtr
!= 0) data
= vc_revclut8
[*alphaPtr
++];
1984 *(dst
+ col
) = data
;
1986 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1991 static void vc_blit_rect_16( int x
, int y
,
1992 int width
, int height
,
1993 const unsigned char * dataPtr
,
1994 const unsigned char * alphaPtr
,
1995 unsigned short * backPtr
,
1996 boolean_t save
, boolean_t static_alpha
)
1998 volatile unsigned short * dst
;
2000 unsigned int data
, index
, alpha
, back
;
2002 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
2003 (y
* vinfo
.v_rowbytes
) +
2006 for( line
= 0; line
< height
; line
++) {
2007 for( col
= 0; col
< width
; col
++) {
2013 if( alphaPtr
&& backPtr
) {
2015 alpha
= *alphaPtr
++;
2018 if( vc_clut
[index
+ 0] > alpha
)
2019 data
|= (((vc_clut
[index
+ 0] - alpha
) & 0xf8) << 7);
2020 if( vc_clut
[index
+ 1] > alpha
)
2021 data
|= (((vc_clut
[index
+ 1] - alpha
) & 0xf8) << 2);
2022 if( vc_clut
[index
+ 2] > alpha
)
2023 data
|= (((vc_clut
[index
+ 2] - alpha
) & 0xf8) >> 3);
2027 back
= *(dst
+ col
);
2030 back
= (((((back
& 0x7c00) * alpha
) + 0x3fc00) >> 8) & 0x7c00)
2031 | (((((back
& 0x03e0) * alpha
) + 0x01fe0) >> 8) & 0x03e0)
2032 | (((((back
& 0x001f) * alpha
) + 0x000ff) >> 8) & 0x001f);
2037 if ( !static_alpha
) {
2038 back
= (((((back
& 0x7c00) * alpha
) + 0x3fc00) >> 8) & 0x7c00)
2039 | (((((back
& 0x03e0) * alpha
) + 0x01fe0) >> 8) & 0x03e0)
2040 | (((((back
& 0x001f) * alpha
) + 0x000ff) >> 8) & 0x001f);
2048 data
= ( (0xf8 & (vc_clut
[index
+ 0])) << 7)
2049 | ( (0xf8 & (vc_clut
[index
+ 1])) << 2)
2050 | ( (0xf8 & (vc_clut
[index
+ 2])) >> 3);
2053 *(dst
+ col
) = data
;
2055 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
2059 static void vc_blit_rect_32( unsigned int x
, unsigned int y
,
2060 unsigned int width
, unsigned int height
,
2061 const unsigned char * dataPtr
,
2062 const unsigned char * alphaPtr
,
2063 unsigned int * backPtr
,
2064 boolean_t save
, boolean_t static_alpha
)
2066 volatile unsigned int * dst
;
2068 unsigned int data
, index
, alpha
, back
;
2070 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2071 (y
* vinfo
.v_rowbytes
) +
2074 for( line
= 0; line
< height
; line
++) {
2075 for( col
= 0; col
< width
; col
++) {
2081 if( alphaPtr
&& backPtr
) {
2083 alpha
= *alphaPtr
++;
2086 if( vc_clut
[index
+ 0] > alpha
)
2087 data
|= ((vc_clut
[index
+ 0] - alpha
) << 16);
2088 if( vc_clut
[index
+ 1] > alpha
)
2089 data
|= ((vc_clut
[index
+ 1] - alpha
) << 8);
2090 if( vc_clut
[index
+ 2] > alpha
)
2091 data
|= ((vc_clut
[index
+ 2] - alpha
));
2095 back
= *(dst
+ col
);
2098 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2099 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2104 if ( !static_alpha
) {
2105 back
= (((((back
& 0x00ff00ff) * alpha
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2106 | (((((back
& 0x0000ff00) * alpha
) + 0x0000ff00) >> 8) & 0x0000ff00);
2114 data
= (vc_clut
[index
+ 0] << 16)
2115 | (vc_clut
[index
+ 1] << 8)
2116 | (vc_clut
[index
+ 2]);
2119 *(dst
+ col
) = data
;
2121 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2126 draw_panic_dialog( void )
2128 int pd_x
,pd_y
, iconx
, icony
, tx_line
, tx_col
;
2130 int f1
, f2
, d1
, d2
, d3
, rem
;
2137 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
2138 unsigned int ip_addr
= kdp_get_ip_address();
2141 if (!panicDialogDrawn
)
2143 if ( !logPanicDataToScreen
)
2146 /* dim the screen 50% before putting up panic dialog */
2149 /* set up to draw background box */
2150 pd_x
= (vinfo
.v_width
/2) - panic_dialog
.pd_width
/2;
2151 pd_y
= (vinfo
.v_height
/2) - panic_dialog
.pd_height
/2;
2154 panic_blit_rect( pd_x
, pd_y
, panic_dialog
.pd_width
, panic_dialog
.pd_height
, 0, (unsigned char*) panic_dialog
.image_pixel_data
);
2156 /* offset for mac address text */
2157 mac_addr_digit_x
= (vinfo
.v_width
/2) - 130; /* use 62 if no ip */
2158 mac_addr_digit_y
= (vinfo
.v_height
/2) + panic_dialog
.pd_height
/2 - 20;
2160 if(kdp_mac_addr
.ether_addr_octet
[0] || kdp_mac_addr
.ether_addr_octet
[1]|| kdp_mac_addr
.ether_addr_octet
[2]
2161 || kdp_mac_addr
.ether_addr_octet
[3] || kdp_mac_addr
.ether_addr_octet
[4] || kdp_mac_addr
.ether_addr_octet
[5])
2163 /* blit the digits for mac address */
2164 for (count
= 0; count
< 6; count
++ )
2166 nibble
= (kdp_mac_addr
.ether_addr_octet
[count
] & 0xf0) >> 4;
2167 digit
= nibble
< 10 ? nibble
+ '0':nibble
- 10 + 'a';
2170 nibble
= kdp_mac_addr
.ether_addr_octet
[count
] & 0xf;
2171 digit
= nibble
< 10 ? nibble
+ '0':nibble
- 10 + 'a';
2174 blit_digit( colon
);
2177 else /* blit the ff's */
2179 for( count
= 0; count
< 6; count
++ )
2186 blit_digit( colon
);
2189 /* now print the ip address */
2190 mac_addr_digit_x
= (vinfo
.v_width
/2) + 10;
2193 /* blit the digits for ip address */
2194 for (count
= 0; count
< 4; count
++ )
2196 nibble
= (ip_addr
& 0xff000000 ) >> 24;
2198 d3
= (nibble
% 0xa) + '0';
2199 nibble
= nibble
/0xa;
2200 d2
= (nibble
% 0xa) + '0';
2201 nibble
= nibble
/0xa;
2202 d1
= (nibble
% 0xa) + '0';
2204 if( d1
) blit_digit(d1
);
2211 ip_addr
= ip_addr
<< 8;
2216 panicDialogDrawn
= TRUE
;
2222 blit_digit( int digit
)
2227 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
);
2228 mac_addr_digit_x
= mac_addr_digit_x
+ num_0
.num_w
- 1;
2232 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
);
2233 mac_addr_digit_x
= mac_addr_digit_x
+ num_1
.num_w
;
2237 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
);
2238 mac_addr_digit_x
= mac_addr_digit_x
+ num_2
.num_w
;
2242 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
);
2243 mac_addr_digit_x
= mac_addr_digit_x
+ num_3
.num_w
;
2247 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
);
2248 mac_addr_digit_x
= mac_addr_digit_x
+ num_4
.num_w
;
2252 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
);
2253 mac_addr_digit_x
= mac_addr_digit_x
+ num_5
.num_w
;
2257 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
);
2258 mac_addr_digit_x
= mac_addr_digit_x
+ num_6
.num_w
;
2262 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
);
2263 mac_addr_digit_x
= mac_addr_digit_x
+ num_7
.num_w
;
2267 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
);
2268 mac_addr_digit_x
= mac_addr_digit_x
+ num_8
.num_w
;
2272 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
);
2273 mac_addr_digit_x
= mac_addr_digit_x
+ num_9
.num_w
;
2277 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
);
2278 mac_addr_digit_x
= mac_addr_digit_x
+ num_a
.num_w
;
2282 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
);
2283 mac_addr_digit_x
= mac_addr_digit_x
+ num_b
.num_w
;
2287 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
);
2288 mac_addr_digit_x
= mac_addr_digit_x
+ num_c
.num_w
;
2292 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
);
2293 mac_addr_digit_x
= mac_addr_digit_x
+ num_d
.num_w
;
2297 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
);
2298 mac_addr_digit_x
= mac_addr_digit_x
+ num_e
.num_w
;
2302 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
);
2303 mac_addr_digit_x
= mac_addr_digit_x
+ num_f
.num_w
;
2307 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
);
2308 mac_addr_digit_x
= mac_addr_digit_x
+ num_colon
.num_w
;
2312 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
);
2313 mac_addr_digit_x
= mac_addr_digit_x
+ num_colon
.num_w
;
2323 panic_blit_rect( unsigned int x
, unsigned int y
,
2324 unsigned int width
, unsigned int height
,
2325 int transparent
, unsigned char * dataPtr
)
2330 switch( vinfo
.v_depth
) {
2332 panic_blit_rect_8( x
, y
, width
, height
, transparent
, dataPtr
);
2335 panic_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
);
2338 panic_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
);
2343 /* panic_blit_rect_8 is not tested and probably doesn't draw correctly.
2344 it really needs a clut to use
2347 panic_blit_rect_8( unsigned int x
, unsigned int y
,
2348 unsigned int width
, unsigned int height
,
2349 int transparent
, unsigned char * dataPtr
)
2351 volatile unsigned int * dst
;
2353 unsigned int pixelR
, pixelG
, pixelB
;
2355 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2356 (y
* vinfo
.v_rowbytes
) +
2359 for( line
= 0; line
< height
; line
++) {
2360 for( col
= 0; col
< width
; col
++) {
2361 pixelR
= *dataPtr
++;
2362 pixelG
= *dataPtr
++;
2363 pixelB
= *dataPtr
++;
2364 if(( pixelR
!= transparent
) || (pixelG
!= transparent
) || (pixelB
!= transparent
))
2366 *(dst
+ col
) = ((19595 * pixelR
+
2368 7471 * pixelB
) / 65536);
2372 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2376 /* panic_blit_rect_16 draws adequately. It would be better if it had a clut
2377 to use instead of scaling the 32bpp color values.
2379 panic_blit_rect_16 decodes the RLE encoded image data on the fly, scales it down
2380 to 16bpp, and fills in each of the three pixel values (RGB) for each pixel
2381 and writes it to the screen.
2385 panic_blit_rect_16( unsigned int x
, unsigned int y
,
2386 unsigned int width
, unsigned int height
,
2387 int transparent
, unsigned char * dataPtr
)
2389 volatile unsigned int * dst
;
2390 int line
, value
, total
= 0;
2391 unsigned int quantity
, tmp
, pixel
;
2394 boolean_t secondTime
= 0;
2398 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2399 (y
* vinfo
.v_rowbytes
) +
2403 *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
2404 | ( (0xf8 & (vc_clut[data + 1])) << 2)
2405 | ( (0xf8 & (vc_clut[data + 2])) >> 3);
2408 for( line
= 0; line
< height
; line
++)
2410 while ( total
< width
)
2412 quantity
= *dataPtr
++;
2414 value
= (0x1f * value
)/255;
2415 while( quantity
> 0 )
2421 tmp
|= (value
<< 10) & 0x7c00;
2422 // tmp |= (value & 0xf8) << 7;
2429 tmp
|= (value
<< 5) & 0x3e0;
2430 // tmp |= (value & 0xf8) << 2;
2437 tmp
|= value
& 0x1f;
2438 // tmp |= (value & 0xf8) >> 3;
2446 *(dst
+ pix_incr
++) = pixel
;
2460 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2467 panic_blit_rect_32 decodes the RLE encoded image data on the fly, and fills
2468 in each of the three pixel values (RGB) for each pixel and writes it to the
2472 panic_blit_rect_32( unsigned int x
, unsigned int y
,
2473 unsigned int width
, unsigned int height
,
2474 int transparent
, unsigned char * dataPtr
)
2476 volatile unsigned int * dst
;
2477 int line
, total
= 0;
2478 unsigned int value
, quantity
, tmp
;
2481 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2482 (y
* vinfo
.v_rowbytes
) +
2485 for( line
= 0; line
< height
; line
++)
2487 while ( total
< width
)
2489 quantity
= *dataPtr
++;
2491 while( quantity
> 0 )
2512 *(dst
+ total
) = tmp
;
2523 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2534 switch( vinfo
.v_depth
) {
2551 unsigned long *p
, *endp
, *row
;
2553 int rowline
, rowlongs
;
2554 unsigned long value
, tmp
;
2556 rowline
= vinfo
.v_rowscanbytes
/ 4;
2557 rowlongs
= vinfo
.v_rowbytes
/ 4;
2559 p
= (unsigned long*) vinfo
.v_baseaddr
;;
2560 endp
= (unsigned long*) vinfo
.v_baseaddr
;
2562 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
2563 endp
+= rowlongs
* vinfo
.v_height
;
2565 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2566 for (col
= 0; col
< rowline
; col
++) {
2568 tmp
= ((value
& 0x7C007C00) >> 1) & 0x3C003C00;
2569 tmp
|= ((value
& 0x03E003E0) >> 1) & 0x01E001E0;
2570 tmp
|= ((value
& 0x001F001F) >> 1) & 0x000F000F;
2571 *(row
+col
) = tmp
; //half (dimmed)?
2581 unsigned long *p
, *endp
, *row
;
2583 int rowline
, rowlongs
;
2584 unsigned long value
, tmp
;
2586 rowline
= vinfo
.v_rowscanbytes
/ 4;
2587 rowlongs
= vinfo
.v_rowbytes
/ 4;
2589 p
= (unsigned long*) vinfo
.v_baseaddr
;;
2590 endp
= (unsigned long*) vinfo
.v_baseaddr
;
2592 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
2593 endp
+= rowlongs
* vinfo
.v_height
;
2595 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2596 for (col
= 0; col
< rowline
; col
++) {
2598 tmp
= ((value
& 0x00FF0000) >> 1) & 0x007F0000;
2599 tmp
|= ((value
& 0x0000FF00) >> 1) & 0x00007F00;
2600 tmp
|= (value
& 0x000000FF) >> 1;
2601 *(row
+col
) = tmp
; //half (dimmed)?
2608 static void vc_blit_rect( unsigned int x
, unsigned int y
,
2609 unsigned int width
, unsigned int height
,
2610 const unsigned char * dataPtr
,
2611 const unsigned char * alphaPtr
,
2612 vm_address_t backBuffer
,
2613 boolean_t save
, boolean_t static_alpha
)
2615 if(!vinfo
.v_baseaddr
)
2618 switch( vinfo
.v_depth
) {
2620 if( vc_clut8
== vc_clut
)
2621 vc_blit_rect_8c( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned char *) backBuffer
, save
, static_alpha
);
2624 vc_blit_rect_16( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned short *) backBuffer
, save
, static_alpha
);
2627 vc_blit_rect_32( x
, y
, width
, height
, dataPtr
, alphaPtr
, (unsigned int *) backBuffer
, save
, static_alpha
);
2632 static void vc_progress_task( void * arg
)
2635 int count
= (int) arg
;
2636 int x
, y
, width
, height
;
2637 const unsigned char * data
;
2640 simple_lock(&vc_forward_lock
);
2642 if( vc_progress_enable
) {
2645 if( count
>= vc_progress
->count
)
2648 width
= vc_progress
->width
;
2649 height
= vc_progress
->height
;
2650 x
= vc_progress
->dx
;
2651 y
= vc_progress
->dy
;
2652 data
= vc_progress_data
;
2653 data
+= count
* width
* height
;
2654 if( 1 & vc_progress
->flags
) {
2655 x
+= ((vinfo
.v_width
- width
) / 2);
2656 y
+= ((vinfo
.v_height
- height
) / 2);
2658 vc_blit_rect( x
, y
, width
, height
,
2659 NULL
, data
, vc_saveunder
,
2660 vc_needsave
, (0 == (4 & vc_progress
->flags
)) );
2661 vc_needsave
= FALSE
;
2663 timeout( vc_progress_task
, (void *) count
,
2666 simple_unlock(&vc_forward_lock
);
2670 void vc_display_icon( vc_progress_element
* desc
,
2671 const unsigned char * data
)
2673 int x
, y
, width
, height
;
2675 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
2677 width
= desc
->width
;
2678 height
= desc
->height
;
2681 if( 1 & desc
->flags
) {
2682 x
+= ((vinfo
.v_width
- width
) / 2);
2683 y
+= ((vinfo
.v_height
- height
) / 2);
2685 vc_blit_rect( x
, y
, width
, height
, data
, NULL
, (vm_address_t
) NULL
, FALSE
, TRUE
);
2689 static boolean_t ignore_first_enable
= TRUE
;
2692 vc_progress_set( boolean_t enable
, unsigned int initial_tick
)
2695 vm_address_t saveBuf
= 0;
2696 vm_size_t saveLen
= 0;
2699 unsigned char data8
;
2700 unsigned short data16
;
2701 unsigned short * buf16
;
2702 unsigned int data32
;
2703 unsigned int * buf32
;
2708 if( enable
& ignore_first_enable
) {
2710 ignore_first_enable
= FALSE
;
2714 saveLen
= vc_progress
->width
* vc_progress
->height
* vinfo
.v_depth
/ 8;
2715 saveBuf
= kalloc( saveLen
);
2717 if( !vc_need_clear
) switch( vinfo
.v_depth
) {
2719 for( count
= 0; count
< 256; count
++) {
2720 vc_revclut8
[count
] = vc_clut
[0x01 * 3];
2721 data8
= (vc_clut
[0x01 * 3] * count
+ 0x0ff) >> 8;
2722 for( index
= 0; index
< 256; index
++) {
2723 if( (data8
== vc_clut
[index
* 3 + 0]) &&
2724 (data8
== vc_clut
[index
* 3 + 1]) &&
2725 (data8
== vc_clut
[index
* 3 + 2])) {
2726 vc_revclut8
[count
] = index
;
2731 memset( (void *) saveBuf
, 0x01, saveLen
);
2735 buf16
= (unsigned short *) saveBuf
;
2736 data16
= ((vc_clut
[0x01 * 3 + 0] & 0xf8) << 7)
2737 | ((vc_clut
[0x01 * 3 + 0] & 0xf8) << 2)
2738 | ((vc_clut
[0x01 * 3 + 0] & 0xf8) >> 3);
2739 for( count
= 0; count
< saveLen
/ 2; count
++)
2740 buf16
[count
] = data16
;
2744 buf32
= (unsigned int *) saveBuf
;
2745 data32
= ((vc_clut
[0x01 * 3 + 0] & 0xff) << 16)
2746 | ((vc_clut
[0x01 * 3 + 1] & 0xff) << 8)
2747 | ((vc_clut
[0x01 * 3 + 2] & 0xff) << 0);
2748 for( count
= 0; count
< saveLen
/ 4; count
++)
2749 buf32
[count
] = data32
;
2755 simple_lock(&vc_forward_lock
);
2757 if( vc_progress_enable
!= enable
) {
2758 vc_progress_enable
= enable
;
2760 vc_needsave
= vc_need_clear
;
2761 vc_saveunder
= saveBuf
;
2762 vc_saveunder_len
= saveLen
;
2765 timeout(vc_progress_task
, (void *) 0,
2769 saveBuf
= vc_saveunder
;
2770 saveLen
= vc_saveunder_len
;
2772 vc_saveunder_len
= 0;
2774 untimeout( vc_progress_task
, (void *) 0 );
2779 vc_forward_buffer_size
= 0;
2780 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
2782 /* Spin if the flush is in progress */
2783 while (vc_forward_buffer_busy
) {
2784 simple_unlock(&vc_forward_lock
);
2788 simple_lock(&vc_forward_lock
);
2789 vc_forward_buffer_size
= 0;
2793 simple_unlock(&vc_forward_lock
);
2797 kfree( saveBuf
, saveLen
);
2804 vc_progress_initialize( vc_progress_element
* desc
,
2805 const unsigned char * data
,
2806 const unsigned char * clut
)
2808 if( (!clut
) || (!desc
) || (!data
))
2814 vc_progress_data
= data
;
2815 if( 2 & vc_progress
->flags
)
2816 vc_progress_alpha
= vc_progress_data
2817 + vc_progress
->count
* vc_progress
->width
* vc_progress
->height
;
2819 vc_progress_alpha
= NULL
;
2820 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
2825 // FirmwareC.c needs:
2826 Boot_Video boot_video_info
;
2828 extern int disableConsoleOutput
;
2830 static void vc_clear_screen( void )
2840 initialize_screen(Boot_Video
* boot_vinfo
, unsigned int op
)
2843 bcopy( (const void *) boot_vinfo
,
2844 (void *) &boot_video_info
,
2845 sizeof( boot_video_info
));
2847 vinfo
.v_name
[0] = 0;
2848 vinfo
.v_width
= boot_vinfo
->v_width
;
2849 vinfo
.v_height
= boot_vinfo
->v_height
;
2850 vinfo
.v_depth
= boot_vinfo
->v_depth
;
2851 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2852 vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
;
2853 vinfo
.v_baseaddr
= vinfo
.v_physaddr
;
2858 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2864 case kPEGraphicsMode
:
2865 vc_graphics_mode
= TRUE
;
2866 disableConsoleOutput
= TRUE
;
2871 vc_graphics_mode
= FALSE
;
2872 disableConsoleOutput
= FALSE
;
2878 vc_progress_set( FALSE
, 0 );
2879 disableConsoleOutput
= FALSE
;
2880 if( vc_need_clear
) {
2881 vc_need_clear
= FALSE
;
2886 case kPEEnableScreen
:
2888 if( vc_graphics_mode
)
2889 vc_progress_set( TRUE
, vc_progress_tick
);
2895 case kPEDisableScreen
:
2896 vc_progress_set( FALSE
, 0 );
2899 case kPEAcquireScreen
:
2900 vc_need_clear
= (FALSE
== vc_acquired
);
2902 vc_progress_set( vc_graphics_mode
, vc_need_clear
? 2 * hz
: 0 );
2903 disableConsoleOutput
= vc_graphics_mode
;
2904 if( vc_need_clear
&& !vc_graphics_mode
) {
2905 vc_need_clear
= FALSE
;
2910 case kPEReleaseScreen
:
2911 vc_acquired
= FALSE
;
2912 vc_progress_set( FALSE
, 0 );
2914 disableConsoleOutput
= TRUE
;
2916 GratefulDebInit(0); /* Stop grateful debugger */
2921 if( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */