Annotation of XNU/osfmk/ppc/POWERMAC/video_console.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.