qemu

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

cirrus_vga_rop2.h (8493B)


      1 /*
      2  * QEMU Cirrus CLGD 54xx VGA Emulator.
      3  *
      4  * Copyright (c) 2004 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 PUTPIXEL(s, a, c)    ROP_OP(s, a, c)
     27 #elif DEPTH == 16
     28 #define PUTPIXEL(s, a, c)    ROP_OP_16(s, a, c)
     29 #elif DEPTH == 24
     30 #define PUTPIXEL(s, a, c)    do {          \
     31         ROP_OP(s, a,     c);               \
     32         ROP_OP(s, a + 1, (c >> 8));        \
     33         ROP_OP(s, a + 2, (c >> 16));       \
     34     } while (0)
     35 #elif DEPTH == 32
     36 #define PUTPIXEL(s, a, c)    ROP_OP_32(s, a, c)
     37 #else
     38 #error unsupported DEPTH
     39 #endif
     40 
     41 static void
     42 glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
     43      (CirrusVGAState *s, uint32_t dstaddr,
     44       uint32_t srcaddr,
     45       int dstpitch, int srcpitch,
     46       int bltwidth, int bltheight)
     47 {
     48     uint32_t addr;
     49     int x, y, pattern_y, pattern_pitch, pattern_x;
     50     unsigned int col;
     51     uint32_t src1addr;
     52 #if DEPTH == 24
     53     int skipleft = s->vga.gr[0x2f] & 0x1f;
     54 #else
     55     int skipleft = (s->vga.gr[0x2f] & 0x07) * (DEPTH / 8);
     56 #endif
     57 
     58 #if DEPTH == 8
     59     pattern_pitch = 8;
     60 #elif DEPTH == 16
     61     pattern_pitch = 16;
     62 #else
     63     pattern_pitch = 32;
     64 #endif
     65     pattern_y = s->cirrus_blt_srcaddr & 7;
     66     for(y = 0; y < bltheight; y++) {
     67         pattern_x = skipleft;
     68         addr = dstaddr + skipleft;
     69         src1addr = srcaddr + pattern_y * pattern_pitch;
     70         for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
     71 #if DEPTH == 8
     72             col = cirrus_src(s, src1addr + pattern_x);
     73             pattern_x = (pattern_x + 1) & 7;
     74 #elif DEPTH == 16
     75             col = cirrus_src16(s, src1addr + pattern_x);
     76             pattern_x = (pattern_x + 2) & 15;
     77 #elif DEPTH == 24
     78             {
     79                 uint32_t src2addr = src1addr + pattern_x * 3;
     80                 col = cirrus_src(s, src2addr) |
     81                     (cirrus_src(s, src2addr + 1) << 8) |
     82                     (cirrus_src(s, src2addr + 2) << 16);
     83                 pattern_x = (pattern_x + 1) & 7;
     84             }
     85 #else
     86             col = cirrus_src32(s, src1addr + pattern_x);
     87             pattern_x = (pattern_x + 4) & 31;
     88 #endif
     89             PUTPIXEL(s, addr, col);
     90             addr += (DEPTH / 8);
     91         }
     92         pattern_y = (pattern_y + 1) & 7;
     93         dstaddr += dstpitch;
     94     }
     95 }
     96 
     97 /* NOTE: srcpitch is ignored */
     98 static void
     99 glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
    100      (CirrusVGAState *s, uint32_t dstaddr,
    101       uint32_t srcaddr,
    102       int dstpitch, int srcpitch,
    103       int bltwidth, int bltheight)
    104 {
    105     uint32_t addr;
    106     int x, y;
    107     unsigned bits, bits_xor;
    108     unsigned int col;
    109     unsigned bitmask;
    110     unsigned index;
    111 #if DEPTH == 24
    112     int dstskipleft = s->vga.gr[0x2f] & 0x1f;
    113     int srcskipleft = dstskipleft / 3;
    114 #else
    115     int srcskipleft = s->vga.gr[0x2f] & 0x07;
    116     int dstskipleft = srcskipleft * (DEPTH / 8);
    117 #endif
    118 
    119     if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
    120         bits_xor = 0xff;
    121         col = s->cirrus_blt_bgcol;
    122     } else {
    123         bits_xor = 0x00;
    124         col = s->cirrus_blt_fgcol;
    125     }
    126 
    127     for(y = 0; y < bltheight; y++) {
    128         bitmask = 0x80 >> srcskipleft;
    129         bits = cirrus_src(s, srcaddr++) ^ bits_xor;
    130         addr = dstaddr + dstskipleft;
    131         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
    132             if ((bitmask & 0xff) == 0) {
    133                 bitmask = 0x80;
    134                 bits = cirrus_src(s, srcaddr++) ^ bits_xor;
    135             }
    136             index = (bits & bitmask);
    137             if (index) {
    138                 PUTPIXEL(s, addr, col);
    139             }
    140             addr += (DEPTH / 8);
    141             bitmask >>= 1;
    142         }
    143         dstaddr += dstpitch;
    144     }
    145 }
    146 
    147 static void
    148 glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
    149      (CirrusVGAState *s, uint32_t dstaddr,
    150       uint32_t srcaddr,
    151       int dstpitch, int srcpitch,
    152       int bltwidth, int bltheight)
    153 {
    154     uint32_t colors[2];
    155     uint32_t addr;
    156     int x, y;
    157     unsigned bits;
    158     unsigned int col;
    159     unsigned bitmask;
    160     int srcskipleft = s->vga.gr[0x2f] & 0x07;
    161     int dstskipleft = srcskipleft * (DEPTH / 8);
    162 
    163     colors[0] = s->cirrus_blt_bgcol;
    164     colors[1] = s->cirrus_blt_fgcol;
    165     for(y = 0; y < bltheight; y++) {
    166         bitmask = 0x80 >> srcskipleft;
    167         bits = cirrus_src(s, srcaddr++);
    168         addr = dstaddr + dstskipleft;
    169         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
    170             if ((bitmask & 0xff) == 0) {
    171                 bitmask = 0x80;
    172                 bits = cirrus_src(s, srcaddr++);
    173             }
    174             col = colors[!!(bits & bitmask)];
    175             PUTPIXEL(s, addr, col);
    176             addr += (DEPTH / 8);
    177             bitmask >>= 1;
    178         }
    179         dstaddr += dstpitch;
    180     }
    181 }
    182 
    183 static void
    184 glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
    185      (CirrusVGAState *s, uint32_t dstaddr,
    186       uint32_t srcaddr,
    187       int dstpitch, int srcpitch,
    188       int bltwidth, int bltheight)
    189 {
    190     uint32_t addr;
    191     int x, y, bitpos, pattern_y;
    192     unsigned int bits, bits_xor;
    193     unsigned int col;
    194 #if DEPTH == 24
    195     int dstskipleft = s->vga.gr[0x2f] & 0x1f;
    196     int srcskipleft = dstskipleft / 3;
    197 #else
    198     int srcskipleft = s->vga.gr[0x2f] & 0x07;
    199     int dstskipleft = srcskipleft * (DEPTH / 8);
    200 #endif
    201 
    202     if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
    203         bits_xor = 0xff;
    204         col = s->cirrus_blt_bgcol;
    205     } else {
    206         bits_xor = 0x00;
    207         col = s->cirrus_blt_fgcol;
    208     }
    209     pattern_y = s->cirrus_blt_srcaddr & 7;
    210 
    211     for(y = 0; y < bltheight; y++) {
    212         bits = cirrus_src(s, srcaddr + pattern_y) ^ bits_xor;
    213         bitpos = 7 - srcskipleft;
    214         addr = dstaddr + dstskipleft;
    215         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
    216             if ((bits >> bitpos) & 1) {
    217                 PUTPIXEL(s, addr, col);
    218             }
    219             addr += (DEPTH / 8);
    220             bitpos = (bitpos - 1) & 7;
    221         }
    222         pattern_y = (pattern_y + 1) & 7;
    223         dstaddr += dstpitch;
    224     }
    225 }
    226 
    227 static void
    228 glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
    229      (CirrusVGAState *s, uint32_t dstaddr,
    230       uint32_t srcaddr,
    231       int dstpitch, int srcpitch,
    232       int bltwidth, int bltheight)
    233 {
    234     uint32_t colors[2];
    235     uint32_t addr;
    236     int x, y, bitpos, pattern_y;
    237     unsigned int bits;
    238     unsigned int col;
    239     int srcskipleft = s->vga.gr[0x2f] & 0x07;
    240     int dstskipleft = srcskipleft * (DEPTH / 8);
    241 
    242     colors[0] = s->cirrus_blt_bgcol;
    243     colors[1] = s->cirrus_blt_fgcol;
    244     pattern_y = s->cirrus_blt_srcaddr & 7;
    245 
    246     for(y = 0; y < bltheight; y++) {
    247         bits = cirrus_src(s, srcaddr + pattern_y);
    248         bitpos = 7 - srcskipleft;
    249         addr = dstaddr + dstskipleft;
    250         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
    251             col = colors[(bits >> bitpos) & 1];
    252             PUTPIXEL(s, addr, col);
    253             addr += (DEPTH / 8);
    254             bitpos = (bitpos - 1) & 7;
    255         }
    256         pattern_y = (pattern_y + 1) & 7;
    257         dstaddr += dstpitch;
    258     }
    259 }
    260 
    261 static void
    262 glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
    263      (CirrusVGAState *s,
    264       uint32_t dstaddr, int dst_pitch,
    265       int width, int height)
    266 {
    267     uint32_t addr;
    268     uint32_t col;
    269     int x, y;
    270 
    271     col = s->cirrus_blt_fgcol;
    272 
    273     for(y = 0; y < height; y++) {
    274         addr = dstaddr;
    275         for(x = 0; x < width; x += (DEPTH / 8)) {
    276             PUTPIXEL(s, addr, col);
    277             addr += (DEPTH / 8);
    278         }
    279         dstaddr += dst_pitch;
    280     }
    281 }
    282 
    283 #undef DEPTH
    284 #undef PUTPIXEL