|
|
1.1 root 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 <types.h>
100: #include "iso_scan_font.h"
101: #include <pexpert/pexpert.h>
102: #include <pexpert/i386/boot.h>
103:
104: #define CHARWIDTH 8
105: #define CHARHEIGHT 16
106:
107: #define ATTR_NONE 0
108: #define ATTR_BOLD 1
109: #define ATTR_UNDER 2
110: #define ATTR_REVERSE 4
111:
112: enum vt100state_e {
113: ESnormal, /* Nothing yet */
114: ESesc, /* Got ESC */
115: ESsquare, /* Got ESC [ */
116: ESgetpars, /* About to get or getting the parameters */
117: ESgotpars, /* Finished getting the parameters */
118: ESfunckey, /* Function key */
119: EShash, /* DEC-specific stuff (screen align, etc.) */
120: ESsetG0, /* Specify the G0 character set */
121: ESsetG1, /* Specify the G1 character set */
122: ESask,
123: EScharsize,
124: ESignore /* Ignore this sequence */
125: } vt100state = ESnormal;
126:
127: static struct {
128: unsigned long v_baseaddr;
129: unsigned long v_height;
130: unsigned long v_width;
131: unsigned long v_depth;
132: unsigned long v_rowbytes; /* True row bytes */
133: unsigned long v_rowscanbytes; /* Scan bytes */
134: unsigned long v_columns;
135: unsigned long v_rows;
136: } vinfo;
137:
138: /* Calculated in vccninit(): */
139: static int vc_wrap_mode = 1, vc_relative_origin = 0;
140: static int vc_charset_select = 0, vc_save_charset_s = 0;
141: static int vc_charset[2] = { 0, 0 };
142: static int vc_charset_save[2] = { 0, 0 };
143:
144: /* VT100 state: */
145: #define MAXPARS 16
146: static int x = 0, y = 0, savex, savey;
147: static int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
148:
149: /* VT100 tab stops & scroll region */
150: static char tab_stops[255];
151: static int scrreg_top, scrreg_bottom;
152:
153: /* Misc */
154: void vc_initialize(void);
155: void vc_flush_forward_buffer(void);
156: void vc_store_char(unsigned char);
157:
158:
159: /*
160: * For the color support (Michel Pollet)
161: */
162: unsigned char vc_color_index_table[33] =
163: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164: 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
165:
166: unsigned long vc_color_depth_masks[4] =
167: { 0x000000FF, 0x00007FFF, 0x00FFFFFF };
168:
169: unsigned long vc_colors[8][3] = {
170: { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
171: { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
172: { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
173: { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
174: { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
175: // { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
176: { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
177: { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
178: { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
179: };
180:
181: unsigned long vc_color_mask = 0;
182: unsigned long vc_color_fore = 0;
183: unsigned long vc_color_back = 0;
184: int vc_normal_background = 1;
185:
186:
187: /*
188: * For the jump scroll and buffering (Michel Pollet)
189: * 80*22 means on a 80*24 screen, the screen will
190: * scroll jump almost a full screen
191: * keeping only what's necessary for you to be able to read ;-)
192: */
193: #define VC_MAX_FORWARD_SIZE (80*22)
194:
195: /*
196: * Delay between console updates in clock hz units, the larger the
197: * delay the fuller the jump-scroll buffer will be and so the faster the
198: * (scrolling) output. The smaller the delay, the less jerky the
199: * display. Heuristics show that at 10 touch-typists (Mike!) complain
200: */
201: #define VC_CONSOLE_UPDATE_TIMEOUT 5
202:
203: static unsigned char vc_forward_buffer[VC_MAX_FORWARD_SIZE];
204: static long vc_forward_buffer_size = 0;
205:
206: /*
207: * New Rendering code from Michel Pollet
208: */
209:
210: /* That function will be called for drawing */
211: static void (*vc_paintchar) (unsigned char c, int x, int y, int attrs);
212:
213: #define REN_MAX_DEPTH 32
214: /* that's the size for a 32 bits buffer... */
215: #define REN_MAX_SIZE (128L*1024)
216: unsigned char renderedFont[REN_MAX_SIZE];
217:
218: /* Rendered Font Size */
219: unsigned long vc_rendered_font_size = REN_MAX_SIZE;
220: long vc_rendered_error = 0;
221:
222: /* If the one bit table was reversed */
223: short vc_one_bit_reversed = 0;
224:
225: /* Size of a character in the table (bytes) */
226: int vc_rendered_char_size = 0;
227:
228: /*
229: # Attribute codes:
230: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
231: # Text color codes:
232: # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
233: # Background color codes:
234: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
235: */
236:
237: #define VC_RESET_BACKGROUND 40
238: #define VC_RESET_FOREGROUND 37
239:
240: static void vc_color_set(int color)
241: {
242: if (vinfo.v_depth < 8)
243: return;
244: if (color >= 30 && color <= 37)
245: vc_color_fore = vc_colors[color-30][vc_color_index_table[vinfo.v_depth]];
246: if (color >= 40 && color <= 47) {
247: vc_color_back = vc_colors[color-40][vc_color_index_table[vinfo.v_depth]];
248: vc_normal_background = color == 40;
249: }
250:
251: }
252:
253: static void vc_render_font(short olddepth, short newdepth)
254: {
255: int charIndex; /* index in ISO font */
256: union {
257: unsigned char *charptr;
258: unsigned short *shortptr;
259: unsigned long *longptr;
260: } current; /* current place in rendered font, multiple types. */
261:
262: unsigned char *theChar; /* current char in iso_font */
263:
264: if (olddepth == newdepth)
265: return; /* nothing to do */
266:
267: vc_rendered_font_size = REN_MAX_SIZE;
268: if (newdepth == 1) {
269: vc_rendered_char_size = 16;
270: if (!vc_one_bit_reversed) { /* reverse the font for the blitter */
271: int i;
272: for (i = 0; i < ((ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size); i++) {
273: if (iso_font[i]) {
274: unsigned char mask1 = 0x80;
275: unsigned char mask2 = 0x01;
276: unsigned char val = 0;
277: while (mask1) {
278: if (iso_font[i] & mask1)
279: val |= mask2;
280: mask1 >>= 1;
281: mask2 <<= 1;
282: }
283: renderedFont[i] = ~val;
284: } else renderedFont[i] = 0xff;
285: }
286: vc_one_bit_reversed = 1;
287: }
288: return;
289: }
290: {
291: long csize = newdepth / 8; /* bytes per pixel */
292: vc_rendered_char_size = csize ? CHARHEIGHT * (csize * CHARWIDTH) :
293: /* for 2 & 4 */ CHARHEIGHT * (CHARWIDTH/(6-newdepth));
294: csize = (ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size;
295: if (csize > vc_rendered_font_size) {
296: vc_rendered_error = csize;
297: return;
298: } else
299: vc_rendered_font_size = csize;
300: }
301:
302: current.charptr = renderedFont;
303: theChar = iso_font;
304: for (charIndex = ISO_CHAR_MIN; charIndex <= ISO_CHAR_MAX; charIndex++) {
305: int line;
306: for (line = 0; line < CHARHEIGHT; line++) {
307: unsigned char mask = 1;
308: do {
309: switch (newdepth) {
310: case 2: {
311: unsigned char value = 0;
312: if (*theChar & mask) value |= 0xC0; mask <<= 1;
313: if (*theChar & mask) value |= 0x30; mask <<= 1;
314: if (*theChar & mask) value |= 0x0C; mask <<= 1;
315: if (*theChar & mask) value |= 0x03;
316: value = ~value;
317: *current.charptr++ = value;
318: }
319: break;
320: case 4:
321: {
322: unsigned char value = 0;
323: if (*theChar & mask) value |= 0xF0; mask <<= 1;
324: if (*theChar & mask) value |= 0x0F;
325: value = ~value;
326: *current.charptr++ = value;
327: }
328: break;
329: case 8:
330: *current.charptr++ = (*theChar & mask) ? 0xff : 0;
331: break;
332: case 16:
333: *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
334: break;
335:
336: case 32:
337: *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
338: break;
339: }
340: mask <<= 1;
341: } while (mask); /* while the single bit drops to the right */
342: theChar++;
343: }
344: }
345: }
346:
347: static void vc_paint_char1(unsigned char ch, int xx, int yy, int attrs)
348: {
349: unsigned char *theChar;
350: unsigned char *where;
351: int i;
352:
353: theChar = (unsigned char*)(renderedFont + (ch * vc_rendered_char_size));
354: where = (unsigned char*)(vinfo.v_baseaddr +
355: (yy * CHARHEIGHT * vinfo.v_rowbytes) +
356: (xx));
357:
358: if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
359: *where = *theChar++;
360:
361: where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
362: } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
363: unsigned char val = *theChar++, save = val;
364: if (attrs & ATTR_BOLD) { /* bold support */
365: unsigned char mask1 = 0xC0, mask2 = 0x40;
366: int bit = 0;
367: for (bit = 0; bit < 7; bit++) {
368: if ((save & mask1) == mask2)
369: val &= ~mask2;
370: mask1 >>= 1;
371: mask2 >>= 1;
372: }
373: }
374: if (attrs & ATTR_REVERSE) val = ~val;
375: if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
376: *where = val;
377:
378: where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
379: }
380:
381: }
382:
383: static void vc_paint_char2(unsigned char ch, int xx, int yy, int attrs)
384: {
385: unsigned short *theChar;
386: unsigned short *where;
387: int i;
388:
389: theChar = (unsigned short*)(renderedFont + (ch * vc_rendered_char_size));
390: where = (unsigned short*)(vinfo.v_baseaddr +
391: (yy * CHARHEIGHT * vinfo.v_rowbytes) +
392: (xx * 2));
393: if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
394: *where = *theChar++;
395:
396: where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
397: } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
398: unsigned short val = *theChar++, save = val;
399: if (attrs & ATTR_BOLD) { /* bold support */
400: unsigned short mask1 = 0xF000, mask2 = 0x3000;
401: int bit = 0;
402: for (bit = 0; bit < 7; bit++) {
403: if ((save & mask1) == mask2)
404: val &= ~mask2;
405: mask1 >>= 2;
406: mask2 >>= 2;
407: }
408: }
409: if (attrs & ATTR_REVERSE) val = ~val;
410: if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
411: *where = val;
412:
413: where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
414: }
415:
416: }
417:
418: static void vc_paint_char4(unsigned char ch, int xx, int yy, int attrs)
419: {
420: unsigned long *theChar;
421: unsigned long *where;
422: int i;
423:
424: theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
425: where = (unsigned long*)(vinfo.v_baseaddr +
426: (yy * CHARHEIGHT * vinfo.v_rowbytes) +
427: (xx * 4));
428:
429: if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attributes ? FLY !!!! */
430: *where = *theChar++;
431:
432: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
433: } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
434: unsigned long val = *theChar++, save = val;
435: if (attrs & ATTR_BOLD) { /* bold support */
436: unsigned long mask1 = 0xff000000, mask2 = 0x0F000000;
437: int bit = 0;
438: for (bit = 0; bit < 7; bit++) {
439: if ((save & mask1) == mask2)
440: val &= ~mask2;
441: mask1 >>= 4;
442: mask2 >>= 4;
443: }
444: }
445: if (attrs & ATTR_REVERSE) val = ~val;
446: if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
447: *where = val;
448:
449: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
450: }
451:
452: }
453:
454: static void vc_paint_char8c(unsigned char ch, int xx, int yy, int attrs)
455: {
456: unsigned long *theChar;
457: unsigned long *where;
458: int i;
459:
460: theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
461: where = (unsigned long*)(vinfo.v_baseaddr +
462: (yy * CHARHEIGHT * vinfo.v_rowbytes) +
463: (xx * CHARWIDTH));
464:
465: if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attr? FLY !*/
466: unsigned long *store = where;
467: int x;
468: for (x = 0; x < 2; x++) {
469: unsigned long val = *theChar++;
470: val = (vc_color_back & ~val) | (vc_color_fore & val);
471: *store++ = val;
472: }
473:
474: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
475: } else for (i = 0; i < CHARHEIGHT; i++) { /* a little slower */
476: unsigned long *store = where, lastpixel = 0;
477: int x;
478: for (x = 0 ; x < 2; x++) {
479: unsigned long val = *theChar++, save = val;
480: if (attrs & ATTR_BOLD) { /* bold support */
481: if (lastpixel && !(save & 0xFF000000))
482: val |= 0xff000000;
483: if ((save & 0xFFFF0000) == 0xFF000000)
484: val |= 0x00FF0000;
485: if ((save & 0x00FFFF00) == 0x00FF0000)
486: val |= 0x0000FF00;
487: if ((save & 0x0000FFFF) == 0x0000FF00)
488: val |= 0x000000FF;
489: }
490: if (attrs & ATTR_REVERSE) val = ~val;
491: if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
492:
493: val = (vc_color_back & ~val) | (vc_color_fore & val);
494: *store++ = val;
495: lastpixel = save & 0xff;
496: }
497:
498: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
499: }
500:
501: }
502: static void vc_paint_char16c(unsigned char ch, int xx, int yy, int attrs)
503: {
504: unsigned long *theChar;
505: unsigned long *where;
506: int i;
507:
508: theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
509: where = (unsigned long*)(vinfo.v_baseaddr +
510: (yy * CHARHEIGHT * vinfo.v_rowbytes) +
511: (xx * CHARWIDTH * 2));
512:
513: if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
514: unsigned long *store = where;
515: int x;
516: for (x = 0; x < 4; x++) {
517: unsigned long val = *theChar++;
518: val = (vc_color_back & ~val) | (vc_color_fore & val);
519: *store++ = val;
520: }
521:
522: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
523: } else for (i = 0; i < CHARHEIGHT; i++) { /* a little bit slower */
524: unsigned long *store = where, lastpixel = 0;
525: int x;
526: for (x = 0 ; x < 4; x++) {
527: unsigned long val = *theChar++, save = val;
528: if (attrs & ATTR_BOLD) { /* bold support */
529: if (save == 0xFFFF0000) val |= 0xFFFF;
530: else if (lastpixel && !(save & 0xFFFF0000))
531: val |= 0xFFFF0000;
532: }
533: if (attrs & ATTR_REVERSE) val = ~val;
534: if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
535:
536: val = (vc_color_back & ~val) | (vc_color_fore & val);
537:
538: *store++ = val;
539: lastpixel = save & 0x7fff;
540: }
541:
542: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
543: }
544:
545: }
546: static void vc_paint_char32c(unsigned char ch, int xx, int yy, int attrs)
547: {
548: unsigned long *theChar;
549: unsigned long *where;
550: int i;
551:
552: theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
553: where = (unsigned long*)(vinfo.v_baseaddr +
554: (yy * CHARHEIGHT * vinfo.v_rowbytes) +
555: (xx * CHARWIDTH * 4));
556:
557: if (!attrs) for (i = 0; i < CHARHEIGHT; i++) { /* No attrs ? FLY ! */
558: unsigned long *store = where;
559: int x;
560: for (x = 0; x < 8; x++) {
561: unsigned long val = *theChar++;
562: val = (vc_color_back & ~val) | (vc_color_fore & val);
563: *store++ = val;
564: }
565:
566: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
567: } else for (i = 0; i < CHARHEIGHT; i++) { /* a little slower */
568: unsigned long *store = where, lastpixel = 0;
569: int x;
570: for (x = 0 ; x < 8; x++) {
571: unsigned long val = *theChar++, save = val;
572: if (attrs & ATTR_BOLD) { /* bold support */
573: if (lastpixel && !save)
574: val = 0xFFFFFFFF;
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;
582: }
583:
584: where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
585: }
586:
587: }
588:
589: /*
590: * That's a plain dumb reverse of the cursor position
591: * It do a binary reverse, so it will not looks good when we have
592: * color support. we'll see that later
593: */
594: static void reversecursor(void)
595: {
596: union {
597: unsigned char *charptr;
598: unsigned short *shortptr;
599: unsigned long *longptr;
600: } where;
601: int line, col;
602:
603: where.longptr = (unsigned long*)(vinfo.v_baseaddr +
604: (y * CHARHEIGHT * vinfo.v_rowbytes) +
605: (x /** CHARWIDTH*/ * vinfo.v_depth));
606: for (line = 0; line < CHARHEIGHT; line++) {
607: switch (vinfo.v_depth) {
608: case 1:
609: *where.charptr = ~*where.charptr;
610: break;
611: case 2:
612: *where.shortptr = ~*where.shortptr;
613: break;
614: case 4:
615: *where.longptr = ~*where.longptr;
616: break;
617: /* that code still exists because since characters on the screen are
618: * of different colors that reverse function may not work if the
619: * cursor is on a character that is in a different color that the
620: * current one. When we have buffering, things will work better. MP
621: */
622: #ifdef 1 /*VC_BINARY_REVERSE*/
623: case 8:
624: where.longptr[0] = ~where.longptr[0];
625: where.longptr[1] = ~where.longptr[1];
626: break;
627: case 16:
628: for (col = 0; col < 4; col++)
629: where.longptr[col] = ~where.longptr[col];
630: break;
631: case 32:
632: for (col = 0; col < 8; col++)
633: where.longptr[col] = ~where.longptr[col];
634: break;
635: #else
636: case 8:
637: for (col = 0; col < 8; col++)
638: where.charptr[col] = where.charptr[col] != (vc_color_fore & vc_color_mask) ?
639: vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
640: break;
641: case 16:
642: for (col = 0; col < 8; col++)
643: where.shortptr[col] = where.shortptr[col] != (vc_color_fore & vc_color_mask) ?
644: vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
645: break;
646: case 32:
647: for (col = 0; col < 8; col++)
648: where.longptr[col] = where.longptr[col] != (vc_color_fore & vc_color_mask) ?
649: vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
650: break;
651: #endif
652: }
653: where.charptr += vinfo.v_rowbytes;
654: }
655: }
656:
657:
658: static void
659: scrollup(int num)
660: {
661: unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
662:
663: linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
664: rowline = vinfo.v_rowbytes / 4;
665: rowscanline = vinfo.v_rowscanbytes / 4;
666:
667: to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
668: from = to + (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
669:
670: i = (scrreg_bottom - scrreg_top) - num;
671:
672: while (i-- > 0) {
673: for (line = 0; line < CHARHEIGHT; line++) {
674: /*
675: * Only copy what is displayed
676: */
677: #if 1
678: bcopy((unsigned int) from, (unsigned int) to,
679: vinfo.v_rowscanbytes);
680: #else
681: video_scroll_up((unsigned int) from,
682: (unsigned int) (from+(vinfo.v_rowscanbytes/4)),
683: (unsigned int) to);
684: #endif
685:
686: from += rowline;
687: to += rowline;
688: }
689: }
690:
691: /* Now set the freed up lines to the background colour */
692:
693:
694: to = ((unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs))
695: + ((scrreg_bottom - scrreg_top - num) * linelongs);
696:
697: for (linelongs = CHARHEIGHT * num; linelongs-- > 0;) {
698: from = to;
699: for (i = 0; i < rowscanline; i++)
700: *to++ = vc_color_back;
701:
702: to = from + rowline;
703: }
704:
705: }
706:
707: static void
708: scrolldown(int num)
709: {
710: unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
711:
712: linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
713: rowline = vinfo.v_rowbytes / 4;
714: rowscanline = vinfo.v_rowscanbytes / 4;
715:
716:
717: to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
718: - (rowline - rowscanline);
719: from = to - (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
720:
721: i = (scrreg_bottom - scrreg_top) - num;
722:
723: while (i-- > 0) {
724: for (line = 0; line < CHARHEIGHT; line++) {
725: /*
726: * Only copy what is displayed
727: */
728: #if 1
729: bcopy(from-(vinfo.v_rowscanbytes/4), to,
730: vinfo.v_rowscanbytes);
731: #else
732:
733: video_scroll_down((unsigned int) from,
734: (unsigned int) (from-(vinfo.v_rowscanbytes/4)),
735: (unsigned int) to);
736: #endif
737:
738: from -= rowline;
739: to -= rowline;
740: }
741: }
742:
743: /* Now set the freed up lines to the background colour */
744:
745: to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_top);
746:
747: for (line = CHARHEIGHT * num; line > 0; line--) {
748: from = to;
749:
750: for (i = 0; i < rowscanline; i++)
751: *(to++) = vc_color_back;
752:
753: to = from + rowline;
754: }
755:
756: }
757:
758:
759: static void
760: clear_line(int which)
761: {
762: int start, end, i;
763:
764: /*
765: * This routine runs extremely slowly. I don't think it's
766: * used all that often, except for To end of line. I'll go
767: * back and speed this up when I speed up the whole vc
768: * module. --LK
769: */
770:
771: switch (which) {
772: case 0: /* To end of line */
773: start = x;
774: end = vinfo.v_columns-1;
775: break;
776: case 1: /* To start of line */
777: start = 0;
778: end = x;
779: break;
780: case 2: /* Whole line */
781: start = 0;
782: end = vinfo.v_columns-1;
783: break;
784: }
785:
786: for (i = start; i <= end; i++) {
787: vc_paintchar(' ', i, y, ATTR_NONE);
788: }
789:
790: }
791:
792: static void
793: clear_screen(int which)
794: {
795: unsigned long *p, *endp, *row;
796: int linelongs, col;
797: int rowline, rowlongs;
798:
799: rowline = vinfo.v_rowscanbytes / 4;
800: rowlongs = vinfo.v_rowbytes / 4;
801:
802: p = (unsigned long*) vinfo.v_baseaddr;;
803: endp = (unsigned long*) vinfo.v_baseaddr;
804:
805: linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
806:
807: switch (which) {
808: case 0: /* To end of screen */
809: clear_line(0);
810: if (y < vinfo.v_rows - 1) {
811: p += (y + 1) * linelongs;
812: endp += rowlongs * vinfo.v_height;
813: }
814: break;
815: case 1: /* To start of screen */
816: clear_line(1);
817: if (y > 1) {
818: endp += (y + 1) * linelongs;
819: }
820: break;
821: case 2: /* Whole screen */
822: endp += rowlongs * vinfo.v_height;
823: break;
824: }
825:
826: for (row = p ; row < endp ; row += rowlongs) {
827: for (col = 0; col < rowline; col++)
828: *(row+col) = vc_color_back;
829: }
830:
831: }
832:
833: static void
834: reset_tabs(void)
835: {
836: int i;
837:
838: for (i = 0; i<= vinfo.v_columns; i++) {
839: tab_stops[i] = ((i % 8) == 0);
840: }
841:
842: }
843:
844: static void
845: vt100_reset(void)
846: {
847: reset_tabs();
848: scrreg_top = 0;
849: scrreg_bottom = vinfo.v_rows;
850: attr = ATTR_NONE;
851: vc_charset[0] = vc_charset[1] = 0;
852: vc_charset_select = 0;
853: vc_wrap_mode = 1;
854: vc_relative_origin = 0;
855: vc_color_set(VC_RESET_BACKGROUND);
856: vc_color_set(VC_RESET_FOREGROUND);
857:
858: }
859:
860: static void
861: putc_normal(unsigned char ch)
862: {
863: switch (ch) {
864: case '\a': /* Beep */
865: {
866: extern int asc_ringbell(); //In IOBSDConsole.cpp
867: int rang;
868:
869: rang = asc_ringbell();
870:
871: if(!rang) {
872: /*
873: * No sound hardware, invert the screen twice instead
874: */
875: unsigned long *ptr;
876: int i, j;
877: /* XOR the screen twice */
878: for (i = 0; i < 2 ; i++) {
879: /* For each row, xor the scanbytes */
880: for (ptr = (unsigned long*)vinfo.v_baseaddr;
881: ptr < (unsigned long*)(vinfo.v_baseaddr +
882: (vinfo.v_height * vinfo.v_rowbytes));
883: ptr += (vinfo.v_rowbytes /
884: sizeof (unsigned long*)))
885: for (j = 0;
886: j < vinfo.v_rowscanbytes /
887: sizeof (unsigned long*);
888: j++)
889: *(ptr+j) =~*(ptr+j);
890: }
891: }
892: }
893: break;
894:
895: case 127: /* Delete */
896: case '\b': /* Backspace */
897: if (hanging_cursor) {
898: hanging_cursor = 0;
899: } else
900: if (x > 0) {
901: x--;
902: }
903: break;
904: case '\t': /* Tab */
905: while (x < vinfo.v_columns && !tab_stops[++x]);
906: if (x >= vinfo.v_columns)
907: x = vinfo.v_columns-1;
908: break;
909: case 0x0b:
910: case 0x0c:
911: case '\n': /* Line feed */
912: if (y >= scrreg_bottom -1 ) {
913: scrollup(1);
914: y = scrreg_bottom - 1;
915: } else {
916: y++;
917: }
918: /*break; Pass thru */
919: case '\r': /* Carriage return */
920: x = 0;
921: hanging_cursor = 0;
922: break;
923: case 0x0e: /* Select G1 charset (Control-N) */
924: vc_charset_select = 1;
925: break;
926: case 0x0f: /* Select G0 charset (Control-O) */
927: vc_charset_select = 0;
928: break;
929: case 0x18 : /* CAN : cancel */
930: case 0x1A : /* like cancel */
931: /* well, i do nothing here, may be later */
932: break;
933: case '\033': /* Escape */
934: vt100state = ESesc;
935: hanging_cursor = 0;
936: break;
937: default:
938: if (ch >= ' ') {
939: if (hanging_cursor) {
940: x = 0;
941: if (y >= scrreg_bottom -1 ) {
942: scrollup(1);
943: y = scrreg_bottom - 1;
944: } else {
945: y++;
946: }
947: hanging_cursor = 0;
948: }
949: vc_paintchar((ch >= 0x60 && ch <= 0x7f) ? ch + vc_charset[vc_charset_select]
950: : ch, x, y, attr);
951: if (x == vinfo.v_columns - 1) {
952: hanging_cursor = vc_wrap_mode;
953: } else {
954: x++;
955: }
956: }
957: break;
958: }
959:
960: }
961:
962: static void
963: putc_esc(unsigned char ch)
964: {
965: vt100state = ESnormal;
966:
967: switch (ch) {
968: case '[':
969: vt100state = ESsquare;
970: break;
971: case 'c': /* Reset terminal */
972: vt100_reset();
973: clear_screen(2);
974: x = y = 0;
975: break;
976: case 'D': /* Line feed */
977: case 'E':
978: if (y >= scrreg_bottom -1) {
979: scrollup(1);
980: y = scrreg_bottom - 1;
981: } else {
982: y++;
983: }
984: if (ch == 'E') x = 0;
985: break;
986: case 'H': /* Set tab stop */
987: tab_stops[x] = 1;
988: break;
989: case 'M': /* Cursor up */
990: if (y <= scrreg_top) {
991: scrolldown(1);
992: y = scrreg_top;
993: } else {
994: y--;
995: }
996: break;
997: case '>':
998: vt100_reset();
999: break;
1000: case '7': /* Save cursor */
1001: savex = x;
1002: savey = y;
1003: saveattr = attr;
1004: vc_save_charset_s = vc_charset_select;
1005: vc_charset_save[0] = vc_charset[0];
1006: vc_charset_save[1] = vc_charset[1];
1007: break;
1008: case '8': /* Restore cursor */
1009: x = savex;
1010: y = savey;
1011: attr = saveattr;
1012: vc_charset_select = vc_save_charset_s;
1013: vc_charset[0] = vc_charset_save[0];
1014: vc_charset[1] = vc_charset_save[1];
1015: break;
1016: case 'Z': /* return terminal ID */
1017: break;
1018: case '#': /* change characters height */
1019: vt100state = EScharsize;
1020: break;
1021: case '(':
1022: vt100state = ESsetG0;
1023: break;
1024: case ')': /* character set sequence */
1025: vt100state = ESsetG1;
1026: break;
1027: case '=':
1028: break;
1029: default:
1030: /* Rest not supported */
1031: break;
1032: }
1033:
1034: }
1035:
1036: static void
1037: putc_askcmd(unsigned char ch)
1038: {
1039: if (ch >= '0' && ch <= '9') {
1040: par[numpars] = (10*par[numpars]) + (ch-'0');
1041: return;
1042: }
1043: vt100state = ESnormal;
1044:
1045: switch (par[0]) {
1046: case 6:
1047: vc_relative_origin = ch == 'h';
1048: break;
1049: case 7: /* wrap around mode h=1, l=0*/
1050: vc_wrap_mode = ch == 'h';
1051: break;
1052: default:
1053: break;
1054: }
1055:
1056: }
1057:
1058: static void
1059: putc_charsizecmd(unsigned char ch)
1060: {
1061: vt100state = ESnormal;
1062:
1063: switch (ch) {
1064: case '3' :
1065: case '4' :
1066: case '5' :
1067: case '6' :
1068: break;
1069: case '8' : /* fill 'E's */
1070: {
1071: int xx, yy;
1072: for (yy = 0; yy < vinfo.v_rows; yy++)
1073: for (xx = 0; xx < vinfo.v_columns; xx++)
1074: vc_paintchar('E', xx, yy, ATTR_NONE);
1075: }
1076: break;
1077: }
1078:
1079: }
1080:
1081: static void
1082: putc_charsetcmd(int charset, unsigned char ch)
1083: {
1084: vt100state = ESnormal;
1085:
1086: switch (ch) {
1087: case 'A' :
1088: case 'B' :
1089: default:
1090: vc_charset[charset] = 0;
1091: break;
1092: case '0' : /* Graphic characters */
1093: case '2' :
1094: vc_charset[charset] = 0x21;
1095: break;
1096: }
1097:
1098: }
1099:
1100: static void
1101: putc_gotpars(unsigned char ch)
1102: {
1103: int i;
1104:
1105: if (ch < ' ') {
1106: /* special case for vttest for handling cursor
1107: movement in escape sequences */
1108: putc_normal(ch);
1109: vt100state = ESgotpars;
1110: return;
1111: }
1112: vt100state = ESnormal;
1113: switch (ch) {
1114: case 'A': /* Up */
1115: y -= par[0] ? par[0] : 1;
1116: if (y < scrreg_top)
1117: y = scrreg_top;
1118: break;
1119: case 'B': /* Down */
1120: y += par[0] ? par[0] : 1;
1121: if (y >= scrreg_bottom)
1122: y = scrreg_bottom - 1;
1123: break;
1124: case 'C': /* Right */
1125: x += par[0] ? par[0] : 1;
1126: if (x >= vinfo.v_columns)
1127: x = vinfo.v_columns-1;
1128: break;
1129: case 'D': /* Left */
1130: x -= par[0] ? par[0] : 1;
1131: if (x < 0)
1132: x = 0;
1133: break;
1134: case 'H': /* Set cursor position */
1135: case 'f':
1136: x = par[1] ? par[1] - 1 : 0;
1137: y = par[0] ? par[0] - 1 : 0;
1138: if (vc_relative_origin)
1139: y += scrreg_top;
1140: hanging_cursor = 0;
1141: break;
1142: case 'X': /* clear p1 characters */
1143: if (numpars) {
1144: int i;
1145: for (i = x; i < x + par[0]; i++)
1146: vc_paintchar(' ', i, y, ATTR_NONE);
1147: }
1148: break;
1149: case 'J': /* Clear part of screen */
1150: clear_screen(par[0]);
1151: break;
1152: case 'K': /* Clear part of line */
1153: clear_line(par[0]);
1154: break;
1155: case 'g': /* tab stops */
1156: switch (par[0]) {
1157: case 1:
1158: case 2: /* reset tab stops */
1159: /* reset_tabs(); */
1160: break;
1161: case 3: /* Clear every tabs */
1162: {
1163: int i;
1164:
1165: for (i = 0; i <= vinfo.v_columns; i++)
1166: tab_stops[i] = 0;
1167: }
1168: break;
1169: case 0:
1170: tab_stops[x] = 0;
1171: break;
1172: }
1173: break;
1174: case 'm': /* Set attribute */
1175: for (i = 0; i < numpars; i++) {
1176: switch (par[i]) {
1177: case 0:
1178: attr = ATTR_NONE;
1179: vc_color_set(VC_RESET_BACKGROUND);
1180: vc_color_set(VC_RESET_FOREGROUND);
1181: break;
1182: case 1:
1183: attr |= ATTR_BOLD;
1184: break;
1185: case 4:
1186: attr |= ATTR_UNDER;
1187: break;
1188: case 7:
1189: attr |= ATTR_REVERSE;
1190: break;
1191: case 22:
1192: attr &= ~ATTR_BOLD;
1193: break;
1194: case 24:
1195: attr &= ~ATTR_UNDER;
1196: break;
1197: case 27:
1198: attr &= ~ATTR_REVERSE;
1199: break;
1200: case 5:
1201: case 25: /* blink/no blink */
1202: break;
1203: default:
1204: vc_color_set(par[i]);
1205: break;
1206: }
1207: }
1208: break;
1209: case 'r': /* Set scroll region */
1210: x = y = 0;
1211: /* ensure top < bottom, and both within limits */
1212: if ((numpars > 0) && (par[0] < vinfo.v_rows)) {
1213: scrreg_top = par[0] ? par[0] - 1 : 0;
1214: if (scrreg_top < 0)
1215: scrreg_top = 0;
1216: } else {
1217: scrreg_top = 0;
1218: }
1219: if ((numpars > 1) && (par[1] <= vinfo.v_rows) && (par[1] > par[0])) {
1220: scrreg_bottom = par[1];
1221: if (scrreg_bottom > vinfo.v_rows)
1222: scrreg_bottom = vinfo.v_rows;
1223: } else {
1224: scrreg_bottom = vinfo.v_rows;
1225: }
1226: if (vc_relative_origin)
1227: y = scrreg_top;
1228: break;
1229: }
1230:
1231: }
1232:
1233: static void
1234: putc_getpars(unsigned char ch)
1235: {
1236: if (ch == '?') {
1237: vt100state = ESask;
1238: return;
1239: }
1240: if (ch == '[') {
1241: vt100state = ESnormal;
1242: /* Not supported */
1243: return;
1244: }
1245: if (ch == ';' && numpars < MAXPARS - 1) {
1246: numpars++;
1247: } else
1248: if (ch >= '0' && ch <= '9') {
1249: par[numpars] *= 10;
1250: par[numpars] += ch - '0';
1251: } else {
1252: numpars++;
1253: vt100state = ESgotpars;
1254: putc_gotpars(ch);
1255: }
1256: }
1257:
1258: static void
1259: putc_square(unsigned char ch)
1260: {
1261: int i;
1262:
1263: for (i = 0; i < MAXPARS; i++) {
1264: par[i] = 0;
1265: }
1266:
1267: numpars = 0;
1268: vt100state = ESgetpars;
1269:
1270: putc_getpars(ch);
1271:
1272: }
1273:
1274: void
1275: cnputc(char ch)
1276: {
1277: if (!ch) {
1278: return; /* ignore null characters */
1279: }
1280: switch (vt100state) {
1281: default:vt100state = ESnormal; /* FALLTHROUGH */
1282: case ESnormal:
1283: putc_normal(ch);
1284: break;
1285: case ESesc:
1286: putc_esc(ch);
1287: break;
1288: case ESsquare:
1289: putc_square(ch);
1290: break;
1291: case ESgetpars:
1292: putc_getpars(ch);
1293: break;
1294: case ESgotpars:
1295: putc_gotpars(ch);
1296: break;
1297: case ESask:
1298: putc_askcmd(ch);
1299: break;
1300: case EScharsize:
1301: putc_charsizecmd(ch);
1302: break;
1303: case ESsetG0:
1304: putc_charsetcmd(0, ch);
1305: break;
1306: case ESsetG1:
1307: putc_charsetcmd(1, ch);
1308: break;
1309: }
1310:
1311: if (x >= vinfo.v_columns) {
1312: x = vinfo.v_columns - 1;
1313: }
1314: if (x < 0) {
1315: x = 0;
1316: }
1317: if (y >= vinfo.v_rows) {
1318: y = vinfo.v_rows - 1;
1319: }
1320: if (y < 0) {
1321: y = 0;
1322: }
1323:
1324: }
1325:
1326: /*
1327: * Actually draws the buffer, handle the jump scroll
1328: */
1329: void vc_flush_forward_buffer(void)
1330: {
1331: if (vc_forward_buffer_size) {
1332: int start = 0;
1333: reversecursor();
1334: do {
1335: int i;
1336: int plaintext = 1;
1337: int drawlen = start;
1338: int jump = 0;
1339: int param = 0, changebackground = 0;
1340: enum vt100state_e vtState = vt100state;
1341: /*
1342: * In simple words, here we're pre-parsing the text to look for
1343: * + Newlines, for computing jump scroll
1344: * + /\033\[[0-9;]*]m/ to continue on
1345: * any other sequence will stop. We don't want to have cursor
1346: * movement escape sequences while we're trying to pre-scroll
1347: * the screen.
1348: * We have to be extra carefull about the sequences that changes
1349: * the background color to prevent scrolling in those
1350: * particular cases.
1351: * That parsing was added to speed up 'man' and 'color-ls' a
1352: * zillion time (at least). It's worth it, trust me.
1353: * (mail Nick Stephen for a True Performance Graph)
1354: * Michel Pollet
1355: */
1356: for (i = start; i < vc_forward_buffer_size && plaintext; i++) {
1357: drawlen++;
1358: switch (vtState) {
1359: case ESnormal:
1360: switch (vc_forward_buffer[i]) {
1361: case '\033':
1362: vtState = ESesc;
1363: break;
1364: case '\n':
1365: jump++;
1366: break;
1367: }
1368: break;
1369: case ESesc:
1370: switch (vc_forward_buffer[i]) {
1371: case '[':
1372: vtState = ESgetpars;
1373: param = 0;
1374: changebackground = 0;
1375: break;
1376: default:
1377: plaintext = 0;
1378: break;
1379: }
1380: break;
1381: case ESgetpars:
1382: if ((vc_forward_buffer[i] >= '0' &&
1383: vc_forward_buffer[i] <= '9') ||
1384: vc_forward_buffer[i] == ';') {
1385: if (vc_forward_buffer[i] >= '0' &&
1386: vc_forward_buffer[i] <= '9')
1387: param = (param*10)+(vc_forward_buffer[i]-'0');
1388: else {
1389: if (param >= 40 && param <= 47)
1390: changebackground = 1;
1391: if (!vc_normal_background &&
1392: !param)
1393: changebackground = 1;
1394: param = 0;
1395: }
1396: break; /* continue on */
1397: }
1398: vtState = ESgotpars;
1399: /* fall */
1400: case ESgotpars:
1401: switch (vc_forward_buffer[i]) {
1402: case 'm':
1403: vtState = ESnormal;
1404: if (param >= 40 && param <= 47)
1405: changebackground = 1;
1406: if (!vc_normal_background &&
1407: !param)
1408: changebackground = 1;
1409: if (changebackground) {
1410: plaintext = 0;
1411: jump = 0;
1412: /* REALLY don't jump */
1413: }
1414: /* Yup ! we've got it */
1415: break;
1416: default:
1417: plaintext = 0;
1418: break;
1419: }
1420: break;
1421: default:
1422: plaintext = 0;
1423: break;
1424: }
1425:
1426: }
1427:
1428: /*
1429: * Then we look if it would be appropriate to forward jump
1430: * the screen before drawing
1431: */
1432: if (jump && (scrreg_bottom - scrreg_top) > 2) {
1433: jump -= scrreg_bottom - y - 1;
1434: if (jump > 0 ) {
1435: if (jump >= scrreg_bottom - scrreg_top)
1436: jump = scrreg_bottom - scrreg_top -1;
1437: y -= jump;
1438: scrollup(jump);
1439: }
1440: }
1441: /*
1442: * and we draw what we've found to the parser
1443: */
1444: for (i = start; i < drawlen; i++)
1445: cnputc(vc_forward_buffer[start++]);
1446: /*
1447: * Continue sending characters to the parser until we're sure we're
1448: * back on normal characters.
1449: */
1450: for (i = start; i < vc_forward_buffer_size &&
1451: vt100state != ESnormal ; i++)
1452: cnputc(vc_forward_buffer[start++]);
1453: /* Then loop again if there still things to draw */
1454: } while (start < vc_forward_buffer_size);
1455: vc_forward_buffer_size = 0;
1456: reversecursor();
1457: }
1458: }
1459:
1460:
1461: /*
1462: * Immediate character display.. kernel printf uses this. Make sure
1463: * pre-clock printfs get flushed and that panics get fully displayed.
1464: */
1465:
1466: int
1467: vcputc(int l, int u, int c)
1468: {
1469: vc_store_char(c);
1470: vc_flush_forward_buffer();
1471:
1472: return 0;
1473: }
1474:
1475: /*
1476: * Store characters to be drawn 'later', handle overflows
1477: */
1478:
1479: void
1480: vc_store_char(unsigned char c)
1481: {
1482:
1483: /* Either we're really buffering stuff or we're not yet because
1484: * the probe hasn't been done. If we're not, then we can only
1485: * ever have a maximum of one character in the buffer waiting to
1486: * be flushed
1487: */
1488:
1489: vc_forward_buffer[vc_forward_buffer_size++] = (unsigned char)c;
1490:
1491: switch (vc_forward_buffer_size) {
1492: case 1:
1493: /* If we're adding the first character to the buffer,
1494: * start the timer, otherwise it is already running.
1495: */
1496: break;
1497: case VC_MAX_FORWARD_SIZE:
1498: vc_flush_forward_buffer();
1499: break;
1500: default:
1501: /*
1502: * the character will be flushed on timeout
1503: */
1504: break;
1505: }
1506: }
1507:
1508: void
1509: vc_initialize(void)
1510: {
1511: vinfo.v_rows = vinfo.v_height / CHARHEIGHT;
1512: vinfo.v_columns = vinfo.v_width / CHARWIDTH;
1513:
1514: if (vinfo.v_depth >= 8) {
1515: vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
1516: } else {
1517: vinfo.v_rowscanbytes = vinfo.v_width / (8 / vinfo.v_depth);
1518: }
1519:
1520:
1521: vc_render_font(1, vinfo.v_depth);
1522: vc_color_mask = vc_color_depth_masks[vc_color_index_table[vinfo.v_depth]];
1523: vt100_reset();
1524: switch (vinfo.v_depth) {
1525: default:
1526: case 1:
1527: vc_paintchar = vc_paint_char1;
1528: break;
1529: case 2:
1530: vc_paintchar = vc_paint_char2;
1531: break;
1532: case 4:
1533: vc_paintchar = vc_paint_char4;
1534: break;
1535: case 8:
1536: vc_paintchar = vc_paint_char8c;
1537: break;
1538: case 16:
1539: vc_paintchar = vc_paint_char16c;
1540: break;
1541: case 32:
1542: vc_paintchar = vc_paint_char32c;
1543: break;
1544: }
1545: }
1546:
1547: #if 0
1548: struct vc_progress_element {
1549: unsigned int version;
1550: unsigned int flags;
1551: unsigned int time;
1552: unsigned char count;
1553: unsigned char res[3];
1554: int width;
1555: int height;
1556: int dx;
1557: int dy;
1558: int transparent;
1559: unsigned int res2[3];
1560: unsigned char data[0];
1561: };
1562: typedef struct vc_progress_element vc_progress_element;
1563:
1564: static vc_progress_element * vc_progress;
1565: static unsigned char * vc_progress_data;
1566: static boolean_t vc_progress_enable;
1567: static unsigned char * vc_clut;
1568: static unsigned int vc_progress_tick;
1569: static boolean_t vc_graphics_mode;
1570: static boolean_t vc_acquired;
1571: static boolean_t vc_need_clear;
1572:
1573: void vc_blit_rect_8c( int x, int y,
1574: int width, int height,
1575: int transparent, unsigned char * dataPtr )
1576: {
1577: volatile unsigned char * dst;
1578: int line, col;
1579: unsigned char data;
1580:
1581: dst = (unsigned char *)(vinfo.v_baseaddr +
1582: (y * vinfo.v_rowbytes) +
1583: (x));
1584:
1585: for( line = 0; line < height; line++) {
1586: for( col = 0; col < width; col++) {
1587: data = *dataPtr++;
1588: if( data == transparent)
1589: continue;
1590:
1591: *(dst + col) = data;
1592: }
1593: dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1594: }
1595:
1596: }
1597:
1598: void vc_blit_rect_8m( int x, int y,
1599: int width, int height,
1600: int transparent, unsigned char * dataPtr )
1601: {
1602: volatile unsigned char * dst;
1603: int line, col;
1604: unsigned int data;
1605:
1606: dst = (unsigned char *)(vinfo.v_baseaddr +
1607: (y * vinfo.v_rowbytes) +
1608: (x));
1609:
1610: for( line = 0; line < height; line++) {
1611: for( col = 0; col < width; col++) {
1612: data = *dataPtr++;
1613: if( data == transparent)
1614: continue;
1615:
1616: data *= 3;
1617: *(dst + col) = ((19595 * vc_clut[data + 0] +
1618: 38470 * vc_clut[data + 1] +
1619: 7471 * vc_clut[data + 2] ) / 65536);
1620: }
1621: dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
1622: }
1623: }
1624:
1625:
1626:
1627: void vc_blit_rect_16( int x, int y,
1628: int width, int height,
1629: int transparent, unsigned char * dataPtr )
1630: {
1631: volatile unsigned short * dst;
1632: int line, col;
1633: unsigned int data;
1634:
1635: dst = (volatile unsigned short *)(vinfo.v_baseaddr +
1636: (y * vinfo.v_rowbytes) +
1637: (x * 2));
1638:
1639: for( line = 0; line < height; line++) {
1640: for( col = 0; col < width; col++) {
1641: data = *dataPtr++;
1642: if( data == transparent)
1643: continue;
1644:
1645: data *= 3;
1646: *(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
1647: | ( (0xf8 & (vc_clut[data + 1])) << 2)
1648: | ( (0xf8 & (vc_clut[data + 2])) >> 3);
1649: }
1650: dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
1651: }
1652: }
1653:
1654: void vc_blit_rect_32( unsigned int x, unsigned int y,
1655: unsigned int width, unsigned int height,
1656: int transparent, unsigned char * dataPtr )
1657: {
1658: volatile unsigned int * dst;
1659: int line, col;
1660: unsigned int data;
1661:
1662: dst = (volatile unsigned int *) (vinfo.v_baseaddr +
1663: (y * vinfo.v_rowbytes) +
1664: (x * 4));
1665:
1666: for( line = 0; line < height; line++) {
1667: for( col = 0; col < width; col++) {
1668: data = *dataPtr++;
1669: if( data == transparent)
1670: continue;
1671:
1672: data *= 3;
1673: *(dst + col) = (vc_clut[data + 0] << 16)
1674: | (vc_clut[data + 1] << 8)
1675: | (vc_clut[data + 2]);
1676: }
1677: dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
1678: }
1679: }
1680:
1681: void vc_blit_rect( int x, int y,
1682: int width, int height,
1683: int transparent, unsigned char * dataPtr )
1684: {
1685: switch( vinfo.v_depth) {
1686: case 8:
1687: vc_blit_rect_8c( x, y, width, height, transparent, dataPtr);
1688: break;
1689: case 16:
1690: vc_blit_rect_16( x, y, width, height, transparent, dataPtr);
1691: break;
1692: case 32:
1693: vc_blit_rect_32( x, y, width, height, transparent, dataPtr);
1694: break;
1695: }
1696: }
1697:
1698: void vc_progress_task( void * arg )
1699: {
1700: int count = (int) arg;
1701: int x, y, width, height;
1702: unsigned char * data;
1703:
1704: s = SPL_CONSOLE();
1705: simple_lock(&vc_forward_lock);
1706:
1707: if( vc_progress_enable) {
1708: count++;
1709: if( count >= vc_progress->count)
1710: count = 0;
1711:
1712: width = vc_progress->width;
1713: height = vc_progress->height;
1714: x = vc_progress->dx;
1715: y = vc_progress->dy;
1716: data = vc_progress_data;
1717: data += count * width * height;
1718: if( 1 & vc_progress->flags) {
1719: x += (vinfo.v_width / 2);
1720: x += (vinfo.v_height / 2);
1721: }
1722: vc_blit_rect( x, y, width, height,
1723: vc_progress->transparent,data );
1724:
1725: timeout( vc_progress_task, (void *) count,
1726: vc_progress_tick );
1727: }
1728: simple_unlock(&vc_forward_lock);
1729: splx(s);
1730: }
1731:
1732: void vc_display_icon( vc_progress_element * desc,
1733: unsigned char * data )
1734: {
1735: int x, y, width, height;
1736:
1737: if( vc_acquired && vc_graphics_mode && vc_clut) {
1738:
1739: width = desc->width;
1740: height = desc->height;
1741: x = desc->dx;
1742: y = desc->dy;
1743: if( 1 & desc->flags) {
1744: x += (vinfo.v_width / 2);
1745: y += (vinfo.v_height / 2);
1746: }
1747: vc_blit_rect( x, y, width, height, desc->transparent, data );
1748: }
1749: }
1750:
1751: boolean_t
1752: vc_progress_set( boolean_t enable )
1753: {
1754: spl_t s;
1755:
1756: if( !vc_progress)
1757: return( FALSE );
1758:
1759: s = SPL_CONSOLE();
1760: simple_lock(&vc_forward_lock);
1761:
1762: if( vc_progress_enable != enable) {
1763: vc_progress_enable = enable;
1764: if( enable)
1765: timeout(vc_progress_task, (void *) 0,
1766: vc_progress_tick );
1767: else
1768: untimeout( vc_progress_task, (void *) 0 );
1769: }
1770:
1771: simple_unlock(&vc_forward_lock);
1772: splx(s);
1773:
1774: return( TRUE );
1775: }
1776:
1777:
1778: boolean_t
1779: vc_progress_initialize( vc_progress_element * desc,
1780: unsigned char * data,
1781: unsigned char * clut )
1782: {
1783: if( (!clut) || (!desc) || (!data))
1784: return( FALSE );
1785: vc_clut = clut;
1786:
1787: vc_progress = desc;
1788: vc_progress_data = data;
1789: vc_progress_tick = vc_progress->time * hz / 1000;
1790:
1791: return( TRUE );
1792: }
1793:
1794:
1795: // FirmwareC.c needs:
1796: Boot_Video boot_video_info;
1797:
1798: extern int disableConsoleOutput;
1799:
1800:
1801: void
1802: initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
1803: {
1804: if( boot_vinfo) {
1805: vinfo.v_width = boot_vinfo->v_width;
1806: vinfo.v_height = boot_vinfo->v_height;
1807: vinfo.v_depth = boot_vinfo->v_depth;
1808: vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
1809: vinfo.v_baseaddr = vinfo.v_physaddr;
1810:
1811: vc_initialize();
1812: }
1813:
1814: switch( op ) {
1815:
1816: case kPEGraphicsMode:
1817: vc_graphics_mode = TRUE;
1818: disableConsoleOutput = TRUE;
1819: vc_acquired = TRUE;
1820: break;
1821:
1822: case kPETextMode:
1823: vc_graphics_mode = FALSE;
1824: disableConsoleOutput = FALSE;
1825: vc_acquired = TRUE;
1826: vc_clear_screen();
1827: break;
1828:
1829: case kPETextScreen:
1830: vc_progress_set( FALSE );
1831: disableConsoleOutput = FALSE;
1832: if( vc_need_clear) {
1833: vc_need_clear = FALSE;
1834: vc_clear_screen();
1835: }
1836: break;
1837:
1838: case kPEEnableScreen:
1839: if( vc_acquired) {
1840: if( vc_graphics_mode)
1841: vc_progress_set( TRUE );
1842: else
1843: vc_clear_screen();
1844: }
1845: break;
1846:
1847: case kPEDisableScreen:
1848: vc_progress_set( FALSE );
1849: break;
1850:
1851: case kPEAcquireScreen:
1852: vc_need_clear = (FALSE == vc_acquired);
1853: vc_acquired = TRUE;
1854: vc_progress_set( vc_graphics_mode );
1855: disableConsoleOutput = vc_graphics_mode;
1856: if( vc_need_clear && !vc_graphics_mode) {
1857: vc_need_clear = FALSE;
1858: vc_clear_screen();
1859: }
1860: break;
1861:
1862: case kPEReleaseScreen:
1863: vc_acquired = FALSE;
1864: vc_progress_set( FALSE );
1865: disableConsoleOutput = TRUE;
1866: break;
1867: }
1868: }
1869: #endif
1870:
1871: void vc_clear_screen( void )
1872: {
1873: reversecursor();
1874: vt100_reset();
1875: x = y = 0;
1876: clear_screen(2);
1877: reversecursor();
1878: };
1879:
1880: void
1881: initialize_screen(PE_Video *boot_vinfo, unsigned long addr)
1882: {
1883: vinfo.v_width = boot_vinfo->v_width;
1884: vinfo.v_height = boot_vinfo->v_height;
1885: vinfo.v_depth = boot_vinfo->v_depth;
1886: vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
1887: vinfo.v_baseaddr = addr;
1888:
1889: vc_initialize();
1890: vc_clear_screen();
1891: }
1892:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.