qemu/hw/display/vga-helpers.h
<<
>>
Prefs
   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
  25static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
  26                                       uint32_t xorcol, uint32_t bgcol)
  27{
  28        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
  29        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
  30        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
  31        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
  32        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
  33        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
  34        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
  35        ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
  36}
  37
  38static void vga_draw_glyph8(uint8_t *d, int linesize,
  39                            const uint8_t *font_ptr, int h,
  40                            uint32_t fgcol, uint32_t bgcol)
  41{
  42    uint32_t font_data, xorcol;
  43
  44    xorcol = bgcol ^ fgcol;
  45    do {
  46        font_data = font_ptr[0];
  47        vga_draw_glyph_line(d, font_data, xorcol, bgcol);
  48        font_ptr += 4;
  49        d += linesize;
  50    } while (--h);
  51}
  52
  53static void vga_draw_glyph16(uint8_t *d, int linesize,
  54                                          const uint8_t *font_ptr, int h,
  55                                          uint32_t fgcol, uint32_t bgcol)
  56{
  57    uint32_t font_data, xorcol;
  58
  59    xorcol = bgcol ^ fgcol;
  60    do {
  61        font_data = font_ptr[0];
  62        vga_draw_glyph_line(d, expand4to8[font_data >> 4],
  63                            xorcol, bgcol);
  64        vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
  65                            xorcol, bgcol);
  66        font_ptr += 4;
  67        d += linesize;
  68    } while (--h);
  69}
  70
  71static void vga_draw_glyph9(uint8_t *d, int linesize,
  72                            const uint8_t *font_ptr, int h,
  73                            uint32_t fgcol, uint32_t bgcol, int dup9)
  74{
  75    uint32_t font_data, xorcol, v;
  76
  77    xorcol = bgcol ^ fgcol;
  78    do {
  79        font_data = font_ptr[0];
  80        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
  81        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
  82        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
  83        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
  84        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
  85        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
  86        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
  87        v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
  88        ((uint32_t *)d)[7] = v;
  89        if (dup9)
  90            ((uint32_t *)d)[8] = v;
  91        else
  92            ((uint32_t *)d)[8] = bgcol;
  93        font_ptr += 4;
  94        d += linesize;
  95    } while (--h);
  96}
  97
  98/*
  99 * 4 color mode
 100 */
 101static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
 102                           const uint8_t *s, int width)
 103{
 104    uint32_t plane_mask, *palette, data, v;
 105    int x;
 106
 107    palette = s1->last_palette;
 108    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 109    width >>= 3;
 110    for(x = 0; x < width; x++) {
 111        data = ((uint32_t *)s)[0];
 112        data &= plane_mask;
 113        v = expand2[GET_PLANE(data, 0)];
 114        v |= expand2[GET_PLANE(data, 2)] << 2;
 115        ((uint32_t *)d)[0] = palette[v >> 12];
 116        ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
 117        ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
 118        ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
 119
 120        v = expand2[GET_PLANE(data, 1)];
 121        v |= expand2[GET_PLANE(data, 3)] << 2;
 122        ((uint32_t *)d)[4] = palette[v >> 12];
 123        ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
 124        ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
 125        ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
 126        d += 32;
 127        s += 4;
 128    }
 129}
 130
 131#define PUT_PIXEL2(d, n, v) \
 132((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
 133
 134/*
 135 * 4 color mode, dup2 horizontal
 136 */
 137static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
 138                             const uint8_t *s, int width)
 139{
 140    uint32_t plane_mask, *palette, data, v;
 141    int x;
 142
 143    palette = s1->last_palette;
 144    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 145    width >>= 3;
 146    for(x = 0; x < width; x++) {
 147        data = ((uint32_t *)s)[0];
 148        data &= plane_mask;
 149        v = expand2[GET_PLANE(data, 0)];
 150        v |= expand2[GET_PLANE(data, 2)] << 2;
 151        PUT_PIXEL2(d, 0, palette[v >> 12]);
 152        PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
 153        PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
 154        PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
 155
 156        v = expand2[GET_PLANE(data, 1)];
 157        v |= expand2[GET_PLANE(data, 3)] << 2;
 158        PUT_PIXEL2(d, 4, palette[v >> 12]);
 159        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
 160        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
 161        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
 162        d += 64;
 163        s += 4;
 164    }
 165}
 166
 167/*
 168 * 16 color mode
 169 */
 170static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
 171                           const uint8_t *s, int width)
 172{
 173    uint32_t plane_mask, data, v, *palette;
 174    int x;
 175
 176    palette = s1->last_palette;
 177    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 178    width >>= 3;
 179    for(x = 0; x < width; x++) {
 180        data = ((uint32_t *)s)[0];
 181        data &= plane_mask;
 182        v = expand4[GET_PLANE(data, 0)];
 183        v |= expand4[GET_PLANE(data, 1)] << 1;
 184        v |= expand4[GET_PLANE(data, 2)] << 2;
 185        v |= expand4[GET_PLANE(data, 3)] << 3;
 186        ((uint32_t *)d)[0] = palette[v >> 28];
 187        ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
 188        ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
 189        ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
 190        ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
 191        ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
 192        ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
 193        ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
 194        d += 32;
 195        s += 4;
 196    }
 197}
 198
 199/*
 200 * 16 color mode, dup2 horizontal
 201 */
 202static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
 203                             const uint8_t *s, int width)
 204{
 205    uint32_t plane_mask, data, v, *palette;
 206    int x;
 207
 208    palette = s1->last_palette;
 209    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 210    width >>= 3;
 211    for(x = 0; x < width; x++) {
 212        data = ((uint32_t *)s)[0];
 213        data &= plane_mask;
 214        v = expand4[GET_PLANE(data, 0)];
 215        v |= expand4[GET_PLANE(data, 1)] << 1;
 216        v |= expand4[GET_PLANE(data, 2)] << 2;
 217        v |= expand4[GET_PLANE(data, 3)] << 3;
 218        PUT_PIXEL2(d, 0, palette[v >> 28]);
 219        PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
 220        PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
 221        PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
 222        PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
 223        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
 224        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
 225        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
 226        d += 64;
 227        s += 4;
 228    }
 229}
 230
 231/*
 232 * 256 color mode, double pixels
 233 *
 234 * XXX: add plane_mask support (never used in standard VGA modes)
 235 */
 236static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
 237                             const uint8_t *s, int width)
 238{
 239    uint32_t *palette;
 240    int x;
 241
 242    palette = s1->last_palette;
 243    width >>= 3;
 244    for(x = 0; x < width; x++) {
 245        PUT_PIXEL2(d, 0, palette[s[0]]);
 246        PUT_PIXEL2(d, 1, palette[s[1]]);
 247        PUT_PIXEL2(d, 2, palette[s[2]]);
 248        PUT_PIXEL2(d, 3, palette[s[3]]);
 249        d += 32;
 250        s += 4;
 251    }
 252}
 253
 254/*
 255 * standard 256 color mode
 256 *
 257 * XXX: add plane_mask support (never used in standard VGA modes)
 258 */
 259static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
 260                           const uint8_t *s, int width)
 261{
 262    uint32_t *palette;
 263    int x;
 264
 265    palette = s1->last_palette;
 266    width >>= 3;
 267    for(x = 0; x < width; x++) {
 268        ((uint32_t *)d)[0] = palette[s[0]];
 269        ((uint32_t *)d)[1] = palette[s[1]];
 270        ((uint32_t *)d)[2] = palette[s[2]];
 271        ((uint32_t *)d)[3] = palette[s[3]];
 272        ((uint32_t *)d)[4] = palette[s[4]];
 273        ((uint32_t *)d)[5] = palette[s[5]];
 274        ((uint32_t *)d)[6] = palette[s[6]];
 275        ((uint32_t *)d)[7] = palette[s[7]];
 276        d += 32;
 277        s += 8;
 278    }
 279}
 280
 281/*
 282 * 15 bit color
 283 */
 284static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
 285                               const uint8_t *s, int width)
 286{
 287    int w;
 288    uint32_t v, r, g, b;
 289
 290    w = width;
 291    do {
 292        v = lduw_le_p((void *)s);
 293        r = (v >> 7) & 0xf8;
 294        g = (v >> 2) & 0xf8;
 295        b = (v << 3) & 0xf8;
 296        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 297        s += 2;
 298        d += 4;
 299    } while (--w != 0);
 300}
 301
 302static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
 303                               const uint8_t *s, int width)
 304{
 305    int w;
 306    uint32_t v, r, g, b;
 307
 308    w = width;
 309    do {
 310        v = lduw_be_p((void *)s);
 311        r = (v >> 7) & 0xf8;
 312        g = (v >> 2) & 0xf8;
 313        b = (v << 3) & 0xf8;
 314        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 315        s += 2;
 316        d += 4;
 317    } while (--w != 0);
 318}
 319
 320/*
 321 * 16 bit color
 322 */
 323static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
 324                               const uint8_t *s, int width)
 325{
 326    int w;
 327    uint32_t v, r, g, b;
 328
 329    w = width;
 330    do {
 331        v = lduw_le_p((void *)s);
 332        r = (v >> 8) & 0xf8;
 333        g = (v >> 3) & 0xfc;
 334        b = (v << 3) & 0xf8;
 335        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 336        s += 2;
 337        d += 4;
 338    } while (--w != 0);
 339}
 340
 341static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
 342                               const uint8_t *s, int width)
 343{
 344    int w;
 345    uint32_t v, r, g, b;
 346
 347    w = width;
 348    do {
 349        v = lduw_be_p((void *)s);
 350        r = (v >> 8) & 0xf8;
 351        g = (v >> 3) & 0xfc;
 352        b = (v << 3) & 0xf8;
 353        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 354        s += 2;
 355        d += 4;
 356    } while (--w != 0);
 357}
 358
 359/*
 360 * 24 bit color
 361 */
 362static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
 363                               const uint8_t *s, int width)
 364{
 365    int w;
 366    uint32_t r, g, b;
 367
 368    w = width;
 369    do {
 370        b = s[0];
 371        g = s[1];
 372        r = s[2];
 373        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 374        s += 3;
 375        d += 4;
 376    } while (--w != 0);
 377}
 378
 379static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
 380                               const uint8_t *s, int width)
 381{
 382    int w;
 383    uint32_t r, g, b;
 384
 385    w = width;
 386    do {
 387        r = s[0];
 388        g = s[1];
 389        b = s[2];
 390        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 391        s += 3;
 392        d += 4;
 393    } while (--w != 0);
 394}
 395
 396/*
 397 * 32 bit color
 398 */
 399static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
 400                               const uint8_t *s, int width)
 401{
 402#ifndef HOST_WORDS_BIGENDIAN
 403    memcpy(d, s, width * 4);
 404#else
 405    int w;
 406    uint32_t r, g, b;
 407
 408    w = width;
 409    do {
 410        b = s[0];
 411        g = s[1];
 412        r = s[2];
 413        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 414        s += 4;
 415        d += 4;
 416    } while (--w != 0);
 417#endif
 418}
 419
 420static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
 421                               const uint8_t *s, int width)
 422{
 423#ifdef HOST_WORDS_BIGENDIAN
 424    memcpy(d, s, width * 4);
 425#else
 426    int w;
 427    uint32_t r, g, b;
 428
 429    w = width;
 430    do {
 431        r = s[1];
 432        g = s[2];
 433        b = s[3];
 434        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 435        s += 4;
 436        d += 4;
 437    } while (--w != 0);
 438#endif
 439}
 440