]> xenbits.xensource.com Git - people/pauldu/demu.git/commitdiff
Put VRAM in guest memory.
authorPaul Durrant <paul.durrant@citrix.com>
Mon, 10 Feb 2014 15:50:05 +0000 (15:50 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Mon, 10 Feb 2014 15:50:05 +0000 (15:50 +0000)
The VRAM is now in guest memory and is set up when the VRAM BAR is
programmed. Text mode is still painfully slow indicating that there's
still some issue with VGA emulation, but graphics mode now looks fine.

Still no keyboard or mouse.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
demu.c
demu.h
device.c
device.h
mapcache.c
surface.c
surface.h

diff --git a/demu.c b/demu.c
index 246326a6ecce38a4dd88ba5c569c316616416d4c..548216ef16bc2b873958818e1d2a65aa20bd1101 100644 (file)
--- a/demu.c
+++ b/demu.c
@@ -175,18 +175,76 @@ typedef struct demu_state {
 static demu_state_t demu_state;
 
 void *
-demu_map_guest_pages(xen_pfn_t pfn[], unsigned int n)
+demu_map_guest_pages(xen_pfn_t pfn[], unsigned int n, int populate)
 {
     void *ptr;
 
+    if (populate) {
+        int rc;
+
+        rc = xc_domain_populate_physmap_exact(demu_state.xch, demu_state.domid,
+                                              n, 0, 0, pfn);
+        if (rc < 0)
+            goto fail1;
+    }
+
     ptr = xc_map_foreign_pages(demu_state.xch, demu_state.domid,
                                PROT_READ | PROT_WRITE,
                                pfn, n);
     if (ptr == NULL)
+        goto fail2;
+
+    if (populate)
+        memset(ptr, 0, n * TARGET_PAGE_SIZE);
+    
+    return ptr;
+
+fail2:
+    DBG("fail2\n");
+
+    if (populate)
+        (void) xc_domain_decrease_reservation(demu_state.xch, demu_state.domid,
+                                              n, 0, pfn);
+    
+fail1:
+    DBG("fail1\n");
+
+    warn("fail");
+    return NULL;
+}
+
+void *
+demu_map_guest_range(uint64_t addr, uint64_t size, int populate)
+{
+    xen_pfn_t   *pfn;
+    int         i, n;
+    void        *ptr;
+
+    DBG("%"PRIx64"+%"PRIx64" %s\n", addr, size, (populate) ? "[POPULATE]" : "");
+
+    size = P2ROUNDUP(size, TARGET_PAGE_SIZE);
+
+    n = size >> TARGET_PAGE_SHIFT;
+    pfn = malloc(sizeof (xen_pfn_t) * n);
+
+    if (pfn == NULL)
         goto fail1;
+
+    for (i = 0; i < n; i++)
+        pfn[i] = (addr >> TARGET_PAGE_SHIFT) + i;
+    
+    ptr = demu_map_guest_pages(pfn, n, populate);
+    if (ptr == NULL)
+        goto fail2;
     
+    free(pfn);
     return ptr;
     
+fail2:
+    DBG("fail2\n");
+    
+    free(pfn);
+    
 fail1:
     DBG("fail1\n");
 
@@ -194,6 +252,138 @@ fail1:
     return NULL;
 }
 
+void
+demu_unmap_guest_pages(void *ptr, xen_pfn_t pfn[], unsigned int n, int depopulate)
+{
+    munmap(ptr, TARGET_PAGE_SIZE * n);
+    if (depopulate)
+        (void) xc_domain_decrease_reservation(demu_state.xch, demu_state.domid,
+                                              n, 0, pfn);
+}
+
+int
+demu_unmap_guest_range(void *ptr, uint64_t addr, uint64_t size, int depopulate)
+{
+    xen_pfn_t   *pfn;
+    int         i, n;
+
+    DBG("%"PRIx64"+%"PRIx64" %s\n", addr, size, (depopulate) ? "[DEPOPULATE]" : "");
+
+    size = P2ROUNDUP(size, TARGET_PAGE_SIZE);
+
+    n = size >> TARGET_PAGE_SHIFT;
+    pfn = malloc(sizeof (xen_pfn_t) * n);
+
+    if (pfn == NULL)
+        goto fail1;
+
+    for (i = 0; i < n; i++)
+        pfn[i] = (addr >> TARGET_PAGE_SHIFT) + i;
+    
+    demu_unmap_guest_pages(ptr, pfn, n, depopulate);
+    
+    free(pfn);
+    return 0;
+    
+fail1:
+    DBG("fail1\n");
+
+    warn("fail");
+    return -1;
+}
+
+int
+demu_relocate_guest_pages(xen_pfn_t old[], xen_pfn_t new[], unsigned int n)
+{
+    int i;
+    int rc;
+
+    for (i = 0; i < n; i++) {
+        rc = xc_domain_add_to_physmap(demu_state.xch, demu_state.domid,
+                                      XENMAPSPACE_gmfn, old[i], new[i]);
+        if (rc < 0)
+            goto fail1;
+
+    }
+
+    return 0;
+
+fail1:
+    DBG("fail1\n");
+    
+    warn("fail");
+    return -1;
+}
+
+int
+demu_relocate_guest_range(uint64_t old, uint64_t new, uint64_t size)
+{
+    xen_pfn_t   *old_pfn, *new_pfn;
+    int         i, n;
+    int         rc;
+
+    DBG("%"PRIx64"+%"PRIx64" -> %"PRIx64"\n", old, size, new);
+
+    size = P2ROUNDUP(size, TARGET_PAGE_SIZE);
+
+    n = size >> TARGET_PAGE_SHIFT;
+
+    old_pfn = malloc(sizeof (xen_pfn_t) * n);
+    if (old_pfn == NULL)
+        goto fail1;
+
+    new_pfn = malloc(sizeof (xen_pfn_t) * n);
+    if (new_pfn == NULL)
+        goto fail2;
+
+    for (i = 0; i < n; i++) {
+        old_pfn[i] = (old >> TARGET_PAGE_SHIFT) + i;
+        new_pfn[i] = (new >> TARGET_PAGE_SHIFT) + i;
+    }
+    
+    rc = demu_relocate_guest_pages(old_pfn, new_pfn, n);
+    if (rc < 0)
+        goto fail3;
+    
+    free(new_pfn);
+    free(old_pfn);
+    return 0;
+    
+fail3:
+    DBG("fail3\n");
+    
+    free(new_pfn);
+
+fail2:
+    DBG("fail2\n");
+    
+    free(old_pfn);
+    
+fail1:
+    DBG("fail1\n");
+
+    warn("fail");
+    return -1;
+}
+
+void
+demu_set_guest_dirty_page(xen_pfn_t pfn)
+{
+    (void) xc_hvm_modified_memory(demu_state.xch, demu_state.domid,
+                                  pfn, 1);
+}
+
+void
+demu_track_dirty_vram(xen_pfn_t pfn, int n, unsigned long *bitmap)
+{
+    int rc;
+
+    rc = xc_hvm_track_dirty_vram(demu_state.xch, demu_state.domid,
+                                 pfn, n, bitmap);
+    if (rc < 0 && bitmap != NULL)
+        memset(bitmap, 0, n / 8);
+}
+
 static demu_space_t *
 demu_find_space(demu_space_t *head, uint64_t addr)
 {
diff --git a/demu.h b/demu.h
index 75cd4f6faa8b427c02c282453011b8807d8ec2f8..278cfcaceddf3680973b6d6e0a70551b91b8ebc5 100644 (file)
--- a/demu.h
+++ b/demu.h
 #ifndef  _DEMU_H
 #define  _DEMU_H
 
+#ifndef TRUE
+#define TRUE    1
+#endif
+
+#ifndef FALSE
+#define FALSE   0
+#endif
+
 #define TARGET_PAGE_SHIFT   12
 #define TARGET_PAGE_SIZE    (1 << TARGET_PAGE_SHIFT)
 
 #define        P2ROUNDUP(_x, _a) -(-(_x) & -(_a))
 
-void    *demu_map_guest_pages(xen_pfn_t pfn[], unsigned int n);
+void    *demu_map_guest_pages(xen_pfn_t pfn[], unsigned int n, int populate);
 
-static inline void *demu_map_guest_page(xen_pfn_t pfn)
+static inline void *demu_map_guest_page(xen_pfn_t pfn, int populate)
 {
-       return demu_map_guest_pages(&pfn, 1);
+       return demu_map_guest_pages(&pfn, 1, populate);
 }
 
+void    *demu_map_guest_range(uint64_t addr, uint64_t size, int populate);
+
+void    demu_unmap_guest_pages(void *ptr, xen_pfn_t pfn[], unsigned int n,
+                               int depopulate);
+
+static inline void demu_unmap_guest_page(void *ptr, xen_pfn_t pfn,
+                                         int depopulate)
+{
+       return demu_unmap_guest_pages(ptr, &pfn, 1, depopulate);
+}
+
+int     demu_unmap_guest_range(void *ptr, uint64_t addr, uint64_t size,
+                               int depopulate);
+
+int     demu_relocate_guest_pages(xen_pfn_t old[], xen_pfn_t new[],
+                                  unsigned int n);
+int     demu_relocate_guest_range(uint64_t old, uint64_t new,
+                                  uint64_t size);
+
+void    demu_set_guest_dirty_page(xen_pfn_t pfn);
+void    demu_track_dirty_vram(xen_pfn_t pfn, int n, unsigned long *bitmap);
+
 typedef struct io_ops {
         uint8_t         (*readb)(void *priv, uint64_t addr);
         uint16_t        (*readw)(void *priv, uint64_t addr);
@@ -64,7 +94,6 @@ void demu_deregister_pci_config_space(uint8_t bus, uint8_t device, uint8_t funct
 void demu_deregister_port_space(uint64_t start);
 void demu_deregister_memory_space(uint64_t start);
 
-
 void    demu_new_framebuffer(uint32_t width, uint32_t height, uint32_t depth);
 uint8_t *demu_get_framebuffer(void);
 void    demu_update_framebuffer(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
index 18e7daa1a5daaa8ac48b4679aba23cc7ea378ae6..9cc376098d6100babd50414480500984e5cff44d 100644 (file)
--- a/device.c
+++ b/device.c
@@ -73,8 +73,6 @@
 #include "mapcache.h"
 #include "vga.h"
 
-#define FALSE 0
-
 #define DEBUG_VGA_MEMORY    0
 #define DEBUG_VGA_IO        0
 #define DEBUG_VBE_IO        0
@@ -141,6 +139,8 @@ typedef struct device {
     uint64_t        vram_addr;
     uint64_t        vram_size;
     uint8_t         *vram;
+    int             vram_enabled;
+    unsigned long   *bitmap;
     uint64_t        mmio_addr;
     uint64_t        mmio_size;
     uint64_t        rom_addr;
@@ -534,7 +534,10 @@ static io_ops_t device_vga_port_ops  = {
 static void
 __copy_from_vram(uint64_t addr, uint8_t *dst, uint64_t size)
 {
-    memcpy(dst, &device_state.vram[addr], size);
+    if (device_state.vram != NULL && device_state.vram_enabled)
+        memcpy(dst, &device_state.vram[addr], size);
+    else
+        memset(dst, 0xff, size);
 }
 
 static uint8_t
@@ -607,7 +610,10 @@ device_vga_memory_readb(void *priv, uint64_t addr)
 static void
 __copy_to_vram(uint8_t *src, uint64_t addr, uint64_t size)
 {
-    memcpy(&device_state.vram[addr], src, size);
+    if (device_state.vram != NULL && device_state.vram_enabled) {
+        memcpy(&device_state.vram[addr], src, size);
+        demu_set_guest_dirty_page((device_state.vram_addr + addr) >> TARGET_PAGE_SHIFT);
+    }
 }
 
 static void
@@ -848,6 +854,13 @@ device_vbe_index_write(void *priv, uint16_t val)
     vga->vbe_index = val;
 }
 
+static void
+__clear_vram(uint64_t size)
+{
+    if (device_state.vram != NULL && device_state.vram_enabled)
+        memset(device_state.vram, 0, size);
+}
+
 static void
 device_vbe_data_write(void *priv, uint16_t val)
 {
@@ -914,8 +927,7 @@ device_vbe_data_write(void *priv, uint16_t val)
 
                 /* clear the screen (should be done in BIOS) */
                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
-                    memset(device_state.vram, 0,
-                           vga->vbe_regs[VBE_DISPI_INDEX_YRES] * vga->vbe_line_offset);
+                    __clear_vram(vga->vbe_regs[VBE_DISPI_INDEX_YRES] * vga->vbe_line_offset);
                 }
 
                 /* we initialize the VGA graphic mode (should be done
@@ -1120,31 +1132,6 @@ device_vga_deregister(void)
     demu_deregister_port_space(0x3c0);
 }
 
-static uint8_t
-device_vram_readb(void *priv, uint64_t addr)
-{
-    uint8_t val;
-
-    addr -= device_state.vram_addr;
-
-    __copy_from_vram(addr, &val, 1);
-
-    return val;
-}
-
-static void
-device_vram_writeb(void *priv, uint64_t addr, uint8_t val)
-{
-    addr -= device_state.vram_addr;
-
-    __copy_to_vram(&val, addr, 1);
-}
-
-static io_ops_t device_vram_ops = {
-    .readb = device_vram_readb,
-    .writeb = device_vram_writeb
-};
-
 static void
 device_vram_bar_enable(void *priv, uint64_t addr)
 {
@@ -1152,8 +1139,18 @@ device_vram_bar_enable(void *priv, uint64_t addr)
 
     assert(priv == NULL);
 
+    DBG("%"PRIx64"\n", addr);
+
+    if (device_state.vram_addr == 0)
+        device_state.vram = demu_map_guest_range(addr,
+                                                 device_state.vram_size,
+                                                 TRUE);
+    else if (addr != device_state.vram_addr)
+        (void) demu_relocate_guest_range(device_state.vram_addr,
+                                         addr,
+                                         device_state.vram_size);
     device_state.vram_addr = addr;
-    DBG("%"PRIx64"\n", device_state.vram_addr);
+    device_state.vram_enabled = TRUE;
 
     vga->lfb_addr = device_state.vram_addr;
     vga->lfb_size = device_state.vram_size;
@@ -1161,11 +1158,6 @@ device_vram_bar_enable(void *priv, uint64_t addr)
     vga->vbe_regs[VBE_DISPI_INDEX_LFB_ADDRESS_H] = vga->lfb_addr >> 16;
     vga->vbe_regs[VBE_DISPI_INDEX_LFB_ADDRESS_L] = vga->lfb_addr & 0xFFFF;
     vga->vbe_regs[VBE_DISPI_INDEX_VIDEO_MEMORY_64K] = vga->lfb_size >> 16;
-
-    (void) demu_register_memory_space(device_state.vram_addr,
-                                      device_state.vram_size,
-                                      &device_vram_ops,
-                                      NULL);
 }
 
 static void
@@ -1175,7 +1167,8 @@ device_vram_bar_disable(void *priv)
 
     DBG("%"PRIx64"\n", device_state.vram_addr);
 
-    demu_deregister_memory_space(device_state.vram_addr);
+    demu_track_dirty_vram(0, 0, NULL);
+    device_state.vram_enabled = FALSE;
 }
 
 #define PCI_VGA_OFFSET  0x400
@@ -1320,9 +1313,9 @@ device_initialize(unsigned int bus, unsigned int device, unsigned int function,
     int         rc;
 
     device_state.vram_size = vram_size;
-    device_state.vram = malloc(vram_size);
 
-    if (device_state.vram == NULL)
+    device_state.bitmap = (unsigned long *)malloc(vram_size >> TARGET_PAGE_SHIFT);
+    if (device_state.bitmap == NULL)
         goto fail1;
 
     device_vga_reset();
@@ -1456,7 +1449,7 @@ fail3:
 fail2:
     DBG("fail2\n");
 
-    free(device_state.vram);
+    free(device_state.bitmap);
 
 fail1:
     DBG("fail1\n");
@@ -1465,19 +1458,44 @@ fail1:
     return -1;
 }
 
-uint8_t *device_get_vram(void)
+uint8_t *
+device_get_vram(void)
 {
        return device_state.vram;
 }
 
-vga_t *device_get_vga(void)
+vga_t *
+device_get_vga(void)
 {
        return &device_state.vga;
 }
 
-int device_vram_dirty(uint64_t addr, uint64_t size)
+void
+device_vram_get_dirty_map(int enable)
+{
+    if (enable && device_state.vram_enabled)
+        demu_track_dirty_vram(device_state.vram_addr >> TARGET_PAGE_SHIFT,
+                              device_state.vram_size >> TARGET_PAGE_SHIFT,
+                              device_state.bitmap);
+    else
+        demu_track_dirty_vram(0, 0, NULL);
+}
+
+int
+device_vram_is_dirty(uint64_t addr, uint64_t size)
 {
-    return 1;
+    xen_pfn_t   pfn = addr >> TARGET_PAGE_SHIFT;
+    int         n = size >> TARGET_PAGE_SHIFT;
+    int         dirty;
+
+    dirty = FALSE;
+    while (--n >= 0) {
+        dirty |= !!(device_state.bitmap[pfn / sizeof(unsigned long) * 8] &
+                    (1ul << (pfn % sizeof(unsigned long) * 8)));
+        pfn++;
+    }
+
+    return dirty;
 }
 
 void
@@ -1493,7 +1511,7 @@ device_teardown(void)
     pci_bar_deregister(0);
     pci_device_deregister();
     device_vga_deregister();
-    free(device_state.vram);
+    free(device_state.bitmap);
 }
 
 /*
index b83233e4341721ebc91435e52b2259053077977e..497898f7c921656d9cac6073dc5714cf22784e4b 100644 (file)
--- a/device.h
+++ b/device.h
@@ -38,7 +38,9 @@ void    device_teardown(void);
 
 uint8_t *device_get_vram(void);
 vga_t   *device_get_vga(void);
-int     device_vram_dirty(uint64_t addr, uint64_t size);
+
+void    device_vram_get_dirty_map(int enable);
+int     device_vram_is_dirty(uint64_t addr, uint64_t size);
 
 #endif  /* _DEVICE_H */
 
index f9c20eddd3a3d3775462104839b57ba0179342b5..6f6be07545dd668cf39630fe6aa1fb9e8f28ebe1 100644 (file)
@@ -114,11 +114,11 @@ __mapcache_fault(xen_pfn_t pfn)
             continue;
 
         if (entry->ptr != NULL) {
-            munmap(entry->ptr, TARGET_PAGE_SIZE);
+            demu_unmap_guest_page(entry->ptr, entry->pfn, FALSE);
             entry->ptr = NULL;
         }
 
-        entry->ptr = demu_map_guest_page(pfn);
+        entry->ptr = demu_map_guest_page(pfn, FALSE);
         if (entry->ptr != NULL)
             entry->pfn = pfn;
 
@@ -133,7 +133,7 @@ mapcache_lookup(xen_pfn_t pfn)
     int             faulted;
 
     faulted = 0;
-gain:
+again:
     ptr = __mapcache_lookup(pfn);
     if (ptr == NULL) {
         if (!faulted) {
index 3894d03feead1038a0c8e2b173eacec031027887..bf3dc90cc90c16d525a435ca7378fa4f6f01fd50 100644 (file)
--- a/surface.c
+++ b/surface.c
@@ -80,9 +80,7 @@
 #define VGA_MAX_HEIGHT 2048
 
 typedef struct surface {
-    uint8_t             *vram;
     uint8_t             *framebuffer;
-    vga_t               *vga;
     uint32_t            font_offsets[2];
     int                 graphic_mode;
     uint8_t             shift_control;
@@ -116,56 +114,56 @@ static uint8_t      expand4to8[16];
 
 static uint8_t get_ar_index(surface_t *s)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->ar_index;
 }
 
 static uint8_t get_ar(surface_t *s, int reg)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->ar[reg];
 }
 
 static uint8_t get_cr(surface_t *s, int reg)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->cr[reg];
 }
 
 static uint8_t get_sr(surface_t *s, int reg)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->sr[reg];
 }
 
 static uint8_t get_gr(surface_t *s, int reg)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->gr[reg];
 }
 
 static uint8_t get_palette(surface_t *s, int offset)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->palette[offset];
 }
 
 static int is_dac_8bit(surface_t *s)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return !!vga->dac_8bit;
 }
 
 static int test_and_clear_plane2(surface_t *s)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
     uint32_t val;
 
     val = vga->plane_updated & (1 << 2);
@@ -177,21 +175,21 @@ static int test_and_clear_plane2(surface_t *s)
 
 static uint16_t get_vbe_regs(surface_t *s, int reg)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->vbe_regs[reg];
 }
 
 static uint32_t get_vbe_start_addr(surface_t *s)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->vbe_start_addr;
 }
 
 static uint32_t get_vbe_line_offset(surface_t *s)
 {
-    vga_t   *vga = s->vga;
+    vga_t   *vga = device_get_vga();
 
     return vga->vbe_line_offset;
 }
@@ -539,8 +537,6 @@ surface_initialize(void)
     }
 
     surface_state.graphic_mode = -1;
-    surface_state.vram = device_get_vram();
-    surface_state.vga = device_get_vga();
 
     return 0;
 }
@@ -564,6 +560,11 @@ surface_draw_text(surface_t *s, int full_update)
     uint32_t *ch_attr_ptr;
     vga_draw_glyph8_func *__vga_draw_glyph8;
     vga_draw_glyph9_func *__vga_draw_glyph9;
+    uint8_t *vram = device_get_vram();
+
+    assert(vram != NULL);
+
+    device_vram_get_dirty_map(FALSE);
 
     /* compute font data address (in plane 2) */
     v = get_sr(s, 3);
@@ -572,10 +573,10 @@ surface_draw_text(surface_t *s, int full_update)
         s->font_offsets[0] = offset;
         full_update = 1;
     }
-    font_base[0] = s->vram + offset;
+    font_base[0] = vram + offset;
 
     offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
-    font_base[1] = s->vram + offset;
+    font_base[1] = vram + offset;
     if (offset != s->font_offsets[1]) {
         s->font_offsets[1] = offset;
         full_update = 1;
@@ -590,7 +591,7 @@ surface_draw_text(surface_t *s, int full_update)
     full_update |= update_basic_params(s);
 
     line_offset = s->line_offset;
-    s1 = s->vram + (s->start_addr * 4);
+    s1 = vram + (s->start_addr * 4);
 
     /* total width & height */
     cheight = (get_cr(s, 9) & 0x1f) + 1;
@@ -647,7 +648,7 @@ surface_draw_text(surface_t *s, int full_update)
         s->cursor_start = get_cr(s, 0xa);
         s->cursor_end = get_cr(s, 0xb);
     }
-    cursor_ptr = s->vram + (s->start_addr + cursor_offset) * 4;
+    cursor_ptr = vram + (s->start_addr + cursor_offset) * 4;
 
     if (cw == 16)
         __vga_draw_glyph8 = vga_draw_glyph16;
@@ -727,6 +728,9 @@ surface_draw_graphic(surface_t *s, int full_update)
     uint8_t *d;
     uint32_t v, addr1, addr;
     vga_draw_line_func *__vga_draw_line;
+    uint8_t *vram = device_get_vram();
+
+    assert(vram != NULL);
 
     full_update |= update_basic_params(s);
 
@@ -839,6 +843,8 @@ surface_draw_graphic(surface_t *s, int full_update)
     linesize = s->linesize;
     y1 = 0;
 
+    device_vram_get_dirty_map(TRUE);
+
     for(y = 0; y < height; y++) {
         addr = addr1;
         if (!(get_cr(s, 0x17) & 1)) {
@@ -850,7 +856,7 @@ surface_draw_graphic(surface_t *s, int full_update)
         if (!(get_cr(s, 0x17) & 2)) {
             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
         }
-        update = full_update | device_vram_dirty(addr, bwidth);
+        update = full_update | device_vram_is_dirty(addr, bwidth);
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
         if (update) {
@@ -860,7 +866,7 @@ surface_draw_graphic(surface_t *s, int full_update)
                 y_start = y;
 
             plane_enable = get_ar(s, 0x12) & 0xf;
-            __vga_draw_line(s->last_palette, plane_enable, d, s->vram + addr, width);
+            __vga_draw_line(s->last_palette, plane_enable, d, vram + addr, width);
         } else {
             if (y_start >= 0) {
                 /* flush to display */
@@ -898,6 +904,8 @@ surface_draw_blank(surface_t *s, int full_update)
 {
     int val;
 
+    device_vram_get_dirty_map(FALSE);
+
     if (!full_update)
         return;
 
@@ -920,8 +928,9 @@ surface_refresh(void)
     surface_t *s = &surface_state;
     int full_update;
     int graphic_mode;
+    uint8_t *vram = device_get_vram();
 
-    if (!(get_ar_index(s) & 0x20)) {
+    if (!(get_ar_index(s) & 0x20) || vram == NULL) {
         graphic_mode = GMODE_BLANK;
     } else {
         graphic_mode = get_gr(s, 6) & 1;
@@ -961,37 +970,6 @@ surface_refresh(void)
 
 }
 
-void
-surface_refresh_test(void)
-{
-    surface_t       *s = &surface_state;
-    uint32_t        pixel;
-    static uint8_t  val;
-
-    if (s->last_scr_width != 640 ||
-        s->last_scr_height != 480 ||
-        s->last_depth != 32) {
-        surface_resize(640, 480);
-
-        s->last_width = 640;
-        s->last_height = 480;
-        s->last_depth = 32;
-    }
-
-    for (pixel = 0;
-         pixel < s->last_scr_width * s->last_scr_height * 4;
-         pixel += 4) {
-        s->framebuffer[pixel] = val;
-        s->framebuffer[pixel + 1] = val;
-        s->framebuffer[pixel + 2] = val;
-    }
-
-    surface_update(0, 0,
-                   s->last_scr_width, s->last_scr_height);
-
-    val++;
-}
-
 void
 surface_teardown(void)
 {
index 45eb1fdc10824d15ae9e8b8159dbaa2caf70acc8..015bc6b5bab488f5b4cf5504a3167d151b3353fe 100644 (file)
--- a/surface.h
+++ b/surface.h
@@ -32,7 +32,6 @@
 
 int     surface_initialize(void);
 void    surface_refresh(void);
-void    surface_refresh_test(void);
 void    surface_teardown(void);
 
 #endif  /* _SURFACE_H */