]> Git Repo - qemu.git/blob - hw/jazz_led.c
jazz-led: use trace framework
[qemu.git] / hw / jazz_led.c
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 "hw.h"
26 #include "mips.h"
27 #include "console.h"
28 #include "pixel_ops.h"
29 #include "trace.h"
30
31 typedef enum {
32     REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
33 } screen_state_t;
34
35 typedef struct LedState {
36     MemoryRegion iomem;
37     uint8_t segments;
38     DisplayState *ds;
39     screen_state_t state;
40 } LedState;
41
42 static uint32_t led_readb(void *opaque, target_phys_addr_t addr)
43 {
44     LedState *s = opaque;
45     uint8_t val;
46
47     switch (addr) {
48         case 0:
49             val = s->segments;
50             break;
51         default:
52             error_report("invalid read at [" TARGET_FMT_plx "]\n", addr);
53             val = 0;
54     }
55
56     trace_jazz_led_read(addr, val);
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     uint8_t new_val = val & 0xff;
95
96     trace_jazz_led_write(addr, new_val);
97
98     switch (addr) {
99         case 0:
100             s->segments = new_val;
101             s->state |= REDRAW_SEGMENTS;
102             break;
103         default:
104             error_report("invalid write of 0x%x at [" TARGET_FMT_plx "]\n",
105                          new_val, addr);
106             break;
107     }
108 }
109
110 static void led_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
111 {
112 #ifdef TARGET_WORDS_BIGENDIAN
113     led_writeb(opaque, addr, (val >> 8) & 0xff);
114     led_writeb(opaque, addr + 1, val & 0xff);
115 #else
116     led_writeb(opaque, addr, val & 0xff);
117     led_writeb(opaque, addr + 1, (val >> 8) & 0xff);
118 #endif
119 }
120
121 static void led_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
122 {
123 #ifdef TARGET_WORDS_BIGENDIAN
124     led_writeb(opaque, addr, (val >> 24) & 0xff);
125     led_writeb(opaque, addr + 1, (val >> 16) & 0xff);
126     led_writeb(opaque, addr + 2, (val >> 8) & 0xff);
127     led_writeb(opaque, addr + 3, val & 0xff);
128 #else
129     led_writeb(opaque, addr, val & 0xff);
130     led_writeb(opaque, addr + 1, (val >> 8) & 0xff);
131     led_writeb(opaque, addr + 2, (val >> 16) & 0xff);
132     led_writeb(opaque, addr + 3, (val >> 24) & 0xff);
133 #endif
134 }
135
136 static const MemoryRegionOps led_ops = {
137     .old_mmio = {
138         .read = { led_readb, led_readw, led_readl, },
139         .write = { led_writeb, led_writew, led_writel, },
140     },
141     .endianness = DEVICE_NATIVE_ENDIAN,
142 };
143
144 /***********************************************************/
145 /* jazz_led display */
146
147 static void draw_horizontal_line(DisplayState *ds, int posy, int posx1, int posx2, uint32_t color)
148 {
149     uint8_t *d;
150     int x, bpp;
151
152     bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
153     d = ds_get_data(ds) + ds_get_linesize(ds) * posy + bpp * posx1;
154     switch(bpp) {
155         case 1:
156             for (x = posx1; x <= posx2; x++) {
157                 *((uint8_t *)d) = color;
158                 d++;
159             }
160             break;
161         case 2:
162             for (x = posx1; x <= posx2; x++) {
163                 *((uint16_t *)d) = color;
164                 d += 2;
165             }
166             break;
167         case 4:
168             for (x = posx1; x <= posx2; x++) {
169                 *((uint32_t *)d) = color;
170                 d += 4;
171             }
172             break;
173     }
174 }
175
176 static void draw_vertical_line(DisplayState *ds, int posx, int posy1, int posy2, uint32_t color)
177 {
178     uint8_t *d;
179     int y, bpp;
180
181     bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
182     d = ds_get_data(ds) + ds_get_linesize(ds) * posy1 + bpp * posx;
183     switch(bpp) {
184         case 1:
185             for (y = posy1; y <= posy2; y++) {
186                 *((uint8_t *)d) = color;
187                 d += ds_get_linesize(ds);
188             }
189             break;
190         case 2:
191             for (y = posy1; y <= posy2; y++) {
192                 *((uint16_t *)d) = color;
193                 d += ds_get_linesize(ds);
194             }
195             break;
196         case 4:
197             for (y = posy1; y <= posy2; y++) {
198                 *((uint32_t *)d) = color;
199                 d += ds_get_linesize(ds);
200             }
201             break;
202     }
203 }
204
205 static void jazz_led_update_display(void *opaque)
206 {
207     LedState *s = opaque;
208     DisplayState *ds = s->ds;
209     uint8_t *d1;
210     uint32_t color_segment, color_led;
211     int y, bpp;
212
213     if (s->state & REDRAW_BACKGROUND) {
214         /* clear screen */
215         bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
216         d1 = ds_get_data(ds);
217         for (y = 0; y < ds_get_height(ds); y++) {
218             memset(d1, 0x00, ds_get_width(ds) * bpp);
219             d1 += ds_get_linesize(ds);
220         }
221     }
222
223     if (s->state & REDRAW_SEGMENTS) {
224         /* set colors according to bpp */
225         switch (ds_get_bits_per_pixel(ds)) {
226             case 8:
227                 color_segment = rgb_to_pixel8(0xaa, 0xaa, 0xaa);
228                 color_led = rgb_to_pixel8(0x00, 0xff, 0x00);
229                 break;
230             case 15:
231                 color_segment = rgb_to_pixel15(0xaa, 0xaa, 0xaa);
232                 color_led = rgb_to_pixel15(0x00, 0xff, 0x00);
233                 break;
234             case 16:
235                 color_segment = rgb_to_pixel16(0xaa, 0xaa, 0xaa);
236                 color_led = rgb_to_pixel16(0x00, 0xff, 0x00);
237             case 24:
238                 color_segment = rgb_to_pixel24(0xaa, 0xaa, 0xaa);
239                 color_led = rgb_to_pixel24(0x00, 0xff, 0x00);
240                 break;
241             case 32:
242                 color_segment = rgb_to_pixel32(0xaa, 0xaa, 0xaa);
243                 color_led = rgb_to_pixel32(0x00, 0xff, 0x00);
244                 break;
245             default:
246                 return;
247         }
248
249         /* display segments */
250         draw_horizontal_line(ds, 40, 10, 40, (s->segments & 0x02) ? color_segment : 0);
251         draw_vertical_line(ds, 10, 10, 40, (s->segments & 0x04) ? color_segment : 0);
252         draw_vertical_line(ds, 10, 40, 70, (s->segments & 0x08) ? color_segment : 0);
253         draw_horizontal_line(ds, 70, 10, 40, (s->segments & 0x10) ? color_segment : 0);
254         draw_vertical_line(ds, 40, 40, 70, (s->segments & 0x20) ? color_segment : 0);
255         draw_vertical_line(ds, 40, 10, 40, (s->segments & 0x40) ? color_segment : 0);
256         draw_horizontal_line(ds, 10, 10, 40, (s->segments & 0x80) ? color_segment : 0);
257
258         /* display led */
259         if (!(s->segments & 0x01))
260             color_led = 0; /* black */
261         draw_horizontal_line(ds, 68, 50, 50, color_led);
262         draw_horizontal_line(ds, 69, 49, 51, color_led);
263         draw_horizontal_line(ds, 70, 48, 52, color_led);
264         draw_horizontal_line(ds, 71, 49, 51, color_led);
265         draw_horizontal_line(ds, 72, 50, 50, color_led);
266     }
267
268     s->state = REDRAW_NONE;
269     dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
270 }
271
272 static void jazz_led_invalidate_display(void *opaque)
273 {
274     LedState *s = opaque;
275     s->state |= REDRAW_SEGMENTS | REDRAW_BACKGROUND;
276 }
277
278 static void jazz_led_screen_dump(void *opaque, const char *filename)
279 {
280     printf("jazz_led_screen_dump() not implemented\n");
281 }
282
283 static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
284 {
285     LedState *s = opaque;
286     char buf[2];
287
288     dpy_cursor(s->ds, -1, -1);
289     qemu_console_resize(s->ds, 2, 1);
290
291     /* TODO: draw the segments */
292     snprintf(buf, 2, "%02hhx\n", s->segments);
293     console_write_ch(chardata++, 0x00200100 | buf[0]);
294     console_write_ch(chardata++, 0x00200100 | buf[1]);
295
296     dpy_update(s->ds, 0, 0, 2, 1);
297 }
298
299 void jazz_led_init(MemoryRegion *address_space, target_phys_addr_t base)
300 {
301     LedState *s;
302
303     s = g_malloc0(sizeof(LedState));
304
305     s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
306
307     memory_region_init_io(&s->iomem, &led_ops, s, "led", 1);
308     memory_region_add_subregion(address_space, base, &s->iomem);
309
310     s->ds = graphic_console_init(jazz_led_update_display,
311                                  jazz_led_invalidate_display,
312                                  jazz_led_screen_dump,
313                                  jazz_led_text_update, s);
314     qemu_console_resize(s->ds, 60, 80);
315 }
This page took 0.04604 seconds and 4 git commands to generate.