Statistics
| Branch: | Revision:

root / hw / cirrus_vga_rop2.h @ 89344d5a

History | View | Annotate | Download (7.6 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
    int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8);
51

    
52
#if DEPTH == 8
53
    pattern_pitch = 8;
54
#elif DEPTH == 16
55
    pattern_pitch = 16;
56
#else
57
    pattern_pitch = 32;
58
#endif
59
    pattern_y = s->cirrus_blt_srcaddr & 7;
60
    pattern_x = skipleft;
61
    for(y = 0; y < bltheight; y++) {
62
        d = dst + skipleft;
63
        src1 = src + pattern_y * pattern_pitch;
64
        for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
65
#if DEPTH == 8
66
            col = src1[pattern_x];
67
            pattern_x = (pattern_x + 1) & 7;
68
#elif DEPTH == 16
69
            col = ((uint16_t *)(src1 + pattern_x))[0];
70
            pattern_x = (pattern_x + 2) & 15;
71
#elif DEPTH == 24
72
            {
73
                const uint8_t *src2 = src1 + pattern_x * 3;
74
                col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
75
                pattern_x = (pattern_x + 1) & 7;
76
            }
77
#else
78
            col = ((uint32_t *)(src1 + pattern_x))[0];
79
            pattern_x = (pattern_x + 4) & 31;
80
#endif
81
            PUTPIXEL();
82
            d += (DEPTH / 8);
83
        }
84
        pattern_y = (pattern_y + 1) & 7;
85
        dst += dstpitch;
86
    }
87
}
88

    
89
/* NOTE: srcpitch is ignored */
90
static void
91
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
92
     (CirrusVGAState * s, uint8_t * dst,
93
      const uint8_t * src, 
94
      int dstpitch, int srcpitch, 
95
      int bltwidth, int bltheight)
96
{
97
    uint8_t *d;
98
    int x, y;
99
    unsigned bits, bits_xor;
100
    unsigned int col;
101
    unsigned bitmask;
102
    unsigned index;
103
    int srcskipleft = s->gr[0x2f] & 0x07;
104
    int dstskipleft = srcskipleft * (DEPTH / 8);
105

    
106
    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
107
        bits_xor = 0xff;
108
        col = s->cirrus_blt_bgcol;
109
    } else {
110
        bits_xor = 0x00;
111
        col = s->cirrus_blt_fgcol;
112
    }
113

    
114
    for(y = 0; y < bltheight; y++) {
115
        bitmask = 0x80 >> srcskipleft;
116
        bits = *src++ ^ bits_xor;
117
        d = dst + dstskipleft;
118
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
119
            if ((bitmask & 0xff) == 0) {
120
                bitmask = 0x80;
121
                bits = *src++ ^ bits_xor;
122
            }
123
            index = (bits & bitmask);
124
            if (index) {
125
                PUTPIXEL();
126
            }
127
            d += (DEPTH / 8);
128
            bitmask >>= 1;
129
        }
130
        dst += dstpitch;
131
    }
132
}
133

    
134
static void
135
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
136
     (CirrusVGAState * s, uint8_t * dst,
137
      const uint8_t * src, 
138
      int dstpitch, int srcpitch, 
139
      int bltwidth, int bltheight)
140
{
141
    uint32_t colors[2];
142
    uint8_t *d;
143
    int x, y;
144
    unsigned bits;
145
    unsigned int col;
146
    unsigned bitmask;
147
    int srcskipleft = s->gr[0x2f] & 0x07;
148
    int dstskipleft = srcskipleft * (DEPTH / 8);
149

    
150
    colors[0] = s->cirrus_blt_bgcol;
151
    colors[1] = s->cirrus_blt_fgcol;
152
    for(y = 0; y < bltheight; y++) {
153
        bitmask = 0x80 >> srcskipleft;
154
        bits = *src++;
155
        d = dst + dstskipleft;
156
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
157
            if ((bitmask & 0xff) == 0) {
158
                bitmask = 0x80;
159
                bits = *src++;
160
            }
161
            col = colors[!!(bits & bitmask)];
162
            PUTPIXEL();
163
            d += (DEPTH / 8);
164
            bitmask >>= 1;
165
        }
166
        dst += dstpitch;
167
    }
168
}
169

    
170
static void
171
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
172
     (CirrusVGAState * s, uint8_t * dst,
173
      const uint8_t * src, 
174
      int dstpitch, int srcpitch, 
175
      int bltwidth, int bltheight)
176
{
177
    uint8_t *d;
178
    int x, y, bitpos, pattern_y;
179
    unsigned int bits, bits_xor;
180
    unsigned int col;
181
    int srcskipleft = s->gr[0x2f] & 0x07;
182
    int dstskipleft = srcskipleft * (DEPTH / 8);
183

    
184
    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
185
        bits_xor = 0xff;
186
        col = s->cirrus_blt_bgcol;
187
    } else {
188
        bits_xor = 0x00;
189
        col = s->cirrus_blt_fgcol;
190
    }
191
    pattern_y = s->cirrus_blt_srcaddr & 7;
192

    
193
    for(y = 0; y < bltheight; y++) {
194
        bits = src[pattern_y] ^ bits_xor;
195
        bitpos = 7 - srcskipleft;
196
        d = dst + dstskipleft;
197
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
198
            if ((bits >> bitpos) & 1) {
199
                PUTPIXEL();
200
            }
201
            d += (DEPTH / 8);
202
            bitpos = (bitpos - 1) & 7;
203
        }
204
        pattern_y = (pattern_y + 1) & 7;
205
        dst += dstpitch;
206
    }
207
}
208

    
209
static void
210
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
211
     (CirrusVGAState * s, uint8_t * dst,
212
      const uint8_t * src, 
213
      int dstpitch, int srcpitch, 
214
      int bltwidth, int bltheight)
215
{
216
    uint32_t colors[2];
217
    uint8_t *d;
218
    int x, y, bitpos, pattern_y;
219
    unsigned int bits;
220
    unsigned int col;
221
    int srcskipleft = s->gr[0x2f] & 0x07;
222
    int dstskipleft = srcskipleft * (DEPTH / 8);
223

    
224
    colors[0] = s->cirrus_blt_bgcol;
225
    colors[1] = s->cirrus_blt_fgcol;
226
    pattern_y = s->cirrus_blt_srcaddr & 7;
227

    
228
    for(y = 0; y < bltheight; y++) {
229
        bits = src[pattern_y];
230
        bitpos = 7 - srcskipleft;
231
        d = dst + dstskipleft;
232
        for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
233
            col = colors[(bits >> bitpos) & 1];
234
            PUTPIXEL();
235
            d += (DEPTH / 8);
236
            bitpos = (bitpos - 1) & 7;
237
        }
238
        pattern_y = (pattern_y + 1) & 7;
239
        dst += dstpitch;
240
    }
241
}
242

    
243
static void 
244
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
245
     (CirrusVGAState *s,
246
      uint8_t *dst, int dst_pitch, 
247
      int width, int height)
248
{
249
    uint8_t *d, *d1;
250
    uint32_t col;
251
    int x, y;
252

    
253
    col = s->cirrus_blt_fgcol;
254

    
255
    d1 = dst;
256
    for(y = 0; y < height; y++) {
257
        d = d1;
258
        for(x = 0; x < width; x += (DEPTH / 8)) {
259
            PUTPIXEL();
260
            d += (DEPTH / 8);
261
        }
262
        d1 += dst_pitch;
263
    }
264
}
265

    
266
#undef DEPTH
267
#undef PUTPIXEL