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 *vga, uint8_t *d,
 102                           uint32_t addr, int width)
 103{
 104    uint32_t plane_mask, *palette, data, v;
 105    int x;
 106
 107    palette = vga->last_palette;
 108    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 109    width >>= 3;
 110    for(x = 0; x < width; x++) {
 111        data = vga_read_dword_le(vga, addr);
 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        addr += 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 *vga, uint8_t *d,
 138                             uint32_t addr, int width)
 139{
 140    uint32_t plane_mask, *palette, data, v;
 141    int x;
 142
 143    palette = vga->last_palette;
 144    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 145    width >>= 3;
 146    for(x = 0; x < width; x++) {
 147        data = vga_read_dword_le(vga, addr);
 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        addr += 4;
 164    }
 165}
 166
 167/*
 168 * 16 color mode
 169 */
 170static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
 171                           uint32_t addr, int width)
 172{
 173    uint32_t plane_mask, data, v, *palette;
 174    int x;
 175
 176    palette = vga->last_palette;
 177    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 178    width >>= 3;
 179    for(x = 0; x < width; x++) {
 180        data = vga_read_dword_le(vga, addr);
 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        addr += 4;
 196    }
 197}
 198
 199/*
 200 * 16 color mode, dup2 horizontal
 201 */
 202static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
 203                             uint32_t addr, int width)
 204{
 205    uint32_t plane_mask, data, v, *palette;
 206    int x;
 207
 208    palette = vga->last_palette;
 209    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
 210    width >>= 3;
 211    for(x = 0; x < width; x++) {
 212        data = vga_read_dword_le(vga, addr);
 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        addr += 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 *vga, uint8_t *d,
 237                             uint32_t addr, int width)
 238{
 239    uint32_t *palette;
 240    int x;
 241
 242    palette = vga->last_palette;
 243    width >>= 3;
 244    for(x = 0; x < width; x++) {
 245        PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
 246        PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
 247        PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
 248        PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
 249        d += 32;
 250        addr += 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 *vga, uint8_t *d,
 260                           uint32_t addr, int width)
 261{
 262    uint32_t *palette;
 263    int x;
 264
 265    palette = vga->last_palette;
 266    width >>= 3;
 267    for(x = 0; x < width; x++) {
 268        ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
 269        ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
 270        ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
 271        ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
 272        ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
 273        ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
 274        ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
 275        ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
 276        d += 32;
 277        addr += 8;
 278    }
 279}
 280
 281/*
 282 * 15 bit color
 283 */
 284static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
 285                               uint32_t addr, int width)
 286{
 287    int w;
 288    uint32_t v, r, g, b;
 289
 290    w = width;
 291    do {
 292        v = vga_read_word_le(vga, addr);
 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        addr += 2;
 298        d += 4;
 299    } while (--w != 0);
 300}
 301
 302static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
 303                               uint32_t addr, int width)
 304{
 305    int w;
 306    uint32_t v, r, g, b;
 307
 308    w = width;
 309    do {
 310        v = vga_read_word_be(vga, addr);
 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        addr += 2;
 316        d += 4;
 317    } while (--w != 0);
 318}
 319
 320/*
 321 * 16 bit color
 322 */
 323static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
 324                               uint32_t addr, int width)
 325{
 326    int w;
 327    uint32_t v, r, g, b;
 328
 329    w = width;
 330    do {
 331        v = vga_read_word_le(vga, addr);
 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        addr += 2;
 337        d += 4;
 338    } while (--w != 0);
 339}
 340
 341static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
 342                               uint32_t addr, int width)
 343{
 344    int w;
 345    uint32_t v, r, g, b;
 346
 347    w = width;
 348    do {
 349        v = vga_read_word_be(vga, addr);
 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        addr += 2;
 355        d += 4;
 356    } while (--w != 0);
 357}
 358
 359/*
 360 * 24 bit color
 361 */
 362static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
 363                               uint32_t addr, int width)
 364{
 365    int w;
 366    uint32_t r, g, b;
 367
 368    w = width;
 369    do {
 370        b = vga_read_byte(vga, addr + 0);
 371        g = vga_read_byte(vga, addr + 1);
 372        r = vga_read_byte(vga, addr + 2);
 373        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 374        addr += 3;
 375        d += 4;
 376    } while (--w != 0);
 377}
 378
 379static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
 380                               uint32_t addr, int width)
 381{
 382    int w;
 383    uint32_t r, g, b;
 384
 385    w = width;
 386    do {
 387        r = vga_read_byte(vga, addr + 0);
 388        g = vga_read_byte(vga, addr + 1);
 389        b = vga_read_byte(vga, addr + 2);
 390        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 391        addr += 3;
 392        d += 4;
 393    } while (--w != 0);
 394}
 395
 396/*
 397 * 32 bit color
 398 */
 399static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
 400                               uint32_t addr, int width)
 401{
 402    int w;
 403    uint32_t r, g, b;
 404
 405    w = width;
 406    do {
 407        b = vga_read_byte(vga, addr + 0);
 408        g = vga_read_byte(vga, addr + 1);
 409        r = vga_read_byte(vga, addr + 2);
 410        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 411        addr += 4;
 412        d += 4;
 413    } while (--w != 0);
 414}
 415
 416static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
 417                               uint32_t addr, int width)
 418{
 419    int w;
 420    uint32_t r, g, b;
 421
 422    w = width;
 423    do {
 424        r = vga_read_byte(vga, addr + 1);
 425        g = vga_read_byte(vga, addr + 2);
 426        b = vga_read_byte(vga, addr + 3);
 427        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
 428        addr += 4;
 429        d += 4;
 430    } while (--w != 0);
 431}
 432