]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/POWERMAC/video_console.c
xnu-344.49.tar.gz
[apple/xnu.git] / osfmk / ppc / POWERMAC / video_console.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
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
13 * file.
14 *
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.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * @OSF_FREE_COPYRIGHT@
27 *
28 */
29 /*
30 * @APPLE_FREE_COPYRIGHT@
31 */
32 /* MACH PPC - video_console.c
33 *
34 * Original based on NetBSD's mac68k/dev/ite.c driver
35 *
36 * This driver differs in
37 * - MACH driver"ized"
38 * - Uses phys_copy and flush_cache to in several places
39 * for performance optimizations
40 * - 7x15 font
41 * - Black background and white (character) foreground
42 * - Assumes 6100/7100/8100 class of machine
43 *
44 * The original header follows...
45 *
46 *
47 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
48 *
49 * Copyright (c) 1988 University of Utah.
50 * Copyright (c) 1990, 1993
51 * The Regents of the University of California. All rights reserved.
52 *
53 * This code is derived from software contributed to Berkeley by
54 * the Systems Programming Group of the University of Utah Computer
55 * Science Department.
56 *
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
59 * are met:
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.
72 *
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
83 * SUCH DAMAGE.
84 *
85 * from: Utah $Hdr: ite.c 1.28 92/12/20$
86 *
87 * @(#)ite.c 8.2 (Berkeley) 1/12/94
88 */
89
90 /*
91 * ite.c
92 *
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.
97 *
98 * -- Brad and Lawrence, June 26th, 1994
99 *
100 */
101
102 #include <vc.h>
103
104 #include <mach_kdb.h>
105 #include <kern/spl.h>
106 #include <machine/machparam.h> /* spl definitions */
107 #include <types.h>
108 #include <ppc/iso_font.h>
109 #include <ppc/Firmware.h>
110
111 #include <ppc/POWERMAC/video_console_entries.h>
112 #include <ppc/POWERMAC/video_console.h>
113 #include <pexpert/pexpert.h>
114 #include <kern/time_out.h>
115 #include <kern/lock.h>
116 #include <kern/debug.h>
117
118 #include <kdp/kdp_udp.h>
119
120 #include "panic_image.c"
121 #include "rendered_numbers.c"
122
123
124 #define FAST_JUMP_SCROLL
125
126 #define CHARWIDTH 8
127 #define CHARHEIGHT 16
128
129 #define ATTR_NONE 0
130 #define ATTR_BOLD 1
131 #define ATTR_UNDER 2
132 #define ATTR_REVERSE 4
133
134 enum vt100state_e {
135 ESnormal, /* Nothing yet */
136 ESesc, /* Got ESC */
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 */
144 ESask,
145 EScharsize,
146 ESignore /* Ignore this sequence */
147 } vt100state = ESnormal;
148
149 struct vc_info vinfo;
150
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 };
156
157 /* VT100 state: */
158 #define MAXPARS 16
159 static int x = 0, y = 0, savex, savey;
160 static int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
161
162 /* VT100 tab stops & scroll region */
163 static char tab_stops[255];
164 static int scrreg_top, scrreg_bottom;
165
166 /* Misc */
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);
171
172 void vcattach(void);
173
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;
179
180 static void
181 panic_blit_rect( unsigned int x, unsigned int y,
182 unsigned int width, unsigned int height,
183 int transparent, unsigned char * dataPtr );
184
185 static void
186 panic_blit_rect_8( unsigned int x, unsigned int y,
187 unsigned int width, unsigned int height,
188 int transparent, unsigned char * dataPtr );
189
190 static void
191 panic_blit_rect_16( unsigned int x, unsigned int y,
192 unsigned int width, unsigned int height,
193 int transparent, unsigned char * dataPtr );
194
195 static void
196 panic_blit_rect_32( unsigned int x, unsigned int y,
197 unsigned int width, unsigned int height,
198 int transparent, unsigned char * dataPtr );
199
200 static void
201 blit_rect_of_size_and_color( unsigned int x, unsigned int y,
202 unsigned int width, unsigned int height,
203 unsigned int dataPtr );
204
205 static void
206 dim_screen(void);
207
208 /*static void
209 dim_screen8(void);
210 */
211
212 static void
213 dim_screen16(void);
214
215 static void
216 dim_screen32(void);
217
218
219 /*
220 * For the color support (Michel Pollet)
221 */
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 };
225
226 static unsigned long vc_color_depth_masks[4] =
227 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
228
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 */
239 };
240
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;
245
246
247 /*
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 ;-)
252 */
253 #define VC_MAX_FORWARD_SIZE (100*36)
254
255 /*
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
260 */
261 #define VC_CONSOLE_UPDATE_TIMEOUT 5
262
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)
268
269 #ifdef FAST_JUMP_SCROLL
270 static void (*vc_forward_paintchar) (unsigned char c, int x, int y, int attrs);
271 static enum {
272 PFoff,
273 PFwind,
274 PFscroll,
275 PFunwind
276 } vc_forward_preflight_mode = PFoff;
277 static struct {
278 enum vt100state_e vt100state;
279
280 int vc_wrap_mode, vc_relative_origin;
281 int vc_charset_select, vc_save_charset_s;
282 int vc_charset[2];
283 int vc_charset_save[2];
284
285 int x, y, savex, savey;
286 int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
287
288 char tab_stops[255];
289 int scrreg_top, scrreg_bottom;
290
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
296
297 /*
298 * New Rendering code from Michel Pollet
299 */
300
301 /* That function will be called for drawing */
302 static void (*vc_paintchar) (unsigned char c, int x, int y, int attrs);
303
304 #ifdef RENDERALLOCATE
305 static unsigned char *renderedFont = NULL; /* rendered font buffer */
306 #else
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];
311 #endif
312
313 /* Rendered Font Size */
314 static unsigned long vc_rendered_font_size = REN_MAX_SIZE;
315 static long vc_rendered_error = 0;
316
317 /* If the one bit table was reversed */
318 static short vc_one_bit_reversed = 0;
319
320 /* Size of a character in the table (bytes) */
321 static int vc_rendered_char_size = 0;
322
323 /*
324 # Attribute codes:
325 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
326 # Text color codes:
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
330 */
331
332 #define VC_RESET_BACKGROUND 40
333 #define VC_RESET_FOREGROUND 37
334
335 static void vc_color_set(int color)
336 {
337 if (vinfo.v_depth < 8)
338 return;
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;
344 }
345
346 }
347
348 static void vc_render_font(short olddepth, short newdepth)
349 {
350 int charIndex; /* index in ISO font */
351 union {
352 unsigned char *charptr;
353 unsigned short *shortptr;
354 unsigned long *longptr;
355 } current; /* current place in rendered font, multiple types. */
356
357 unsigned char *theChar; /* current char in iso_font */
358
359 if (olddepth == newdepth && renderedFont) {
360 return; /* nothing to do */
361 }
362
363 if (olddepth != 1 && renderedFont) {
364 #ifdef RENDERALLOCATE
365 (void) kmem_free(kernel_map, (vm_offset_t*)renderedFont, vc_rendered_font_size);
366 #endif
367 }
368 vc_rendered_font_size = REN_MAX_SIZE;
369 if (newdepth == 1) {
370 #ifdef RENDERALLOCATE
371 renderedFont = iso_font;
372 #endif
373 vc_rendered_char_size = 16;
374 if (!vc_one_bit_reversed) { /* reverse the font for the blitter */
375 int i;
376 for (i = 0; i < ((ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size); i++) {
377 if (iso_font[i]) {
378 unsigned char mask1 = 0x80;
379 unsigned char mask2 = 0x01;
380 unsigned char val = 0;
381 while (mask1) {
382 if (iso_font[i] & mask1)
383 val |= mask2;
384 mask1 >>= 1;
385 mask2 <<= 1;
386 }
387 renderedFont[i] = ~val;
388 } else renderedFont[i] = 0xff;
389 }
390 vc_one_bit_reversed = 1;
391 }
392 return;
393 }
394 {
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;
402 return;
403 } else
404 vc_rendered_font_size = csize;
405 #else
406 vc_rendered_font_size = csize;
407 #endif
408 }
409
410 #ifdef RENDERALLOCATE
411 if (kmem_alloc(kernel_map,
412 (vm_offset_t *)&renderedFont,
413 vc_rendered_font_size) != KERN_SUCCESS) {
414 renderedFont = NULL;
415 vc_rendered_error = vc_rendered_font_size;
416 return;
417 }
418 #endif
419 current.charptr = renderedFont;
420 theChar = iso_font;
421 for (charIndex = ISO_CHAR_MIN; charIndex <= ISO_CHAR_MAX; charIndex++) {
422 int line;
423 for (line = 0; line < CHARHEIGHT; line++) {
424 unsigned char mask = 1;
425 do {
426 switch (newdepth) {
427 case 2: {
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;
433 value = ~value;
434 *current.charptr++ = value;
435 }
436 break;
437 case 4:
438 {
439 unsigned char value = 0;
440 if (*theChar & mask) value |= 0xF0; mask <<= 1;
441 if (*theChar & mask) value |= 0x0F;
442 value = ~value;
443 *current.charptr++ = value;
444 }
445 break;
446 case 8:
447 *current.charptr++ = (*theChar & mask) ? 0xff : 0;
448 break;
449 case 16:
450 *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
451 break;
452
453 case 32:
454 *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
455 break;
456 }
457 mask <<= 1;
458 } while (mask); /* while the single bit drops to the right */
459 theChar++;
460 }
461 }
462 }
463
464 #ifdef FAST_JUMP_SCROLL
465 static void vc_paint_char(unsigned char ch, int xx, int yy, int attrs)
466 {
467 switch (vc_forward_preflight_mode) {
468 case PFoff:
469 vc_forward_paintchar(ch, xx, yy, attrs);
470 break;
471 case PFwind:
472 break;
473 case PFscroll:
474 break;
475 case PFunwind:
476 if (yy >= scrreg_top && yy < scrreg_bottom) {
477 yy -= vc_forward_scroll;
478 if (yy < scrreg_top || yy >= scrreg_bottom)
479 break;
480 }
481 vc_forward_paintchar(ch, xx, yy, attrs);
482 break;
483 }
484 }
485 #endif FAST_JUMP_SCROLL
486
487 static void vc_paint_char1(unsigned char ch, int xx, int yy, int attrs)
488 {
489 unsigned char *theChar;
490 unsigned char *where;
491 int i;
492
493 theChar = (unsigned char*)(renderedFont + (ch * vc_rendered_char_size));
494 where = (unsigned char*)(vinfo.v_baseaddr +
495 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
496 (xx));
497
498 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
499 *where = *theChar++;
500
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;
506 int bit = 0;
507 for (bit = 0; bit < 7; bit++) {
508 if ((save & mask1) == mask2)
509 val &= ~mask2;
510 mask1 >>= 1;
511 mask2 >>= 1;
512 }
513 }
514 if (attrs & ATTR_REVERSE) val = ~val;
515 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
516 *where = val;
517
518 where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
519 }
520
521 }
522
523 static void vc_paint_char2(unsigned char ch, int xx, int yy, int attrs)
524 {
525 unsigned short *theChar;
526 unsigned short *where;
527 int i;
528
529 theChar = (unsigned short*)(renderedFont + (ch * vc_rendered_char_size));
530 where = (unsigned short*)(vinfo.v_baseaddr +
531 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
532 (xx * 2));
533 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
534 *where = *theChar++;
535
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;
541 int bit = 0;
542 for (bit = 0; bit < 7; bit++) {
543 if ((save & mask1) == mask2)
544 val &= ~mask2;
545 mask1 >>= 2;
546 mask2 >>= 2;
547 }
548 }
549 if (attrs & ATTR_REVERSE) val = ~val;
550 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
551 *where = val;
552
553 where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
554 }
555
556 }
557
558 static void vc_paint_char4(unsigned char ch, int xx, int yy, int attrs)
559 {
560 unsigned long *theChar;
561 unsigned long *where;
562 int i;
563
564 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
565 where = (unsigned long*)(vinfo.v_baseaddr +
566 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
567 (xx * 4));
568
569 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
570 *where = *theChar++;
571
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;
577 int bit = 0;
578 for (bit = 0; bit < 7; bit++) {
579 if ((save & mask1) == mask2)
580 val &= ~mask2;
581 mask1 >>= 4;
582 mask2 >>= 4;
583 }
584 }
585 if (attrs & ATTR_REVERSE) val = ~val;
586 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
587 *where = val;
588
589 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
590 }
591
592 }
593
594 static void vc_paint_char8c(unsigned char ch, int xx, int yy, int attrs)
595 {
596 unsigned long *theChar;
597 unsigned long *where;
598 int i;
599
600 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
601 where = (unsigned long*)(vinfo.v_baseaddr +
602 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
603 (xx * CHARWIDTH));
604
605 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attr? FLY !*/
606 unsigned long *store = where;
607 int x;
608 for (x = 0; x < 2; x++) {
609 unsigned long val = *theChar++;
610 val = (vc_color_back & ~val) | (vc_color_fore & val);
611 *store++ = val;
612 }
613
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;
617 int x;
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))
622 val |= 0xff000000;
623 if ((save & 0xFFFF0000) == 0xFF000000)
624 val |= 0x00FF0000;
625 if ((save & 0x00FFFF00) == 0x00FF0000)
626 val |= 0x0000FF00;
627 if ((save & 0x0000FFFF) == 0x0000FF00)
628 val |= 0x000000FF;
629 }
630 if (attrs & ATTR_REVERSE) val = ~val;
631 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
632
633 val = (vc_color_back & ~val) | (vc_color_fore & val);
634 *store++ = val;
635 lastpixel = save & 0xff;
636 }
637
638 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
639 }
640
641 }
642 static void vc_paint_char16c(unsigned char ch, int xx, int yy, int attrs)
643 {
644 unsigned long *theChar;
645 unsigned long *where;
646 int i;
647
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));
652
653 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
654 unsigned long *store = where;
655 int x;
656 for (x = 0; x < 4; x++) {
657 unsigned long val = *theChar++;
658 val = (vc_color_back & ~val) | (vc_color_fore & val);
659 *store++ = val;
660 }
661
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;
665 int x;
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))
671 val |= 0xFFFF0000;
672 }
673 if (attrs & ATTR_REVERSE) val = ~val;
674 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
675
676 val = (vc_color_back & ~val) | (vc_color_fore & val);
677
678 *store++ = val;
679 lastpixel = save & 0x7fff;
680 }
681
682 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
683 }
684
685 }
686 static void vc_paint_char32c(unsigned char ch, int xx, int yy, int attrs)
687 {
688 unsigned long *theChar;
689 unsigned long *where;
690 int i;
691
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));
696
697 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
698 unsigned long *store = where;
699 int x;
700 for (x = 0; x < 8; x++) {
701 unsigned long val = *theChar++;
702 val = (vc_color_back & ~val) | (vc_color_fore & val);
703 *store++ = val;
704 }
705
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;
709 int x;
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)
714 val = 0xFFFFFFFF;
715 }
716 if (attrs & ATTR_REVERSE) val = ~val;
717 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
718
719 val = (vc_color_back & ~val) | (vc_color_fore & val);
720 *store++ = val;
721 lastpixel = save;
722 }
723
724 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
725 }
726
727 }
728
729 /*
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
733 */
734 static void reversecursor(void)
735 {
736 union {
737 unsigned char *charptr;
738 unsigned short *shortptr;
739 unsigned long *longptr;
740 } where;
741 int line, col;
742
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) {
748 case 1:
749 *where.charptr = ~*where.charptr;
750 break;
751 case 2:
752 *where.shortptr = ~*where.shortptr;
753 break;
754 case 4:
755 *where.longptr = ~*where.longptr;
756 break;
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
761 */
762 #ifdef VC_BINARY_REVERSE
763 case 8:
764 where.longptr[0] = ~where.longptr[0];
765 where.longptr[1] = ~where.longptr[1];
766 break;
767 case 16:
768 for (col = 0; col < 4; col++)
769 where.longptr[col] = ~where.longptr[col];
770 break;
771 case 32:
772 for (col = 0; col < 8; col++)
773 where.longptr[col] = ~where.longptr[col];
774 break;
775 #else
776 case 8:
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;
780 break;
781 case 16:
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;
785 break;
786 case 32:
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;
790 break;
791 #endif
792 }
793 where.charptr += vinfo.v_rowbytes;
794 }
795 }
796
797
798 static void
799 scrollup(int num)
800 {
801 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
802
803 linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
804 rowline = (vinfo.v_rowbytes) >> 2;
805 rowscanline = (vinfo.v_rowscanbytes) >> 2;
806
807 #ifdef FAST_JUMP_SCROLL
808 if (vc_forward_preflight_mode == PFwind) {
809 vc_forward_scroll += num;
810 return;
811 }
812 if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
813 #endif FAST_JUMP_SCROLL
814
815 to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
816 from = to + (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
817
818 i = (scrreg_bottom - scrreg_top) - num;
819
820 while (i-- > 0) {
821 for (line = 0; line < CHARHEIGHT; line++) {
822 /*
823 * Only copy what is displayed
824 */
825 video_scroll_up((unsigned int) from,
826 (unsigned int) (from+(vinfo.v_rowscanbytes/4)),
827 (unsigned int) to);
828
829 from += rowline;
830 to += rowline;
831 }
832 }
833
834 /* Now set the freed up lines to the background colour */
835
836
837 to = ((unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs))
838 + ((scrreg_bottom - scrreg_top - num) * linelongs);
839
840 #ifdef FAST_JUMP_SCROLL
841 if (vc_forward_preflight_mode == PFscroll)
842 return;
843 } else if (vc_forward_preflight_mode == PFunwind) {
844 long linestart, linelast;
845 vc_forward_scroll -= num;
846
847 linestart = scrreg_bottom - num - vc_forward_scroll;
848 linelast = linestart + num - 1;
849
850 if (linestart >= scrreg_bottom || linelast < scrreg_top)
851 return;
852
853 if (linelast >= scrreg_bottom)
854 linelast = scrreg_bottom - 1;
855 if (linestart < scrreg_top)
856 linestart = scrreg_top;
857
858 to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
859 num = linelast - linestart + 1;
860 }
861 #endif FAST_JUMP_SCROLL
862
863 for (linelongs = CHARHEIGHT * num; linelongs-- > 0;) {
864 from = to;
865 for (i = 0; i < rowscanline; i++)
866 *to++ = vc_color_back;
867
868 to = from + rowline;
869 }
870
871 }
872
873 static void
874 scrolldown(int num)
875 {
876 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
877
878 linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
879 rowline = (vinfo.v_rowbytes) >> 2;
880 rowscanline = (vinfo.v_rowscanbytes) >> 2;
881
882 #ifdef FAST_JUMP_SCROLL
883 if (vc_forward_preflight_mode == PFwind) {
884 vc_forward_scroll -= num;
885 return;
886 }
887 if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
888 #endif FAST_JUMP_SCROLL
889
890 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
891 - (rowline - rowscanline);
892 from = to - (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
893
894 i = (scrreg_bottom - scrreg_top) - num;
895
896 while (i-- > 0) {
897 for (line = 0; line < CHARHEIGHT; line++) {
898 /*
899 * Only copy what is displayed
900 */
901 video_scroll_down((unsigned int) from,
902 (unsigned int) (from-(vinfo.v_rowscanbytes/4)),
903 (unsigned int) to);
904
905 from -= rowline;
906 to -= rowline;
907 }
908 }
909
910 /* Now set the freed up lines to the background colour */
911
912 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_top);
913
914 #ifdef FAST_JUMP_SCROLL
915 if (vc_forward_preflight_mode == PFscroll)
916 return;
917 } else if (vc_forward_preflight_mode == PFunwind) {
918 long linestart, linelast;
919 vc_forward_scroll += num;
920
921 linestart = scrreg_top - vc_forward_scroll;
922 linelast = linestart + num - 1;
923
924 if (linestart >= scrreg_bottom || linelast < scrreg_top)
925 return;
926
927 if (linelast >= scrreg_bottom)
928 linelast = scrreg_bottom - 1;
929 if (linestart < scrreg_top)
930 linestart = scrreg_top;
931
932 to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
933 num = linelast - linestart + 1;
934 }
935 #endif FAST_JUMP_SCROLL
936
937 for (line = CHARHEIGHT * num; line > 0; line--) {
938 from = to;
939
940 for (i = 0; i < rowscanline; i++)
941 *(to++) = vc_color_back;
942
943 to = from + rowline;
944 }
945
946 }
947
948
949 static void
950 clear_line(int which)
951 {
952 int start, end, i;
953
954 /*
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
958 * module. --LK
959 */
960
961 switch (which) {
962 case 0: /* To end of line */
963 start = x;
964 end = vinfo.v_columns-1;
965 break;
966 case 1: /* To start of line */
967 start = 0;
968 end = x;
969 break;
970 case 2: /* Whole line */
971 start = 0;
972 end = vinfo.v_columns-1;
973 break;
974 }
975
976 for (i = start; i <= end; i++) {
977 vc_paintchar(' ', i, y, ATTR_NONE);
978 }
979
980 }
981
982 static void
983 clear_screen(int which)
984 {
985 unsigned long *p, *endp, *row;
986 int linelongs, col;
987 int rowline, rowlongs;
988
989 rowline = vinfo.v_rowscanbytes / 4;
990 rowlongs = vinfo.v_rowbytes / 4;
991
992 p = (unsigned long*) vinfo.v_baseaddr;;
993 endp = (unsigned long*) vinfo.v_baseaddr;
994
995 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
996
997 switch (which) {
998 case 0: /* To end of screen */
999 clear_line(0);
1000 if (y < vinfo.v_rows - 1) {
1001 p += (y + 1) * linelongs;
1002 endp += rowlongs * vinfo.v_height;
1003 }
1004 break;
1005 case 1: /* To start of screen */
1006 clear_line(1);
1007 if (y > 1) {
1008 endp += (y + 1) * linelongs;
1009 }
1010 break;
1011 case 2: /* Whole screen */
1012 endp += rowlongs * vinfo.v_height;
1013 break;
1014 }
1015
1016 for (row = p ; row < endp ; row += rowlongs) {
1017 for (col = 0; col < rowline; col++)
1018 *(row+col) = vc_color_back;
1019 }
1020
1021 }
1022
1023 static void
1024 reset_tabs(void)
1025 {
1026 int i;
1027
1028 for (i = 0; i<= vinfo.v_columns; i++) {
1029 tab_stops[i] = ((i % 8) == 0);
1030 }
1031
1032 }
1033
1034 static void
1035 vt100_reset(void)
1036 {
1037 reset_tabs();
1038 scrreg_top = 0;
1039 scrreg_bottom = vinfo.v_rows;
1040 attr = ATTR_NONE;
1041 vc_charset[0] = vc_charset[1] = 0;
1042 vc_charset_select = 0;
1043 vc_wrap_mode = 1;
1044 vc_relative_origin = 0;
1045 vc_color_set(VC_RESET_BACKGROUND);
1046 vc_color_set(VC_RESET_FOREGROUND);
1047
1048 }
1049
1050 static void
1051 putc_normal(unsigned char ch)
1052 {
1053 switch (ch) {
1054 case '\a': /* Beep */
1055 {
1056 spl_t s;
1057
1058 if(FALSE) {
1059 /*
1060 * No sound hardware, invert the screen twice instead
1061 */
1062 unsigned long *ptr;
1063 int i, j;
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*)))
1072 for (j = 0;
1073 j < vinfo.v_rowscanbytes /
1074 sizeof (unsigned long*);
1075 j++)
1076 *(ptr+j) =~*(ptr+j);
1077 }
1078 }
1079 }
1080 break;
1081
1082 case 127: /* Delete */
1083 case '\b': /* Backspace */
1084 if (hanging_cursor) {
1085 hanging_cursor = 0;
1086 } else
1087 if (x > 0) {
1088 x--;
1089 }
1090 break;
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;
1095 break;
1096 case 0x0b:
1097 case 0x0c:
1098 case '\n': /* Line feed */
1099 if (y >= scrreg_bottom -1 ) {
1100 scrollup(1);
1101 y = scrreg_bottom - 1;
1102 } else {
1103 y++;
1104 }
1105 break;
1106 case '\r': /* Carriage return */
1107 x = 0;
1108 hanging_cursor = 0;
1109 break;
1110 case 0x0e: /* Select G1 charset (Control-N) */
1111 vc_charset_select = 1;
1112 break;
1113 case 0x0f: /* Select G0 charset (Control-O) */
1114 vc_charset_select = 0;
1115 break;
1116 case 0x18 : /* CAN : cancel */
1117 case 0x1A : /* like cancel */
1118 /* well, i do nothing here, may be later */
1119 break;
1120 case '\033': /* Escape */
1121 vt100state = ESesc;
1122 hanging_cursor = 0;
1123 break;
1124 default:
1125 if (ch >= ' ') {
1126 if (hanging_cursor) {
1127 x = 0;
1128 if (y >= scrreg_bottom -1 ) {
1129 scrollup(1);
1130 y = scrreg_bottom - 1;
1131 } else {
1132 y++;
1133 }
1134 hanging_cursor = 0;
1135 }
1136 vc_paintchar((ch >= 0x60 && ch <= 0x7f) ? ch + vc_charset[vc_charset_select]
1137 : ch, x, y, attr);
1138 if (x == vinfo.v_columns - 1) {
1139 hanging_cursor = vc_wrap_mode;
1140 } else {
1141 x++;
1142 }
1143 }
1144 break;
1145 }
1146
1147 }
1148
1149 static void
1150 putc_esc(unsigned char ch)
1151 {
1152 vt100state = ESnormal;
1153
1154 switch (ch) {
1155 case '[':
1156 vt100state = ESsquare;
1157 break;
1158 case 'c': /* Reset terminal */
1159 vt100_reset();
1160 clear_screen(2);
1161 x = y = 0;
1162 break;
1163 case 'D': /* Line feed */
1164 case 'E':
1165 if (y >= scrreg_bottom -1) {
1166 scrollup(1);
1167 y = scrreg_bottom - 1;
1168 } else {
1169 y++;
1170 }
1171 if (ch == 'E') x = 0;
1172 break;
1173 case 'H': /* Set tab stop */
1174 tab_stops[x] = 1;
1175 break;
1176 case 'M': /* Cursor up */
1177 if (y <= scrreg_top) {
1178 scrolldown(1);
1179 y = scrreg_top;
1180 } else {
1181 y--;
1182 }
1183 break;
1184 case '>':
1185 vt100_reset();
1186 break;
1187 case '7': /* Save cursor */
1188 savex = x;
1189 savey = y;
1190 saveattr = attr;
1191 vc_save_charset_s = vc_charset_select;
1192 vc_charset_save[0] = vc_charset[0];
1193 vc_charset_save[1] = vc_charset[1];
1194 break;
1195 case '8': /* Restore cursor */
1196 x = savex;
1197 y = savey;
1198 attr = saveattr;
1199 vc_charset_select = vc_save_charset_s;
1200 vc_charset[0] = vc_charset_save[0];
1201 vc_charset[1] = vc_charset_save[1];
1202 break;
1203 case 'Z': /* return terminal ID */
1204 break;
1205 case '#': /* change characters height */
1206 vt100state = EScharsize;
1207 break;
1208 case '(':
1209 vt100state = ESsetG0;
1210 break;
1211 case ')': /* character set sequence */
1212 vt100state = ESsetG1;
1213 break;
1214 case '=':
1215 break;
1216 default:
1217 /* Rest not supported */
1218 break;
1219 }
1220
1221 }
1222
1223 static void
1224 putc_askcmd(unsigned char ch)
1225 {
1226 if (ch >= '0' && ch <= '9') {
1227 par[numpars] = (10*par[numpars]) + (ch-'0');
1228 return;
1229 }
1230 vt100state = ESnormal;
1231
1232 switch (par[0]) {
1233 case 6:
1234 vc_relative_origin = ch == 'h';
1235 break;
1236 case 7: /* wrap around mode h=1, l=0*/
1237 vc_wrap_mode = ch == 'h';
1238 break;
1239 default:
1240 break;
1241 }
1242
1243 }
1244
1245 static void
1246 putc_charsizecmd(unsigned char ch)
1247 {
1248 vt100state = ESnormal;
1249
1250 switch (ch) {
1251 case '3' :
1252 case '4' :
1253 case '5' :
1254 case '6' :
1255 break;
1256 case '8' : /* fill 'E's */
1257 {
1258 int xx, yy;
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);
1262 }
1263 break;
1264 }
1265
1266 }
1267
1268 static void
1269 putc_charsetcmd(int charset, unsigned char ch)
1270 {
1271 vt100state = ESnormal;
1272
1273 switch (ch) {
1274 case 'A' :
1275 case 'B' :
1276 default:
1277 vc_charset[charset] = 0;
1278 break;
1279 case '0' : /* Graphic characters */
1280 case '2' :
1281 vc_charset[charset] = 0x21;
1282 break;
1283 }
1284
1285 }
1286
1287 static void
1288 putc_gotpars(unsigned char ch)
1289 {
1290 int i;
1291
1292 if (ch < ' ') {
1293 /* special case for vttest for handling cursor
1294 movement in escape sequences */
1295 putc_normal(ch);
1296 vt100state = ESgotpars;
1297 return;
1298 }
1299 vt100state = ESnormal;
1300 switch (ch) {
1301 case 'A': /* Up */
1302 y -= par[0] ? par[0] : 1;
1303 if (y < scrreg_top)
1304 y = scrreg_top;
1305 break;
1306 case 'B': /* Down */
1307 y += par[0] ? par[0] : 1;
1308 if (y >= scrreg_bottom)
1309 y = scrreg_bottom - 1;
1310 break;
1311 case 'C': /* Right */
1312 x += par[0] ? par[0] : 1;
1313 if (x >= vinfo.v_columns)
1314 x = vinfo.v_columns-1;
1315 break;
1316 case 'D': /* Left */
1317 x -= par[0] ? par[0] : 1;
1318 if (x < 0)
1319 x = 0;
1320 break;
1321 case 'H': /* Set cursor position */
1322 case 'f':
1323 x = par[1] ? par[1] - 1 : 0;
1324 y = par[0] ? par[0] - 1 : 0;
1325 if (vc_relative_origin)
1326 y += scrreg_top;
1327 hanging_cursor = 0;
1328 break;
1329 case 'X': /* clear p1 characters */
1330 if (numpars) {
1331 int i;
1332 for (i = x; i < x + par[0]; i++)
1333 vc_paintchar(' ', i, y, ATTR_NONE);
1334 }
1335 break;
1336 case 'J': /* Clear part of screen */
1337 clear_screen(par[0]);
1338 break;
1339 case 'K': /* Clear part of line */
1340 clear_line(par[0]);
1341 break;
1342 case 'g': /* tab stops */
1343 switch (par[0]) {
1344 case 1:
1345 case 2: /* reset tab stops */
1346 /* reset_tabs(); */
1347 break;
1348 case 3: /* Clear every tabs */
1349 {
1350 int i;
1351
1352 for (i = 0; i <= vinfo.v_columns; i++)
1353 tab_stops[i] = 0;
1354 }
1355 break;
1356 case 0:
1357 tab_stops[x] = 0;
1358 break;
1359 }
1360 break;
1361 case 'm': /* Set attribute */
1362 for (i = 0; i < numpars; i++) {
1363 switch (par[i]) {
1364 case 0:
1365 attr = ATTR_NONE;
1366 vc_color_set(VC_RESET_BACKGROUND);
1367 vc_color_set(VC_RESET_FOREGROUND);
1368 break;
1369 case 1:
1370 attr |= ATTR_BOLD;
1371 break;
1372 case 4:
1373 attr |= ATTR_UNDER;
1374 break;
1375 case 7:
1376 attr |= ATTR_REVERSE;
1377 break;
1378 case 22:
1379 attr &= ~ATTR_BOLD;
1380 break;
1381 case 24:
1382 attr &= ~ATTR_UNDER;
1383 break;
1384 case 27:
1385 attr &= ~ATTR_REVERSE;
1386 break;
1387 case 5:
1388 case 25: /* blink/no blink */
1389 break;
1390 default:
1391 vc_color_set(par[i]);
1392 break;
1393 }
1394 }
1395 break;
1396 case 'r': /* Set scroll region */
1397 x = y = 0;
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;
1401 if (scrreg_top < 0)
1402 scrreg_top = 0;
1403 } else {
1404 scrreg_top = 0;
1405 }
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;
1410 } else {
1411 scrreg_bottom = vinfo.v_rows;
1412 }
1413 if (vc_relative_origin)
1414 y = scrreg_top;
1415 break;
1416 }
1417
1418 }
1419
1420 static void
1421 putc_getpars(unsigned char ch)
1422 {
1423 if (ch == '?') {
1424 vt100state = ESask;
1425 return;
1426 }
1427 if (ch == '[') {
1428 vt100state = ESnormal;
1429 /* Not supported */
1430 return;
1431 }
1432 if (ch == ';' && numpars < MAXPARS - 1) {
1433 numpars++;
1434 } else
1435 if (ch >= '0' && ch <= '9') {
1436 par[numpars] *= 10;
1437 par[numpars] += ch - '0';
1438 } else {
1439 numpars++;
1440 vt100state = ESgotpars;
1441 putc_gotpars(ch);
1442 }
1443 }
1444
1445 static void
1446 putc_square(unsigned char ch)
1447 {
1448 int i;
1449
1450 for (i = 0; i < MAXPARS; i++) {
1451 par[i] = 0;
1452 }
1453
1454 numpars = 0;
1455 vt100state = ESgetpars;
1456
1457 putc_getpars(ch);
1458
1459 }
1460
1461 static void
1462 vc_putchar(char ch)
1463 {
1464 if (!ch) {
1465 return; /* ignore null characters */
1466 }
1467 switch (vt100state) {
1468 default:vt100state = ESnormal; /* FALLTHROUGH */
1469 case ESnormal:
1470 putc_normal(ch);
1471 break;
1472 case ESesc:
1473 putc_esc(ch);
1474 break;
1475 case ESsquare:
1476 putc_square(ch);
1477 break;
1478 case ESgetpars:
1479 putc_getpars(ch);
1480 break;
1481 case ESgotpars:
1482 putc_gotpars(ch);
1483 break;
1484 case ESask:
1485 putc_askcmd(ch);
1486 break;
1487 case EScharsize:
1488 putc_charsizecmd(ch);
1489 break;
1490 case ESsetG0:
1491 putc_charsetcmd(0, ch);
1492 break;
1493 case ESsetG1:
1494 putc_charsetcmd(1, ch);
1495 break;
1496 }
1497
1498 if (x >= vinfo.v_columns) {
1499 x = vinfo.v_columns - 1;
1500 }
1501 if (x < 0) {
1502 x = 0;
1503 }
1504 if (y >= vinfo.v_rows) {
1505 y = vinfo.v_rows - 1;
1506 }
1507 if (y < 0) {
1508 y = 0;
1509 }
1510
1511 }
1512
1513 /*
1514 * Actually draws the buffer, handle the jump scroll
1515 */
1516 static void vc_flush_forward_buffer(void)
1517 {
1518 int start = 0;
1519 int todo = 0;
1520 spl_t s;
1521
1522 assert(vc_forward_buffer_enabled);
1523
1524 s = splhigh();
1525 simple_lock(&vc_forward_lock);
1526
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);
1530 splx(s);
1531 return;
1532 }
1533
1534 vc_forward_buffer_busy = 1;
1535
1536 while (todo < vc_forward_buffer_size) {
1537 todo = vc_forward_buffer_size;
1538
1539 /* Drop the lock while we update the screen. */
1540 simple_unlock(&vc_forward_lock);
1541 splx(s);
1542
1543 reversecursor();
1544
1545 do {
1546 int i;
1547 #ifdef FAST_JUMP_SCROLL
1548 if ((todo - start) < 2) {
1549 vc_putchar(vc_forward_buffer[start++]);
1550 } else {
1551 assert(vc_forward_scroll == 0);
1552
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) );
1580
1581 vc_forward_preflight_mode = PFwind;
1582
1583 for (i = start;
1584 i < todo &&
1585 vc_forward_preflight_save.scrreg_top == scrreg_top &&
1586 vc_forward_preflight_save.scrreg_bottom == scrreg_bottom;
1587 i++)
1588 vc_putchar(vc_forward_buffer[i]);
1589
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,
1612 (char *) par,
1613 (vm_size_t) sizeof(par) );
1614 bcopy( (const char *) vc_forward_preflight_save.tab_stops,
1615 (char *) tab_stops,
1616 (vm_size_t) sizeof(tab_stops) );
1617
1618 vc_forward_preflight_mode = PFscroll;
1619
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);
1626
1627 vc_forward_preflight_mode = PFunwind;
1628
1629 for (; start < i; start++)
1630 vc_putchar(vc_forward_buffer[start]);
1631
1632 assert(vc_forward_scroll == 0);
1633
1634 vc_forward_preflight_mode = PFoff;
1635 }
1636 #else !FAST_JUMP_SCROLL
1637 int plaintext = 1;
1638 int drawlen = start;
1639 int jump = 0;
1640 int param = 0, changebackground = 0;
1641 enum vt100state_e vtState = vt100state;
1642 /*
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
1648 * the screen.
1649 * We have to be extra carefull about the sequences that changes
1650 * the background color to prevent scrolling in those
1651 * particular cases.
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)
1655 * Michel Pollet
1656 */
1657 for (i = start; i < todo && plaintext; i++) {
1658 drawlen++;
1659 switch (vtState) {
1660 case ESnormal:
1661 switch (vc_forward_buffer[i]) {
1662 case '\033':
1663 vtState = ESesc;
1664 break;
1665 case '\n':
1666 jump++;
1667 break;
1668 }
1669 break;
1670 case ESesc:
1671 switch (vc_forward_buffer[i]) {
1672 case '[':
1673 vtState = ESgetpars;
1674 param = 0;
1675 changebackground = 0;
1676 break;
1677 default:
1678 plaintext = 0;
1679 break;
1680 }
1681 break;
1682 case ESgetpars:
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');
1689 else {
1690 if (param >= 40 && param <= 47)
1691 changebackground = 1;
1692 if (!vc_normal_background &&
1693 !param)
1694 changebackground = 1;
1695 param = 0;
1696 }
1697 break; /* continue on */
1698 }
1699 vtState = ESgotpars;
1700 /* fall */
1701 case ESgotpars:
1702 switch (vc_forward_buffer[i]) {
1703 case 'm':
1704 vtState = ESnormal;
1705 if (param >= 40 && param <= 47)
1706 changebackground = 1;
1707 if (!vc_normal_background &&
1708 !param)
1709 changebackground = 1;
1710 if (changebackground) {
1711 plaintext = 0;
1712 jump = 0;
1713 /* REALLY don't jump */
1714 }
1715 /* Yup ! we've got it */
1716 break;
1717 default:
1718 plaintext = 0;
1719 break;
1720 }
1721 break;
1722 default:
1723 plaintext = 0;
1724 break;
1725 }
1726
1727 }
1728
1729 /*
1730 * Then we look if it would be appropriate to forward jump
1731 * the screen before drawing
1732 */
1733 if (jump && (scrreg_bottom - scrreg_top) > 2) {
1734 jump -= scrreg_bottom - y - 1;
1735 if (jump > 0 ) {
1736 if (jump >= scrreg_bottom - scrreg_top)
1737 jump = scrreg_bottom - scrreg_top -1;
1738 y -= jump;
1739 scrollup(jump);
1740 }
1741 }
1742 /*
1743 * and we draw what we've found to the parser
1744 */
1745 for (i = start; i < drawlen; i++)
1746 vc_putchar(vc_forward_buffer[start++]);
1747 /*
1748 * Continue sending characters to the parser until we're sure we're
1749 * back on normal characters.
1750 */
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);
1757
1758 reversecursor();
1759
1760 /* Re-acquire the lock while we check our state. */
1761 s = splhigh();
1762 simple_lock(&vc_forward_lock);
1763 }
1764
1765 vc_forward_buffer_busy = 0;
1766 vc_forward_buffer_size = 0;
1767
1768 simple_unlock(&vc_forward_lock);
1769 splx(s);
1770 }
1771
1772 int
1773 vcputc(int l, int u, int c)
1774 {
1775 if(!vinfo.v_baseaddr)
1776 return;
1777
1778 /*
1779 * Either we're really buffering stuff or we're not yet because
1780 * the probe hasn't been done.
1781 */
1782 if (vc_forward_buffer_enabled)
1783 vc_store_char(c);
1784 else
1785 vc_putchar(c);
1786
1787 return 0;
1788 }
1789
1790 /*
1791 * Store characters to be drawn 'later', handle overflows
1792 */
1793
1794 static void
1795 vc_store_char(unsigned char c)
1796 {
1797 int flush = 0;
1798 spl_t s;
1799
1800 assert(vc_forward_buffer_enabled);
1801
1802 s = splhigh();
1803 simple_lock(&vc_forward_lock);
1804
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);
1808 splx(s);
1809 /* wait */
1810 s = splhigh();
1811 simple_lock(&vc_forward_lock);
1812 }
1813
1814 assert(vc_forward_buffer_size < VC_MAX_FORWARD_SIZE);
1815
1816 vc_forward_buffer[vc_forward_buffer_size++] = (unsigned char)c;
1817
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.
1821 */
1822 if (debug_mode) {
1823 flush = 1;
1824 } else {
1825 timeout((timeout_fcn_t)vc_flush_forward_buffer,
1826 (void *)0,
1827 VC_CONSOLE_UPDATE_TIMEOUT);
1828 }
1829 } else if (vc_forward_buffer_size == VC_MAX_FORWARD_SIZE || debug_mode) {
1830 /*
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).
1834 */
1835 if (!vc_forward_buffer_busy) {
1836 flush = 1;
1837 untimeout((timeout_fcn_t)vc_flush_forward_buffer, (void *)0);
1838 }
1839 }
1840
1841 simple_unlock(&vc_forward_lock);
1842 splx(s);
1843
1844 if (flush) {
1845 /*
1846 * Immediate character display.. kernel printf uses this. Make sure
1847 * get flushed and that panics get fully displayed.
1848 */
1849 vc_flush_forward_buffer();
1850 }
1851 }
1852
1853 static void
1854 vc_initialize(void)
1855 {
1856 #if 0
1857 GratefulDebInit(); /* (TEST/DEBUG) */
1858 #endif
1859
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);
1866 #endif
1867
1868 vinfo.v_rows = vinfo.v_height / CHARHEIGHT;
1869 vinfo.v_columns = vinfo.v_width / CHARWIDTH;
1870
1871 if (vinfo.v_depth >= 8) {
1872 vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
1873 } else {
1874 vinfo.v_rowscanbytes = vinfo.v_width / (8 / vinfo.v_depth);
1875 }
1876
1877 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1878 printf(" inited=%d\n", vc_initted);
1879 #endif
1880
1881
1882 vc_render_font(1, vinfo.v_depth);
1883 vc_color_mask = vc_color_depth_masks[vc_color_index_table[vinfo.v_depth]];
1884 vt100_reset();
1885 switch (vinfo.v_depth) {
1886 default:
1887 case 1:
1888 vc_paintchar = vc_paint_char1;
1889 break;
1890 case 2:
1891 vc_paintchar = vc_paint_char2;
1892 break;
1893 case 4:
1894 vc_paintchar = vc_paint_char4;
1895 break;
1896 case 8:
1897 vc_paintchar = vc_paint_char8c;
1898 break;
1899 case 16:
1900 vc_paintchar = vc_paint_char16c;
1901 break;
1902 case 32:
1903 vc_paintchar = vc_paint_char32c;
1904 break;
1905 }
1906
1907 #ifdef FAST_JUMP_SCROLL
1908 vc_forward_paintchar = vc_paintchar;
1909 vc_paintchar = vc_paint_char;
1910 #endif FAST_JUMP_SCROLL
1911 }
1912
1913 void
1914 vcattach(void)
1915 {
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);
1920
1921 /*
1922 * Added for the buffering and jump scrolling
1923 */
1924 /* Init our lock */
1925 simple_lock_init(&vc_forward_lock, ETAP_IO_TTY);
1926
1927 vc_forward_buffer_enabled = 1;
1928
1929 }
1930
1931
1932 struct vc_progress_element {
1933 unsigned int version;
1934 unsigned int flags;
1935 unsigned int time;
1936 unsigned char count;
1937 unsigned char res[3];
1938 int width;
1939 int height;
1940 int dx;
1941 int dy;
1942 int transparent;
1943 unsigned int res2[3];
1944 unsigned char data[0];
1945 };
1946 typedef struct vc_progress_element vc_progress_element;
1947
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;
1962
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 )
1969 {
1970 volatile unsigned char * dst;
1971 int line, col;
1972 unsigned int data;
1973 unsigned char alpha;
1974
1975 dst = (unsigned char *)(vinfo.v_baseaddr +
1976 (y * vinfo.v_rowbytes) +
1977 (x));
1978
1979 for( line = 0; line < height; line++) {
1980 for( col = 0; col < width; col++) {
1981 data = 0;
1982 if( dataPtr != 0) data = *dataPtr++;
1983 else if( alphaPtr != 0) data = vc_revclut8[*alphaPtr++];
1984 *(dst + col) = data;
1985 }
1986 dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1987 }
1988
1989 }
1990
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 )
1997 {
1998 volatile unsigned short * dst;
1999 int line, col;
2000 unsigned int data, index, alpha, back;
2001
2002 dst = (volatile unsigned short *)(vinfo.v_baseaddr +
2003 (y * vinfo.v_rowbytes) +
2004 (x * 2));
2005
2006 for( line = 0; line < height; line++) {
2007 for( col = 0; col < width; col++) {
2008 if( dataPtr != 0) {
2009 index = *dataPtr++;
2010 index *= 3;
2011 }
2012
2013 if( alphaPtr && backPtr) {
2014
2015 alpha = *alphaPtr++;
2016 data = 0;
2017 if( dataPtr != 0) {
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);
2024 }
2025
2026 if( save) {
2027 back = *(dst + col);
2028 if ( !static_alpha)
2029 *backPtr++ = back;
2030 back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
2031 | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
2032 | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
2033 if ( static_alpha)
2034 *backPtr++ = back;
2035 } else {
2036 back = *backPtr++;
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);
2041 }
2042 }
2043
2044 data += back;
2045
2046 } else
2047 if( dataPtr != 0) {
2048 data = ( (0xf8 & (vc_clut[index + 0])) << 7)
2049 | ( (0xf8 & (vc_clut[index + 1])) << 2)
2050 | ( (0xf8 & (vc_clut[index + 2])) >> 3);
2051 }
2052
2053 *(dst + col) = data;
2054 }
2055 dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
2056 }
2057 }
2058
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 )
2065 {
2066 volatile unsigned int * dst;
2067 int line, col;
2068 unsigned int data, index, alpha, back;
2069
2070 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2071 (y * vinfo.v_rowbytes) +
2072 (x * 4));
2073
2074 for( line = 0; line < height; line++) {
2075 for( col = 0; col < width; col++) {
2076 if( dataPtr != 0) {
2077 index = *dataPtr++;
2078 index *= 3;
2079 }
2080
2081 if( alphaPtr && backPtr) {
2082
2083 alpha = *alphaPtr++;
2084 data = 0;
2085 if( dataPtr != 0) {
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));
2092 }
2093
2094 if( save) {
2095 back = *(dst + col);
2096 if ( !static_alpha)
2097 *backPtr++ = back;
2098 back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2099 | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
2100 if ( static_alpha)
2101 *backPtr++ = back;
2102 } else {
2103 back = *backPtr++;
2104 if ( !static_alpha) {
2105 back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2106 | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
2107 }
2108 }
2109
2110 data += back;
2111
2112 } else
2113 if( dataPtr != 0) {
2114 data = (vc_clut[index + 0] << 16)
2115 | (vc_clut[index + 1] << 8)
2116 | (vc_clut[index + 2]);
2117 }
2118
2119 *(dst + col) = data;
2120 }
2121 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2122 }
2123 }
2124
2125 void
2126 draw_panic_dialog( void )
2127 {
2128 int pd_x,pd_y, iconx, icony, tx_line, tx_col;
2129 int line_width = 1;
2130 int f1, f2, d1, d2, d3, rem;
2131 char *pair = "ff";
2132 int count = 0;
2133 char digit;
2134 int nibble;
2135 char colon = ':';
2136 char dot = '.';
2137 struct ether_addr kdp_mac_addr = kdp_get_mac_addr();
2138 unsigned int ip_addr = kdp_get_ip_address();
2139
2140
2141 if (!panicDialogDrawn)
2142 {
2143 if ( !logPanicDataToScreen )
2144 {
2145
2146 /* dim the screen 50% before putting up panic dialog */
2147 dim_screen();
2148
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;
2152
2153 /* draw image */
2154 panic_blit_rect( pd_x, pd_y, panic_dialog.pd_width, panic_dialog.pd_height, 0, (unsigned char*) panic_dialog.image_pixel_data);
2155
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;
2159
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])
2162 {
2163 /* blit the digits for mac address */
2164 for (count = 0; count < 6; count++ )
2165 {
2166 nibble = (kdp_mac_addr.ether_addr_octet[count] & 0xf0) >> 4;
2167 digit = nibble < 10 ? nibble + '0':nibble - 10 + 'a';
2168 blit_digit(digit);
2169
2170 nibble = kdp_mac_addr.ether_addr_octet[count] & 0xf;
2171 digit = nibble < 10 ? nibble + '0':nibble - 10 + 'a';
2172 blit_digit(digit);
2173 if( count < 5 )
2174 blit_digit( colon );
2175 }
2176 }
2177 else /* blit the ff's */
2178 {
2179 for( count = 0; count < 6; count++ )
2180 {
2181 digit = pair[0];
2182 blit_digit(digit);
2183 digit = pair[1];
2184 blit_digit(digit);
2185 if( count < 5 )
2186 blit_digit( colon );
2187 }
2188 }
2189 /* now print the ip address */
2190 mac_addr_digit_x = (vinfo.v_width/2) + 10;
2191 if(ip_addr != 0)
2192 {
2193 /* blit the digits for ip address */
2194 for (count = 0; count < 4; count++ )
2195 {
2196 nibble = (ip_addr & 0xff000000 ) >> 24;
2197
2198 d3 = (nibble % 0xa) + '0';
2199 nibble = nibble/0xa;
2200 d2 = (nibble % 0xa) + '0';
2201 nibble = nibble /0xa;
2202 d1 = (nibble % 0xa) + '0';
2203
2204 if( d1 ) blit_digit(d1);
2205 blit_digit(d2);
2206 blit_digit(d3);
2207 if( count < 3 )
2208 blit_digit(dot);
2209
2210 d1= d2 = d3 = 0;
2211 ip_addr = ip_addr << 8;
2212 }
2213 }
2214 }
2215 }
2216 panicDialogDrawn = TRUE;
2217
2218 }
2219
2220
2221 static void
2222 blit_digit( int digit )
2223 {
2224 switch( digit )
2225 {
2226 case '0': {
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;
2229 break;
2230 }
2231 case '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 ;
2234 break;
2235 }
2236 case '2': {
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 ;
2239 break;
2240 }
2241 case '3': {
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 ;
2244 break;
2245 }
2246 case '4': {
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 ;
2249 break;
2250 }
2251 case '5': {
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 ;
2254 break;
2255 }
2256 case '6': {
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 ;
2259 break;
2260 }
2261 case '7': {
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 ;
2264 break;
2265 }
2266 case '8': {
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 ;
2269 break;
2270 }
2271 case '9': {
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 ;
2274 break;
2275 }
2276 case 'a': {
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 ;
2279 break;
2280 }
2281 case 'b': {
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 ;
2284 break;
2285 }
2286 case 'c': {
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 ;
2289 break;
2290 }
2291 case 'd': {
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 ;
2294 break;
2295 }
2296 case 'e': {
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 ;
2299 break;
2300 }
2301 case 'f': {
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 ;
2304 break;
2305 }
2306 case ':': {
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;
2309 break;
2310 }
2311 case '.': {
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;
2314 break;
2315 }
2316 default:
2317 break;
2318
2319 }
2320 }
2321
2322 static void
2323 panic_blit_rect( unsigned int x, unsigned int y,
2324 unsigned int width, unsigned int height,
2325 int transparent, unsigned char * dataPtr )
2326 {
2327 if(!vinfo.v_depth)
2328 return;
2329
2330 switch( vinfo.v_depth) {
2331 case 8:
2332 panic_blit_rect_8( x, y, width, height, transparent, dataPtr);
2333 break;
2334 case 16:
2335 panic_blit_rect_16( x, y, width, height, transparent, dataPtr);
2336 break;
2337 case 32:
2338 panic_blit_rect_32( x, y, width, height, transparent, dataPtr);
2339 break;
2340 }
2341 }
2342
2343 /* panic_blit_rect_8 is not tested and probably doesn't draw correctly.
2344 it really needs a clut to use
2345 */
2346 static void
2347 panic_blit_rect_8( unsigned int x, unsigned int y,
2348 unsigned int width, unsigned int height,
2349 int transparent, unsigned char * dataPtr )
2350 {
2351 volatile unsigned int * dst;
2352 int line, col;
2353 unsigned int pixelR, pixelG, pixelB;
2354
2355 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2356 (y * vinfo.v_rowbytes) +
2357 x);
2358
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))
2365 {
2366 *(dst + col) = ((19595 * pixelR +
2367 38470 * pixelG +
2368 7471 * pixelB ) / 65536);
2369 }
2370
2371 }
2372 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2373 }
2374 }
2375
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.
2378
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.
2382
2383 */
2384 static void
2385 panic_blit_rect_16( unsigned int x, unsigned int y,
2386 unsigned int width, unsigned int height,
2387 int transparent, unsigned char * dataPtr )
2388 {
2389 volatile unsigned int * dst;
2390 int line, value, total = 0;
2391 unsigned int quantity, tmp, pixel;
2392 int pix_pos = 2;
2393 int w = width / 2;
2394 boolean_t secondTime = 0;
2395 int pix_incr = 0;
2396
2397
2398 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2399 (y * vinfo.v_rowbytes) +
2400 (x * 2));
2401
2402 /*
2403 *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
2404 | ( (0xf8 & (vc_clut[data + 1])) << 2)
2405 | ( (0xf8 & (vc_clut[data + 2])) >> 3);
2406
2407 */
2408 for( line = 0; line < height; line++)
2409 {
2410 while ( total < width )
2411 {
2412 quantity = *dataPtr++;
2413 value = *dataPtr++;
2414 value = (0x1f * value)/255;
2415 while( quantity > 0 )
2416 {
2417 switch( pix_pos )
2418 {
2419 case 2: /* red */
2420 {
2421 tmp |= (value << 10) & 0x7c00;
2422 // tmp |= (value & 0xf8) << 7;
2423 quantity--;
2424 pix_pos--;
2425 break;
2426 }
2427 case 1: /* green */
2428 {
2429 tmp |= (value << 5) & 0x3e0;
2430 // tmp |= (value & 0xf8) << 2;
2431 quantity--;
2432 pix_pos--;
2433 break;
2434 }
2435 default: /* blue */
2436 {
2437 tmp |= value & 0x1f;
2438 // tmp |= (value & 0xf8) >> 3;
2439 total++;
2440 quantity--;
2441 pix_pos = 2;
2442 if( secondTime )
2443 {
2444 pixel |= tmp;
2445 secondTime = 0;
2446 *(dst + pix_incr++) = pixel;
2447 tmp = 0;
2448 pixel = 0;
2449 }
2450 else
2451 {
2452 pixel = tmp << 16;
2453 secondTime = 1;
2454 }
2455 break;
2456 }
2457 }
2458 }
2459 }
2460 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2461 total = 0;
2462 pix_incr = 0;
2463 }
2464 }
2465
2466 /*
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
2469 screen.
2470 */
2471 static void
2472 panic_blit_rect_32( unsigned int x, unsigned int y,
2473 unsigned int width, unsigned int height,
2474 int transparent, unsigned char * dataPtr )
2475 {
2476 volatile unsigned int * dst;
2477 int line, total = 0;
2478 unsigned int value, quantity, tmp;
2479 int pix_pos = 2;
2480
2481 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2482 (y * vinfo.v_rowbytes) +
2483 (x * 4));
2484
2485 for( line = 0; line < height; line++)
2486 {
2487 while ( total < width )
2488 {
2489 quantity = *dataPtr++;
2490 value = *dataPtr++;
2491 while( quantity > 0 )
2492 {
2493 switch( pix_pos )
2494 {
2495 case 2:
2496 {
2497 tmp = value << 16;
2498 quantity--;
2499 pix_pos--;
2500 break;
2501 }
2502 case 1:
2503 {
2504 tmp |= value << 8;
2505 quantity--;
2506 pix_pos--;
2507 break;
2508 }
2509 default:
2510 {
2511 tmp |= value;
2512 *(dst + total) = tmp;
2513 total++;
2514 quantity--;
2515 pix_pos = 2;
2516 break;
2517 }
2518
2519 }
2520 }
2521
2522 }
2523 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2524 total = 0;
2525 }
2526 }
2527
2528 static void
2529 dim_screen(void)
2530 {
2531 if(!vinfo.v_depth)
2532 return;
2533
2534 switch( vinfo.v_depth) {
2535 /*case 8:
2536 dim_screen8();
2537 break;
2538 */
2539 case 16:
2540 dim_screen16();
2541 break;
2542 case 32:
2543 dim_screen32();
2544 break;
2545 }
2546 }
2547
2548 static void
2549 dim_screen16(void)
2550 {
2551 unsigned long *p, *endp, *row;
2552 int linelongs, col;
2553 int rowline, rowlongs;
2554 unsigned long value, tmp;
2555
2556 rowline = vinfo.v_rowscanbytes / 4;
2557 rowlongs = vinfo.v_rowbytes / 4;
2558
2559 p = (unsigned long*) vinfo.v_baseaddr;;
2560 endp = (unsigned long*) vinfo.v_baseaddr;
2561
2562 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
2563 endp += rowlongs * vinfo.v_height;
2564
2565 for (row = p ; row < endp ; row += rowlongs) {
2566 for (col = 0; col < rowline; col++) {
2567 value = *(row+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)?
2572 }
2573
2574 }
2575
2576 }
2577
2578 static void
2579 dim_screen32(void)
2580 {
2581 unsigned long *p, *endp, *row;
2582 int linelongs, col;
2583 int rowline, rowlongs;
2584 unsigned long value, tmp;
2585
2586 rowline = vinfo.v_rowscanbytes / 4;
2587 rowlongs = vinfo.v_rowbytes / 4;
2588
2589 p = (unsigned long*) vinfo.v_baseaddr;;
2590 endp = (unsigned long*) vinfo.v_baseaddr;
2591
2592 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
2593 endp += rowlongs * vinfo.v_height;
2594
2595 for (row = p ; row < endp ; row += rowlongs) {
2596 for (col = 0; col < rowline; col++) {
2597 value = *(row+col);
2598 tmp = ((value & 0x00FF0000) >> 1) & 0x007F0000;
2599 tmp |= ((value & 0x0000FF00) >> 1) & 0x00007F00;
2600 tmp |= (value & 0x000000FF) >> 1;
2601 *(row+col) = tmp; //half (dimmed)?
2602 }
2603
2604 }
2605
2606 }
2607
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 )
2614 {
2615 if(!vinfo.v_baseaddr)
2616 return;
2617
2618 switch( vinfo.v_depth) {
2619 case 8:
2620 if( vc_clut8 == vc_clut)
2621 vc_blit_rect_8c( x, y, width, height, dataPtr, alphaPtr, (unsigned char *) backBuffer, save, static_alpha );
2622 break;
2623 case 16:
2624 vc_blit_rect_16( x, y, width, height, dataPtr, alphaPtr, (unsigned short *) backBuffer, save, static_alpha );
2625 break;
2626 case 32:
2627 vc_blit_rect_32( x, y, width, height, dataPtr, alphaPtr, (unsigned int *) backBuffer, save, static_alpha );
2628 break;
2629 }
2630 }
2631
2632 static void vc_progress_task( void * arg )
2633 {
2634 spl_t s;
2635 int count = (int) arg;
2636 int x, y, width, height;
2637 const unsigned char * data;
2638
2639 s = splhigh();
2640 simple_lock(&vc_forward_lock);
2641
2642 if( vc_progress_enable) {
2643
2644 count++;
2645 if( count >= vc_progress->count)
2646 count = 0;
2647
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);
2657 }
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;
2662
2663 timeout( vc_progress_task, (void *) count,
2664 vc_progress_tick );
2665 }
2666 simple_unlock(&vc_forward_lock);
2667 splx(s);
2668 }
2669
2670 void vc_display_icon( vc_progress_element * desc,
2671 const unsigned char * data )
2672 {
2673 int x, y, width, height;
2674
2675 if( vc_acquired && vc_graphics_mode && vc_clut) {
2676
2677 width = desc->width;
2678 height = desc->height;
2679 x = desc->dx;
2680 y = desc->dy;
2681 if( 1 & desc->flags) {
2682 x += ((vinfo.v_width - width) / 2);
2683 y += ((vinfo.v_height - height) / 2);
2684 }
2685 vc_blit_rect( x, y, width, height, data, NULL, (vm_address_t) NULL, FALSE, TRUE );
2686 }
2687 }
2688
2689 static boolean_t ignore_first_enable = TRUE;
2690
2691 static boolean_t
2692 vc_progress_set( boolean_t enable, unsigned int initial_tick )
2693 {
2694 spl_t s;
2695 vm_address_t saveBuf = 0;
2696 vm_size_t saveLen = 0;
2697 unsigned int count;
2698 unsigned int index;
2699 unsigned char data8;
2700 unsigned short data16;
2701 unsigned short * buf16;
2702 unsigned int data32;
2703 unsigned int * buf32;
2704
2705 if( !vc_progress)
2706 return( FALSE );
2707
2708 if( enable & ignore_first_enable) {
2709 enable = FALSE;
2710 ignore_first_enable = FALSE;
2711 }
2712
2713 if( enable) {
2714 saveLen = vc_progress->width * vc_progress->height * vinfo.v_depth / 8;
2715 saveBuf = kalloc( saveLen );
2716
2717 if( !vc_need_clear) switch( vinfo.v_depth) {
2718 case 8 :
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;
2727 break;
2728 }
2729 }
2730 }
2731 memset( (void *) saveBuf, 0x01, saveLen );
2732 break;
2733
2734 case 16 :
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;
2741 break;
2742
2743 case 32 :
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;
2750 break;
2751 }
2752 }
2753
2754 s = splhigh();
2755 simple_lock(&vc_forward_lock);
2756
2757 if( vc_progress_enable != enable) {
2758 vc_progress_enable = enable;
2759 if( enable) {
2760 vc_needsave = vc_need_clear;
2761 vc_saveunder = saveBuf;
2762 vc_saveunder_len = saveLen;
2763 saveBuf = 0;
2764 saveLen = 0;
2765 timeout(vc_progress_task, (void *) 0,
2766 initial_tick );
2767 } else {
2768 if( vc_saveunder) {
2769 saveBuf = vc_saveunder;
2770 saveLen = vc_saveunder_len;
2771 vc_saveunder = 0;
2772 vc_saveunder_len = 0;
2773 }
2774 untimeout( vc_progress_task, (void *) 0 );
2775 }
2776 }
2777
2778 if( !enable) {
2779 vc_forward_buffer_size = 0;
2780 untimeout((timeout_fcn_t)vc_flush_forward_buffer, (void *)0);
2781
2782 /* Spin if the flush is in progress */
2783 while (vc_forward_buffer_busy) {
2784 simple_unlock(&vc_forward_lock);
2785 splx(s);
2786 /* wait */
2787 s = splhigh();
2788 simple_lock(&vc_forward_lock);
2789 vc_forward_buffer_size = 0;
2790 }
2791 }
2792
2793 simple_unlock(&vc_forward_lock);
2794 splx(s);
2795
2796 if( saveBuf)
2797 kfree( saveBuf, saveLen );
2798
2799 return( TRUE );
2800 }
2801
2802
2803 boolean_t
2804 vc_progress_initialize( vc_progress_element * desc,
2805 const unsigned char * data,
2806 const unsigned char * clut )
2807 {
2808 if( (!clut) || (!desc) || (!data))
2809 return( FALSE );
2810 vc_clut = clut;
2811 vc_clut8 = clut;
2812
2813 vc_progress = desc;
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;
2818 else
2819 vc_progress_alpha = NULL;
2820 vc_progress_tick = vc_progress->time * hz / 1000;
2821
2822 return( TRUE );
2823 }
2824
2825 // FirmwareC.c needs:
2826 Boot_Video boot_video_info;
2827
2828 extern int disableConsoleOutput;
2829
2830 static void vc_clear_screen( void )
2831 {
2832 reversecursor();
2833 vt100_reset();
2834 x = y = 0;
2835 clear_screen(2);
2836 reversecursor();
2837 };
2838
2839 void
2840 initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
2841 {
2842 if( boot_vinfo) {
2843 bcopy( (const void *) boot_vinfo,
2844 (void *) &boot_video_info,
2845 sizeof( boot_video_info));
2846
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;
2854 vinfo.v_type = 0;
2855
2856 vc_initialize();
2857 #if 0
2858 GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re-initialize GratefulDeb */
2859 #endif
2860 }
2861
2862 switch( op ) {
2863
2864 case kPEGraphicsMode:
2865 vc_graphics_mode = TRUE;
2866 disableConsoleOutput = TRUE;
2867 vc_acquired = TRUE;
2868 break;
2869
2870 case kPETextMode:
2871 vc_graphics_mode = FALSE;
2872 disableConsoleOutput = FALSE;
2873 vc_acquired = TRUE;
2874 vc_clear_screen();
2875 break;
2876
2877 case kPETextScreen:
2878 vc_progress_set( FALSE, 0 );
2879 disableConsoleOutput = FALSE;
2880 if( vc_need_clear) {
2881 vc_need_clear = FALSE;
2882 vc_clear_screen();
2883 }
2884 break;
2885
2886 case kPEEnableScreen:
2887 if( vc_acquired) {
2888 if( vc_graphics_mode)
2889 vc_progress_set( TRUE, vc_progress_tick );
2890 else
2891 vc_clear_screen();
2892 }
2893 break;
2894
2895 case kPEDisableScreen:
2896 vc_progress_set( FALSE, 0 );
2897 break;
2898
2899 case kPEAcquireScreen:
2900 vc_need_clear = (FALSE == vc_acquired);
2901 vc_acquired = TRUE;
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;
2906 vc_clear_screen();
2907 }
2908 break;
2909
2910 case kPEReleaseScreen:
2911 vc_acquired = FALSE;
2912 vc_progress_set( FALSE, 0 );
2913 vc_clut8 = NULL;
2914 disableConsoleOutput = TRUE;
2915 #if 0
2916 GratefulDebInit(0); /* Stop grateful debugger */
2917 #endif
2918 break;
2919 }
2920 #if 0
2921 if( boot_vinfo) GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re initialize GratefulDeb */
2922 #endif
2923 }