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