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) qemu_console_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 qemu_console_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); }