]> git.saurik.com Git - apple/xnu.git/blob - osfmk/console/video_console.c
xnu-792.12.6.tar.gz
[apple/xnu.git] / osfmk / console / video_console.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 /*
31 * @OSF_FREE_COPYRIGHT@
32 *
33 */
34 /*
35 * @APPLE_FREE_COPYRIGHT@
36 */
37 /*
38 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
39 *
40 * Copyright (c) 1988 University of Utah.
41 * Copyright (c) 1990, 1993
42 * The Regents of the University of California. All rights reserved.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 * from: Utah $Hdr: ite.c 1.28 92/12/20$
77 *
78 * @(#)ite.c 8.2 (Berkeley) 1/12/94
79 */
80
81 /*
82 * ite.c
83 *
84 * The ite module handles the system console; that is, stuff printed
85 * by the kernel and by user programs while "desktop" and X aren't
86 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
87 * hence the above copyright.
88 *
89 * -- Brad and Lawrence, June 26th, 1994
90 *
91 */
92
93 #include <vc.h>
94
95 #include <console/video_console.h>
96
97 #include <kern/kern_types.h>
98 #include <kern/kalloc.h>
99 #include <kern/debug.h>
100 #include <kern/lock.h>
101 #include <kern/spl.h>
102 #include <kern/thread_call.h>
103
104 #include <vm/pmap.h>
105 #include <vm/vm_kern.h>
106
107 #include <pexpert/pexpert.h>
108
109 #include "iso_font.c"
110
111 /*
112 * Generic Console (Front-End)
113 * ---------------------------
114 */
115
116 struct vc_info vinfo;
117 /* if panicDialogDesired is true then we use the panic dialog when its */
118 /* allowed otherwise we won't use the panic dialog even if it is allowed */
119 boolean_t panicDialogDesired;
120
121
122 extern int disableConsoleOutput;
123 static boolean_t gc_enabled = FALSE;
124 static boolean_t gc_initialized = FALSE;
125 static boolean_t vm_initialized = FALSE;
126
127 static struct {
128 void (*initialize)(struct vc_info * info);
129 void (*enable)(boolean_t enable);
130 void (*paint_char)(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
131 void (*clear_screen)(int xx, int yy, int top, int bottom, int which);
132 void (*scroll_down)(int num, int top, int bottom);
133 void (*scroll_up)(int num, int top, int bottom);
134 void (*hide_cursor)(int xx, int yy);
135 void (*show_cursor)(int xx, int yy);
136 void (*update_color)(int color, boolean_t fore);
137 } gc_ops;
138
139 static unsigned char * gc_buffer_attributes = NULL;
140 static unsigned char * gc_buffer_characters = NULL;
141 static unsigned char * gc_buffer_colorcodes = NULL;
142 static unsigned long gc_buffer_columns = 0;
143 static unsigned long gc_buffer_rows = 0;
144 static unsigned long gc_buffer_size = 0;
145 decl_simple_lock_data(,gc_buffer_lock)
146
147 /*
148 # Attribute codes:
149 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
150 # Text color codes:
151 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
152 # Background color codes:
153 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
154 */
155
156 #define ATTR_NONE 0
157 #define ATTR_BOLD 1
158 #define ATTR_UNDER 2
159 #define ATTR_REVERSE 4
160
161 #define COLOR_BACKGROUND 0
162 #define COLOR_FOREGROUND 7
163
164 #define COLOR_CODE_GET(code, fore) (((code) & ((fore) ? 0xF0 : 0x0F)) >> ((fore) ? 4 : 0))
165 #define COLOR_CODE_SET(code, color, fore) (((code) & ((fore) ? 0x0F : 0xF0)) | ((color) << ((fore) ? 4 : 0)))
166
167 static unsigned char gc_color_code = 0;
168
169 /* VT100 state: */
170 #define MAXPARS 16
171 static int gc_x = 0, gc_y = 0, gc_savex, gc_savey;
172 static int gc_par[MAXPARS], gc_numpars, gc_hanging_cursor, gc_attr, gc_saveattr;
173
174 /* VT100 tab stops & scroll region */
175 static char gc_tab_stops[255];
176 static int gc_scrreg_top, gc_scrreg_bottom;
177
178 enum { kProgressAcquireDelay = 5 /* secs */ };
179
180 enum vt100state_e {
181 ESnormal, /* Nothing yet */
182 ESesc, /* Got ESC */
183 ESsquare, /* Got ESC [ */
184 ESgetpars, /* About to get or getting the parameters */
185 ESgotpars, /* Finished getting the parameters */
186 ESfunckey, /* Function key */
187 EShash, /* DEC-specific stuff (screen align, etc.) */
188 ESsetG0, /* Specify the G0 character set */
189 ESsetG1, /* Specify the G1 character set */
190 ESask,
191 EScharsize,
192 ESignore /* Ignore this sequence */
193 } gc_vt100state = ESnormal;
194
195 static int gc_wrap_mode = 1, gc_relative_origin = 0;
196 static int gc_charset_select = 0, gc_save_charset_s = 0;
197 static int gc_charset[2] = { 0, 0 };
198 static int gc_charset_save[2] = { 0, 0 };
199
200 static void gc_clear_line(int xx, int yy, int which);
201 static void gc_clear_screen(int xx, int yy, int top, int bottom, int which);
202 static void gc_enable(boolean_t enable);
203 static void gc_hide_cursor(int xx, int yy);
204 static void gc_initialize(struct vc_info * info);
205 static void gc_paint_char(int xx, int yy, unsigned char ch, int attrs);
206 static void gc_putchar(char ch);
207 static void gc_putc_askcmd(unsigned char ch);
208 static void gc_putc_charsetcmd(int charset, unsigned char ch);
209 static void gc_putc_charsizecmd(unsigned char ch);
210 static void gc_putc_esc(unsigned char ch);
211 static void gc_putc_getpars(unsigned char ch);
212 static void gc_putc_gotpars(unsigned char ch);
213 static void gc_putc_normal(unsigned char ch);
214 static void gc_putc_square(unsigned char ch);
215 static void gc_refresh_screen(void);
216 static void gc_reset_screen(void);
217 static void gc_reset_tabs(void);
218 static void gc_reset_vt100(void);
219 static void gc_scroll_down(int num, int top, int bottom);
220 static void gc_scroll_up(int num, int top, int bottom);
221 static void gc_show_cursor(int xx, int yy);
222 static void gc_update_color(int color, boolean_t fore);
223 extern int vcputc(int l, int u, int c);
224
225 static void
226 gc_clear_line(int xx, int yy, int which)
227 {
228 int start, end, i;
229
230 /*
231 * This routine runs extremely slowly. I don't think it's
232 * used all that often, except for To end of line. I'll go
233 * back and speed this up when I speed up the whole vc
234 * module. --LK
235 */
236
237 switch (which) {
238 case 0: /* To end of line */
239 start = xx;
240 end = vinfo.v_columns-1;
241 break;
242 case 1: /* To start of line */
243 start = 0;
244 end = xx;
245 break;
246 case 2: /* Whole line */
247 start = 0;
248 end = vinfo.v_columns-1;
249 break;
250 }
251
252 for (i = start; i <= end; i++) {
253 gc_paint_char(i, yy, ' ', ATTR_NONE);
254 }
255
256 }
257
258 static void
259 gc_clear_screen(int xx, int yy, int top, int bottom, int which)
260 {
261 spl_t s;
262
263 s = splhigh();
264 simple_lock(&gc_buffer_lock);
265
266 if ( xx < gc_buffer_columns && yy < gc_buffer_rows && bottom <= gc_buffer_rows )
267 {
268 unsigned long start, end;
269
270 switch (which) {
271 case 0: /* To end of screen */
272 start = (yy * gc_buffer_columns) + xx;
273 end = (bottom * gc_buffer_columns) - 1;
274 break;
275 case 1: /* To start of screen */
276 start = (top * gc_buffer_columns);
277 end = (yy * gc_buffer_columns) + xx;
278 break;
279 case 2: /* Whole screen */
280 start = (top * gc_buffer_columns);
281 end = (bottom * gc_buffer_columns) - 1;
282 break;
283 }
284
285 memset(gc_buffer_attributes + start, 0x00, end - start + 1);
286 memset(gc_buffer_characters + start, 0x00, end - start + 1);
287 memset(gc_buffer_colorcodes + start, gc_color_code, end - start + 1);
288 }
289
290 simple_unlock(&gc_buffer_lock);
291 splx(s);
292
293 gc_ops.clear_screen(xx, yy, top, bottom, which);
294 }
295
296 static void
297 gc_enable( boolean_t enable )
298 {
299 unsigned char * buffer_attributes;
300 unsigned char * buffer_characters;
301 unsigned char * buffer_colorcodes;
302 unsigned long buffer_columns;
303 unsigned long buffer_rows;
304 unsigned long buffer_size;
305
306 spl_t s;
307
308 if ( enable == FALSE )
309 {
310 disableConsoleOutput = TRUE;
311 gc_enabled = FALSE;
312 gc_ops.enable(FALSE);
313 }
314
315 s = splhigh( );
316 simple_lock( &gc_buffer_lock );
317
318 if ( gc_buffer_size )
319 {
320 buffer_attributes = gc_buffer_attributes;
321 buffer_characters = gc_buffer_characters;
322 buffer_colorcodes = gc_buffer_colorcodes;
323 buffer_size = gc_buffer_size;
324
325 gc_buffer_attributes = NULL;
326 gc_buffer_characters = NULL;
327 gc_buffer_colorcodes = NULL;
328 gc_buffer_columns = 0;
329 gc_buffer_rows = 0;
330 gc_buffer_size = 0;
331
332 simple_unlock( &gc_buffer_lock );
333 splx( s );
334
335 kfree( buffer_attributes, buffer_size );
336 kfree( buffer_characters, buffer_size );
337 kfree( buffer_colorcodes, buffer_size );
338 }
339 else
340 {
341 simple_unlock( &gc_buffer_lock );
342 splx( s );
343 }
344
345 if ( enable )
346 {
347 if ( vm_initialized )
348 {
349 buffer_columns = vinfo.v_columns;
350 buffer_rows = vinfo.v_rows;
351 buffer_size = buffer_columns * buffer_rows;
352
353 if ( buffer_size )
354 {
355 buffer_attributes = (unsigned char *) kalloc( buffer_size );
356 buffer_characters = (unsigned char *) kalloc( buffer_size );
357 buffer_colorcodes = (unsigned char *) kalloc( buffer_size );
358
359 if ( buffer_attributes == NULL ||
360 buffer_characters == NULL ||
361 buffer_colorcodes == NULL )
362 {
363 if ( buffer_attributes ) kfree( buffer_attributes, buffer_size );
364 if ( buffer_characters ) kfree( buffer_characters, buffer_size );
365 if ( buffer_colorcodes ) kfree( buffer_colorcodes, buffer_size );
366
367 buffer_columns = 0;
368 buffer_rows = 0;
369 buffer_size = 0;
370 }
371 else
372 {
373 memset( buffer_attributes, 0x00, buffer_size );
374 memset( buffer_characters, 0x00, buffer_size );
375 memset( buffer_colorcodes, 0x0F, buffer_size );
376 }
377 }
378 }
379
380 s = splhigh( );
381 simple_lock( &gc_buffer_lock );
382
383 gc_buffer_attributes = buffer_attributes;
384 gc_buffer_characters = buffer_characters;
385 gc_buffer_colorcodes = buffer_colorcodes;
386 gc_buffer_columns = buffer_columns;
387 gc_buffer_rows = buffer_rows;
388 gc_buffer_size = buffer_size;
389
390 simple_unlock( &gc_buffer_lock );
391 splx( s );
392
393 gc_reset_screen();
394
395 gc_ops.enable(TRUE);
396 gc_enabled = TRUE;
397 disableConsoleOutput = FALSE;
398 }
399 }
400
401 static void
402 gc_hide_cursor(int xx, int yy)
403 {
404 spl_t s;
405
406 s = splhigh();
407 simple_lock(&gc_buffer_lock);
408
409 if ( xx < gc_buffer_columns && yy < gc_buffer_rows )
410 {
411 unsigned long index = (yy * gc_buffer_columns) + xx;
412 unsigned char attribute = gc_buffer_attributes[index];
413 unsigned char character = gc_buffer_characters[index];
414 unsigned char colorcode = gc_buffer_colorcodes[index];
415 unsigned char colorcodesave = gc_color_code;
416
417 simple_unlock(&gc_buffer_lock);
418 splx(s);
419
420 gc_update_color(COLOR_CODE_GET(colorcode, TRUE ), TRUE );
421 gc_update_color(COLOR_CODE_GET(colorcode, FALSE), FALSE);
422
423 gc_ops.paint_char(xx, yy, character, attribute, 0, 0);
424
425 gc_update_color(COLOR_CODE_GET(colorcodesave, TRUE ), TRUE );
426 gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
427 }
428 else
429 {
430 simple_unlock(&gc_buffer_lock);
431 splx(s);
432
433 gc_ops.hide_cursor(xx, yy);
434 }
435 }
436
437 static void
438 gc_initialize(struct vc_info * info)
439 {
440 if ( gc_initialized == FALSE )
441 {
442 /* Init our lock */
443 simple_lock_init(&gc_buffer_lock, 0);
444
445 gc_initialized = TRUE;
446 }
447
448 gc_ops.initialize(info);
449
450 gc_reset_vt100();
451 gc_x = gc_y = 0;
452 }
453
454 static void
455 gc_paint_char(int xx, int yy, unsigned char ch, int attrs)
456 {
457 spl_t s;
458
459 s = splhigh();
460 simple_lock(&gc_buffer_lock);
461
462 if ( xx < gc_buffer_columns && yy < gc_buffer_rows )
463 {
464 unsigned long index = (yy * gc_buffer_columns) + xx;
465
466 gc_buffer_attributes[index] = attrs;
467 gc_buffer_characters[index] = ch;
468 gc_buffer_colorcodes[index] = gc_color_code;
469 }
470
471 simple_unlock(&gc_buffer_lock);
472 splx(s);
473
474 gc_ops.paint_char(xx, yy, ch, attrs, 0, 0);
475 }
476
477 static void
478 gc_putchar(char ch)
479 {
480 if (!ch) {
481 return; /* ignore null characters */
482 }
483 switch (gc_vt100state) {
484 default:gc_vt100state = ESnormal; /* FALLTHROUGH */
485 case ESnormal:
486 gc_putc_normal(ch);
487 break;
488 case ESesc:
489 gc_putc_esc(ch);
490 break;
491 case ESsquare:
492 gc_putc_square(ch);
493 break;
494 case ESgetpars:
495 gc_putc_getpars(ch);
496 break;
497 case ESgotpars:
498 gc_putc_gotpars(ch);
499 break;
500 case ESask:
501 gc_putc_askcmd(ch);
502 break;
503 case EScharsize:
504 gc_putc_charsizecmd(ch);
505 break;
506 case ESsetG0:
507 gc_putc_charsetcmd(0, ch);
508 break;
509 case ESsetG1:
510 gc_putc_charsetcmd(1, ch);
511 break;
512 }
513
514 if (gc_x >= vinfo.v_columns) {
515 gc_x = vinfo.v_columns - 1;
516 }
517 if (gc_x < 0) {
518 gc_x = 0;
519 }
520 if (gc_y >= vinfo.v_rows) {
521 gc_y = vinfo.v_rows - 1;
522 }
523 if (gc_y < 0) {
524 gc_y = 0;
525 }
526
527 }
528
529 static void
530 gc_putc_askcmd(unsigned char ch)
531 {
532 if (ch >= '0' && ch <= '9') {
533 gc_par[gc_numpars] = (10*gc_par[gc_numpars]) + (ch-'0');
534 return;
535 }
536 gc_vt100state = ESnormal;
537
538 switch (gc_par[0]) {
539 case 6:
540 gc_relative_origin = ch == 'h';
541 break;
542 case 7: /* wrap around mode h=1, l=0*/
543 gc_wrap_mode = ch == 'h';
544 break;
545 default:
546 break;
547 }
548
549 }
550
551 static void
552 gc_putc_charsetcmd(int charset, unsigned char ch)
553 {
554 gc_vt100state = ESnormal;
555
556 switch (ch) {
557 case 'A' :
558 case 'B' :
559 default:
560 gc_charset[charset] = 0;
561 break;
562 case '0' : /* Graphic characters */
563 case '2' :
564 gc_charset[charset] = 0x21;
565 break;
566 }
567
568 }
569
570 static void
571 gc_putc_charsizecmd(unsigned char ch)
572 {
573 gc_vt100state = ESnormal;
574
575 switch (ch) {
576 case '3' :
577 case '4' :
578 case '5' :
579 case '6' :
580 break;
581 case '8' : /* fill 'E's */
582 {
583 int xx, yy;
584 for (yy = 0; yy < vinfo.v_rows; yy++)
585 for (xx = 0; xx < vinfo.v_columns; xx++)
586 gc_paint_char(xx, yy, 'E', ATTR_NONE);
587 }
588 break;
589 }
590
591 }
592
593 static void
594 gc_putc_esc(unsigned char ch)
595 {
596 gc_vt100state = ESnormal;
597
598 switch (ch) {
599 case '[':
600 gc_vt100state = ESsquare;
601 break;
602 case 'c': /* Reset terminal */
603 gc_reset_vt100();
604 gc_clear_screen(gc_x, gc_y, 0, vinfo.v_rows, 2);
605 gc_x = gc_y = 0;
606 break;
607 case 'D': /* Line feed */
608 case 'E':
609 if (gc_y >= gc_scrreg_bottom -1) {
610 gc_scroll_up(1, gc_scrreg_top, gc_scrreg_bottom);
611 gc_y = gc_scrreg_bottom - 1;
612 } else {
613 gc_y++;
614 }
615 if (ch == 'E') gc_x = 0;
616 break;
617 case 'H': /* Set tab stop */
618 gc_tab_stops[gc_x] = 1;
619 break;
620 case 'M': /* Cursor up */
621 if (gc_y <= gc_scrreg_top) {
622 gc_scroll_down(1, gc_scrreg_top, gc_scrreg_bottom);
623 gc_y = gc_scrreg_top;
624 } else {
625 gc_y--;
626 }
627 break;
628 case '>':
629 gc_reset_vt100();
630 break;
631 case '7': /* Save cursor */
632 gc_savex = gc_x;
633 gc_savey = gc_y;
634 gc_saveattr = gc_attr;
635 gc_save_charset_s = gc_charset_select;
636 gc_charset_save[0] = gc_charset[0];
637 gc_charset_save[1] = gc_charset[1];
638 break;
639 case '8': /* Restore cursor */
640 gc_x = gc_savex;
641 gc_y = gc_savey;
642 gc_attr = gc_saveattr;
643 gc_charset_select = gc_save_charset_s;
644 gc_charset[0] = gc_charset_save[0];
645 gc_charset[1] = gc_charset_save[1];
646 break;
647 case 'Z': /* return terminal ID */
648 break;
649 case '#': /* change characters height */
650 gc_vt100state = EScharsize;
651 break;
652 case '(':
653 gc_vt100state = ESsetG0;
654 break;
655 case ')': /* character set sequence */
656 gc_vt100state = ESsetG1;
657 break;
658 case '=':
659 break;
660 default:
661 /* Rest not supported */
662 break;
663 }
664
665 }
666
667 static void
668 gc_putc_getpars(unsigned char ch)
669 {
670 if (ch == '?') {
671 gc_vt100state = ESask;
672 return;
673 }
674 if (ch == '[') {
675 gc_vt100state = ESnormal;
676 /* Not supported */
677 return;
678 }
679 if (ch == ';' && gc_numpars < MAXPARS - 1) {
680 gc_numpars++;
681 } else
682 if (ch >= '0' && ch <= '9') {
683 gc_par[gc_numpars] *= 10;
684 gc_par[gc_numpars] += ch - '0';
685 } else {
686 gc_numpars++;
687 gc_vt100state = ESgotpars;
688 gc_putc_gotpars(ch);
689 }
690 }
691
692 static void
693 gc_putc_gotpars(unsigned char ch)
694 {
695 int i;
696
697 if (ch < ' ') {
698 /* special case for vttest for handling cursor
699 movement in escape sequences */
700 gc_putc_normal(ch);
701 gc_vt100state = ESgotpars;
702 return;
703 }
704 gc_vt100state = ESnormal;
705 switch (ch) {
706 case 'A': /* Up */
707 gc_y -= gc_par[0] ? gc_par[0] : 1;
708 if (gc_y < gc_scrreg_top)
709 gc_y = gc_scrreg_top;
710 break;
711 case 'B': /* Down */
712 gc_y += gc_par[0] ? gc_par[0] : 1;
713 if (gc_y >= gc_scrreg_bottom)
714 gc_y = gc_scrreg_bottom - 1;
715 break;
716 case 'C': /* Right */
717 gc_x += gc_par[0] ? gc_par[0] : 1;
718 if (gc_x >= vinfo.v_columns)
719 gc_x = vinfo.v_columns-1;
720 break;
721 case 'D': /* Left */
722 gc_x -= gc_par[0] ? gc_par[0] : 1;
723 if (gc_x < 0)
724 gc_x = 0;
725 break;
726 case 'H': /* Set cursor position */
727 case 'f':
728 gc_x = gc_par[1] ? gc_par[1] - 1 : 0;
729 gc_y = gc_par[0] ? gc_par[0] - 1 : 0;
730 if (gc_relative_origin)
731 gc_y += gc_scrreg_top;
732 gc_hanging_cursor = 0;
733 break;
734 case 'X': /* clear p1 characters */
735 if (gc_numpars) {
736 int i;
737 for (i = gc_x; i < gc_x + gc_par[0]; i++)
738 gc_paint_char(i, gc_y, ' ', ATTR_NONE);
739 }
740 break;
741 case 'J': /* Clear part of screen */
742 gc_clear_screen(gc_x, gc_y, 0, vinfo.v_rows, gc_par[0]);
743 break;
744 case 'K': /* Clear part of line */
745 gc_clear_line(gc_x, gc_y, gc_par[0]);
746 break;
747 case 'g': /* tab stops */
748 switch (gc_par[0]) {
749 case 1:
750 case 2: /* reset tab stops */
751 /* gc_reset_tabs(); */
752 break;
753 case 3: /* Clear every tabs */
754 {
755 int i;
756
757 for (i = 0; i <= vinfo.v_columns; i++)
758 gc_tab_stops[i] = 0;
759 }
760 break;
761 case 0:
762 gc_tab_stops[gc_x] = 0;
763 break;
764 }
765 break;
766 case 'm': /* Set attribute */
767 for (i = 0; i < gc_numpars; i++) {
768 switch (gc_par[i]) {
769 case 0:
770 gc_attr = ATTR_NONE;
771 gc_update_color(COLOR_BACKGROUND, FALSE);
772 gc_update_color(COLOR_FOREGROUND, TRUE );
773 break;
774 case 1:
775 gc_attr |= ATTR_BOLD;
776 break;
777 case 4:
778 gc_attr |= ATTR_UNDER;
779 break;
780 case 7:
781 gc_attr |= ATTR_REVERSE;
782 break;
783 case 22:
784 gc_attr &= ~ATTR_BOLD;
785 break;
786 case 24:
787 gc_attr &= ~ATTR_UNDER;
788 break;
789 case 27:
790 gc_attr &= ~ATTR_REVERSE;
791 break;
792 case 5:
793 case 25: /* blink/no blink */
794 break;
795 default:
796 if (gc_par[i] >= 30 && gc_par[i] <= 37)
797 gc_update_color(gc_par[i] - 30, TRUE);
798 if (gc_par[i] >= 40 && gc_par[i] <= 47)
799 gc_update_color(gc_par[i] - 40, FALSE);
800 break;
801 }
802 }
803 break;
804 case 'r': /* Set scroll region */
805 gc_x = gc_y = 0;
806 /* ensure top < bottom, and both within limits */
807 if ((gc_numpars > 0) && (gc_par[0] < vinfo.v_rows)) {
808 gc_scrreg_top = gc_par[0] ? gc_par[0] - 1 : 0;
809 if (gc_scrreg_top < 0)
810 gc_scrreg_top = 0;
811 } else {
812 gc_scrreg_top = 0;
813 }
814 if ((gc_numpars > 1) && (gc_par[1] <= vinfo.v_rows) && (gc_par[1] > gc_par[0])) {
815 gc_scrreg_bottom = gc_par[1];
816 if (gc_scrreg_bottom > vinfo.v_rows)
817 gc_scrreg_bottom = vinfo.v_rows;
818 } else {
819 gc_scrreg_bottom = vinfo.v_rows;
820 }
821 if (gc_relative_origin)
822 gc_y = gc_scrreg_top;
823 break;
824 }
825
826 }
827
828 static void
829 gc_putc_normal(unsigned char ch)
830 {
831 switch (ch) {
832 case '\a': /* Beep */
833 break;
834 case 127: /* Delete */
835 case '\b': /* Backspace */
836 if (gc_hanging_cursor) {
837 gc_hanging_cursor = 0;
838 } else
839 if (gc_x > 0) {
840 gc_x--;
841 }
842 break;
843 case '\t': /* Tab */
844 while (gc_x < vinfo.v_columns && !gc_tab_stops[++gc_x]);
845 if (gc_x >= vinfo.v_columns)
846 gc_x = vinfo.v_columns-1;
847 break;
848 case 0x0b:
849 case 0x0c:
850 case '\n': /* Line feed */
851 if (gc_y >= gc_scrreg_bottom -1 ) {
852 gc_scroll_up(1, gc_scrreg_top, gc_scrreg_bottom);
853 gc_y = gc_scrreg_bottom - 1;
854 } else {
855 gc_y++;
856 }
857 break;
858 case '\r': /* Carriage return */
859 gc_x = 0;
860 gc_hanging_cursor = 0;
861 break;
862 case 0x0e: /* Select G1 charset (Control-N) */
863 gc_charset_select = 1;
864 break;
865 case 0x0f: /* Select G0 charset (Control-O) */
866 gc_charset_select = 0;
867 break;
868 case 0x18 : /* CAN : cancel */
869 case 0x1A : /* like cancel */
870 /* well, i do nothing here, may be later */
871 break;
872 case '\033': /* Escape */
873 gc_vt100state = ESesc;
874 gc_hanging_cursor = 0;
875 break;
876 default:
877 if (ch >= ' ') {
878 if (gc_hanging_cursor) {
879 gc_x = 0;
880 if (gc_y >= gc_scrreg_bottom -1 ) {
881 gc_scroll_up(1, gc_scrreg_top, gc_scrreg_bottom);
882 gc_y = gc_scrreg_bottom - 1;
883 } else {
884 gc_y++;
885 }
886 gc_hanging_cursor = 0;
887 }
888 gc_paint_char(gc_x, gc_y, (ch >= 0x60 && ch <= 0x7f) ? ch + gc_charset[gc_charset_select]
889 : ch, gc_attr);
890 if (gc_x == vinfo.v_columns - 1) {
891 gc_hanging_cursor = gc_wrap_mode;
892 } else {
893 gc_x++;
894 }
895 }
896 break;
897 }
898
899 }
900
901 static void
902 gc_putc_square(unsigned char ch)
903 {
904 int i;
905
906 for (i = 0; i < MAXPARS; i++) {
907 gc_par[i] = 0;
908 }
909
910 gc_numpars = 0;
911 gc_vt100state = ESgetpars;
912
913 gc_putc_getpars(ch);
914
915 }
916
917 static void
918 gc_refresh_screen(void)
919 {
920 spl_t s;
921
922 s = splhigh();
923 simple_lock(&gc_buffer_lock);
924
925 if ( gc_buffer_size )
926 {
927 unsigned char colorcodesave = gc_color_code;
928 unsigned long column, row;
929 unsigned long index;
930
931 for ( index = 0, row = 0 ; row < gc_buffer_rows ; row++ )
932 {
933 for ( column = 0 ; column < gc_buffer_columns ; index++, column++ )
934 {
935 if ( gc_buffer_colorcodes[index] != gc_color_code )
936 {
937 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index], TRUE ), TRUE );
938 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index], FALSE), FALSE);
939 }
940
941 gc_ops.paint_char(column, row, gc_buffer_characters[index], gc_buffer_attributes[index], 0, 0);
942 }
943 }
944
945 if ( colorcodesave != gc_color_code )
946 {
947 gc_update_color(COLOR_CODE_GET(colorcodesave, TRUE ), TRUE );
948 gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
949 }
950 }
951
952 simple_unlock(&gc_buffer_lock);
953 splx(s);
954 }
955
956 static void
957 gc_reset_screen(void)
958 {
959 gc_hide_cursor(gc_x, gc_y);
960 gc_reset_vt100();
961 gc_x = gc_y = 0;
962 gc_clear_screen(gc_x, gc_y, 0, vinfo.v_rows, 2);
963 gc_show_cursor(gc_x, gc_y);
964 }
965
966 static void
967 gc_reset_tabs(void)
968 {
969 int i;
970
971 for (i = 0; i<= vinfo.v_columns; i++) {
972 gc_tab_stops[i] = ((i % 8) == 0);
973 }
974
975 }
976
977 static void
978 gc_reset_vt100(void)
979 {
980 gc_reset_tabs();
981 gc_scrreg_top = 0;
982 gc_scrreg_bottom = vinfo.v_rows;
983 gc_attr = ATTR_NONE;
984 gc_charset[0] = gc_charset[1] = 0;
985 gc_charset_select = 0;
986 gc_wrap_mode = 1;
987 gc_relative_origin = 0;
988 gc_update_color(COLOR_BACKGROUND, FALSE);
989 gc_update_color(COLOR_FOREGROUND, TRUE);
990 }
991
992 static void
993 gc_scroll_down(int num, int top, int bottom)
994 {
995 spl_t s;
996
997 s = splhigh();
998 simple_lock(&gc_buffer_lock);
999
1000 if ( bottom <= gc_buffer_rows )
1001 {
1002 unsigned char colorcodesave = gc_color_code;
1003 unsigned long column, row;
1004 unsigned long index, jump;
1005
1006 jump = num * gc_buffer_columns;
1007
1008 for ( row = bottom - 1 ; row >= top + num ; row-- )
1009 {
1010 index = row * gc_buffer_columns;
1011
1012 for ( column = 0 ; column < gc_buffer_columns ; index++, column++ )
1013 {
1014 if ( gc_buffer_attributes[index] != gc_buffer_attributes[index - jump] ||
1015 gc_buffer_characters[index] != gc_buffer_characters[index - jump] ||
1016 gc_buffer_colorcodes[index] != gc_buffer_colorcodes[index - jump] )
1017 {
1018 if ( gc_color_code != gc_buffer_colorcodes[index - jump] )
1019 {
1020 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index - jump], TRUE ), TRUE );
1021 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index - jump], FALSE), FALSE);
1022 }
1023
1024 if ( gc_buffer_colorcodes[index] != gc_buffer_colorcodes[index - jump] )
1025 {
1026 gc_ops.paint_char( /* xx */ column,
1027 /* yy */ row,
1028 /* ch */ gc_buffer_characters[index - jump],
1029 /* attrs */ gc_buffer_attributes[index - jump],
1030 /* ch_previous */ 0,
1031 /* attrs_previous */ 0 );
1032 }
1033 else
1034 {
1035 gc_ops.paint_char( /* xx */ column,
1036 /* yy */ row,
1037 /* ch */ gc_buffer_characters[index - jump],
1038 /* attrs */ gc_buffer_attributes[index - jump],
1039 /* ch_previous */ gc_buffer_characters[index],
1040 /* attrs_previous */ gc_buffer_attributes[index] );
1041 }
1042
1043 gc_buffer_attributes[index] = gc_buffer_attributes[index - jump];
1044 gc_buffer_characters[index] = gc_buffer_characters[index - jump];
1045 gc_buffer_colorcodes[index] = gc_buffer_colorcodes[index - jump];
1046 }
1047 }
1048 }
1049
1050 if ( colorcodesave != gc_color_code )
1051 {
1052 gc_update_color(COLOR_CODE_GET(colorcodesave, TRUE ), TRUE );
1053 gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
1054 }
1055
1056 simple_unlock(&gc_buffer_lock);
1057 splx(s);
1058 }
1059 else
1060 {
1061 simple_unlock(&gc_buffer_lock);
1062 splx(s);
1063
1064 gc_ops.scroll_down(num, top, bottom);
1065 }
1066
1067 /* Now set the freed up lines to the background colour */
1068
1069 gc_clear_screen(vinfo.v_columns - 1, top + num - 1, top, bottom, 1);
1070 }
1071
1072 static void
1073 gc_scroll_up(int num, int top, int bottom)
1074 {
1075 spl_t s;
1076
1077 s = splhigh();
1078 simple_lock(&gc_buffer_lock);
1079
1080 if ( bottom <= gc_buffer_rows )
1081 {
1082 unsigned char colorcodesave = gc_color_code;
1083 unsigned long column, row;
1084 unsigned long index, jump;
1085
1086 jump = num * gc_buffer_columns;
1087
1088 for ( row = top ; row < bottom - num ; row++ )
1089 {
1090 index = row * gc_buffer_columns;
1091
1092 for ( column = 0 ; column < gc_buffer_columns ; index++, column++ )
1093 {
1094 if ( gc_buffer_attributes[index] != gc_buffer_attributes[index + jump] ||
1095 gc_buffer_characters[index] != gc_buffer_characters[index + jump] ||
1096 gc_buffer_colorcodes[index] != gc_buffer_colorcodes[index + jump] )
1097 {
1098 if ( gc_color_code != gc_buffer_colorcodes[index + jump] )
1099 {
1100 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index + jump], TRUE ), TRUE );
1101 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index + jump], FALSE), FALSE);
1102 }
1103
1104 if ( gc_buffer_colorcodes[index] != gc_buffer_colorcodes[index + jump] )
1105 {
1106 gc_ops.paint_char( /* xx */ column,
1107 /* yy */ row,
1108 /* ch */ gc_buffer_characters[index + jump],
1109 /* attrs */ gc_buffer_attributes[index + jump],
1110 /* ch_previous */ 0,
1111 /* attrs_previous */ 0 );
1112 }
1113 else
1114 {
1115 gc_ops.paint_char( /* xx */ column,
1116 /* yy */ row,
1117 /* ch */ gc_buffer_characters[index + jump],
1118 /* attrs */ gc_buffer_attributes[index + jump],
1119 /* ch_previous */ gc_buffer_characters[index],
1120 /* attrs_previous */ gc_buffer_attributes[index] );
1121 }
1122
1123 gc_buffer_attributes[index] = gc_buffer_attributes[index + jump];
1124 gc_buffer_characters[index] = gc_buffer_characters[index + jump];
1125 gc_buffer_colorcodes[index] = gc_buffer_colorcodes[index + jump];
1126
1127 }
1128 }
1129 }
1130
1131 if ( colorcodesave != gc_color_code )
1132 {
1133 gc_update_color(COLOR_CODE_GET(colorcodesave, TRUE ), TRUE );
1134 gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
1135 }
1136
1137 simple_unlock(&gc_buffer_lock);
1138 splx(s);
1139 }
1140 else
1141 {
1142 simple_unlock(&gc_buffer_lock);
1143 splx(s);
1144
1145 gc_ops.scroll_up(num, top, bottom);
1146 }
1147
1148 /* Now set the freed up lines to the background colour */
1149
1150 gc_clear_screen(0, bottom - num, top, bottom, 0);
1151 }
1152
1153 static void
1154 gc_show_cursor(int xx, int yy)
1155 {
1156 spl_t s;
1157
1158 s = splhigh();
1159 simple_lock(&gc_buffer_lock);
1160
1161 if ( xx < gc_buffer_columns && yy < gc_buffer_rows )
1162 {
1163 unsigned long index = (yy * gc_buffer_columns) + xx;
1164 unsigned char attribute = gc_buffer_attributes[index];
1165 unsigned char character = gc_buffer_characters[index];
1166 unsigned char colorcode = gc_buffer_colorcodes[index];
1167 unsigned char colorcodesave = gc_color_code;
1168
1169 simple_unlock(&gc_buffer_lock);
1170 splx(s);
1171
1172 gc_update_color(COLOR_CODE_GET(colorcode, FALSE), TRUE );
1173 gc_update_color(COLOR_CODE_GET(colorcode, TRUE ), FALSE);
1174
1175 gc_ops.paint_char(xx, yy, character, attribute, 0, 0);
1176
1177 gc_update_color(COLOR_CODE_GET(colorcodesave, TRUE ), TRUE );
1178 gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
1179 }
1180 else
1181 {
1182 simple_unlock(&gc_buffer_lock);
1183 splx(s);
1184
1185 gc_ops.show_cursor(xx, yy);
1186 }
1187 }
1188
1189 static void
1190 gc_update_color(int color, boolean_t fore)
1191 {
1192 gc_color_code = COLOR_CODE_SET(gc_color_code, color, fore);
1193 gc_ops.update_color(color, fore);
1194 }
1195
1196 int
1197 vcputc(int l, int u, int c)
1198 {
1199 if ( gc_enabled || debug_mode )
1200 {
1201 gc_hide_cursor(gc_x, gc_y);
1202 gc_putchar(c);
1203 gc_show_cursor(gc_x, gc_y);
1204 }
1205
1206 return 0;
1207 }
1208
1209 /*
1210 * Video Console (Back-End)
1211 * ------------------------
1212 */
1213
1214 /*
1215 * For the color support (Michel Pollet)
1216 */
1217 static unsigned char vc_color_index_table[33] =
1218 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1219 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
1220
1221 static unsigned long vc_colors[8][3] = {
1222 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
1223 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
1224 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
1225 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
1226 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
1227 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
1228 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
1229 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
1230 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
1231 };
1232
1233 static unsigned long vc_color_fore = 0;
1234 static unsigned long vc_color_back = 0;
1235
1236 /*
1237 * New Rendering code from Michel Pollet
1238 */
1239
1240 /* Rendered Font Buffer */
1241 static unsigned char *vc_rendered_font = NULL;
1242
1243 /* Rendered Font Size */
1244 static unsigned long vc_rendered_font_size = 0;
1245
1246 /* Size of a character in the table (bytes) */
1247 static int vc_rendered_char_size = 0;
1248
1249 #define REN_MAX_DEPTH 32
1250 static unsigned char vc_rendered_char[ISO_CHAR_HEIGHT * ((REN_MAX_DEPTH / 8) * ISO_CHAR_WIDTH)];
1251
1252 static void vc_clear_screen(int xx, int yy, int scrreg_top, int scrreg_bottom, int which);
1253 static void vc_enable(boolean_t enable);
1254 static void vc_initialize(struct vc_info * vinfo_p);
1255 static void vc_paint_char(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
1256 static void vc_paint_char_8(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
1257 static void vc_paint_char_16(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
1258 static void vc_paint_char_32(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
1259 static void vc_render_char(unsigned char ch, unsigned char *renderptr, short newdepth);
1260 static void vc_render_font(short newdepth);
1261 static void vc_reverse_cursor(int xx, int yy);
1262 static void vc_scroll_down(int num, int scrreg_top, int scrreg_bottom);
1263 static void vc_scroll_up(int num, int scrreg_top, int scrreg_bottom);
1264 static void vc_update_color(int color, boolean_t fore);
1265
1266 static void
1267 vc_clear_screen(int xx, int yy, int scrreg_top, int scrreg_bottom, int which)
1268 {
1269 unsigned long *p, *endp, *row;
1270 int linelongs, col;
1271 int rowline, rowlongs;
1272
1273 if(!vinfo.v_depth)
1274 return;
1275
1276 linelongs = vinfo.v_rowbytes * (ISO_CHAR_HEIGHT >> 2);
1277 rowline = vinfo.v_rowscanbytes >> 2;
1278 rowlongs = vinfo.v_rowbytes >> 2;
1279
1280 p = (unsigned long*) vinfo.v_baseaddr;
1281 endp = (unsigned long*) vinfo.v_baseaddr;
1282
1283 switch (which) {
1284 case 0: /* To end of screen */
1285 gc_clear_line(xx, yy, 0);
1286 if (yy < scrreg_bottom - 1) {
1287 p += (yy + 1) * linelongs;
1288 endp += scrreg_bottom * linelongs;
1289 }
1290 break;
1291 case 1: /* To start of screen */
1292 gc_clear_line(xx, yy, 1);
1293 if (yy > scrreg_top) {
1294 p += scrreg_top * linelongs;
1295 endp += yy * linelongs;
1296 }
1297 break;
1298 case 2: /* Whole screen */
1299 p += scrreg_top * linelongs;
1300 if (scrreg_bottom == vinfo.v_rows) {
1301 endp += rowlongs * vinfo.v_height;
1302 } else {
1303 endp += scrreg_bottom * linelongs;
1304 }
1305 break;
1306 }
1307
1308 for (row = p ; row < endp ; row += rowlongs) {
1309 for (col = 0; col < rowline; col++)
1310 *(row+col) = vc_color_back;
1311 }
1312 }
1313
1314 static void
1315 vc_enable(boolean_t enable)
1316 {
1317 if ( enable )
1318 {
1319 vc_render_font(vinfo.v_depth);
1320 }
1321 }
1322
1323 static void
1324 vc_initialize(struct vc_info * vinfo_p)
1325 {
1326 vinfo.v_rows = vinfo.v_height / ISO_CHAR_HEIGHT;
1327 vinfo.v_columns = vinfo.v_width / ISO_CHAR_WIDTH;
1328 vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
1329 }
1330
1331 static void
1332 vc_paint_char(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
1333 {
1334 if( !vinfo.v_depth)
1335 return;
1336
1337 switch( vinfo.v_depth) {
1338 case 8:
1339 vc_paint_char_8(xx, yy, ch, attrs, ch_previous, attrs_previous);
1340 break;
1341 case 16:
1342 vc_paint_char_16(xx, yy, ch, attrs, ch_previous, attrs_previous);
1343 break;
1344 case 32:
1345 vc_paint_char_32(xx, yy, ch, attrs, ch_previous, attrs_previous);
1346 break;
1347 }
1348 }
1349
1350 static void
1351 vc_paint_char_8(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
1352 {
1353 unsigned long *theChar;
1354 unsigned long *where;
1355 int i;
1356
1357 if (vc_rendered_font) {
1358 theChar = (unsigned long*)(vc_rendered_font + (ch * vc_rendered_char_size));
1359 } else {
1360 vc_render_char(ch, vc_rendered_char, 8);
1361 theChar = (unsigned long*)(vc_rendered_char);
1362 }
1363 where = (unsigned long*)(vinfo.v_baseaddr +
1364 (yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
1365 (xx * ISO_CHAR_WIDTH));
1366
1367 if (!attrs) for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* No attr? FLY !*/
1368 unsigned long *store = where;
1369 int x;
1370 for (x = 0; x < 2; x++) {
1371 unsigned long val = *theChar++;
1372 val = (vc_color_back & ~val) | (vc_color_fore & val);
1373 *store++ = val;
1374 }
1375
1376 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1377 } else for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* a little slower */
1378 unsigned long *store = where, lastpixel = 0;
1379 int x;
1380 for (x = 0 ; x < 2; x++) {
1381 unsigned long val = *theChar++, save = val;
1382 if (attrs & ATTR_BOLD) { /* bold support */
1383 if (lastpixel && !(save & 0xFF000000))
1384 val |= 0xff000000;
1385 if ((save & 0xFFFF0000) == 0xFF000000)
1386 val |= 0x00FF0000;
1387 if ((save & 0x00FFFF00) == 0x00FF0000)
1388 val |= 0x0000FF00;
1389 if ((save & 0x0000FFFF) == 0x0000FF00)
1390 val |= 0x000000FF;
1391 }
1392 if (attrs & ATTR_REVERSE) val = ~val;
1393 if (attrs & ATTR_UNDER && i == ISO_CHAR_HEIGHT-1) val = ~val;
1394
1395 val = (vc_color_back & ~val) | (vc_color_fore & val);
1396 *store++ = val;
1397 lastpixel = save & 0xff;
1398 }
1399
1400 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1401 }
1402
1403 }
1404
1405 static void
1406 vc_paint_char_16(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
1407 {
1408 unsigned long *theChar;
1409 unsigned long *where;
1410 int i;
1411
1412 if (vc_rendered_font) {
1413 theChar = (unsigned long*)(vc_rendered_font + (ch * vc_rendered_char_size));
1414 } else {
1415 vc_render_char(ch, vc_rendered_char, 16);
1416 theChar = (unsigned long*)(vc_rendered_char);
1417 }
1418 where = (unsigned long*)(vinfo.v_baseaddr +
1419 (yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
1420 (xx * ISO_CHAR_WIDTH * 2));
1421
1422 if (!attrs) for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* No attrs ? FLY ! */
1423 unsigned long *store = where;
1424 int x;
1425 for (x = 0; x < 4; x++) {
1426 unsigned long val = *theChar++;
1427 val = (vc_color_back & ~val) | (vc_color_fore & val);
1428 *store++ = val;
1429 }
1430
1431 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1432 } else for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* a little bit slower */
1433 unsigned long *store = where, lastpixel = 0;
1434 int x;
1435 for (x = 0 ; x < 4; x++) {
1436 unsigned long val = *theChar++, save = val;
1437 if (attrs & ATTR_BOLD) { /* bold support */
1438 if (save == 0xFFFF0000) val |= 0xFFFF;
1439 else if (lastpixel && !(save & 0xFFFF0000))
1440 val |= 0xFFFF0000;
1441 }
1442 if (attrs & ATTR_REVERSE) val = ~val;
1443 if (attrs & ATTR_UNDER && i == ISO_CHAR_HEIGHT-1) val = ~val;
1444
1445 val = (vc_color_back & ~val) | (vc_color_fore & val);
1446
1447 *store++ = val;
1448 lastpixel = save & 0x7fff;
1449 }
1450
1451 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1452 }
1453
1454 }
1455
1456 static void
1457 vc_paint_char_32(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
1458 {
1459 unsigned long *theChar;
1460 unsigned long *theCharPrevious;
1461 unsigned long *where;
1462 int i;
1463
1464 if (vc_rendered_font) {
1465 theChar = (unsigned long*)(vc_rendered_font + (ch * vc_rendered_char_size));
1466 theCharPrevious = (unsigned long*)(vc_rendered_font + (ch_previous * vc_rendered_char_size));
1467 } else {
1468 vc_render_char(ch, vc_rendered_char, 32);
1469 theChar = (unsigned long*)(vc_rendered_char);
1470 theCharPrevious = NULL;
1471 }
1472 if (!ch_previous) {
1473 theCharPrevious = NULL;
1474 }
1475 if (attrs_previous) {
1476 theCharPrevious = NULL;
1477 }
1478 where = (unsigned long*)(vinfo.v_baseaddr +
1479 (yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
1480 (xx * ISO_CHAR_WIDTH * 4));
1481
1482 if (!attrs) for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* No attrs ? FLY ! */
1483 unsigned long *store = where;
1484 int x;
1485 for (x = 0; x < 8; x++) {
1486 unsigned long val = *theChar++;
1487 if (theCharPrevious == NULL || val != *theCharPrevious++ ) {
1488 val = (vc_color_back & ~val) | (vc_color_fore & val);
1489 *store++ = val;
1490 } else {
1491 store++;
1492 }
1493 }
1494
1495 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1496 } else for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* a little slower */
1497 unsigned long *store = where, lastpixel = 0;
1498 int x;
1499 for (x = 0 ; x < 8; x++) {
1500 unsigned long val = *theChar++, save = val;
1501 if (attrs & ATTR_BOLD) { /* bold support */
1502 if (lastpixel && !save)
1503 val = 0xFFFFFFFF;
1504 }
1505 if (attrs & ATTR_REVERSE) val = ~val;
1506 if (attrs & ATTR_UNDER && i == ISO_CHAR_HEIGHT-1) val = ~val;
1507
1508 val = (vc_color_back & ~val) | (vc_color_fore & val);
1509 *store++ = val;
1510 lastpixel = save;
1511 }
1512
1513 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1514 }
1515
1516 }
1517
1518 static void
1519 vc_render_char(unsigned char ch, unsigned char *renderptr, short newdepth)
1520 {
1521 union {
1522 unsigned char *charptr;
1523 unsigned short *shortptr;
1524 unsigned long *longptr;
1525 } current; /* current place in rendered font, multiple types. */
1526
1527 unsigned char *theChar; /* current char in iso_font */
1528
1529 int line;
1530
1531 current.charptr = renderptr;
1532 theChar = iso_font + (ch * ISO_CHAR_HEIGHT);
1533
1534 for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
1535 unsigned char mask = 1;
1536 do {
1537 switch (newdepth) {
1538 case 8:
1539 *current.charptr++ = (*theChar & mask) ? 0xFF : 0;
1540 break;
1541 case 16:
1542 *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
1543 break;
1544
1545 case 32:
1546 *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
1547 break;
1548 }
1549 mask <<= 1;
1550 } while (mask); /* while the single bit drops to the right */
1551 theChar++;
1552 }
1553 }
1554
1555 static void
1556 vc_render_font(short newdepth)
1557 {
1558 static short olddepth = 0;
1559
1560 int charindex; /* index in ISO font */
1561
1562 if (vm_initialized == FALSE) {
1563 return; /* nothing to do */
1564 }
1565 if (olddepth == newdepth && vc_rendered_font) {
1566 return; /* nothing to do */
1567 }
1568 if (vc_rendered_font) {
1569 kfree(vc_rendered_font, vc_rendered_font_size);
1570 }
1571
1572 vc_rendered_char_size = ISO_CHAR_HEIGHT * ((newdepth / 8) * ISO_CHAR_WIDTH);
1573 vc_rendered_font_size = (ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size;
1574 vc_rendered_font = (unsigned char *) kalloc(vc_rendered_font_size);
1575
1576 if (vc_rendered_font == NULL) {
1577 vc_rendered_font_size = 0;
1578 return;
1579 }
1580
1581 for (charindex = ISO_CHAR_MIN; charindex <= ISO_CHAR_MAX; charindex++) {
1582 vc_render_char(charindex, vc_rendered_font + (charindex * vc_rendered_char_size), newdepth);
1583 }
1584
1585 olddepth = newdepth;
1586 }
1587
1588 static void
1589 vc_reverse_cursor(int xx, int yy)
1590 {
1591 unsigned long *where;
1592 int line, col;
1593
1594 if(!vinfo.v_depth)
1595 return;
1596
1597 where = (unsigned long*)(vinfo.v_baseaddr +
1598 (yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
1599 (xx /** ISO_CHAR_WIDTH*/ * vinfo.v_depth));
1600 for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
1601 switch (vinfo.v_depth) {
1602 case 8:
1603 where[0] = ~where[0];
1604 where[1] = ~where[1];
1605 break;
1606 case 16:
1607 for (col = 0; col < 4; col++)
1608 where[col] = ~where[col];
1609 break;
1610 case 32:
1611 for (col = 0; col < 8; col++)
1612 where[col] = ~where[col];
1613 break;
1614 }
1615 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
1616 }
1617 }
1618
1619 static void
1620 vc_scroll_down(int num, int scrreg_top, int scrreg_bottom)
1621 {
1622 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
1623
1624 if(!vinfo.v_depth)
1625 return;
1626
1627 linelongs = vinfo.v_rowbytes * (ISO_CHAR_HEIGHT >> 2);
1628 rowline = vinfo.v_rowbytes >> 2;
1629 rowscanline = vinfo.v_rowscanbytes >> 2;
1630
1631 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
1632 - (rowline - rowscanline);
1633 from = to - (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
1634
1635 i = (scrreg_bottom - scrreg_top) - num;
1636
1637 while (i-- > 0) {
1638 for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
1639 /*
1640 * Only copy what is displayed
1641 */
1642 video_scroll_down((unsigned int) from,
1643 (unsigned int) (from-(vinfo.v_rowscanbytes >> 2)),
1644 (unsigned int) to);
1645
1646 from -= rowline;
1647 to -= rowline;
1648 }
1649 }
1650 }
1651
1652 static void
1653 vc_scroll_up(int num, int scrreg_top, int scrreg_bottom)
1654 {
1655 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
1656
1657 if(!vinfo.v_depth)
1658 return;
1659
1660 linelongs = vinfo.v_rowbytes * (ISO_CHAR_HEIGHT >> 2);
1661 rowline = vinfo.v_rowbytes >> 2;
1662 rowscanline = vinfo.v_rowscanbytes >> 2;
1663
1664 to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
1665 from = to + (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
1666
1667 i = (scrreg_bottom - scrreg_top) - num;
1668
1669 while (i-- > 0) {
1670 for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
1671 /*
1672 * Only copy what is displayed
1673 */
1674 video_scroll_up((unsigned int) from,
1675 (unsigned int) (from+(vinfo.v_rowscanbytes >> 2)),
1676 (unsigned int) to);
1677
1678 from += rowline;
1679 to += rowline;
1680 }
1681 }
1682 }
1683
1684 static void
1685 vc_update_color(int color, boolean_t fore)
1686 {
1687 if (!vinfo.v_depth)
1688 return;
1689 if (fore) {
1690 vc_color_fore = vc_colors[color][vc_color_index_table[vinfo.v_depth]];
1691 } else {
1692 vc_color_back = vc_colors[color][vc_color_index_table[vinfo.v_depth]];
1693 }
1694 }
1695
1696 /*
1697 * Video Console (Back-End): Icon Control
1698 * --------------------------------------
1699 */
1700
1701 struct vc_progress_element {
1702 unsigned int version;
1703 unsigned int flags;
1704 unsigned int time;
1705 unsigned char count;
1706 unsigned char res[3];
1707 int width;
1708 int height;
1709 int dx;
1710 int dy;
1711 int transparent;
1712 unsigned int res2[3];
1713 unsigned char data[0];
1714 };
1715 typedef struct vc_progress_element vc_progress_element;
1716
1717 static vc_progress_element * vc_progress;
1718 static const unsigned char * vc_progress_data;
1719 static const unsigned char * vc_progress_alpha;
1720 static boolean_t vc_progress_enable;
1721 static const unsigned char * vc_clut;
1722 static const unsigned char * vc_clut8;
1723 static unsigned char vc_revclut8[256];
1724 static uint32_t vc_progress_interval;
1725 static uint64_t vc_progress_deadline;
1726 static thread_call_data_t vc_progress_call;
1727 static boolean_t vc_needsave;
1728 static void * vc_saveunder;
1729 static vm_size_t vc_saveunder_len;
1730 decl_simple_lock_data(,vc_progress_lock)
1731
1732 static void vc_blit_rect( int x, int y, int width, int height,
1733 const unsigned char * dataPtr, const unsigned char * alphaPtr,
1734 void * backBuffer, boolean_t save, boolean_t static_alpha );
1735 static void vc_blit_rect_8( int x, int y, int width, int height,
1736 const unsigned char * dataPtr, const unsigned char * alphaPtr,
1737 unsigned char * backBuffer, boolean_t save, boolean_t static_alpha );
1738 static void vc_blit_rect_16( int x, int y, int width, int height,
1739 const unsigned char * dataPtr, const unsigned char * alphaPtr,
1740 unsigned short * backBuffer, boolean_t save, boolean_t static_alpha );
1741 static void vc_blit_rect_32( int x, int y, int width, int height,
1742 const unsigned char * dataPtr, const unsigned char * alphaPtr,
1743 unsigned int * backBuffer, boolean_t save, boolean_t static_alpha );
1744 extern void vc_display_icon( vc_progress_element * desc, const unsigned char * data );
1745 extern void vc_progress_initialize( vc_progress_element * desc, const unsigned char * data, const unsigned char * clut );
1746 static void vc_progress_set( boolean_t enable, uint32_t delay );
1747 static void vc_progress_task( void * arg0, void * arg );
1748
1749 static void vc_blit_rect( int x, int y,
1750 int width, int height,
1751 const unsigned char * dataPtr,
1752 const unsigned char * alphaPtr,
1753 void * backBuffer,
1754 boolean_t save, boolean_t static_alpha )
1755 {
1756 if(!vinfo.v_depth)
1757 return;
1758
1759 switch( vinfo.v_depth) {
1760 case 8:
1761 if( vc_clut8 == vc_clut)
1762 vc_blit_rect_8( x, y, width, height, dataPtr, alphaPtr, (unsigned char *) backBuffer, save, static_alpha );
1763 break;
1764 case 16:
1765 vc_blit_rect_16( x, y, width, height, dataPtr, alphaPtr, (unsigned short *) backBuffer, save, static_alpha );
1766 break;
1767 case 32:
1768 vc_blit_rect_32( x, y, width, height, dataPtr, alphaPtr, (unsigned int *) backBuffer, save, static_alpha );
1769 break;
1770 }
1771 }
1772
1773 static void vc_blit_rect_8( int x, int y,
1774 int width, int height,
1775 const unsigned char * dataPtr,
1776 const unsigned char * alphaPtr,
1777 unsigned char * backPtr,
1778 boolean_t save, boolean_t static_alpha )
1779 {
1780 volatile unsigned char * dst;
1781 int line, col;
1782 unsigned int data;
1783
1784 dst = (unsigned char *)(vinfo.v_baseaddr +
1785 (y * vinfo.v_rowbytes) +
1786 (x));
1787
1788 for( line = 0; line < height; line++) {
1789 for( col = 0; col < width; col++) {
1790 data = 0;
1791 if( dataPtr != 0) data = *dataPtr++;
1792 else if( alphaPtr != 0) data = vc_revclut8[*alphaPtr++];
1793 *(dst + col) = data;
1794 }
1795 dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1796 }
1797 }
1798
1799 static void vc_blit_rect_16( int x, int y,
1800 int width, int height,
1801 const unsigned char * dataPtr,
1802 const unsigned char * alphaPtr,
1803 unsigned short * backPtr,
1804 boolean_t save, boolean_t static_alpha )
1805 {
1806 volatile unsigned short * dst;
1807 int line, col;
1808 unsigned int data, index, alpha, back;
1809
1810 dst = (volatile unsigned short *)(vinfo.v_baseaddr +
1811 (y * vinfo.v_rowbytes) +
1812 (x * 2));
1813
1814 for( line = 0; line < height; line++) {
1815 for( col = 0; col < width; col++) {
1816 if( dataPtr != 0) {
1817 index = *dataPtr++;
1818 index *= 3;
1819 }
1820
1821 if( alphaPtr && backPtr) {
1822
1823 alpha = *alphaPtr++;
1824 data = 0;
1825 if( dataPtr != 0) {
1826 if( vc_clut[index + 0] > alpha)
1827 data |= (((vc_clut[index + 0] - alpha) & 0xf8) << 7);
1828 if( vc_clut[index + 1] > alpha)
1829 data |= (((vc_clut[index + 1] - alpha) & 0xf8) << 2);
1830 if( vc_clut[index + 2] > alpha)
1831 data |= (((vc_clut[index + 2] - alpha) & 0xf8) >> 3);
1832 }
1833
1834 if( save) {
1835 back = *(dst + col);
1836 if ( !static_alpha)
1837 *backPtr++ = back;
1838 back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
1839 | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
1840 | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
1841 if ( static_alpha)
1842 *backPtr++ = back;
1843 } else {
1844 back = *backPtr++;
1845 if ( !static_alpha) {
1846 back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
1847 | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
1848 | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
1849 }
1850 }
1851
1852 data += back;
1853
1854 } else
1855 if( dataPtr != 0) {
1856 data = ( (0xf8 & (vc_clut[index + 0])) << 7)
1857 | ( (0xf8 & (vc_clut[index + 1])) << 2)
1858 | ( (0xf8 & (vc_clut[index + 2])) >> 3);
1859 }
1860
1861 *(dst + col) = data;
1862 }
1863 dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
1864 }
1865 }
1866
1867 static void vc_blit_rect_32( int x, int y,
1868 int width, int height,
1869 const unsigned char * dataPtr,
1870 const unsigned char * alphaPtr,
1871 unsigned int * backPtr,
1872 boolean_t save, boolean_t static_alpha )
1873 {
1874 volatile unsigned int * dst;
1875 int line, col;
1876 unsigned int data, index, alpha, back;
1877
1878 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
1879 (y * vinfo.v_rowbytes) +
1880 (x * 4));
1881
1882 for( line = 0; line < height; line++) {
1883 for( col = 0; col < width; col++) {
1884 if( dataPtr != 0) {
1885 index = *dataPtr++;
1886 index *= 3;
1887 }
1888
1889 if( alphaPtr && backPtr) {
1890
1891 alpha = *alphaPtr++;
1892 data = 0;
1893 if( dataPtr != 0) {
1894 if( vc_clut[index + 0] > alpha)
1895 data |= ((vc_clut[index + 0] - alpha) << 16);
1896 if( vc_clut[index + 1] > alpha)
1897 data |= ((vc_clut[index + 1] - alpha) << 8);
1898 if( vc_clut[index + 2] > alpha)
1899 data |= ((vc_clut[index + 2] - alpha));
1900 }
1901
1902 if( save) {
1903 back = *(dst + col);
1904 if ( !static_alpha)
1905 *backPtr++ = back;
1906 back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
1907 | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
1908 if ( static_alpha)
1909 *backPtr++ = back;
1910 } else {
1911 back = *backPtr++;
1912 if ( !static_alpha) {
1913 back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
1914 | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
1915 }
1916 }
1917
1918 data += back;
1919
1920 } else
1921 if( dataPtr != 0) {
1922 data = (vc_clut[index + 0] << 16)
1923 | (vc_clut[index + 1] << 8)
1924 | (vc_clut[index + 2]);
1925 }
1926
1927 *(dst + col) = data;
1928 }
1929 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
1930 }
1931 }
1932
1933 void vc_display_icon( vc_progress_element * desc,
1934 const unsigned char * data )
1935 {
1936 int x, y, width, height;
1937
1938 if( vc_progress_enable && vc_clut) {
1939
1940 width = desc->width;
1941 height = desc->height;
1942 x = desc->dx;
1943 y = desc->dy;
1944 if( 1 & desc->flags) {
1945 x += ((vinfo.v_width - width) / 2);
1946 y += ((vinfo.v_height - height) / 2);
1947 }
1948 vc_blit_rect( x, y, width, height, data, NULL, NULL, FALSE, TRUE );
1949 }
1950 }
1951
1952 void
1953 vc_progress_initialize( vc_progress_element * desc,
1954 const unsigned char * data,
1955 const unsigned char * clut )
1956 {
1957 uint64_t abstime;
1958
1959 if( (!clut) || (!desc) || (!data))
1960 return;
1961 vc_clut = clut;
1962 vc_clut8 = clut;
1963
1964 vc_progress = desc;
1965 vc_progress_data = data;
1966 if( 2 & vc_progress->flags)
1967 vc_progress_alpha = vc_progress_data
1968 + vc_progress->count * vc_progress->width * vc_progress->height;
1969 else
1970 vc_progress_alpha = NULL;
1971
1972 thread_call_setup(&vc_progress_call, vc_progress_task, NULL);
1973
1974 clock_interval_to_absolutetime_interval(vc_progress->time, 1000 * 1000, &abstime);
1975 vc_progress_interval = abstime;
1976
1977 simple_lock_init(&vc_progress_lock, 0);
1978 }
1979
1980 static void
1981 vc_progress_set( boolean_t enable, uint32_t delay )
1982 {
1983 spl_t s;
1984 void *saveBuf = 0;
1985 vm_size_t saveLen = 0;
1986 unsigned int count;
1987 unsigned int index;
1988 unsigned char pdata8;
1989 unsigned short pdata16;
1990 unsigned short * buf16;
1991 unsigned int pdata32;
1992 unsigned int * buf32;
1993
1994 if( !vc_progress)
1995 return;
1996
1997 if( enable) {
1998 saveLen = vc_progress->width * vc_progress->height * vinfo.v_depth / 8;
1999 saveBuf = kalloc( saveLen );
2000
2001 switch( vinfo.v_depth) {
2002 case 8 :
2003 for( count = 0; count < 256; count++) {
2004 vc_revclut8[count] = vc_clut[0x01 * 3];
2005 pdata8 = (vc_clut[0x01 * 3] * count + 0x0ff) >> 8;
2006 for( index = 0; index < 256; index++) {
2007 if( (pdata8 == vc_clut[index * 3 + 0]) &&
2008 (pdata8 == vc_clut[index * 3 + 1]) &&
2009 (pdata8 == vc_clut[index * 3 + 2])) {
2010 vc_revclut8[count] = index;
2011 break;
2012 }
2013 }
2014 }
2015 memset( saveBuf, 0x01, saveLen );
2016 break;
2017
2018 case 16 :
2019 buf16 = (unsigned short *) saveBuf;
2020 pdata16 = ((vc_clut[0x01 * 3 + 0] & 0xf8) << 7)
2021 | ((vc_clut[0x01 * 3 + 0] & 0xf8) << 2)
2022 | ((vc_clut[0x01 * 3 + 0] & 0xf8) >> 3);
2023 for( count = 0; count < saveLen / 2; count++)
2024 buf16[count] = pdata16;
2025 break;
2026
2027 case 32 :
2028 buf32 = (unsigned int *) saveBuf;
2029 pdata32 = ((vc_clut[0x01 * 3 + 0] & 0xff) << 16)
2030 | ((vc_clut[0x01 * 3 + 1] & 0xff) << 8)
2031 | ((vc_clut[0x01 * 3 + 2] & 0xff) << 0);
2032 for( count = 0; count < saveLen / 4; count++)
2033 buf32[count] = pdata32;
2034 break;
2035 }
2036 }
2037
2038 s = splhigh();
2039 simple_lock(&vc_progress_lock);
2040
2041 if( vc_progress_enable != enable) {
2042 vc_progress_enable = enable;
2043 if( enable) {
2044 vc_needsave = TRUE;
2045 vc_saveunder = saveBuf;
2046 vc_saveunder_len = saveLen;
2047 saveBuf = 0;
2048 saveLen = 0;
2049
2050 clock_interval_to_deadline(delay, 1000 * 1000 * 1000 /*second scale*/, &vc_progress_deadline);
2051 thread_call_enter_delayed(&vc_progress_call, vc_progress_deadline);
2052
2053 } else {
2054 if( vc_saveunder) {
2055 saveBuf = vc_saveunder;
2056 saveLen = vc_saveunder_len;
2057 vc_saveunder = 0;
2058 vc_saveunder_len = 0;
2059 }
2060
2061 thread_call_cancel(&vc_progress_call);
2062 }
2063 }
2064
2065 simple_unlock(&vc_progress_lock);
2066 splx(s);
2067
2068 if( saveBuf)
2069 kfree( saveBuf, saveLen );
2070 }
2071
2072 static void vc_progress_task( void * arg0, void * arg )
2073 {
2074 spl_t s;
2075 int count = (int) arg;
2076 int x, y, width, height;
2077 const unsigned char * data;
2078
2079 s = splhigh();
2080 simple_lock(&vc_progress_lock);
2081
2082 if( vc_progress_enable) {
2083
2084 count++;
2085 if( count >= vc_progress->count)
2086 count = 0;
2087
2088 width = vc_progress->width;
2089 height = vc_progress->height;
2090 x = vc_progress->dx;
2091 y = vc_progress->dy;
2092 data = vc_progress_data;
2093 data += count * width * height;
2094 if( 1 & vc_progress->flags) {
2095 x += ((vinfo.v_width - width) / 2);
2096 y += ((vinfo.v_height - height) / 2);
2097 }
2098 vc_blit_rect( x, y, width, height,
2099 NULL, data, vc_saveunder,
2100 vc_needsave, (0 == (4 & vc_progress->flags)) );
2101 vc_needsave = FALSE;
2102
2103 clock_deadline_for_periodic_event(vc_progress_interval, mach_absolute_time(), &vc_progress_deadline);
2104 thread_call_enter1_delayed(&vc_progress_call, (void *)count, vc_progress_deadline);
2105 }
2106 simple_unlock(&vc_progress_lock);
2107 splx(s);
2108 }
2109
2110 /*
2111 * Generic Console (Front-End): Master Control
2112 * -------------------------------------------
2113 */
2114
2115 #ifdef __i386__
2116 #include <console/i386/text_console.h>
2117 #endif /* __i386__ */
2118
2119 static boolean_t gc_acquired = FALSE;
2120 static boolean_t gc_graphics_boot = FALSE;
2121
2122 static unsigned int lastVideoPhys = 0;
2123 static unsigned int lastVideoVirt = 0;
2124 static unsigned int lastVideoSize = 0;
2125
2126 void
2127 initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
2128 {
2129 unsigned int fbsize;
2130 unsigned int newVideoVirt;
2131 ppnum_t fbppage;
2132
2133 if ( boot_vinfo )
2134 {
2135 // bcopy((const void *)boot_vinfo, (void *)&boot_video_info, sizeof(boot_video_info));
2136
2137 /*
2138 * First, check if we are changing the size and/or location of the framebuffer
2139 */
2140
2141 vinfo.v_name[0] = 0;
2142 vinfo.v_width = boot_vinfo->v_width;
2143 vinfo.v_height = boot_vinfo->v_height;
2144 vinfo.v_depth = boot_vinfo->v_depth;
2145 vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
2146 vinfo.v_physaddr = boot_vinfo->v_baseAddr; /* Get the physical address */
2147
2148 kprintf("initialize_screen: b=%08X, w=%08X, h=%08X, r=%08X\n", /* (BRINGUP) */
2149 vinfo.v_physaddr, vinfo.v_width, vinfo.v_height, vinfo.v_rowbytes); /* (BRINGUP) */
2150
2151 if (!vinfo.v_physaddr) /* Check to see if we have a framebuffer */
2152 {
2153 kprintf("initialize_screen: No video - forcing serial mode\n"); /* (BRINGUP) */
2154 vinfo.v_depth = 0; /* vc routines are nop */
2155 (void)switch_to_serial_console(); /* Switch into serial mode */
2156 gc_graphics_boot = FALSE; /* Say we are not in graphics mode */
2157 disableConsoleOutput = FALSE; /* Allow printfs to happen */
2158 gc_acquired = TRUE;
2159 }
2160 else
2161 {
2162 /*
2163 * Note that for the first time only, boot_vinfo->v_baseAddr is physical.
2164 */
2165
2166 if (kernel_map != VM_MAP_NULL) /* If VM is up, we are given a virtual address */
2167 {
2168 fbppage = pmap_find_phys(kernel_pmap, (addr64_t)boot_vinfo->v_baseAddr); /* Get the physical address of frame buffer */
2169 if(!fbppage) /* Did we find it? */
2170 {
2171 panic("initialize_screen: Strange framebuffer - addr = %08X\n", boot_vinfo->v_baseAddr);
2172 }
2173 vinfo.v_physaddr = (fbppage << 12) | (boot_vinfo->v_baseAddr & PAGE_MASK); /* Get the physical address */
2174 }
2175
2176 #ifdef __i386__
2177 vinfo.v_type = boot_vinfo->v_display;
2178 #else
2179 vinfo.v_type = 0;
2180 #endif
2181
2182 fbsize = round_page_32(vinfo.v_height * vinfo.v_rowbytes); /* Remember size */
2183
2184 if ((lastVideoPhys != vinfo.v_physaddr) || (fbsize > lastVideoSize)) /* Did framebuffer change location or get bigger? */
2185 {
2186 newVideoVirt = io_map_spec((vm_offset_t)vinfo.v_physaddr, fbsize); /* Allocate address space for framebuffer */
2187
2188 if (lastVideoVirt) /* Was the framebuffer mapped before? */
2189 {
2190 pmap_remove(kernel_pmap, trunc_page_64(lastVideoVirt),
2191 round_page_64(lastVideoVirt + lastVideoSize)); /* Toss mappings */
2192
2193 if(lastVideoVirt <= vm_last_addr) /* Was this not a special pre-VM mapping? */
2194 {
2195 kmem_free(kernel_map, lastVideoVirt, lastVideoSize); /* Toss kernel addresses */
2196 }
2197 }
2198
2199 lastVideoPhys = vinfo.v_physaddr; /* Remember the framebuffer address */
2200 lastVideoSize = fbsize; /* Remember the size */
2201 lastVideoVirt = newVideoVirt; /* Remember the virtual framebuffer address */
2202 }
2203 }
2204
2205 vinfo.v_baseaddr = lastVideoVirt; /* Set the new framebuffer address */
2206
2207 #ifdef __i386__
2208 if ( (vinfo.v_type == TEXT_MODE) )
2209 {
2210 // Text mode setup by the booter.
2211
2212 gc_ops.initialize = tc_initialize;
2213 gc_ops.enable = tc_enable;
2214 gc_ops.paint_char = tc_paint_char;
2215 gc_ops.clear_screen = tc_clear_screen;
2216 gc_ops.scroll_down = tc_scroll_down;
2217 gc_ops.scroll_up = tc_scroll_up;
2218 gc_ops.hide_cursor = tc_hide_cursor;
2219 gc_ops.show_cursor = tc_show_cursor;
2220 gc_ops.update_color = tc_update_color;
2221 }
2222 else
2223 #endif /* __i386__ */
2224 {
2225 // Graphics mode setup by the booter.
2226
2227 gc_ops.initialize = vc_initialize;
2228 gc_ops.enable = vc_enable;
2229 gc_ops.paint_char = vc_paint_char;
2230 gc_ops.scroll_down = vc_scroll_down;
2231 gc_ops.scroll_up = vc_scroll_up;
2232 gc_ops.clear_screen = vc_clear_screen;
2233 gc_ops.hide_cursor = vc_reverse_cursor;
2234 gc_ops.show_cursor = vc_reverse_cursor;
2235 gc_ops.update_color = vc_update_color;
2236 }
2237
2238 gc_initialize(&vinfo);
2239
2240 #ifdef GRATEFULDEBUGGER
2241 GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re-initialize GratefulDeb */
2242 #endif /* GRATEFULDEBUGGER */
2243 }
2244
2245 switch ( op )
2246 {
2247 case kPEGraphicsMode:
2248 panicDialogDesired = TRUE;
2249 gc_graphics_boot = TRUE;
2250 break;
2251
2252 case kPETextMode:
2253 panicDialogDesired = FALSE;
2254 gc_graphics_boot = FALSE;
2255 break;
2256
2257 case kPEAcquireScreen:
2258 if ( gc_acquired ) break;
2259
2260 vc_progress_set( gc_graphics_boot, kProgressAcquireDelay );
2261 gc_enable( !gc_graphics_boot );
2262 gc_acquired = TRUE;
2263 break;
2264
2265 case kPEEnableScreen:
2266 /* deprecated */
2267 break;
2268
2269 case kPETextScreen:
2270 panicDialogDesired = FALSE;
2271 if ( gc_acquired == FALSE ) break;
2272 if ( gc_graphics_boot == FALSE ) break;
2273
2274 vc_progress_set( FALSE, 0 );
2275 gc_enable( TRUE );
2276 break;
2277
2278 case kPEDisableScreen:
2279 /* deprecated */
2280 /* skip break */
2281
2282 case kPEReleaseScreen:
2283 gc_acquired = FALSE;
2284 gc_enable( FALSE );
2285 vc_progress_set( FALSE, 0 );
2286
2287 vc_clut8 = NULL;
2288 #ifdef GRATEFULDEBUGGER
2289 GratefulDebInit(0); /* Stop grateful debugger */
2290 #endif /* GRATEFULDEBUGGER */
2291 break;
2292 }
2293 #ifdef GRATEFULDEBUGGER
2294 if ( boot_vinfo ) GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re initialize GratefulDeb */
2295 #endif /* GRATEFULDEBUGGER */
2296 }
2297
2298 void
2299 refresh_screen(void)
2300 {
2301 if ( gc_enabled )
2302 {
2303 gc_refresh_screen();
2304 gc_show_cursor(gc_x, gc_y);
2305 }
2306 }
2307
2308 void
2309 vcattach(void)
2310 {
2311 extern struct { long msg_magic; long msg_bufx; long msg_bufr; char msg_bufc[]; } * msgbufp;
2312
2313 vm_initialized = TRUE;
2314
2315 if ( gc_graphics_boot == FALSE )
2316 {
2317 unsigned int index;
2318
2319 if ( gc_acquired )
2320 {
2321 initialize_screen( 0, kPEReleaseScreen );
2322 }
2323
2324 initialize_screen( 0, kPEAcquireScreen );
2325
2326 for ( index = 0 ; index < msgbufp->msg_bufx ; index++ )
2327 {
2328 vcputc( 0, 0, msgbufp->msg_bufc[index] );
2329
2330 if ( msgbufp->msg_bufc[index] == '\n' )
2331 {
2332 vcputc( 0, 0,'\r' );
2333 }
2334 }
2335 }
2336 }