2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * @OSF_FREE_COPYRIGHT@
27 * @APPLE_FREE_COPYRIGHT@
29 /* MACH PPC - video_console.c
31 * Original based on NetBSD's mac68k/dev/ite.c driver
33 * This driver differs in
35 * - Uses phys_copy and flush_cache to in several places
36 * for performance optimizations
38 * - Black background and white (character) foreground
39 * - Assumes 6100/7100/8100 class of machine
41 * The original header follows...
44 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
46 * Copyright (c) 1988 University of Utah.
47 * Copyright (c) 1990, 1993
48 * The Regents of the University of California. All rights reserved.
50 * This code is derived from software contributed to Berkeley by
51 * the Systems Programming Group of the University of Utah Computer
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
57 * 1. Redistributions of source code must retain the above copyright
58 * notice, this list of conditions and the following disclaimer.
59 * 2. Redistributions in binary form must reproduce the above copyright
60 * notice, this list of conditions and the following disclaimer in the
61 * documentation and/or other materials provided with the distribution.
62 * 3. All advertising materials mentioning features or use of this software
63 * must display the following acknowledgement:
64 * This product includes software developed by the University of
65 * California, Berkeley and its contributors.
66 * 4. Neither the name of the University nor the names of its contributors
67 * may be used to endorse or promote products derived from this software
68 * without specific prior written permission.
70 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82 * from: Utah $Hdr: ite.c 1.28 92/12/20$
84 * @(#)ite.c 8.2 (Berkeley) 1/12/94
90 * The ite module handles the system console; that is, stuff printed
91 * by the kernel and by user programs while "desktop" and X aren't
92 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
93 * hence the above copyright.
95 * -- Brad and Lawrence, June 26th, 1994
101 #include <mach_kdb.h>
102 #include <kern/spl.h>
103 #include <machine/machparam.h> /* spl definitions */
105 #include <ppc/iso_font.h>
106 #include <ppc/Firmware.h>
108 #include <ppc/POWERMAC/video_console_entries.h>
109 #include <ppc/POWERMAC/video_console.h>
110 #include <pexpert/pexpert.h>
111 #include <kern/time_out.h>
112 #include <kern/lock.h>
113 #include <kern/debug.h>
115 #define FAST_JUMP_SCROLL
118 #define CHARHEIGHT 16
123 #define ATTR_REVERSE 4
126 ESnormal
, /* Nothing yet */
128 ESsquare
, /* Got ESC [ */
129 ESgetpars
, /* About to get or getting the parameters */
130 ESgotpars
, /* Finished getting the parameters */
131 ESfunckey
, /* Function key */
132 EShash
, /* DEC-specific stuff (screen align, etc.) */
133 ESsetG0
, /* Specify the G0 character set */
134 ESsetG1
, /* Specify the G1 character set */
137 ESignore
/* Ignore this sequence */
138 } vt100state
= ESnormal
;
140 struct vc_info vinfo
;
142 /* Calculated in vccninit(): */
143 static int vc_wrap_mode
= 1, vc_relative_origin
= 0;
144 static int vc_charset_select
= 0, vc_save_charset_s
= 0;
145 static int vc_charset
[2] = { 0, 0 };
146 static int vc_charset_save
[2] = { 0, 0 };
150 static int x
= 0, y
= 0, savex
, savey
;
151 static int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
153 /* VT100 tab stops & scroll region */
154 static char tab_stops
[255];
155 static int scrreg_top
, scrreg_bottom
;
158 void vc_initialize(void);
159 void vc_flush_forward_buffer(void);
160 void vc_store_char(unsigned char);
166 * For the color support (Michel Pollet)
168 unsigned char vc_color_index_table
[33] =
169 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
172 unsigned long vc_color_depth_masks
[4] =
173 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
175 unsigned long vc_colors
[8][3] = {
176 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
177 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
178 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
179 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
180 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
181 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
182 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
183 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
184 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
187 unsigned long vc_color_mask
= 0;
188 unsigned long vc_color_fore
= 0;
189 unsigned long vc_color_back
= 0;
190 int vc_normal_background
= 1;
194 * For the jump scroll and buffering (Michel Pollet)
195 * 80*22 means on a 80*24 screen, the screen will
196 * scroll jump almost a full screen
197 * keeping only what's necessary for you to be able to read ;-)
199 #define VC_MAX_FORWARD_SIZE (100*36)
202 * Delay between console updates in clock hz units, the larger the
203 * delay the fuller the jump-scroll buffer will be and so the faster the
204 * (scrolling) output. The smaller the delay, the less jerky the
205 * display. Heuristics show that at 10 touch-typists (Mike!) complain
207 #define VC_CONSOLE_UPDATE_TIMEOUT 5
209 static unsigned char vc_forward_buffer
[VC_MAX_FORWARD_SIZE
];
210 static long vc_forward_buffer_size
= 0;
211 static int vc_forward_buffer_enabled
= 0;
212 static int vc_forward_buffer_busy
= 0;
213 decl_simple_lock_data(,vc_forward_lock
)
215 #ifdef FAST_JUMP_SCROLL
216 static void (*vc_forward_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
222 } vc_forward_preflight_mode
= PFoff
;
224 enum vt100state_e vt100state
;
226 int vc_wrap_mode
, vc_relative_origin
;
227 int vc_charset_select
, vc_save_charset_s
;
229 int vc_charset_save
[2];
231 int x
, y
, savex
, savey
;
232 int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
235 int scrreg_top
, scrreg_bottom
;
237 unsigned long vc_color_fore
;
238 unsigned long vc_color_back
;
239 } vc_forward_preflight_save
;
240 static int vc_forward_scroll
= 0;
241 #endif FAST_JUMP_SCROLL
244 * New Rendering code from Michel Pollet
247 /* That function will be called for drawing */
248 static void (*vc_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
250 #ifdef RENDERALLOCATE
251 unsigned char *renderedFont
= NULL
; /* rendered font buffer */
253 #define REN_MAX_DEPTH 32
254 /* that's the size for a 32 bits buffer... */
255 #define REN_MAX_SIZE (128L*1024)
256 unsigned char renderedFont
[REN_MAX_SIZE
];
259 /* Rendered Font Size */
260 unsigned long vc_rendered_font_size
= REN_MAX_SIZE
;
261 long vc_rendered_error
= 0;
263 /* If the one bit table was reversed */
264 short vc_one_bit_reversed
= 0;
266 /* Size of a character in the table (bytes) */
267 int vc_rendered_char_size
= 0;
271 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
273 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
274 # Background color codes:
275 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
278 #define VC_RESET_BACKGROUND 40
279 #define VC_RESET_FOREGROUND 37
281 static void vc_color_set(int color
)
283 if (vinfo
.v_depth
< 8)
285 if (color
>= 30 && color
<= 37)
286 vc_color_fore
= vc_colors
[color
-30][vc_color_index_table
[vinfo
.v_depth
]];
287 if (color
>= 40 && color
<= 47) {
288 vc_color_back
= vc_colors
[color
-40][vc_color_index_table
[vinfo
.v_depth
]];
289 vc_normal_background
= color
== 40;
294 static void vc_render_font(short olddepth
, short newdepth
)
296 int charIndex
; /* index in ISO font */
298 unsigned char *charptr
;
299 unsigned short *shortptr
;
300 unsigned long *longptr
;
301 } current
; /* current place in rendered font, multiple types. */
303 unsigned char *theChar
; /* current char in iso_font */
305 if (olddepth
== newdepth
&& renderedFont
) {
306 return; /* nothing to do */
309 if (olddepth
!= 1 && renderedFont
) {
310 #ifdef RENDERALLOCATE
311 (void) kmem_free(kernel_map
, (vm_offset_t
*)renderedFont
, vc_rendered_font_size
);
314 vc_rendered_font_size
= REN_MAX_SIZE
;
316 #ifdef RENDERALLOCATE
317 renderedFont
= iso_font
;
319 vc_rendered_char_size
= 16;
320 if (!vc_one_bit_reversed
) { /* reverse the font for the blitter */
322 for (i
= 0; i
< ((ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
); i
++) {
324 unsigned char mask1
= 0x80;
325 unsigned char mask2
= 0x01;
326 unsigned char val
= 0;
328 if (iso_font
[i
] & mask1
)
333 renderedFont
[i
] = ~val
;
334 } else renderedFont
[i
] = 0xff;
336 vc_one_bit_reversed
= 1;
341 long csize
= newdepth
/ 8; /* bytes per pixel */
342 vc_rendered_char_size
= csize
? CHARHEIGHT
* (csize
* CHARWIDTH
) :
343 /* for 2 & 4 */ CHARHEIGHT
* (CHARWIDTH
/(6-newdepth
));
344 csize
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
;
345 #ifndef RENDERALLOCATE
346 if (csize
> vc_rendered_font_size
) {
347 vc_rendered_error
= csize
;
350 vc_rendered_font_size
= csize
;
352 vc_rendered_font_size
= csize
;
356 #ifdef RENDERALLOCATE
357 if (kmem_alloc(kernel_map
,
358 (vm_offset_t
*)&renderedFont
,
359 vc_rendered_font_size
) != KERN_SUCCESS
) {
361 vc_rendered_error
= vc_rendered_font_size
;
365 current
.charptr
= renderedFont
;
367 for (charIndex
= ISO_CHAR_MIN
; charIndex
<= ISO_CHAR_MAX
; charIndex
++) {
369 for (line
= 0; line
< CHARHEIGHT
; line
++) {
370 unsigned char mask
= 1;
374 unsigned char value
= 0;
375 if (*theChar
& mask
) value
|= 0xC0; mask
<<= 1;
376 if (*theChar
& mask
) value
|= 0x30; mask
<<= 1;
377 if (*theChar
& mask
) value
|= 0x0C; mask
<<= 1;
378 if (*theChar
& mask
) value
|= 0x03;
380 *current
.charptr
++ = value
;
385 unsigned char value
= 0;
386 if (*theChar
& mask
) value
|= 0xF0; mask
<<= 1;
387 if (*theChar
& mask
) value
|= 0x0F;
389 *current
.charptr
++ = value
;
393 *current
.charptr
++ = (*theChar
& mask
) ? 0xff : 0;
396 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
400 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
404 } while (mask
); /* while the single bit drops to the right */
410 #ifdef FAST_JUMP_SCROLL
411 static void vc_paint_char(unsigned char ch
, int xx
, int yy
, int attrs
)
413 switch (vc_forward_preflight_mode
) {
415 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
422 if (yy
>= scrreg_top
&& yy
< scrreg_bottom
) {
423 yy
-= vc_forward_scroll
;
424 if (yy
< scrreg_top
|| yy
>= scrreg_bottom
)
427 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
431 #endif FAST_JUMP_SCROLL
433 static void vc_paint_char1(unsigned char ch
, int xx
, int yy
, int attrs
)
435 unsigned char *theChar
;
436 unsigned char *where
;
439 theChar
= (unsigned char*)(renderedFont
+ (ch
* vc_rendered_char_size
));
440 where
= (unsigned char*)(vinfo
.v_baseaddr
+
441 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
444 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
447 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
448 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
449 unsigned char val
= *theChar
++, save
= val
;
450 if (attrs
& ATTR_BOLD
) { /* bold support */
451 unsigned char mask1
= 0xC0, mask2
= 0x40;
453 for (bit
= 0; bit
< 7; bit
++) {
454 if ((save
& mask1
) == mask2
)
460 if (attrs
& ATTR_REVERSE
) val
= ~val
;
461 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
464 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
469 static void vc_paint_char2(unsigned char ch
, int xx
, int yy
, int attrs
)
471 unsigned short *theChar
;
472 unsigned short *where
;
475 theChar
= (unsigned short*)(renderedFont
+ (ch
* vc_rendered_char_size
));
476 where
= (unsigned short*)(vinfo
.v_baseaddr
+
477 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
479 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
482 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
483 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
484 unsigned short val
= *theChar
++, save
= val
;
485 if (attrs
& ATTR_BOLD
) { /* bold support */
486 unsigned short mask1
= 0xF000, mask2
= 0x3000;
488 for (bit
= 0; bit
< 7; bit
++) {
489 if ((save
& mask1
) == mask2
)
495 if (attrs
& ATTR_REVERSE
) val
= ~val
;
496 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
499 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
504 static void vc_paint_char4(unsigned char ch
, int xx
, int yy
, int attrs
)
506 unsigned long *theChar
;
507 unsigned long *where
;
510 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
511 where
= (unsigned long*)(vinfo
.v_baseaddr
+
512 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
515 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
518 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
519 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
520 unsigned long val
= *theChar
++, save
= val
;
521 if (attrs
& ATTR_BOLD
) { /* bold support */
522 unsigned long mask1
= 0xff000000, mask2
= 0x0F000000;
524 for (bit
= 0; bit
< 7; bit
++) {
525 if ((save
& mask1
) == mask2
)
531 if (attrs
& ATTR_REVERSE
) val
= ~val
;
532 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
535 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
540 static void vc_paint_char8c(unsigned char ch
, int xx
, int yy
, int attrs
)
542 unsigned long *theChar
;
543 unsigned long *where
;
546 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
547 where
= (unsigned long*)(vinfo
.v_baseaddr
+
548 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
551 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attr? FLY !*/
552 unsigned long *store
= where
;
554 for (x
= 0; x
< 2; x
++) {
555 unsigned long val
= *theChar
++;
556 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
560 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
561 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
562 unsigned long *store
= where
, lastpixel
= 0;
564 for (x
= 0 ; x
< 2; x
++) {
565 unsigned long val
= *theChar
++, save
= val
;
566 if (attrs
& ATTR_BOLD
) { /* bold support */
567 if (lastpixel
&& !(save
& 0xFF000000))
569 if ((save
& 0xFFFF0000) == 0xFF000000)
571 if ((save
& 0x00FFFF00) == 0x00FF0000)
573 if ((save
& 0x0000FFFF) == 0x0000FF00)
576 if (attrs
& ATTR_REVERSE
) val
= ~val
;
577 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
579 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
581 lastpixel
= save
& 0xff;
584 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
588 static void vc_paint_char16c(unsigned char ch
, int xx
, int yy
, int attrs
)
590 unsigned long *theChar
;
591 unsigned long *where
;
594 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
595 where
= (unsigned long*)(vinfo
.v_baseaddr
+
596 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
597 (xx
* CHARWIDTH
* 2));
599 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
600 unsigned long *store
= where
;
602 for (x
= 0; x
< 4; x
++) {
603 unsigned long val
= *theChar
++;
604 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
608 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
609 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
610 unsigned long *store
= where
, lastpixel
= 0;
612 for (x
= 0 ; x
< 4; x
++) {
613 unsigned long val
= *theChar
++, save
= val
;
614 if (attrs
& ATTR_BOLD
) { /* bold support */
615 if (save
== 0xFFFF0000) val
|= 0xFFFF;
616 else if (lastpixel
&& !(save
& 0xFFFF0000))
619 if (attrs
& ATTR_REVERSE
) val
= ~val
;
620 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
622 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
625 lastpixel
= save
& 0x7fff;
628 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
632 static void vc_paint_char32c(unsigned char ch
, int xx
, int yy
, int attrs
)
634 unsigned long *theChar
;
635 unsigned long *where
;
638 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
639 where
= (unsigned long*)(vinfo
.v_baseaddr
+
640 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
641 (xx
* CHARWIDTH
* 4));
643 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
644 unsigned long *store
= where
;
646 for (x
= 0; x
< 8; x
++) {
647 unsigned long val
= *theChar
++;
648 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
652 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
653 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
654 unsigned long *store
= where
, lastpixel
= 0;
656 for (x
= 0 ; x
< 8; x
++) {
657 unsigned long val
= *theChar
++, save
= val
;
658 if (attrs
& ATTR_BOLD
) { /* bold support */
659 if (lastpixel
&& !save
)
662 if (attrs
& ATTR_REVERSE
) val
= ~val
;
663 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
665 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
670 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
676 * That's a plain dumb reverse of the cursor position
677 * It do a binary reverse, so it will not looks good when we have
678 * color support. we'll see that later
680 static void reversecursor(void)
683 unsigned char *charptr
;
684 unsigned short *shortptr
;
685 unsigned long *longptr
;
689 where
.longptr
= (unsigned long*)(vinfo
.v_baseaddr
+
690 (y
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
691 (x
/** CHARWIDTH*/ * vinfo
.v_depth
));
692 for (line
= 0; line
< CHARHEIGHT
; line
++) {
693 switch (vinfo
.v_depth
) {
695 *where
.charptr
= ~*where
.charptr
;
698 *where
.shortptr
= ~*where
.shortptr
;
701 *where
.longptr
= ~*where
.longptr
;
703 /* that code still exists because since characters on the screen are
704 * of different colors that reverse function may not work if the
705 * cursor is on a character that is in a different color that the
706 * current one. When we have buffering, things will work better. MP
708 #ifdef VC_BINARY_REVERSE
710 where
.longptr
[0] = ~where
.longptr
[0];
711 where
.longptr
[1] = ~where
.longptr
[1];
714 for (col
= 0; col
< 4; col
++)
715 where
.longptr
[col
] = ~where
.longptr
[col
];
718 for (col
= 0; col
< 8; col
++)
719 where
.longptr
[col
] = ~where
.longptr
[col
];
723 for (col
= 0; col
< 8; col
++)
724 where
.charptr
[col
] = where
.charptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
725 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
728 for (col
= 0; col
< 8; col
++)
729 where
.shortptr
[col
] = where
.shortptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
730 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
733 for (col
= 0; col
< 8; col
++)
734 where
.longptr
[col
] = where
.longptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
735 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
739 where
.charptr
+= vinfo
.v_rowbytes
;
747 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
749 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
750 rowline
= (vinfo
.v_rowbytes
) >> 2;
751 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
753 #ifdef FAST_JUMP_SCROLL
754 if (vc_forward_preflight_mode
== PFwind
) {
755 vc_forward_scroll
+= num
;
758 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
759 #endif FAST_JUMP_SCROLL
761 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
762 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
764 i
= (scrreg_bottom
- scrreg_top
) - num
;
767 for (line
= 0; line
< CHARHEIGHT
; line
++) {
769 * Only copy what is displayed
771 video_scroll_up((unsigned int) from
,
772 (unsigned int) (from
+(vinfo
.v_rowscanbytes
/4)),
780 /* Now set the freed up lines to the background colour */
783 to
= ((unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
))
784 + ((scrreg_bottom
- scrreg_top
- num
) * linelongs
);
786 #ifdef FAST_JUMP_SCROLL
787 if (vc_forward_preflight_mode
== PFscroll
)
789 } else if (vc_forward_preflight_mode
== PFunwind
) {
790 long linestart
, linelast
;
791 vc_forward_scroll
-= num
;
793 linestart
= scrreg_bottom
- num
- vc_forward_scroll
;
794 linelast
= linestart
+ num
- 1;
796 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
799 if (linelast
>= scrreg_bottom
)
800 linelast
= scrreg_bottom
- 1;
801 if (linestart
< scrreg_top
)
802 linestart
= scrreg_top
;
804 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
805 num
= linelast
- linestart
+ 1;
807 #endif FAST_JUMP_SCROLL
809 for (linelongs
= CHARHEIGHT
* num
; linelongs
-- > 0;) {
811 for (i
= 0; i
< rowscanline
; i
++)
812 *to
++ = vc_color_back
;
822 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
824 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
825 rowline
= (vinfo
.v_rowbytes
) >> 2;
826 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
828 #ifdef FAST_JUMP_SCROLL
829 if (vc_forward_preflight_mode
== PFwind
) {
830 vc_forward_scroll
-= num
;
833 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
834 #endif FAST_JUMP_SCROLL
836 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
837 - (rowline
- rowscanline
);
838 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
840 i
= (scrreg_bottom
- scrreg_top
) - num
;
843 for (line
= 0; line
< CHARHEIGHT
; line
++) {
845 * Only copy what is displayed
847 video_scroll_down((unsigned int) from
,
848 (unsigned int) (from
-(vinfo
.v_rowscanbytes
/4)),
856 /* Now set the freed up lines to the background colour */
858 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_top
);
860 #ifdef FAST_JUMP_SCROLL
861 if (vc_forward_preflight_mode
== PFscroll
)
863 } else if (vc_forward_preflight_mode
== PFunwind
) {
864 long linestart
, linelast
;
865 vc_forward_scroll
+= num
;
867 linestart
= scrreg_top
- vc_forward_scroll
;
868 linelast
= linestart
+ num
- 1;
870 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
873 if (linelast
>= scrreg_bottom
)
874 linelast
= scrreg_bottom
- 1;
875 if (linestart
< scrreg_top
)
876 linestart
= scrreg_top
;
878 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
879 num
= linelast
- linestart
+ 1;
881 #endif FAST_JUMP_SCROLL
883 for (line
= CHARHEIGHT
* num
; line
> 0; line
--) {
886 for (i
= 0; i
< rowscanline
; i
++)
887 *(to
++) = vc_color_back
;
896 clear_line(int which
)
901 * This routine runs extremely slowly. I don't think it's
902 * used all that often, except for To end of line. I'll go
903 * back and speed this up when I speed up the whole vc
908 case 0: /* To end of line */
910 end
= vinfo
.v_columns
-1;
912 case 1: /* To start of line */
916 case 2: /* Whole line */
918 end
= vinfo
.v_columns
-1;
922 for (i
= start
; i
<= end
; i
++) {
923 vc_paintchar(' ', i
, y
, ATTR_NONE
);
929 clear_screen(int which
)
931 unsigned long *p
, *endp
, *row
;
933 int rowline
, rowlongs
;
935 rowline
= vinfo
.v_rowscanbytes
/ 4;
936 rowlongs
= vinfo
.v_rowbytes
/ 4;
938 p
= (unsigned long*) vinfo
.v_baseaddr
;;
939 endp
= (unsigned long*) vinfo
.v_baseaddr
;
941 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
944 case 0: /* To end of screen */
946 if (y
< vinfo
.v_rows
- 1) {
947 p
+= (y
+ 1) * linelongs
;
948 endp
+= rowlongs
* vinfo
.v_height
;
951 case 1: /* To start of screen */
954 endp
+= (y
+ 1) * linelongs
;
957 case 2: /* Whole screen */
958 endp
+= rowlongs
* vinfo
.v_height
;
962 for (row
= p
; row
< endp
; row
+= rowlongs
) {
963 for (col
= 0; col
< rowline
; col
++)
964 *(row
+col
) = vc_color_back
;
974 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
975 tab_stops
[i
] = ((i
% 8) == 0);
985 scrreg_bottom
= vinfo
.v_rows
;
987 vc_charset
[0] = vc_charset
[1] = 0;
988 vc_charset_select
= 0;
990 vc_relative_origin
= 0;
991 vc_color_set(VC_RESET_BACKGROUND
);
992 vc_color_set(VC_RESET_FOREGROUND
);
997 putc_normal(unsigned char ch
)
1000 case '\a': /* Beep */
1002 extern int asc_ringbell(); //In IOBSDConsole.cpp
1006 rang
= asc_ringbell();
1010 * No sound hardware, invert the screen twice instead
1014 /* XOR the screen twice */
1015 for (i
= 0; i
< 2 ; i
++) {
1016 /* For each row, xor the scanbytes */
1017 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
1018 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
1019 (vinfo
.v_height
* vinfo
.v_rowbytes
));
1020 ptr
+= (vinfo
.v_rowbytes
/
1021 sizeof (unsigned long*)))
1023 j
< vinfo
.v_rowscanbytes
/
1024 sizeof (unsigned long*);
1026 *(ptr
+j
) =~*(ptr
+j
);
1032 case 127: /* Delete */
1033 case '\b': /* Backspace */
1034 if (hanging_cursor
) {
1041 case '\t': /* Tab */
1042 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
1043 if (x
>= vinfo
.v_columns
)
1044 x
= vinfo
.v_columns
-1;
1048 case '\n': /* Line feed */
1049 if (y
>= scrreg_bottom
-1 ) {
1051 y
= scrreg_bottom
- 1;
1056 case '\r': /* Carriage return */
1060 case 0x0e: /* Select G1 charset (Control-N) */
1061 vc_charset_select
= 1;
1063 case 0x0f: /* Select G0 charset (Control-O) */
1064 vc_charset_select
= 0;
1066 case 0x18 : /* CAN : cancel */
1067 case 0x1A : /* like cancel */
1068 /* well, i do nothing here, may be later */
1070 case '\033': /* Escape */
1076 if (hanging_cursor
) {
1078 if (y
>= scrreg_bottom
-1 ) {
1080 y
= scrreg_bottom
- 1;
1086 vc_paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
1088 if (x
== vinfo
.v_columns
- 1) {
1089 hanging_cursor
= vc_wrap_mode
;
1100 putc_esc(unsigned char ch
)
1102 vt100state
= ESnormal
;
1106 vt100state
= ESsquare
;
1108 case 'c': /* Reset terminal */
1113 case 'D': /* Line feed */
1115 if (y
>= scrreg_bottom
-1) {
1117 y
= scrreg_bottom
- 1;
1121 if (ch
== 'E') x
= 0;
1123 case 'H': /* Set tab stop */
1126 case 'M': /* Cursor up */
1127 if (y
<= scrreg_top
) {
1137 case '7': /* Save cursor */
1141 vc_save_charset_s
= vc_charset_select
;
1142 vc_charset_save
[0] = vc_charset
[0];
1143 vc_charset_save
[1] = vc_charset
[1];
1145 case '8': /* Restore cursor */
1149 vc_charset_select
= vc_save_charset_s
;
1150 vc_charset
[0] = vc_charset_save
[0];
1151 vc_charset
[1] = vc_charset_save
[1];
1153 case 'Z': /* return terminal ID */
1155 case '#': /* change characters height */
1156 vt100state
= EScharsize
;
1159 vt100state
= ESsetG0
;
1161 case ')': /* character set sequence */
1162 vt100state
= ESsetG1
;
1167 /* Rest not supported */
1174 putc_askcmd(unsigned char ch
)
1176 if (ch
>= '0' && ch
<= '9') {
1177 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1180 vt100state
= ESnormal
;
1184 vc_relative_origin
= ch
== 'h';
1186 case 7: /* wrap around mode h=1, l=0*/
1187 vc_wrap_mode
= ch
== 'h';
1196 putc_charsizecmd(unsigned char ch
)
1198 vt100state
= ESnormal
;
1206 case '8' : /* fill 'E's */
1209 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1210 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1211 vc_paintchar('E', xx
, yy
, ATTR_NONE
);
1219 putc_charsetcmd(int charset
, unsigned char ch
)
1221 vt100state
= ESnormal
;
1227 vc_charset
[charset
] = 0;
1229 case '0' : /* Graphic characters */
1231 vc_charset
[charset
] = 0x21;
1238 putc_gotpars(unsigned char ch
)
1243 /* special case for vttest for handling cursor
1244 movement in escape sequences */
1246 vt100state
= ESgotpars
;
1249 vt100state
= ESnormal
;
1252 y
-= par
[0] ? par
[0] : 1;
1256 case 'B': /* Down */
1257 y
+= par
[0] ? par
[0] : 1;
1258 if (y
>= scrreg_bottom
)
1259 y
= scrreg_bottom
- 1;
1261 case 'C': /* Right */
1262 x
+= par
[0] ? par
[0] : 1;
1263 if (x
>= vinfo
.v_columns
)
1264 x
= vinfo
.v_columns
-1;
1266 case 'D': /* Left */
1267 x
-= par
[0] ? par
[0] : 1;
1271 case 'H': /* Set cursor position */
1273 x
= par
[1] ? par
[1] - 1 : 0;
1274 y
= par
[0] ? par
[0] - 1 : 0;
1275 if (vc_relative_origin
)
1279 case 'X': /* clear p1 characters */
1282 for (i
= x
; i
< x
+ par
[0]; i
++)
1283 vc_paintchar(' ', i
, y
, ATTR_NONE
);
1286 case 'J': /* Clear part of screen */
1287 clear_screen(par
[0]);
1289 case 'K': /* Clear part of line */
1292 case 'g': /* tab stops */
1295 case 2: /* reset tab stops */
1298 case 3: /* Clear every tabs */
1302 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1311 case 'm': /* Set attribute */
1312 for (i
= 0; i
< numpars
; i
++) {
1316 vc_color_set(VC_RESET_BACKGROUND
);
1317 vc_color_set(VC_RESET_FOREGROUND
);
1326 attr
|= ATTR_REVERSE
;
1332 attr
&= ~ATTR_UNDER
;
1335 attr
&= ~ATTR_REVERSE
;
1338 case 25: /* blink/no blink */
1341 vc_color_set(par
[i
]);
1346 case 'r': /* Set scroll region */
1348 /* ensure top < bottom, and both within limits */
1349 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1350 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1356 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1357 scrreg_bottom
= par
[1];
1358 if (scrreg_bottom
> vinfo
.v_rows
)
1359 scrreg_bottom
= vinfo
.v_rows
;
1361 scrreg_bottom
= vinfo
.v_rows
;
1363 if (vc_relative_origin
)
1371 putc_getpars(unsigned char ch
)
1378 vt100state
= ESnormal
;
1382 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1385 if (ch
>= '0' && ch
<= '9') {
1387 par
[numpars
] += ch
- '0';
1390 vt100state
= ESgotpars
;
1396 putc_square(unsigned char ch
)
1400 for (i
= 0; i
< MAXPARS
; i
++) {
1405 vt100state
= ESgetpars
;
1415 return; /* ignore null characters */
1417 switch (vt100state
) {
1418 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1438 putc_charsizecmd(ch
);
1441 putc_charsetcmd(0, ch
);
1444 putc_charsetcmd(1, ch
);
1448 if (x
>= vinfo
.v_columns
) {
1449 x
= vinfo
.v_columns
- 1;
1454 if (y
>= vinfo
.v_rows
) {
1455 y
= vinfo
.v_rows
- 1;
1464 * Actually draws the buffer, handle the jump scroll
1466 void vc_flush_forward_buffer(void)
1472 assert(vc_forward_buffer_enabled
);
1475 simple_lock(&vc_forward_lock
);
1477 if (vc_forward_buffer_busy
) {
1478 /* Bail out if we're already in the middle of a flush. */
1479 simple_unlock(&vc_forward_lock
);
1484 vc_forward_buffer_busy
= 1;
1486 while (todo
< vc_forward_buffer_size
) {
1487 todo
= vc_forward_buffer_size
;
1489 /* Drop the lock while we update the screen. */
1490 simple_unlock(&vc_forward_lock
);
1497 #ifdef FAST_JUMP_SCROLL
1498 if ((todo
- start
) < 2) {
1499 vc_putchar(vc_forward_buffer
[start
++]);
1501 assert(vc_forward_scroll
== 0);
1503 vc_forward_preflight_save
.vt100state
= vt100state
;
1504 vc_forward_preflight_save
.vc_wrap_mode
= vc_wrap_mode
;
1505 vc_forward_preflight_save
.vc_relative_origin
= vc_relative_origin
;
1506 vc_forward_preflight_save
.vc_charset_select
= vc_charset_select
;
1507 vc_forward_preflight_save
.vc_save_charset_s
= vc_save_charset_s
;
1508 vc_forward_preflight_save
.vc_charset
[0] = vc_charset
[0];
1509 vc_forward_preflight_save
.vc_charset
[1] = vc_charset
[1];
1510 vc_forward_preflight_save
.vc_charset_save
[0] = vc_charset_save
[0];
1511 vc_forward_preflight_save
.vc_charset_save
[1] = vc_charset_save
[1];
1512 vc_forward_preflight_save
.x
= x
;
1513 vc_forward_preflight_save
.y
= y
;
1514 vc_forward_preflight_save
.savex
= savex
;
1515 vc_forward_preflight_save
.savey
= savey
;
1516 vc_forward_preflight_save
.numpars
= numpars
;
1517 vc_forward_preflight_save
.hanging_cursor
= hanging_cursor
;
1518 vc_forward_preflight_save
.attr
= attr
;
1519 vc_forward_preflight_save
.saveattr
= saveattr
;
1520 vc_forward_preflight_save
.scrreg_top
= scrreg_top
;
1521 vc_forward_preflight_save
.scrreg_bottom
= scrreg_bottom
;
1522 vc_forward_preflight_save
.vc_color_fore
= vc_color_fore
;
1523 vc_forward_preflight_save
.vc_color_back
= vc_color_back
;
1524 bcopy( (const char *) par
,
1525 (char *) vc_forward_preflight_save
.par
,
1526 (vm_size_t
) sizeof(par
) );
1527 bcopy( (const char *) tab_stops
,
1528 (char *) vc_forward_preflight_save
.tab_stops
,
1529 (vm_size_t
) sizeof(tab_stops
) );
1531 vc_forward_preflight_mode
= PFwind
;
1535 vc_forward_preflight_save
.scrreg_top
== scrreg_top
&&
1536 vc_forward_preflight_save
.scrreg_bottom
== scrreg_bottom
;
1538 vc_putchar(vc_forward_buffer
[i
]);
1540 vt100state
= vc_forward_preflight_save
.vt100state
;
1541 vc_wrap_mode
= vc_forward_preflight_save
.vc_wrap_mode
;
1542 vc_relative_origin
= vc_forward_preflight_save
.vc_relative_origin
;
1543 vc_charset_select
= vc_forward_preflight_save
.vc_charset_select
;
1544 vc_save_charset_s
= vc_forward_preflight_save
.vc_save_charset_s
;
1545 vc_charset
[0] = vc_forward_preflight_save
.vc_charset
[0];
1546 vc_charset
[1] = vc_forward_preflight_save
.vc_charset
[1];
1547 vc_charset_save
[0] = vc_forward_preflight_save
.vc_charset_save
[0];
1548 vc_charset_save
[1] = vc_forward_preflight_save
.vc_charset_save
[1];
1549 x
= vc_forward_preflight_save
.x
;
1550 y
= vc_forward_preflight_save
.y
;
1551 savex
= vc_forward_preflight_save
.savex
;
1552 savey
= vc_forward_preflight_save
.savey
;
1553 numpars
= vc_forward_preflight_save
.numpars
;
1554 hanging_cursor
= vc_forward_preflight_save
.hanging_cursor
;
1555 attr
= vc_forward_preflight_save
.attr
;
1556 saveattr
= vc_forward_preflight_save
.saveattr
;
1557 scrreg_top
= vc_forward_preflight_save
.scrreg_top
;
1558 scrreg_bottom
= vc_forward_preflight_save
.scrreg_bottom
;
1559 vc_color_fore
= vc_forward_preflight_save
.vc_color_fore
;
1560 vc_color_back
= vc_forward_preflight_save
.vc_color_back
;
1561 bcopy( (const char *) vc_forward_preflight_save
.par
,
1563 (vm_size_t
) sizeof(par
) );
1564 bcopy( (const char *) vc_forward_preflight_save
.tab_stops
,
1566 (vm_size_t
) sizeof(tab_stops
) );
1568 vc_forward_preflight_mode
= PFscroll
;
1570 if (vc_forward_scroll
> 0)
1571 scrollup(vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1572 scrreg_bottom
- scrreg_top
: vc_forward_scroll
);
1573 else if (vc_forward_scroll
< 0)
1574 scrolldown(-vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1575 scrreg_bottom
- scrreg_top
: -vc_forward_scroll
);
1577 vc_forward_preflight_mode
= PFunwind
;
1579 for (; start
< i
; start
++)
1580 vc_putchar(vc_forward_buffer
[start
]);
1582 assert(vc_forward_scroll
== 0);
1584 vc_forward_preflight_mode
= PFoff
;
1586 #else !FAST_JUMP_SCROLL
1588 int drawlen
= start
;
1590 int param
= 0, changebackground
= 0;
1591 enum vt100state_e vtState
= vt100state
;
1593 * In simple words, here we're pre-parsing the text to look for
1594 * + Newlines, for computing jump scroll
1595 * + /\033\[[0-9;]*]m/ to continue on
1596 * any other sequence will stop. We don't want to have cursor
1597 * movement escape sequences while we're trying to pre-scroll
1599 * We have to be extra carefull about the sequences that changes
1600 * the background color to prevent scrolling in those
1602 * That parsing was added to speed up 'man' and 'color-ls' a
1603 * zillion time (at least). It's worth it, trust me.
1604 * (mail Nick Stephen for a True Performance Graph)
1607 for (i
= start
; i
< todo
&& plaintext
; i
++) {
1611 switch (vc_forward_buffer
[i
]) {
1621 switch (vc_forward_buffer
[i
]) {
1623 vtState
= ESgetpars
;
1625 changebackground
= 0;
1633 if ((vc_forward_buffer
[i
] >= '0' &&
1634 vc_forward_buffer
[i
] <= '9') ||
1635 vc_forward_buffer
[i
] == ';') {
1636 if (vc_forward_buffer
[i
] >= '0' &&
1637 vc_forward_buffer
[i
] <= '9')
1638 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1640 if (param
>= 40 && param
<= 47)
1641 changebackground
= 1;
1642 if (!vc_normal_background
&&
1644 changebackground
= 1;
1647 break; /* continue on */
1649 vtState
= ESgotpars
;
1652 switch (vc_forward_buffer
[i
]) {
1655 if (param
>= 40 && param
<= 47)
1656 changebackground
= 1;
1657 if (!vc_normal_background
&&
1659 changebackground
= 1;
1660 if (changebackground
) {
1663 /* REALLY don't jump */
1665 /* Yup ! we've got it */
1680 * Then we look if it would be appropriate to forward jump
1681 * the screen before drawing
1683 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1684 jump
-= scrreg_bottom
- y
- 1;
1686 if (jump
>= scrreg_bottom
- scrreg_top
)
1687 jump
= scrreg_bottom
- scrreg_top
-1;
1693 * and we draw what we've found to the parser
1695 for (i
= start
; i
< drawlen
; i
++)
1696 vc_putchar(vc_forward_buffer
[start
++]);
1698 * Continue sending characters to the parser until we're sure we're
1699 * back on normal characters.
1701 for (i
= start
; i
< todo
&&
1702 vt100state
!= ESnormal
; i
++)
1703 vc_putchar(vc_forward_buffer
[start
++]);
1704 #endif !FAST_JUMP_SCROLL
1705 /* Then loop again if there still things to draw */
1706 } while (start
< todo
);
1710 /* Re-acquire the lock while we check our state. */
1712 simple_lock(&vc_forward_lock
);
1715 vc_forward_buffer_busy
= 0;
1716 vc_forward_buffer_size
= 0;
1718 simple_unlock(&vc_forward_lock
);
1723 vcputc(int l
, int u
, int c
)
1726 * Either we're really buffering stuff or we're not yet because
1727 * the probe hasn't been done.
1729 if (vc_forward_buffer_enabled
)
1738 * Store characters to be drawn 'later', handle overflows
1742 vc_store_char(unsigned char c
)
1747 assert(vc_forward_buffer_enabled
);
1750 simple_lock(&vc_forward_lock
);
1752 /* Spin until the buffer has space for another character. */
1753 while (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
) {
1754 simple_unlock(&vc_forward_lock
);
1758 simple_lock(&vc_forward_lock
);
1761 assert(vc_forward_buffer_size
< VC_MAX_FORWARD_SIZE
);
1763 vc_forward_buffer
[vc_forward_buffer_size
++] = (unsigned char)c
;
1765 if (vc_forward_buffer_size
== 1) {
1766 /* If we're adding the first character to the buffer,
1767 * start the timer, otherwise it is already running.
1772 timeout((timeout_fcn_t
)vc_flush_forward_buffer
,
1774 VC_CONSOLE_UPDATE_TIMEOUT
);
1776 } else if (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
|| debug_mode
) {
1778 * If there is an overflow or this is an immediate character display
1779 * (eg. pre-clock printfs, panics), then we force a draw (take into
1780 * account that a flush might already be in progress).
1782 if (!vc_forward_buffer_busy
) {
1784 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
1788 simple_unlock(&vc_forward_lock
);
1793 * Immediate character display.. kernel printf uses this. Make sure
1794 * get flushed and that panics get fully displayed.
1796 vc_flush_forward_buffer();
1804 GratefulDebInit(); /* (TEST/DEBUG) */
1807 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1808 printf(" Video info: %d; video_board=%08X\n", i
, vboard
);
1809 printf(" Video name: %s\n", vinfo
.v_name
);
1810 printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
1811 vinfo
.v_height
, vinfo
.v_width
, vinfo
.v_depth
, vinfo
.v_rowbytes
, vinfo
.v_type
);
1812 printf(" physical address=%08X\n", vinfo
.v_physaddr
);
1815 vinfo
.v_rows
= vinfo
.v_height
/ CHARHEIGHT
;
1816 vinfo
.v_columns
= vinfo
.v_width
/ CHARWIDTH
;
1818 if (vinfo
.v_depth
>= 8) {
1819 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1821 vinfo
.v_rowscanbytes
= vinfo
.v_width
/ (8 / vinfo
.v_depth
);
1824 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1825 printf(" inited=%d\n", vc_initted
);
1829 vc_render_font(1, vinfo
.v_depth
);
1830 vc_color_mask
= vc_color_depth_masks
[vc_color_index_table
[vinfo
.v_depth
]];
1832 switch (vinfo
.v_depth
) {
1835 vc_paintchar
= vc_paint_char1
;
1838 vc_paintchar
= vc_paint_char2
;
1841 vc_paintchar
= vc_paint_char4
;
1844 vc_paintchar
= vc_paint_char8c
;
1847 vc_paintchar
= vc_paint_char16c
;
1850 vc_paintchar
= vc_paint_char32c
;
1854 #ifdef FAST_JUMP_SCROLL
1855 vc_forward_paintchar
= vc_paintchar
;
1856 vc_paintchar
= vc_paint_char
;
1857 #endif FAST_JUMP_SCROLL
1863 if (vinfo
.v_depth
>= 8)
1864 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1865 printf("video console at 0x%x (%dx%dx%d)\n", vinfo
.v_baseaddr
,
1866 vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_depth
);
1869 * Added for the buffering and jump scrolling
1872 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1874 vc_forward_buffer_enabled
= 1;
1879 struct vc_progress_element
{
1880 unsigned int version
;
1883 unsigned char count
;
1884 unsigned char res
[3];
1890 unsigned int res2
[3];
1891 unsigned char data
[0];
1893 typedef struct vc_progress_element vc_progress_element
;
1895 static vc_progress_element
* vc_progress
;
1896 static unsigned char * vc_progress_data
;
1897 static boolean_t vc_progress_enable
;
1898 static unsigned char * vc_clut
;
1899 static unsigned int vc_progress_tick
;
1900 static boolean_t vc_graphics_mode
;
1901 static boolean_t vc_acquired
;
1902 static boolean_t vc_need_clear
;
1904 void vc_blit_rect_8c( int x
, int y
,
1905 int width
, int height
,
1906 int transparent
, unsigned char * dataPtr
)
1908 volatile unsigned char * dst
;
1912 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1913 (y
* vinfo
.v_rowbytes
) +
1916 for( line
= 0; line
< height
; line
++) {
1917 for( col
= 0; col
< width
; col
++) {
1919 if( data
== transparent
)
1922 *(dst
+ col
) = data
;
1924 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1929 void vc_blit_rect_8m( int x
, int y
,
1930 int width
, int height
,
1931 int transparent
, unsigned char * dataPtr
)
1933 volatile unsigned char * dst
;
1937 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1938 (y
* vinfo
.v_rowbytes
) +
1941 for( line
= 0; line
< height
; line
++) {
1942 for( col
= 0; col
< width
; col
++) {
1944 if( data
== transparent
)
1948 *(dst
+ col
) = ((19595 * vc_clut
[data
+ 0] +
1949 38470 * vc_clut
[data
+ 1] +
1950 7471 * vc_clut
[data
+ 2] ) / 65536);
1952 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1958 void vc_blit_rect_16( int x
, int y
,
1959 int width
, int height
,
1960 int transparent
, unsigned char * dataPtr
)
1962 volatile unsigned short * dst
;
1966 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
1967 (y
* vinfo
.v_rowbytes
) +
1970 for( line
= 0; line
< height
; line
++) {
1971 for( col
= 0; col
< width
; col
++) {
1973 if( data
== transparent
)
1977 *(dst
+ col
) = ( (0xf8 & (vc_clut
[data
+ 0])) << 7)
1978 | ( (0xf8 & (vc_clut
[data
+ 1])) << 2)
1979 | ( (0xf8 & (vc_clut
[data
+ 2])) >> 3);
1981 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
1985 void vc_blit_rect_32( unsigned int x
, unsigned int y
,
1986 unsigned int width
, unsigned int height
,
1987 int transparent
, unsigned char * dataPtr
)
1989 volatile unsigned int * dst
;
1993 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
1994 (y
* vinfo
.v_rowbytes
) +
1997 for( line
= 0; line
< height
; line
++) {
1998 for( col
= 0; col
< width
; col
++) {
2000 if( data
== transparent
)
2004 *(dst
+ col
) = (vc_clut
[data
+ 0] << 16)
2005 | (vc_clut
[data
+ 1] << 8)
2006 | (vc_clut
[data
+ 2]);
2008 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2012 void vc_blit_rect( int x
, int y
,
2013 int width
, int height
,
2014 int transparent
, unsigned char * dataPtr
)
2016 switch( vinfo
.v_depth
) {
2018 vc_blit_rect_8c( x
, y
, width
, height
, transparent
, dataPtr
);
2021 vc_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
);
2024 vc_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
);
2029 void vc_progress_task( void * arg
)
2032 int count
= (int) arg
;
2033 int x
, y
, width
, height
;
2034 unsigned char * data
;
2037 simple_lock(&vc_forward_lock
);
2039 if( vc_progress_enable
) {
2041 if( count
>= vc_progress
->count
)
2044 width
= vc_progress
->width
;
2045 height
= vc_progress
->height
;
2046 x
= vc_progress
->dx
;
2047 y
= vc_progress
->dy
;
2048 data
= vc_progress_data
;
2049 data
+= count
* width
* height
;
2050 if( 1 & vc_progress
->flags
) {
2051 x
+= (vinfo
.v_width
/ 2);
2052 x
+= (vinfo
.v_height
/ 2);
2054 vc_blit_rect( x
, y
, width
, height
,
2055 vc_progress
->transparent
,data
);
2057 timeout( vc_progress_task
, (void *) count
,
2060 simple_unlock(&vc_forward_lock
);
2064 void vc_display_icon( vc_progress_element
* desc
,
2065 unsigned char * data
)
2067 int x
, y
, width
, height
;
2069 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
2071 width
= desc
->width
;
2072 height
= desc
->height
;
2075 if( 1 & desc
->flags
) {
2076 x
+= (vinfo
.v_width
/ 2);
2077 y
+= (vinfo
.v_height
/ 2);
2079 vc_blit_rect( x
, y
, width
, height
, desc
->transparent
, data
);
2084 vc_progress_set( boolean_t enable
)
2092 simple_lock(&vc_forward_lock
);
2094 if( vc_progress_enable
!= enable
) {
2095 vc_progress_enable
= enable
;
2097 timeout(vc_progress_task
, (void *) 0,
2100 untimeout( vc_progress_task
, (void *) 0 );
2103 simple_unlock(&vc_forward_lock
);
2111 vc_progress_initialize( vc_progress_element
* desc
,
2112 unsigned char * data
,
2113 unsigned char * clut
)
2115 if( (!clut
) || (!desc
) || (!data
))
2120 vc_progress_data
= data
;
2121 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
2126 // FirmwareC.c needs:
2127 Boot_Video boot_video_info
;
2129 extern int disableConsoleOutput
;
2131 void vc_clear_screen( void )
2141 initialize_screen(Boot_Video
* boot_vinfo
, unsigned int op
)
2144 bcopy( (const void *) boot_vinfo
,
2145 (void *) &boot_video_info
,
2146 sizeof( boot_video_info
));
2148 vinfo
.v_name
[0] = 0;
2149 vinfo
.v_width
= boot_vinfo
->v_width
;
2150 vinfo
.v_height
= boot_vinfo
->v_height
;
2151 vinfo
.v_depth
= boot_vinfo
->v_depth
;
2152 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2153 vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
;
2154 vinfo
.v_baseaddr
= vinfo
.v_physaddr
;
2159 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2165 case kPEGraphicsMode
:
2166 vc_graphics_mode
= TRUE
;
2167 disableConsoleOutput
= TRUE
;
2172 vc_graphics_mode
= FALSE
;
2173 disableConsoleOutput
= FALSE
;
2179 vc_progress_set( FALSE
);
2180 disableConsoleOutput
= FALSE
;
2181 if( vc_need_clear
) {
2182 vc_need_clear
= FALSE
;
2187 case kPEEnableScreen
:
2189 if( vc_graphics_mode
)
2190 vc_progress_set( TRUE
);
2196 case kPEDisableScreen
:
2197 vc_progress_set( FALSE
);
2200 case kPEAcquireScreen
:
2201 vc_need_clear
= (FALSE
== vc_acquired
);
2203 vc_progress_set( vc_graphics_mode
);
2204 disableConsoleOutput
= vc_graphics_mode
;
2205 if( vc_need_clear
&& !vc_graphics_mode
) {
2206 vc_need_clear
= FALSE
;
2211 case kPEReleaseScreen
:
2212 vc_acquired
= FALSE
;
2213 vc_progress_set( FALSE
);
2214 disableConsoleOutput
= TRUE
;
2216 GratefulDebInit(0); /* Stop grateful debugger */
2221 if( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */