*/
#include "qemu/osdep.h"
-#include "qapi/error.h"
#include "qemu-common.h"
+#include "qapi/error.h"
#include "ui/console.h"
#include "ui/pixel_ops.h"
#include "hw/loader.h"
+#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
+#include "migration/vmstate.h"
#include "qemu/error-report.h"
+#include "qemu/module.h"
#define TCX_ROM_FILE "QEMU,tcx.bin"
#define FCODE_MAX_ROM_SIZE 0x10000
}
}
-static int tcx_check_dirty(TCXState *s, ram_addr_t addr, int len)
+static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
+ ram_addr_t addr, int len)
{
int ret;
- ret = memory_region_get_dirty(&s->vram_mem, addr, len, DIRTY_MEMORY_VGA);
+ ret = memory_region_snapshot_get_dirty(&s->vram_mem, snap, addr, len);
if (s->depth == 24) {
- ret |= memory_region_get_dirty(&s->vram_mem,
- s->vram24_offset + addr * 4, len * 4,
- DIRTY_MEMORY_VGA);
- ret |= memory_region_get_dirty(&s->vram_mem,
- s->cplane_offset + addr * 4, len * 4,
- DIRTY_MEMORY_VGA);
+ ret |= memory_region_snapshot_get_dirty(&s->vram_mem, snap,
+ s->vram24_offset + addr * 4, len * 4);
+ ret |= memory_region_snapshot_get_dirty(&s->vram_mem, snap,
+ s->cplane_offset + addr * 4, len * 4);
}
return ret;
}
-static void tcx_reset_dirty(TCXState *s, ram_addr_t addr, int len)
-{
- memory_region_reset_dirty(&s->vram_mem, addr, len, DIRTY_MEMORY_VGA);
-
- if (s->depth == 24) {
- memory_region_reset_dirty(&s->vram_mem, s->vram24_offset + addr * 4,
- len * 4, DIRTY_MEMORY_VGA);
- memory_region_reset_dirty(&s->vram_mem, s->cplane_offset + addr * 4,
- len * 4, DIRTY_MEMORY_VGA);
- }
-}
-
static void update_palette_entries(TCXState *s, int start, int end)
{
DisplaySurface *surface = qemu_console_surface(s->con);
} else {
s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
}
- break;
}
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
}
{
TCXState *ts = opaque;
DisplaySurface *surface = qemu_console_surface(ts->con);
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
+ DirtyBitmapSnapshot *snap = NULL;
int y, y_start, dd, ds;
uint8_t *d, *s;
page = 0;
y_start = -1;
- page_min = -1;
- page_max = 0;
d = surface_data(surface);
s = ts->vram;
dd = surface_stride(surface);
ds = 1024;
- memory_region_sync_dirty_bitmap(&ts->vram_mem);
+ snap = memory_region_snapshot_and_clear_dirty(&ts->vram_mem, 0x0,
+ memory_region_size(&ts->vram_mem),
+ DIRTY_MEMORY_VGA);
+
for (y = 0; y < ts->height; y++, page += ds) {
- if (tcx_check_dirty(ts, page, ds)) {
+ if (tcx_check_dirty(ts, snap, page, ds)) {
if (y_start < 0)
y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
tcx_draw_line32(ts, d, s, ts->width);
if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
dpy_gfx_update(ts->con, 0, y_start,
ts->width, y - y_start);
}
- /* reset modified pages */
- if (page_max >= page_min) {
- tcx_reset_dirty(ts, page_min, page_max - page_min);
- }
+ g_free(snap);
}
static void tcx24_update_display(void *opaque)
{
TCXState *ts = opaque;
DisplaySurface *surface = qemu_console_surface(ts->con);
- ram_addr_t page, page_min, page_max;
+ ram_addr_t page;
+ DirtyBitmapSnapshot *snap = NULL;
int y, y_start, dd, ds;
uint8_t *d, *s;
uint32_t *cptr, *s24;
page = 0;
y_start = -1;
- page_min = -1;
- page_max = 0;
d = surface_data(surface);
s = ts->vram;
s24 = ts->vram24;
dd = surface_stride(surface);
ds = 1024;
- memory_region_sync_dirty_bitmap(&ts->vram_mem);
+ snap = memory_region_snapshot_and_clear_dirty(&ts->vram_mem, 0x0,
+ memory_region_size(&ts->vram_mem),
+ DIRTY_MEMORY_VGA);
+
for (y = 0; y < ts->height; y++, page += ds) {
- if (tcx_check_dirty(ts, page, ds)) {
+ if (tcx_check_dirty(ts, snap, page, ds)) {
if (y_start < 0)
y_start = y;
- if (page < page_min)
- page_min = page;
- if (page > page_max)
- page_max = page;
+
tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
tcx_draw_cursor32(ts, d, y, ts->width);
dpy_gfx_update(ts->con, 0, y_start,
ts->width, y - y_start);
}
- /* reset modified pages */
- if (page_max >= page_min) {
- tcx_reset_dirty(ts, page_min, page_max - page_min);
- }
+ g_free(snap);
}
static void tcx_invalidate_display(void *opaque)
case 2:
val = s->b[s->dac_index] << 24;
s->dac_index = (s->dac_index + 1) & 0xff; /* Index autoincrement */
+ /* fall through */
default:
s->dac_state = 0;
break;
s->b[index] = val >> 24;
update_palette_entries(s, index, index + 1);
s->dac_index = (s->dac_index + 1) & 0xff; /* Index autoincrement */
+ /* fall through */
default:
s->dac_state = 0;
break;
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
TCXState *s = TCX(obj);
- memory_region_init_ram(&s->rom, obj, "tcx.prom", FCODE_MAX_ROM_SIZE,
- &error_fatal);
- memory_region_set_readonly(&s->rom, true);
+ memory_region_init_rom_nomigrate(&s->rom, obj, "tcx.prom",
+ FCODE_MAX_ROM_SIZE, &error_fatal);
sysbus_init_mmio(sbd, &s->rom);
/* 2/STIP : Stippler */
uint8_t *vram_base;
char *fcode_filename;
- memory_region_init_ram(&s->vram_mem, OBJECT(s), "tcx.vram",
+ memory_region_init_ram_nomigrate(&s->vram_mem, OBJECT(s), "tcx.vram",
s->vram_size * (1 + 4 + 4), &error_fatal);
vmstate_register_ram_global(&s->vram_mem);
memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);
ret = load_image_mr(fcode_filename, &s->rom);
g_free(fcode_filename);
if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
- error_report("tcx: could not load prom '%s'", TCX_ROM_FILE);
+ warn_report("tcx: could not load prom '%s'", TCX_ROM_FILE);
}
}
sysbus_init_irq(sbd, &s->irq);
if (s->depth == 8) {
- s->con = graphic_console_init(DEVICE(dev), 0, &tcx_ops, s);
+ s->con = graphic_console_init(dev, 0, &tcx_ops, s);
} else {
- s->con = graphic_console_init(DEVICE(dev), 0, &tcx24_ops, s);
+ s->con = graphic_console_init(dev, 0, &tcx24_ops, s);
}
s->thcmisc = 0;
dc->realize = tcx_realizefn;
dc->reset = tcx_reset;
dc->vmsd = &vmstate_tcx;
- dc->props = tcx_properties;
+ device_class_set_props(dc, tcx_properties);
}
static const TypeInfo tcx_info = {