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