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 static void vc_initialize(void);
159 static void vc_flush_forward_buffer(void);
160 static void vc_store_char(unsigned char);
161 static void vc_putchar(char ch
);
167 * For the color support (Michel Pollet)
169 static unsigned char vc_color_index_table
[33] =
170 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
173 static unsigned long vc_color_depth_masks
[4] =
174 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
176 static unsigned long vc_colors
[8][3] = {
177 { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
178 { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
179 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
180 { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
181 { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
182 // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
183 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
184 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
185 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
188 static unsigned long vc_color_mask
= 0;
189 static unsigned long vc_color_fore
= 0;
190 static unsigned long vc_color_back
= 0;
191 static int vc_normal_background
= 1;
195 * For the jump scroll and buffering (Michel Pollet)
196 * 80*22 means on a 80*24 screen, the screen will
197 * scroll jump almost a full screen
198 * keeping only what's necessary for you to be able to read ;-)
200 #define VC_MAX_FORWARD_SIZE (100*36)
203 * Delay between console updates in clock hz units, the larger the
204 * delay the fuller the jump-scroll buffer will be and so the faster the
205 * (scrolling) output. The smaller the delay, the less jerky the
206 * display. Heuristics show that at 10 touch-typists (Mike!) complain
208 #define VC_CONSOLE_UPDATE_TIMEOUT 5
210 static unsigned char vc_forward_buffer
[VC_MAX_FORWARD_SIZE
];
211 static long vc_forward_buffer_size
= 0;
212 static int vc_forward_buffer_enabled
= 0;
213 static int vc_forward_buffer_busy
= 0;
214 decl_simple_lock_data(,vc_forward_lock
)
216 #ifdef FAST_JUMP_SCROLL
217 static void (*vc_forward_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
223 } vc_forward_preflight_mode
= PFoff
;
225 enum vt100state_e vt100state
;
227 int vc_wrap_mode
, vc_relative_origin
;
228 int vc_charset_select
, vc_save_charset_s
;
230 int vc_charset_save
[2];
232 int x
, y
, savex
, savey
;
233 int par
[MAXPARS
], numpars
, hanging_cursor
, attr
, saveattr
;
236 int scrreg_top
, scrreg_bottom
;
238 unsigned long vc_color_fore
;
239 unsigned long vc_color_back
;
240 } vc_forward_preflight_save
;
241 static int vc_forward_scroll
= 0;
242 #endif FAST_JUMP_SCROLL
245 * New Rendering code from Michel Pollet
248 /* That function will be called for drawing */
249 static void (*vc_paintchar
) (unsigned char c
, int x
, int y
, int attrs
);
251 #ifdef RENDERALLOCATE
252 static unsigned char *renderedFont
= NULL
; /* rendered font buffer */
254 #define REN_MAX_DEPTH 32
255 /* that's the size for a 32 bits buffer... */
256 #define REN_MAX_SIZE (128L*1024)
257 static unsigned char renderedFont
[REN_MAX_SIZE
];
260 /* Rendered Font Size */
261 static unsigned long vc_rendered_font_size
= REN_MAX_SIZE
;
262 static long vc_rendered_error
= 0;
264 /* If the one bit table was reversed */
265 static short vc_one_bit_reversed
= 0;
267 /* Size of a character in the table (bytes) */
268 static int vc_rendered_char_size
= 0;
272 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
274 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
275 # Background color codes:
276 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
279 #define VC_RESET_BACKGROUND 40
280 #define VC_RESET_FOREGROUND 37
282 static void vc_color_set(int color
)
284 if (vinfo
.v_depth
< 8)
286 if (color
>= 30 && color
<= 37)
287 vc_color_fore
= vc_colors
[color
-30][vc_color_index_table
[vinfo
.v_depth
]];
288 if (color
>= 40 && color
<= 47) {
289 vc_color_back
= vc_colors
[color
-40][vc_color_index_table
[vinfo
.v_depth
]];
290 vc_normal_background
= color
== 40;
295 static void vc_render_font(short olddepth
, short newdepth
)
297 int charIndex
; /* index in ISO font */
299 unsigned char *charptr
;
300 unsigned short *shortptr
;
301 unsigned long *longptr
;
302 } current
; /* current place in rendered font, multiple types. */
304 unsigned char *theChar
; /* current char in iso_font */
306 if (olddepth
== newdepth
&& renderedFont
) {
307 return; /* nothing to do */
310 if (olddepth
!= 1 && renderedFont
) {
311 #ifdef RENDERALLOCATE
312 (void) kmem_free(kernel_map
, (vm_offset_t
*)renderedFont
, vc_rendered_font_size
);
315 vc_rendered_font_size
= REN_MAX_SIZE
;
317 #ifdef RENDERALLOCATE
318 renderedFont
= iso_font
;
320 vc_rendered_char_size
= 16;
321 if (!vc_one_bit_reversed
) { /* reverse the font for the blitter */
323 for (i
= 0; i
< ((ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
); i
++) {
325 unsigned char mask1
= 0x80;
326 unsigned char mask2
= 0x01;
327 unsigned char val
= 0;
329 if (iso_font
[i
] & mask1
)
334 renderedFont
[i
] = ~val
;
335 } else renderedFont
[i
] = 0xff;
337 vc_one_bit_reversed
= 1;
342 long csize
= newdepth
/ 8; /* bytes per pixel */
343 vc_rendered_char_size
= csize
? CHARHEIGHT
* (csize
* CHARWIDTH
) :
344 /* for 2 & 4 */ CHARHEIGHT
* (CHARWIDTH
/(6-newdepth
));
345 csize
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * vc_rendered_char_size
;
346 #ifndef RENDERALLOCATE
347 if (csize
> vc_rendered_font_size
) {
348 vc_rendered_error
= csize
;
351 vc_rendered_font_size
= csize
;
353 vc_rendered_font_size
= csize
;
357 #ifdef RENDERALLOCATE
358 if (kmem_alloc(kernel_map
,
359 (vm_offset_t
*)&renderedFont
,
360 vc_rendered_font_size
) != KERN_SUCCESS
) {
362 vc_rendered_error
= vc_rendered_font_size
;
366 current
.charptr
= renderedFont
;
368 for (charIndex
= ISO_CHAR_MIN
; charIndex
<= ISO_CHAR_MAX
; charIndex
++) {
370 for (line
= 0; line
< CHARHEIGHT
; line
++) {
371 unsigned char mask
= 1;
375 unsigned char value
= 0;
376 if (*theChar
& mask
) value
|= 0xC0; mask
<<= 1;
377 if (*theChar
& mask
) value
|= 0x30; mask
<<= 1;
378 if (*theChar
& mask
) value
|= 0x0C; mask
<<= 1;
379 if (*theChar
& mask
) value
|= 0x03;
381 *current
.charptr
++ = value
;
386 unsigned char value
= 0;
387 if (*theChar
& mask
) value
|= 0xF0; mask
<<= 1;
388 if (*theChar
& mask
) value
|= 0x0F;
390 *current
.charptr
++ = value
;
394 *current
.charptr
++ = (*theChar
& mask
) ? 0xff : 0;
397 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
401 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
405 } while (mask
); /* while the single bit drops to the right */
411 #ifdef FAST_JUMP_SCROLL
412 static void vc_paint_char(unsigned char ch
, int xx
, int yy
, int attrs
)
414 switch (vc_forward_preflight_mode
) {
416 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
423 if (yy
>= scrreg_top
&& yy
< scrreg_bottom
) {
424 yy
-= vc_forward_scroll
;
425 if (yy
< scrreg_top
|| yy
>= scrreg_bottom
)
428 vc_forward_paintchar(ch
, xx
, yy
, attrs
);
432 #endif FAST_JUMP_SCROLL
434 static void vc_paint_char1(unsigned char ch
, int xx
, int yy
, int attrs
)
436 unsigned char *theChar
;
437 unsigned char *where
;
440 theChar
= (unsigned char*)(renderedFont
+ (ch
* vc_rendered_char_size
));
441 where
= (unsigned char*)(vinfo
.v_baseaddr
+
442 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
445 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
448 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
449 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
450 unsigned char val
= *theChar
++, save
= val
;
451 if (attrs
& ATTR_BOLD
) { /* bold support */
452 unsigned char mask1
= 0xC0, mask2
= 0x40;
454 for (bit
= 0; bit
< 7; bit
++) {
455 if ((save
& mask1
) == mask2
)
461 if (attrs
& ATTR_REVERSE
) val
= ~val
;
462 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
465 where
= (unsigned char*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
470 static void vc_paint_char2(unsigned char ch
, int xx
, int yy
, int attrs
)
472 unsigned short *theChar
;
473 unsigned short *where
;
476 theChar
= (unsigned short*)(renderedFont
+ (ch
* vc_rendered_char_size
));
477 where
= (unsigned short*)(vinfo
.v_baseaddr
+
478 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
480 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
483 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
484 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
485 unsigned short val
= *theChar
++, save
= val
;
486 if (attrs
& ATTR_BOLD
) { /* bold support */
487 unsigned short mask1
= 0xF000, mask2
= 0x3000;
489 for (bit
= 0; bit
< 7; bit
++) {
490 if ((save
& mask1
) == mask2
)
496 if (attrs
& ATTR_REVERSE
) val
= ~val
;
497 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
500 where
= (unsigned short*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
505 static void vc_paint_char4(unsigned char ch
, int xx
, int yy
, int attrs
)
507 unsigned long *theChar
;
508 unsigned long *where
;
511 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
512 where
= (unsigned long*)(vinfo
.v_baseaddr
+
513 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
516 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attributes ? FLY !!!! */
519 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
520 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
521 unsigned long val
= *theChar
++, save
= val
;
522 if (attrs
& ATTR_BOLD
) { /* bold support */
523 unsigned long mask1
= 0xff000000, mask2
= 0x0F000000;
525 for (bit
= 0; bit
< 7; bit
++) {
526 if ((save
& mask1
) == mask2
)
532 if (attrs
& ATTR_REVERSE
) val
= ~val
;
533 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
536 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
541 static void vc_paint_char8c(unsigned char ch
, int xx
, int yy
, int attrs
)
543 unsigned long *theChar
;
544 unsigned long *where
;
547 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
548 where
= (unsigned long*)(vinfo
.v_baseaddr
+
549 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
552 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attr? FLY !*/
553 unsigned long *store
= where
;
555 for (x
= 0; x
< 2; x
++) {
556 unsigned long val
= *theChar
++;
557 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
561 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
562 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
563 unsigned long *store
= where
, lastpixel
= 0;
565 for (x
= 0 ; x
< 2; x
++) {
566 unsigned long val
= *theChar
++, save
= val
;
567 if (attrs
& ATTR_BOLD
) { /* bold support */
568 if (lastpixel
&& !(save
& 0xFF000000))
570 if ((save
& 0xFFFF0000) == 0xFF000000)
572 if ((save
& 0x00FFFF00) == 0x00FF0000)
574 if ((save
& 0x0000FFFF) == 0x0000FF00)
577 if (attrs
& ATTR_REVERSE
) val
= ~val
;
578 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
580 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
582 lastpixel
= save
& 0xff;
585 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
589 static void vc_paint_char16c(unsigned char ch
, int xx
, int yy
, int attrs
)
591 unsigned long *theChar
;
592 unsigned long *where
;
595 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
596 where
= (unsigned long*)(vinfo
.v_baseaddr
+
597 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
598 (xx
* CHARWIDTH
* 2));
600 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
601 unsigned long *store
= where
;
603 for (x
= 0; x
< 4; x
++) {
604 unsigned long val
= *theChar
++;
605 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
609 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
610 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little bit slower */
611 unsigned long *store
= where
, lastpixel
= 0;
613 for (x
= 0 ; x
< 4; x
++) {
614 unsigned long val
= *theChar
++, save
= val
;
615 if (attrs
& ATTR_BOLD
) { /* bold support */
616 if (save
== 0xFFFF0000) val
|= 0xFFFF;
617 else if (lastpixel
&& !(save
& 0xFFFF0000))
620 if (attrs
& ATTR_REVERSE
) val
= ~val
;
621 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
623 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
626 lastpixel
= save
& 0x7fff;
629 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
633 static void vc_paint_char32c(unsigned char ch
, int xx
, int yy
, int attrs
)
635 unsigned long *theChar
;
636 unsigned long *where
;
639 theChar
= (unsigned long*)(renderedFont
+ (ch
* vc_rendered_char_size
));
640 where
= (unsigned long*)(vinfo
.v_baseaddr
+
641 (yy
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
642 (xx
* CHARWIDTH
* 4));
644 if (!attrs
) for (i
= 0; i
< CHARHEIGHT
; i
++) { /* No attrs ? FLY ! */
645 unsigned long *store
= where
;
647 for (x
= 0; x
< 8; x
++) {
648 unsigned long val
= *theChar
++;
649 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
653 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
654 } else for (i
= 0; i
< CHARHEIGHT
; i
++) { /* a little slower */
655 unsigned long *store
= where
, lastpixel
= 0;
657 for (x
= 0 ; x
< 8; x
++) {
658 unsigned long val
= *theChar
++, save
= val
;
659 if (attrs
& ATTR_BOLD
) { /* bold support */
660 if (lastpixel
&& !save
)
663 if (attrs
& ATTR_REVERSE
) val
= ~val
;
664 if (attrs
& ATTR_UNDER
&& i
== CHARHEIGHT
-1) val
= ~val
;
666 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
671 where
= (unsigned long*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
677 * That's a plain dumb reverse of the cursor position
678 * It do a binary reverse, so it will not looks good when we have
679 * color support. we'll see that later
681 static void reversecursor(void)
684 unsigned char *charptr
;
685 unsigned short *shortptr
;
686 unsigned long *longptr
;
690 where
.longptr
= (unsigned long*)(vinfo
.v_baseaddr
+
691 (y
* CHARHEIGHT
* vinfo
.v_rowbytes
) +
692 (x
/** CHARWIDTH*/ * vinfo
.v_depth
));
693 for (line
= 0; line
< CHARHEIGHT
; line
++) {
694 switch (vinfo
.v_depth
) {
696 *where
.charptr
= ~*where
.charptr
;
699 *where
.shortptr
= ~*where
.shortptr
;
702 *where
.longptr
= ~*where
.longptr
;
704 /* that code still exists because since characters on the screen are
705 * of different colors that reverse function may not work if the
706 * cursor is on a character that is in a different color that the
707 * current one. When we have buffering, things will work better. MP
709 #ifdef VC_BINARY_REVERSE
711 where
.longptr
[0] = ~where
.longptr
[0];
712 where
.longptr
[1] = ~where
.longptr
[1];
715 for (col
= 0; col
< 4; col
++)
716 where
.longptr
[col
] = ~where
.longptr
[col
];
719 for (col
= 0; col
< 8; col
++)
720 where
.longptr
[col
] = ~where
.longptr
[col
];
724 for (col
= 0; col
< 8; col
++)
725 where
.charptr
[col
] = where
.charptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
726 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
729 for (col
= 0; col
< 8; col
++)
730 where
.shortptr
[col
] = where
.shortptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
731 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
734 for (col
= 0; col
< 8; col
++)
735 where
.longptr
[col
] = where
.longptr
[col
] != (vc_color_fore
& vc_color_mask
) ?
736 vc_color_fore
& vc_color_mask
: vc_color_back
& vc_color_mask
;
740 where
.charptr
+= vinfo
.v_rowbytes
;
748 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
750 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
751 rowline
= (vinfo
.v_rowbytes
) >> 2;
752 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
754 #ifdef FAST_JUMP_SCROLL
755 if (vc_forward_preflight_mode
== PFwind
) {
756 vc_forward_scroll
+= num
;
759 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
760 #endif FAST_JUMP_SCROLL
762 to
= (unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
763 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
765 i
= (scrreg_bottom
- scrreg_top
) - num
;
768 for (line
= 0; line
< CHARHEIGHT
; line
++) {
770 * Only copy what is displayed
772 video_scroll_up((unsigned int) from
,
773 (unsigned int) (from
+(vinfo
.v_rowscanbytes
/4)),
781 /* Now set the freed up lines to the background colour */
784 to
= ((unsigned long *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
))
785 + ((scrreg_bottom
- scrreg_top
- num
) * linelongs
);
787 #ifdef FAST_JUMP_SCROLL
788 if (vc_forward_preflight_mode
== PFscroll
)
790 } else if (vc_forward_preflight_mode
== PFunwind
) {
791 long linestart
, linelast
;
792 vc_forward_scroll
-= num
;
794 linestart
= scrreg_bottom
- num
- vc_forward_scroll
;
795 linelast
= linestart
+ num
- 1;
797 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
800 if (linelast
>= scrreg_bottom
)
801 linelast
= scrreg_bottom
- 1;
802 if (linestart
< scrreg_top
)
803 linestart
= scrreg_top
;
805 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
806 num
= linelast
- linestart
+ 1;
808 #endif FAST_JUMP_SCROLL
810 for (linelongs
= CHARHEIGHT
* num
; linelongs
-- > 0;) {
812 for (i
= 0; i
< rowscanline
; i
++)
813 *to
++ = vc_color_back
;
823 unsigned long *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
825 linelongs
= (vinfo
.v_rowbytes
* CHARHEIGHT
) >> 2;
826 rowline
= (vinfo
.v_rowbytes
) >> 2;
827 rowscanline
= (vinfo
.v_rowscanbytes
) >> 2;
829 #ifdef FAST_JUMP_SCROLL
830 if (vc_forward_preflight_mode
== PFwind
) {
831 vc_forward_scroll
-= num
;
834 if (vc_forward_preflight_mode
== PFscroll
|| vc_forward_preflight_mode
== PFoff
) {
835 #endif FAST_JUMP_SCROLL
837 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
838 - (rowline
- rowscanline
);
839 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
841 i
= (scrreg_bottom
- scrreg_top
) - num
;
844 for (line
= 0; line
< CHARHEIGHT
; line
++) {
846 * Only copy what is displayed
848 video_scroll_down((unsigned int) from
,
849 (unsigned int) (from
-(vinfo
.v_rowscanbytes
/4)),
857 /* Now set the freed up lines to the background colour */
859 to
= (unsigned long *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_top
);
861 #ifdef FAST_JUMP_SCROLL
862 if (vc_forward_preflight_mode
== PFscroll
)
864 } else if (vc_forward_preflight_mode
== PFunwind
) {
865 long linestart
, linelast
;
866 vc_forward_scroll
+= num
;
868 linestart
= scrreg_top
- vc_forward_scroll
;
869 linelast
= linestart
+ num
- 1;
871 if (linestart
>= scrreg_bottom
|| linelast
< scrreg_top
)
874 if (linelast
>= scrreg_bottom
)
875 linelast
= scrreg_bottom
- 1;
876 if (linestart
< scrreg_top
)
877 linestart
= scrreg_top
;
879 to
= ((unsigned long *) vinfo
.v_baseaddr
) + (linelongs
* linestart
);
880 num
= linelast
- linestart
+ 1;
882 #endif FAST_JUMP_SCROLL
884 for (line
= CHARHEIGHT
* num
; line
> 0; line
--) {
887 for (i
= 0; i
< rowscanline
; i
++)
888 *(to
++) = vc_color_back
;
897 clear_line(int which
)
902 * This routine runs extremely slowly. I don't think it's
903 * used all that often, except for To end of line. I'll go
904 * back and speed this up when I speed up the whole vc
909 case 0: /* To end of line */
911 end
= vinfo
.v_columns
-1;
913 case 1: /* To start of line */
917 case 2: /* Whole line */
919 end
= vinfo
.v_columns
-1;
923 for (i
= start
; i
<= end
; i
++) {
924 vc_paintchar(' ', i
, y
, ATTR_NONE
);
930 clear_screen(int which
)
932 unsigned long *p
, *endp
, *row
;
934 int rowline
, rowlongs
;
936 rowline
= vinfo
.v_rowscanbytes
/ 4;
937 rowlongs
= vinfo
.v_rowbytes
/ 4;
939 p
= (unsigned long*) vinfo
.v_baseaddr
;;
940 endp
= (unsigned long*) vinfo
.v_baseaddr
;
942 linelongs
= vinfo
.v_rowbytes
* CHARHEIGHT
/ 4;
945 case 0: /* To end of screen */
947 if (y
< vinfo
.v_rows
- 1) {
948 p
+= (y
+ 1) * linelongs
;
949 endp
+= rowlongs
* vinfo
.v_height
;
952 case 1: /* To start of screen */
955 endp
+= (y
+ 1) * linelongs
;
958 case 2: /* Whole screen */
959 endp
+= rowlongs
* vinfo
.v_height
;
963 for (row
= p
; row
< endp
; row
+= rowlongs
) {
964 for (col
= 0; col
< rowline
; col
++)
965 *(row
+col
) = vc_color_back
;
975 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
976 tab_stops
[i
] = ((i
% 8) == 0);
986 scrreg_bottom
= vinfo
.v_rows
;
988 vc_charset
[0] = vc_charset
[1] = 0;
989 vc_charset_select
= 0;
991 vc_relative_origin
= 0;
992 vc_color_set(VC_RESET_BACKGROUND
);
993 vc_color_set(VC_RESET_FOREGROUND
);
998 putc_normal(unsigned char ch
)
1001 case '\a': /* Beep */
1007 * No sound hardware, invert the screen twice instead
1011 /* XOR the screen twice */
1012 for (i
= 0; i
< 2 ; i
++) {
1013 /* For each row, xor the scanbytes */
1014 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
1015 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
1016 (vinfo
.v_height
* vinfo
.v_rowbytes
));
1017 ptr
+= (vinfo
.v_rowbytes
/
1018 sizeof (unsigned long*)))
1020 j
< vinfo
.v_rowscanbytes
/
1021 sizeof (unsigned long*);
1023 *(ptr
+j
) =~*(ptr
+j
);
1029 case 127: /* Delete */
1030 case '\b': /* Backspace */
1031 if (hanging_cursor
) {
1038 case '\t': /* Tab */
1039 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
1040 if (x
>= vinfo
.v_columns
)
1041 x
= vinfo
.v_columns
-1;
1045 case '\n': /* Line feed */
1046 if (y
>= scrreg_bottom
-1 ) {
1048 y
= scrreg_bottom
- 1;
1053 case '\r': /* Carriage return */
1057 case 0x0e: /* Select G1 charset (Control-N) */
1058 vc_charset_select
= 1;
1060 case 0x0f: /* Select G0 charset (Control-O) */
1061 vc_charset_select
= 0;
1063 case 0x18 : /* CAN : cancel */
1064 case 0x1A : /* like cancel */
1065 /* well, i do nothing here, may be later */
1067 case '\033': /* Escape */
1073 if (hanging_cursor
) {
1075 if (y
>= scrreg_bottom
-1 ) {
1077 y
= scrreg_bottom
- 1;
1083 vc_paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
1085 if (x
== vinfo
.v_columns
- 1) {
1086 hanging_cursor
= vc_wrap_mode
;
1097 putc_esc(unsigned char ch
)
1099 vt100state
= ESnormal
;
1103 vt100state
= ESsquare
;
1105 case 'c': /* Reset terminal */
1110 case 'D': /* Line feed */
1112 if (y
>= scrreg_bottom
-1) {
1114 y
= scrreg_bottom
- 1;
1118 if (ch
== 'E') x
= 0;
1120 case 'H': /* Set tab stop */
1123 case 'M': /* Cursor up */
1124 if (y
<= scrreg_top
) {
1134 case '7': /* Save cursor */
1138 vc_save_charset_s
= vc_charset_select
;
1139 vc_charset_save
[0] = vc_charset
[0];
1140 vc_charset_save
[1] = vc_charset
[1];
1142 case '8': /* Restore cursor */
1146 vc_charset_select
= vc_save_charset_s
;
1147 vc_charset
[0] = vc_charset_save
[0];
1148 vc_charset
[1] = vc_charset_save
[1];
1150 case 'Z': /* return terminal ID */
1152 case '#': /* change characters height */
1153 vt100state
= EScharsize
;
1156 vt100state
= ESsetG0
;
1158 case ')': /* character set sequence */
1159 vt100state
= ESsetG1
;
1164 /* Rest not supported */
1171 putc_askcmd(unsigned char ch
)
1173 if (ch
>= '0' && ch
<= '9') {
1174 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1177 vt100state
= ESnormal
;
1181 vc_relative_origin
= ch
== 'h';
1183 case 7: /* wrap around mode h=1, l=0*/
1184 vc_wrap_mode
= ch
== 'h';
1193 putc_charsizecmd(unsigned char ch
)
1195 vt100state
= ESnormal
;
1203 case '8' : /* fill 'E's */
1206 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1207 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1208 vc_paintchar('E', xx
, yy
, ATTR_NONE
);
1216 putc_charsetcmd(int charset
, unsigned char ch
)
1218 vt100state
= ESnormal
;
1224 vc_charset
[charset
] = 0;
1226 case '0' : /* Graphic characters */
1228 vc_charset
[charset
] = 0x21;
1235 putc_gotpars(unsigned char ch
)
1240 /* special case for vttest for handling cursor
1241 movement in escape sequences */
1243 vt100state
= ESgotpars
;
1246 vt100state
= ESnormal
;
1249 y
-= par
[0] ? par
[0] : 1;
1253 case 'B': /* Down */
1254 y
+= par
[0] ? par
[0] : 1;
1255 if (y
>= scrreg_bottom
)
1256 y
= scrreg_bottom
- 1;
1258 case 'C': /* Right */
1259 x
+= par
[0] ? par
[0] : 1;
1260 if (x
>= vinfo
.v_columns
)
1261 x
= vinfo
.v_columns
-1;
1263 case 'D': /* Left */
1264 x
-= par
[0] ? par
[0] : 1;
1268 case 'H': /* Set cursor position */
1270 x
= par
[1] ? par
[1] - 1 : 0;
1271 y
= par
[0] ? par
[0] - 1 : 0;
1272 if (vc_relative_origin
)
1276 case 'X': /* clear p1 characters */
1279 for (i
= x
; i
< x
+ par
[0]; i
++)
1280 vc_paintchar(' ', i
, y
, ATTR_NONE
);
1283 case 'J': /* Clear part of screen */
1284 clear_screen(par
[0]);
1286 case 'K': /* Clear part of line */
1289 case 'g': /* tab stops */
1292 case 2: /* reset tab stops */
1295 case 3: /* Clear every tabs */
1299 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1308 case 'm': /* Set attribute */
1309 for (i
= 0; i
< numpars
; i
++) {
1313 vc_color_set(VC_RESET_BACKGROUND
);
1314 vc_color_set(VC_RESET_FOREGROUND
);
1323 attr
|= ATTR_REVERSE
;
1329 attr
&= ~ATTR_UNDER
;
1332 attr
&= ~ATTR_REVERSE
;
1335 case 25: /* blink/no blink */
1338 vc_color_set(par
[i
]);
1343 case 'r': /* Set scroll region */
1345 /* ensure top < bottom, and both within limits */
1346 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1347 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1353 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1354 scrreg_bottom
= par
[1];
1355 if (scrreg_bottom
> vinfo
.v_rows
)
1356 scrreg_bottom
= vinfo
.v_rows
;
1358 scrreg_bottom
= vinfo
.v_rows
;
1360 if (vc_relative_origin
)
1368 putc_getpars(unsigned char ch
)
1375 vt100state
= ESnormal
;
1379 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1382 if (ch
>= '0' && ch
<= '9') {
1384 par
[numpars
] += ch
- '0';
1387 vt100state
= ESgotpars
;
1393 putc_square(unsigned char ch
)
1397 for (i
= 0; i
< MAXPARS
; i
++) {
1402 vt100state
= ESgetpars
;
1412 return; /* ignore null characters */
1414 switch (vt100state
) {
1415 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1435 putc_charsizecmd(ch
);
1438 putc_charsetcmd(0, ch
);
1441 putc_charsetcmd(1, ch
);
1445 if (x
>= vinfo
.v_columns
) {
1446 x
= vinfo
.v_columns
- 1;
1451 if (y
>= vinfo
.v_rows
) {
1452 y
= vinfo
.v_rows
- 1;
1461 * Actually draws the buffer, handle the jump scroll
1463 static void vc_flush_forward_buffer(void)
1469 assert(vc_forward_buffer_enabled
);
1472 simple_lock(&vc_forward_lock
);
1474 if (vc_forward_buffer_busy
) {
1475 /* Bail out if we're already in the middle of a flush. */
1476 simple_unlock(&vc_forward_lock
);
1481 vc_forward_buffer_busy
= 1;
1483 while (todo
< vc_forward_buffer_size
) {
1484 todo
= vc_forward_buffer_size
;
1486 /* Drop the lock while we update the screen. */
1487 simple_unlock(&vc_forward_lock
);
1494 #ifdef FAST_JUMP_SCROLL
1495 if ((todo
- start
) < 2) {
1496 vc_putchar(vc_forward_buffer
[start
++]);
1498 assert(vc_forward_scroll
== 0);
1500 vc_forward_preflight_save
.vt100state
= vt100state
;
1501 vc_forward_preflight_save
.vc_wrap_mode
= vc_wrap_mode
;
1502 vc_forward_preflight_save
.vc_relative_origin
= vc_relative_origin
;
1503 vc_forward_preflight_save
.vc_charset_select
= vc_charset_select
;
1504 vc_forward_preflight_save
.vc_save_charset_s
= vc_save_charset_s
;
1505 vc_forward_preflight_save
.vc_charset
[0] = vc_charset
[0];
1506 vc_forward_preflight_save
.vc_charset
[1] = vc_charset
[1];
1507 vc_forward_preflight_save
.vc_charset_save
[0] = vc_charset_save
[0];
1508 vc_forward_preflight_save
.vc_charset_save
[1] = vc_charset_save
[1];
1509 vc_forward_preflight_save
.x
= x
;
1510 vc_forward_preflight_save
.y
= y
;
1511 vc_forward_preflight_save
.savex
= savex
;
1512 vc_forward_preflight_save
.savey
= savey
;
1513 vc_forward_preflight_save
.numpars
= numpars
;
1514 vc_forward_preflight_save
.hanging_cursor
= hanging_cursor
;
1515 vc_forward_preflight_save
.attr
= attr
;
1516 vc_forward_preflight_save
.saveattr
= saveattr
;
1517 vc_forward_preflight_save
.scrreg_top
= scrreg_top
;
1518 vc_forward_preflight_save
.scrreg_bottom
= scrreg_bottom
;
1519 vc_forward_preflight_save
.vc_color_fore
= vc_color_fore
;
1520 vc_forward_preflight_save
.vc_color_back
= vc_color_back
;
1521 bcopy( (const char *) par
,
1522 (char *) vc_forward_preflight_save
.par
,
1523 (vm_size_t
) sizeof(par
) );
1524 bcopy( (const char *) tab_stops
,
1525 (char *) vc_forward_preflight_save
.tab_stops
,
1526 (vm_size_t
) sizeof(tab_stops
) );
1528 vc_forward_preflight_mode
= PFwind
;
1532 vc_forward_preflight_save
.scrreg_top
== scrreg_top
&&
1533 vc_forward_preflight_save
.scrreg_bottom
== scrreg_bottom
;
1535 vc_putchar(vc_forward_buffer
[i
]);
1537 vt100state
= vc_forward_preflight_save
.vt100state
;
1538 vc_wrap_mode
= vc_forward_preflight_save
.vc_wrap_mode
;
1539 vc_relative_origin
= vc_forward_preflight_save
.vc_relative_origin
;
1540 vc_charset_select
= vc_forward_preflight_save
.vc_charset_select
;
1541 vc_save_charset_s
= vc_forward_preflight_save
.vc_save_charset_s
;
1542 vc_charset
[0] = vc_forward_preflight_save
.vc_charset
[0];
1543 vc_charset
[1] = vc_forward_preflight_save
.vc_charset
[1];
1544 vc_charset_save
[0] = vc_forward_preflight_save
.vc_charset_save
[0];
1545 vc_charset_save
[1] = vc_forward_preflight_save
.vc_charset_save
[1];
1546 x
= vc_forward_preflight_save
.x
;
1547 y
= vc_forward_preflight_save
.y
;
1548 savex
= vc_forward_preflight_save
.savex
;
1549 savey
= vc_forward_preflight_save
.savey
;
1550 numpars
= vc_forward_preflight_save
.numpars
;
1551 hanging_cursor
= vc_forward_preflight_save
.hanging_cursor
;
1552 attr
= vc_forward_preflight_save
.attr
;
1553 saveattr
= vc_forward_preflight_save
.saveattr
;
1554 scrreg_top
= vc_forward_preflight_save
.scrreg_top
;
1555 scrreg_bottom
= vc_forward_preflight_save
.scrreg_bottom
;
1556 vc_color_fore
= vc_forward_preflight_save
.vc_color_fore
;
1557 vc_color_back
= vc_forward_preflight_save
.vc_color_back
;
1558 bcopy( (const char *) vc_forward_preflight_save
.par
,
1560 (vm_size_t
) sizeof(par
) );
1561 bcopy( (const char *) vc_forward_preflight_save
.tab_stops
,
1563 (vm_size_t
) sizeof(tab_stops
) );
1565 vc_forward_preflight_mode
= PFscroll
;
1567 if (vc_forward_scroll
> 0)
1568 scrollup(vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1569 scrreg_bottom
- scrreg_top
: vc_forward_scroll
);
1570 else if (vc_forward_scroll
< 0)
1571 scrolldown(-vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1572 scrreg_bottom
- scrreg_top
: -vc_forward_scroll
);
1574 vc_forward_preflight_mode
= PFunwind
;
1576 for (; start
< i
; start
++)
1577 vc_putchar(vc_forward_buffer
[start
]);
1579 assert(vc_forward_scroll
== 0);
1581 vc_forward_preflight_mode
= PFoff
;
1583 #else !FAST_JUMP_SCROLL
1585 int drawlen
= start
;
1587 int param
= 0, changebackground
= 0;
1588 enum vt100state_e vtState
= vt100state
;
1590 * In simple words, here we're pre-parsing the text to look for
1591 * + Newlines, for computing jump scroll
1592 * + /\033\[[0-9;]*]m/ to continue on
1593 * any other sequence will stop. We don't want to have cursor
1594 * movement escape sequences while we're trying to pre-scroll
1596 * We have to be extra carefull about the sequences that changes
1597 * the background color to prevent scrolling in those
1599 * That parsing was added to speed up 'man' and 'color-ls' a
1600 * zillion time (at least). It's worth it, trust me.
1601 * (mail Nick Stephen for a True Performance Graph)
1604 for (i
= start
; i
< todo
&& plaintext
; i
++) {
1608 switch (vc_forward_buffer
[i
]) {
1618 switch (vc_forward_buffer
[i
]) {
1620 vtState
= ESgetpars
;
1622 changebackground
= 0;
1630 if ((vc_forward_buffer
[i
] >= '0' &&
1631 vc_forward_buffer
[i
] <= '9') ||
1632 vc_forward_buffer
[i
] == ';') {
1633 if (vc_forward_buffer
[i
] >= '0' &&
1634 vc_forward_buffer
[i
] <= '9')
1635 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1637 if (param
>= 40 && param
<= 47)
1638 changebackground
= 1;
1639 if (!vc_normal_background
&&
1641 changebackground
= 1;
1644 break; /* continue on */
1646 vtState
= ESgotpars
;
1649 switch (vc_forward_buffer
[i
]) {
1652 if (param
>= 40 && param
<= 47)
1653 changebackground
= 1;
1654 if (!vc_normal_background
&&
1656 changebackground
= 1;
1657 if (changebackground
) {
1660 /* REALLY don't jump */
1662 /* Yup ! we've got it */
1677 * Then we look if it would be appropriate to forward jump
1678 * the screen before drawing
1680 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1681 jump
-= scrreg_bottom
- y
- 1;
1683 if (jump
>= scrreg_bottom
- scrreg_top
)
1684 jump
= scrreg_bottom
- scrreg_top
-1;
1690 * and we draw what we've found to the parser
1692 for (i
= start
; i
< drawlen
; i
++)
1693 vc_putchar(vc_forward_buffer
[start
++]);
1695 * Continue sending characters to the parser until we're sure we're
1696 * back on normal characters.
1698 for (i
= start
; i
< todo
&&
1699 vt100state
!= ESnormal
; i
++)
1700 vc_putchar(vc_forward_buffer
[start
++]);
1701 #endif !FAST_JUMP_SCROLL
1702 /* Then loop again if there still things to draw */
1703 } while (start
< todo
);
1707 /* Re-acquire the lock while we check our state. */
1709 simple_lock(&vc_forward_lock
);
1712 vc_forward_buffer_busy
= 0;
1713 vc_forward_buffer_size
= 0;
1715 simple_unlock(&vc_forward_lock
);
1720 vcputc(int l
, int u
, int c
)
1722 if(!vinfo
.v_baseaddr
)
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 static 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 static 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 static 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 static 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 static void vc_blit_rect( int x
, int y
,
2013 int width
, int height
,
2014 int transparent
, unsigned char * dataPtr
)
2016 if(!vinfo
.v_baseaddr
)
2019 switch( vinfo
.v_depth
) {
2021 vc_blit_rect_8c( x
, y
, width
, height
, transparent
, dataPtr
);
2024 vc_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
);
2027 vc_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
);
2032 static void vc_progress_task( void * arg
)
2035 int count
= (int) arg
;
2036 int x
, y
, width
, height
;
2037 unsigned char * data
;
2040 simple_lock(&vc_forward_lock
);
2042 if( vc_progress_enable
) {
2044 if( count
>= vc_progress
->count
)
2047 width
= vc_progress
->width
;
2048 height
= vc_progress
->height
;
2049 x
= vc_progress
->dx
;
2050 y
= vc_progress
->dy
;
2051 data
= vc_progress_data
;
2052 data
+= count
* width
* height
;
2053 if( 1 & vc_progress
->flags
) {
2054 x
+= (vinfo
.v_width
/ 2);
2055 x
+= (vinfo
.v_height
/ 2);
2057 vc_blit_rect( x
, y
, width
, height
,
2058 vc_progress
->transparent
,data
);
2060 timeout( vc_progress_task
, (void *) count
,
2063 simple_unlock(&vc_forward_lock
);
2067 void vc_display_icon( vc_progress_element
* desc
,
2068 unsigned char * data
)
2070 int x
, y
, width
, height
;
2072 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
2074 width
= desc
->width
;
2075 height
= desc
->height
;
2078 if( 1 & desc
->flags
) {
2079 x
+= (vinfo
.v_width
/ 2);
2080 y
+= (vinfo
.v_height
/ 2);
2082 vc_blit_rect( x
, y
, width
, height
, desc
->transparent
, data
);
2087 vc_progress_set( boolean_t enable
)
2095 simple_lock(&vc_forward_lock
);
2097 if( vc_progress_enable
!= enable
) {
2098 vc_progress_enable
= enable
;
2100 timeout(vc_progress_task
, (void *) 0,
2103 untimeout( vc_progress_task
, (void *) 0 );
2106 simple_unlock(&vc_forward_lock
);
2114 vc_progress_initialize( vc_progress_element
* desc
,
2115 unsigned char * data
,
2116 unsigned char * clut
)
2118 if( (!clut
) || (!desc
) || (!data
))
2123 vc_progress_data
= data
;
2124 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
2129 // FirmwareC.c needs:
2130 Boot_Video boot_video_info
;
2132 extern int disableConsoleOutput
;
2134 static void vc_clear_screen( void )
2144 initialize_screen(Boot_Video
* boot_vinfo
, unsigned int op
)
2147 bcopy( (const void *) boot_vinfo
,
2148 (void *) &boot_video_info
,
2149 sizeof( boot_video_info
));
2151 vinfo
.v_name
[0] = 0;
2152 vinfo
.v_width
= boot_vinfo
->v_width
;
2153 vinfo
.v_height
= boot_vinfo
->v_height
;
2154 vinfo
.v_depth
= boot_vinfo
->v_depth
;
2155 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2156 vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
;
2157 vinfo
.v_baseaddr
= vinfo
.v_physaddr
;
2162 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2168 case kPEGraphicsMode
:
2169 vc_graphics_mode
= TRUE
;
2170 disableConsoleOutput
= TRUE
;
2175 vc_graphics_mode
= FALSE
;
2176 disableConsoleOutput
= FALSE
;
2182 vc_progress_set( FALSE
);
2183 disableConsoleOutput
= FALSE
;
2184 if( vc_need_clear
) {
2185 vc_need_clear
= FALSE
;
2190 case kPEEnableScreen
:
2192 if( vc_graphics_mode
)
2193 vc_progress_set( TRUE
);
2199 case kPEDisableScreen
:
2200 vc_progress_set( FALSE
);
2203 case kPEAcquireScreen
:
2204 vc_need_clear
= (FALSE
== vc_acquired
);
2206 vc_progress_set( vc_graphics_mode
);
2207 disableConsoleOutput
= vc_graphics_mode
;
2208 if( vc_need_clear
&& !vc_graphics_mode
) {
2209 vc_need_clear
= FALSE
;
2214 case kPEReleaseScreen
:
2215 vc_acquired
= FALSE
;
2216 vc_progress_set( FALSE
);
2217 disableConsoleOutput
= TRUE
;
2219 GratefulDebInit(0); /* Stop grateful debugger */
2224 if( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */