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