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