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