Statistics
| Branch: | Revision:

root / hw / cirrus_vga_rop2.h @ 5fafdf24

History | View | Annotate | Download (7.8 kB)

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(((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(((uint32_t *)d)[0], col)
35
#else
36
#error unsupported DEPTH
37
#endif               
38

    
39
static void
40
glue(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->gr[0x2f] & 0x1f;
52
#else
53
    int skipleft = (s->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 */
94
static void
95
glue(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->gr[0x2f] & 0x1f;
109
    int srcskipleft = dstskipleft / 3;
110
#else
111
    int srcskipleft = s->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

    
143
static void
144
glue(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->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

    
179
static void
180
glue(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->gr[0x2f] & 0x1f;
192
    int srcskipleft = dstskipleft / 3;
193
#else
194
    int srcskipleft = s->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

    
223
static void
224
glue(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->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

    
257
static void
258
glue(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