cirrus blitter fixes
[qemu] / hw / cirrus_vga_rop2.h
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 /* NOTE: srcpitch is ignored */
40 static void
41 glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
42      (CirrusVGAState * s, uint8_t * dst,
43       const uint8_t * src, 
44       int dstpitch, int srcpitch, 
45       int bltwidth, int bltheight)
46 {
47     uint8_t *d;
48     int x, y;
49     unsigned bits;
50     unsigned int col;
51     unsigned bitmask;
52     unsigned index;
53     int srcskipleft = 0;
54
55     col = s->cirrus_blt_fgcol;
56     for(y = 0; y < bltheight; y++) {
57         bitmask = 0x80 >> srcskipleft;
58         bits = *src++;
59         d = dst;
60         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
61             if ((bitmask & 0xff) == 0) {
62                 bitmask = 0x80;
63                 bits = *src++;
64             }
65             index = (bits & bitmask);
66             if (index) {
67                 PUTPIXEL();
68             }
69             d += (DEPTH / 8);
70             bitmask >>= 1;
71         }
72         dst += dstpitch;
73     }
74 }
75
76 /* NOTE: srcpitch is ignored */
77 static void
78 glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH)
79      (CirrusVGAState * s, uint8_t * dst,
80       const uint8_t * src, 
81       int dstpitch, int srcpitch, 
82       int bltwidth, int bltheight)
83 {
84     uint8_t *d;
85     int x, y;
86     unsigned bits;
87     unsigned int col;
88     unsigned bitmask;
89     unsigned index;
90     int srcskipleft = 0;
91
92     col = s->cirrus_blt_bgcol;
93     for(y = 0; y < bltheight; y++) {
94         bitmask = 0x80 >> srcskipleft;
95         bits = *src++;
96         d = dst;
97         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
98             if ((bitmask & 0xff) == 0) {
99                 bitmask = 0x80;
100                 bits = *src++;
101             }
102             index = (bits & bitmask);
103             if (!index) {
104                 PUTPIXEL();
105             }
106             d += (DEPTH / 8);
107             bitmask >>= 1;
108         }
109         dst += dstpitch;
110     }
111 }
112
113 static void
114 glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
115      (CirrusVGAState * s, uint8_t * dst,
116       const uint8_t * src, 
117       int dstpitch, int srcpitch, 
118       int bltwidth, int bltheight)
119 {
120     uint32_t colors[2];
121     uint8_t *d;
122     int x, y;
123     unsigned bits;
124     unsigned int col;
125     unsigned bitmask;
126     int srcskipleft = 0;
127
128     colors[0] = s->cirrus_blt_bgcol;
129     colors[1] = s->cirrus_blt_fgcol;
130     for(y = 0; y < bltheight; y++) {
131         bitmask = 0x80 >> srcskipleft;
132         bits = *src++;
133         d = dst;
134         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
135             if ((bitmask & 0xff) == 0) {
136                 bitmask = 0x80;
137                 bits = *src++;
138             }
139             col = colors[!!(bits & bitmask)];
140             PUTPIXEL();
141             d += (DEPTH / 8);
142             bitmask >>= 1;
143         }
144         dst += dstpitch;
145     }
146 }
147
148 static void 
149 glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
150      (CirrusVGAState *s,
151       uint8_t *dst, int dst_pitch, 
152       int width, int height)
153 {
154     uint8_t *d, *d1;
155     uint32_t col;
156     int x, y;
157
158     col = s->cirrus_blt_fgcol;
159
160     d1 = dst;
161     for(y = 0; y < height; y++) {
162         d = d1;
163         for(x = 0; x < width; x += (DEPTH / 8)) {
164             PUTPIXEL();
165             d += (DEPTH / 8);
166         }
167         d1 += dst_pitch;
168     }
169 }
170
171 #undef DEPTH
172 #undef PUTPIXEL