diff options
Diffstat (limited to 'hw/display/macfb.c')
-rw-r--r-- | hw/display/macfb.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/hw/display/macfb.c b/hw/display/macfb.c index c9b468c10e..2f8e016566 100644 --- a/hw/display/macfb.c +++ b/hw/display/macfb.c @@ -476,7 +476,8 @@ static void macfb_update_display(void *opaque) static void macfb_update_irq(MacfbState *s) { - uint32_t irq_state = s->irq_state & s->irq_mask; + uint32_t irq_state = s->regs[DAFB_INTR_STAT >> 2] & + s->regs[DAFB_INTR_MASK >> 2]; if (irq_state) { qemu_irq_raise(s->irq); @@ -496,7 +497,7 @@ static void macfb_vbl_timer(void *opaque) MacfbState *s = opaque; int64_t next_vbl; - s->irq_state |= DAFB_INTR_VBL; + s->regs[DAFB_INTR_STAT >> 2] |= DAFB_INTR_VBL; macfb_update_irq(s); /* 60 Hz irq */ @@ -530,14 +531,16 @@ static uint64_t macfb_ctrl_read(void *opaque, case DAFB_MODE_VADDR2: case DAFB_MODE_CTRL1: case DAFB_MODE_CTRL2: - val = s->regs[addr >> 2]; - break; case DAFB_INTR_STAT: - val = s->irq_state; + val = s->regs[addr >> 2]; break; case DAFB_MODE_SENSE: val = macfb_sense_read(s); break; + default: + if (addr < MACFB_CTRL_TOPADDR) { + val = s->regs[addr >> 2]; + } } trace_macfb_ctrl_read(addr, val, size); @@ -568,7 +571,7 @@ static void macfb_ctrl_write(void *opaque, macfb_sense_write(s, val); break; case DAFB_INTR_MASK: - s->irq_mask = val; + s->regs[addr >> 2] = val; if (val & DAFB_INTR_VBL) { next_vbl = macfb_next_vbl(); timer_mod(s->vbl_timer, next_vbl); @@ -577,12 +580,12 @@ static void macfb_ctrl_write(void *opaque, } break; case DAFB_INTR_CLEAR: - s->irq_state &= ~DAFB_INTR_VBL; + s->regs[DAFB_INTR_STAT >> 2] &= ~DAFB_INTR_VBL; macfb_update_irq(s); break; case DAFB_RESET: s->palette_current = 0; - s->irq_state &= ~DAFB_INTR_VBL; + s->regs[DAFB_INTR_STAT >> 2] &= ~DAFB_INTR_VBL; macfb_update_irq(s); break; case DAFB_LUT: @@ -593,6 +596,10 @@ static void macfb_ctrl_write(void *opaque, macfb_invalidate_display(s); } break; + default: + if (addr < MACFB_CTRL_TOPADDR) { + s->regs[addr >> 2] = val; + } } trace_macfb_ctrl_write(addr, val, size); @@ -618,9 +625,11 @@ static const VMStateDescription vmstate_macfb = { .minimum_version_id = 1, .post_load = macfb_post_load, .fields = (VMStateField[]) { + VMSTATE_UINT8(type, MacfbState), VMSTATE_UINT8_ARRAY(color_palette, MacfbState, 256 * 3), VMSTATE_UINT32(palette_current, MacfbState), VMSTATE_UINT32_ARRAY(regs, MacfbState, MACFB_NUM_REGS), + VMSTATE_TIMER_PTR(vbl_timer, MacfbState), VMSTATE_END_OF_LIST() } }; @@ -646,6 +655,14 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp) return false; } + /* + * Set mode control registers to match the mode found above so that + * macfb_mode_write() does the right thing if no MacOS toolbox ROM + * is present to initialise them + */ + s->regs[DAFB_MODE_CTRL1 >> 2] = s->mode->mode_ctrl1; + s->regs[DAFB_MODE_CTRL2 >> 2] = s->mode->mode_ctrl2; + s->con = graphic_console_init(dev, 0, &macfb_ops, s); surface = qemu_console_surface(s->con); @@ -746,6 +763,16 @@ static Property macfb_sysbus_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_macfb_sysbus = { + .name = "macfb-sysbus", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(macfb, MacfbSysBusState, 1, vmstate_macfb, MacfbState), + VMSTATE_END_OF_LIST() + } +}; + static Property macfb_nubus_properties[] = { DEFINE_PROP_UINT32("width", MacfbNubusState, macfb.width, 640), DEFINE_PROP_UINT32("height", MacfbNubusState, macfb.height, 480), @@ -755,6 +782,16 @@ static Property macfb_nubus_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_macfb_nubus = { + .name = "macfb-nubus", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(macfb, MacfbNubusState, 1, vmstate_macfb, MacfbState), + VMSTATE_END_OF_LIST() + } +}; + static void macfb_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -762,7 +799,7 @@ static void macfb_sysbus_class_init(ObjectClass *klass, void *data) dc->realize = macfb_sysbus_realize; dc->desc = "SysBus Macintosh framebuffer"; dc->reset = macfb_sysbus_reset; - dc->vmsd = &vmstate_macfb; + dc->vmsd = &vmstate_macfb_sysbus; device_class_set_props(dc, macfb_sysbus_properties); } @@ -777,7 +814,7 @@ static void macfb_nubus_class_init(ObjectClass *klass, void *data) &ndc->parent_unrealize); dc->desc = "Nubus Macintosh framebuffer"; dc->reset = macfb_nubus_reset; - dc->vmsd = &vmstate_macfb; + dc->vmsd = &vmstate_macfb_nubus; set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); device_class_set_props(dc, macfb_nubus_properties); } |