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

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

unix.superglobalmegacorp.com

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