*/
#include "qemu/osdep.h"
-#include "qapi/error.h"
#include "qemu-common.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
#include "ui/console.h"
#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
#include "hw/loader.h"
+#include "hw/qdev-properties.h"
#include "qemu/log.h"
+#include "qemu/module.h"
/* Change to 1 to enable debugging */
#define DEBUG_CG3 0
if (DEBUG_CG3) { \
printf("CG3: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_CG3 "cgthree"
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)
uint32_t dval;
int x, y, y_start;
unsigned int width, height;
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
+ DirtyBitmapSnapshot *snap = NULL;
if (surface_bits_per_pixel(surface) != 32) {
return;
height = s->height;
y_start = -1;
- page_min = -1;
- page_max = 0;
- page = 0;
pix = memory_region_get_ram_ptr(&s->vram_mem);
data = (uint32_t *)surface_data(surface);
- memory_region_sync_dirty_bitmap(&s->vram_mem);
+ if (!s->full_update) {
+ snap = memory_region_snapshot_and_clear_dirty(&s->vram_mem, 0x0,
+ memory_region_size(&s->vram_mem),
+ DIRTY_MEMORY_VGA);
+ }
+
for (y = 0; y < height; y++) {
- int update = s->full_update;
+ int update;
page = (ram_addr_t)y * width;
- update |= memory_region_get_dirty(&s->vram_mem, page, width,
- DIRTY_MEMORY_VGA);
+
+ if (s->full_update) {
+ update = 1;
+ } else {
+ update = memory_region_snapshot_get_dirty(&s->vram_mem, snap, page,
+ width);
+ }
+
if (update) {
if (y_start < 0) {
y_start = y;
}
- if (page < page_min) {
- page_min = page;
- }
- if (page > page_max) {
- page_max = page;
- }
for (x = 0; x < width; x++) {
dval = *pix++;
}
} else {
if (y_start >= 0) {
- dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
+ dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
y_start = -1;
}
pix += width;
}
s->full_update = 0;
if (y_start >= 0) {
- dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
- }
- if (page_max >= page_min) {
- memory_region_reset_dirty(&s->vram_mem,
- page_min, page_max - page_min, DIRTY_MEMORY_VGA);
+ dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
}
/* vsync interrupt? */
if (s->regs[0] & CG3_CR_ENABLE_INTS) {
s->regs[1] |= CG3_SR_PENDING_INT;
qemu_irq_raise(s->irq);
}
+ g_free(snap);
}
static void cg3_invalidate_display(void *opaque)
s->b[s->dac_index] = regval;
/* Index autoincrement */
s->dac_index = (s->dac_index + 1) & 0xff;
+ /* fall through */
default:
s->dac_state = 0;
break;
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
CG3State *s = CG3(obj);
- memory_region_init_ram(&s->rom, obj, "cg3.prom", FCODE_MAX_ROM_SIZE,
- &error_fatal);
- memory_region_set_readonly(&s->rom, true);
+ memory_region_init_rom_nomigrate(&s->rom, obj, "cg3.prom",
+ FCODE_MAX_ROM_SIZE, &error_fatal);
sysbus_init_mmio(sbd, &s->rom);
memory_region_init_io(&s->reg, obj, &cg3_reg_ops, s, "cg3.reg",
ret = load_image_mr(fcode_filename, &s->rom);
g_free(fcode_filename);
if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
- error_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
+ warn_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
}
}
memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size,
&error_fatal);
memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
- vmstate_register_ram_global(&s->vram_mem);
sysbus_init_mmio(sbd, &s->vram_mem);
sysbus_init_irq(sbd, &s->irq);
dc->realize = cg3_realizefn;
dc->reset = cg3_reset;
dc->vmsd = &vmstate_cg3;
- dc->props = cg3_properties;
+ device_class_set_props(dc, cg3_properties);
}
static const TypeInfo cg3_info = {