static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)

{

    struct vmsvga_state_s *s = opaque;



    if (s->index >= SVGA_SCRATCH_BASE) {

        trace_vmware_scratch_write(s->index, value);

    } else if (s->index >= SVGA_PALETTE_BASE) {

        trace_vmware_palette_write(s->index, value);

    } else {

        trace_vmware_value_write(s->index, value);

    }

    switch (s->index) {

    case SVGA_REG_ID:

        if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) {

            s->svgaid = value;

        }

        break;



    case SVGA_REG_ENABLE:

        s->enable = !!value;

        s->invalidated = 1;

        s->vga.hw_ops->invalidate(&s->vga);

        if (s->enable && s->config) {

            vga_dirty_log_stop(&s->vga);

        } else {

            vga_dirty_log_start(&s->vga);

        }

        break;



    case SVGA_REG_WIDTH:

        if (value <= SVGA_MAX_WIDTH) {

            s->new_width = value;

            s->invalidated = 1;

        } else {

            printf("%s: Bad width: %i\n", __func__, value);

        }

        break;



    case SVGA_REG_HEIGHT:

        if (value <= SVGA_MAX_HEIGHT) {

            s->new_height = value;

            s->invalidated = 1;

        } else {

            printf("%s: Bad height: %i\n", __func__, value);

        }

        break;



    case SVGA_REG_BITS_PER_PIXEL:

        if (value != 32) {

            printf("%s: Bad bits per pixel: %i bits\n", __func__, value);

            s->config = 0;

            s->invalidated = 1;

        }

        break;



    case SVGA_REG_CONFIG_DONE:

        if (value) {

            s->fifo = (uint32_t *) s->fifo_ptr;

            /* Check range and alignment.  */

            if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) {

                break;

            }

            if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {

                break;

            }

            if (CMD(max) > SVGA_FIFO_SIZE) {

                break;

            }

            if (CMD(max) < CMD(min) + 10 * 1024) {

                break;

            }

            vga_dirty_log_stop(&s->vga);

        }

        s->config = !!value;

        break;



    case SVGA_REG_SYNC:

        s->syncing = 1;

        vmsvga_fifo_run(s); /* Or should we just wait for update_display? */

        break;



    case SVGA_REG_GUEST_ID:

        s->guest = value;

#ifdef VERBOSE

        if (value >= GUEST_OS_BASE && value < GUEST_OS_BASE +

            ARRAY_SIZE(vmsvga_guest_id)) {

            printf("%s: guest runs %s.\n", __func__,

                   vmsvga_guest_id[value - GUEST_OS_BASE]);

        }

#endif

        break;



    case SVGA_REG_CURSOR_ID:

        s->cursor.id = value;

        break;



    case SVGA_REG_CURSOR_X:

        s->cursor.x = value;

        break;



    case SVGA_REG_CURSOR_Y:

        s->cursor.y = value;

        break;



    case SVGA_REG_CURSOR_ON:

        s->cursor.on |= (value == SVGA_CURSOR_ON_SHOW);

        s->cursor.on &= (value != SVGA_CURSOR_ON_HIDE);

#ifdef HW_MOUSE_ACCEL

        if (value <= SVGA_CURSOR_ON_SHOW) {

            dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on);

        }

#endif

        break;



    case SVGA_REG_DEPTH:

    case SVGA_REG_MEM_REGS:

    case SVGA_REG_NUM_DISPLAYS:

    case SVGA_REG_PITCHLOCK:

    case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:

        break;



    default:

        if (s->index >= SVGA_SCRATCH_BASE &&

                s->index < SVGA_SCRATCH_BASE + s->scratch_size) {

            s->scratch[s->index - SVGA_SCRATCH_BASE] = value;

            break;

        }

        printf("%s: Bad register %02x\n", __func__, s->index);

    }

}
