|
|
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.