PS2 mouse and keyboard separation (Paul Brook)
[qemu] / hw / cirrus_vga.c
index 7c34c57..934cde9 100644 (file)
@@ -31,7 +31,7 @@
 
 /*
  * TODO:
- *    - add support for WRITEMASK (GR2F)
+ *    - destination write mask support not complete (bits 5..7)
  *    - optimize linear mappings
  *    - optimize bitblt functions
  */
@@ -737,7 +737,8 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
             else
                 s->cirrus_blt_srcpitch = ((w + 7) >> 3);
        } else {
-           s->cirrus_blt_srcpitch = s->cirrus_blt_width;
+            /* 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;
     }
@@ -789,7 +790,7 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
     blt_rop = s->gr[0x32];
 
 #ifdef DEBUG_BITBLT
-    printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spicth=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
+    printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
            blt_rop, 
            s->cirrus_blt_mode,
            s->cirrus_blt_modeext,
@@ -799,7 +800,7 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
            s->cirrus_blt_srcpitch,
            s->cirrus_blt_dstaddr,
            s->cirrus_blt_srcaddr,
-           s->sr[0x2f]);
+           s->gr[0x2f]);
 #endif
 
     switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
@@ -1041,10 +1042,10 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
     else
        offset <<= 12;
 
-    if (s->vram_size <= offset)
+    if (s->real_vram_size <= offset)
        limit = 0;
     else
-       limit = s->vram_size - offset;
+       limit = s->real_vram_size - offset;
 
     if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
        if (limit > 0x8000) {
@@ -1212,7 +1213,7 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
 #endif
        break;
     case 0x17:                 // Configuration Readback and Extended Control
-       s->sr[reg_index] = reg_value;
+       s->sr[reg_index] = (s->sr[reg_index] & 0x38) | (reg_value & 0xc7);
         cirrus_update_memory_access(s);
         break;
     default:
@@ -1779,11 +1780,12 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
     dst = s->vram_ptr + offset;
     for (x = 0; x < 8; x++) {
        if (val & 0x80) {
-           *dst++ = s->cirrus_shadow_gr1;
+           *dst = s->cirrus_shadow_gr1;
        } else if (mode == 5) {
-           *dst++ = s->cirrus_shadow_gr0;
+           *dst = s->cirrus_shadow_gr0;
        }
        val <<= 1;
+       dst++;
     }
     cpu_physical_memory_set_dirty(s->vram_offset + offset);
     cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);
@@ -1801,13 +1803,14 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
     dst = s->vram_ptr + offset;
     for (x = 0; x < 8; x++) {
        if (val & 0x80) {
-           *dst++ = s->cirrus_shadow_gr1;
-           *dst++ = s->gr[0x11];
+           *dst = s->cirrus_shadow_gr1;
+           *(dst + 1) = s->gr[0x11];
        } else if (mode == 5) {
-           *dst++ = s->cirrus_shadow_gr0;
-           *dst++ = s->gr[0x10];
+           *dst = s->cirrus_shadow_gr0;
+           *(dst + 1) = s->gr[0x10];
        }
        val <<= 1;
+       dst += 2;
     }
     cpu_physical_memory_set_dirty(s->vram_offset + offset);
     cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);