]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/POWERMAC/video_console.c
xnu-124.13.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 extern int asc_ringbell(); //In IOBSDConsole.cpp
1003 int rang;
1004 spl_t s;
1005
1006 rang = asc_ringbell();
1007
1008 if(!rang) {
1009 /*
1010 * No sound hardware, invert the screen twice instead
1011 */
1012 unsigned long *ptr;
1013 int i, j;
1014 /* XOR the screen twice */
1015 for (i = 0; i < 2 ; i++) {
1016 /* For each row, xor the scanbytes */
1017 for (ptr = (unsigned long*)vinfo.v_baseaddr;
1018 ptr < (unsigned long*)(vinfo.v_baseaddr +
1019 (vinfo.v_height * vinfo.v_rowbytes));
1020 ptr += (vinfo.v_rowbytes /
1021 sizeof (unsigned long*)))
1022 for (j = 0;
1023 j < vinfo.v_rowscanbytes /
1024 sizeof (unsigned long*);
1025 j++)
1026 *(ptr+j) =~*(ptr+j);
1027 }
1028 }
1029 }
1030 break;
1031
1032 case 127: /* Delete */
1033 case '\b': /* Backspace */
1034 if (hanging_cursor) {
1035 hanging_cursor = 0;
1036 } else
1037 if (x > 0) {
1038 x--;
1039 }
1040 break;
1041 case '\t': /* Tab */
1042 while (x < vinfo.v_columns && !tab_stops[++x]);
1043 if (x >= vinfo.v_columns)
1044 x = vinfo.v_columns-1;
1045 break;
1046 case 0x0b:
1047 case 0x0c:
1048 case '\n': /* Line feed */
1049 if (y >= scrreg_bottom -1 ) {
1050 scrollup(1);
1051 y = scrreg_bottom - 1;
1052 } else {
1053 y++;
1054 }
1055 break;
1056 case '\r': /* Carriage return */
1057 x = 0;
1058 hanging_cursor = 0;
1059 break;
1060 case 0x0e: /* Select G1 charset (Control-N) */
1061 vc_charset_select = 1;
1062 break;
1063 case 0x0f: /* Select G0 charset (Control-O) */
1064 vc_charset_select = 0;
1065 break;
1066 case 0x18 : /* CAN : cancel */
1067 case 0x1A : /* like cancel */
1068 /* well, i do nothing here, may be later */
1069 break;
1070 case '\033': /* Escape */
1071 vt100state = ESesc;
1072 hanging_cursor = 0;
1073 break;
1074 default:
1075 if (ch >= ' ') {
1076 if (hanging_cursor) {
1077 x = 0;
1078 if (y >= scrreg_bottom -1 ) {
1079 scrollup(1);
1080 y = scrreg_bottom - 1;
1081 } else {
1082 y++;
1083 }
1084 hanging_cursor = 0;
1085 }
1086 vc_paintchar((ch >= 0x60 && ch <= 0x7f) ? ch + vc_charset[vc_charset_select]
1087 : ch, x, y, attr);
1088 if (x == vinfo.v_columns - 1) {
1089 hanging_cursor = vc_wrap_mode;
1090 } else {
1091 x++;
1092 }
1093 }
1094 break;
1095 }
1096
1097 }
1098
1099 static void
1100 putc_esc(unsigned char ch)
1101 {
1102 vt100state = ESnormal;
1103
1104 switch (ch) {
1105 case '[':
1106 vt100state = ESsquare;
1107 break;
1108 case 'c': /* Reset terminal */
1109 vt100_reset();
1110 clear_screen(2);
1111 x = y = 0;
1112 break;
1113 case 'D': /* Line feed */
1114 case 'E':
1115 if (y >= scrreg_bottom -1) {
1116 scrollup(1);
1117 y = scrreg_bottom - 1;
1118 } else {
1119 y++;
1120 }
1121 if (ch == 'E') x = 0;
1122 break;
1123 case 'H': /* Set tab stop */
1124 tab_stops[x] = 1;
1125 break;
1126 case 'M': /* Cursor up */
1127 if (y <= scrreg_top) {
1128 scrolldown(1);
1129 y = scrreg_top;
1130 } else {
1131 y--;
1132 }
1133 break;
1134 case '>':
1135 vt100_reset();
1136 break;
1137 case '7': /* Save cursor */
1138 savex = x;
1139 savey = y;
1140 saveattr = attr;
1141 vc_save_charset_s = vc_charset_select;
1142 vc_charset_save[0] = vc_charset[0];
1143 vc_charset_save[1] = vc_charset[1];
1144 break;
1145 case '8': /* Restore cursor */
1146 x = savex;
1147 y = savey;
1148 attr = saveattr;
1149 vc_charset_select = vc_save_charset_s;
1150 vc_charset[0] = vc_charset_save[0];
1151 vc_charset[1] = vc_charset_save[1];
1152 break;
1153 case 'Z': /* return terminal ID */
1154 break;
1155 case '#': /* change characters height */
1156 vt100state = EScharsize;
1157 break;
1158 case '(':
1159 vt100state = ESsetG0;
1160 break;
1161 case ')': /* character set sequence */
1162 vt100state = ESsetG1;
1163 break;
1164 case '=':
1165 break;
1166 default:
1167 /* Rest not supported */
1168 break;
1169 }
1170
1171 }
1172
1173 static void
1174 putc_askcmd(unsigned char ch)
1175 {
1176 if (ch >= '0' && ch <= '9') {
1177 par[numpars] = (10*par[numpars]) + (ch-'0');
1178 return;
1179 }
1180 vt100state = ESnormal;
1181
1182 switch (par[0]) {
1183 case 6:
1184 vc_relative_origin = ch == 'h';
1185 break;
1186 case 7: /* wrap around mode h=1, l=0*/
1187 vc_wrap_mode = ch == 'h';
1188 break;
1189 default:
1190 break;
1191 }
1192
1193 }
1194
1195 static void
1196 putc_charsizecmd(unsigned char ch)
1197 {
1198 vt100state = ESnormal;
1199
1200 switch (ch) {
1201 case '3' :
1202 case '4' :
1203 case '5' :
1204 case '6' :
1205 break;
1206 case '8' : /* fill 'E's */
1207 {
1208 int xx, yy;
1209 for (yy = 0; yy < vinfo.v_rows; yy++)
1210 for (xx = 0; xx < vinfo.v_columns; xx++)
1211 vc_paintchar('E', xx, yy, ATTR_NONE);
1212 }
1213 break;
1214 }
1215
1216 }
1217
1218 static void
1219 putc_charsetcmd(int charset, unsigned char ch)
1220 {
1221 vt100state = ESnormal;
1222
1223 switch (ch) {
1224 case 'A' :
1225 case 'B' :
1226 default:
1227 vc_charset[charset] = 0;
1228 break;
1229 case '0' : /* Graphic characters */
1230 case '2' :
1231 vc_charset[charset] = 0x21;
1232 break;
1233 }
1234
1235 }
1236
1237 static void
1238 putc_gotpars(unsigned char ch)
1239 {
1240 int i;
1241
1242 if (ch < ' ') {
1243 /* special case for vttest for handling cursor
1244 movement in escape sequences */
1245 putc_normal(ch);
1246 vt100state = ESgotpars;
1247 return;
1248 }
1249 vt100state = ESnormal;
1250 switch (ch) {
1251 case 'A': /* Up */
1252 y -= par[0] ? par[0] : 1;
1253 if (y < scrreg_top)
1254 y = scrreg_top;
1255 break;
1256 case 'B': /* Down */
1257 y += par[0] ? par[0] : 1;
1258 if (y >= scrreg_bottom)
1259 y = scrreg_bottom - 1;
1260 break;
1261 case 'C': /* Right */
1262 x += par[0] ? par[0] : 1;
1263 if (x >= vinfo.v_columns)
1264 x = vinfo.v_columns-1;
1265 break;
1266 case 'D': /* Left */
1267 x -= par[0] ? par[0] : 1;
1268 if (x < 0)
1269 x = 0;
1270 break;
1271 case 'H': /* Set cursor position */
1272 case 'f':
1273 x = par[1] ? par[1] - 1 : 0;
1274 y = par[0] ? par[0] - 1 : 0;
1275 if (vc_relative_origin)
1276 y += scrreg_top;
1277 hanging_cursor = 0;
1278 break;
1279 case 'X': /* clear p1 characters */
1280 if (numpars) {
1281 int i;
1282 for (i = x; i < x + par[0]; i++)
1283 vc_paintchar(' ', i, y, ATTR_NONE);
1284 }
1285 break;
1286 case 'J': /* Clear part of screen */
1287 clear_screen(par[0]);
1288 break;
1289 case 'K': /* Clear part of line */
1290 clear_line(par[0]);
1291 break;
1292 case 'g': /* tab stops */
1293 switch (par[0]) {
1294 case 1:
1295 case 2: /* reset tab stops */
1296 /* reset_tabs(); */
1297 break;
1298 case 3: /* Clear every tabs */
1299 {
1300 int i;
1301
1302 for (i = 0; i <= vinfo.v_columns; i++)
1303 tab_stops[i] = 0;
1304 }
1305 break;
1306 case 0:
1307 tab_stops[x] = 0;
1308 break;
1309 }
1310 break;
1311 case 'm': /* Set attribute */
1312 for (i = 0; i < numpars; i++) {
1313 switch (par[i]) {
1314 case 0:
1315 attr = ATTR_NONE;
1316 vc_color_set(VC_RESET_BACKGROUND);
1317 vc_color_set(VC_RESET_FOREGROUND);
1318 break;
1319 case 1:
1320 attr |= ATTR_BOLD;
1321 break;
1322 case 4:
1323 attr |= ATTR_UNDER;
1324 break;
1325 case 7:
1326 attr |= ATTR_REVERSE;
1327 break;
1328 case 22:
1329 attr &= ~ATTR_BOLD;
1330 break;
1331 case 24:
1332 attr &= ~ATTR_UNDER;
1333 break;
1334 case 27:
1335 attr &= ~ATTR_REVERSE;
1336 break;
1337 case 5:
1338 case 25: /* blink/no blink */
1339 break;
1340 default:
1341 vc_color_set(par[i]);
1342 break;
1343 }
1344 }
1345 break;
1346 case 'r': /* Set scroll region */
1347 x = y = 0;
1348 /* ensure top < bottom, and both within limits */
1349 if ((numpars > 0) && (par[0] < vinfo.v_rows)) {
1350 scrreg_top = par[0] ? par[0] - 1 : 0;
1351 if (scrreg_top < 0)
1352 scrreg_top = 0;
1353 } else {
1354 scrreg_top = 0;
1355 }
1356 if ((numpars > 1) && (par[1] <= vinfo.v_rows) && (par[1] > par[0])) {
1357 scrreg_bottom = par[1];
1358 if (scrreg_bottom > vinfo.v_rows)
1359 scrreg_bottom = vinfo.v_rows;
1360 } else {
1361 scrreg_bottom = vinfo.v_rows;
1362 }
1363 if (vc_relative_origin)
1364 y = scrreg_top;
1365 break;
1366 }
1367
1368 }
1369
1370 static void
1371 putc_getpars(unsigned char ch)
1372 {
1373 if (ch == '?') {
1374 vt100state = ESask;
1375 return;
1376 }
1377 if (ch == '[') {
1378 vt100state = ESnormal;
1379 /* Not supported */
1380 return;
1381 }
1382 if (ch == ';' && numpars < MAXPARS - 1) {
1383 numpars++;
1384 } else
1385 if (ch >= '0' && ch <= '9') {
1386 par[numpars] *= 10;
1387 par[numpars] += ch - '0';
1388 } else {
1389 numpars++;
1390 vt100state = ESgotpars;
1391 putc_gotpars(ch);
1392 }
1393 }
1394
1395 static void
1396 putc_square(unsigned char ch)
1397 {
1398 int i;
1399
1400 for (i = 0; i < MAXPARS; i++) {
1401 par[i] = 0;
1402 }
1403
1404 numpars = 0;
1405 vt100state = ESgetpars;
1406
1407 putc_getpars(ch);
1408
1409 }
1410
1411 void
1412 vc_putchar(char ch)
1413 {
1414 if (!ch) {
1415 return; /* ignore null characters */
1416 }
1417 switch (vt100state) {
1418 default:vt100state = ESnormal; /* FALLTHROUGH */
1419 case ESnormal:
1420 putc_normal(ch);
1421 break;
1422 case ESesc:
1423 putc_esc(ch);
1424 break;
1425 case ESsquare:
1426 putc_square(ch);
1427 break;
1428 case ESgetpars:
1429 putc_getpars(ch);
1430 break;
1431 case ESgotpars:
1432 putc_gotpars(ch);
1433 break;
1434 case ESask:
1435 putc_askcmd(ch);
1436 break;
1437 case EScharsize:
1438 putc_charsizecmd(ch);
1439 break;
1440 case ESsetG0:
1441 putc_charsetcmd(0, ch);
1442 break;
1443 case ESsetG1:
1444 putc_charsetcmd(1, ch);
1445 break;
1446 }
1447
1448 if (x >= vinfo.v_columns) {
1449 x = vinfo.v_columns - 1;
1450 }
1451 if (x < 0) {
1452 x = 0;
1453 }
1454 if (y >= vinfo.v_rows) {
1455 y = vinfo.v_rows - 1;
1456 }
1457 if (y < 0) {
1458 y = 0;
1459 }
1460
1461 }
1462
1463 /*
1464 * Actually draws the buffer, handle the jump scroll
1465 */
1466 void vc_flush_forward_buffer(void)
1467 {
1468 int start = 0;
1469 int todo = 0;
1470 spl_t s;
1471
1472 assert(vc_forward_buffer_enabled);
1473
1474 s = splhigh();
1475 simple_lock(&vc_forward_lock);
1476
1477 if (vc_forward_buffer_busy) {
1478 /* Bail out if we're already in the middle of a flush. */
1479 simple_unlock(&vc_forward_lock);
1480 splx(s);
1481 return;
1482 }
1483
1484 vc_forward_buffer_busy = 1;
1485
1486 while (todo < vc_forward_buffer_size) {
1487 todo = vc_forward_buffer_size;
1488
1489 /* Drop the lock while we update the screen. */
1490 simple_unlock(&vc_forward_lock);
1491 splx(s);
1492
1493 reversecursor();
1494
1495 do {
1496 int i;
1497 #ifdef FAST_JUMP_SCROLL
1498 if ((todo - start) < 2) {
1499 vc_putchar(vc_forward_buffer[start++]);
1500 } else {
1501 assert(vc_forward_scroll == 0);
1502
1503 vc_forward_preflight_save.vt100state = vt100state;
1504 vc_forward_preflight_save.vc_wrap_mode = vc_wrap_mode;
1505 vc_forward_preflight_save.vc_relative_origin = vc_relative_origin;
1506 vc_forward_preflight_save.vc_charset_select = vc_charset_select;
1507 vc_forward_preflight_save.vc_save_charset_s = vc_save_charset_s;
1508 vc_forward_preflight_save.vc_charset[0] = vc_charset[0];
1509 vc_forward_preflight_save.vc_charset[1] = vc_charset[1];
1510 vc_forward_preflight_save.vc_charset_save[0] = vc_charset_save[0];
1511 vc_forward_preflight_save.vc_charset_save[1] = vc_charset_save[1];
1512 vc_forward_preflight_save.x = x;
1513 vc_forward_preflight_save.y = y;
1514 vc_forward_preflight_save.savex = savex;
1515 vc_forward_preflight_save.savey = savey;
1516 vc_forward_preflight_save.numpars = numpars;
1517 vc_forward_preflight_save.hanging_cursor = hanging_cursor;
1518 vc_forward_preflight_save.attr = attr;
1519 vc_forward_preflight_save.saveattr = saveattr;
1520 vc_forward_preflight_save.scrreg_top = scrreg_top;
1521 vc_forward_preflight_save.scrreg_bottom = scrreg_bottom;
1522 vc_forward_preflight_save.vc_color_fore = vc_color_fore;
1523 vc_forward_preflight_save.vc_color_back = vc_color_back;
1524 bcopy( (const char *) par,
1525 (char *) vc_forward_preflight_save.par,
1526 (vm_size_t) sizeof(par) );
1527 bcopy( (const char *) tab_stops,
1528 (char *) vc_forward_preflight_save.tab_stops,
1529 (vm_size_t) sizeof(tab_stops) );
1530
1531 vc_forward_preflight_mode = PFwind;
1532
1533 for (i = start;
1534 i < todo &&
1535 vc_forward_preflight_save.scrreg_top == scrreg_top &&
1536 vc_forward_preflight_save.scrreg_bottom == scrreg_bottom;
1537 i++)
1538 vc_putchar(vc_forward_buffer[i]);
1539
1540 vt100state = vc_forward_preflight_save.vt100state;
1541 vc_wrap_mode = vc_forward_preflight_save.vc_wrap_mode;
1542 vc_relative_origin = vc_forward_preflight_save.vc_relative_origin;
1543 vc_charset_select = vc_forward_preflight_save.vc_charset_select;
1544 vc_save_charset_s = vc_forward_preflight_save.vc_save_charset_s;
1545 vc_charset[0] = vc_forward_preflight_save.vc_charset[0];
1546 vc_charset[1] = vc_forward_preflight_save.vc_charset[1];
1547 vc_charset_save[0] = vc_forward_preflight_save.vc_charset_save[0];
1548 vc_charset_save[1] = vc_forward_preflight_save.vc_charset_save[1];
1549 x = vc_forward_preflight_save.x;
1550 y = vc_forward_preflight_save.y;
1551 savex = vc_forward_preflight_save.savex;
1552 savey = vc_forward_preflight_save.savey;
1553 numpars = vc_forward_preflight_save.numpars;
1554 hanging_cursor = vc_forward_preflight_save.hanging_cursor;
1555 attr = vc_forward_preflight_save.attr;
1556 saveattr = vc_forward_preflight_save.saveattr;
1557 scrreg_top = vc_forward_preflight_save.scrreg_top;
1558 scrreg_bottom = vc_forward_preflight_save.scrreg_bottom;
1559 vc_color_fore = vc_forward_preflight_save.vc_color_fore;
1560 vc_color_back = vc_forward_preflight_save.vc_color_back;
1561 bcopy( (const char *) vc_forward_preflight_save.par,
1562 (char *) par,
1563 (vm_size_t) sizeof(par) );
1564 bcopy( (const char *) vc_forward_preflight_save.tab_stops,
1565 (char *) tab_stops,
1566 (vm_size_t) sizeof(tab_stops) );
1567
1568 vc_forward_preflight_mode = PFscroll;
1569
1570 if (vc_forward_scroll > 0)
1571 scrollup(vc_forward_scroll > scrreg_bottom - scrreg_top ?
1572 scrreg_bottom - scrreg_top : vc_forward_scroll);
1573 else if (vc_forward_scroll < 0)
1574 scrolldown(-vc_forward_scroll > scrreg_bottom - scrreg_top ?
1575 scrreg_bottom - scrreg_top : -vc_forward_scroll);
1576
1577 vc_forward_preflight_mode = PFunwind;
1578
1579 for (; start < i; start++)
1580 vc_putchar(vc_forward_buffer[start]);
1581
1582 assert(vc_forward_scroll == 0);
1583
1584 vc_forward_preflight_mode = PFoff;
1585 }
1586 #else !FAST_JUMP_SCROLL
1587 int plaintext = 1;
1588 int drawlen = start;
1589 int jump = 0;
1590 int param = 0, changebackground = 0;
1591 enum vt100state_e vtState = vt100state;
1592 /*
1593 * In simple words, here we're pre-parsing the text to look for
1594 * + Newlines, for computing jump scroll
1595 * + /\033\[[0-9;]*]m/ to continue on
1596 * any other sequence will stop. We don't want to have cursor
1597 * movement escape sequences while we're trying to pre-scroll
1598 * the screen.
1599 * We have to be extra carefull about the sequences that changes
1600 * the background color to prevent scrolling in those
1601 * particular cases.
1602 * That parsing was added to speed up 'man' and 'color-ls' a
1603 * zillion time (at least). It's worth it, trust me.
1604 * (mail Nick Stephen for a True Performance Graph)
1605 * Michel Pollet
1606 */
1607 for (i = start; i < todo && plaintext; i++) {
1608 drawlen++;
1609 switch (vtState) {
1610 case ESnormal:
1611 switch (vc_forward_buffer[i]) {
1612 case '\033':
1613 vtState = ESesc;
1614 break;
1615 case '\n':
1616 jump++;
1617 break;
1618 }
1619 break;
1620 case ESesc:
1621 switch (vc_forward_buffer[i]) {
1622 case '[':
1623 vtState = ESgetpars;
1624 param = 0;
1625 changebackground = 0;
1626 break;
1627 default:
1628 plaintext = 0;
1629 break;
1630 }
1631 break;
1632 case ESgetpars:
1633 if ((vc_forward_buffer[i] >= '0' &&
1634 vc_forward_buffer[i] <= '9') ||
1635 vc_forward_buffer[i] == ';') {
1636 if (vc_forward_buffer[i] >= '0' &&
1637 vc_forward_buffer[i] <= '9')
1638 param = (param*10)+(vc_forward_buffer[i]-'0');
1639 else {
1640 if (param >= 40 && param <= 47)
1641 changebackground = 1;
1642 if (!vc_normal_background &&
1643 !param)
1644 changebackground = 1;
1645 param = 0;
1646 }
1647 break; /* continue on */
1648 }
1649 vtState = ESgotpars;
1650 /* fall */
1651 case ESgotpars:
1652 switch (vc_forward_buffer[i]) {
1653 case 'm':
1654 vtState = ESnormal;
1655 if (param >= 40 && param <= 47)
1656 changebackground = 1;
1657 if (!vc_normal_background &&
1658 !param)
1659 changebackground = 1;
1660 if (changebackground) {
1661 plaintext = 0;
1662 jump = 0;
1663 /* REALLY don't jump */
1664 }
1665 /* Yup ! we've got it */
1666 break;
1667 default:
1668 plaintext = 0;
1669 break;
1670 }
1671 break;
1672 default:
1673 plaintext = 0;
1674 break;
1675 }
1676
1677 }
1678
1679 /*
1680 * Then we look if it would be appropriate to forward jump
1681 * the screen before drawing
1682 */
1683 if (jump && (scrreg_bottom - scrreg_top) > 2) {
1684 jump -= scrreg_bottom - y - 1;
1685 if (jump > 0 ) {
1686 if (jump >= scrreg_bottom - scrreg_top)
1687 jump = scrreg_bottom - scrreg_top -1;
1688 y -= jump;
1689 scrollup(jump);
1690 }
1691 }
1692 /*
1693 * and we draw what we've found to the parser
1694 */
1695 for (i = start; i < drawlen; i++)
1696 vc_putchar(vc_forward_buffer[start++]);
1697 /*
1698 * Continue sending characters to the parser until we're sure we're
1699 * back on normal characters.
1700 */
1701 for (i = start; i < todo &&
1702 vt100state != ESnormal ; i++)
1703 vc_putchar(vc_forward_buffer[start++]);
1704 #endif !FAST_JUMP_SCROLL
1705 /* Then loop again if there still things to draw */
1706 } while (start < todo);
1707
1708 reversecursor();
1709
1710 /* Re-acquire the lock while we check our state. */
1711 s = splhigh();
1712 simple_lock(&vc_forward_lock);
1713 }
1714
1715 vc_forward_buffer_busy = 0;
1716 vc_forward_buffer_size = 0;
1717
1718 simple_unlock(&vc_forward_lock);
1719 splx(s);
1720 }
1721
1722 int
1723 vcputc(int l, int u, int c)
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 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 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 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 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 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 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 void vc_blit_rect( int x, int y,
2013 int width, int height,
2014 int transparent, unsigned char * dataPtr )
2015 {
2016 switch( vinfo.v_depth) {
2017 case 8:
2018 vc_blit_rect_8c( x, y, width, height, transparent, dataPtr);
2019 break;
2020 case 16:
2021 vc_blit_rect_16( x, y, width, height, transparent, dataPtr);
2022 break;
2023 case 32:
2024 vc_blit_rect_32( x, y, width, height, transparent, dataPtr);
2025 break;
2026 }
2027 }
2028
2029 void vc_progress_task( void * arg )
2030 {
2031 spl_t s;
2032 int count = (int) arg;
2033 int x, y, width, height;
2034 unsigned char * data;
2035
2036 s = splhigh();
2037 simple_lock(&vc_forward_lock);
2038
2039 if( vc_progress_enable) {
2040 count++;
2041 if( count >= vc_progress->count)
2042 count = 0;
2043
2044 width = vc_progress->width;
2045 height = vc_progress->height;
2046 x = vc_progress->dx;
2047 y = vc_progress->dy;
2048 data = vc_progress_data;
2049 data += count * width * height;
2050 if( 1 & vc_progress->flags) {
2051 x += (vinfo.v_width / 2);
2052 x += (vinfo.v_height / 2);
2053 }
2054 vc_blit_rect( x, y, width, height,
2055 vc_progress->transparent,data );
2056
2057 timeout( vc_progress_task, (void *) count,
2058 vc_progress_tick );
2059 }
2060 simple_unlock(&vc_forward_lock);
2061 splx(s);
2062 }
2063
2064 void vc_display_icon( vc_progress_element * desc,
2065 unsigned char * data )
2066 {
2067 int x, y, width, height;
2068
2069 if( vc_acquired && vc_graphics_mode && vc_clut) {
2070
2071 width = desc->width;
2072 height = desc->height;
2073 x = desc->dx;
2074 y = desc->dy;
2075 if( 1 & desc->flags) {
2076 x += (vinfo.v_width / 2);
2077 y += (vinfo.v_height / 2);
2078 }
2079 vc_blit_rect( x, y, width, height, desc->transparent, data );
2080 }
2081 }
2082
2083 boolean_t
2084 vc_progress_set( boolean_t enable )
2085 {
2086 spl_t s;
2087
2088 if( !vc_progress)
2089 return( FALSE );
2090
2091 s = splhigh();
2092 simple_lock(&vc_forward_lock);
2093
2094 if( vc_progress_enable != enable) {
2095 vc_progress_enable = enable;
2096 if( enable)
2097 timeout(vc_progress_task, (void *) 0,
2098 vc_progress_tick );
2099 else
2100 untimeout( vc_progress_task, (void *) 0 );
2101 }
2102
2103 simple_unlock(&vc_forward_lock);
2104 splx(s);
2105
2106 return( TRUE );
2107 }
2108
2109
2110 boolean_t
2111 vc_progress_initialize( vc_progress_element * desc,
2112 unsigned char * data,
2113 unsigned char * clut )
2114 {
2115 if( (!clut) || (!desc) || (!data))
2116 return( FALSE );
2117 vc_clut = clut;
2118
2119 vc_progress = desc;
2120 vc_progress_data = data;
2121 vc_progress_tick = vc_progress->time * hz / 1000;
2122
2123 return( TRUE );
2124 }
2125
2126 // FirmwareC.c needs:
2127 Boot_Video boot_video_info;
2128
2129 extern int disableConsoleOutput;
2130
2131 void vc_clear_screen( void )
2132 {
2133 reversecursor();
2134 vt100_reset();
2135 x = y = 0;
2136 clear_screen(2);
2137 reversecursor();
2138 };
2139
2140 void
2141 initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
2142 {
2143 if( boot_vinfo) {
2144 bcopy( (const void *) boot_vinfo,
2145 (void *) &boot_video_info,
2146 sizeof( boot_video_info));
2147
2148 vinfo.v_name[0] = 0;
2149 vinfo.v_width = boot_vinfo->v_width;
2150 vinfo.v_height = boot_vinfo->v_height;
2151 vinfo.v_depth = boot_vinfo->v_depth;
2152 vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
2153 vinfo.v_physaddr = boot_vinfo->v_baseAddr;
2154 vinfo.v_baseaddr = vinfo.v_physaddr;
2155 vinfo.v_type = 0;
2156
2157 vc_initialize();
2158 #if 0
2159 GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re-initialize GratefulDeb */
2160 #endif
2161 }
2162
2163 switch( op ) {
2164
2165 case kPEGraphicsMode:
2166 vc_graphics_mode = TRUE;
2167 disableConsoleOutput = TRUE;
2168 vc_acquired = TRUE;
2169 break;
2170
2171 case kPETextMode:
2172 vc_graphics_mode = FALSE;
2173 disableConsoleOutput = FALSE;
2174 vc_acquired = TRUE;
2175 vc_clear_screen();
2176 break;
2177
2178 case kPETextScreen:
2179 vc_progress_set( FALSE );
2180 disableConsoleOutput = FALSE;
2181 if( vc_need_clear) {
2182 vc_need_clear = FALSE;
2183 vc_clear_screen();
2184 }
2185 break;
2186
2187 case kPEEnableScreen:
2188 if( vc_acquired) {
2189 if( vc_graphics_mode)
2190 vc_progress_set( TRUE );
2191 else
2192 vc_clear_screen();
2193 }
2194 break;
2195
2196 case kPEDisableScreen:
2197 vc_progress_set( FALSE );
2198 break;
2199
2200 case kPEAcquireScreen:
2201 vc_need_clear = (FALSE == vc_acquired);
2202 vc_acquired = TRUE;
2203 vc_progress_set( vc_graphics_mode );
2204 disableConsoleOutput = vc_graphics_mode;
2205 if( vc_need_clear && !vc_graphics_mode) {
2206 vc_need_clear = FALSE;
2207 vc_clear_screen();
2208 }
2209 break;
2210
2211 case kPEReleaseScreen:
2212 vc_acquired = FALSE;
2213 vc_progress_set( FALSE );
2214 disableConsoleOutput = TRUE;
2215 #if 0
2216 GratefulDebInit(0); /* Stop grateful debugger */
2217 #endif
2218 break;
2219 }
2220 #if 0
2221 if( boot_vinfo) GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re initialize GratefulDeb */
2222 #endif
2223 }