diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/openbios/libopenbios/video_common.c | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/openbios/libopenbios/video_common.c')
-rw-r--r-- | qemu/roms/openbios/libopenbios/video_common.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/qemu/roms/openbios/libopenbios/video_common.c b/qemu/roms/openbios/libopenbios/video_common.c new file mode 100644 index 000000000..9bbc18c3c --- /dev/null +++ b/qemu/roms/openbios/libopenbios/video_common.c @@ -0,0 +1,258 @@ +/* + * Creation Date: <2002/10/23 20:26:40 samuel> + * Time-stamp: <2004/01/07 19:39:15 samuel> + * + * <video_common.c> + * + * Shared video routines + * + * Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation + * + */ + +#include "config.h" +#include "libc/vsprintf.h" +#include "libopenbios/bindings.h" +#include "libopenbios/fontdata.h" +#include "libopenbios/ofmem.h" +#include "libopenbios/video.h" +#include "packages/video.h" +#include "drivers/vga.h" +#define NO_QEMU_PROTOS +#include "arch/common/fw_cfg.h" + +struct video_info video; + +unsigned long +video_get_color( int col_ind ) +{ + unsigned long col; + if( !VIDEO_DICT_VALUE(video.ih) || col_ind < 0 || col_ind > 255 ) + return 0; + if( VIDEO_DICT_VALUE(video.depth) == 8 ) + return col_ind; + col = video.pal[col_ind]; + if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) + return col; + if( VIDEO_DICT_VALUE(video.depth) == 15 ) + return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f); + return 0; +} + +/* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */ + +void +video_mask_blit(void) +{ + ucell bgcolor = POP(); + ucell fgcolor = POP(); + ucell height = POP(); + ucell width = POP(); + unsigned char *mask = (unsigned char *)POP(); + unsigned char *fbaddr = (unsigned char *)POP(); + + ucell color; + unsigned char *dst, *rowdst; + int x, y, m, b, d, depthbytes; + + fgcolor = video_get_color(fgcolor); + bgcolor = video_get_color(bgcolor); + d = VIDEO_DICT_VALUE(video.depth); + depthbytes = (d + 1) >> 3; + + dst = fbaddr; + for( y = 0; y < height; y++) { + rowdst = dst; + for( x = 0; x < (width + 1) >> 3; x++ ) { + for (b = 0; b < 8; b++) { + m = (1 << (7 - b)); + + if (*mask & m) { + color = fgcolor; + } else { + color = bgcolor; + } + + if( d >= 24 ) + *((uint32_t*)dst) = color; + else if( d >= 15 ) + *((uint16_t*)dst) = color; + else + *dst = color; + + dst += depthbytes; + } + mask++; + } + dst = rowdst; + dst += VIDEO_DICT_VALUE(video.rb); + } +} + +/* ( x y w h fgcolor bgcolor -- ) */ + +void +video_invert_rect( void ) +{ + ucell bgcolor = POP(); + ucell fgcolor = POP(); + int h = POP(); + int w = POP(); + int y = POP(); + int x = POP(); + char *pp; + + bgcolor = video_get_color(bgcolor); + fgcolor = video_get_color(fgcolor); + + if (!VIDEO_DICT_VALUE(video.ih) || x < 0 || y < 0 || w <= 0 || h <= 0 || + x + w > VIDEO_DICT_VALUE(video.w) || y + h > VIDEO_DICT_VALUE(video.h)) + return; + + pp = (char*)VIDEO_DICT_VALUE(video.mvirt) + VIDEO_DICT_VALUE(video.rb) * y; + for( ; h--; pp += *(video.rb) ) { + int ww = w; + if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) { + uint32_t *p = (uint32_t*)pp + x; + while( ww-- ) { + if (*p == fgcolor) { + *p++ = bgcolor; + } else if (*p == bgcolor) { + *p++ = fgcolor; + } + } + } else if( VIDEO_DICT_VALUE(video.depth) == 16 || VIDEO_DICT_VALUE(video.depth) == 15 ) { + uint16_t *p = (uint16_t*)pp + x; + while( ww-- ) { + if (*p == (uint16_t)fgcolor) { + *p++ = bgcolor; + } else if (*p == (uint16_t)bgcolor) { + *p++ = fgcolor; + } + } + } else { + char *p = (char *)(pp + x); + + while( ww-- ) { + if (*p == (char)fgcolor) { + *p++ = bgcolor; + } else if (*p == (char)bgcolor) { + *p++ = fgcolor; + } + } + } + } +} + +/* ( color_ind x y width height -- ) (?) */ +void +video_fill_rect(void) +{ + int h = POP(); + int w = POP(); + int y = POP(); + int x = POP(); + int col_ind = POP(); + + char *pp; + unsigned long col = video_get_color(col_ind); + + if (!VIDEO_DICT_VALUE(video.ih) || x < 0 || y < 0 || w <= 0 || h <= 0 || + x + w > VIDEO_DICT_VALUE(video.w) || y + h > VIDEO_DICT_VALUE(video.h)) + return; + + pp = (char*)VIDEO_DICT_VALUE(video.mvirt) + VIDEO_DICT_VALUE(video.rb) * y; + for( ; h--; pp += VIDEO_DICT_VALUE(video.rb) ) { + int ww = w; + if( VIDEO_DICT_VALUE(video.depth) == 24 || VIDEO_DICT_VALUE(video.depth) == 32 ) { + uint32_t *p = (uint32_t*)pp + x; + while( ww-- ) + *p++ = col; + } else if( VIDEO_DICT_VALUE(video.depth) == 16 || VIDEO_DICT_VALUE(video.depth) == 15 ) { + uint16_t *p = (uint16_t*)pp + x; + while( ww-- ) + *p++ = col; + } else { + char *p = (char *)(pp + x); + + while( ww-- ) + *p++ = col; + } + } +} + +void setup_video() +{ + /* Make everything inside the video_info structure point to the + values in the Forth dictionary. Hence everything is always in + sync. */ + phandle_t options; + char buf[6]; + + feval("['] display-ih cell+"); + video.ih = cell2pointer(POP()); + + feval("['] frame-buffer-adr cell+"); + video.mvirt = cell2pointer(POP()); + feval("['] openbios-video-width cell+"); + video.w = cell2pointer(POP()); + feval("['] openbios-video-height cell+"); + video.h = cell2pointer(POP()); + feval("['] depth-bits cell+"); + video.depth = cell2pointer(POP()); + feval("['] line-bytes cell+"); + video.rb = cell2pointer(POP()); + feval("['] color-palette cell+"); + video.pal = cell2pointer(POP()); + + /* Set global variables ready for fb8-install */ + PUSH( pointer2cell(video_mask_blit) ); + fword("is-noname-cfunc"); + feval("to fb8-blitmask"); + PUSH( pointer2cell(video_fill_rect) ); + fword("is-noname-cfunc"); + feval("to fb8-fillrect"); + PUSH( pointer2cell(video_invert_rect) ); + fword("is-noname-cfunc"); + feval("to fb8-invertrect"); + + /* Static information */ + PUSH((ucell)fontdata); + feval("to (romfont)"); + PUSH(FONT_HEIGHT); + feval("to (romfont-height)"); + PUSH(FONT_WIDTH); + feval("to (romfont-width)"); + + /* Initialise the structure */ + VIDEO_DICT_VALUE(video.w) = VGA_DEFAULT_WIDTH; + VIDEO_DICT_VALUE(video.h) = VGA_DEFAULT_HEIGHT; + VIDEO_DICT_VALUE(video.depth) = VGA_DEFAULT_DEPTH; + VIDEO_DICT_VALUE(video.rb) = VGA_DEFAULT_LINEBYTES; + +#if defined(CONFIG_QEMU) && (defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)) + /* If running from QEMU, grab the parameters from the firmware interface */ + int w, h, d; + + w = fw_cfg_read_i16(FW_CFG_ARCH_WIDTH); + h = fw_cfg_read_i16(FW_CFG_ARCH_HEIGHT); + d = fw_cfg_read_i16(FW_CFG_ARCH_DEPTH); + if (w && h && d) { + VIDEO_DICT_VALUE(video.w) = w; + VIDEO_DICT_VALUE(video.h) = h; + VIDEO_DICT_VALUE(video.depth) = d; + VIDEO_DICT_VALUE(video.rb) = (w * ((d + 7) / 8)); + } +#endif + + /* Setup screen-#rows/screen-#columns */ + options = find_dev("/options"); + snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.w) / FONT_WIDTH); + set_property(options, "screen-#columns", buf, strlen(buf) + 1); + snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.h) / FONT_HEIGHT); + set_property(options, "screen-#rows", buf, strlen(buf) + 1); +} |