Index: hw/cirrus_vga.c =================================================================== RCS file: /home/Cvsroot/qemu/hw/cirrus_vga.c,v retrieving revision 1.1.1.1 diff -B -b -U3 -r1.1.1.1 cirrus_vga.c --- hw/cirrus_vga.c 14 Jan 2006 13:19:59 -0000 1.1.1.1 +++ hw/cirrus_vga.c 16 Jan 2006 10:10:02 -0000 @@ -579,6 +579,20 @@ } } +// ------------------------ VGA speed hack ------------------------- +static inline void my_physical_memory_set_dirty(uint32_t uaddr) +{ + if(vga_dirty_left != 0xffff) { // only for 1024 pix width! + int jx = uaddr % 3072; // pixel*3 - will divide later + if(jx < vga_dirty_left) + vga_dirty_left = jx; + else if(jx > vga_dirty_right) + vga_dirty_right = jx; + } + cpu_physical_memory_set_dirty(uaddr); +} +// ----------------------------------------------------------------- + static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, int off_pitch, int bytesperline, int lines) @@ -587,6 +601,17 @@ int off_cur; int off_cur_end; +// ------------------------ VGA speed hack ------------------------- + if(vga_dirty_left != 0xffff) { // only for 1024 pix width! + int jx = off_begin % 3072; // pixel*3 - will divide later + if(off_pitch < 0) + jx -= bytesperline - 3; + if(jx < vga_dirty_left) vga_dirty_left = jx; + jx += bytesperline - 3; + if(jx > vga_dirty_right) vga_dirty_right = jx; + } +// ----------------------------------------------------------------- + for (y = 0; y < lines; y++) { off_cur = off_begin; off_cur_end = off_cur + bytesperline; @@ -1787,8 +1812,8 @@ val <<= 1; dst++; } - cpu_physical_memory_set_dirty(s->vram_offset + offset); - cpu_physical_memory_set_dirty(s->vram_offset + offset + 7); + my_physical_memory_set_dirty(s->vram_offset + offset); + my_physical_memory_set_dirty(s->vram_offset + offset + 7); } static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, @@ -1812,8 +1837,8 @@ val <<= 1; dst += 2; } - cpu_physical_memory_set_dirty(s->vram_offset + offset); - cpu_physical_memory_set_dirty(s->vram_offset + offset + 15); + my_physical_memory_set_dirty(s->vram_offset + offset); + my_physical_memory_set_dirty(s->vram_offset + offset + 15); } /*************************************** @@ -1933,7 +1958,7 @@ mode = s->gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { *(s->vram_ptr + bank_offset) = mem_value; - cpu_physical_memory_set_dirty(s->vram_offset + + my_physical_memory_set_dirty(s->vram_offset + bank_offset); } else { if ((s->gr[0x0B] & 0x14) != 0x14) { @@ -2262,7 +2287,7 @@ mode = s->gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { *(s->vram_ptr + addr) = (uint8_t) val; - cpu_physical_memory_set_dirty(s->vram_offset + addr); + my_physical_memory_set_dirty(s->vram_offset + addr); } else { if ((s->gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); @@ -2321,7 +2346,7 @@ addr &= s->cirrus_addr_mask; *(s->vram_ptr + addr) = val; - cpu_physical_memory_set_dirty(s->vram_offset + addr); + my_physical_memory_set_dirty(s->vram_offset + addr); } static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr, @@ -2331,7 +2356,7 @@ addr &= s->cirrus_addr_mask; cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val); - cpu_physical_memory_set_dirty(s->vram_offset + addr); + my_physical_memory_set_dirty(s->vram_offset + addr); } static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr, @@ -2341,7 +2366,7 @@ addr &= s->cirrus_addr_mask; cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val); - cpu_physical_memory_set_dirty(s->vram_offset + addr); + my_physical_memory_set_dirty(s->vram_offset + addr); } /*************************************** Index: hw/vga.c =================================================================== RCS file: /home/Cvsroot/qemu/hw/vga.c,v retrieving revision 1.1.1.1 diff -B -b -U3 -r1.1.1.1 vga.c --- hw/vga.c 14 Jan 2006 13:19:59 -0000 1.1.1.1 +++ hw/vga.c 16 Jan 2006 10:10:18 -0000 @@ -24,6 +24,11 @@ #include "vl.h" #include "vga_int.h" +// ------------------------ VGA speed hack ------------------------- +uint16_t vga_dirty_left = 0xffff; +uint16_t vga_dirty_right; +// ----------------------------------------------------------------- + //#define DEBUG_VGA //#define DEBUG_VGA_MEM //#define DEBUG_VGA_REG @@ -1379,6 +1384,27 @@ printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]); #endif + // ------------------------ VGA speed hack ------------------------- + if(vga_dirty_left == 0xffff || full_update) { // was disabled + vga_dirty_left = 0; + vga_dirty_right = disp_width; + } + // do nothing if no update (this code is called by a timer!) + else if(vga_dirty_right == 0 && vga_dirty_left == disp_width*3) + return; + else { // has info + if(vga_dirty_left > vga_dirty_right) + vga_dirty_right = vga_dirty_left; + vga_dirty_left /= 3; + vga_dirty_right /= 3; + + vga_dirty_right -= vga_dirty_left; + vga_dirty_right += 2; + if(vga_dirty_left + vga_dirty_right > disp_width) + vga_dirty_right = disp_width - vga_dirty_left; + } + // ----------------------------------------------------------------- + addr1 = (s->start_addr * 4); bwidth = width * 4; y_start = -1; @@ -1400,14 +1427,17 @@ } page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); - update = full_update | - cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | - cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); - if ((page1 - page0) > TARGET_PAGE_SIZE) { + update = full_update; + if(!update) { // && y >= vga_dirty_top && y <= vga_dirty_bottom) { + if( cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | + cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG)) + update = 1; + else if((page1 - page0) > TARGET_PAGE_SIZE) { /* if wide line, can use another page */ update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, VGA_DIRTY_FLAG); } + } /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; if (update) { @@ -1423,8 +1453,8 @@ } else { if (y_start >= 0) { /* flush to display */ - dpy_update(s->ds, 0, y_start, - disp_width, y - y_start); + dpy_update(s->ds, vga_dirty_left, y_start, + vga_dirty_right, y - y_start); y_start = -1; } } @@ -1444,8 +1474,8 @@ } if (y_start >= 0) { /* flush to display */ - dpy_update(s->ds, 0, y_start, - disp_width, y - y_start); + dpy_update(s->ds, vga_dirty_left, y_start, + vga_dirty_right, y - y_start); } /* reset modified pages */ if (page_max != -1) { @@ -1453,6 +1483,10 @@ VGA_DIRTY_FLAG); } memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); +// ------------------------ VGA speed hack ------------------------- + vga_dirty_left = (disp_width == 1024) ? 3072 : 0xffff; + vga_dirty_right = 0; +// ----------------------------------------------------------------- } static void vga_draw_blank(VGAState *s, int full_update) Index: hw/vga_int.h =================================================================== RCS file: /home/Cvsroot/qemu/hw/vga_int.h,v retrieving revision 1.1.1.1 diff -B -b -U3 -r1.1.1.1 vga_int.h --- hw/vga_int.h 14 Jan 2006 13:19:59 -0000 1.1.1.1 +++ hw/vga_int.h 16 Jan 2006 10:10:20 -0000 @@ -168,3 +168,10 @@ extern const uint8_t sr_mask[8]; extern const uint8_t gr_mask[16]; + +// ------------------------ VGA speed hack ------------------------- +// limits the update region horizontally, only in some cirrus modes! +// for vga_dirty_left == 0xffff the hack becomes disabled +extern uint16_t vga_dirty_left; +extern uint16_t vga_dirty_right; +// -----------------------------------------------------------------