cirrus_vga.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,128 行 · 第 1/5 页

C
2,128
字号
    cirrus_bitblt_rop_bkwd_notsrc,    cirrus_bitblt_rop_bkwd_notsrc_or_dst,    cirrus_bitblt_rop_bkwd_notsrc_and_notdst,};#define TRANSP_ROP(name) {\    name ## _8,\    name ## _16,\        }#define TRANSP_NOP(func) {\    func,\    func,\        }static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),    TRANSP_NOP(cirrus_bitblt_rop_nop),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),    TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),};static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),    TRANSP_NOP(cirrus_bitblt_rop_nop),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),    TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),};#define ROP2(name) {\    name ## _8,\    name ## _16,\    name ## _24,\    name ## _32,\        }#define ROP_NOP2(func) {\    func,\    func,\    func,\    func,\        }static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {    ROP2(cirrus_patternfill_0),    ROP2(cirrus_patternfill_src_and_dst),    ROP_NOP2(cirrus_bitblt_rop_nop),    ROP2(cirrus_patternfill_src_and_notdst),    ROP2(cirrus_patternfill_notdst),    ROP2(cirrus_patternfill_src),    ROP2(cirrus_patternfill_1),    ROP2(cirrus_patternfill_notsrc_and_dst),    ROP2(cirrus_patternfill_src_xor_dst),    ROP2(cirrus_patternfill_src_or_dst),    ROP2(cirrus_patternfill_notsrc_or_notdst),    ROP2(cirrus_patternfill_src_notxor_dst),    ROP2(cirrus_patternfill_src_or_notdst),    ROP2(cirrus_patternfill_notsrc),    ROP2(cirrus_patternfill_notsrc_or_dst),    ROP2(cirrus_patternfill_notsrc_and_notdst),};static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {    ROP2(cirrus_colorexpand_transp_0),    ROP2(cirrus_colorexpand_transp_src_and_dst),    ROP_NOP2(cirrus_bitblt_rop_nop),    ROP2(cirrus_colorexpand_transp_src_and_notdst),    ROP2(cirrus_colorexpand_transp_notdst),    ROP2(cirrus_colorexpand_transp_src),    ROP2(cirrus_colorexpand_transp_1),    ROP2(cirrus_colorexpand_transp_notsrc_and_dst),    ROP2(cirrus_colorexpand_transp_src_xor_dst),    ROP2(cirrus_colorexpand_transp_src_or_dst),    ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),    ROP2(cirrus_colorexpand_transp_src_notxor_dst),    ROP2(cirrus_colorexpand_transp_src_or_notdst),    ROP2(cirrus_colorexpand_transp_notsrc),    ROP2(cirrus_colorexpand_transp_notsrc_or_dst),    ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),};static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {    ROP2(cirrus_colorexpand_0),    ROP2(cirrus_colorexpand_src_and_dst),    ROP_NOP2(cirrus_bitblt_rop_nop),    ROP2(cirrus_colorexpand_src_and_notdst),    ROP2(cirrus_colorexpand_notdst),    ROP2(cirrus_colorexpand_src),    ROP2(cirrus_colorexpand_1),    ROP2(cirrus_colorexpand_notsrc_and_dst),    ROP2(cirrus_colorexpand_src_xor_dst),    ROP2(cirrus_colorexpand_src_or_dst),    ROP2(cirrus_colorexpand_notsrc_or_notdst),    ROP2(cirrus_colorexpand_src_notxor_dst),    ROP2(cirrus_colorexpand_src_or_notdst),    ROP2(cirrus_colorexpand_notsrc),    ROP2(cirrus_colorexpand_notsrc_or_dst),    ROP2(cirrus_colorexpand_notsrc_and_notdst),};static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {    ROP2(cirrus_colorexpand_pattern_transp_0),    ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),    ROP_NOP2(cirrus_bitblt_rop_nop),    ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),    ROP2(cirrus_colorexpand_pattern_transp_notdst),    ROP2(cirrus_colorexpand_pattern_transp_src),    ROP2(cirrus_colorexpand_pattern_transp_1),    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),    ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),    ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),    ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),    ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),    ROP2(cirrus_colorexpand_pattern_transp_notsrc),    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),};static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {    ROP2(cirrus_colorexpand_pattern_0),    ROP2(cirrus_colorexpand_pattern_src_and_dst),    ROP_NOP2(cirrus_bitblt_rop_nop),    ROP2(cirrus_colorexpand_pattern_src_and_notdst),    ROP2(cirrus_colorexpand_pattern_notdst),    ROP2(cirrus_colorexpand_pattern_src),    ROP2(cirrus_colorexpand_pattern_1),    ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),    ROP2(cirrus_colorexpand_pattern_src_xor_dst),    ROP2(cirrus_colorexpand_pattern_src_or_dst),    ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),    ROP2(cirrus_colorexpand_pattern_src_notxor_dst),    ROP2(cirrus_colorexpand_pattern_src_or_notdst),    ROP2(cirrus_colorexpand_pattern_notsrc),    ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),    ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),};static const cirrus_fill_t cirrus_fill[16][4] = {    ROP2(cirrus_fill_0),    ROP2(cirrus_fill_src_and_dst),    ROP_NOP2(cirrus_bitblt_fill_nop),    ROP2(cirrus_fill_src_and_notdst),    ROP2(cirrus_fill_notdst),    ROP2(cirrus_fill_src),    ROP2(cirrus_fill_1),    ROP2(cirrus_fill_notsrc_and_dst),    ROP2(cirrus_fill_src_xor_dst),    ROP2(cirrus_fill_src_or_dst),    ROP2(cirrus_fill_notsrc_or_notdst),    ROP2(cirrus_fill_src_notxor_dst),    ROP2(cirrus_fill_src_or_notdst),    ROP2(cirrus_fill_notsrc),    ROP2(cirrus_fill_notsrc_or_dst),    ROP2(cirrus_fill_notsrc_and_notdst),};static inline void cirrus_bitblt_fgcol(CirrusVGAState *s){    unsigned int color;    switch (s->cirrus_blt_pixelwidth) {    case 1:        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;        break;    case 2:        color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);        s->cirrus_blt_fgcol = le16_to_cpu(color);        break;    case 3:        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |            (s->gr[0x11] << 8) | (s->gr[0x13] << 16);        break;    default:    case 4:        color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |            (s->gr[0x13] << 16) | (s->gr[0x15] << 24);        s->cirrus_blt_fgcol = le32_to_cpu(color);        break;    }}static inline void cirrus_bitblt_bgcol(CirrusVGAState *s){    unsigned int color;    switch (s->cirrus_blt_pixelwidth) {    case 1:        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;        break;    case 2:        color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8);        s->cirrus_blt_bgcol = le16_to_cpu(color);        break;    case 3:        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |            (s->gr[0x10] << 8) | (s->gr[0x12] << 16);        break;    default:    case 4:        color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8) |            (s->gr[0x12] << 16) | (s->gr[0x14] << 24);        s->cirrus_blt_bgcol = le32_to_cpu(color);        break;    }}static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,				     int off_pitch, int bytesperline,				     int lines){    int y;    int off_cur;    int off_cur_end;    for (y = 0; y < lines; y++) {	off_cur = off_begin;	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;	off_cur &= TARGET_PAGE_MASK;	while (off_cur < off_cur_end) {	    cpu_physical_memory_set_dirty(s->vram_offset +					  (off_cur & s->cirrus_addr_mask));	    off_cur += TARGET_PAGE_SIZE;	}	off_begin += off_pitch;    }}static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,					    const uint8_t * src){    uint8_t *dst;    dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);    if (BLTUNSAFE(s))        return 0;    (*s->cirrus_rop) (s, dst, src,                      s->cirrus_blt_dstpitch, 0,                      s->cirrus_blt_width, s->cirrus_blt_height);    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,                             s->cirrus_blt_height);    return 1;}/* fill */static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop){    cirrus_fill_t rop_func;    if (BLTUNSAFE(s))        return 0;    rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];    rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),             s->cirrus_blt_dstpitch,             s->cirrus_blt_width, s->cirrus_blt_height);    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,			     s->cirrus_blt_dstpitch, s->cirrus_blt_width,			     s->cirrus_blt_height);    cirrus_bitblt_reset(s);    return 1;}/*************************************** * *  bitblt (video-to-video) * ***************************************/static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s){    return cirrus_bitblt_common_patterncopy(s,					    s->vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &                                            s->cirrus_addr_mask));}static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h){    int sx, sy;    int dx, dy;    int width, height;    int depth;    int notify = 0;    depth = s->get_bpp((VGAState *)s) / 8;    s->get_resolution((VGAState *)s, &width, &height);    /* extra x, y */    sx = (src % (width * depth)) / depth;    sy = (src / (width * depth));    dx = (dst % (width *depth)) / depth;    dy = (dst / (width * depth));    /* normalize width */    w /= depth;    /* if we're doing a backward copy, we have to adjust       our x/y to be the upper left corner (instead of the lower       right corner) */    if (s->cirrus_blt_dstpitch < 0) {	sx -= (s->cirrus_blt_width / depth) - 1;	dx -= (s->cirrus_blt_width / depth) - 1;	sy -= s->cirrus_blt_height - 1;	dy -= s->cirrus_blt_height - 1;    }    /* are we in the visible portion of memory? */    if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&	(sx + w) <= width && (sy + h) <= height &&	(dx + w) <= width && (dy + h) <= height) {	notify = 1;    }    /* make to sure only copy if it's a plain copy ROP */    if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src &&	*s->cirrus_rop != cirrus_bitblt_rop_bkwd_src)	notify = 0;    /* we have to flush all pending changes so that the copy       is generated at the appropriate moment in time */    if (notify)	vga_hw_update();    (*s->cirrus_rop) (s, s->vram_ptr +		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),		      s->vram_ptr +		      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,		      s->cirrus_blt_width, s->cirrus_blt_height);    if (notify)	s->ds->dpy_copy(s->ds,			sx, sy, dx, dy,			s->cirrus_blt_width / depth,			s->cirrus_blt_height);    /* we don't have to notify the display that this portion has       changed since dpy_copy implies this */    if (!notify)	cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,				 s->cirrus_blt_dstpitch, s->cirrus_blt_width,				 s->cirrus_blt_height);}static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s){    if (s->ds->dpy_copy) {	cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,		       s->cirrus_blt_srcaddr - s->start_addr,		       s->cirrus_blt_width, s->cirrus_blt_height);    } else {    if (BLTUNSAFE(s))        return 0;	(*s->cirrus_rop) (s, s->vram_ptr +                (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),			  s->vram_ptr +                (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),			  s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,			  s->cirrus_blt_width, s->cirrus_blt_height);	cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,				 s->cirrus_blt_dstpitch, s->cirrus_blt_width,				 s->cirrus_blt_height);    }    return 1;}/*************************************** * *  bitblt (cpu-to-video) * ***************************************/static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s){    int copy_count;    uint8_t *end_ptr;    if (s->cirrus_srccounter > 0) {        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {            cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);        the_end:            s->cirrus_srccounter = 0;            cirrus_bitblt_reset(s);        } else {            /* at least one scan line */            do {                (*s->cirrus_rop)(s, s->vram_ptr +                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);                cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,                                         s->cirrus_blt_width, 1);                s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;                s->cirrus_srccounter -= s->cirrus_blt_srcpitch;                if (s->cirrus_srccounter <= 0)                    goto the_end;                /* more bytes than needed can be transfered because of                   word alignment, so we keep them for the next line */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?