]>
Commit | Line | Data |
---|---|---|
a5082316 FB |
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 | ||
e69390ce FB |
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; | |
b30d4608 FB |
70 | #elif DEPTH == 24 |
71 | { | |
72 | const uint8_t *src2 = src1 + pattern_x * 3; | |
73 | col = src2[0] | (src2[1] << 8) | (src2[2] << 16); | |
74 | pattern_x = (pattern_x + 1) & 7; | |
75 | } | |
e69390ce FB |
76 | #else |
77 | col = ((uint32_t *)(src1 + pattern_x))[0]; | |
78 | pattern_x = (pattern_x + 4) & 31; | |
79 | #endif | |
80 | PUTPIXEL(); | |
81 | d += (DEPTH / 8); | |
82 | } | |
83 | pattern_y = (pattern_y + 1) & 7; | |
84 | dst += dstpitch; | |
85 | } | |
86 | } | |
87 | ||
4c8732d7 | 88 | /* NOTE: srcpitch is ignored */ |
a5082316 FB |
89 | static void |
90 | glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) | |
91 | (CirrusVGAState * s, uint8_t * dst, | |
4c8732d7 | 92 | const uint8_t * src, |
a5082316 FB |
93 | int dstpitch, int srcpitch, |
94 | int bltwidth, int bltheight) | |
95 | { | |
a5082316 FB |
96 | uint8_t *d; |
97 | int x, y; | |
b30d4608 | 98 | unsigned bits, bits_xor; |
a5082316 FB |
99 | unsigned int col; |
100 | unsigned bitmask; | |
101 | unsigned index; | |
102 | int srcskipleft = 0; | |
103 | ||
b30d4608 FB |
104 | if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { |
105 | bits_xor = 0xff; | |
106 | col = s->cirrus_blt_bgcol; | |
107 | } else { | |
108 | bits_xor = 0x00; | |
109 | col = s->cirrus_blt_fgcol; | |
110 | } | |
111 | ||
a5082316 | 112 | for(y = 0; y < bltheight; y++) { |
a5082316 | 113 | bitmask = 0x80 >> srcskipleft; |
b30d4608 | 114 | bits = *src++ ^ bits_xor; |
a5082316 FB |
115 | d = dst; |
116 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | |
117 | if ((bitmask & 0xff) == 0) { | |
118 | bitmask = 0x80; | |
b30d4608 | 119 | bits = *src++ ^ bits_xor; |
a5082316 FB |
120 | } |
121 | index = (bits & bitmask); | |
122 | if (index) { | |
123 | PUTPIXEL(); | |
124 | } | |
125 | d += (DEPTH / 8); | |
126 | bitmask >>= 1; | |
127 | } | |
4c8732d7 FB |
128 | dst += dstpitch; |
129 | } | |
130 | } | |
131 | ||
4c8732d7 | 132 | static void |
b30d4608 | 133 | glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) |
4c8732d7 FB |
134 | (CirrusVGAState * s, uint8_t * dst, |
135 | const uint8_t * src, | |
136 | int dstpitch, int srcpitch, | |
137 | int bltwidth, int bltheight) | |
138 | { | |
b30d4608 | 139 | uint32_t colors[2]; |
4c8732d7 FB |
140 | uint8_t *d; |
141 | int x, y; | |
142 | unsigned bits; | |
143 | unsigned int col; | |
144 | unsigned bitmask; | |
4c8732d7 FB |
145 | int srcskipleft = 0; |
146 | ||
b30d4608 FB |
147 | colors[0] = s->cirrus_blt_bgcol; |
148 | colors[1] = s->cirrus_blt_fgcol; | |
4c8732d7 FB |
149 | for(y = 0; y < bltheight; y++) { |
150 | bitmask = 0x80 >> srcskipleft; | |
151 | bits = *src++; | |
152 | d = dst; | |
153 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | |
154 | if ((bitmask & 0xff) == 0) { | |
155 | bitmask = 0x80; | |
156 | bits = *src++; | |
157 | } | |
b30d4608 FB |
158 | col = colors[!!(bits & bitmask)]; |
159 | PUTPIXEL(); | |
160 | d += (DEPTH / 8); | |
161 | bitmask >>= 1; | |
162 | } | |
163 | dst += dstpitch; | |
164 | } | |
165 | } | |
166 | ||
167 | static void | |
168 | glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) | |
169 | (CirrusVGAState * s, uint8_t * dst, | |
170 | const uint8_t * src, | |
171 | int dstpitch, int srcpitch, | |
172 | int bltwidth, int bltheight) | |
173 | { | |
174 | uint8_t *d; | |
175 | int x, y, bitpos, pattern_y; | |
176 | unsigned int bits, bits_xor; | |
177 | unsigned int col; | |
178 | ||
179 | if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
180 | bits_xor = 0xff; | |
181 | col = s->cirrus_blt_bgcol; | |
182 | } else { | |
183 | bits_xor = 0x00; | |
184 | col = s->cirrus_blt_fgcol; | |
185 | } | |
186 | pattern_y = s->cirrus_blt_srcaddr & 7; | |
187 | ||
188 | for(y = 0; y < bltheight; y++) { | |
189 | bits = src[pattern_y] ^ bits_xor; | |
190 | bitpos = 7; | |
191 | d = dst; | |
192 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | |
193 | if ((bits >> bitpos) & 1) { | |
4c8732d7 FB |
194 | PUTPIXEL(); |
195 | } | |
196 | d += (DEPTH / 8); | |
b30d4608 | 197 | bitpos = (bitpos - 1) & 7; |
4c8732d7 | 198 | } |
b30d4608 | 199 | pattern_y = (pattern_y + 1) & 7; |
a5082316 FB |
200 | dst += dstpitch; |
201 | } | |
202 | } | |
203 | ||
204 | static void | |
b30d4608 | 205 | glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) |
a5082316 | 206 | (CirrusVGAState * s, uint8_t * dst, |
4c8732d7 | 207 | const uint8_t * src, |
a5082316 FB |
208 | int dstpitch, int srcpitch, |
209 | int bltwidth, int bltheight) | |
210 | { | |
a5082316 FB |
211 | uint32_t colors[2]; |
212 | uint8_t *d; | |
b30d4608 FB |
213 | int x, y, bitpos, pattern_y; |
214 | unsigned int bits; | |
a5082316 | 215 | unsigned int col; |
a5082316 FB |
216 | |
217 | colors[0] = s->cirrus_blt_bgcol; | |
218 | colors[1] = s->cirrus_blt_fgcol; | |
b30d4608 FB |
219 | pattern_y = s->cirrus_blt_srcaddr & 7; |
220 | ||
a5082316 | 221 | for(y = 0; y < bltheight; y++) { |
b30d4608 FB |
222 | bits = src[pattern_y]; |
223 | bitpos = 7; | |
a5082316 FB |
224 | d = dst; |
225 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | |
b30d4608 | 226 | col = colors[(bits >> bitpos) & 1]; |
a5082316 FB |
227 | PUTPIXEL(); |
228 | d += (DEPTH / 8); | |
b30d4608 | 229 | bitpos = (bitpos - 1) & 7; |
a5082316 | 230 | } |
b30d4608 | 231 | pattern_y = (pattern_y + 1) & 7; |
a5082316 FB |
232 | dst += dstpitch; |
233 | } | |
234 | } | |
235 | ||
236 | static void | |
237 | glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH) | |
238 | (CirrusVGAState *s, | |
239 | uint8_t *dst, int dst_pitch, | |
240 | int width, int height) | |
241 | { | |
242 | uint8_t *d, *d1; | |
243 | uint32_t col; | |
244 | int x, y; | |
245 | ||
246 | col = s->cirrus_blt_fgcol; | |
247 | ||
248 | d1 = dst; | |
249 | for(y = 0; y < height; y++) { | |
250 | d = d1; | |
251 | for(x = 0; x < width; x += (DEPTH / 8)) { | |
252 | PUTPIXEL(); | |
253 | d += (DEPTH / 8); | |
254 | } | |
255 | d1 += dst_pitch; | |
256 | } | |
257 | } | |
258 | ||
259 | #undef DEPTH | |
260 | #undef PUTPIXEL |