]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/POWERMAC/video_console.c
61a510e9789083d25b8249aca7ef46c64243a41c
[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 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * @OSF_FREE_COPYRIGHT@
24 *
25 */
26 /*
27 * @APPLE_FREE_COPYRIGHT@
28 */
29 /* MACH PPC - video_console.c
30 *
31 * Original based on NetBSD's mac68k/dev/ite.c driver
32 *
33 * This driver differs in
34 * - MACH driver"ized"
35 * - Uses phys_copy and flush_cache to in several places
36 * for performance optimizations
37 * - 7x15 font
38 * - Black background and white (character) foreground
39 * - Assumes 6100/7100/8100 class of machine
40 *
41 * The original header follows...
42 *
43 *
44 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
45 *
46 * Copyright (c) 1988 University of Utah.
47 * Copyright (c) 1990, 1993
48 * The Regents of the University of California. All rights reserved.
49 *
50 * This code is derived from software contributed to Berkeley by
51 * the Systems Programming Group of the University of Utah Computer
52 * Science Department.
53 *
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
56 * are met:
57 * 1. Redistributions of source code must retain the above copyright
58 * notice, this list of conditions and the following disclaimer.
59 * 2. Redistributions in binary form must reproduce the above copyright
60 * notice, this list of conditions and the following disclaimer in the
61 * documentation and/or other materials provided with the distribution.
62 * 3. All advertising materials mentioning features or use of this software
63 * must display the following acknowledgement:
64 * This product includes software developed by the University of
65 * California, Berkeley and its contributors.
66 * 4. Neither the name of the University nor the names of its contributors
67 * may be used to endorse or promote products derived from this software
68 * without specific prior written permission.
69 *
70 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80 * SUCH DAMAGE.
81 *
82 * from: Utah $Hdr: ite.c 1.28 92/12/20$
83 *
84 * @(#)ite.c 8.2 (Berkeley) 1/12/94
85 */
86
87 /*
88 * ite.c
89 *
90 * The ite module handles the system console; that is, stuff printed
91 * by the kernel and by user programs while "desktop" and X aren't
92 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
93 * hence the above copyright.
94 *
95 * -- Brad and Lawrence, June 26th, 1994
96 *
97 */
98
99 #include <vc.h>
100
101 #include <mach_kdb.h>
102 #include <kern/spl.h>
103 #include <machine/machparam.h> /* spl definitions */
104 #include <types.h>
105 #include <ppc/iso_font.h>
106 #include <ppc/Firmware.h>
107
108 #include <ppc/POWERMAC/video_console_entries.h>
109 #include <ppc/POWERMAC/video_console.h>
110 #include <pexpert/pexpert.h>
111 #include <kern/time_out.h>
112 #include <kern/lock.h>
113 #include <kern/debug.h>
114
115 #include <kdp/kdp_udp.h>
116
117 #include "panic_image.c"
118 #include "rendered_numbers.c"
119
120
121 #define FAST_JUMP_SCROLL
122
123 #define CHARWIDTH 8
124 #define CHARHEIGHT 16
125
126 #define ATTR_NONE 0
127 #define ATTR_BOLD 1
128 #define ATTR_UNDER 2
129 #define ATTR_REVERSE 4
130
131 enum vt100state_e {
132 ESnormal, /* Nothing yet */
133 ESesc, /* Got ESC */
134 ESsquare, /* Got ESC [ */
135 ESgetpars, /* About to get or getting the parameters */
136 ESgotpars, /* Finished getting the parameters */
137 ESfunckey, /* Function key */
138 EShash, /* DEC-specific stuff (screen align, etc.) */
139 ESsetG0, /* Specify the G0 character set */
140 ESsetG1, /* Specify the G1 character set */
141 ESask,
142 EScharsize,
143 ESignore /* Ignore this sequence */
144 } vt100state = ESnormal;
145
146 struct vc_info vinfo;
147
148 /* Calculated in vccninit(): */
149 static int vc_wrap_mode = 1, vc_relative_origin = 0;
150 static int vc_charset_select = 0, vc_save_charset_s = 0;
151 static int vc_charset[2] = { 0, 0 };
152 static int vc_charset_save[2] = { 0, 0 };
153
154 /* VT100 state: */
155 #define MAXPARS 16
156 static int x = 0, y = 0, savex, savey;
157 static int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
158
159 /* VT100 tab stops & scroll region */
160 static char tab_stops[255];
161 static int scrreg_top, scrreg_bottom;
162
163 /* Misc */
164 static void vc_initialize(void);
165 static void vc_flush_forward_buffer(void);
166 static void vc_store_char(unsigned char);
167 static void vc_putchar(char ch);
168
169 void vcattach(void);
170
171 /* panic dialog and info saving */
172 int mac_addr_digit_x;
173 int mac_addr_digit_y;
174 static void blit_digit( int digit );
175 boolean_t panicDialogDrawn = FALSE;
176
177 static void
178 panic_blit_rect( unsigned int x, unsigned int y,
179 unsigned int width, unsigned int height,
180 int transparent, unsigned char * dataPtr );
181
182 static void
183 panic_blit_rect_8( unsigned int x, unsigned int y,
184 unsigned int width, unsigned int height,
185 int transparent, unsigned char * dataPtr );
186
187 static void
188 panic_blit_rect_16( unsigned int x, unsigned int y,
189 unsigned int width, unsigned int height,
190 int transparent, unsigned char * dataPtr );
191
192 static void
193 panic_blit_rect_32( unsigned int x, unsigned int y,
194 unsigned int width, unsigned int height,
195 int transparent, unsigned char * dataPtr );
196
197 static void
198 blit_rect_of_size_and_color( unsigned int x, unsigned int y,
199 unsigned int width, unsigned int height,
200 unsigned int dataPtr );
201
202 static void
203 dim_screen(void);
204
205 /*static void
206 dim_screen8(void);
207 */
208
209 static void
210 dim_screen16(void);
211
212 static void
213 dim_screen32(void);
214
215
216 /*
217 * For the color support (Michel Pollet)
218 */
219 static unsigned char vc_color_index_table[33] =
220 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
222
223 static unsigned long vc_color_depth_masks[4] =
224 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
225
226 static unsigned long vc_colors[8][3] = {
227 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
228 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
229 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
230 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
231 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
232 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
233 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
234 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
235 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
236 };
237
238 static unsigned long vc_color_mask = 0;
239 static unsigned long vc_color_fore = 0;
240 static unsigned long vc_color_back = 0;
241 static int vc_normal_background = 1;
242
243
244 /*
245 * For the jump scroll and buffering (Michel Pollet)
246 * 80*22 means on a 80*24 screen, the screen will
247 * scroll jump almost a full screen
248 * keeping only what's necessary for you to be able to read ;-)
249 */
250 #define VC_MAX_FORWARD_SIZE (100*36)
251
252 /*
253 * Delay between console updates in clock hz units, the larger the
254 * delay the fuller the jump-scroll buffer will be and so the faster the
255 * (scrolling) output. The smaller the delay, the less jerky the
256 * display. Heuristics show that at 10 touch-typists (Mike!) complain
257 */
258 #define VC_CONSOLE_UPDATE_TIMEOUT 5
259
260 static unsigned char vc_forward_buffer[VC_MAX_FORWARD_SIZE];
261 static long vc_forward_buffer_size = 0;
262 static int vc_forward_buffer_enabled = 0;
263 static int vc_forward_buffer_busy = 0;
264 decl_simple_lock_data(,vc_forward_lock)
265
266 #ifdef FAST_JUMP_SCROLL
267 static void (*vc_forward_paintchar) (unsigned char c, int x, int y, int attrs);
268 static enum {
269 PFoff,
270 PFwind,
271 PFscroll,
272 PFunwind
273 } vc_forward_preflight_mode = PFoff;
274 static struct {
275 enum vt100state_e vt100state;
276
277 int vc_wrap_mode, vc_relative_origin;
278 int vc_charset_select, vc_save_charset_s;
279 int vc_charset[2];
280 int vc_charset_save[2];
281
282 int x, y, savex, savey;
283 int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
284
285 char tab_stops[255];
286 int scrreg_top, scrreg_bottom;
287
288 unsigned long vc_color_fore;
289 unsigned long vc_color_back;
290 } vc_forward_preflight_save;
291 static int vc_forward_scroll = 0;
292 #endif FAST_JUMP_SCROLL
293
294 /*
295 * New Rendering code from Michel Pollet
296 */
297
298 /* That function will be called for drawing */
299 static void (*vc_paintchar) (unsigned char c, int x, int y, int attrs);
300
301 #ifdef RENDERALLOCATE
302 static unsigned char *renderedFont = NULL; /* rendered font buffer */
303 #else
304 #define REN_MAX_DEPTH 32
305 /* that's the size for a 32 bits buffer... */
306 #define REN_MAX_SIZE (128L*1024)
307 static unsigned char renderedFont[REN_MAX_SIZE];
308 #endif
309
310 /* Rendered Font Size */
311 static unsigned long vc_rendered_font_size = REN_MAX_SIZE;
312 static long vc_rendered_error = 0;
313
314 /* If the one bit table was reversed */
315 static short vc_one_bit_reversed = 0;
316
317 /* Size of a character in the table (bytes) */
318 static int vc_rendered_char_size = 0;
319
320 /*
321 # Attribute codes:
322 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
323 # Text color codes:
324 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
325 # Background color codes:
326 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
327 */
328
329 #define VC_RESET_BACKGROUND 40
330 #define VC_RESET_FOREGROUND 37
331
332 static void vc_color_set(int color)
333 {
334 if (vinfo.v_depth < 8)
335 return;
336 if (color >= 30 && color <= 37)
337 vc_color_fore = vc_colors[color-30][vc_color_index_table[vinfo.v_depth]];
338 if (color >= 40 && color <= 47) {
339 vc_color_back = vc_colors[color-40][vc_color_index_table[vinfo.v_depth]];
340 vc_normal_background = color == 40;
341 }
342
343 }
344
345 static void vc_render_font(short olddepth, short newdepth)
346 {
347 int charIndex; /* index in ISO font */
348 union {
349 unsigned char *charptr;
350 unsigned short *shortptr;
351 unsigned long *longptr;
352 } current; /* current place in rendered font, multiple types. */
353
354 unsigned char *theChar; /* current char in iso_font */
355
356 if (olddepth == newdepth && renderedFont) {
357 return; /* nothing to do */
358 }
359
360 if (olddepth != 1 && renderedFont) {
361 #ifdef RENDERALLOCATE
362 (void) kmem_free(kernel_map, (vm_offset_t*)renderedFont, vc_rendered_font_size);
363 #endif
364 }
365 vc_rendered_font_size = REN_MAX_SIZE;
366 if (newdepth == 1) {
367 #ifdef RENDERALLOCATE
368 renderedFont = iso_font;
369 #endif
370 vc_rendered_char_size = 16;
371 if (!vc_one_bit_reversed) { /* reverse the font for the blitter */
372 int i;
373 for (i = 0; i < ((ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size); i++) {
374 if (iso_font[i]) {
375 unsigned char mask1 = 0x80;
376 unsigned char mask2 = 0x01;
377 unsigned char val = 0;
378 while (mask1) {
379 if (iso_font[i] & mask1)
380 val |= mask2;
381 mask1 >>= 1;
382 mask2 <<= 1;
383 }
384 renderedFont[i] = ~val;
385 } else renderedFont[i] = 0xff;
386 }
387 vc_one_bit_reversed = 1;
388 }
389 return;
390 }
391 {
392 long csize = newdepth / 8; /* bytes per pixel */
393 vc_rendered_char_size = csize ? CHARHEIGHT * (csize * CHARWIDTH) :
394 /* for 2 & 4 */ CHARHEIGHT * (CHARWIDTH/(6-newdepth));
395 csize = (ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size;
396 #ifndef RENDERALLOCATE
397 if (csize > vc_rendered_font_size) {
398 vc_rendered_error = csize;
399 return;
400 } else
401 vc_rendered_font_size = csize;
402 #else
403 vc_rendered_font_size = csize;
404 #endif
405 }
406
407 #ifdef RENDERALLOCATE
408 if (kmem_alloc(kernel_map,
409 (vm_offset_t *)&renderedFont,
410 vc_rendered_font_size) != KERN_SUCCESS) {
411 renderedFont = NULL;
412 vc_rendered_error = vc_rendered_font_size;
413 return;
414 }
415 #endif
416 current.charptr = renderedFont;
417 theChar = iso_font;
418 for (charIndex = ISO_CHAR_MIN; charIndex <= ISO_CHAR_MAX; charIndex++) {
419 int line;
420 for (line = 0; line < CHARHEIGHT; line++) {
421 unsigned char mask = 1;
422 do {
423 switch (newdepth) {
424 case 2: {
425 unsigned char value = 0;
426 if (*theChar & mask) value |= 0xC0; mask <<= 1;
427 if (*theChar & mask) value |= 0x30; mask <<= 1;
428 if (*theChar & mask) value |= 0x0C; mask <<= 1;
429 if (*theChar & mask) value |= 0x03;
430 value = ~value;
431 *current.charptr++ = value;
432 }
433 break;
434 case 4:
435 {
436 unsigned char value = 0;
437 if (*theChar & mask) value |= 0xF0; mask <<= 1;
438 if (*theChar & mask) value |= 0x0F;
439 value = ~value;
440 *current.charptr++ = value;
441 }
442 break;
443 case 8:
444 *current.charptr++ = (*theChar & mask) ? 0xff : 0;
445 break;
446 case 16:
447 *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
448 break;
449
450 case 32:
451 *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
452 break;
453 }
454 mask <<= 1;
455 } while (mask); /* while the single bit drops to the right */
456 theChar++;
457 }
458 }
459 }
460
461 #ifdef FAST_JUMP_SCROLL
462 static void vc_paint_char(unsigned char ch, int xx, int yy, int attrs)
463 {
464 switch (vc_forward_preflight_mode) {
465 case PFoff:
466 vc_forward_paintchar(ch, xx, yy, attrs);
467 break;
468 case PFwind:
469 break;
470 case PFscroll:
471 break;
472 case PFunwind:
473 if (yy >= scrreg_top && yy < scrreg_bottom) {
474 yy -= vc_forward_scroll;
475 if (yy < scrreg_top || yy >= scrreg_bottom)
476 break;
477 }
478 vc_forward_paintchar(ch, xx, yy, attrs);
479 break;
480 }
481 }
482 #endif FAST_JUMP_SCROLL
483
484 static void vc_paint_char1(unsigned char ch, int xx, int yy, int attrs)
485 {
486 unsigned char *theChar;
487 unsigned char *where;
488 int i;
489
490 theChar = (unsigned char*)(renderedFont + (ch * vc_rendered_char_size));
491 where = (unsigned char*)(vinfo.v_baseaddr +
492 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
493 (xx));
494
495 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
496 *where = *theChar++;
497
498 where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
499 } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
500 unsigned char val = *theChar++, save = val;
501 if (attrs & ATTR_BOLD) { /* bold support */
502 unsigned char mask1 = 0xC0, mask2 = 0x40;
503 int bit = 0;
504 for (bit = 0; bit < 7; bit++) {
505 if ((save & mask1) == mask2)
506 val &= ~mask2;
507 mask1 >>= 1;
508 mask2 >>= 1;
509 }
510 }
511 if (attrs & ATTR_REVERSE) val = ~val;
512 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
513 *where = val;
514
515 where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
516 }
517
518 }
519
520 static void vc_paint_char2(unsigned char ch, int xx, int yy, int attrs)
521 {
522 unsigned short *theChar;
523 unsigned short *where;
524 int i;
525
526 theChar = (unsigned short*)(renderedFont + (ch * vc_rendered_char_size));
527 where = (unsigned short*)(vinfo.v_baseaddr +
528 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
529 (xx * 2));
530 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
531 *where = *theChar++;
532
533 where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
534 } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
535 unsigned short val = *theChar++, save = val;
536 if (attrs & ATTR_BOLD) { /* bold support */
537 unsigned short mask1 = 0xF000, mask2 = 0x3000;
538 int bit = 0;
539 for (bit = 0; bit < 7; bit++) {
540 if ((save & mask1) == mask2)
541 val &= ~mask2;
542 mask1 >>= 2;
543 mask2 >>= 2;
544 }
545 }
546 if (attrs & ATTR_REVERSE) val = ~val;
547 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
548 *where = val;
549
550 where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
551 }
552
553 }
554
555 static void vc_paint_char4(unsigned char ch, int xx, int yy, int attrs)
556 {
557 unsigned long *theChar;
558 unsigned long *where;
559 int i;
560
561 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
562 where = (unsigned long*)(vinfo.v_baseaddr +
563 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
564 (xx * 4));
565
566 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
567 *where = *theChar++;
568
569 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
570 } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
571 unsigned long val = *theChar++, save = val;
572 if (attrs & ATTR_BOLD) { /* bold support */
573 unsigned long mask1 = 0xff000000, mask2 = 0x0F000000;
574 int bit = 0;
575 for (bit = 0; bit < 7; bit++) {
576 if ((save & mask1) == mask2)
577 val &= ~mask2;
578 mask1 >>= 4;
579 mask2 >>= 4;
580 }
581 }
582 if (attrs & ATTR_REVERSE) val = ~val;
583 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
584 *where = val;
585
586 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
587 }
588
589 }
590
591 static void vc_paint_char8c(unsigned char ch, int xx, int yy, int attrs)
592 {
593 unsigned long *theChar;
594 unsigned long *where;
595 int i;
596
597 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
598 where = (unsigned long*)(vinfo.v_baseaddr +
599 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
600 (xx * CHARWIDTH));
601
602 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attr? FLY !*/
603 unsigned long *store = where;
604 int x;
605 for (x = 0; x < 2; x++) {
606 unsigned long val = *theChar++;
607 val = (vc_color_back & ~val) | (vc_color_fore & val);
608 *store++ = val;
609 }
610
611 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
612 } else for (i = 0; i < CHARHEIGHT; i++) { /* a little slower */
613 unsigned long *store = where, lastpixel = 0;
614 int x;
615 for (x = 0 ; x < 2; x++) {
616 unsigned long val = *theChar++, save = val;
617 if (attrs & ATTR_BOLD) { /* bold support */
618 if (lastpixel && !(save & 0xFF000000))
619 val |= 0xff000000;
620 if ((save & 0xFFFF0000) == 0xFF000000)
621 val |= 0x00FF0000;
622 if ((save & 0x00FFFF00) == 0x00FF0000)
623 val |= 0x0000FF00;
624 if ((save & 0x0000FFFF) == 0x0000FF00)
625 val |= 0x000000FF;
626 }
627 if (attrs & ATTR_REVERSE) val = ~val;
628 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
629
630 val = (vc_color_back & ~val) | (vc_color_fore & val);
631 *store++ = val;
632 lastpixel = save & 0xff;
633 }
634
635 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
636 }
637
638 }
639 static void vc_paint_char16c(unsigned char ch, int xx, int yy, int attrs)
640 {
641 unsigned long *theChar;
642 unsigned long *where;
643 int i;
644
645 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
646 where = (unsigned long*)(vinfo.v_baseaddr +
647 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
648 (xx * CHARWIDTH * 2));
649
650 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
651 unsigned long *store = where;
652 int x;
653 for (x = 0; x < 4; x++) {
654 unsigned long val = *theChar++;
655 val = (vc_color_back & ~val) | (vc_color_fore & val);
656 *store++ = val;
657 }
658
659 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
660 } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
661 unsigned long *store = where, lastpixel = 0;
662 int x;
663 for (x = 0 ; x < 4; x++) {
664 unsigned long val = *theChar++, save = val;
665 if (attrs & ATTR_BOLD) { /* bold support */
666 if (save == 0xFFFF0000) val |= 0xFFFF;
667 else if (lastpixel && !(save & 0xFFFF0000))
668 val |= 0xFFFF0000;
669 }
670 if (attrs & ATTR_REVERSE) val = ~val;
671 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
672
673 val = (vc_color_back & ~val) | (vc_color_fore & val);
674
675 *store++ = val;
676 lastpixel = save & 0x7fff;
677 }
678
679 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
680 }
681
682 }
683 static void vc_paint_char32c(unsigned char ch, int xx, int yy, int attrs)
684 {
685 unsigned long *theChar;
686 unsigned long *where;
687 int i;
688
689 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
690 where = (unsigned long*)(vinfo.v_baseaddr +
691 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
692 (xx * CHARWIDTH * 4));
693
694 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
695 unsigned long *store = where;
696 int x;
697 for (x = 0; x < 8; x++) {
698 unsigned long val = *theChar++;
699 val = (vc_color_back & ~val) | (vc_color_fore & val);
700 *store++ = val;
701 }
702
703 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
704 } else for (i = 0; i < CHARHEIGHT; i++) { /* a little slower */
705 unsigned long *store = where, lastpixel = 0;
706 int x;
707 for (x = 0 ; x < 8; x++) {
708 unsigned long val = *theChar++, save = val;
709 if (attrs & ATTR_BOLD) { /* bold support */
710 if (lastpixel && !save)
711 val = 0xFFFFFFFF;
712 }
713 if (attrs & ATTR_REVERSE) val = ~val;
714 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
715
716 val = (vc_color_back & ~val) | (vc_color_fore & val);
717 *store++ = val;
718 lastpixel = save;
719 }
720
721 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
722 }
723
724 }
725
726 /*
727 * That's a plain dumb reverse of the cursor position
728 * It do a binary reverse, so it will not looks good when we have
729 * color support. we'll see that later
730 */
731 static void reversecursor(void)
732 {
733 union {
734 unsigned char *charptr;
735 unsigned short *shortptr;
736 unsigned long *longptr;
737 } where;
738 int line, col;
739
740 where.longptr = (unsigned long*)(vinfo.v_baseaddr +
741 (y * CHARHEIGHT * vinfo.v_rowbytes) +
742 (x /** CHARWIDTH*/ * vinfo.v_depth));
743 for (line = 0; line < CHARHEIGHT; line++) {
744 switch (vinfo.v_depth) {
745 case 1:
746 *where.charptr = ~*where.charptr;
747 break;
748 case 2:
749 *where.shortptr = ~*where.shortptr;
750 break;
751 case 4:
752 *where.longptr = ~*where.longptr;
753 break;
754 /* that code still exists because since characters on the screen are
755 * of different colors that reverse function may not work if the
756 * cursor is on a character that is in a different color that the
757 * current one. When we have buffering, things will work better. MP
758 */
759 #ifdef VC_BINARY_REVERSE
760 case 8:
761 where.longptr[0] = ~where.longptr[0];
762 where.longptr[1] = ~where.longptr[1];
763 break;
764 case 16:
765 for (col = 0; col < 4; col++)
766 where.longptr[col] = ~where.longptr[col];
767 break;
768 case 32:
769 for (col = 0; col < 8; col++)
770 where.longptr[col] = ~where.longptr[col];
771 break;
772 #else
773 case 8:
774 for (col = 0; col < 8; col++)
775 where.charptr[col] = where.charptr[col] != (vc_color_fore & vc_color_mask) ?
776 vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
777 break;
778 case 16:
779 for (col = 0; col < 8; col++)
780 where.shortptr[col] = where.shortptr[col] != (vc_color_fore & vc_color_mask) ?
781 vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
782 break;
783 case 32:
784 for (col = 0; col < 8; col++)
785 where.longptr[col] = where.longptr[col] != (vc_color_fore & vc_color_mask) ?
786 vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
787 break;
788 #endif
789 }
790 where.charptr += vinfo.v_rowbytes;
791 }
792 }
793
794
795 static void
796 scrollup(int num)
797 {
798 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
799
800 linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
801 rowline = (vinfo.v_rowbytes) >> 2;
802 rowscanline = (vinfo.v_rowscanbytes) >> 2;
803
804 #ifdef FAST_JUMP_SCROLL
805 if (vc_forward_preflight_mode == PFwind) {
806 vc_forward_scroll += num;
807 return;
808 }
809 if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
810 #endif FAST_JUMP_SCROLL
811
812 to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
813 from = to + (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
814
815 i = (scrreg_bottom - scrreg_top) - num;
816
817 while (i-- > 0) {
818 for (line = 0; line < CHARHEIGHT; line++) {
819 /*
820 * Only copy what is displayed
821 */
822 video_scroll_up((unsigned int) from,
823 (unsigned int) (from+(vinfo.v_rowscanbytes/4)),
824 (unsigned int) to);
825
826 from += rowline;
827 to += rowline;
828 }
829 }
830
831 /* Now set the freed up lines to the background colour */
832
833
834 to = ((unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs))
835 + ((scrreg_bottom - scrreg_top - num) * linelongs);
836
837 #ifdef FAST_JUMP_SCROLL
838 if (vc_forward_preflight_mode == PFscroll)
839 return;
840 } else if (vc_forward_preflight_mode == PFunwind) {
841 long linestart, linelast;
842 vc_forward_scroll -= num;
843
844 linestart = scrreg_bottom - num - vc_forward_scroll;
845 linelast = linestart + num - 1;
846
847 if (linestart >= scrreg_bottom || linelast < scrreg_top)
848 return;
849
850 if (linelast >= scrreg_bottom)
851 linelast = scrreg_bottom - 1;
852 if (linestart < scrreg_top)
853 linestart = scrreg_top;
854
855 to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
856 num = linelast - linestart + 1;
857 }
858 #endif FAST_JUMP_SCROLL
859
860 for (linelongs = CHARHEIGHT * num; linelongs-- > 0;) {
861 from = to;
862 for (i = 0; i < rowscanline; i++)
863 *to++ = vc_color_back;
864
865 to = from + rowline;
866 }
867
868 }
869
870 static void
871 scrolldown(int num)
872 {
873 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
874
875 linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
876 rowline = (vinfo.v_rowbytes) >> 2;
877 rowscanline = (vinfo.v_rowscanbytes) >> 2;
878
879 #ifdef FAST_JUMP_SCROLL
880 if (vc_forward_preflight_mode == PFwind) {
881 vc_forward_scroll -= num;
882 return;
883 }
884 if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
885 #endif FAST_JUMP_SCROLL
886
887 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
888 - (rowline - rowscanline);
889 from = to - (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
890
891 i = (scrreg_bottom - scrreg_top) - num;
892
893 while (i-- > 0) {
894 for (line = 0; line < CHARHEIGHT; line++) {
895 /*
896 * Only copy what is displayed
897 */
898 video_scroll_down((unsigned int) from,
899 (unsigned int) (from-(vinfo.v_rowscanbytes/4)),
900 (unsigned int) to);
901
902 from -= rowline;
903 to -= rowline;
904 }
905 }
906
907 /* Now set the freed up lines to the background colour */
908
909 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_top);
910
911 #ifdef FAST_JUMP_SCROLL
912 if (vc_forward_preflight_mode == PFscroll)
913 return;
914 } else if (vc_forward_preflight_mode == PFunwind) {
915 long linestart, linelast;
916 vc_forward_scroll += num;
917
918 linestart = scrreg_top - vc_forward_scroll;
919 linelast = linestart + num - 1;
920
921 if (linestart >= scrreg_bottom || linelast < scrreg_top)
922 return;
923
924 if (linelast >= scrreg_bottom)
925 linelast = scrreg_bottom - 1;
926 if (linestart < scrreg_top)
927 linestart = scrreg_top;
928
929 to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
930 num = linelast - linestart + 1;
931 }
932 #endif FAST_JUMP_SCROLL
933
934 for (line = CHARHEIGHT * num; line > 0; line--) {
935 from = to;
936
937 for (i = 0; i < rowscanline; i++)
938 *(to++) = vc_color_back;
939
940 to = from + rowline;
941 }
942
943 }
944
945
946 static void
947 clear_line(int which)
948 {
949 int start, end, i;
950
951 /*
952 * This routine runs extremely slowly. I don't think it's
953 * used all that often, except for To end of line. I'll go
954 * back and speed this up when I speed up the whole vc
955 * module. --LK
956 */
957
958 switch (which) {
959 case 0: /* To end of line */
960 start = x;
961 end = vinfo.v_columns-1;
962 break;
963 case 1: /* To start of line */
964 start = 0;
965 end = x;
966 break;
967 case 2: /* Whole line */
968 start = 0;
969 end = vinfo.v_columns-1;
970 break;
971 }
972
973 for (i = start; i <= end; i++) {
974 vc_paintchar(' ', i, y, ATTR_NONE);
975 }
976
977 }
978
979 static void
980 clear_screen(int which)
981 {
982 unsigned long *p, *endp, *row;
983 int linelongs, col;
984 int rowline, rowlongs;
985
986 rowline = vinfo.v_rowscanbytes / 4;
987 rowlongs = vinfo.v_rowbytes / 4;
988
989 p = (unsigned long*) vinfo.v_baseaddr;;
990 endp = (unsigned long*) vinfo.v_baseaddr;
991
992 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
993
994 switch (which) {
995 case 0: /* To end of screen */
996 clear_line(0);
997 if (y < vinfo.v_rows - 1) {
998 p += (y + 1) * linelongs;
999 endp += rowlongs * vinfo.v_height;
1000 }
1001 break;
1002 case 1: /* To start of screen */
1003 clear_line(1);
1004 if (y > 1) {
1005 endp += (y + 1) * linelongs;
1006 }
1007 break;
1008 case 2: /* Whole screen */
1009 endp += rowlongs * vinfo.v_height;
1010 break;
1011 }
1012
1013 for (row = p ; row < endp ; row += rowlongs) {
1014 for (col = 0; col < rowline; col++)
1015 *(row+col) = vc_color_back;
1016 }
1017
1018 }
1019
1020 static void
1021 reset_tabs(void)
1022 {
1023 int i;
1024
1025 for (i = 0; i<= vinfo.v_columns; i++) {
1026 tab_stops[i] = ((i % 8) == 0);
1027 }
1028
1029 }
1030
1031 static void
1032 vt100_reset(void)
1033 {
1034 reset_tabs();
1035 scrreg_top = 0;
1036 scrreg_bottom = vinfo.v_rows;
1037 attr = ATTR_NONE;
1038 vc_charset[0] = vc_charset[1] = 0;
1039 vc_charset_select = 0;
1040 vc_wrap_mode = 1;
1041 vc_relative_origin = 0;
1042 vc_color_set(VC_RESET_BACKGROUND);
1043 vc_color_set(VC_RESET_FOREGROUND);
1044
1045 }
1046
1047 static void
1048 putc_normal(unsigned char ch)
1049 {
1050 switch (ch) {
1051 case '\a': /* Beep */
1052 {
1053 spl_t s;
1054
1055 if(FALSE) {
1056 /*
1057 * No sound hardware, invert the screen twice instead
1058 */
1059 unsigned long *ptr;
1060 int i, j;
1061 /* XOR the screen twice */
1062 for (i = 0; i < 2 ; i++) {
1063 /* For each row, xor the scanbytes */
1064 for (ptr = (unsigned long*)vinfo.v_baseaddr;
1065 ptr < (unsigned long*)(vinfo.v_baseaddr +
1066 (vinfo.v_height * vinfo.v_rowbytes));
1067 ptr += (vinfo.v_rowbytes /
1068 sizeof (unsigned long*)))
1069 for (j = 0;
1070 j < vinfo.v_rowscanbytes /
1071 sizeof (unsigned long*);
1072 j++)
1073 *(ptr+j) =~*(ptr+j);
1074 }
1075 }
1076 }
1077 break;
1078
1079 case 127: /* Delete */
1080 case '\b': /* Backspace */
1081 if (hanging_cursor) {
1082 hanging_cursor = 0;
1083 } else
1084 if (x > 0) {
1085 x--;
1086 }
1087 break;
1088 case '\t': /* Tab */
1089 while (x < vinfo.v_columns && !tab_stops[++x]);
1090 if (x >= vinfo.v_columns)
1091 x = vinfo.v_columns-1;
1092 break;
1093 case 0x0b:
1094 case 0x0c:
1095 case '\n': /* Line feed */
1096 if (y >= scrreg_bottom -1 ) {
1097 scrollup(1);
1098 y = scrreg_bottom - 1;
1099 } else {
1100 y++;
1101 }
1102 break;
1103 case '\r': /* Carriage return */
1104 x = 0;
1105 hanging_cursor = 0;
1106 break;
1107 case 0x0e: /* Select G1 charset (Control-N) */
1108 vc_charset_select = 1;
1109 break;
1110 case 0x0f: /* Select G0 charset (Control-O) */
1111 vc_charset_select = 0;
1112 break;
1113 case 0x18 : /* CAN : cancel */
1114 case 0x1A : /* like cancel */
1115 /* well, i do nothing here, may be later */
1116 break;
1117 case '\033': /* Escape */
1118 vt100state = ESesc;
1119 hanging_cursor = 0;
1120 break;
1121 default:
1122 if (ch >= ' ') {
1123 if (hanging_cursor) {
1124 x = 0;
1125 if (y >= scrreg_bottom -1 ) {
1126 scrollup(1);
1127 y = scrreg_bottom - 1;
1128 } else {
1129 y++;
1130 }
1131 hanging_cursor = 0;
1132 }
1133 vc_paintchar((ch >= 0x60 && ch <= 0x7f) ? ch + vc_charset[vc_charset_select]
1134 : ch, x, y, attr);
1135 if (x == vinfo.v_columns - 1) {
1136 hanging_cursor = vc_wrap_mode;
1137 } else {
1138 x++;
1139 }
1140 }
1141 break;
1142 }
1143
1144 }
1145
1146 static void
1147 putc_esc(unsigned char ch)
1148 {
1149 vt100state = ESnormal;
1150
1151 switch (ch) {
1152 case '[':
1153 vt100state = ESsquare;
1154 break;
1155 case 'c': /* Reset terminal */
1156 vt100_reset();
1157 clear_screen(2);
1158 x = y = 0;
1159 break;
1160 case 'D': /* Line feed */
1161 case 'E':
1162 if (y >= scrreg_bottom -1) {
1163 scrollup(1);
1164 y = scrreg_bottom - 1;
1165 } else {
1166 y++;
1167 }
1168 if (ch == 'E') x = 0;
1169 break;
1170 case 'H': /* Set tab stop */
1171 tab_stops[x] = 1;
1172 break;
1173 case 'M': /* Cursor up */
1174 if (y <= scrreg_top) {
1175 scrolldown(1);
1176 y = scrreg_top;
1177 } else {
1178 y--;
1179 }
1180 break;
1181 case '>':
1182 vt100_reset();
1183 break;
1184 case '7': /* Save cursor */
1185 savex = x;
1186 savey = y;
1187 saveattr = attr;
1188 vc_save_charset_s = vc_charset_select;
1189 vc_charset_save[0] = vc_charset[0];
1190 vc_charset_save[1] = vc_charset[1];
1191 break;
1192 case '8': /* Restore cursor */
1193 x = savex;
1194 y = savey;
1195 attr = saveattr;
1196 vc_charset_select = vc_save_charset_s;
1197 vc_charset[0] = vc_charset_save[0];
1198 vc_charset[1] = vc_charset_save[1];
1199 break;
1200 case 'Z': /* return terminal ID */
1201 break;
1202 case '#': /* change characters height */
1203 vt100state = EScharsize;
1204 break;
1205 case '(':
1206 vt100state = ESsetG0;
1207 break;
1208 case ')': /* character set sequence */
1209 vt100state = ESsetG1;
1210 break;
1211 case '=':
1212 break;
1213 default:
1214 /* Rest not supported */
1215 break;
1216 }
1217
1218 }
1219
1220 static void
1221 putc_askcmd(unsigned char ch)
1222 {
1223 if (ch >= '0' && ch <= '9') {
1224 par[numpars] = (10*par[numpars]) + (ch-'0');
1225 return;
1226 }
1227 vt100state = ESnormal;
1228
1229 switch (par[0]) {
1230 case 6:
1231 vc_relative_origin = ch == 'h';
1232 break;
1233 case 7: /* wrap around mode h=1, l=0*/
1234 vc_wrap_mode = ch == 'h';
1235 break;
1236 default:
1237 break;
1238 }
1239
1240 }
1241
1242 static void
1243 putc_charsizecmd(unsigned char ch)
1244 {
1245 vt100state = ESnormal;
1246
1247 switch (ch) {
1248 case '3' :
1249 case '4' :
1250 case '5' :
1251 case '6' :
1252 break;
1253 case '8' : /* fill 'E's */
1254 {
1255 int xx, yy;
1256 for (yy = 0; yy < vinfo.v_rows; yy++)
1257 for (xx = 0; xx < vinfo.v_columns; xx++)
1258 vc_paintchar('E', xx, yy, ATTR_NONE);
1259 }
1260 break;
1261 }
1262
1263 }
1264
1265 static void
1266 putc_charsetcmd(int charset, unsigned char ch)
1267 {
1268 vt100state = ESnormal;
1269
1270 switch (ch) {
1271 case 'A' :
1272 case 'B' :
1273 default:
1274 vc_charset[charset] = 0;
1275 break;
1276 case '0' : /* Graphic characters */
1277 case '2' :
1278 vc_charset[charset] = 0x21;
1279 break;
1280 }
1281
1282 }
1283
1284 static void
1285 putc_gotpars(unsigned char ch)
1286 {
1287 int i;
1288
1289 if (ch < ' ') {
1290 /* special case for vttest for handling cursor
1291 movement in escape sequences */
1292 putc_normal(ch);
1293 vt100state = ESgotpars;
1294 return;
1295 }
1296 vt100state = ESnormal;
1297 switch (ch) {
1298 case 'A': /* Up */
1299 y -= par[0] ? par[0] : 1;
1300 if (y < scrreg_top)
1301 y = scrreg_top;
1302 break;
1303 case 'B': /* Down */
1304 y += par[0] ? par[0] : 1;
1305 if (y >= scrreg_bottom)
1306 y = scrreg_bottom - 1;
1307 break;
1308 case 'C': /* Right */
1309 x += par[0] ? par[0] : 1;
1310 if (x >= vinfo.v_columns)
1311 x = vinfo.v_columns-1;
1312 break;
1313 case 'D': /* Left */
1314 x -= par[0] ? par[0] : 1;
1315 if (x < 0)
1316 x = 0;
1317 break;
1318 case 'H': /* Set cursor position */
1319 case 'f':
1320 x = par[1] ? par[1] - 1 : 0;
1321 y = par[0] ? par[0] - 1 : 0;
1322 if (vc_relative_origin)
1323 y += scrreg_top;
1324 hanging_cursor = 0;
1325 break;
1326 case 'X': /* clear p1 characters */
1327 if (numpars) {
1328 int i;
1329 for (i = x; i < x + par[0]; i++)
1330 vc_paintchar(' ', i, y, ATTR_NONE);
1331 }
1332 break;
1333 case 'J': /* Clear part of screen */
1334 clear_screen(par[0]);
1335 break;
1336 case 'K': /* Clear part of line */
1337 clear_line(par[0]);
1338 break;
1339 case 'g': /* tab stops */
1340 switch (par[0]) {
1341 case 1:
1342 case 2: /* reset tab stops */
1343 /* reset_tabs(); */
1344 break;
1345 case 3: /* Clear every tabs */
1346 {
1347 int i;
1348
1349 for (i = 0; i <= vinfo.v_columns; i++)
1350 tab_stops[i] = 0;
1351 }
1352 break;
1353 case 0:
1354 tab_stops[x] = 0;
1355 break;
1356 }
1357 break;
1358 case 'm': /* Set attribute */
1359 for (i = 0; i < numpars; i++) {
1360 switch (par[i]) {
1361 case 0:
1362 attr = ATTR_NONE;
1363 vc_color_set(VC_RESET_BACKGROUND);
1364 vc_color_set(VC_RESET_FOREGROUND);
1365 break;
1366 case 1:
1367 attr |= ATTR_BOLD;
1368 break;
1369 case 4:
1370 attr |= ATTR_UNDER;
1371 break;
1372 case 7:
1373 attr |= ATTR_REVERSE;
1374 break;
1375 case 22:
1376 attr &= ~ATTR_BOLD;
1377 break;
1378 case 24:
1379 attr &= ~ATTR_UNDER;
1380 break;
1381 case 27:
1382 attr &= ~ATTR_REVERSE;
1383 break;
1384 case 5:
1385 case 25: /* blink/no blink */
1386 break;
1387 default:
1388 vc_color_set(par[i]);
1389 break;
1390 }
1391 }
1392 break;
1393 case 'r': /* Set scroll region */
1394 x = y = 0;
1395 /* ensure top < bottom, and both within limits */
1396 if ((numpars > 0) && (par[0] < vinfo.v_rows)) {
1397 scrreg_top = par[0] ? par[0] - 1 : 0;
1398 if (scrreg_top < 0)
1399 scrreg_top = 0;
1400 } else {
1401 scrreg_top = 0;
1402 }
1403 if ((numpars > 1) && (par[1] <= vinfo.v_rows) && (par[1] > par[0])) {
1404 scrreg_bottom = par[1];
1405 if (scrreg_bottom > vinfo.v_rows)
1406 scrreg_bottom = vinfo.v_rows;
1407 } else {
1408 scrreg_bottom = vinfo.v_rows;
1409 }
1410 if (vc_relative_origin)
1411 y = scrreg_top;
1412 break;
1413 }
1414
1415 }
1416
1417 static void
1418 putc_getpars(unsigned char ch)
1419 {
1420 if (ch == '?') {
1421 vt100state = ESask;
1422 return;
1423 }
1424 if (ch == '[') {
1425 vt100state = ESnormal;
1426 /* Not supported */
1427 return;
1428 }
1429 if (ch == ';' && numpars < MAXPARS - 1) {
1430 numpars++;
1431 } else
1432 if (ch >= '0' && ch <= '9') {
1433 par[numpars] *= 10;
1434 par[numpars] += ch - '0';
1435 } else {
1436 numpars++;
1437 vt100state = ESgotpars;
1438 putc_gotpars(ch);
1439 }
1440 }
1441
1442 static void
1443 putc_square(unsigned char ch)
1444 {
1445 int i;
1446
1447 for (i = 0; i < MAXPARS; i++) {
1448 par[i] = 0;
1449 }
1450
1451 numpars = 0;
1452 vt100state = ESgetpars;
1453
1454 putc_getpars(ch);
1455
1456 }
1457
1458 static void
1459 vc_putchar(char ch)
1460 {
1461 if (!ch) {
1462 return; /* ignore null characters */
1463 }
1464 switch (vt100state) {
1465 default:vt100state = ESnormal; /* FALLTHROUGH */
1466 case ESnormal:
1467 putc_normal(ch);
1468 break;
1469 case ESesc:
1470 putc_esc(ch);
1471 break;
1472 case ESsquare:
1473 putc_square(ch);
1474 break;
1475 case ESgetpars:
1476 putc_getpars(ch);
1477 break;
1478 case ESgotpars:
1479 putc_gotpars(ch);
1480 break;
1481 case ESask:
1482 putc_askcmd(ch);
1483 break;
1484 case EScharsize:
1485 putc_charsizecmd(ch);
1486 break;
1487 case ESsetG0:
1488 putc_charsetcmd(0, ch);
1489 break;
1490 case ESsetG1:
1491 putc_charsetcmd(1, ch);
1492 break;
1493 }
1494
1495 if (x >= vinfo.v_columns) {
1496 x = vinfo.v_columns - 1;
1497 }
1498 if (x < 0) {
1499 x = 0;
1500 }
1501 if (y >= vinfo.v_rows) {
1502 y = vinfo.v_rows - 1;
1503 }
1504 if (y < 0) {
1505 y = 0;
1506 }
1507
1508 }
1509
1510 /*
1511 * Actually draws the buffer, handle the jump scroll
1512 */
1513 static void vc_flush_forward_buffer(void)
1514 {
1515 int start = 0;
1516 int todo = 0;
1517 spl_t s;
1518
1519 assert(vc_forward_buffer_enabled);
1520
1521 s = splhigh();
1522 simple_lock(&vc_forward_lock);
1523
1524 if (vc_forward_buffer_busy) {
1525 /* Bail out if we're already in the middle of a flush. */
1526 simple_unlock(&vc_forward_lock);
1527 splx(s);
1528 return;
1529 }
1530
1531 vc_forward_buffer_busy = 1;
1532
1533 while (todo < vc_forward_buffer_size) {
1534 todo = vc_forward_buffer_size;
1535
1536 /* Drop the lock while we update the screen. */
1537 simple_unlock(&vc_forward_lock);
1538 splx(s);
1539
1540 reversecursor();
1541
1542 do {
1543 int i;
1544 #ifdef FAST_JUMP_SCROLL
1545 if ((todo - start) < 2) {
1546 vc_putchar(vc_forward_buffer[start++]);
1547 } else {
1548 assert(vc_forward_scroll == 0);
1549
1550 vc_forward_preflight_save.vt100state = vt100state;
1551 vc_forward_preflight_save.vc_wrap_mode = vc_wrap_mode;
1552 vc_forward_preflight_save.vc_relative_origin = vc_relative_origin;
1553 vc_forward_preflight_save.vc_charset_select = vc_charset_select;
1554 vc_forward_preflight_save.vc_save_charset_s = vc_save_charset_s;
1555 vc_forward_preflight_save.vc_charset[0] = vc_charset[0];
1556 vc_forward_preflight_save.vc_charset[1] = vc_charset[1];
1557 vc_forward_preflight_save.vc_charset_save[0] = vc_charset_save[0];
1558 vc_forward_preflight_save.vc_charset_save[1] = vc_charset_save[1];
1559 vc_forward_preflight_save.x = x;
1560 vc_forward_preflight_save.y = y;
1561 vc_forward_preflight_save.savex = savex;
1562 vc_forward_preflight_save.savey = savey;
1563 vc_forward_preflight_save.numpars = numpars;
1564 vc_forward_preflight_save.hanging_cursor = hanging_cursor;
1565 vc_forward_preflight_save.attr = attr;
1566 vc_forward_preflight_save.saveattr = saveattr;
1567 vc_forward_preflight_save.scrreg_top = scrreg_top;
1568 vc_forward_preflight_save.scrreg_bottom = scrreg_bottom;
1569 vc_forward_preflight_save.vc_color_fore = vc_color_fore;
1570 vc_forward_preflight_save.vc_color_back = vc_color_back;
1571 bcopy( (const char *) par,
1572 (char *) vc_forward_preflight_save.par,
1573 (vm_size_t) sizeof(par) );
1574 bcopy( (const char *) tab_stops,
1575 (char *) vc_forward_preflight_save.tab_stops,
1576 (vm_size_t) sizeof(tab_stops) );
1577
1578 vc_forward_preflight_mode = PFwind;
1579
1580 for (i = start;
1581 i < todo &&
1582 vc_forward_preflight_save.scrreg_top == scrreg_top &&
1583 vc_forward_preflight_save.scrreg_bottom == scrreg_bottom;
1584 i++)
1585 vc_putchar(vc_forward_buffer[i]);
1586
1587 vt100state = vc_forward_preflight_save.vt100state;
1588 vc_wrap_mode = vc_forward_preflight_save.vc_wrap_mode;
1589 vc_relative_origin = vc_forward_preflight_save.vc_relative_origin;
1590 vc_charset_select = vc_forward_preflight_save.vc_charset_select;
1591 vc_save_charset_s = vc_forward_preflight_save.vc_save_charset_s;
1592 vc_charset[0] = vc_forward_preflight_save.vc_charset[0];
1593 vc_charset[1] = vc_forward_preflight_save.vc_charset[1];
1594 vc_charset_save[0] = vc_forward_preflight_save.vc_charset_save[0];
1595 vc_charset_save[1] = vc_forward_preflight_save.vc_charset_save[1];
1596 x = vc_forward_preflight_save.x;
1597 y = vc_forward_preflight_save.y;
1598 savex = vc_forward_preflight_save.savex;
1599 savey = vc_forward_preflight_save.savey;
1600 numpars = vc_forward_preflight_save.numpars;
1601 hanging_cursor = vc_forward_preflight_save.hanging_cursor;
1602 attr = vc_forward_preflight_save.attr;
1603 saveattr = vc_forward_preflight_save.saveattr;
1604 scrreg_top = vc_forward_preflight_save.scrreg_top;
1605 scrreg_bottom = vc_forward_preflight_save.scrreg_bottom;
1606 vc_color_fore = vc_forward_preflight_save.vc_color_fore;
1607 vc_color_back = vc_forward_preflight_save.vc_color_back;
1608 bcopy( (const char *) vc_forward_preflight_save.par,
1609 (char *) par,
1610 (vm_size_t) sizeof(par) );
1611 bcopy( (const char *) vc_forward_preflight_save.tab_stops,
1612 (char *) tab_stops,
1613 (vm_size_t) sizeof(tab_stops) );
1614
1615 vc_forward_preflight_mode = PFscroll;
1616
1617 if (vc_forward_scroll > 0)
1618 scrollup(vc_forward_scroll > scrreg_bottom - scrreg_top ?
1619 scrreg_bottom - scrreg_top : vc_forward_scroll);
1620 else if (vc_forward_scroll < 0)
1621 scrolldown(-vc_forward_scroll > scrreg_bottom - scrreg_top ?
1622 scrreg_bottom - scrreg_top : -vc_forward_scroll);
1623
1624 vc_forward_preflight_mode = PFunwind;
1625
1626 for (; start < i; start++)
1627 vc_putchar(vc_forward_buffer[start]);
1628
1629 assert(vc_forward_scroll == 0);
1630
1631 vc_forward_preflight_mode = PFoff;
1632 }
1633 #else !FAST_JUMP_SCROLL
1634 int plaintext = 1;
1635 int drawlen = start;
1636 int jump = 0;
1637 int param = 0, changebackground = 0;
1638 enum vt100state_e vtState = vt100state;
1639 /*
1640 * In simple words, here we're pre-parsing the text to look for
1641 * + Newlines, for computing jump scroll
1642 * + /\033\[[0-9;]*]m/ to continue on
1643 * any other sequence will stop. We don't want to have cursor
1644 * movement escape sequences while we're trying to pre-scroll
1645 * the screen.
1646 * We have to be extra carefull about the sequences that changes
1647 * the background color to prevent scrolling in those
1648 * particular cases.
1649 * That parsing was added to speed up 'man' and 'color-ls' a
1650 * zillion time (at least). It's worth it, trust me.
1651 * (mail Nick Stephen for a True Performance Graph)
1652 * Michel Pollet
1653 */
1654 for (i = start; i < todo && plaintext; i++) {
1655 drawlen++;
1656 switch (vtState) {
1657 case ESnormal:
1658 switch (vc_forward_buffer[i]) {
1659 case '\033':
1660 vtState = ESesc;
1661 break;
1662 case '\n':
1663 jump++;
1664 break;
1665 }
1666 break;
1667 case ESesc:
1668 switch (vc_forward_buffer[i]) {
1669 case '[':
1670 vtState = ESgetpars;
1671 param = 0;
1672 changebackground = 0;
1673 break;
1674 default:
1675 plaintext = 0;
1676 break;
1677 }
1678 break;
1679 case ESgetpars:
1680 if ((vc_forward_buffer[i] >= '0' &&
1681 vc_forward_buffer[i] <= '9') ||
1682 vc_forward_buffer[i] == ';') {
1683 if (vc_forward_buffer[i] >= '0' &&
1684 vc_forward_buffer[i] <= '9')
1685 param = (param*10)+(vc_forward_buffer[i]-'0');
1686 else {
1687 if (param >= 40 && param <= 47)
1688 changebackground = 1;
1689 if (!vc_normal_background &&
1690 !param)
1691 changebackground = 1;
1692 param = 0;
1693 }
1694 break; /* continue on */
1695 }
1696 vtState = ESgotpars;
1697 /* fall */
1698 case ESgotpars:
1699 switch (vc_forward_buffer[i]) {
1700 case 'm':
1701 vtState = ESnormal;
1702 if (param >= 40 && param <= 47)
1703 changebackground = 1;
1704 if (!vc_normal_background &&
1705 !param)
1706 changebackground = 1;
1707 if (changebackground) {
1708 plaintext = 0;
1709 jump = 0;
1710 /* REALLY don't jump */
1711 }
1712 /* Yup ! we've got it */
1713 break;
1714 default:
1715 plaintext = 0;
1716 break;
1717 }
1718 break;
1719 default:
1720 plaintext = 0;
1721 break;
1722 }
1723
1724 }
1725
1726 /*
1727 * Then we look if it would be appropriate to forward jump
1728 * the screen before drawing
1729 */
1730 if (jump && (scrreg_bottom - scrreg_top) > 2) {
1731 jump -= scrreg_bottom - y - 1;
1732 if (jump > 0 ) {
1733 if (jump >= scrreg_bottom - scrreg_top)
1734 jump = scrreg_bottom - scrreg_top -1;
1735 y -= jump;
1736 scrollup(jump);
1737 }
1738 }
1739 /*
1740 * and we draw what we've found to the parser
1741 */
1742 for (i = start; i < drawlen; i++)
1743 vc_putchar(vc_forward_buffer[start++]);
1744 /*
1745 * Continue sending characters to the parser until we're sure we're
1746 * back on normal characters.
1747 */
1748 for (i = start; i < todo &&
1749 vt100state != ESnormal ; i++)
1750 vc_putchar(vc_forward_buffer[start++]);
1751 #endif !FAST_JUMP_SCROLL
1752 /* Then loop again if there still things to draw */
1753 } while (start < todo);
1754
1755 reversecursor();
1756
1757 /* Re-acquire the lock while we check our state. */
1758 s = splhigh();
1759 simple_lock(&vc_forward_lock);
1760 }
1761
1762 vc_forward_buffer_busy = 0;
1763 vc_forward_buffer_size = 0;
1764
1765 simple_unlock(&vc_forward_lock);
1766 splx(s);
1767 }
1768
1769 int
1770 vcputc(int l, int u, int c)
1771 {
1772 if(!vinfo.v_baseaddr)
1773 return;
1774
1775 /*
1776 * Either we're really buffering stuff or we're not yet because
1777 * the probe hasn't been done.
1778 */
1779 if (vc_forward_buffer_enabled)
1780 vc_store_char(c);
1781 else
1782 vc_putchar(c);
1783
1784 return 0;
1785 }
1786
1787 /*
1788 * Store characters to be drawn 'later', handle overflows
1789 */
1790
1791 static void
1792 vc_store_char(unsigned char c)
1793 {
1794 int flush = 0;
1795 spl_t s;
1796
1797 assert(vc_forward_buffer_enabled);
1798
1799 s = splhigh();
1800 simple_lock(&vc_forward_lock);
1801
1802 /* Spin until the buffer has space for another character. */
1803 while (vc_forward_buffer_size == VC_MAX_FORWARD_SIZE) {
1804 simple_unlock(&vc_forward_lock);
1805 splx(s);
1806 /* wait */
1807 s = splhigh();
1808 simple_lock(&vc_forward_lock);
1809 }
1810
1811 assert(vc_forward_buffer_size < VC_MAX_FORWARD_SIZE);
1812
1813 vc_forward_buffer[vc_forward_buffer_size++] = (unsigned char)c;
1814
1815 if (vc_forward_buffer_size == 1) {
1816 /* If we're adding the first character to the buffer,
1817 * start the timer, otherwise it is already running.
1818 */
1819 if (debug_mode) {
1820 flush = 1;
1821 } else {
1822 timeout((timeout_fcn_t)vc_flush_forward_buffer,
1823 (void *)0,
1824 VC_CONSOLE_UPDATE_TIMEOUT);
1825 }
1826 } else if (vc_forward_buffer_size == VC_MAX_FORWARD_SIZE || debug_mode) {
1827 /*
1828 * If there is an overflow or this is an immediate character display
1829 * (eg. pre-clock printfs, panics), then we force a draw (take into
1830 * account that a flush might already be in progress).
1831 */
1832 if (!vc_forward_buffer_busy) {
1833 flush = 1;
1834 untimeout((timeout_fcn_t)vc_flush_forward_buffer, (void *)0);
1835 }
1836 }
1837
1838 simple_unlock(&vc_forward_lock);
1839 splx(s);
1840
1841 if (flush) {
1842 /*
1843 * Immediate character display.. kernel printf uses this. Make sure
1844 * get flushed and that panics get fully displayed.
1845 */
1846 vc_flush_forward_buffer();
1847 }
1848 }
1849
1850 static void
1851 vc_initialize(void)
1852 {
1853 #if 0
1854 GratefulDebInit(); /* (TEST/DEBUG) */
1855 #endif
1856
1857 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1858 printf(" Video info: %d; video_board=%08X\n", i, vboard);
1859 printf(" Video name: %s\n", vinfo.v_name);
1860 printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
1861 vinfo.v_height, vinfo.v_width, vinfo.v_depth, vinfo.v_rowbytes, vinfo.v_type);
1862 printf(" physical address=%08X\n", vinfo.v_physaddr);
1863 #endif
1864
1865 vinfo.v_rows = vinfo.v_height / CHARHEIGHT;
1866 vinfo.v_columns = vinfo.v_width / CHARWIDTH;
1867
1868 if (vinfo.v_depth >= 8) {
1869 vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
1870 } else {
1871 vinfo.v_rowscanbytes = vinfo.v_width / (8 / vinfo.v_depth);
1872 }
1873
1874 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1875 printf(" inited=%d\n", vc_initted);
1876 #endif
1877
1878
1879 vc_render_font(1, vinfo.v_depth);
1880 vc_color_mask = vc_color_depth_masks[vc_color_index_table[vinfo.v_depth]];
1881 vt100_reset();
1882 switch (vinfo.v_depth) {
1883 default:
1884 case 1:
1885 vc_paintchar = vc_paint_char1;
1886 break;
1887 case 2:
1888 vc_paintchar = vc_paint_char2;
1889 break;
1890 case 4:
1891 vc_paintchar = vc_paint_char4;
1892 break;
1893 case 8:
1894 vc_paintchar = vc_paint_char8c;
1895 break;
1896 case 16:
1897 vc_paintchar = vc_paint_char16c;
1898 break;
1899 case 32:
1900 vc_paintchar = vc_paint_char32c;
1901 break;
1902 }
1903
1904 #ifdef FAST_JUMP_SCROLL
1905 vc_forward_paintchar = vc_paintchar;
1906 vc_paintchar = vc_paint_char;
1907 #endif FAST_JUMP_SCROLL
1908 }
1909
1910 void
1911 vcattach(void)
1912 {
1913 if (vinfo.v_depth >= 8)
1914 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1915 printf("video console at 0x%x (%dx%dx%d)\n", vinfo.v_baseaddr,
1916 vinfo.v_width, vinfo.v_height, vinfo.v_depth);
1917
1918 /*
1919 * Added for the buffering and jump scrolling
1920 */
1921 /* Init our lock */
1922 simple_lock_init(&vc_forward_lock, ETAP_IO_TTY);
1923
1924 vc_forward_buffer_enabled = 1;
1925
1926 }
1927
1928
1929 struct vc_progress_element {
1930 unsigned int version;
1931 unsigned int flags;
1932 unsigned int time;
1933 unsigned char count;
1934 unsigned char res[3];
1935 int width;
1936 int height;
1937 int dx;
1938 int dy;
1939 int transparent;
1940 unsigned int res2[3];
1941 unsigned char data[0];
1942 };
1943 typedef struct vc_progress_element vc_progress_element;
1944
1945 static vc_progress_element * vc_progress;
1946 static const unsigned char * vc_progress_data;
1947 static const unsigned char * vc_progress_alpha;
1948 static boolean_t vc_progress_enable;
1949 static const unsigned char * vc_clut;
1950 static const unsigned char * vc_clut8;
1951 static unsigned char vc_revclut8[256];
1952 static unsigned int vc_progress_tick;
1953 static boolean_t vc_graphics_mode;
1954 static boolean_t vc_acquired;
1955 static boolean_t vc_need_clear;
1956 static boolean_t vc_needsave;
1957 static vm_address_t vc_saveunder;
1958 static vm_size_t vc_saveunder_len;
1959
1960 static void vc_blit_rect_8c( int x, int y,
1961 int width, int height,
1962 const unsigned char * dataPtr,
1963 const unsigned char * alphaPtr,
1964 unsigned char * backPtr,
1965 boolean_t save, boolean_t static_alpha )
1966 {
1967 volatile unsigned char * dst;
1968 int line, col;
1969 unsigned int data;
1970 unsigned char alpha;
1971
1972 dst = (unsigned char *)(vinfo.v_baseaddr +
1973 (y * vinfo.v_rowbytes) +
1974 (x));
1975
1976 for( line = 0; line < height; line++) {
1977 for( col = 0; col < width; col++) {
1978 data = 0;
1979 if( dataPtr != 0) data = *dataPtr++;
1980 else if( alphaPtr != 0) data = vc_revclut8[*alphaPtr++];
1981 *(dst + col) = data;
1982 }
1983 dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1984 }
1985
1986 }
1987
1988 static void vc_blit_rect_16( int x, int y,
1989 int width, int height,
1990 const unsigned char * dataPtr,
1991 const unsigned char * alphaPtr,
1992 unsigned short * backPtr,
1993 boolean_t save, boolean_t static_alpha )
1994 {
1995 volatile unsigned short * dst;
1996 int line, col;
1997 unsigned int data, index, alpha, back;
1998
1999 dst = (volatile unsigned short *)(vinfo.v_baseaddr +
2000 (y * vinfo.v_rowbytes) +
2001 (x * 2));
2002
2003 for( line = 0; line < height; line++) {
2004 for( col = 0; col < width; col++) {
2005 if( dataPtr != 0) {
2006 index = *dataPtr++;
2007 index *= 3;
2008 }
2009
2010 if( alphaPtr && backPtr) {
2011
2012 alpha = *alphaPtr++;
2013 data = 0;
2014 if( dataPtr != 0) {
2015 if( vc_clut[index + 0] > alpha)
2016 data |= (((vc_clut[index + 0] - alpha) & 0xf8) << 7);
2017 if( vc_clut[index + 1] > alpha)
2018 data |= (((vc_clut[index + 1] - alpha) & 0xf8) << 2);
2019 if( vc_clut[index + 2] > alpha)
2020 data |= (((vc_clut[index + 2] - alpha) & 0xf8) >> 3);
2021 }
2022
2023 if( save) {
2024 back = *(dst + col);
2025 if ( !static_alpha)
2026 *backPtr++ = back;
2027 back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
2028 | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
2029 | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
2030 if ( static_alpha)
2031 *backPtr++ = back;
2032 } else {
2033 back = *backPtr++;
2034 if ( !static_alpha) {
2035 back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
2036 | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
2037 | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
2038 }
2039 }
2040
2041 data += back;
2042
2043 } else
2044 if( dataPtr != 0) {
2045 data = ( (0xf8 & (vc_clut[index + 0])) << 7)
2046 | ( (0xf8 & (vc_clut[index + 1])) << 2)
2047 | ( (0xf8 & (vc_clut[index + 2])) >> 3);
2048 }
2049
2050 *(dst + col) = data;
2051 }
2052 dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
2053 }
2054 }
2055
2056 static void vc_blit_rect_32( unsigned int x, unsigned int y,
2057 unsigned int width, unsigned int height,
2058 const unsigned char * dataPtr,
2059 const unsigned char * alphaPtr,
2060 unsigned int * backPtr,
2061 boolean_t save, boolean_t static_alpha )
2062 {
2063 volatile unsigned int * dst;
2064 int line, col;
2065 unsigned int data, index, alpha, back;
2066
2067 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2068 (y * vinfo.v_rowbytes) +
2069 (x * 4));
2070
2071 for( line = 0; line < height; line++) {
2072 for( col = 0; col < width; col++) {
2073 if( dataPtr != 0) {
2074 index = *dataPtr++;
2075 index *= 3;
2076 }
2077
2078 if( alphaPtr && backPtr) {
2079
2080 alpha = *alphaPtr++;
2081 data = 0;
2082 if( dataPtr != 0) {
2083 if( vc_clut[index + 0] > alpha)
2084 data |= ((vc_clut[index + 0] - alpha) << 16);
2085 if( vc_clut[index + 1] > alpha)
2086 data |= ((vc_clut[index + 1] - alpha) << 8);
2087 if( vc_clut[index + 2] > alpha)
2088 data |= ((vc_clut[index + 2] - alpha));
2089 }
2090
2091 if( save) {
2092 back = *(dst + col);
2093 if ( !static_alpha)
2094 *backPtr++ = back;
2095 back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2096 | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
2097 if ( static_alpha)
2098 *backPtr++ = back;
2099 } else {
2100 back = *backPtr++;
2101 if ( !static_alpha) {
2102 back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2103 | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
2104 }
2105 }
2106
2107 data += back;
2108
2109 } else
2110 if( dataPtr != 0) {
2111 data = (vc_clut[index + 0] << 16)
2112 | (vc_clut[index + 1] << 8)
2113 | (vc_clut[index + 2]);
2114 }
2115
2116 *(dst + col) = data;
2117 }
2118 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2119 }
2120 }
2121
2122 void
2123 draw_panic_dialog( void )
2124 {
2125 int pd_x,pd_y, iconx, icony, tx_line, tx_col;
2126 int line_width = 1;
2127 int f1, f2, d1, d2, d3, rem;
2128 char *pair = "ff";
2129 int count = 0;
2130 char digit;
2131 int nibble;
2132 char colon = ':';
2133 char dot = '.';
2134 struct ether_addr kdp_mac_addr = kdp_get_mac_addr();
2135 unsigned int ip_addr = kdp_get_ip_address();
2136
2137
2138 if (!panicDialogDrawn)
2139 {
2140 if ( !logPanicDataToScreen )
2141 {
2142
2143 /* dim the screen 50% before putting up panic dialog */
2144 dim_screen();
2145
2146 /* set up to draw background box */
2147 pd_x = (vinfo.v_width/2) - panic_dialog.pd_width/2;
2148 pd_y = (vinfo.v_height/2) - panic_dialog.pd_height/2;
2149
2150 /* draw image */
2151 panic_blit_rect( pd_x, pd_y, panic_dialog.pd_width, panic_dialog.pd_height, 0, (unsigned char*) panic_dialog.image_pixel_data);
2152
2153 /* offset for mac address text */
2154 mac_addr_digit_x = (vinfo.v_width/2) - 130; /* use 62 if no ip */
2155 mac_addr_digit_y = (vinfo.v_height/2) + panic_dialog.pd_height/2 - 20;
2156
2157 if(kdp_mac_addr.ether_addr_octet[0] || kdp_mac_addr.ether_addr_octet[1]|| kdp_mac_addr.ether_addr_octet[2]
2158 || kdp_mac_addr.ether_addr_octet[3] || kdp_mac_addr.ether_addr_octet[4] || kdp_mac_addr.ether_addr_octet[5])
2159 {
2160 /* blit the digits for mac address */
2161 for (count = 0; count < 6; count++ )
2162 {
2163 nibble = (kdp_mac_addr.ether_addr_octet[count] & 0xf0) >> 4;
2164 digit = nibble < 10 ? nibble + '0':nibble - 10 + 'a';
2165 blit_digit(digit);
2166
2167 nibble = kdp_mac_addr.ether_addr_octet[count] & 0xf;
2168 digit = nibble < 10 ? nibble + '0':nibble - 10 + 'a';
2169 blit_digit(digit);
2170 if( count < 5 )
2171 blit_digit( colon );
2172 }
2173 }
2174 else /* blit the ff's */
2175 {
2176 for( count = 0; count < 6; count++ )
2177 {
2178 digit = pair[0];
2179 blit_digit(digit);
2180 digit = pair[1];
2181 blit_digit(digit);
2182 if( count < 5 )
2183 blit_digit( colon );
2184 }
2185 }
2186 /* now print the ip address */
2187 mac_addr_digit_x = (vinfo.v_width/2) + 10;
2188 if(ip_addr != 0)
2189 {
2190 /* blit the digits for ip address */
2191 for (count = 0; count < 4; count++ )
2192 {
2193 nibble = (ip_addr & 0xff000000 ) >> 24;
2194
2195 d3 = (nibble % 0xa) + '0';
2196 nibble = nibble/0xa;
2197 d2 = (nibble % 0xa) + '0';
2198 nibble = nibble /0xa;
2199 d1 = (nibble % 0xa) + '0';
2200
2201 if( d1 ) blit_digit(d1);
2202 blit_digit(d2);
2203 blit_digit(d3);
2204 if( count < 3 )
2205 blit_digit(dot);
2206
2207 d1= d2 = d3 = 0;
2208 ip_addr = ip_addr << 8;
2209 }
2210 }
2211 }
2212 }
2213 panicDialogDrawn = TRUE;
2214
2215 }
2216
2217
2218 static void
2219 blit_digit( int digit )
2220 {
2221 switch( digit )
2222 {
2223 case '0': {
2224 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_0.num_w, num_0.num_h, 255, (unsigned char*) num_0.num_pixel_data);
2225 mac_addr_digit_x = mac_addr_digit_x + num_0.num_w - 1;
2226 break;
2227 }
2228 case '1': {
2229 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_1.num_w, num_1.num_h, 255, (unsigned char*) num_1.num_pixel_data);
2230 mac_addr_digit_x = mac_addr_digit_x + num_1.num_w ;
2231 break;
2232 }
2233 case '2': {
2234 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_2.num_w, num_2.num_h, 255, (unsigned char*) num_2.num_pixel_data);
2235 mac_addr_digit_x = mac_addr_digit_x + num_2.num_w ;
2236 break;
2237 }
2238 case '3': {
2239 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_3.num_w, num_3.num_h, 255, (unsigned char*) num_3.num_pixel_data);
2240 mac_addr_digit_x = mac_addr_digit_x + num_3.num_w ;
2241 break;
2242 }
2243 case '4': {
2244 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_4.num_w, num_4.num_h, 255, (unsigned char*) num_4.num_pixel_data);
2245 mac_addr_digit_x = mac_addr_digit_x + num_4.num_w ;
2246 break;
2247 }
2248 case '5': {
2249 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_5.num_w, num_5.num_h, 255, (unsigned char*) num_5.num_pixel_data);
2250 mac_addr_digit_x = mac_addr_digit_x + num_5.num_w ;
2251 break;
2252 }
2253 case '6': {
2254 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_6.num_w, num_6.num_h, 255, (unsigned char*) num_6.num_pixel_data);
2255 mac_addr_digit_x = mac_addr_digit_x + num_6.num_w ;
2256 break;
2257 }
2258 case '7': {
2259 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_7.num_w, num_7.num_h, 255, (unsigned char*) num_7.num_pixel_data);
2260 mac_addr_digit_x = mac_addr_digit_x + num_7.num_w ;
2261 break;
2262 }
2263 case '8': {
2264 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_8.num_w, num_8.num_h, 255, (unsigned char*) num_8.num_pixel_data);
2265 mac_addr_digit_x = mac_addr_digit_x + num_8.num_w ;
2266 break;
2267 }
2268 case '9': {
2269 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_9.num_w, num_9.num_h, 255, (unsigned char*) num_9.num_pixel_data);
2270 mac_addr_digit_x = mac_addr_digit_x + num_9.num_w ;
2271 break;
2272 }
2273 case 'a': {
2274 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_a.num_w, num_a.num_h, 255, (unsigned char*) num_a.num_pixel_data);
2275 mac_addr_digit_x = mac_addr_digit_x + num_a.num_w ;
2276 break;
2277 }
2278 case 'b': {
2279 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_b.num_w, num_b.num_h, 255, (unsigned char*) num_b.num_pixel_data);
2280 mac_addr_digit_x = mac_addr_digit_x + num_b.num_w ;
2281 break;
2282 }
2283 case 'c': {
2284 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_c.num_w, num_c.num_h, 255, (unsigned char*) num_c.num_pixel_data);
2285 mac_addr_digit_x = mac_addr_digit_x + num_c.num_w ;
2286 break;
2287 }
2288 case 'd': {
2289 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_d.num_w, num_d.num_h, 255, (unsigned char*) num_d.num_pixel_data);
2290 mac_addr_digit_x = mac_addr_digit_x + num_d.num_w ;
2291 break;
2292 }
2293 case 'e': {
2294 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_e.num_w, num_e.num_h, 255, (unsigned char*) num_e.num_pixel_data);
2295 mac_addr_digit_x = mac_addr_digit_x + num_e.num_w ;
2296 break;
2297 }
2298 case 'f': {
2299 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_f.num_w, num_f.num_h, 255, (unsigned char*) num_f.num_pixel_data);
2300 mac_addr_digit_x = mac_addr_digit_x + num_f.num_w ;
2301 break;
2302 }
2303 case ':': {
2304 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y, num_colon.num_w, num_colon.num_h, 255, (unsigned char*) num_colon.num_pixel_data);
2305 mac_addr_digit_x = mac_addr_digit_x + num_colon.num_w;
2306 break;
2307 }
2308 case '.': {
2309 panic_blit_rect( mac_addr_digit_x, mac_addr_digit_y + (num_colon.num_h/2), num_colon.num_w, num_colon.num_h/2, 255, (unsigned char*) num_colon.num_pixel_data);
2310 mac_addr_digit_x = mac_addr_digit_x + num_colon.num_w;
2311 break;
2312 }
2313 default:
2314 break;
2315
2316 }
2317 }
2318
2319 static void
2320 panic_blit_rect( unsigned int x, unsigned int y,
2321 unsigned int width, unsigned int height,
2322 int transparent, unsigned char * dataPtr )
2323 {
2324 if(!vinfo.v_depth)
2325 return;
2326
2327 switch( vinfo.v_depth) {
2328 case 8:
2329 panic_blit_rect_8( x, y, width, height, transparent, dataPtr);
2330 break;
2331 case 16:
2332 panic_blit_rect_16( x, y, width, height, transparent, dataPtr);
2333 break;
2334 case 32:
2335 panic_blit_rect_32( x, y, width, height, transparent, dataPtr);
2336 break;
2337 }
2338 }
2339
2340 /* panic_blit_rect_8 is not tested and probably doesn't draw correctly.
2341 it really needs a clut to use
2342 */
2343 static void
2344 panic_blit_rect_8( unsigned int x, unsigned int y,
2345 unsigned int width, unsigned int height,
2346 int transparent, unsigned char * dataPtr )
2347 {
2348 volatile unsigned int * dst;
2349 int line, col;
2350 unsigned int pixelR, pixelG, pixelB;
2351
2352 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2353 (y * vinfo.v_rowbytes) +
2354 x);
2355
2356 for( line = 0; line < height; line++) {
2357 for( col = 0; col < width; col++) {
2358 pixelR = *dataPtr++;
2359 pixelG = *dataPtr++;
2360 pixelB = *dataPtr++;
2361 if(( pixelR != transparent) || (pixelG != transparent) || (pixelB != transparent))
2362 {
2363 *(dst + col) = ((19595 * pixelR +
2364 38470 * pixelG +
2365 7471 * pixelB ) / 65536);
2366 }
2367
2368 }
2369 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2370 }
2371 }
2372
2373 /* panic_blit_rect_16 draws adequately. It would be better if it had a clut
2374 to use instead of scaling the 32bpp color values.
2375
2376 panic_blit_rect_16 decodes the RLE encoded image data on the fly, scales it down
2377 to 16bpp, and fills in each of the three pixel values (RGB) for each pixel
2378 and writes it to the screen.
2379
2380 */
2381 static void
2382 panic_blit_rect_16( unsigned int x, unsigned int y,
2383 unsigned int width, unsigned int height,
2384 int transparent, unsigned char * dataPtr )
2385 {
2386 volatile unsigned int * dst;
2387 int line, value, total = 0;
2388 unsigned int quantity, tmp, pixel;
2389 int pix_pos = 2;
2390 int w = width / 2;
2391 boolean_t secondTime = 0;
2392 int pix_incr = 0;
2393
2394
2395 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2396 (y * vinfo.v_rowbytes) +
2397 (x * 2));
2398
2399 /*
2400 *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
2401 | ( (0xf8 & (vc_clut[data + 1])) << 2)
2402 | ( (0xf8 & (vc_clut[data + 2])) >> 3);
2403
2404 */
2405 for( line = 0; line < height; line++)
2406 {
2407 while ( total < width )
2408 {
2409 quantity = *dataPtr++;
2410 value = *dataPtr++;
2411 value = (0x1f * value)/255;
2412 while( quantity > 0 )
2413 {
2414 switch( pix_pos )
2415 {
2416 case 2: /* red */
2417 {
2418 tmp |= (value << 10) & 0x7c00;
2419 // tmp |= (value & 0xf8) << 7;
2420 quantity--;
2421 pix_pos--;
2422 break;
2423 }
2424 case 1: /* green */
2425 {
2426 tmp |= (value << 5) & 0x3e0;
2427 // tmp |= (value & 0xf8) << 2;
2428 quantity--;
2429 pix_pos--;
2430 break;
2431 }
2432 default: /* blue */
2433 {
2434 tmp |= value & 0x1f;
2435 // tmp |= (value & 0xf8) >> 3;
2436 total++;
2437 quantity--;
2438 pix_pos = 2;
2439 if( secondTime )
2440 {
2441 pixel |= tmp;
2442 secondTime = 0;
2443 *(dst + pix_incr++) = pixel;
2444 tmp = 0;
2445 pixel = 0;
2446 }
2447 else
2448 {
2449 pixel = tmp << 16;
2450 secondTime = 1;
2451 }
2452 break;
2453 }
2454 }
2455 }
2456 }
2457 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2458 total = 0;
2459 pix_incr = 0;
2460 }
2461 }
2462
2463 /*
2464 panic_blit_rect_32 decodes the RLE encoded image data on the fly, and fills
2465 in each of the three pixel values (RGB) for each pixel and writes it to the
2466 screen.
2467 */
2468 static void
2469 panic_blit_rect_32( unsigned int x, unsigned int y,
2470 unsigned int width, unsigned int height,
2471 int transparent, unsigned char * dataPtr )
2472 {
2473 volatile unsigned int * dst;
2474 int line, total = 0;
2475 unsigned int value, quantity, tmp;
2476 int pix_pos = 2;
2477
2478 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
2479 (y * vinfo.v_rowbytes) +
2480 (x * 4));
2481
2482 for( line = 0; line < height; line++)
2483 {
2484 while ( total < width )
2485 {
2486 quantity = *dataPtr++;
2487 value = *dataPtr++;
2488 while( quantity > 0 )
2489 {
2490 switch( pix_pos )
2491 {
2492 case 2:
2493 {
2494 tmp = value << 16;
2495 quantity--;
2496 pix_pos--;
2497 break;
2498 }
2499 case 1:
2500 {
2501 tmp |= value << 8;
2502 quantity--;
2503 pix_pos--;
2504 break;
2505 }
2506 default:
2507 {
2508 tmp |= value;
2509 *(dst + total) = tmp;
2510 total++;
2511 quantity--;
2512 pix_pos = 2;
2513 break;
2514 }
2515
2516 }
2517 }
2518
2519 }
2520 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2521 total = 0;
2522 }
2523 }
2524
2525 static void
2526 dim_screen(void)
2527 {
2528 if(!vinfo.v_depth)
2529 return;
2530
2531 switch( vinfo.v_depth) {
2532 /*case 8:
2533 dim_screen8();
2534 break;
2535 */
2536 case 16:
2537 dim_screen16();
2538 break;
2539 case 32:
2540 dim_screen32();
2541 break;
2542 }
2543 }
2544
2545 static void
2546 dim_screen16(void)
2547 {
2548 unsigned long *p, *endp, *row;
2549 int linelongs, col;
2550 int rowline, rowlongs;
2551 unsigned long value, tmp;
2552
2553 rowline = vinfo.v_rowscanbytes / 4;
2554 rowlongs = vinfo.v_rowbytes / 4;
2555
2556 p = (unsigned long*) vinfo.v_baseaddr;;
2557 endp = (unsigned long*) vinfo.v_baseaddr;
2558
2559 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
2560 endp += rowlongs * vinfo.v_height;
2561
2562 for (row = p ; row < endp ; row += rowlongs) {
2563 for (col = 0; col < rowline; col++) {
2564 value = *(row+col);
2565 tmp = ((value & 0x7C007C00) >> 1) & 0x3C003C00;
2566 tmp |= ((value & 0x03E003E0) >> 1) & 0x01E001E0;
2567 tmp |= ((value & 0x001F001F) >> 1) & 0x000F000F;
2568 *(row+col) = tmp; //half (dimmed)?
2569 }
2570
2571 }
2572
2573 }
2574
2575 static void
2576 dim_screen32(void)
2577 {
2578 unsigned long *p, *endp, *row;
2579 int linelongs, col;
2580 int rowline, rowlongs;
2581 unsigned long value, tmp;
2582
2583 rowline = vinfo.v_rowscanbytes / 4;
2584 rowlongs = vinfo.v_rowbytes / 4;
2585
2586 p = (unsigned long*) vinfo.v_baseaddr;;
2587 endp = (unsigned long*) vinfo.v_baseaddr;
2588
2589 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
2590 endp += rowlongs * vinfo.v_height;
2591
2592 for (row = p ; row < endp ; row += rowlongs) {
2593 for (col = 0; col < rowline; col++) {
2594 value = *(row+col);
2595 tmp = ((value & 0x00FF0000) >> 1) & 0x007F0000;
2596 tmp |= ((value & 0x0000FF00) >> 1) & 0x00007F00;
2597 tmp |= (value & 0x000000FF) >> 1;
2598 *(row+col) = tmp; //half (dimmed)?
2599 }
2600
2601 }
2602
2603 }
2604
2605 static void vc_blit_rect( unsigned int x, unsigned int y,
2606 unsigned int width, unsigned int height,
2607 const unsigned char * dataPtr,
2608 const unsigned char * alphaPtr,
2609 vm_address_t backBuffer,
2610 boolean_t save, boolean_t static_alpha )
2611 {
2612 if(!vinfo.v_baseaddr)
2613 return;
2614
2615 switch( vinfo.v_depth) {
2616 case 8:
2617 if( vc_clut8 == vc_clut)
2618 vc_blit_rect_8c( x, y, width, height, dataPtr, alphaPtr, (unsigned char *) backBuffer, save, static_alpha );
2619 break;
2620 case 16:
2621 vc_blit_rect_16( x, y, width, height, dataPtr, alphaPtr, (unsigned short *) backBuffer, save, static_alpha );
2622 break;
2623 case 32:
2624 vc_blit_rect_32( x, y, width, height, dataPtr, alphaPtr, (unsigned int *) backBuffer, save, static_alpha );
2625 break;
2626 }
2627 }
2628
2629 static void vc_progress_task( void * arg )
2630 {
2631 spl_t s;
2632 int count = (int) arg;
2633 int x, y, width, height;
2634 const unsigned char * data;
2635
2636 s = splhigh();
2637 simple_lock(&vc_forward_lock);
2638
2639 if( vc_progress_enable) {
2640
2641 count++;
2642 if( count >= vc_progress->count)
2643 count = 0;
2644
2645 width = vc_progress->width;
2646 height = vc_progress->height;
2647 x = vc_progress->dx;
2648 y = vc_progress->dy;
2649 data = vc_progress_data;
2650 data += count * width * height;
2651 if( 1 & vc_progress->flags) {
2652 x += ((vinfo.v_width - width) / 2);
2653 y += ((vinfo.v_height - height) / 2);
2654 }
2655 vc_blit_rect( x, y, width, height,
2656 NULL, data, vc_saveunder,
2657 vc_needsave, (0 == (4 & vc_progress->flags)) );
2658 vc_needsave = FALSE;
2659
2660 timeout( vc_progress_task, (void *) count,
2661 vc_progress_tick );
2662 }
2663 simple_unlock(&vc_forward_lock);
2664 splx(s);
2665 }
2666
2667 void vc_display_icon( vc_progress_element * desc,
2668 const unsigned char * data )
2669 {
2670 int x, y, width, height;
2671
2672 if( vc_acquired && vc_graphics_mode && vc_clut) {
2673
2674 width = desc->width;
2675 height = desc->height;
2676 x = desc->dx;
2677 y = desc->dy;
2678 if( 1 & desc->flags) {
2679 x += ((vinfo.v_width - width) / 2);
2680 y += ((vinfo.v_height - height) / 2);
2681 }
2682 vc_blit_rect( x, y, width, height, data, NULL, (vm_address_t) NULL, FALSE, TRUE );
2683 }
2684 }
2685
2686 static boolean_t ignore_first_enable = TRUE;
2687
2688 static boolean_t
2689 vc_progress_set( boolean_t enable, unsigned int initial_tick )
2690 {
2691 spl_t s;
2692 vm_address_t saveBuf = 0;
2693 vm_size_t saveLen = 0;
2694 unsigned int count;
2695 unsigned int index;
2696 unsigned char data8;
2697 unsigned short data16;
2698 unsigned short * buf16;
2699 unsigned int data32;
2700 unsigned int * buf32;
2701
2702 if( !vc_progress)
2703 return( FALSE );
2704
2705 if( enable & ignore_first_enable) {
2706 enable = FALSE;
2707 ignore_first_enable = FALSE;
2708 }
2709
2710 if( enable) {
2711 saveLen = vc_progress->width * vc_progress->height * vinfo.v_depth / 8;
2712 saveBuf = kalloc( saveLen );
2713
2714 if( !vc_need_clear) switch( vinfo.v_depth) {
2715 case 8 :
2716 for( count = 0; count < 256; count++) {
2717 vc_revclut8[count] = vc_clut[0x01 * 3];
2718 data8 = (vc_clut[0x01 * 3] * count + 0x0ff) >> 8;
2719 for( index = 0; index < 256; index++) {
2720 if( (data8 == vc_clut[index * 3 + 0]) &&
2721 (data8 == vc_clut[index * 3 + 1]) &&
2722 (data8 == vc_clut[index * 3 + 2])) {
2723 vc_revclut8[count] = index;
2724 break;
2725 }
2726 }
2727 }
2728 memset( (void *) saveBuf, 0x01, saveLen );
2729 break;
2730
2731 case 16 :
2732 buf16 = (unsigned short *) saveBuf;
2733 data16 = ((vc_clut[0x01 * 3 + 0] & 0xf8) << 7)
2734 | ((vc_clut[0x01 * 3 + 0] & 0xf8) << 2)
2735 | ((vc_clut[0x01 * 3 + 0] & 0xf8) >> 3);
2736 for( count = 0; count < saveLen / 2; count++)
2737 buf16[count] = data16;
2738 break;
2739
2740 case 32 :
2741 buf32 = (unsigned int *) saveBuf;
2742 data32 = ((vc_clut[0x01 * 3 + 0] & 0xff) << 16)
2743 | ((vc_clut[0x01 * 3 + 1] & 0xff) << 8)
2744 | ((vc_clut[0x01 * 3 + 2] & 0xff) << 0);
2745 for( count = 0; count < saveLen / 4; count++)
2746 buf32[count] = data32;
2747 break;
2748 }
2749 }
2750
2751 s = splhigh();
2752 simple_lock(&vc_forward_lock);
2753
2754 if( vc_progress_enable != enable) {
2755 vc_progress_enable = enable;
2756 if( enable) {
2757 vc_needsave = vc_need_clear;
2758 vc_saveunder = saveBuf;
2759 vc_saveunder_len = saveLen;
2760 saveBuf = 0;
2761 saveLen = 0;
2762 timeout(vc_progress_task, (void *) 0,
2763 initial_tick );
2764 } else {
2765 if( vc_saveunder) {
2766 saveBuf = vc_saveunder;
2767 saveLen = vc_saveunder_len;
2768 vc_saveunder = 0;
2769 vc_saveunder_len = 0;
2770 }
2771 untimeout( vc_progress_task, (void *) 0 );
2772 }
2773 }
2774
2775 if( !enable) {
2776 vc_forward_buffer_size = 0;
2777 untimeout((timeout_fcn_t)vc_flush_forward_buffer, (void *)0);
2778
2779 /* Spin if the flush is in progress */
2780 while (vc_forward_buffer_busy) {
2781 simple_unlock(&vc_forward_lock);
2782 splx(s);
2783 /* wait */
2784 s = splhigh();
2785 simple_lock(&vc_forward_lock);
2786 vc_forward_buffer_size = 0;
2787 }
2788 }
2789
2790 simple_unlock(&vc_forward_lock);
2791 splx(s);
2792
2793 if( saveBuf)
2794 kfree( saveBuf, saveLen );
2795
2796 return( TRUE );
2797 }
2798
2799
2800 boolean_t
2801 vc_progress_initialize( vc_progress_element * desc,
2802 const unsigned char * data,
2803 const unsigned char * clut )
2804 {
2805 if( (!clut) || (!desc) || (!data))
2806 return( FALSE );
2807 vc_clut = clut;
2808 vc_clut8 = clut;
2809
2810 vc_progress = desc;
2811 vc_progress_data = data;
2812 if( 2 & vc_progress->flags)
2813 vc_progress_alpha = vc_progress_data
2814 + vc_progress->count * vc_progress->width * vc_progress->height;
2815 else
2816 vc_progress_alpha = NULL;
2817 vc_progress_tick = vc_progress->time * hz / 1000;
2818
2819 return( TRUE );
2820 }
2821
2822 // FirmwareC.c needs:
2823 Boot_Video boot_video_info;
2824
2825 extern int disableConsoleOutput;
2826
2827 static void vc_clear_screen( void )
2828 {
2829 reversecursor();
2830 vt100_reset();
2831 x = y = 0;
2832 clear_screen(2);
2833 reversecursor();
2834 };
2835
2836 void
2837 initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
2838 {
2839 if( boot_vinfo) {
2840 bcopy( (const void *) boot_vinfo,
2841 (void *) &boot_video_info,
2842 sizeof( boot_video_info));
2843
2844 vinfo.v_name[0] = 0;
2845 vinfo.v_width = boot_vinfo->v_width;
2846 vinfo.v_height = boot_vinfo->v_height;
2847 vinfo.v_depth = boot_vinfo->v_depth;
2848 vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
2849 vinfo.v_physaddr = boot_vinfo->v_baseAddr;
2850 vinfo.v_baseaddr = vinfo.v_physaddr;
2851 vinfo.v_type = 0;
2852
2853 vc_initialize();
2854 #if 0
2855 GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re-initialize GratefulDeb */
2856 #endif
2857 }
2858
2859 switch( op ) {
2860
2861 case kPEGraphicsMode:
2862 vc_graphics_mode = TRUE;
2863 disableConsoleOutput = TRUE;
2864 vc_acquired = TRUE;
2865 break;
2866
2867 case kPETextMode:
2868 vc_graphics_mode = FALSE;
2869 disableConsoleOutput = FALSE;
2870 vc_acquired = TRUE;
2871 vc_clear_screen();
2872 break;
2873
2874 case kPETextScreen:
2875 vc_progress_set( FALSE, 0 );
2876 disableConsoleOutput = FALSE;
2877 if( vc_need_clear) {
2878 vc_need_clear = FALSE;
2879 vc_clear_screen();
2880 }
2881 break;
2882
2883 case kPEEnableScreen:
2884 if( vc_acquired) {
2885 if( vc_graphics_mode)
2886 vc_progress_set( TRUE, vc_progress_tick );
2887 else
2888 vc_clear_screen();
2889 }
2890 break;
2891
2892 case kPEDisableScreen:
2893 vc_progress_set( FALSE, 0 );
2894 break;
2895
2896 case kPEAcquireScreen:
2897 vc_need_clear = (FALSE == vc_acquired);
2898 vc_acquired = TRUE;
2899 vc_progress_set( vc_graphics_mode, vc_need_clear ? 2 * hz : 0 );
2900 disableConsoleOutput = vc_graphics_mode;
2901 if( vc_need_clear && !vc_graphics_mode) {
2902 vc_need_clear = FALSE;
2903 vc_clear_screen();
2904 }
2905 break;
2906
2907 case kPEReleaseScreen:
2908 vc_acquired = FALSE;
2909 vc_progress_set( FALSE, 0 );
2910 vc_clut8 = NULL;
2911 disableConsoleOutput = TRUE;
2912 #if 0
2913 GratefulDebInit(0); /* Stop grateful debugger */
2914 #endif
2915 break;
2916 }
2917 #if 0
2918 if( boot_vinfo) GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re initialize GratefulDeb */
2919 #endif
2920 }