⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cirrus_vga.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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;	off_cur &= TARGET_PAGE_MASK;	while (off_cur < off_cur_end) {	    cpu_physical_memory_set_dirty(s->vram_offset + off_cur);	    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_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;    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_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));}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->vram_ptr + s->cirrus_blt_srcaddr,		      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 {	(*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,			  s->vram_ptr + s->cirrus_blt_srcaddr,			  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_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 */                /* XXX: keep alignment to speed up transfer */                end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;                copy_count = s->cirrus_srcptr_end - end_ptr;                memmove(s->cirrus_bltbuf, end_ptr, copy_count);                s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;                s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;            } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);        }    }}/*************************************** * *  bitblt wrapper * ***************************************/static void cirrus_bitblt_reset(CirrusVGAState * s){    s->gr[0x31] &=	~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);    s->cirrus_srcptr = &s->cirrus_bltbuf[0];    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];    s->cirrus_srccounter = 0;    cirrus_update_memory_access(s);}static int cirrus_bitblt_cputovideo(CirrusVGAState * s){    int w;    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;    s->cirrus_srcptr = &s->cirrus_bltbuf[0];    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {	if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {	    s->cirrus_blt_srcpitch = 8;	} else {            /* XXX: check for 24 bpp */	    s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;	}	s->cirrus_srccounter = s->cirrus_blt_srcpitch;    } else {	if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {            w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;            if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)                 s->cirrus_blt_srcpitch = ((w + 31) >> 5);            else                s->cirrus_blt_srcpitch = ((w + 7) >> 3);	} else {            /* always align input size to 32 bits */	    s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;	}        s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;    }    s->cirrus_srcptr = s->cirrus_bltbuf;    s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;    cirrus_update_memory_access(s);    return 1;}static int cirrus_bitblt_videotocpu(CirrusVGAState * s){    /* XXX */#ifdef DEBUG_BITBLT    printf("cirrus: bitblt (video to cpu) is not implemented yet\n");#endif    return 0;}static int cirrus_bitblt_videotovideo(CirrusVGAState * s){    int ret;    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {	ret = cirrus_bitblt_videotovideo_patterncopy(s);    } else {	ret = cirrus_bitblt_videotovideo_copy(s);    }    if (ret)	cirrus_bitblt_reset(s);    return ret;}static void cirrus_bitblt_start(CirrusVGAState * s){    uint8_t blt_rop;    s->gr[0x31] |= CIRRUS_BLT_BUSY;    s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;    s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;    s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));    s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8));    s->cirrus_blt_dstaddr =	(s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16));    s->cirrus_blt_srcaddr =	(s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));    s->cirrus_blt_mode = s->gr[0x30];    s->cirrus_blt_modeext = s->gr[0x33];

⌨️ 快捷键说明

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