540e308e890659e21471c9bb21ad96bbc3462f13
[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 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
51 #if DEPTH == 8
52     pattern_pitch = 8;
53 #elif DEPTH == 16
54     pattern_pitch = 16;
55 #else
56     pattern_pitch = 32;
57 #endif
58     pattern_y = s->cirrus_blt_srcaddr & 7;
59     pattern_x = 0;
60     for(y = 0; y < bltheight; y++) {
61         d = dst;
62         src1 = src + pattern_y * pattern_pitch;
63         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
64 #if DEPTH == 8
65             col = src1[pattern_x];
66             pattern_x = (pattern_x + 1) & 7;
67 #elif DEPTH == 16
68             col = ((uint16_t *)(src1 + pattern_x))[0];
69             pattern_x = (pattern_x + 2) & 15;
70 #else
71             col = ((uint32_t *)(src1 + pattern_x))[0];
72             pattern_x = (pattern_x + 4) & 31;
73 #endif
74             PUTPIXEL();
75             d += (DEPTH / 8);
76         }
77         pattern_y = (pattern_y + 1) & 7;
78         dst += dstpitch;
79     }
80 }
81
82 /* NOTE: srcpitch is ignored */
83 static void
84 glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
85      (CirrusVGAState * s, uint8_t * dst,
86       const uint8_t * src, 
87       int dstpitch, int srcpitch, 
88       int bltwidth, int bltheight)
89 {
90     uint8_t *d;
91     int x, y;
92     unsigned bits;
93     unsigned int col;
94     unsigned bitmask;
95     unsigned index;
96     int srcskipleft = 0;
97
98     col = s->cirrus_blt_fgcol;
99     for(y = 0; y < bltheight; y++) {
100         bitmask = 0x80 >> srcskipleft;
101         bits = *src++;
102         d = dst;
103         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
104             if ((bitmask & 0xff) == 0) {
105                 bitmask = 0x80;
106                 bits = *src++;
107             }
108             index = (bits & bitmask);
109             if (index) {
110                 PUTPIXEL();
111             }
112             d += (DEPTH / 8);
113             bitmask >>= 1;
114         }
115         dst += dstpitch;
116     }
117 }
118
119 /* NOTE: srcpitch is ignored */
120 static void
121 glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH)
122      (CirrusVGAState * s, uint8_t * dst,
123       const uint8_t * src, 
124       int dstpitch, int srcpitch, 
125       int bltwidth, int bltheight)
126 {
127     uint8_t *d;
128     int x, y;
129     unsigned bits;
130     unsigned int col;
131     unsigned bitmask;
132     unsigned index;
133     int srcskipleft = 0;
134
135     col = s->cirrus_blt_bgcol;
136     for(y = 0; y < bltheight; y++) {
137         bitmask = 0x80 >> srcskipleft;
138         bits = *src++;
139         d = dst;
140         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
141             if ((bitmask & 0xff) == 0) {
142                 bitmask = 0x80;
143                 bits = *src++;
144             }
145             index = (bits & bitmask);
146             if (!index) {
147                 PUTPIXEL();
148             }
149             d += (DEPTH / 8);
150             bitmask >>= 1;
151         }
152         dst += dstpitch;
153     }
154 }
155
156 static void
157 glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
158      (CirrusVGAState * s, uint8_t * dst,
159       const uint8_t * src, 
160       int dstpitch, int srcpitch, 
161       int bltwidth, int bltheight)
162 {
163     uint32_t colors[2];
164     uint8_t *d;
165     int x, y;
166     unsigned bits;
167     unsigned int col;
168     unsigned bitmask;
169     int srcskipleft = 0;
170
171     colors[0] = s->cirrus_blt_bgcol;
172     colors[1] = s->cirrus_blt_fgcol;
173     for(y = 0; y < bltheight; y++) {
174         bitmask = 0x80 >> srcskipleft;
175         bits = *src++;
176         d = dst;
177         for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
178             if ((bitmask & 0xff) == 0) {
179                 bitmask = 0x80;
180                 bits = *src++;
181             }
182             col = colors[!!(bits & bitmask)];
183             PUTPIXEL();
184             d += (DEPTH / 8);
185             bitmask >>= 1;
186         }
187         dst += dstpitch;
188     }
189 }
190
191 static void 
192 glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
193      (CirrusVGAState *s,
194       uint8_t *dst, int dst_pitch, 
195       int width, int height)
196 {
197     uint8_t *d, *d1;
198     uint32_t col;
199     int x, y;
200
201     col = s->cirrus_blt_fgcol;
202
203     d1 = dst;
204     for(y = 0; y < height; y++) {
205         d = d1;
206         for(x = 0; x < width; x += (DEPTH / 8)) {
207             PUTPIXEL();
208             d += (DEPTH / 8);
209         }
210         d1 += dst_pitch;
211     }
212 }
213
214 #undef DEPTH
215 #undef PUTPIXEL