Commit 31211df14dd887cd9976722dd527a4b592dd5a07

Authored by ths
1 parent 611d7189

Add a 7 segments + led display, by Herve Poussineau.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3015 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -438,6 +438,7 @@ endif
438 438 ifeq ($(TARGET_BASE_ARCH), mips)
439 439 VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o
440 440 VL_OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
  441 +VL_OBJS+= jazz_led.o
441 442 VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
442 443 VL_OBJS+= piix_pci.o smbus_eeprom.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
443 444 CPPFLAGS += -DHAS_AUDIO
... ...
hw/jazz_led.c 0 → 100644
  1 +/*
  2 + * QEMU JAZZ LED emulator.
  3 + *
  4 + * Copyright (c) 2007 Hervé Poussineau
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include "vl.h"
  26 +#include "pixel_ops.h"
  27 +
  28 +//#define DEBUG_LED
  29 +
  30 +typedef enum {
  31 + REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
  32 +} screen_state_t;
  33 +
  34 +typedef struct LedState {
  35 + target_phys_addr_t base;
  36 + uint8_t segments;
  37 + DisplayState *ds;
  38 + screen_state_t state;
  39 +} LedState;
  40 +
  41 +static uint32_t led_readb(void *opaque, target_phys_addr_t addr)
  42 +{
  43 + LedState *s = opaque;
  44 + int relative_addr = addr - s->base;
  45 + uint32_t val;
  46 +
  47 + switch (relative_addr) {
  48 + case 0:
  49 + val = s->segments;
  50 + break;
  51 + default:
  52 +#ifdef DEBUG_LED
  53 + printf("jazz led: invalid read [0x%x]\n", relative_addr);
  54 +#endif
  55 + val = 0;
  56 + }
  57 +
  58 + return val;
  59 +}
  60 +
  61 +static uint32_t led_readw(void *opaque, target_phys_addr_t addr)
  62 +{
  63 + uint32_t v;
  64 +#ifdef TARGET_WORDS_BIGENDIAN
  65 + v = led_readb(opaque, addr) << 8;
  66 + v |= led_readb(opaque, addr + 1);
  67 +#else
  68 + v = led_readb(opaque, addr);
  69 + v |= led_readb(opaque, addr + 1) << 8;
  70 +#endif
  71 + return v;
  72 +}
  73 +
  74 +static uint32_t led_readl(void *opaque, target_phys_addr_t addr)
  75 +{
  76 + uint32_t v;
  77 +#ifdef TARGET_WORDS_BIGENDIAN
  78 + v = led_readb(opaque, addr) << 24;
  79 + v |= led_readb(opaque, addr + 1) << 16;
  80 + v |= led_readb(opaque, addr + 2) << 8;
  81 + v |= led_readb(opaque, addr + 3);
  82 +#else
  83 + v = led_readb(opaque, addr);
  84 + v |= led_readb(opaque, addr + 1) << 8;
  85 + v |= led_readb(opaque, addr + 2) << 16;
  86 + v |= led_readb(opaque, addr + 3) << 24;
  87 +#endif
  88 + return v;
  89 +}
  90 +
  91 +static void led_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  92 +{
  93 + LedState *s = opaque;
  94 + int relative_addr = addr - s->base;
  95 +
  96 + switch (relative_addr) {
  97 + case 0:
  98 + s->segments = val;
  99 + s->state |= REDRAW_SEGMENTS;
  100 + break;
  101 + default:
  102 +#ifdef DEBUG_LED
  103 + printf("jazz led: invalid write of 0x%02x at [0x%x]\n", val, relative_addr);
  104 +#endif
  105 + break;
  106 + }
  107 +}
  108 +
  109 +static void led_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  110 +{
  111 +#ifdef TARGET_WORDS_BIGENDIAN
  112 + led_writeb(opaque, addr, (val >> 8) & 0xff);
  113 + led_writeb(opaque, addr + 1, val & 0xff);
  114 +#else
  115 + led_writeb(opaque, addr, val & 0xff);
  116 + led_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  117 +#endif
  118 +}
  119 +
  120 +static void led_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  121 +{
  122 +#ifdef TARGET_WORDS_BIGENDIAN
  123 + led_writeb(opaque, addr, (val >> 24) & 0xff);
  124 + led_writeb(opaque, addr + 1, (val >> 16) & 0xff);
  125 + led_writeb(opaque, addr + 2, (val >> 8) & 0xff);
  126 + led_writeb(opaque, addr + 3, val & 0xff);
  127 +#else
  128 + led_writeb(opaque, addr, val & 0xff);
  129 + led_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  130 + led_writeb(opaque, addr + 2, (val >> 16) & 0xff);
  131 + led_writeb(opaque, addr + 3, (val >> 24) & 0xff);
  132 +#endif
  133 +}
  134 +
  135 +static CPUReadMemoryFunc *led_read[3] = {
  136 + led_readb,
  137 + led_readw,
  138 + led_readl,
  139 +};
  140 +
  141 +static CPUWriteMemoryFunc *led_write[3] = {
  142 + led_writeb,
  143 + led_writew,
  144 + led_writel,
  145 +};
  146 +
  147 +/***********************************************************/
  148 +/* jazz_led display */
  149 +
  150 +static void draw_horizontal_line(DisplayState *ds, int posy, int posx1, int posx2, uint32_t color)
  151 +{
  152 + uint8_t *d;
  153 + int x, bpp;
  154 +
  155 + bpp = (ds->depth + 7) >> 3;
  156 + d = ds->data + ds->linesize * posy + bpp * posx1;
  157 + switch(bpp) {
  158 + case 1:
  159 + for (x = posx1; x <= posx2; x++) {
  160 + *((uint8_t *)d) = color;
  161 + d++;
  162 + }
  163 + break;
  164 + case 2:
  165 + for (x = posx1; x <= posx2; x++) {
  166 + *((uint16_t *)d) = color;
  167 + d += 2;
  168 + }
  169 + break;
  170 + case 4:
  171 + for (x = posx1; x <= posx2; x++) {
  172 + *((uint32_t *)d) = color;
  173 + d += 4;
  174 + }
  175 + break;
  176 + }
  177 +}
  178 +
  179 +static void draw_vertical_line(DisplayState *ds, int posx, int posy1, int posy2, uint32_t color)
  180 +{
  181 + uint8_t *d;
  182 + int y, bpp;
  183 +
  184 + bpp = (ds->depth + 7) >> 3;
  185 + d = ds->data + ds->linesize * posy1 + bpp * posx;
  186 + switch(bpp) {
  187 + case 1:
  188 + for (y = posy1; y <= posy2; y++) {
  189 + *((uint8_t *)d) = color;
  190 + d += ds->linesize;
  191 + }
  192 + break;
  193 + case 2:
  194 + for (y = posy1; y <= posy2; y++) {
  195 + *((uint16_t *)d) = color;
  196 + d += ds->linesize;
  197 + }
  198 + break;
  199 + case 4:
  200 + for (y = posy1; y <= posy2; y++) {
  201 + *((uint32_t *)d) = color;
  202 + d += ds->linesize;
  203 + }
  204 + break;
  205 + }
  206 +}
  207 +
  208 +static void jazz_led_update_display(void *opaque)
  209 +{
  210 + LedState *s = opaque;
  211 + DisplayState *ds = s->ds;
  212 + uint8_t *d1;
  213 + uint32_t color_segment, color_led;
  214 + int y, bpp;
  215 +
  216 + if (s->state & REDRAW_BACKGROUND) {
  217 + /* clear screen */
  218 + bpp = (ds->depth + 7) >> 3;
  219 + d1 = ds->data;
  220 + for (y = 0; y < ds->height; y++) {
  221 + memset(d1, 0x00, ds->width * bpp);
  222 + d1 += ds->linesize;
  223 + }
  224 + }
  225 +
  226 + if (s->state & REDRAW_SEGMENTS) {
  227 + /* set colors according to bpp */
  228 + switch (ds->depth) {
  229 + case 8:
  230 + color_segment = rgb_to_pixel8(0xaa, 0xaa, 0xaa);
  231 + color_led = rgb_to_pixel8(0x00, 0xff, 0x00);
  232 + break;
  233 + case 15:
  234 + color_segment = rgb_to_pixel15(0xaa, 0xaa, 0xaa);
  235 + color_led = rgb_to_pixel15(0x00, 0xff, 0x00);
  236 + break;
  237 + case 16:
  238 + color_segment = rgb_to_pixel16(0xaa, 0xaa, 0xaa);
  239 + color_led = rgb_to_pixel16(0x00, 0xff, 0x00);
  240 + case 24:
  241 + color_segment = rgb_to_pixel24(0xaa, 0xaa, 0xaa);
  242 + color_led = rgb_to_pixel24(0x00, 0xff, 0x00);
  243 + break;
  244 + case 32:
  245 + color_segment = rgb_to_pixel32(0xaa, 0xaa, 0xaa);
  246 + color_led = rgb_to_pixel32(0x00, 0xff, 0x00);
  247 + break;
  248 + default:
  249 + return;
  250 + }
  251 +
  252 + /* display segments */
  253 + draw_horizontal_line(ds, 40, 10, 40, (s->segments & 0x02) ? color_segment : 0);
  254 + draw_vertical_line(ds, 10, 10, 40, (s->segments & 0x04) ? color_segment : 0);
  255 + draw_vertical_line(ds, 10, 40, 70, (s->segments & 0x08) ? color_segment : 0);
  256 + draw_horizontal_line(ds, 70, 10, 40, (s->segments & 0x10) ? color_segment : 0);
  257 + draw_vertical_line(ds, 40, 40, 70, (s->segments & 0x20) ? color_segment : 0);
  258 + draw_vertical_line(ds, 40, 10, 40, (s->segments & 0x40) ? color_segment : 0);
  259 + draw_horizontal_line(ds, 10, 10, 40, (s->segments & 0x80) ? color_segment : 0);
  260 +
  261 + /* display led */
  262 + if (!(s->segments & 0x01))
  263 + color_led = 0; /* black */
  264 + draw_horizontal_line(ds, 68, 50, 50, color_led);
  265 + draw_horizontal_line(ds, 69, 49, 51, color_led);
  266 + draw_horizontal_line(ds, 70, 48, 52, color_led);
  267 + draw_horizontal_line(ds, 71, 49, 51, color_led);
  268 + draw_horizontal_line(ds, 72, 50, 50, color_led);
  269 + }
  270 +
  271 + s->state = REDRAW_NONE;
  272 + dpy_update(ds, 0, 0, ds->width, ds->height);
  273 +}
  274 +
  275 +static void jazz_led_invalidate_display(void *opaque)
  276 +{
  277 + LedState *s = opaque;
  278 + s->state |= REDRAW_SEGMENTS | REDRAW_BACKGROUND;
  279 +}
  280 +
  281 +static void jazz_led_screen_dump(void *opaque, const char *filename)
  282 +{
  283 + printf("jazz_led_screen_dump() not implemented\n");
  284 +}
  285 +
  286 +void jazz_led_init(DisplayState *ds, target_phys_addr_t base)
  287 +{
  288 + LedState *s;
  289 + int io;
  290 +
  291 + s = qemu_mallocz(sizeof(LedState));
  292 + if (!s)
  293 + return;
  294 +
  295 + s->base = base;
  296 + s->ds = ds;
  297 + s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
  298 +
  299 + io = cpu_register_io_memory(0, led_read, led_write, s);
  300 + cpu_register_physical_memory(s->base, 1, io);
  301 +
  302 + graphic_console_init(ds, jazz_led_update_display, jazz_led_invalidate_display, jazz_led_screen_dump, s);
  303 +}
... ...
hw/mips_pica61.c
... ... @@ -168,6 +168,9 @@ void mips_pica61_init (int ram_size, int vga_ram_size, int boot_device,
168 168 * but let's do with what Qemu currenly emulates... */
169 169 isa_vga_mm_init(ds, phys_ram_base + ram_size, ram_size, vga_ram_size,
170 170 0x40000000, 0x60000000, 0);
  171 +
  172 + /* LED indicator */
  173 + jazz_led_init(ds, 0x8000f000);
171 174 }
172 175  
173 176 QEMUMachine mips_pica61_machine = {
... ...
... ... @@ -1128,6 +1128,9 @@ int pit_get_initial_count(PITState *pit, int channel);
1128 1128 int pit_get_mode(PITState *pit, int channel);
1129 1129 int pit_get_out(PITState *pit, int channel, int64_t current_time);
1130 1130  
  1131 +/* jazz_led.c */
  1132 +extern void jazz_led_init(DisplayState *ds, target_phys_addr_t base);
  1133 +
1131 1134 /* pcspk.c */
1132 1135 void pcspk_init(PITState *);
1133 1136 int pcspk_audio_init(AudioState *, qemu_irq *pic);
... ...