Annotation of qemu/roms/openbios/packages/video.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *   Creation Date: <2002/10/23 20:26:40 samuel>
        !             3:  *   Time-stamp: <2004/01/07 19:39:15 samuel>
        !             4:  *
        !             5:  *     <video.c>
        !             6:  *
        !             7:  *     Mac-on-Linux display node
        !             8:  *
        !             9:  *   Copyright (C) 2002, 2003, 2004 Samuel Rydh ([email protected])
        !            10:  *
        !            11:  *   This program is free software; you can redistribute it and/or
        !            12:  *   modify it under the terms of the GNU General Public License
        !            13:  *   as published by the Free Software Foundation
        !            14:  *
        !            15:  */
        !            16: 
        !            17: #include "config.h"
        !            18: #include "libopenbios/bindings.h"
        !            19: #include "libc/diskio.h"
        !            20: #include "libopenbios/ofmem.h"
        !            21: #include "drivers/drivers.h"
        !            22: #include "packages/video.h"
        !            23: #include "libopenbios/console.h"
        !            24: #include "drivers/vga.h"
        !            25: 
        !            26: typedef struct osi_fb_info {
        !            27:     unsigned long mphys;
        !            28:     int rb, w, h, depth;
        !            29: } osi_fb_info_t;
        !            30: 
        !            31: static struct {
        !            32:        int             has_video;
        !            33:        osi_fb_info_t   fb;
        !            34:        unsigned long           *pal;           /* 256 elements */
        !            35: } video;
        !            36: 
        !            37: 
        !            38: int
        !            39: video_get_res( int *w, int *h )
        !            40: {
        !            41:        if( !video.has_video ) {
        !            42:                *w = *h = 0;
        !            43:                return -1;
        !            44:        }
        !            45:        *w = video.fb.w;
        !            46:        *h = video.fb.h;
        !            47:        return 0;
        !            48: }
        !            49: 
        !            50: static void
        !            51: startup_splash( void )
        !            52: {
        !            53: #ifdef CONFIG_MOL
        !            54:        int fd, s, i, y, x, dx, dy;
        !            55:        int width, height;
        !            56:        char *pp, *p;
        !            57:        char buf[64];
        !            58: #endif
        !            59: 
        !            60:        /* only draw logo in 24-bit mode (for now) */
        !            61:        if( video.fb.depth < 15 )
        !            62:                return;
        !            63: #ifdef CONFIG_MOL
        !            64:        for( i=0; i<2; i++ ) {
        !            65:                if( !BootHGetStrResInd("bootlogo", buf, sizeof(buf), 0, i) )
        !            66:                        return;
        !            67:                *(!i ? &width : &height) = atol(buf);
        !            68:        }
        !            69: 
        !            70:        if( (s=width * height * 3) > 0x20000 )
        !            71:                return;
        !            72: 
        !            73:        if( (fd=open_io("pseudo:,bootlogo")) >= 0 ) {
        !            74:                p = malloc( s );
        !            75:                if( read_io(fd, p, s) != s )
        !            76:                        printk("bootlogo size error\n");
        !            77:                close_io( fd );
        !            78: 
        !            79:                dx = (video.fb.w - width)/2;
        !            80:                dy = (video.fb.h - height)/3;
        !            81: 
        !            82:                pp = (char*)video.fb.mphys + dy * video.fb.rb + dx * (video.fb.depth >= 24 ? 4 : 2);
        !            83: 
        !            84:                for( y=0 ; y<height; y++, pp += video.fb.rb ) {
        !            85:                        if( video.fb.depth >= 24 ) {
        !            86:                                unsigned long *d = (unsigned long*)pp;
        !            87:                                for( x=0; x<width; x++, p+=3, d++ )
        !            88:                                        *d = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2];
        !            89:                        } else if( video.fb.depth == 15 ) {
        !            90:                                unsigned short *d = (unsigned short*)pp;
        !            91:                                for( x=0; x<width; x++, p+=3, d++ ) {
        !            92:                                        int col = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2];
        !            93:                                        *d = ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f);
        !            94:                                }
        !            95:                        }
        !            96:                }
        !            97:                free( p );
        !            98:        }
        !            99: #else
        !           100:        /* No bootlogo support yet on other platforms */
        !           101:        return;
        !           102: #endif
        !           103: }
        !           104: 
        !           105: static unsigned long
        !           106: get_color( int col_ind )
        !           107: {
        !           108:        unsigned long col;
        !           109:        if( !video.has_video || col_ind < 0 || col_ind > 255 )
        !           110:                return 0;
        !           111:        if( video.fb.depth == 8 )
        !           112:                return col_ind;
        !           113:        col = video.pal[col_ind];
        !           114:        if( video.fb.depth == 24 || video.fb.depth == 32 )
        !           115:                return col;
        !           116:        if( video.fb.depth == 15 )
        !           117:                return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f);
        !           118:        return 0;
        !           119: }
        !           120: 
        !           121: void
        !           122: draw_pixel( int x, int y, int colind )
        !           123: {
        !           124:        char *p = (char*)video.fb.mphys + video.fb.rb * y;
        !           125:        int color, d = video.fb.depth;
        !           126: 
        !           127:        if( x < 0 || y < 0 || x >= video.fb.w || y >=video.fb.h )
        !           128:                return;
        !           129:        color = get_color( colind );
        !           130: 
        !           131:        if( d >= 24 )
        !           132:                *((unsigned long*)p + x) = color;
        !           133:        else if( d >= 15 )
        !           134:                *((short*)p + x) = color;
        !           135:        else
        !           136:                *(p + x) = color;
        !           137: }
        !           138: 
        !           139: static void
        !           140: fill_rect( int col_ind, int x, int y, int w, int h )
        !           141: {
        !           142:        char *pp;
        !           143:        unsigned long col = get_color(col_ind);
        !           144: 
        !           145:         if (!video.has_video || x < 0 || y < 0 || w <= 0 || h <= 0 ||
        !           146:             x + w > video.fb.w || y + h > video.fb.h)
        !           147:                return;
        !           148: 
        !           149:        pp = (char*)video.fb.mphys + video.fb.rb * y;
        !           150:        for( ; h--; pp += video.fb.rb ) {
        !           151:                int ww = w;
        !           152:                if( video.fb.depth == 24 || video.fb.depth == 32 ) {
        !           153:                        unsigned long *p = (unsigned long*)pp + x;
        !           154:                        while( ww-- )
        !           155:                                *p++ = col;
        !           156:                } else if( video.fb.depth == 16 || video.fb.depth == 15 ) {
        !           157:                        unsigned short *p = (unsigned short*)pp + x;
        !           158:                        while( ww-- )
        !           159:                                *p++ = col;
        !           160:                } else {
        !           161:                         char *p = (char *)((unsigned short*)pp + x);
        !           162: 
        !           163:                        while( ww-- )
        !           164:                                *p++ = col;
        !           165:                }
        !           166:        }
        !           167: }
        !           168: 
        !           169: static void
        !           170: refresh_palette( void )
        !           171: {
        !           172: #ifdef CONFIG_MOL
        !           173:        if( video.fb.depth == 8 )
        !           174:                OSI_RefreshPalette();
        !           175: #endif
        !           176: }
        !           177: 
        !           178: void
        !           179: set_color( int ind, unsigned long color )
        !           180: {
        !           181:        if( !video.has_video || ind < 0 || ind > 255 )
        !           182:                return;
        !           183:        video.pal[ind] = color;
        !           184: 
        !           185: #ifdef CONFIG_MOL
        !           186:        if( video.fb.depth == 8 )
        !           187:                OSI_SetColor( ind, color );
        !           188: #elif defined(CONFIG_SPARC32)
        !           189:        if( video.fb.depth == 8 ) {
        !           190:             dac[0] = ind << 24;
        !           191:             dac[1] = ((color >> 16) & 0xff) << 24; // Red
        !           192:             dac[1] = ((color >> 8) & 0xff) << 24; // Green
        !           193:             dac[1] = (color & 0xff) << 24; // Blue
        !           194:         }
        !           195: #else
        !           196:        vga_set_color(ind, ((color >> 16) & 0xff),
        !           197:                           ((color >> 8) & 0xff),
        !           198:                           (color & 0xff));
        !           199: #endif
        !           200: }
        !           201: 
        !           202: void
        !           203: video_scroll( int height )
        !           204: {
        !           205:        int i, offs, size, *dest, *src;
        !           206: 
        !           207:         if (height <= 0 || height >= video.fb.h) {
        !           208:                 return;
        !           209:         }
        !           210:        offs = video.fb.rb * height;
        !           211:        size = (video.fb.h * video.fb.rb - offs)/16;
        !           212:        dest = (int*)video.fb.mphys;
        !           213:        src = (int*)(video.fb.mphys + offs);
        !           214: 
        !           215:        for( i=0; i<size; i++ ) {
        !           216:                dest[0] = src[0];
        !           217:                dest[1] = src[1];
        !           218:                dest[2] = src[2];
        !           219:                dest[3] = src[3];
        !           220:                dest += 4;
        !           221:                src += 4;
        !           222:        }
        !           223: }
        !           224: 
        !           225: /************************************************************************/
        !           226: /*     OF methods                                                      */
        !           227: /************************************************************************/
        !           228: 
        !           229: DECLARE_NODE( video, INSTALL_OPEN, 0, "Tdisplay" );
        !           230: 
        !           231: /* ( -- width height ) (?) */
        !           232: static void
        !           233: video_dimensions( void )
        !           234: {
        !           235:        int w, h;
        !           236:        (void) video_get_res( &w, &h );
        !           237:        PUSH( w );
        !           238:        PUSH( h );
        !           239: }
        !           240: 
        !           241: /* ( table start count -- ) (?) */
        !           242: static void
        !           243: video_set_colors( void )
        !           244: {
        !           245:        int count = POP();
        !           246:        int start = POP();
        !           247:        unsigned char *p = (unsigned char*)cell2pointer(POP());
        !           248:        int i;
        !           249: 
        !           250:        for( i=0; i<count; i++, p+=3 ) {
        !           251:                unsigned long col = (p[0] << 16) | (p[1] << 8) | p[2];
        !           252:                set_color( i + start, col );
        !           253:        }
        !           254:        refresh_palette();
        !           255: }
        !           256: 
        !           257: /* ( r g b index -- ) */
        !           258: static void
        !           259: video_color_bang( void )
        !           260: {
        !           261:        int index = POP();
        !           262:        int b = POP();
        !           263:        int g = POP();
        !           264:        int r = POP();
        !           265:        unsigned long col = ((r << 16) & 0xff0000) | ((g << 8) & 0x00ff00) | (b & 0xff);
        !           266:        /* printk("color!: %08lx %08lx %08lx %08lx\n", r, g, b, index ); */
        !           267:        set_color( index, col );
        !           268:        refresh_palette();
        !           269: }
        !           270: 
        !           271: /* ( color_ind x y width height -- ) (?) */
        !           272: static void
        !           273: video_fill_rect( void )
        !           274: {
        !           275:        int h = POP();
        !           276:        int w = POP();
        !           277:        int y = POP();
        !           278:        int x = POP();
        !           279:        int color_ind = POP();
        !           280: 
        !           281:        fill_rect( color_ind, x, y, w, h );
        !           282: }
        !           283: 
        !           284: /* ( addr len -- actual ) */
        !           285: static void
        !           286: video_write(void)
        !           287: {
        !           288:     char *addr;
        !           289:     int len;
        !           290: 
        !           291:     len = POP();
        !           292:     addr = (char *)cell2pointer(POP());
        !           293: 
        !           294:     console_draw_fstr(addr, len);
        !           295:     PUSH(len);
        !           296: }
        !           297: 
        !           298: NODE_METHODS( video ) = {
        !           299:        {"dimensions",          video_dimensions        },
        !           300:        {"set-colors",          video_set_colors        },
        !           301:        {"fill-rectangle",      video_fill_rect         },
        !           302:        {"color!",              video_color_bang        },
        !           303:        {"write",               video_write             },
        !           304: };
        !           305: 
        !           306: 
        !           307: /************************************************************************/
        !           308: /*     init                                                            */
        !           309: /************************************************************************/
        !           310: 
        !           311: void
        !           312: init_video( unsigned long fb,  int width, int height, int depth, int rb )
        !           313: {
        !           314:         int i;
        !           315: #ifdef CONFIG_PPC
        !           316:         int s, size;
        !           317: #endif
        !           318:        phandle_t ph=0;
        !           319: 
        !           320:        video.fb.mphys = fb;
        !           321:        video.fb.w = width;
        !           322:        video.fb.h = height;
        !           323:        video.fb.depth = depth;
        !           324:        video.fb.rb = rb;
        !           325:        while( (ph=dt_iterate_type(ph, "display")) ) {
        !           326:                set_int_property( ph, "width", video.fb.w );
        !           327:                set_int_property( ph, "height", video.fb.h );
        !           328:                set_int_property( ph, "depth", video.fb.depth );
        !           329:                set_int_property( ph, "linebytes", video.fb.rb );
        !           330:                set_int_property( ph, "address", video.fb.mphys );
        !           331:        }
        !           332:        video.has_video = 1;
        !           333:        video.pal = malloc( 256 * sizeof(unsigned long) );
        !           334: 
        !           335: #ifdef CONFIG_PPC
        !           336:         s = (video.fb.mphys & 0xfff);
        !           337:         size = ((video.fb.h * video.fb.rb + s) + 0xfff) & ~0xfff;
        !           338: 
        !           339:        ofmem_claim_phys( video.fb.mphys, size, 0 );
        !           340:        ofmem_claim_virt( video.fb.mphys, size, 0 );
        !           341:        ofmem_map( video.fb.mphys, video.fb.mphys, size, -1 );
        !           342: #endif
        !           343: 
        !           344:        for( i=0; i<256; i++ )
        !           345:                set_color( i, i * 0x010101 );
        !           346: 
        !           347:        set_color( 254, 0xffffcc );
        !           348:        fill_rect( 254, 0, 0, video.fb.w, video.fb.h );
        !           349: 
        !           350:        refresh_palette();
        !           351:        startup_splash();
        !           352: 
        !           353:        REGISTER_NODE( video );
        !           354: }

unix.superglobalmegacorp.com

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