source: trunk/packages/xen-common/xen-common/tools/ioemu/hw/vga_template.h @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 15.8 KB
Line 
1/*
2 * QEMU VGA Emulator templates
3 *
4 * Copyright (c) 2003 Fabrice Bellard
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#if DEPTH == 8
26#define BPP 1
27#define PIXEL_TYPE uint8_t
28#elif DEPTH == 15 || DEPTH == 16
29#define BPP 2
30#define PIXEL_TYPE uint16_t
31#elif DEPTH == 32
32#define BPP 4
33#define PIXEL_TYPE uint32_t
34#else
35#error unsupport depth
36#endif
37
38#ifdef BGR_FORMAT
39#define PIXEL_NAME glue(DEPTH, bgr)
40#else
41#define PIXEL_NAME DEPTH
42#endif /* BGR_FORMAT */
43
44#if DEPTH != 15 && !defined(BGR_FORMAT)
45
46static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, 
47                                                     uint32_t font_data,
48                                                     uint32_t xorcol, 
49                                                     uint32_t bgcol)
50{
51#if BPP == 1
52        ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
53        ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
54#elif BPP == 2
55        ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
56        ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
57        ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
58        ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
59#else
60        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
61        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
62        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
63        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
64        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
65        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
66        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
67        ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
68#endif
69}
70
71static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
72                                          const uint8_t *font_ptr, int h,
73                                          uint32_t fgcol, uint32_t bgcol)
74{
75    uint32_t font_data, xorcol;
76   
77    xorcol = bgcol ^ fgcol;
78    do {
79        font_data = font_ptr[0];
80        glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
81        font_ptr += 4;
82        d += linesize;
83    } while (--h);
84}
85
86static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
87                                          const uint8_t *font_ptr, int h,
88                                          uint32_t fgcol, uint32_t bgcol)
89{
90    uint32_t font_data, xorcol;
91   
92    xorcol = bgcol ^ fgcol;
93    do {
94        font_data = font_ptr[0];
95        glue(vga_draw_glyph_line_, DEPTH)(d, 
96                                          expand4to8[font_data >> 4], 
97                                          xorcol, bgcol);
98        glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP, 
99                                          expand4to8[font_data & 0x0f], 
100                                          xorcol, bgcol);
101        font_ptr += 4;
102        d += linesize;
103    } while (--h);
104}
105
106static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
107                                          const uint8_t *font_ptr, int h, 
108                                          uint32_t fgcol, uint32_t bgcol, int dup9)
109{
110    uint32_t font_data, xorcol, v;
111   
112    xorcol = bgcol ^ fgcol;
113    do {
114        font_data = font_ptr[0];
115#if BPP == 1
116        cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
117        v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
118        cpu_to_32wu(((uint32_t *)d)+1, v);
119        if (dup9)
120            ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
121        else
122            ((uint8_t *)d)[8] = bgcol;
123       
124#elif BPP == 2
125        cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
126        cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
127        cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
128        v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
129        cpu_to_32wu(((uint32_t *)d)+3, v);
130        if (dup9)
131            ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
132        else
133            ((uint16_t *)d)[8] = bgcol;
134#else
135        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
136        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
137        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
138        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
139        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
140        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
141        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
142        v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
143        ((uint32_t *)d)[7] = v;
144        if (dup9)
145            ((uint32_t *)d)[8] = v;
146        else
147            ((uint32_t *)d)[8] = bgcol;
148#endif
149        font_ptr += 4;
150        d += linesize;
151    } while (--h);
152}
153
154/*
155 * 4 color mode
156 */
157static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d, 
158                                         const uint8_t *s, int width)
159{
160    uint32_t plane_mask, *palette, data, v;
161    int x;
162
163    palette = s1->last_palette;
164    plane_mask = mask16[s1->ar[0x12] & 0xf];
165    width >>= 3;
166    for(x = 0; x < width; x++) {
167        data = ((uint32_t *)s)[0];
168        data &= plane_mask;
169        v = expand2[GET_PLANE(data, 0)];
170        v |= expand2[GET_PLANE(data, 2)] << 2;
171        ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
172        ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
173        ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
174        ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
175
176        v = expand2[GET_PLANE(data, 1)];
177        v |= expand2[GET_PLANE(data, 3)] << 2;
178        ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
179        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
180        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
181        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
182        d += BPP * 8;
183        s += 4;
184    }
185}
186
187#if BPP == 1
188#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
189#elif BPP == 2
190#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
191#else
192#define PUT_PIXEL2(d, n, v) \
193((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
194#endif
195
196/*
197 * 4 color mode, dup2 horizontal
198 */
199static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d, 
200                                           const uint8_t *s, int width)
201{
202    uint32_t plane_mask, *palette, data, v;
203    int x;
204
205    palette = s1->last_palette;
206    plane_mask = mask16[s1->ar[0x12] & 0xf];
207    width >>= 3;
208    for(x = 0; x < width; x++) {
209        data = ((uint32_t *)s)[0];
210        data &= plane_mask;
211        v = expand2[GET_PLANE(data, 0)];
212        v |= expand2[GET_PLANE(data, 2)] << 2;
213        PUT_PIXEL2(d, 0, palette[v >> 12]);
214        PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
215        PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
216        PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
217
218        v = expand2[GET_PLANE(data, 1)];
219        v |= expand2[GET_PLANE(data, 3)] << 2;
220        PUT_PIXEL2(d, 4, palette[v >> 12]);
221        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
222        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
223        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
224        d += BPP * 16;
225        s += 4;
226    }
227}
228
229/*
230 * 16 color mode
231 */
232static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d, 
233                                         const uint8_t *s, int width)
234{
235    uint32_t plane_mask, data, v, *palette;
236    int x;
237
238    palette = s1->last_palette;
239    plane_mask = mask16[s1->ar[0x12] & 0xf];
240    width >>= 3;
241    for(x = 0; x < width; x++) {
242        data = ((uint32_t *)s)[0];
243        data &= plane_mask;
244        v = expand4[GET_PLANE(data, 0)];
245        v |= expand4[GET_PLANE(data, 1)] << 1;
246        v |= expand4[GET_PLANE(data, 2)] << 2;
247        v |= expand4[GET_PLANE(data, 3)] << 3;
248        ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
249        ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
250        ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
251        ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
252        ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
253        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
254        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
255        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
256        d += BPP * 8;
257        s += 4;
258    }
259}
260
261/*
262 * 16 color mode, dup2 horizontal
263 */
264static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d, 
265                                           const uint8_t *s, int width)
266{
267    uint32_t plane_mask, data, v, *palette;
268    int x;
269
270    palette = s1->last_palette;
271    plane_mask = mask16[s1->ar[0x12] & 0xf];
272    width >>= 3;
273    for(x = 0; x < width; x++) {
274        data = ((uint32_t *)s)[0];
275        data &= plane_mask;
276        v = expand4[GET_PLANE(data, 0)];
277        v |= expand4[GET_PLANE(data, 1)] << 1;
278        v |= expand4[GET_PLANE(data, 2)] << 2;
279        v |= expand4[GET_PLANE(data, 3)] << 3;
280        PUT_PIXEL2(d, 0, palette[v >> 28]);
281        PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
282        PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
283        PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
284        PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
285        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
286        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
287        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
288        d += BPP * 16;
289        s += 4;
290    }
291}
292
293/*
294 * 256 color mode, double pixels
295 *
296 * XXX: add plane_mask support (never used in standard VGA modes)
297 */
298static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d, 
299                                           const uint8_t *s, int width)
300{
301    uint32_t *palette;
302    int x;
303
304    palette = s1->last_palette;
305    width >>= 3;
306    for(x = 0; x < width; x++) {
307        PUT_PIXEL2(d, 0, palette[s[0]]);
308        PUT_PIXEL2(d, 1, palette[s[1]]);
309        PUT_PIXEL2(d, 2, palette[s[2]]);
310        PUT_PIXEL2(d, 3, palette[s[3]]);
311        d += BPP * 8;
312        s += 4;
313    }
314}
315
316/*
317 * standard 256 color mode
318 *
319 * XXX: add plane_mask support (never used in standard VGA modes)
320 */
321static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d, 
322                                         const uint8_t *s, int width)
323{
324    uint32_t *palette;
325    int x;
326
327    palette = s1->last_palette;
328    width >>= 3;
329    for(x = 0; x < width; x++) {
330        ((PIXEL_TYPE *)d)[0] = palette[s[0]];
331        ((PIXEL_TYPE *)d)[1] = palette[s[1]];
332        ((PIXEL_TYPE *)d)[2] = palette[s[2]];
333        ((PIXEL_TYPE *)d)[3] = palette[s[3]];
334        ((PIXEL_TYPE *)d)[4] = palette[s[4]];
335        ((PIXEL_TYPE *)d)[5] = palette[s[5]];
336        ((PIXEL_TYPE *)d)[6] = palette[s[6]];
337        ((PIXEL_TYPE *)d)[7] = palette[s[7]];
338        d += BPP * 8;
339        s += 8;
340    }
341}
342
343void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, 
344                                        const uint8_t *src1, 
345                                        int poffset, int w,
346                                        unsigned int color0, 
347                                        unsigned int color1,
348                                        unsigned int color_xor)
349{
350    const uint8_t *plane0, *plane1;
351    int x, b0, b1;
352    uint8_t *d;
353
354    d = d1;
355    plane0 = src1;
356    plane1 = src1 + poffset;
357    for(x = 0; x < w; x++) {
358        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
359        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
360#if DEPTH == 8
361        switch(b0 | (b1 << 1)) {
362        case 0:
363            break;
364        case 1:
365            d[0] ^= color_xor;
366            break;
367        case 2:
368            d[0] = color0;
369            break;
370        case 3:
371            d[0] = color1;
372            break;
373        }
374#elif DEPTH == 16
375        switch(b0 | (b1 << 1)) {
376        case 0:
377            break;
378        case 1:
379            ((uint16_t *)d)[0] ^= color_xor;
380            break;
381        case 2:
382            ((uint16_t *)d)[0] = color0;
383            break;
384        case 3:
385            ((uint16_t *)d)[0] = color1;
386            break;
387        }
388#elif DEPTH == 32
389        switch(b0 | (b1 << 1)) {
390        case 0:
391            break;
392        case 1:
393            ((uint32_t *)d)[0] ^= color_xor;
394            break;
395        case 2:
396            ((uint32_t *)d)[0] = color0;
397            break;
398        case 3:
399            ((uint32_t *)d)[0] = color1;
400            break;
401        }
402#else
403#error unsupported depth
404#endif
405        d += BPP;
406    }
407}
408
409#endif /* DEPTH != 15 */
410
411
412/* XXX: optimize */
413
414/*
415 * 15 bit color
416 */
417static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
418                                          const uint8_t *s, int width)
419{
420#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
421    memcpy(d, s, width * 2);
422#else
423    int w;
424    uint32_t v, r, g, b;
425
426    w = width;
427    do {
428        v = lduw_raw((void *)s);
429        r = (v >> 7) & 0xf8;
430        g = (v >> 2) & 0xf8;
431        b = (v << 3) & 0xf8;
432        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
433        s += 2;
434        d += BPP;
435    } while (--w != 0);
436#endif   
437}
438
439/*
440 * 16 bit color
441 */
442static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
443                                          const uint8_t *s, int width)
444{
445#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
446    memcpy(d, s, width * 2);
447#else
448    int w;
449    uint32_t v, r, g, b;
450
451    w = width;
452    do {
453        v = lduw_raw((void *)s);
454        r = (v >> 8) & 0xf8;
455        g = (v >> 3) & 0xfc;
456        b = (v << 3) & 0xf8;
457        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
458        s += 2;
459        d += BPP;
460    } while (--w != 0);
461#endif   
462}
463
464/*
465 * 24 bit color
466 */
467static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
468                                          const uint8_t *s, int width)
469{
470    int w;
471    uint32_t r, g, b;
472
473    w = width;
474    do {
475#if defined(TARGET_WORDS_BIGENDIAN)
476        r = s[0];
477        g = s[1];
478        b = s[2];
479#else
480        b = s[0];
481        g = s[1];
482        r = s[2];
483#endif
484        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
485        s += 3;
486        d += BPP;
487    } while (--w != 0);
488}
489
490/*
491 * 32 bit color
492 */
493static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d, 
494                                          const uint8_t *s, int width)
495{
496#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
497    memcpy(d, s, width * 4);
498#else
499    int w;
500    uint32_t r, g, b;
501
502    w = width;
503    do {
504#if defined(TARGET_WORDS_BIGENDIAN)
505        r = s[1];
506        g = s[2];
507        b = s[3];
508#else
509        b = s[0];
510        g = s[1];
511        r = s[2];
512#endif
513        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
514        s += 4;
515        d += BPP;
516    } while (--w != 0);
517#endif
518}
519
520#undef PUT_PIXEL2
521#undef DEPTH
522#undef BPP
523#undef PIXEL_TYPE
524#undef PIXEL_NAME
525#undef BGR_FORMAT
Note: See TracBrowser for help on using the repository browser.