Statistics
| Branch: | Revision:

root / hw / vga_template.h @ 71be0fc3

History | View | Annotate | Download (15.6 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)[1] = (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
#if BPP == 1
110
        cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
111
        v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
112
        cpu_to_32wu(((uint32_t *)d)+1, v);
113
        if (dup9)
114
            ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
115
        else
116
            ((uint8_t *)d)[8] = bgcol;
117
        
118
#elif BPP == 2
119
        cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
120
        cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
121
        cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
122
        v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
123
        cpu_to_32wu(((uint32_t *)d)+3, v);
124
        if (dup9)
125
            ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
126
        else
127
            ((uint16_t *)d)[8] = bgcol;
128
#else
129
        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
130
        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
131
        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
132
        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
133
        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
134
        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
135
        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
136
        v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
137
        ((uint32_t *)d)[7] = v;
138
        if (dup9)
139
            ((uint32_t *)d)[8] = v;
140
        else
141
            ((uint32_t *)d)[8] = bgcol;
142
#endif
143
        font_ptr += 4;
144
        d += linesize;
145
    } while (--h);
146
}
147

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
339

    
340
/* XXX: optimize */
341

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

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

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

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

    
392
/* 
393
 * 24 bit color
394
 */
395
static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, 
396
                                          const uint8_t *s, int width)
397
{
398
    int w;
399
    uint32_t r, g, b;
400

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

    
418
/* 
419
 * 32 bit color
420
 */
421
static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, 
422
                                          const uint8_t *s, int width)
423
{
424
#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
425
    memcpy(d, s, width * 4);
426
#else
427
    int w;
428
    uint32_t r, g, b;
429

    
430
    w = width;
431
    do {
432
#if defined(TARGET_WORDS_BIGENDIAN)
433
        r = s[1];
434
        g = s[2];
435
        b = s[3];
436
#else
437
        b = s[0];
438
        g = s[1];
439
        r = s[2];
440
#endif
441
        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
442
        s += 4;
443
        d += BPP;
444
    } while (--w != 0);
445
#endif
446
}
447

    
448
#if DEPTH != 15
449
void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, 
450
                                        const uint8_t *src1, 
451
                                        int poffset, int w,
452
                                        unsigned int color0, 
453
                                        unsigned int color1,
454
                                        unsigned int color_xor)
455
{
456
    const uint8_t *plane0, *plane1;
457
    int x, b0, b1;
458
    uint8_t *d;
459

    
460
    d = d1;
461
    plane0 = src1;
462
    plane1 = src1 + poffset;
463
    for(x = 0; x < w; x++) {
464
        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
465
        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
466
#if DEPTH == 8
467
        switch(b0 | (b1 << 1)) {
468
        case 0:
469
            break;
470
        case 1:
471
            d[0] ^= color_xor;
472
            break;
473
        case 2:
474
            d[0] = color0;
475
            break;
476
        case 3:
477
            d[0] = color1;
478
            break;
479
        }
480
#elif DEPTH == 16
481
        switch(b0 | (b1 << 1)) {
482
        case 0:
483
            break;
484
        case 1:
485
            ((uint16_t *)d)[0] ^= color_xor;
486
            break;
487
        case 2:
488
            ((uint16_t *)d)[0] = color0;
489
            break;
490
        case 3:
491
            ((uint16_t *)d)[0] = color1;
492
            break;
493
        }
494
#elif DEPTH == 32
495
        switch(b0 | (b1 << 1)) {
496
        case 0:
497
            break;
498
        case 1:
499
            ((uint32_t *)d)[0] ^= color_xor;
500
            break;
501
        case 2:
502
            ((uint32_t *)d)[0] = color0;
503
            break;
504
        case 3:
505
            ((uint32_t *)d)[0] = color1;
506
            break;
507
        }
508
#else
509
#error unsupported depth
510
#endif
511
        d += BPP;
512
    }
513
}
514
#endif
515

    
516
#undef PUT_PIXEL2
517
#undef DEPTH
518
#undef BPP
519
#undef PIXEL_TYPE