Statistics
| Branch: | Revision:

root / hw / vga_template.h @ 17b0018b

History | View | Annotate | Download (13.2 kB)

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
#if DEPTH != 15
39

    
40
static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, 
41
                                                     uint32_t font_data,
42
                                                     uint32_t xorcol, 
43
                                                     uint32_t bgcol)
44
{
45
#if BPP == 1
46
        ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
47
        ((uint32_t *)d)[3] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
48
#elif BPP == 2
49
        ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
50
        ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
51
        ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
52
        ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
53
#else
54
        ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol;
55
        ((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol;
56
        ((uint32_t *)d)[2] = ((-(font_data >> 5) & 1) & xorcol) ^ bgcol;
57
        ((uint32_t *)d)[3] = ((-(font_data >> 4) & 1) & xorcol) ^ bgcol;
58
        ((uint32_t *)d)[4] = ((-(font_data >> 3) & 1) & xorcol) ^ bgcol;
59
        ((uint32_t *)d)[5] = ((-(font_data >> 2) & 1) & xorcol) ^ bgcol;
60
        ((uint32_t *)d)[6] = ((-(font_data >> 1) & 1) & xorcol) ^ bgcol;
61
        ((uint32_t *)d)[7] = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol;
62
#endif
63
}
64

    
65
static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
66
                                          const uint8_t *font_ptr, int h,
67
                                          uint32_t fgcol, uint32_t bgcol)
68
{
69
    uint32_t font_data, xorcol;
70
    
71
    xorcol = bgcol ^ fgcol;
72
    do {
73
        font_data = font_ptr[0];
74
        glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
75
        font_ptr += 4;
76
        d += linesize;
77
    } while (--h);
78
}
79

    
80
static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
81
                                          const uint8_t *font_ptr, int h,
82
                                          uint32_t fgcol, uint32_t bgcol)
83
{
84
    uint32_t font_data, xorcol;
85
    
86
    xorcol = bgcol ^ fgcol;
87
    do {
88
        font_data = font_ptr[0];
89
        glue(vga_draw_glyph_line_, DEPTH)(d, 
90
                                          expand4to8[font_data >> 4], 
91
                                          xorcol, bgcol);
92
        glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP, 
93
                                          expand4to8[font_data & 0x0f], 
94
                                          xorcol, bgcol);
95
        font_ptr += 4;
96
        d += linesize;
97
    } while (--h);
98
}
99

    
100
static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
101
                                          const uint8_t *font_ptr, int h, 
102
                                          uint32_t fgcol, uint32_t bgcol, int dup9)
103
{
104
    uint32_t font_data, xorcol, v;
105
    
106
    xorcol = bgcol ^ fgcol;
107
    do {
108
        font_data = font_ptr[0];
109
        /* XXX: unaligned accesses are done */
110
#if BPP == 1
111
        ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
112
        v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
113
        ((uint32_t *)d)[3] = v;
114
        if (dup9)
115
            ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
116
        else
117
            ((uint8_t *)d)[8] = bgcol;
118
        
119
#elif BPP == 2
120
        ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
121
        ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
122
        ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
123
        v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
124
        ((uint32_t *)d)[3] = v;
125
        if (dup9)
126
            ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
127
        else
128
            ((uint16_t *)d)[8] = bgcol;
129
#else
130
        ((uint32_t *)d)[0] = ((-(font_data >> 7)) & xorcol) ^ bgcol;
131
        ((uint32_t *)d)[1] = ((-(font_data >> 6) & 1) & xorcol) ^ bgcol;
132
        ((uint32_t *)d)[2] = ((-(font_data >> 5) & 1) & xorcol) ^ bgcol;
133
        ((uint32_t *)d)[3] = ((-(font_data >> 4) & 1) & xorcol) ^ bgcol;
134
        ((uint32_t *)d)[4] = ((-(font_data >> 3) & 1) & xorcol) ^ bgcol;
135
        ((uint32_t *)d)[5] = ((-(font_data >> 2) & 1) & xorcol) ^ bgcol;
136
        ((uint32_t *)d)[6] = ((-(font_data >> 1) & 1) & xorcol) ^ bgcol;
137
        v = ((-(font_data >> 0) & 1) & xorcol) ^ bgcol;
138
        ((uint32_t *)d)[7] = v;
139
        if (dup9)
140
            ((uint32_t *)d)[8] = v;
141
        else
142
            ((uint32_t *)d)[8] = bgcol;
143
#endif
144
        font_ptr += 4;
145
        d += linesize;
146
    } while (--h);
147
}
148

    
149
/* 
150
 * 4 color mode
151
 */
152
static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d, 
153
                                         const uint8_t *s, int width)
154
{
155
    uint32_t plane_mask, *palette, data, v;
156
    int x;
157

    
158
    palette = s1->last_palette;
159
    plane_mask = mask16[s1->ar[0x12] & 0xf];
160
    width >>= 3;
161
    for(x = 0; x < width; x++) {
162
        data = ((uint32_t *)s)[0];
163
        data &= plane_mask;
164
        v = expand2[GET_PLANE(data, 0)];
165
        v |= expand2[GET_PLANE(data, 2)] << 2;
166
        ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
167
        ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
168
        ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
169
        ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
170

    
171
        v = expand2[GET_PLANE(data, 1)];
172
        v |= expand2[GET_PLANE(data, 3)] << 2;
173
        ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
174
        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
175
        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
176
        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
177
        d += BPP * 8;
178
        s += 4;
179
    }
180
}
181

    
182
#if BPP == 1
183
#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
184
#elif BPP == 2
185
#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
186
#else
187
#define PUT_PIXEL2(d, n, v) \
188
((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
189
#endif
190

    
191
/* 
192
 * 4 color mode, dup2 horizontal
193
 */
194
static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d, 
195
                                           const uint8_t *s, int width)
196
{
197
    uint32_t plane_mask, *palette, data, v;
198
    int x;
199

    
200
    palette = s1->last_palette;
201
    plane_mask = mask16[s1->ar[0x12] & 0xf];
202
    width >>= 3;
203
    for(x = 0; x < width; x++) {
204
        data = ((uint32_t *)s)[0];
205
        data &= plane_mask;
206
        v = expand2[GET_PLANE(data, 0)];
207
        v |= expand2[GET_PLANE(data, 2)] << 2;
208
        PUT_PIXEL2(d, 0, palette[v >> 12]);
209
        PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
210
        PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
211
        PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
212

    
213
        v = expand2[GET_PLANE(data, 1)];
214
        v |= expand2[GET_PLANE(data, 3)] << 2;
215
        PUT_PIXEL2(d, 4, palette[v >> 12]);
216
        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
217
        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
218
        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
219
        d += BPP * 16;
220
        s += 4;
221
    }
222
}
223

    
224
/* 
225
 * 16 color mode
226
 */
227
static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d, 
228
                                         const uint8_t *s, int width)
229
{
230
    uint32_t plane_mask, data, v, *palette;
231
    int x;
232

    
233
    palette = s1->last_palette;
234
    plane_mask = mask16[s1->ar[0x12] & 0xf];
235
    width >>= 3;
236
    for(x = 0; x < width; x++) {
237
        data = ((uint32_t *)s)[0];
238
        data &= plane_mask;
239
        v = expand4[GET_PLANE(data, 0)];
240
        v |= expand4[GET_PLANE(data, 1)] << 1;
241
        v |= expand4[GET_PLANE(data, 2)] << 2;
242
        v |= expand4[GET_PLANE(data, 3)] << 3;
243
        ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
244
        ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
245
        ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
246
        ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
247
        ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
248
        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
249
        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
250
        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
251
        d += BPP * 8;
252
        s += 4;
253
    }
254
}
255

    
256
/* 
257
 * 16 color mode, dup2 horizontal
258
 */
259
static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d, 
260
                                           const uint8_t *s, int width)
261
{
262
    uint32_t plane_mask, data, v, *palette;
263
    int x;
264

    
265
    palette = s1->last_palette;
266
    plane_mask = mask16[s1->ar[0x12] & 0xf];
267
    width >>= 3;
268
    for(x = 0; x < width; x++) {
269
        data = ((uint32_t *)s)[0];
270
        data &= plane_mask;
271
        v = expand4[GET_PLANE(data, 0)];
272
        v |= expand4[GET_PLANE(data, 1)] << 1;
273
        v |= expand4[GET_PLANE(data, 2)] << 2;
274
        v |= expand4[GET_PLANE(data, 3)] << 3;
275
        PUT_PIXEL2(d, 0, palette[v >> 28]);
276
        PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
277
        PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
278
        PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
279
        PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
280
        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
281
        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
282
        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
283
        d += BPP * 16;
284
        s += 4;
285
    }
286
}
287

    
288
/* 
289
 * 256 color mode, double pixels
290
 *
291
 * XXX: add plane_mask support (never used in standard VGA modes)
292
 */
293
static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d, 
294
                                           const uint8_t *s, int width)
295
{
296
    uint32_t *palette;
297
    int x;
298

    
299
    palette = s1->last_palette;
300
    width >>= 3;
301
    for(x = 0; x < width; x++) {
302
        PUT_PIXEL2(d, 0, palette[s[0]]);
303
        PUT_PIXEL2(d, 1, palette[s[1]]);
304
        PUT_PIXEL2(d, 2, palette[s[2]]);
305
        PUT_PIXEL2(d, 3, palette[s[3]]);
306
        d += BPP * 8;
307
        s += 4;
308
    }
309
}
310

    
311
/* 
312
 * standard 256 color mode
313
 *
314
 * XXX: add plane_mask support (never used in standard VGA modes)
315
 */
316
static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d, 
317
                                         const uint8_t *s, int width)
318
{
319
    uint32_t *palette;
320
    int x;
321

    
322
    palette = s1->last_palette;
323
    width >>= 3;
324
    for(x = 0; x < width; x++) {
325
        ((PIXEL_TYPE *)d)[0] = palette[s[0]];
326
        ((PIXEL_TYPE *)d)[1] = palette[s[1]];
327
        ((PIXEL_TYPE *)d)[2] = palette[s[2]];
328
        ((PIXEL_TYPE *)d)[3] = palette[s[3]];
329
        ((PIXEL_TYPE *)d)[4] = palette[s[4]];
330
        ((PIXEL_TYPE *)d)[5] = palette[s[5]];
331
        ((PIXEL_TYPE *)d)[6] = palette[s[6]];
332
        ((PIXEL_TYPE *)d)[7] = palette[s[7]];
333
        d += BPP * 8;
334
        s += 8;
335
    }
336
}
337

    
338
#endif /* DEPTH != 15 */
339

    
340

    
341
/* XXX: optimize */
342

    
343
/* 
344
 * 15 bit color
345
 */
346
static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, 
347
                                          const uint8_t *s, int width)
348
{
349
#if DEPTH == 15 && !defined(WORDS_BIGENDIAN)
350
    memcpy(d, s, width * 2);
351
#else
352
    int w;
353
    uint32_t v, r, g, b;
354

    
355
    w = width;
356
    do {
357
        v = lduw((void *)s);
358
        r = (v >> 7) & 0xf8;
359
        g = (v >> 2) & 0xf8;
360
        b = (v << 3) & 0xf8;
361
        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
362
        s += 2;
363
        d += BPP;
364
    } while (--w != 0);
365
#endif    
366
}
367

    
368
/* 
369
 * 16 bit color
370
 */
371
static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, 
372
                                          const uint8_t *s, int width)
373
{
374
#if DEPTH == 16 && !defined(WORDS_BIGENDIAN)
375
    memcpy(d, s, width * 2);
376
#else
377
    int w;
378
    uint32_t v, r, g, b;
379

    
380
    w = width;
381
    do {
382
        v = lduw((void *)s);
383
        r = (v >> 8) & 0xf8;
384
        g = (v >> 3) & 0xfc;
385
        b = (v << 3) & 0xf8;
386
        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
387
        s += 2;
388
        d += BPP;
389
    } while (--w != 0);
390
#endif    
391
}
392

    
393
/* 
394
 * 32 bit color
395
 */
396
static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, 
397
                                          const uint8_t *s, int width)
398
{
399
#if DEPTH == 32 && !defined(WORDS_BIGENDIAN)
400
    memcpy(d, s, width * 4);
401
#else
402
    int w;
403
    uint32_t r, g, b;
404

    
405
    w = width;
406
    do {
407
        b = s[0];
408
        g = s[1];
409
        r = s[2];
410
        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
411
        s += 4;
412
        d += BPP;
413
    } while (--w != 0);
414
#endif
415
}
416

    
417
#undef PUT_PIXEL2
418
#undef DEPTH
419
#undef BPP
420
#undef PIXEL_TYPE