]> Git Repo - qemu.git/blob - hw/jazz_led.c
Fix false positive for AIO on OpenBSD
[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
30 //#define DEBUG_LED
31
32 typedef enum {
33     REDRAW_NONE = 0, REDRAW_SEGMENTS = 1, REDRAW_BACKGROUND = 2,
34 } screen_state_t;
35
36 typedef struct LedState {
37     uint8_t segments;
38     DisplayState *ds;
39     QEMUConsole *console;
40     screen_state_t state;
41 } LedState;
42
43 static uint32_t led_readb(void *opaque, target_phys_addr_t addr)
44 {
45     LedState *s = opaque;
46     uint32_t val;
47
48     switch (addr) {
49         case 0:
50             val = s->segments;
51             break;
52         default:
53 #ifdef DEBUG_LED
54             printf("jazz led: invalid read [0x%x]\n", relative_addr);
55 #endif
56             val = 0;
57     }
58
59     return val;
60 }
61
62 static uint32_t led_readw(void *opaque, target_phys_addr_t addr)
63 {
64     uint32_t v;
65 #ifdef TARGET_WORDS_BIGENDIAN
66     v = led_readb(opaque, addr) << 8;
67     v |= led_readb(opaque, addr + 1);
68 #else
69     v = led_readb(opaque, addr);
70     v |= led_readb(opaque, addr + 1) << 8;
71 #endif
72     return v;
73 }
74
75 static uint32_t led_readl(void *opaque, target_phys_addr_t addr)
76 {
77     uint32_t v;
78 #ifdef TARGET_WORDS_BIGENDIAN
79     v = led_readb(opaque, addr) << 24;
80     v |= led_readb(opaque, addr + 1) << 16;
81     v |= led_readb(opaque, addr + 2) << 8;
82     v |= led_readb(opaque, addr + 3);
83 #else
84     v = led_readb(opaque, addr);
85     v |= led_readb(opaque, addr + 1) << 8;
86     v |= led_readb(opaque, addr + 2) << 16;
87     v |= led_readb(opaque, addr + 3) << 24;
88 #endif
89     return v;
90 }
91
92 static void led_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
93 {
94     LedState *s = opaque;
95
96     switch (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_get_bits_per_pixel(ds) + 7) >> 3;
156     d = ds_get_data(ds) + ds_get_linesize(ds) * 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_get_bits_per_pixel(ds) + 7) >> 3;
185     d = ds_get_data(ds) + ds_get_linesize(ds) * posy1 + bpp * posx;
186     switch(bpp) {
187         case 1:
188             for (y = posy1; y <= posy2; y++) {
189                 *((uint8_t *)d) = color;
190                 d += ds_get_linesize(ds);
191             }
192             break;
193         case 2:
194             for (y = posy1; y <= posy2; y++) {
195                 *((uint16_t *)d) = color;
196                 d += ds_get_linesize(ds);
197             }
198             break;
199         case 4:
200             for (y = posy1; y <= posy2; y++) {
201                 *((uint32_t *)d) = color;
202                 d += ds_get_linesize(ds);
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_get_bits_per_pixel(ds) + 7) >> 3;
219         d1 = ds_get_data(ds);
220         for (y = 0; y < ds_get_height(ds); y++) {
221             memset(d1, 0x00, ds_get_width(ds) * bpp);
222             d1 += ds_get_linesize(ds);
223         }
224     }
225
226     if (s->state & REDRAW_SEGMENTS) {
227         /* set colors according to bpp */
228         switch (ds_get_bits_per_pixel(ds)) {
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_get_width(ds), ds_get_height(ds));
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 static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
287 {
288     LedState *s = opaque;
289     char buf[2];
290
291     dpy_cursor(s->ds, -1, -1);
292     qemu_console_resize(s->console, 2, 1);
293
294     /* TODO: draw the segments */
295     snprintf(buf, 2, "%02hhx\n", s->segments);
296     console_write_ch(chardata++, 0x00200100 | buf[0]);
297     console_write_ch(chardata++, 0x00200100 | buf[1]);
298
299     dpy_update(s->ds, 0, 0, 2, 1);
300 }
301
302 void jazz_led_init(DisplayState *ds, target_phys_addr_t base)
303 {
304     LedState *s;
305     int io;
306
307     s = qemu_mallocz(sizeof(LedState));
308     if (!s)
309         return;
310
311     s->ds = ds;
312     s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
313
314     io = cpu_register_io_memory(0, led_read, led_write, s);
315     cpu_register_physical_memory(base, 1, io);
316
317     s->console = graphic_console_init(ds, jazz_led_update_display,
318                                      jazz_led_invalidate_display,
319                                      jazz_led_screen_dump,
320                                      jazz_led_text_update, s);
321     qemu_console_resize(s->console, 60, 80);
322 }
This page took 0.040944 seconds and 4 git commands to generate.