qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vga-helpers.h (13333B)


      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 static 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 
     38 static 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 
     53 static 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 
     71 static 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  */
    101 static 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  */
    137 static 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  */
    170 static 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  */
    202 static 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  */
    236 static 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  */
    259 static 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  */
    284 static 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 
    302 static 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  */
    323 static 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 
    341 static 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  */
    362 static 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 
    379 static 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  */
    399 static 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 
    416 static 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 }