diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 9f61a01..a7f0d3c 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst,
int src, int w, int h)
int sx, sy;
int dx, dy;
int width, height;
+ uint32_t start_addr, line_offset, line_compare;
int depth;
int notify = 0;
depth = s->vga.get_bpp(&s->vga) / 8;
s->vga.get_resolution(&s->vga,&width,&height);
+ s->vga.get_offsets(&s->vga,&line_offset,&start_addr,&line_compare);
/* extra x, y */
- sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
- sy = (src / ABS(s->cirrus_blt_srcpitch));
+ sx = (src % line_offset) / depth;
+ sy = (src / line_offset);
dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
dy = (dst / ABS(s->cirrus_blt_dstpitch));
@@ -725,18 +727,23 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst,
int src, int w, int h)
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
s->cirrus_blt_width, s->cirrus_blt_height);
- if (notify)
- qemu_console_copy(s->vga.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 */
-
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
+ if (ABS(s->cirrus_blt_dstpitch) != line_offset ||
+ ABS(s->cirrus_blt_srcpitch) != line_offset) {
+ /* this is not going to happen very often */
+ vga_hw_invalidate();
+ } else {
+ if (notify)
+ /* we don't have to notify the display that this portion has
+ changed since qemu_console_copy implies this */
+ qemu_console_copy(s->vga.ds,
+ sx, sy, dx, dy,
+ s->cirrus_blt_width / depth,
+ s->cirrus_blt_height);
+ else
+ 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)
diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
index 39a7b72..80f135b 100644
--- a/hw/cirrus_vga_rop.h
+++ b/hw/cirrus_vga_rop.h
@@ -32,10 +32,10 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
dstpitch -= bltwidth;
srcpitch -= bltwidth;
- if (dstpitch< 0 || srcpitch< 0) {
- /* is 0 valid? srcpitch == 0 could be useful */
+ if (dstpitch< 0)
return;
- }
+ if (srcpitch< 0)
+ srcpitch = 0;
for (y = 0; y< bltheight; y++) {
for (x = 0; x< bltwidth; x++) {
@@ -57,6 +57,12 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
int x,y;
dstpitch += bltwidth;
srcpitch += bltwidth;
+
+ if (dstpitch> 0)
+ return;
+ if (srcpitch> 0)
+ srcpitch = 0;
+
for (y = 0; y< bltheight; y++) {
for (x = 0; x< bltwidth; x++) {
ROP_OP(*dst, *src);
@@ -78,6 +84,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
ROP_NAME),_8)(CirrusVGAState *s,
uint8_t p;
dstpitch -= bltwidth;
srcpitch -= bltwidth;
+
+ if (dstpitch< 0)
+ return;
+ if (srcpitch< 0)
+ srcpitch = 0;
+
for (y = 0; y< bltheight; y++) {
for (x = 0; x< bltwidth; x++) {
p = *dst;
@@ -101,6 +113,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_,
ROP_NAME),_8)(CirrusVGAState *s,
uint8_t p;
dstpitch += bltwidth;
srcpitch += bltwidth;
+
+ if (dstpitch> 0)
+ return;
+ if (srcpitch> 0)
+ srcpitch = 0;
+
for (y = 0; y< bltheight; y++) {
for (x = 0; x< bltwidth; x++) {
p = *dst;
@@ -124,6 +142,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
ROP_NAME),_16)(CirrusVGAState *s,
uint8_t p1, p2;
dstpitch -= bltwidth;
srcpitch -= bltwidth;
+
+ if (dstpitch< 0)
+ return;
+ if (srcpitch< 0)
+ srcpitch = 0;
+
for (y = 0; y< bltheight; y++) {
for (x = 0; x< bltwidth; x+=2) {
p1 = *dst;
@@ -152,6 +176,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_,
ROP_NAME),_16)(CirrusVGAState *s,
uint8_t p1, p2;
dstpitch += bltwidth;
srcpitch += bltwidth;
+
+ if (dstpitch> 0)
+ return;
+ if (srcpitch> 0)
+ srcpitch = 0;
+
for (y = 0; y< bltheight; y++) {
for (x = 0; x< bltwidth; x+=2) {
p1 = *(dst-1);
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to address@hidden
More majordomo info at http://vger.kernel.org/majordomo-info.html