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