]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/POWERMAC/video_console.c
907aef6829aff8e34fd8db2b24d5ff6524468933
[apple/xnu.git] / osfmk / ppc / POWERMAC / video_console.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * @OSF_FREE_COPYRIGHT@
24 *
25 */
26 /*
27 * @APPLE_FREE_COPYRIGHT@
28 */
29 /* MACH PPC - video_console.c
30 *
31 * Original based on NetBSD's mac68k/dev/ite.c driver
32 *
33 * This driver differs in
34 * - MACH driver"ized"
35 * - Uses phys_copy and flush_cache to in several places
36 * for performance optimizations
37 * - 7x15 font
38 * - Black background and white (character) foreground
39 * - Assumes 6100/7100/8100 class of machine
40 *
41 * The original header follows...
42 *
43 *
44 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
45 *
46 * Copyright (c) 1988 University of Utah.
47 * Copyright (c) 1990, 1993
48 * The Regents of the University of California. All rights reserved.
49 *
50 * This code is derived from software contributed to Berkeley by
51 * the Systems Programming Group of the University of Utah Computer
52 * Science Department.
53 *
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
56 * are met:
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.
69 *
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
80 * SUCH DAMAGE.
81 *
82 * from: Utah $Hdr: ite.c 1.28 92/12/20$
83 *
84 * @(#)ite.c 8.2 (Berkeley) 1/12/94
85 */
86
87 /*
88 * ite.c
89 *
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.
94 *
95 * -- Brad and Lawrence, June 26th, 1994
96 *
97 */
98
99 #include <vc.h>
100
101 #include <mach_kdb.h>
102 #include <kern/spl.h>
103 #include <machine/machparam.h> /* spl definitions */
104 #include <types.h>
105 #include <ppc/iso_font.h>
106 #include <ppc/Firmware.h>
107
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>
114
115 #define FAST_JUMP_SCROLL
116
117 #define CHARWIDTH 8
118 #define CHARHEIGHT 16
119
120 #define ATTR_NONE 0
121 #define ATTR_BOLD 1
122 #define ATTR_UNDER 2
123 #define ATTR_REVERSE 4
124
125 enum vt100state_e {
126 ESnormal, /* Nothing yet */
127 ESesc, /* Got ESC */
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 */
135 ESask,
136 EScharsize,
137 ESignore /* Ignore this sequence */
138 } vt100state = ESnormal;
139
140 struct vc_info vinfo;
141
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 };
147
148 /* VT100 state: */
149 #define MAXPARS 16
150 static int x = 0, y = 0, savex, savey;
151 static int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
152
153 /* VT100 tab stops & scroll region */
154 static char tab_stops[255];
155 static int scrreg_top, scrreg_bottom;
156
157 /* Misc */
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);
162
163 void vcattach(void);
164
165
166 /*
167 * For the color support (Michel Pollet)
168 */
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 };
172
173 static unsigned long vc_color_depth_masks[4] =
174 { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
175
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 */
186 };
187
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;
192
193
194 /*
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 ;-)
199 */
200 #define VC_MAX_FORWARD_SIZE (100*36)
201
202 /*
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
207 */
208 #define VC_CONSOLE_UPDATE_TIMEOUT 5
209
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)
215
216 #ifdef FAST_JUMP_SCROLL
217 static void (*vc_forward_paintchar) (unsigned char c, int x, int y, int attrs);
218 static enum {
219 PFoff,
220 PFwind,
221 PFscroll,
222 PFunwind
223 } vc_forward_preflight_mode = PFoff;
224 static struct {
225 enum vt100state_e vt100state;
226
227 int vc_wrap_mode, vc_relative_origin;
228 int vc_charset_select, vc_save_charset_s;
229 int vc_charset[2];
230 int vc_charset_save[2];
231
232 int x, y, savex, savey;
233 int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
234
235 char tab_stops[255];
236 int scrreg_top, scrreg_bottom;
237
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
243
244 /*
245 * New Rendering code from Michel Pollet
246 */
247
248 /* That function will be called for drawing */
249 static void (*vc_paintchar) (unsigned char c, int x, int y, int attrs);
250
251 #ifdef RENDERALLOCATE
252 static unsigned char *renderedFont = NULL; /* rendered font buffer */
253 #else
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];
258 #endif
259
260 /* Rendered Font Size */
261 static unsigned long vc_rendered_font_size = REN_MAX_SIZE;
262 static long vc_rendered_error = 0;
263
264 /* If the one bit table was reversed */
265 static short vc_one_bit_reversed = 0;
266
267 /* Size of a character in the table (bytes) */
268 static int vc_rendered_char_size = 0;
269
270 /*
271 # Attribute codes:
272 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
273 # Text color codes:
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
277 */
278
279 #define VC_RESET_BACKGROUND 40
280 #define VC_RESET_FOREGROUND 37
281
282 static void vc_color_set(int color)
283 {
284 if (vinfo.v_depth < 8)
285 return;
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;
291 }
292
293 }
294
295 static void vc_render_font(short olddepth, short newdepth)
296 {
297 int charIndex; /* index in ISO font */
298 union {
299 unsigned char *charptr;
300 unsigned short *shortptr;
301 unsigned long *longptr;
302 } current; /* current place in rendered font, multiple types. */
303
304 unsigned char *theChar; /* current char in iso_font */
305
306 if (olddepth == newdepth && renderedFont) {
307 return; /* nothing to do */
308 }
309
310 if (olddepth != 1 && renderedFont) {
311 #ifdef RENDERALLOCATE
312 (void) kmem_free(kernel_map, (vm_offset_t*)renderedFont, vc_rendered_font_size);
313 #endif
314 }
315 vc_rendered_font_size = REN_MAX_SIZE;
316 if (newdepth == 1) {
317 #ifdef RENDERALLOCATE
318 renderedFont = iso_font;
319 #endif
320 vc_rendered_char_size = 16;
321 if (!vc_one_bit_reversed) { /* reverse the font for the blitter */
322 int i;
323 for (i = 0; i < ((ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size); i++) {
324 if (iso_font[i]) {
325 unsigned char mask1 = 0x80;
326 unsigned char mask2 = 0x01;
327 unsigned char val = 0;
328 while (mask1) {
329 if (iso_font[i] & mask1)
330 val |= mask2;
331 mask1 >>= 1;
332 mask2 <<= 1;
333 }
334 renderedFont[i] = ~val;
335 } else renderedFont[i] = 0xff;
336 }
337 vc_one_bit_reversed = 1;
338 }
339 return;
340 }
341 {
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;
349 return;
350 } else
351 vc_rendered_font_size = csize;
352 #else
353 vc_rendered_font_size = csize;
354 #endif
355 }
356
357 #ifdef RENDERALLOCATE
358 if (kmem_alloc(kernel_map,
359 (vm_offset_t *)&renderedFont,
360 vc_rendered_font_size) != KERN_SUCCESS) {
361 renderedFont = NULL;
362 vc_rendered_error = vc_rendered_font_size;
363 return;
364 }
365 #endif
366 current.charptr = renderedFont;
367 theChar = iso_font;
368 for (charIndex = ISO_CHAR_MIN; charIndex <= ISO_CHAR_MAX; charIndex++) {
369 int line;
370 for (line = 0; line < CHARHEIGHT; line++) {
371 unsigned char mask = 1;
372 do {
373 switch (newdepth) {
374 case 2: {
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;
380 value = ~value;
381 *current.charptr++ = value;
382 }
383 break;
384 case 4:
385 {
386 unsigned char value = 0;
387 if (*theChar & mask) value |= 0xF0; mask <<= 1;
388 if (*theChar & mask) value |= 0x0F;
389 value = ~value;
390 *current.charptr++ = value;
391 }
392 break;
393 case 8:
394 *current.charptr++ = (*theChar & mask) ? 0xff : 0;
395 break;
396 case 16:
397 *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
398 break;
399
400 case 32:
401 *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
402 break;
403 }
404 mask <<= 1;
405 } while (mask); /* while the single bit drops to the right */
406 theChar++;
407 }
408 }
409 }
410
411 #ifdef FAST_JUMP_SCROLL
412 static void vc_paint_char(unsigned char ch, int xx, int yy, int attrs)
413 {
414 switch (vc_forward_preflight_mode) {
415 case PFoff:
416 vc_forward_paintchar(ch, xx, yy, attrs);
417 break;
418 case PFwind:
419 break;
420 case PFscroll:
421 break;
422 case PFunwind:
423 if (yy >= scrreg_top && yy < scrreg_bottom) {
424 yy -= vc_forward_scroll;
425 if (yy < scrreg_top || yy >= scrreg_bottom)
426 break;
427 }
428 vc_forward_paintchar(ch, xx, yy, attrs);
429 break;
430 }
431 }
432 #endif FAST_JUMP_SCROLL
433
434 static void vc_paint_char1(unsigned char ch, int xx, int yy, int attrs)
435 {
436 unsigned char *theChar;
437 unsigned char *where;
438 int i;
439
440 theChar = (unsigned char*)(renderedFont + (ch * vc_rendered_char_size));
441 where = (unsigned char*)(vinfo.v_baseaddr +
442 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
443 (xx));
444
445 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
446 *where = *theChar++;
447
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;
453 int bit = 0;
454 for (bit = 0; bit < 7; bit++) {
455 if ((save & mask1) == mask2)
456 val &= ~mask2;
457 mask1 >>= 1;
458 mask2 >>= 1;
459 }
460 }
461 if (attrs & ATTR_REVERSE) val = ~val;
462 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
463 *where = val;
464
465 where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
466 }
467
468 }
469
470 static void vc_paint_char2(unsigned char ch, int xx, int yy, int attrs)
471 {
472 unsigned short *theChar;
473 unsigned short *where;
474 int i;
475
476 theChar = (unsigned short*)(renderedFont + (ch * vc_rendered_char_size));
477 where = (unsigned short*)(vinfo.v_baseaddr +
478 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
479 (xx * 2));
480 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
481 *where = *theChar++;
482
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;
488 int bit = 0;
489 for (bit = 0; bit < 7; bit++) {
490 if ((save & mask1) == mask2)
491 val &= ~mask2;
492 mask1 >>= 2;
493 mask2 >>= 2;
494 }
495 }
496 if (attrs & ATTR_REVERSE) val = ~val;
497 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
498 *where = val;
499
500 where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
501 }
502
503 }
504
505 static void vc_paint_char4(unsigned char ch, int xx, int yy, int attrs)
506 {
507 unsigned long *theChar;
508 unsigned long *where;
509 int i;
510
511 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
512 where = (unsigned long*)(vinfo.v_baseaddr +
513 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
514 (xx * 4));
515
516 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
517 *where = *theChar++;
518
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;
524 int bit = 0;
525 for (bit = 0; bit < 7; bit++) {
526 if ((save & mask1) == mask2)
527 val &= ~mask2;
528 mask1 >>= 4;
529 mask2 >>= 4;
530 }
531 }
532 if (attrs & ATTR_REVERSE) val = ~val;
533 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
534 *where = val;
535
536 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
537 }
538
539 }
540
541 static void vc_paint_char8c(unsigned char ch, int xx, int yy, int attrs)
542 {
543 unsigned long *theChar;
544 unsigned long *where;
545 int i;
546
547 theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
548 where = (unsigned long*)(vinfo.v_baseaddr +
549 (yy * CHARHEIGHT * vinfo.v_rowbytes) +
550 (xx * CHARWIDTH));
551
552 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attr? FLY !*/
553 unsigned long *store = where;
554 int x;
555 for (x = 0; x < 2; x++) {
556 unsigned long val = *theChar++;
557 val = (vc_color_back & ~val) | (vc_color_fore & val);
558 *store++ = val;
559 }
560
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;
564 int x;
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))
569 val |= 0xff000000;
570 if ((save & 0xFFFF0000) == 0xFF000000)
571 val |= 0x00FF0000;
572 if ((save & 0x00FFFF00) == 0x00FF0000)
573 val |= 0x0000FF00;
574 if ((save & 0x0000FFFF) == 0x0000FF00)
575 val |= 0x000000FF;
576 }
577 if (attrs & ATTR_REVERSE) val = ~val;
578 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
579
580 val = (vc_color_back & ~val) | (vc_color_fore & val);
581 *store++ = val;
582 lastpixel = save & 0xff;
583 }
584
585 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
586 }
587
588 }
589 static void vc_paint_char16c(unsigned char ch, int xx, int yy, int attrs)
590 {
591 unsigned long *theChar;
592 unsigned long *where;
593 int i;
594
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));
599
600 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
601 unsigned long *store = where;
602 int x;
603 for (x = 0; x < 4; x++) {
604 unsigned long val = *theChar++;
605 val = (vc_color_back & ~val) | (vc_color_fore & val);
606 *store++ = val;
607 }
608
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;
612 int x;
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))
618 val |= 0xFFFF0000;
619 }
620 if (attrs & ATTR_REVERSE) val = ~val;
621 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
622
623 val = (vc_color_back & ~val) | (vc_color_fore & val);
624
625 *store++ = val;
626 lastpixel = save & 0x7fff;
627 }
628
629 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
630 }
631
632 }
633 static void vc_paint_char32c(unsigned char ch, int xx, int yy, int attrs)
634 {
635 unsigned long *theChar;
636 unsigned long *where;
637 int i;
638
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));
643
644 if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
645 unsigned long *store = where;
646 int x;
647 for (x = 0; x < 8; x++) {
648 unsigned long val = *theChar++;
649 val = (vc_color_back & ~val) | (vc_color_fore & val);
650 *store++ = val;
651 }
652
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;
656 int x;
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)
661 val = 0xFFFFFFFF;
662 }
663 if (attrs & ATTR_REVERSE) val = ~val;
664 if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
665
666 val = (vc_color_back & ~val) | (vc_color_fore & val);
667 *store++ = val;
668 lastpixel = save;
669 }
670
671 where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
672 }
673
674 }
675
676 /*
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
680 */
681 static void reversecursor(void)
682 {
683 union {
684 unsigned char *charptr;
685 unsigned short *shortptr;
686 unsigned long *longptr;
687 } where;
688 int line, col;
689
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) {
695 case 1:
696 *where.charptr = ~*where.charptr;
697 break;
698 case 2:
699 *where.shortptr = ~*where.shortptr;
700 break;
701 case 4:
702 *where.longptr = ~*where.longptr;
703 break;
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
708 */
709 #ifdef VC_BINARY_REVERSE
710 case 8:
711 where.longptr[0] = ~where.longptr[0];
712 where.longptr[1] = ~where.longptr[1];
713 break;
714 case 16:
715 for (col = 0; col < 4; col++)
716 where.longptr[col] = ~where.longptr[col];
717 break;
718 case 32:
719 for (col = 0; col < 8; col++)
720 where.longptr[col] = ~where.longptr[col];
721 break;
722 #else
723 case 8:
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;
727 break;
728 case 16:
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;
732 break;
733 case 32:
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;
737 break;
738 #endif
739 }
740 where.charptr += vinfo.v_rowbytes;
741 }
742 }
743
744
745 static void
746 scrollup(int num)
747 {
748 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
749
750 linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
751 rowline = (vinfo.v_rowbytes) >> 2;
752 rowscanline = (vinfo.v_rowscanbytes) >> 2;
753
754 #ifdef FAST_JUMP_SCROLL
755 if (vc_forward_preflight_mode == PFwind) {
756 vc_forward_scroll += num;
757 return;
758 }
759 if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
760 #endif FAST_JUMP_SCROLL
761
762 to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
763 from = to + (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
764
765 i = (scrreg_bottom - scrreg_top) - num;
766
767 while (i-- > 0) {
768 for (line = 0; line < CHARHEIGHT; line++) {
769 /*
770 * Only copy what is displayed
771 */
772 video_scroll_up((unsigned int) from,
773 (unsigned int) (from+(vinfo.v_rowscanbytes/4)),
774 (unsigned int) to);
775
776 from += rowline;
777 to += rowline;
778 }
779 }
780
781 /* Now set the freed up lines to the background colour */
782
783
784 to = ((unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs))
785 + ((scrreg_bottom - scrreg_top - num) * linelongs);
786
787 #ifdef FAST_JUMP_SCROLL
788 if (vc_forward_preflight_mode == PFscroll)
789 return;
790 } else if (vc_forward_preflight_mode == PFunwind) {
791 long linestart, linelast;
792 vc_forward_scroll -= num;
793
794 linestart = scrreg_bottom - num - vc_forward_scroll;
795 linelast = linestart + num - 1;
796
797 if (linestart >= scrreg_bottom || linelast < scrreg_top)
798 return;
799
800 if (linelast >= scrreg_bottom)
801 linelast = scrreg_bottom - 1;
802 if (linestart < scrreg_top)
803 linestart = scrreg_top;
804
805 to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
806 num = linelast - linestart + 1;
807 }
808 #endif FAST_JUMP_SCROLL
809
810 for (linelongs = CHARHEIGHT * num; linelongs-- > 0;) {
811 from = to;
812 for (i = 0; i < rowscanline; i++)
813 *to++ = vc_color_back;
814
815 to = from + rowline;
816 }
817
818 }
819
820 static void
821 scrolldown(int num)
822 {
823 unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
824
825 linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
826 rowline = (vinfo.v_rowbytes) >> 2;
827 rowscanline = (vinfo.v_rowscanbytes) >> 2;
828
829 #ifdef FAST_JUMP_SCROLL
830 if (vc_forward_preflight_mode == PFwind) {
831 vc_forward_scroll -= num;
832 return;
833 }
834 if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
835 #endif FAST_JUMP_SCROLL
836
837 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
838 - (rowline - rowscanline);
839 from = to - (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
840
841 i = (scrreg_bottom - scrreg_top) - num;
842
843 while (i-- > 0) {
844 for (line = 0; line < CHARHEIGHT; line++) {
845 /*
846 * Only copy what is displayed
847 */
848 video_scroll_down((unsigned int) from,
849 (unsigned int) (from-(vinfo.v_rowscanbytes/4)),
850 (unsigned int) to);
851
852 from -= rowline;
853 to -= rowline;
854 }
855 }
856
857 /* Now set the freed up lines to the background colour */
858
859 to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_top);
860
861 #ifdef FAST_JUMP_SCROLL
862 if (vc_forward_preflight_mode == PFscroll)
863 return;
864 } else if (vc_forward_preflight_mode == PFunwind) {
865 long linestart, linelast;
866 vc_forward_scroll += num;
867
868 linestart = scrreg_top - vc_forward_scroll;
869 linelast = linestart + num - 1;
870
871 if (linestart >= scrreg_bottom || linelast < scrreg_top)
872 return;
873
874 if (linelast >= scrreg_bottom)
875 linelast = scrreg_bottom - 1;
876 if (linestart < scrreg_top)
877 linestart = scrreg_top;
878
879 to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
880 num = linelast - linestart + 1;
881 }
882 #endif FAST_JUMP_SCROLL
883
884 for (line = CHARHEIGHT * num; line > 0; line--) {
885 from = to;
886
887 for (i = 0; i < rowscanline; i++)
888 *(to++) = vc_color_back;
889
890 to = from + rowline;
891 }
892
893 }
894
895
896 static void
897 clear_line(int which)
898 {
899 int start, end, i;
900
901 /*
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
905 * module. --LK
906 */
907
908 switch (which) {
909 case 0: /* To end of line */
910 start = x;
911 end = vinfo.v_columns-1;
912 break;
913 case 1: /* To start of line */
914 start = 0;
915 end = x;
916 break;
917 case 2: /* Whole line */
918 start = 0;
919 end = vinfo.v_columns-1;
920 break;
921 }
922
923 for (i = start; i <= end; i++) {
924 vc_paintchar(' ', i, y, ATTR_NONE);
925 }
926
927 }
928
929 static void
930 clear_screen(int which)
931 {
932 unsigned long *p, *endp, *row;
933 int linelongs, col;
934 int rowline, rowlongs;
935
936 rowline = vinfo.v_rowscanbytes / 4;
937 rowlongs = vinfo.v_rowbytes / 4;
938
939 p = (unsigned long*) vinfo.v_baseaddr;;
940 endp = (unsigned long*) vinfo.v_baseaddr;
941
942 linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
943
944 switch (which) {
945 case 0: /* To end of screen */
946 clear_line(0);
947 if (y < vinfo.v_rows - 1) {
948 p += (y + 1) * linelongs;
949 endp += rowlongs * vinfo.v_height;
950 }
951 break;
952 case 1: /* To start of screen */
953 clear_line(1);
954 if (y > 1) {
955 endp += (y + 1) * linelongs;
956 }
957 break;
958 case 2: /* Whole screen */
959 endp += rowlongs * vinfo.v_height;
960 break;
961 }
962
963 for (row = p ; row < endp ; row += rowlongs) {
964 for (col = 0; col < rowline; col++)
965 *(row+col) = vc_color_back;
966 }
967
968 }
969
970 static void
971 reset_tabs(void)
972 {
973 int i;
974
975 for (i = 0; i<= vinfo.v_columns; i++) {
976 tab_stops[i] = ((i % 8) == 0);
977 }
978
979 }
980
981 static void
982 vt100_reset(void)
983 {
984 reset_tabs();
985 scrreg_top = 0;
986 scrreg_bottom = vinfo.v_rows;
987 attr = ATTR_NONE;
988 vc_charset[0] = vc_charset[1] = 0;
989 vc_charset_select = 0;
990 vc_wrap_mode = 1;
991 vc_relative_origin = 0;
992 vc_color_set(VC_RESET_BACKGROUND);
993 vc_color_set(VC_RESET_FOREGROUND);
994
995 }
996
997 static void
998 putc_normal(unsigned char ch)
999 {
1000 switch (ch) {
1001 case '\a': /* Beep */
1002 {
1003 spl_t s;
1004
1005 if(FALSE) {
1006 /*
1007 * No sound hardware, invert the screen twice instead
1008 */
1009 unsigned long *ptr;
1010 int i, j;
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*)))
1019 for (j = 0;
1020 j < vinfo.v_rowscanbytes /
1021 sizeof (unsigned long*);
1022 j++)
1023 *(ptr+j) =~*(ptr+j);
1024 }
1025 }
1026 }
1027 break;
1028
1029 case 127: /* Delete */
1030 case '\b': /* Backspace */
1031 if (hanging_cursor) {
1032 hanging_cursor = 0;
1033 } else
1034 if (x > 0) {
1035 x--;
1036 }
1037 break;
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;
1042 break;
1043 case 0x0b:
1044 case 0x0c:
1045 case '\n': /* Line feed */
1046 if (y >= scrreg_bottom -1 ) {
1047 scrollup(1);
1048 y = scrreg_bottom - 1;
1049 } else {
1050 y++;
1051 }
1052 break;
1053 case '\r': /* Carriage return */
1054 x = 0;
1055 hanging_cursor = 0;
1056 break;
1057 case 0x0e: /* Select G1 charset (Control-N) */
1058 vc_charset_select = 1;
1059 break;
1060 case 0x0f: /* Select G0 charset (Control-O) */
1061 vc_charset_select = 0;
1062 break;
1063 case 0x18 : /* CAN : cancel */
1064 case 0x1A : /* like cancel */
1065 /* well, i do nothing here, may be later */
1066 break;
1067 case '\033': /* Escape */
1068 vt100state = ESesc;
1069 hanging_cursor = 0;
1070 break;
1071 default:
1072 if (ch >= ' ') {
1073 if (hanging_cursor) {
1074 x = 0;
1075 if (y >= scrreg_bottom -1 ) {
1076 scrollup(1);
1077 y = scrreg_bottom - 1;
1078 } else {
1079 y++;
1080 }
1081 hanging_cursor = 0;
1082 }
1083 vc_paintchar((ch >= 0x60 && ch <= 0x7f) ? ch + vc_charset[vc_charset_select]
1084 : ch, x, y, attr);
1085 if (x == vinfo.v_columns - 1) {
1086 hanging_cursor = vc_wrap_mode;
1087 } else {
1088 x++;
1089 }
1090 }
1091 break;
1092 }
1093
1094 }
1095
1096 static void
1097 putc_esc(unsigned char ch)
1098 {
1099 vt100state = ESnormal;
1100
1101 switch (ch) {
1102 case '[':
1103 vt100state = ESsquare;
1104 break;
1105 case 'c': /* Reset terminal */
1106 vt100_reset();
1107 clear_screen(2);
1108 x = y = 0;
1109 break;
1110 case 'D': /* Line feed */
1111 case 'E':
1112 if (y >= scrreg_bottom -1) {
1113 scrollup(1);
1114 y = scrreg_bottom - 1;
1115 } else {
1116 y++;
1117 }
1118 if (ch == 'E') x = 0;
1119 break;
1120 case 'H': /* Set tab stop */
1121 tab_stops[x] = 1;
1122 break;
1123 case 'M': /* Cursor up */
1124 if (y <= scrreg_top) {
1125 scrolldown(1);
1126 y = scrreg_top;
1127 } else {
1128 y--;
1129 }
1130 break;
1131 case '>':
1132 vt100_reset();
1133 break;
1134 case '7': /* Save cursor */
1135 savex = x;
1136 savey = y;
1137 saveattr = attr;
1138 vc_save_charset_s = vc_charset_select;
1139 vc_charset_save[0] = vc_charset[0];
1140 vc_charset_save[1] = vc_charset[1];
1141 break;
1142 case '8': /* Restore cursor */
1143 x = savex;
1144 y = savey;
1145 attr = saveattr;
1146 vc_charset_select = vc_save_charset_s;
1147 vc_charset[0] = vc_charset_save[0];
1148 vc_charset[1] = vc_charset_save[1];
1149 break;
1150 case 'Z': /* return terminal ID */
1151 break;
1152 case '#': /* change characters height */
1153 vt100state = EScharsize;
1154 break;
1155 case '(':
1156 vt100state = ESsetG0;
1157 break;
1158 case ')': /* character set sequence */
1159 vt100state = ESsetG1;
1160 break;
1161 case '=':
1162 break;
1163 default:
1164 /* Rest not supported */
1165 break;
1166 }
1167
1168 }
1169
1170 static void
1171 putc_askcmd(unsigned char ch)
1172 {
1173 if (ch >= '0' && ch <= '9') {
1174 par[numpars] = (10*par[numpars]) + (ch-'0');
1175 return;
1176 }
1177 vt100state = ESnormal;
1178
1179 switch (par[0]) {
1180 case 6:
1181 vc_relative_origin = ch == 'h';
1182 break;
1183 case 7: /* wrap around mode h=1, l=0*/
1184 vc_wrap_mode = ch == 'h';
1185 break;
1186 default:
1187 break;
1188 }
1189
1190 }
1191
1192 static void
1193 putc_charsizecmd(unsigned char ch)
1194 {
1195 vt100state = ESnormal;
1196
1197 switch (ch) {
1198 case '3' :
1199 case '4' :
1200 case '5' :
1201 case '6' :
1202 break;
1203 case '8' : /* fill 'E's */
1204 {
1205 int xx, yy;
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);
1209 }
1210 break;
1211 }
1212
1213 }
1214
1215 static void
1216 putc_charsetcmd(int charset, unsigned char ch)
1217 {
1218 vt100state = ESnormal;
1219
1220 switch (ch) {
1221 case 'A' :
1222 case 'B' :
1223 default:
1224 vc_charset[charset] = 0;
1225 break;
1226 case '0' : /* Graphic characters */
1227 case '2' :
1228 vc_charset[charset] = 0x21;
1229 break;
1230 }
1231
1232 }
1233
1234 static void
1235 putc_gotpars(unsigned char ch)
1236 {
1237 int i;
1238
1239 if (ch < ' ') {
1240 /* special case for vttest for handling cursor
1241 movement in escape sequences */
1242 putc_normal(ch);
1243 vt100state = ESgotpars;
1244 return;
1245 }
1246 vt100state = ESnormal;
1247 switch (ch) {
1248 case 'A': /* Up */
1249 y -= par[0] ? par[0] : 1;
1250 if (y < scrreg_top)
1251 y = scrreg_top;
1252 break;
1253 case 'B': /* Down */
1254 y += par[0] ? par[0] : 1;
1255 if (y >= scrreg_bottom)
1256 y = scrreg_bottom - 1;
1257 break;
1258 case 'C': /* Right */
1259 x += par[0] ? par[0] : 1;
1260 if (x >= vinfo.v_columns)
1261 x = vinfo.v_columns-1;
1262 break;
1263 case 'D': /* Left */
1264 x -= par[0] ? par[0] : 1;
1265 if (x < 0)
1266 x = 0;
1267 break;
1268 case 'H': /* Set cursor position */
1269 case 'f':
1270 x = par[1] ? par[1] - 1 : 0;
1271 y = par[0] ? par[0] - 1 : 0;
1272 if (vc_relative_origin)
1273 y += scrreg_top;
1274 hanging_cursor = 0;
1275 break;
1276 case 'X': /* clear p1 characters */
1277 if (numpars) {
1278 int i;
1279 for (i = x; i < x + par[0]; i++)
1280 vc_paintchar(' ', i, y, ATTR_NONE);
1281 }
1282 break;
1283 case 'J': /* Clear part of screen */
1284 clear_screen(par[0]);
1285 break;
1286 case 'K': /* Clear part of line */
1287 clear_line(par[0]);
1288 break;
1289 case 'g': /* tab stops */
1290 switch (par[0]) {
1291 case 1:
1292 case 2: /* reset tab stops */
1293 /* reset_tabs(); */
1294 break;
1295 case 3: /* Clear every tabs */
1296 {
1297 int i;
1298
1299 for (i = 0; i <= vinfo.v_columns; i++)
1300 tab_stops[i] = 0;
1301 }
1302 break;
1303 case 0:
1304 tab_stops[x] = 0;
1305 break;
1306 }
1307 break;
1308 case 'm': /* Set attribute */
1309 for (i = 0; i < numpars; i++) {
1310 switch (par[i]) {
1311 case 0:
1312 attr = ATTR_NONE;
1313 vc_color_set(VC_RESET_BACKGROUND);
1314 vc_color_set(VC_RESET_FOREGROUND);
1315 break;
1316 case 1:
1317 attr |= ATTR_BOLD;
1318 break;
1319 case 4:
1320 attr |= ATTR_UNDER;
1321 break;
1322 case 7:
1323 attr |= ATTR_REVERSE;
1324 break;
1325 case 22:
1326 attr &= ~ATTR_BOLD;
1327 break;
1328 case 24:
1329 attr &= ~ATTR_UNDER;
1330 break;
1331 case 27:
1332 attr &= ~ATTR_REVERSE;
1333 break;
1334 case 5:
1335 case 25: /* blink/no blink */
1336 break;
1337 default:
1338 vc_color_set(par[i]);
1339 break;
1340 }
1341 }
1342 break;
1343 case 'r': /* Set scroll region */
1344 x = y = 0;
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;
1348 if (scrreg_top < 0)
1349 scrreg_top = 0;
1350 } else {
1351 scrreg_top = 0;
1352 }
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;
1357 } else {
1358 scrreg_bottom = vinfo.v_rows;
1359 }
1360 if (vc_relative_origin)
1361 y = scrreg_top;
1362 break;
1363 }
1364
1365 }
1366
1367 static void
1368 putc_getpars(unsigned char ch)
1369 {
1370 if (ch == '?') {
1371 vt100state = ESask;
1372 return;
1373 }
1374 if (ch == '[') {
1375 vt100state = ESnormal;
1376 /* Not supported */
1377 return;
1378 }
1379 if (ch == ';' && numpars < MAXPARS - 1) {
1380 numpars++;
1381 } else
1382 if (ch >= '0' && ch <= '9') {
1383 par[numpars] *= 10;
1384 par[numpars] += ch - '0';
1385 } else {
1386 numpars++;
1387 vt100state = ESgotpars;
1388 putc_gotpars(ch);
1389 }
1390 }
1391
1392 static void
1393 putc_square(unsigned char ch)
1394 {
1395 int i;
1396
1397 for (i = 0; i < MAXPARS; i++) {
1398 par[i] = 0;
1399 }
1400
1401 numpars = 0;
1402 vt100state = ESgetpars;
1403
1404 putc_getpars(ch);
1405
1406 }
1407
1408 static void
1409 vc_putchar(char ch)
1410 {
1411 if (!ch) {
1412 return; /* ignore null characters */
1413 }
1414 switch (vt100state) {
1415 default:vt100state = ESnormal; /* FALLTHROUGH */
1416 case ESnormal:
1417 putc_normal(ch);
1418 break;
1419 case ESesc:
1420 putc_esc(ch);
1421 break;
1422 case ESsquare:
1423 putc_square(ch);
1424 break;
1425 case ESgetpars:
1426 putc_getpars(ch);
1427 break;
1428 case ESgotpars:
1429 putc_gotpars(ch);
1430 break;
1431 case ESask:
1432 putc_askcmd(ch);
1433 break;
1434 case EScharsize:
1435 putc_charsizecmd(ch);
1436 break;
1437 case ESsetG0:
1438 putc_charsetcmd(0, ch);
1439 break;
1440 case ESsetG1:
1441 putc_charsetcmd(1, ch);
1442 break;
1443 }
1444
1445 if (x >= vinfo.v_columns) {
1446 x = vinfo.v_columns - 1;
1447 }
1448 if (x < 0) {
1449 x = 0;
1450 }
1451 if (y >= vinfo.v_rows) {
1452 y = vinfo.v_rows - 1;
1453 }
1454 if (y < 0) {
1455 y = 0;
1456 }
1457
1458 }
1459
1460 /*
1461 * Actually draws the buffer, handle the jump scroll
1462 */
1463 static void vc_flush_forward_buffer(void)
1464 {
1465 int start = 0;
1466 int todo = 0;
1467 spl_t s;
1468
1469 assert(vc_forward_buffer_enabled);
1470
1471 s = splhigh();
1472 simple_lock(&vc_forward_lock);
1473
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);
1477 splx(s);
1478 return;
1479 }
1480
1481 vc_forward_buffer_busy = 1;
1482
1483 while (todo < vc_forward_buffer_size) {
1484 todo = vc_forward_buffer_size;
1485
1486 /* Drop the lock while we update the screen. */
1487 simple_unlock(&vc_forward_lock);
1488 splx(s);
1489
1490 reversecursor();
1491
1492 do {
1493 int i;
1494 #ifdef FAST_JUMP_SCROLL
1495 if ((todo - start) < 2) {
1496 vc_putchar(vc_forward_buffer[start++]);
1497 } else {
1498 assert(vc_forward_scroll == 0);
1499
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) );
1527
1528 vc_forward_preflight_mode = PFwind;
1529
1530 for (i = start;
1531 i < todo &&
1532 vc_forward_preflight_save.scrreg_top == scrreg_top &&
1533 vc_forward_preflight_save.scrreg_bottom == scrreg_bottom;
1534 i++)
1535 vc_putchar(vc_forward_buffer[i]);
1536
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,
1559 (char *) par,
1560 (vm_size_t) sizeof(par) );
1561 bcopy( (const char *) vc_forward_preflight_save.tab_stops,
1562 (char *) tab_stops,
1563 (vm_size_t) sizeof(tab_stops) );
1564
1565 vc_forward_preflight_mode = PFscroll;
1566
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);
1573
1574 vc_forward_preflight_mode = PFunwind;
1575
1576 for (; start < i; start++)
1577 vc_putchar(vc_forward_buffer[start]);
1578
1579 assert(vc_forward_scroll == 0);
1580
1581 vc_forward_preflight_mode = PFoff;
1582 }
1583 #else !FAST_JUMP_SCROLL
1584 int plaintext = 1;
1585 int drawlen = start;
1586 int jump = 0;
1587 int param = 0, changebackground = 0;
1588 enum vt100state_e vtState = vt100state;
1589 /*
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
1595 * the screen.
1596 * We have to be extra carefull about the sequences that changes
1597 * the background color to prevent scrolling in those
1598 * particular cases.
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)
1602 * Michel Pollet
1603 */
1604 for (i = start; i < todo && plaintext; i++) {
1605 drawlen++;
1606 switch (vtState) {
1607 case ESnormal:
1608 switch (vc_forward_buffer[i]) {
1609 case '\033':
1610 vtState = ESesc;
1611 break;
1612 case '\n':
1613 jump++;
1614 break;
1615 }
1616 break;
1617 case ESesc:
1618 switch (vc_forward_buffer[i]) {
1619 case '[':
1620 vtState = ESgetpars;
1621 param = 0;
1622 changebackground = 0;
1623 break;
1624 default:
1625 plaintext = 0;
1626 break;
1627 }
1628 break;
1629 case ESgetpars:
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');
1636 else {
1637 if (param >= 40 && param <= 47)
1638 changebackground = 1;
1639 if (!vc_normal_background &&
1640 !param)
1641 changebackground = 1;
1642 param = 0;
1643 }
1644 break; /* continue on */
1645 }
1646 vtState = ESgotpars;
1647 /* fall */
1648 case ESgotpars:
1649 switch (vc_forward_buffer[i]) {
1650 case 'm':
1651 vtState = ESnormal;
1652 if (param >= 40 && param <= 47)
1653 changebackground = 1;
1654 if (!vc_normal_background &&
1655 !param)
1656 changebackground = 1;
1657 if (changebackground) {
1658 plaintext = 0;
1659 jump = 0;
1660 /* REALLY don't jump */
1661 }
1662 /* Yup ! we've got it */
1663 break;
1664 default:
1665 plaintext = 0;
1666 break;
1667 }
1668 break;
1669 default:
1670 plaintext = 0;
1671 break;
1672 }
1673
1674 }
1675
1676 /*
1677 * Then we look if it would be appropriate to forward jump
1678 * the screen before drawing
1679 */
1680 if (jump && (scrreg_bottom - scrreg_top) > 2) {
1681 jump -= scrreg_bottom - y - 1;
1682 if (jump > 0 ) {
1683 if (jump >= scrreg_bottom - scrreg_top)
1684 jump = scrreg_bottom - scrreg_top -1;
1685 y -= jump;
1686 scrollup(jump);
1687 }
1688 }
1689 /*
1690 * and we draw what we've found to the parser
1691 */
1692 for (i = start; i < drawlen; i++)
1693 vc_putchar(vc_forward_buffer[start++]);
1694 /*
1695 * Continue sending characters to the parser until we're sure we're
1696 * back on normal characters.
1697 */
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);
1704
1705 reversecursor();
1706
1707 /* Re-acquire the lock while we check our state. */
1708 s = splhigh();
1709 simple_lock(&vc_forward_lock);
1710 }
1711
1712 vc_forward_buffer_busy = 0;
1713 vc_forward_buffer_size = 0;
1714
1715 simple_unlock(&vc_forward_lock);
1716 splx(s);
1717 }
1718
1719 int
1720 vcputc(int l, int u, int c)
1721 {
1722 if(!vinfo.v_baseaddr)
1723 return;
1724
1725 /*
1726 * Either we're really buffering stuff or we're not yet because
1727 * the probe hasn't been done.
1728 */
1729 if (vc_forward_buffer_enabled)
1730 vc_store_char(c);
1731 else
1732 vc_putchar(c);
1733
1734 return 0;
1735 }
1736
1737 /*
1738 * Store characters to be drawn 'later', handle overflows
1739 */
1740
1741 static void
1742 vc_store_char(unsigned char c)
1743 {
1744 int flush = 0;
1745 spl_t s;
1746
1747 assert(vc_forward_buffer_enabled);
1748
1749 s = splhigh();
1750 simple_lock(&vc_forward_lock);
1751
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);
1755 splx(s);
1756 /* wait */
1757 s = splhigh();
1758 simple_lock(&vc_forward_lock);
1759 }
1760
1761 assert(vc_forward_buffer_size < VC_MAX_FORWARD_SIZE);
1762
1763 vc_forward_buffer[vc_forward_buffer_size++] = (unsigned char)c;
1764
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.
1768 */
1769 if (debug_mode) {
1770 flush = 1;
1771 } else {
1772 timeout((timeout_fcn_t)vc_flush_forward_buffer,
1773 (void *)0,
1774 VC_CONSOLE_UPDATE_TIMEOUT);
1775 }
1776 } else if (vc_forward_buffer_size == VC_MAX_FORWARD_SIZE || debug_mode) {
1777 /*
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).
1781 */
1782 if (!vc_forward_buffer_busy) {
1783 flush = 1;
1784 untimeout((timeout_fcn_t)vc_flush_forward_buffer, (void *)0);
1785 }
1786 }
1787
1788 simple_unlock(&vc_forward_lock);
1789 splx(s);
1790
1791 if (flush) {
1792 /*
1793 * Immediate character display.. kernel printf uses this. Make sure
1794 * get flushed and that panics get fully displayed.
1795 */
1796 vc_flush_forward_buffer();
1797 }
1798 }
1799
1800 static void
1801 vc_initialize(void)
1802 {
1803 #if 0
1804 GratefulDebInit(); /* (TEST/DEBUG) */
1805 #endif
1806
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);
1813 #endif
1814
1815 vinfo.v_rows = vinfo.v_height / CHARHEIGHT;
1816 vinfo.v_columns = vinfo.v_width / CHARWIDTH;
1817
1818 if (vinfo.v_depth >= 8) {
1819 vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
1820 } else {
1821 vinfo.v_rowscanbytes = vinfo.v_width / (8 / vinfo.v_depth);
1822 }
1823
1824 #if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
1825 printf(" inited=%d\n", vc_initted);
1826 #endif
1827
1828
1829 vc_render_font(1, vinfo.v_depth);
1830 vc_color_mask = vc_color_depth_masks[vc_color_index_table[vinfo.v_depth]];
1831 vt100_reset();
1832 switch (vinfo.v_depth) {
1833 default:
1834 case 1:
1835 vc_paintchar = vc_paint_char1;
1836 break;
1837 case 2:
1838 vc_paintchar = vc_paint_char2;
1839 break;
1840 case 4:
1841 vc_paintchar = vc_paint_char4;
1842 break;
1843 case 8:
1844 vc_paintchar = vc_paint_char8c;
1845 break;
1846 case 16:
1847 vc_paintchar = vc_paint_char16c;
1848 break;
1849 case 32:
1850 vc_paintchar = vc_paint_char32c;
1851 break;
1852 }
1853
1854 #ifdef FAST_JUMP_SCROLL
1855 vc_forward_paintchar = vc_paintchar;
1856 vc_paintchar = vc_paint_char;
1857 #endif FAST_JUMP_SCROLL
1858 }
1859
1860 void
1861 vcattach(void)
1862 {
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);
1867
1868 /*
1869 * Added for the buffering and jump scrolling
1870 */
1871 /* Init our lock */
1872 simple_lock_init(&vc_forward_lock, ETAP_IO_TTY);
1873
1874 vc_forward_buffer_enabled = 1;
1875
1876 }
1877
1878
1879 struct vc_progress_element {
1880 unsigned int version;
1881 unsigned int flags;
1882 unsigned int time;
1883 unsigned char count;
1884 unsigned char res[3];
1885 int width;
1886 int height;
1887 int dx;
1888 int dy;
1889 int transparent;
1890 unsigned int res2[3];
1891 unsigned char data[0];
1892 };
1893 typedef struct vc_progress_element vc_progress_element;
1894
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;
1903
1904 static void vc_blit_rect_8c( int x, int y,
1905 int width, int height,
1906 int transparent, unsigned char * dataPtr )
1907 {
1908 volatile unsigned char * dst;
1909 int line, col;
1910 unsigned char data;
1911
1912 dst = (unsigned char *)(vinfo.v_baseaddr +
1913 (y * vinfo.v_rowbytes) +
1914 (x));
1915
1916 for( line = 0; line < height; line++) {
1917 for( col = 0; col < width; col++) {
1918 data = *dataPtr++;
1919 if( data == transparent)
1920 continue;
1921
1922 *(dst + col) = data;
1923 }
1924 dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1925 }
1926
1927 }
1928
1929 static void vc_blit_rect_8m( int x, int y,
1930 int width, int height,
1931 int transparent, unsigned char * dataPtr )
1932 {
1933 volatile unsigned char * dst;
1934 int line, col;
1935 unsigned int data;
1936
1937 dst = (unsigned char *)(vinfo.v_baseaddr +
1938 (y * vinfo.v_rowbytes) +
1939 (x));
1940
1941 for( line = 0; line < height; line++) {
1942 for( col = 0; col < width; col++) {
1943 data = *dataPtr++;
1944 if( data == transparent)
1945 continue;
1946
1947 data *= 3;
1948 *(dst + col) = ((19595 * vc_clut[data + 0] +
1949 38470 * vc_clut[data + 1] +
1950 7471 * vc_clut[data + 2] ) / 65536);
1951 }
1952 dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1953 }
1954 }
1955
1956
1957
1958 static void vc_blit_rect_16( int x, int y,
1959 int width, int height,
1960 int transparent, unsigned char * dataPtr )
1961 {
1962 volatile unsigned short * dst;
1963 int line, col;
1964 unsigned int data;
1965
1966 dst = (volatile unsigned short *)(vinfo.v_baseaddr +
1967 (y * vinfo.v_rowbytes) +
1968 (x * 2));
1969
1970 for( line = 0; line < height; line++) {
1971 for( col = 0; col < width; col++) {
1972 data = *dataPtr++;
1973 if( data == transparent)
1974 continue;
1975
1976 data *= 3;
1977 *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
1978 | ( (0xf8 & (vc_clut[data + 1])) << 2)
1979 | ( (0xf8 & (vc_clut[data + 2])) >> 3);
1980 }
1981 dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
1982 }
1983 }
1984
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 )
1988 {
1989 volatile unsigned int * dst;
1990 int line, col;
1991 unsigned int data;
1992
1993 dst = (volatile unsigned int *) (vinfo.v_baseaddr +
1994 (y * vinfo.v_rowbytes) +
1995 (x * 4));
1996
1997 for( line = 0; line < height; line++) {
1998 for( col = 0; col < width; col++) {
1999 data = *dataPtr++;
2000 if( data == transparent)
2001 continue;
2002
2003 data *= 3;
2004 *(dst + col) = (vc_clut[data + 0] << 16)
2005 | (vc_clut[data + 1] << 8)
2006 | (vc_clut[data + 2]);
2007 }
2008 dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
2009 }
2010 }
2011
2012 static void vc_blit_rect( int x, int y,
2013 int width, int height,
2014 int transparent, unsigned char * dataPtr )
2015 {
2016 if(!vinfo.v_baseaddr)
2017 return;
2018
2019 switch( vinfo.v_depth) {
2020 case 8:
2021 vc_blit_rect_8c( x, y, width, height, transparent, dataPtr);
2022 break;
2023 case 16:
2024 vc_blit_rect_16( x, y, width, height, transparent, dataPtr);
2025 break;
2026 case 32:
2027 vc_blit_rect_32( x, y, width, height, transparent, dataPtr);
2028 break;
2029 }
2030 }
2031
2032 static void vc_progress_task( void * arg )
2033 {
2034 spl_t s;
2035 int count = (int) arg;
2036 int x, y, width, height;
2037 unsigned char * data;
2038
2039 s = splhigh();
2040 simple_lock(&vc_forward_lock);
2041
2042 if( vc_progress_enable) {
2043 count++;
2044 if( count >= vc_progress->count)
2045 count = 0;
2046
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);
2056 }
2057 vc_blit_rect( x, y, width, height,
2058 vc_progress->transparent,data );
2059
2060 timeout( vc_progress_task, (void *) count,
2061 vc_progress_tick );
2062 }
2063 simple_unlock(&vc_forward_lock);
2064 splx(s);
2065 }
2066
2067 void vc_display_icon( vc_progress_element * desc,
2068 unsigned char * data )
2069 {
2070 int x, y, width, height;
2071
2072 if( vc_acquired && vc_graphics_mode && vc_clut) {
2073
2074 width = desc->width;
2075 height = desc->height;
2076 x = desc->dx;
2077 y = desc->dy;
2078 if( 1 & desc->flags) {
2079 x += (vinfo.v_width / 2);
2080 y += (vinfo.v_height / 2);
2081 }
2082 vc_blit_rect( x, y, width, height, desc->transparent, data );
2083 }
2084 }
2085
2086 static boolean_t
2087 vc_progress_set( boolean_t enable )
2088 {
2089 spl_t s;
2090
2091 if( !vc_progress)
2092 return( FALSE );
2093
2094 s = splhigh();
2095 simple_lock(&vc_forward_lock);
2096
2097 if( vc_progress_enable != enable) {
2098 vc_progress_enable = enable;
2099 if( enable)
2100 timeout(vc_progress_task, (void *) 0,
2101 vc_progress_tick );
2102 else
2103 untimeout( vc_progress_task, (void *) 0 );
2104 }
2105
2106 simple_unlock(&vc_forward_lock);
2107 splx(s);
2108
2109 return( TRUE );
2110 }
2111
2112
2113 boolean_t
2114 vc_progress_initialize( vc_progress_element * desc,
2115 unsigned char * data,
2116 unsigned char * clut )
2117 {
2118 if( (!clut) || (!desc) || (!data))
2119 return( FALSE );
2120 vc_clut = clut;
2121
2122 vc_progress = desc;
2123 vc_progress_data = data;
2124 vc_progress_tick = vc_progress->time * hz / 1000;
2125
2126 return( TRUE );
2127 }
2128
2129 // FirmwareC.c needs:
2130 Boot_Video boot_video_info;
2131
2132 extern int disableConsoleOutput;
2133
2134 static void vc_clear_screen( void )
2135 {
2136 reversecursor();
2137 vt100_reset();
2138 x = y = 0;
2139 clear_screen(2);
2140 reversecursor();
2141 };
2142
2143 void
2144 initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
2145 {
2146 if( boot_vinfo) {
2147 bcopy( (const void *) boot_vinfo,
2148 (void *) &boot_video_info,
2149 sizeof( boot_video_info));
2150
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;
2158 vinfo.v_type = 0;
2159
2160 vc_initialize();
2161 #if 0
2162 GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re-initialize GratefulDeb */
2163 #endif
2164 }
2165
2166 switch( op ) {
2167
2168 case kPEGraphicsMode:
2169 vc_graphics_mode = TRUE;
2170 disableConsoleOutput = TRUE;
2171 vc_acquired = TRUE;
2172 break;
2173
2174 case kPETextMode:
2175 vc_graphics_mode = FALSE;
2176 disableConsoleOutput = FALSE;
2177 vc_acquired = TRUE;
2178 vc_clear_screen();
2179 break;
2180
2181 case kPETextScreen:
2182 vc_progress_set( FALSE );
2183 disableConsoleOutput = FALSE;
2184 if( vc_need_clear) {
2185 vc_need_clear = FALSE;
2186 vc_clear_screen();
2187 }
2188 break;
2189
2190 case kPEEnableScreen:
2191 if( vc_acquired) {
2192 if( vc_graphics_mode)
2193 vc_progress_set( TRUE );
2194 else
2195 vc_clear_screen();
2196 }
2197 break;
2198
2199 case kPEDisableScreen:
2200 vc_progress_set( FALSE );
2201 break;
2202
2203 case kPEAcquireScreen:
2204 vc_need_clear = (FALSE == vc_acquired);
2205 vc_acquired = TRUE;
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;
2210 vc_clear_screen();
2211 }
2212 break;
2213
2214 case kPEReleaseScreen:
2215 vc_acquired = FALSE;
2216 vc_progress_set( FALSE );
2217 disableConsoleOutput = TRUE;
2218 #if 0
2219 GratefulDebInit(0); /* Stop grateful debugger */
2220 #endif
2221 break;
2222 }
2223 #if 0
2224 if( boot_vinfo) GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re initialize GratefulDeb */
2225 #endif
2226 }