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