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 */
1006 * No sound hardware, invert the screen twice instead
1010 /* XOR the screen twice */
1011 for (i
= 0; i
< 2 ; i
++) {
1012 /* For each row, xor the scanbytes */
1013 for (ptr
= (unsigned long*)vinfo
.v_baseaddr
;
1014 ptr
< (unsigned long*)(vinfo
.v_baseaddr
+
1015 (vinfo
.v_height
* vinfo
.v_rowbytes
));
1016 ptr
+= (vinfo
.v_rowbytes
/
1017 sizeof (unsigned long*)))
1019 j
< vinfo
.v_rowscanbytes
/
1020 sizeof (unsigned long*);
1022 *(ptr
+j
) =~*(ptr
+j
);
1028 case 127: /* Delete */
1029 case '\b': /* Backspace */
1030 if (hanging_cursor
) {
1037 case '\t': /* Tab */
1038 while (x
< vinfo
.v_columns
&& !tab_stops
[++x
]);
1039 if (x
>= vinfo
.v_columns
)
1040 x
= vinfo
.v_columns
-1;
1044 case '\n': /* Line feed */
1045 if (y
>= scrreg_bottom
-1 ) {
1047 y
= scrreg_bottom
- 1;
1052 case '\r': /* Carriage return */
1056 case 0x0e: /* Select G1 charset (Control-N) */
1057 vc_charset_select
= 1;
1059 case 0x0f: /* Select G0 charset (Control-O) */
1060 vc_charset_select
= 0;
1062 case 0x18 : /* CAN : cancel */
1063 case 0x1A : /* like cancel */
1064 /* well, i do nothing here, may be later */
1066 case '\033': /* Escape */
1072 if (hanging_cursor
) {
1074 if (y
>= scrreg_bottom
-1 ) {
1076 y
= scrreg_bottom
- 1;
1082 vc_paintchar((ch
>= 0x60 && ch
<= 0x7f) ? ch
+ vc_charset
[vc_charset_select
]
1084 if (x
== vinfo
.v_columns
- 1) {
1085 hanging_cursor
= vc_wrap_mode
;
1096 putc_esc(unsigned char ch
)
1098 vt100state
= ESnormal
;
1102 vt100state
= ESsquare
;
1104 case 'c': /* Reset terminal */
1109 case 'D': /* Line feed */
1111 if (y
>= scrreg_bottom
-1) {
1113 y
= scrreg_bottom
- 1;
1117 if (ch
== 'E') x
= 0;
1119 case 'H': /* Set tab stop */
1122 case 'M': /* Cursor up */
1123 if (y
<= scrreg_top
) {
1133 case '7': /* Save cursor */
1137 vc_save_charset_s
= vc_charset_select
;
1138 vc_charset_save
[0] = vc_charset
[0];
1139 vc_charset_save
[1] = vc_charset
[1];
1141 case '8': /* Restore cursor */
1145 vc_charset_select
= vc_save_charset_s
;
1146 vc_charset
[0] = vc_charset_save
[0];
1147 vc_charset
[1] = vc_charset_save
[1];
1149 case 'Z': /* return terminal ID */
1151 case '#': /* change characters height */
1152 vt100state
= EScharsize
;
1155 vt100state
= ESsetG0
;
1157 case ')': /* character set sequence */
1158 vt100state
= ESsetG1
;
1163 /* Rest not supported */
1170 putc_askcmd(unsigned char ch
)
1172 if (ch
>= '0' && ch
<= '9') {
1173 par
[numpars
] = (10*par
[numpars
]) + (ch
-'0');
1176 vt100state
= ESnormal
;
1180 vc_relative_origin
= ch
== 'h';
1182 case 7: /* wrap around mode h=1, l=0*/
1183 vc_wrap_mode
= ch
== 'h';
1192 putc_charsizecmd(unsigned char ch
)
1194 vt100state
= ESnormal
;
1202 case '8' : /* fill 'E's */
1205 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
1206 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
1207 vc_paintchar('E', xx
, yy
, ATTR_NONE
);
1215 putc_charsetcmd(int charset
, unsigned char ch
)
1217 vt100state
= ESnormal
;
1223 vc_charset
[charset
] = 0;
1225 case '0' : /* Graphic characters */
1227 vc_charset
[charset
] = 0x21;
1234 putc_gotpars(unsigned char ch
)
1239 /* special case for vttest for handling cursor
1240 movement in escape sequences */
1242 vt100state
= ESgotpars
;
1245 vt100state
= ESnormal
;
1248 y
-= par
[0] ? par
[0] : 1;
1252 case 'B': /* Down */
1253 y
+= par
[0] ? par
[0] : 1;
1254 if (y
>= scrreg_bottom
)
1255 y
= scrreg_bottom
- 1;
1257 case 'C': /* Right */
1258 x
+= par
[0] ? par
[0] : 1;
1259 if (x
>= vinfo
.v_columns
)
1260 x
= vinfo
.v_columns
-1;
1262 case 'D': /* Left */
1263 x
-= par
[0] ? par
[0] : 1;
1267 case 'H': /* Set cursor position */
1269 x
= par
[1] ? par
[1] - 1 : 0;
1270 y
= par
[0] ? par
[0] - 1 : 0;
1271 if (vc_relative_origin
)
1275 case 'X': /* clear p1 characters */
1278 for (i
= x
; i
< x
+ par
[0]; i
++)
1279 vc_paintchar(' ', i
, y
, ATTR_NONE
);
1282 case 'J': /* Clear part of screen */
1283 clear_screen(par
[0]);
1285 case 'K': /* Clear part of line */
1288 case 'g': /* tab stops */
1291 case 2: /* reset tab stops */
1294 case 3: /* Clear every tabs */
1298 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
1307 case 'm': /* Set attribute */
1308 for (i
= 0; i
< numpars
; i
++) {
1312 vc_color_set(VC_RESET_BACKGROUND
);
1313 vc_color_set(VC_RESET_FOREGROUND
);
1322 attr
|= ATTR_REVERSE
;
1328 attr
&= ~ATTR_UNDER
;
1331 attr
&= ~ATTR_REVERSE
;
1334 case 25: /* blink/no blink */
1337 vc_color_set(par
[i
]);
1342 case 'r': /* Set scroll region */
1344 /* ensure top < bottom, and both within limits */
1345 if ((numpars
> 0) && (par
[0] < vinfo
.v_rows
)) {
1346 scrreg_top
= par
[0] ? par
[0] - 1 : 0;
1352 if ((numpars
> 1) && (par
[1] <= vinfo
.v_rows
) && (par
[1] > par
[0])) {
1353 scrreg_bottom
= par
[1];
1354 if (scrreg_bottom
> vinfo
.v_rows
)
1355 scrreg_bottom
= vinfo
.v_rows
;
1357 scrreg_bottom
= vinfo
.v_rows
;
1359 if (vc_relative_origin
)
1367 putc_getpars(unsigned char ch
)
1374 vt100state
= ESnormal
;
1378 if (ch
== ';' && numpars
< MAXPARS
- 1) {
1381 if (ch
>= '0' && ch
<= '9') {
1383 par
[numpars
] += ch
- '0';
1386 vt100state
= ESgotpars
;
1392 putc_square(unsigned char ch
)
1396 for (i
= 0; i
< MAXPARS
; i
++) {
1401 vt100state
= ESgetpars
;
1411 return; /* ignore null characters */
1413 switch (vt100state
) {
1414 default:vt100state
= ESnormal
; /* FALLTHROUGH */
1434 putc_charsizecmd(ch
);
1437 putc_charsetcmd(0, ch
);
1440 putc_charsetcmd(1, ch
);
1444 if (x
>= vinfo
.v_columns
) {
1445 x
= vinfo
.v_columns
- 1;
1450 if (y
>= vinfo
.v_rows
) {
1451 y
= vinfo
.v_rows
- 1;
1460 * Actually draws the buffer, handle the jump scroll
1462 void vc_flush_forward_buffer(void)
1468 assert(vc_forward_buffer_enabled
);
1471 simple_lock(&vc_forward_lock
);
1473 if (vc_forward_buffer_busy
) {
1474 /* Bail out if we're already in the middle of a flush. */
1475 simple_unlock(&vc_forward_lock
);
1480 vc_forward_buffer_busy
= 1;
1482 while (todo
< vc_forward_buffer_size
) {
1483 todo
= vc_forward_buffer_size
;
1485 /* Drop the lock while we update the screen. */
1486 simple_unlock(&vc_forward_lock
);
1493 #ifdef FAST_JUMP_SCROLL
1494 if ((todo
- start
) < 2) {
1495 vc_putchar(vc_forward_buffer
[start
++]);
1497 assert(vc_forward_scroll
== 0);
1499 vc_forward_preflight_save
.vt100state
= vt100state
;
1500 vc_forward_preflight_save
.vc_wrap_mode
= vc_wrap_mode
;
1501 vc_forward_preflight_save
.vc_relative_origin
= vc_relative_origin
;
1502 vc_forward_preflight_save
.vc_charset_select
= vc_charset_select
;
1503 vc_forward_preflight_save
.vc_save_charset_s
= vc_save_charset_s
;
1504 vc_forward_preflight_save
.vc_charset
[0] = vc_charset
[0];
1505 vc_forward_preflight_save
.vc_charset
[1] = vc_charset
[1];
1506 vc_forward_preflight_save
.vc_charset_save
[0] = vc_charset_save
[0];
1507 vc_forward_preflight_save
.vc_charset_save
[1] = vc_charset_save
[1];
1508 vc_forward_preflight_save
.x
= x
;
1509 vc_forward_preflight_save
.y
= y
;
1510 vc_forward_preflight_save
.savex
= savex
;
1511 vc_forward_preflight_save
.savey
= savey
;
1512 vc_forward_preflight_save
.numpars
= numpars
;
1513 vc_forward_preflight_save
.hanging_cursor
= hanging_cursor
;
1514 vc_forward_preflight_save
.attr
= attr
;
1515 vc_forward_preflight_save
.saveattr
= saveattr
;
1516 vc_forward_preflight_save
.scrreg_top
= scrreg_top
;
1517 vc_forward_preflight_save
.scrreg_bottom
= scrreg_bottom
;
1518 vc_forward_preflight_save
.vc_color_fore
= vc_color_fore
;
1519 vc_forward_preflight_save
.vc_color_back
= vc_color_back
;
1520 bcopy( (const char *) par
,
1521 (char *) vc_forward_preflight_save
.par
,
1522 (vm_size_t
) sizeof(par
) );
1523 bcopy( (const char *) tab_stops
,
1524 (char *) vc_forward_preflight_save
.tab_stops
,
1525 (vm_size_t
) sizeof(tab_stops
) );
1527 vc_forward_preflight_mode
= PFwind
;
1531 vc_forward_preflight_save
.scrreg_top
== scrreg_top
&&
1532 vc_forward_preflight_save
.scrreg_bottom
== scrreg_bottom
;
1534 vc_putchar(vc_forward_buffer
[i
]);
1536 vt100state
= vc_forward_preflight_save
.vt100state
;
1537 vc_wrap_mode
= vc_forward_preflight_save
.vc_wrap_mode
;
1538 vc_relative_origin
= vc_forward_preflight_save
.vc_relative_origin
;
1539 vc_charset_select
= vc_forward_preflight_save
.vc_charset_select
;
1540 vc_save_charset_s
= vc_forward_preflight_save
.vc_save_charset_s
;
1541 vc_charset
[0] = vc_forward_preflight_save
.vc_charset
[0];
1542 vc_charset
[1] = vc_forward_preflight_save
.vc_charset
[1];
1543 vc_charset_save
[0] = vc_forward_preflight_save
.vc_charset_save
[0];
1544 vc_charset_save
[1] = vc_forward_preflight_save
.vc_charset_save
[1];
1545 x
= vc_forward_preflight_save
.x
;
1546 y
= vc_forward_preflight_save
.y
;
1547 savex
= vc_forward_preflight_save
.savex
;
1548 savey
= vc_forward_preflight_save
.savey
;
1549 numpars
= vc_forward_preflight_save
.numpars
;
1550 hanging_cursor
= vc_forward_preflight_save
.hanging_cursor
;
1551 attr
= vc_forward_preflight_save
.attr
;
1552 saveattr
= vc_forward_preflight_save
.saveattr
;
1553 scrreg_top
= vc_forward_preflight_save
.scrreg_top
;
1554 scrreg_bottom
= vc_forward_preflight_save
.scrreg_bottom
;
1555 vc_color_fore
= vc_forward_preflight_save
.vc_color_fore
;
1556 vc_color_back
= vc_forward_preflight_save
.vc_color_back
;
1557 bcopy( (const char *) vc_forward_preflight_save
.par
,
1559 (vm_size_t
) sizeof(par
) );
1560 bcopy( (const char *) vc_forward_preflight_save
.tab_stops
,
1562 (vm_size_t
) sizeof(tab_stops
) );
1564 vc_forward_preflight_mode
= PFscroll
;
1566 if (vc_forward_scroll
> 0)
1567 scrollup(vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1568 scrreg_bottom
- scrreg_top
: vc_forward_scroll
);
1569 else if (vc_forward_scroll
< 0)
1570 scrolldown(-vc_forward_scroll
> scrreg_bottom
- scrreg_top
?
1571 scrreg_bottom
- scrreg_top
: -vc_forward_scroll
);
1573 vc_forward_preflight_mode
= PFunwind
;
1575 for (; start
< i
; start
++)
1576 vc_putchar(vc_forward_buffer
[start
]);
1578 assert(vc_forward_scroll
== 0);
1580 vc_forward_preflight_mode
= PFoff
;
1582 #else !FAST_JUMP_SCROLL
1584 int drawlen
= start
;
1586 int param
= 0, changebackground
= 0;
1587 enum vt100state_e vtState
= vt100state
;
1589 * In simple words, here we're pre-parsing the text to look for
1590 * + Newlines, for computing jump scroll
1591 * + /\033\[[0-9;]*]m/ to continue on
1592 * any other sequence will stop. We don't want to have cursor
1593 * movement escape sequences while we're trying to pre-scroll
1595 * We have to be extra carefull about the sequences that changes
1596 * the background color to prevent scrolling in those
1598 * That parsing was added to speed up 'man' and 'color-ls' a
1599 * zillion time (at least). It's worth it, trust me.
1600 * (mail Nick Stephen for a True Performance Graph)
1603 for (i
= start
; i
< todo
&& plaintext
; i
++) {
1607 switch (vc_forward_buffer
[i
]) {
1617 switch (vc_forward_buffer
[i
]) {
1619 vtState
= ESgetpars
;
1621 changebackground
= 0;
1629 if ((vc_forward_buffer
[i
] >= '0' &&
1630 vc_forward_buffer
[i
] <= '9') ||
1631 vc_forward_buffer
[i
] == ';') {
1632 if (vc_forward_buffer
[i
] >= '0' &&
1633 vc_forward_buffer
[i
] <= '9')
1634 param
= (param
*10)+(vc_forward_buffer
[i
]-'0');
1636 if (param
>= 40 && param
<= 47)
1637 changebackground
= 1;
1638 if (!vc_normal_background
&&
1640 changebackground
= 1;
1643 break; /* continue on */
1645 vtState
= ESgotpars
;
1648 switch (vc_forward_buffer
[i
]) {
1651 if (param
>= 40 && param
<= 47)
1652 changebackground
= 1;
1653 if (!vc_normal_background
&&
1655 changebackground
= 1;
1656 if (changebackground
) {
1659 /* REALLY don't jump */
1661 /* Yup ! we've got it */
1676 * Then we look if it would be appropriate to forward jump
1677 * the screen before drawing
1679 if (jump
&& (scrreg_bottom
- scrreg_top
) > 2) {
1680 jump
-= scrreg_bottom
- y
- 1;
1682 if (jump
>= scrreg_bottom
- scrreg_top
)
1683 jump
= scrreg_bottom
- scrreg_top
-1;
1689 * and we draw what we've found to the parser
1691 for (i
= start
; i
< drawlen
; i
++)
1692 vc_putchar(vc_forward_buffer
[start
++]);
1694 * Continue sending characters to the parser until we're sure we're
1695 * back on normal characters.
1697 for (i
= start
; i
< todo
&&
1698 vt100state
!= ESnormal
; i
++)
1699 vc_putchar(vc_forward_buffer
[start
++]);
1700 #endif !FAST_JUMP_SCROLL
1701 /* Then loop again if there still things to draw */
1702 } while (start
< todo
);
1706 /* Re-acquire the lock while we check our state. */
1708 simple_lock(&vc_forward_lock
);
1711 vc_forward_buffer_busy
= 0;
1712 vc_forward_buffer_size
= 0;
1714 simple_unlock(&vc_forward_lock
);
1719 vcputc(int l
, int u
, int c
)
1722 * Either we're really buffering stuff or we're not yet because
1723 * the probe hasn't been done.
1725 if (vc_forward_buffer_enabled
)
1734 * Store characters to be drawn 'later', handle overflows
1738 vc_store_char(unsigned char c
)
1743 assert(vc_forward_buffer_enabled
);
1746 simple_lock(&vc_forward_lock
);
1748 /* Spin until the buffer has space for another character. */
1749 while (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
) {
1750 simple_unlock(&vc_forward_lock
);
1754 simple_lock(&vc_forward_lock
);
1757 assert(vc_forward_buffer_size
< VC_MAX_FORWARD_SIZE
);
1759 vc_forward_buffer
[vc_forward_buffer_size
++] = (unsigned char)c
;
1761 if (vc_forward_buffer_size
== 1) {
1762 /* If we're adding the first character to the buffer,
1763 * start the timer, otherwise it is already running.
1768 timeout((timeout_fcn_t
)vc_flush_forward_buffer
,
1770 VC_CONSOLE_UPDATE_TIMEOUT
);
1772 } else if (vc_forward_buffer_size
== VC_MAX_FORWARD_SIZE
|| debug_mode
) {
1774 * If there is an overflow or this is an immediate character display
1775 * (eg. pre-clock printfs, panics), then we force a draw (take into
1776 * account that a flush might already be in progress).
1778 if (!vc_forward_buffer_busy
) {
1780 untimeout((timeout_fcn_t
)vc_flush_forward_buffer
, (void *)0);
1784 simple_unlock(&vc_forward_lock
);
1789 * Immediate character display.. kernel printf uses this. Make sure
1790 * get flushed and that panics get fully displayed.
1792 vc_flush_forward_buffer();
1800 GratefulDebInit(); /* (TEST/DEBUG) */
1803 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1804 printf(" Video info: %d; video_board=%08X\n", i
, vboard
);
1805 printf(" Video name: %s\n", vinfo
.v_name
);
1806 printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
1807 vinfo
.v_height
, vinfo
.v_width
, vinfo
.v_depth
, vinfo
.v_rowbytes
, vinfo
.v_type
);
1808 printf(" physical address=%08X\n", vinfo
.v_physaddr
);
1811 vinfo
.v_rows
= vinfo
.v_height
/ CHARHEIGHT
;
1812 vinfo
.v_columns
= vinfo
.v_width
/ CHARWIDTH
;
1814 if (vinfo
.v_depth
>= 8) {
1815 vinfo
.v_rowscanbytes
= (vinfo
.v_depth
/ 8) * vinfo
.v_width
;
1817 vinfo
.v_rowscanbytes
= vinfo
.v_width
/ (8 / vinfo
.v_depth
);
1820 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1821 printf(" inited=%d\n", vc_initted
);
1825 vc_render_font(1, vinfo
.v_depth
);
1826 vc_color_mask
= vc_color_depth_masks
[vc_color_index_table
[vinfo
.v_depth
]];
1828 switch (vinfo
.v_depth
) {
1831 vc_paintchar
= vc_paint_char1
;
1834 vc_paintchar
= vc_paint_char2
;
1837 vc_paintchar
= vc_paint_char4
;
1840 vc_paintchar
= vc_paint_char8c
;
1843 vc_paintchar
= vc_paint_char16c
;
1846 vc_paintchar
= vc_paint_char32c
;
1850 #ifdef FAST_JUMP_SCROLL
1851 vc_forward_paintchar
= vc_paintchar
;
1852 vc_paintchar
= vc_paint_char
;
1853 #endif FAST_JUMP_SCROLL
1859 if (vinfo
.v_depth
>= 8)
1860 printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
1861 printf("video console at 0x%x (%dx%dx%d)\n", vinfo
.v_baseaddr
,
1862 vinfo
.v_width
, vinfo
.v_height
, vinfo
.v_depth
);
1865 * Added for the buffering and jump scrolling
1868 simple_lock_init(&vc_forward_lock
, ETAP_IO_TTY
);
1870 vc_forward_buffer_enabled
= 1;
1875 struct vc_progress_element
{
1876 unsigned int version
;
1879 unsigned char count
;
1880 unsigned char res
[3];
1886 unsigned int res2
[3];
1887 unsigned char data
[0];
1889 typedef struct vc_progress_element vc_progress_element
;
1891 static vc_progress_element
* vc_progress
;
1892 static unsigned char * vc_progress_data
;
1893 static boolean_t vc_progress_enable
;
1894 static unsigned char * vc_clut
;
1895 static unsigned int vc_progress_tick
;
1896 static boolean_t vc_graphics_mode
;
1897 static boolean_t vc_acquired
;
1898 static boolean_t vc_need_clear
;
1900 void vc_blit_rect_8c( int x
, int y
,
1901 int width
, int height
,
1902 int transparent
, unsigned char * dataPtr
)
1904 volatile unsigned char * dst
;
1908 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1909 (y
* vinfo
.v_rowbytes
) +
1912 for( line
= 0; line
< height
; line
++) {
1913 for( col
= 0; col
< width
; col
++) {
1915 if( data
== transparent
)
1918 *(dst
+ col
) = data
;
1920 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1925 void vc_blit_rect_8m( int x
, int y
,
1926 int width
, int height
,
1927 int transparent
, unsigned char * dataPtr
)
1929 volatile unsigned char * dst
;
1933 dst
= (unsigned char *)(vinfo
.v_baseaddr
+
1934 (y
* vinfo
.v_rowbytes
) +
1937 for( line
= 0; line
< height
; line
++) {
1938 for( col
= 0; col
< width
; col
++) {
1940 if( data
== transparent
)
1944 *(dst
+ col
) = ((19595 * vc_clut
[data
+ 0] +
1945 38470 * vc_clut
[data
+ 1] +
1946 7471 * vc_clut
[data
+ 2] ) / 65536);
1948 dst
= (volatile unsigned char *) (((int)dst
) + vinfo
.v_rowbytes
);
1954 void vc_blit_rect_16( int x
, int y
,
1955 int width
, int height
,
1956 int transparent
, unsigned char * dataPtr
)
1958 volatile unsigned short * dst
;
1962 dst
= (volatile unsigned short *)(vinfo
.v_baseaddr
+
1963 (y
* vinfo
.v_rowbytes
) +
1966 for( line
= 0; line
< height
; line
++) {
1967 for( col
= 0; col
< width
; col
++) {
1969 if( data
== transparent
)
1973 *(dst
+ col
) = ( (0xf8 & (vc_clut
[data
+ 0])) << 7)
1974 | ( (0xf8 & (vc_clut
[data
+ 1])) << 2)
1975 | ( (0xf8 & (vc_clut
[data
+ 2])) >> 3);
1977 dst
= (volatile unsigned short *) (((int)dst
) + vinfo
.v_rowbytes
);
1981 void vc_blit_rect_32( unsigned int x
, unsigned int y
,
1982 unsigned int width
, unsigned int height
,
1983 int transparent
, unsigned char * dataPtr
)
1985 volatile unsigned int * dst
;
1989 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
1990 (y
* vinfo
.v_rowbytes
) +
1993 for( line
= 0; line
< height
; line
++) {
1994 for( col
= 0; col
< width
; col
++) {
1996 if( data
== transparent
)
2000 *(dst
+ col
) = (vc_clut
[data
+ 0] << 16)
2001 | (vc_clut
[data
+ 1] << 8)
2002 | (vc_clut
[data
+ 2]);
2004 dst
= (volatile unsigned int *) (((int)dst
) + vinfo
.v_rowbytes
);
2008 void vc_blit_rect( int x
, int y
,
2009 int width
, int height
,
2010 int transparent
, unsigned char * dataPtr
)
2012 switch( vinfo
.v_depth
) {
2014 vc_blit_rect_8c( x
, y
, width
, height
, transparent
, dataPtr
);
2017 vc_blit_rect_16( x
, y
, width
, height
, transparent
, dataPtr
);
2020 vc_blit_rect_32( x
, y
, width
, height
, transparent
, dataPtr
);
2025 void vc_progress_task( void * arg
)
2028 int count
= (int) arg
;
2029 int x
, y
, width
, height
;
2030 unsigned char * data
;
2033 simple_lock(&vc_forward_lock
);
2035 if( vc_progress_enable
) {
2037 if( count
>= vc_progress
->count
)
2040 width
= vc_progress
->width
;
2041 height
= vc_progress
->height
;
2042 x
= vc_progress
->dx
;
2043 y
= vc_progress
->dy
;
2044 data
= vc_progress_data
;
2045 data
+= count
* width
* height
;
2046 if( 1 & vc_progress
->flags
) {
2047 x
+= (vinfo
.v_width
/ 2);
2048 x
+= (vinfo
.v_height
/ 2);
2050 vc_blit_rect( x
, y
, width
, height
,
2051 vc_progress
->transparent
,data
);
2053 timeout( vc_progress_task
, (void *) count
,
2056 simple_unlock(&vc_forward_lock
);
2060 void vc_display_icon( vc_progress_element
* desc
,
2061 unsigned char * data
)
2063 int x
, y
, width
, height
;
2065 if( vc_acquired
&& vc_graphics_mode
&& vc_clut
) {
2067 width
= desc
->width
;
2068 height
= desc
->height
;
2071 if( 1 & desc
->flags
) {
2072 x
+= (vinfo
.v_width
/ 2);
2073 y
+= (vinfo
.v_height
/ 2);
2075 vc_blit_rect( x
, y
, width
, height
, desc
->transparent
, data
);
2080 vc_progress_set( boolean_t enable
)
2088 simple_lock(&vc_forward_lock
);
2090 if( vc_progress_enable
!= enable
) {
2091 vc_progress_enable
= enable
;
2093 timeout(vc_progress_task
, (void *) 0,
2096 untimeout( vc_progress_task
, (void *) 0 );
2099 simple_unlock(&vc_forward_lock
);
2107 vc_progress_initialize( vc_progress_element
* desc
,
2108 unsigned char * data
,
2109 unsigned char * clut
)
2111 if( (!clut
) || (!desc
) || (!data
))
2116 vc_progress_data
= data
;
2117 vc_progress_tick
= vc_progress
->time
* hz
/ 1000;
2122 // FirmwareC.c needs:
2123 Boot_Video boot_video_info
;
2125 extern int disableConsoleOutput
;
2127 void vc_clear_screen( void )
2137 initialize_screen(Boot_Video
* boot_vinfo
, unsigned int op
)
2140 bcopy( (const void *) boot_vinfo
,
2141 (void *) &boot_video_info
,
2142 sizeof( boot_video_info
));
2144 vinfo
.v_name
[0] = 0;
2145 vinfo
.v_width
= boot_vinfo
->v_width
;
2146 vinfo
.v_height
= boot_vinfo
->v_height
;
2147 vinfo
.v_depth
= boot_vinfo
->v_depth
;
2148 vinfo
.v_rowbytes
= boot_vinfo
->v_rowBytes
;
2149 vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
;
2150 vinfo
.v_baseaddr
= vinfo
.v_physaddr
;
2155 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2161 case kPEGraphicsMode
:
2162 vc_graphics_mode
= TRUE
;
2163 disableConsoleOutput
= TRUE
;
2168 vc_graphics_mode
= FALSE
;
2169 disableConsoleOutput
= FALSE
;
2175 vc_progress_set( FALSE
);
2176 disableConsoleOutput
= FALSE
;
2177 if( vc_need_clear
) {
2178 vc_need_clear
= FALSE
;
2183 case kPEEnableScreen
:
2185 if( vc_graphics_mode
)
2186 vc_progress_set( TRUE
);
2192 case kPEDisableScreen
:
2193 vc_progress_set( FALSE
);
2196 case kPEAcquireScreen
:
2197 vc_need_clear
= (FALSE
== vc_acquired
);
2199 vc_progress_set( vc_graphics_mode
);
2200 disableConsoleOutput
= vc_graphics_mode
;
2201 if( vc_need_clear
&& !vc_graphics_mode
) {
2202 vc_need_clear
= FALSE
;
2207 case kPEReleaseScreen
:
2208 vc_acquired
= FALSE
;
2209 vc_progress_set( FALSE
);
2210 disableConsoleOutput
= TRUE
;
2212 GratefulDebInit(0); /* Stop grateful debugger */
2217 if( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */