X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/87ecb68bdf8a3e40ef885ddbb7ca1797dca40ebf..1422e32db51ff2b1194fb24a6201c4310be5667d:/hw/jazz_led.c?ds=sidebyside diff --git a/hw/jazz_led.c b/hw/jazz_led.c index a0eea26b5a..09c77429e8 100644 --- a/hw/jazz_led.c +++ b/hw/jazz_led.c @@ -1,7 +1,7 @@ /* * QEMU JAZZ LED emulator. * - * Copyright (c) 2007 Hervé Poussineau + * Copyright (c) 2007-2012 Herve Poussineau * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,128 +22,54 @@ * THE SOFTWARE. */ -#include "hw.h" -#include "mips.h" +#include "qemu-common.h" #include "console.h" #include "pixel_ops.h" - -//#define DEBUG_LED +#include "trace.h" +#include "sysbus.h" typedef enum { REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2, } screen_state_t; typedef struct LedState { - target_phys_addr_t base; + SysBusDevice busdev; + MemoryRegion iomem; uint8_t segments; DisplayState *ds; screen_state_t state; } LedState; -static uint32_t led_readb(void *opaque, target_phys_addr_t addr) +static uint64_t jazz_led_read(void *opaque, hwaddr addr, + unsigned int size) { LedState *s = opaque; - int relative_addr = addr - s->base; - uint32_t val; + uint8_t val; - switch (relative_addr) { - case 0: - val = s->segments; - break; - default: -#ifdef DEBUG_LED - printf("jazz led: invalid read [0x%x]\n", relative_addr); -#endif - val = 0; - } + val = s->segments; + trace_jazz_led_read(addr, val); return val; } -static uint32_t led_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; -#ifdef TARGET_WORDS_BIGENDIAN - v = led_readb(opaque, addr) << 8; - v |= led_readb(opaque, addr + 1); -#else - v = led_readb(opaque, addr); - v |= led_readb(opaque, addr + 1) << 8; -#endif - return v; -} - -static uint32_t led_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; -#ifdef TARGET_WORDS_BIGENDIAN - v = led_readb(opaque, addr) << 24; - v |= led_readb(opaque, addr + 1) << 16; - v |= led_readb(opaque, addr + 2) << 8; - v |= led_readb(opaque, addr + 3); -#else - v = led_readb(opaque, addr); - v |= led_readb(opaque, addr + 1) << 8; - v |= led_readb(opaque, addr + 2) << 16; - v |= led_readb(opaque, addr + 3) << 24; -#endif - return v; -} - -static void led_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void jazz_led_write(void *opaque, hwaddr addr, + uint64_t val, unsigned int size) { LedState *s = opaque; - int relative_addr = addr - s->base; - - switch (relative_addr) { - case 0: - s->segments = val; - s->state |= REDRAW_SEGMENTS; - break; - default: -#ifdef DEBUG_LED - printf("jazz led: invalid write of 0x%02x at [0x%x]\n", val, relative_addr); -#endif - break; - } -} + uint8_t new_val = val & 0xff; -static void led_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ -#ifdef TARGET_WORDS_BIGENDIAN - led_writeb(opaque, addr, (val >> 8) & 0xff); - led_writeb(opaque, addr + 1, val & 0xff); -#else - led_writeb(opaque, addr, val & 0xff); - led_writeb(opaque, addr + 1, (val >> 8) & 0xff); -#endif -} + trace_jazz_led_write(addr, new_val); -static void led_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ -#ifdef TARGET_WORDS_BIGENDIAN - led_writeb(opaque, addr, (val >> 24) & 0xff); - led_writeb(opaque, addr + 1, (val >> 16) & 0xff); - led_writeb(opaque, addr + 2, (val >> 8) & 0xff); - led_writeb(opaque, addr + 3, val & 0xff); -#else - led_writeb(opaque, addr, val & 0xff); - led_writeb(opaque, addr + 1, (val >> 8) & 0xff); - led_writeb(opaque, addr + 2, (val >> 16) & 0xff); - led_writeb(opaque, addr + 3, (val >> 24) & 0xff); -#endif + s->segments = new_val; + s->state |= REDRAW_SEGMENTS; } -static CPUReadMemoryFunc *led_read[3] = { - led_readb, - led_readw, - led_readl, -}; - -static CPUWriteMemoryFunc *led_write[3] = { - led_writeb, - led_writew, - led_writel, +static const MemoryRegionOps led_ops = { + .read = jazz_led_read, + .write = jazz_led_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl.min_access_size = 1, + .impl.max_access_size = 1, }; /***********************************************************/ @@ -154,8 +80,8 @@ static void draw_horizontal_line(DisplayState *ds, int posy, int posx1, int posx uint8_t *d; int x, bpp; - bpp = (ds->depth + 7) >> 3; - d = ds->data + ds->linesize * posy + bpp * posx1; + bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3; + d = ds_get_data(ds) + ds_get_linesize(ds) * posy + bpp * posx1; switch(bpp) { case 1: for (x = posx1; x <= posx2; x++) { @@ -183,25 +109,25 @@ static void draw_vertical_line(DisplayState *ds, int posx, int posy1, int posy2, uint8_t *d; int y, bpp; - bpp = (ds->depth + 7) >> 3; - d = ds->data + ds->linesize * posy1 + bpp * posx; + bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3; + d = ds_get_data(ds) + ds_get_linesize(ds) * posy1 + bpp * posx; switch(bpp) { case 1: for (y = posy1; y <= posy2; y++) { *((uint8_t *)d) = color; - d += ds->linesize; + d += ds_get_linesize(ds); } break; case 2: for (y = posy1; y <= posy2; y++) { *((uint16_t *)d) = color; - d += ds->linesize; + d += ds_get_linesize(ds); } break; case 4: for (y = posy1; y <= posy2; y++) { *((uint32_t *)d) = color; - d += ds->linesize; + d += ds_get_linesize(ds); } break; } @@ -217,17 +143,17 @@ static void jazz_led_update_display(void *opaque) if (s->state & REDRAW_BACKGROUND) { /* clear screen */ - bpp = (ds->depth + 7) >> 3; - d1 = ds->data; - for (y = 0; y < ds->height; y++) { - memset(d1, 0x00, ds->width * bpp); - d1 += ds->linesize; + bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3; + d1 = ds_get_data(ds); + for (y = 0; y < ds_get_height(ds); y++) { + memset(d1, 0x00, ds_get_width(ds) * bpp); + d1 += ds_get_linesize(ds); } } if (s->state & REDRAW_SEGMENTS) { /* set colors according to bpp */ - switch (ds->depth) { + switch (ds_get_bits_per_pixel(ds)) { case 8: color_segment = rgb_to_pixel8(0xaa, 0xaa, 0xaa); color_led = rgb_to_pixel8(0x00, 0xff, 0x00); @@ -271,7 +197,7 @@ static void jazz_led_update_display(void *opaque) } s->state = REDRAW_NONE; - dpy_update(ds, 0, 0, ds->width, ds->height); + dpy_gfx_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds)); } static void jazz_led_invalidate_display(void *opaque) @@ -280,26 +206,87 @@ static void jazz_led_invalidate_display(void *opaque) s->state |= REDRAW_SEGMENTS | REDRAW_BACKGROUND; } -static void jazz_led_screen_dump(void *opaque, const char *filename) +static void jazz_led_text_update(void *opaque, console_ch_t *chardata) { - printf("jazz_led_screen_dump() not implemented\n"); + LedState *s = opaque; + char buf[2]; + + dpy_text_cursor(s->ds, -1, -1); + qemu_console_resize(s->ds, 2, 1); + + /* TODO: draw the segments */ + snprintf(buf, 2, "%02hhx\n", s->segments); + console_write_ch(chardata++, 0x00200100 | buf[0]); + console_write_ch(chardata++, 0x00200100 | buf[1]); + + dpy_text_update(s->ds, 0, 0, 2, 1); } -void jazz_led_init(DisplayState *ds, target_phys_addr_t base) +static int jazz_led_post_load(void *opaque, int version_id) { - LedState *s; - int io; + /* force refresh */ + jazz_led_invalidate_display(opaque); + + return 0; +} + +static const VMStateDescription vmstate_jazz_led = { + .name = "jazz-led", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = jazz_led_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT8(segments, LedState), + VMSTATE_END_OF_LIST() + } +}; - s = qemu_mallocz(sizeof(LedState)); - if (!s) - return; +static int jazz_led_init(SysBusDevice *dev) +{ + LedState *s = FROM_SYSBUS(LedState, dev); + + memory_region_init_io(&s->iomem, &led_ops, s, "led", 1); + sysbus_init_mmio(dev, &s->iomem); + + s->ds = graphic_console_init(jazz_led_update_display, + jazz_led_invalidate_display, + NULL, + jazz_led_text_update, s); + + return 0; +} - s->base = base; - s->ds = ds; +static void jazz_led_reset(DeviceState *d) +{ + LedState *s = DO_UPCAST(LedState, busdev.qdev, d); + + s->segments = 0; s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND; + qemu_console_resize(s->ds, 60, 80); +} + +static void jazz_led_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - io = cpu_register_io_memory(0, led_read, led_write, s); - cpu_register_physical_memory(s->base, 1, io); + k->init = jazz_led_init; + dc->desc = "Jazz LED display", + dc->vmsd = &vmstate_jazz_led; + dc->reset = jazz_led_reset; +} + +static TypeInfo jazz_led_info = { + .name = "jazz-led", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(LedState), + .class_init = jazz_led_class_init, +}; - graphic_console_init(ds, jazz_led_update_display, jazz_led_invalidate_display, jazz_led_screen_dump, s); +static void jazz_led_register(void) +{ + type_register_static(&jazz_led_info); } + +type_init(jazz_led_register);