]> git.proxmox.com Git - mirror_qemu.git/blame - hw/display/cirrus_vga_rop2.h
cirrus: stop passing around dst pointers in the blitter
[mirror_qemu.git] / hw / display / cirrus_vga_rop2.h
CommitLineData
a5082316
FB
1/*
2 * QEMU Cirrus CLGD 54xx VGA Emulator.
5fafdf24 3 *
a5082316 4 * Copyright (c) 2004 Fabrice Bellard
5fafdf24 5 *
a5082316
FB
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
026aeffc 26#define PUTPIXEL(s, a, c) ROP_OP(s, a, c)
a5082316 27#elif DEPTH == 16
026aeffc 28#define PUTPIXEL(s, a, c) ROP_OP_16(s, a, c)
a5082316 29#elif DEPTH == 24
026aeffc
GH
30#define PUTPIXEL(s, a, c) do { \
31 ROP_OP(s, a, c); \
32 ROP_OP(s, a + 1, (col >> 8)); \
33 ROP_OP(s, a + 2, (col >> 16)); \
34 } while (0)
a5082316 35#elif DEPTH == 32
026aeffc 36#define PUTPIXEL(s, a, c) ROP_OP_32(s, a, c)
a5082316
FB
37#else
38#error unsupported DEPTH
3b46e624 39#endif
a5082316 40
e69390ce
FB
41static void
42glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
026aeffc
GH
43 (CirrusVGAState *s, uint32_t dstaddr,
44 const uint8_t *src,
5fafdf24 45 int dstpitch, int srcpitch,
e69390ce
FB
46 int bltwidth, int bltheight)
47{
026aeffc 48 uint32_t addr;
e69390ce
FB
49 int x, y, pattern_y, pattern_pitch, pattern_x;
50 unsigned int col;
51 const uint8_t *src1;
ad81218e 52#if DEPTH == 24
4e12cd94 53 int skipleft = s->vga.gr[0x2f] & 0x1f;
ad81218e 54#else
4e12cd94 55 int skipleft = (s->vga.gr[0x2f] & 0x07) * (DEPTH / 8);
ad81218e 56#endif
e69390ce
FB
57
58#if DEPTH == 8
59 pattern_pitch = 8;
60#elif DEPTH == 16
61 pattern_pitch = 16;
62#else
63 pattern_pitch = 32;
64#endif
65 pattern_y = s->cirrus_blt_srcaddr & 7;
e69390ce 66 for(y = 0; y < bltheight; y++) {
2f636b45 67 pattern_x = skipleft;
026aeffc 68 addr = dstaddr + skipleft;
e69390ce 69 src1 = src + pattern_y * pattern_pitch;
e3a4e4b6 70 for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
e69390ce
FB
71#if DEPTH == 8
72 col = src1[pattern_x];
73 pattern_x = (pattern_x + 1) & 7;
74#elif DEPTH == 16
75 col = ((uint16_t *)(src1 + pattern_x))[0];
76 pattern_x = (pattern_x + 2) & 15;
b30d4608
FB
77#elif DEPTH == 24
78 {
79 const uint8_t *src2 = src1 + pattern_x * 3;
80 col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
81 pattern_x = (pattern_x + 1) & 7;
82 }
e69390ce
FB
83#else
84 col = ((uint32_t *)(src1 + pattern_x))[0];
85 pattern_x = (pattern_x + 4) & 31;
86#endif
026aeffc
GH
87 PUTPIXEL(s, addr, col);
88 addr += (DEPTH / 8);
e69390ce
FB
89 }
90 pattern_y = (pattern_y + 1) & 7;
026aeffc 91 dstaddr += dstpitch;
e69390ce
FB
92 }
93}
94
4c8732d7 95/* NOTE: srcpitch is ignored */
a5082316
FB
96static void
97glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
026aeffc
GH
98 (CirrusVGAState *s, uint32_t dstaddr,
99 const uint8_t *src,
5fafdf24 100 int dstpitch, int srcpitch,
a5082316
FB
101 int bltwidth, int bltheight)
102{
026aeffc 103 uint32_t addr;
a5082316 104 int x, y;
b30d4608 105 unsigned bits, bits_xor;
a5082316
FB
106 unsigned int col;
107 unsigned bitmask;
108 unsigned index;
ad81218e 109#if DEPTH == 24
4e12cd94 110 int dstskipleft = s->vga.gr[0x2f] & 0x1f;
ad81218e
FB
111 int srcskipleft = dstskipleft / 3;
112#else
4e12cd94 113 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 114 int dstskipleft = srcskipleft * (DEPTH / 8);
ad81218e 115#endif
a5082316 116
b30d4608
FB
117 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
118 bits_xor = 0xff;
119 col = s->cirrus_blt_bgcol;
120 } else {
121 bits_xor = 0x00;
122 col = s->cirrus_blt_fgcol;
123 }
124
a5082316 125 for(y = 0; y < bltheight; y++) {
a5082316 126 bitmask = 0x80 >> srcskipleft;
b30d4608 127 bits = *src++ ^ bits_xor;
026aeffc 128 addr = dstaddr + dstskipleft;
e3a4e4b6 129 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
a5082316
FB
130 if ((bitmask & 0xff) == 0) {
131 bitmask = 0x80;
b30d4608 132 bits = *src++ ^ bits_xor;
a5082316
FB
133 }
134 index = (bits & bitmask);
135 if (index) {
026aeffc 136 PUTPIXEL(s, addr, col);
a5082316 137 }
026aeffc 138 addr += (DEPTH / 8);
a5082316
FB
139 bitmask >>= 1;
140 }
026aeffc 141 dstaddr += dstpitch;
4c8732d7
FB
142 }
143}
144
4c8732d7 145static void
b30d4608 146glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
026aeffc
GH
147 (CirrusVGAState *s, uint32_t dstaddr,
148 const uint8_t *src,
5fafdf24 149 int dstpitch, int srcpitch,
4c8732d7
FB
150 int bltwidth, int bltheight)
151{
b30d4608 152 uint32_t colors[2];
026aeffc 153 uint32_t addr;
4c8732d7
FB
154 int x, y;
155 unsigned bits;
156 unsigned int col;
157 unsigned bitmask;
4e12cd94 158 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 159 int dstskipleft = srcskipleft * (DEPTH / 8);
4c8732d7 160
b30d4608
FB
161 colors[0] = s->cirrus_blt_bgcol;
162 colors[1] = s->cirrus_blt_fgcol;
4c8732d7
FB
163 for(y = 0; y < bltheight; y++) {
164 bitmask = 0x80 >> srcskipleft;
165 bits = *src++;
026aeffc 166 addr = dstaddr + dstskipleft;
e3a4e4b6 167 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
4c8732d7
FB
168 if ((bitmask & 0xff) == 0) {
169 bitmask = 0x80;
170 bits = *src++;
171 }
b30d4608 172 col = colors[!!(bits & bitmask)];
026aeffc
GH
173 PUTPIXEL(s, addr, col);
174 addr += (DEPTH / 8);
b30d4608
FB
175 bitmask >>= 1;
176 }
026aeffc 177 dstaddr += dstpitch;
b30d4608
FB
178 }
179}
180
181static void
182glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
026aeffc
GH
183 (CirrusVGAState *s, uint32_t dstaddr,
184 const uint8_t *src,
5fafdf24 185 int dstpitch, int srcpitch,
b30d4608
FB
186 int bltwidth, int bltheight)
187{
026aeffc 188 uint32_t addr;
b30d4608
FB
189 int x, y, bitpos, pattern_y;
190 unsigned int bits, bits_xor;
191 unsigned int col;
ad81218e 192#if DEPTH == 24
4e12cd94 193 int dstskipleft = s->vga.gr[0x2f] & 0x1f;
ad81218e
FB
194 int srcskipleft = dstskipleft / 3;
195#else
4e12cd94 196 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 197 int dstskipleft = srcskipleft * (DEPTH / 8);
ad81218e 198#endif
b30d4608
FB
199
200 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
201 bits_xor = 0xff;
202 col = s->cirrus_blt_bgcol;
203 } else {
204 bits_xor = 0x00;
205 col = s->cirrus_blt_fgcol;
206 }
207 pattern_y = s->cirrus_blt_srcaddr & 7;
208
209 for(y = 0; y < bltheight; y++) {
210 bits = src[pattern_y] ^ bits_xor;
e3a4e4b6 211 bitpos = 7 - srcskipleft;
026aeffc 212 addr = dstaddr + dstskipleft;
e3a4e4b6 213 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
b30d4608 214 if ((bits >> bitpos) & 1) {
026aeffc 215 PUTPIXEL(s, addr, col);
4c8732d7 216 }
026aeffc 217 addr += (DEPTH / 8);
b30d4608 218 bitpos = (bitpos - 1) & 7;
4c8732d7 219 }
b30d4608 220 pattern_y = (pattern_y + 1) & 7;
026aeffc 221 dstaddr += dstpitch;
a5082316
FB
222 }
223}
224
225static void
b30d4608 226glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
026aeffc
GH
227 (CirrusVGAState *s, uint32_t dstaddr,
228 const uint8_t *src,
5fafdf24 229 int dstpitch, int srcpitch,
a5082316
FB
230 int bltwidth, int bltheight)
231{
a5082316 232 uint32_t colors[2];
026aeffc 233 uint32_t addr;
b30d4608
FB
234 int x, y, bitpos, pattern_y;
235 unsigned int bits;
a5082316 236 unsigned int col;
4e12cd94 237 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 238 int dstskipleft = srcskipleft * (DEPTH / 8);
a5082316
FB
239
240 colors[0] = s->cirrus_blt_bgcol;
241 colors[1] = s->cirrus_blt_fgcol;
b30d4608
FB
242 pattern_y = s->cirrus_blt_srcaddr & 7;
243
a5082316 244 for(y = 0; y < bltheight; y++) {
b30d4608 245 bits = src[pattern_y];
e3a4e4b6 246 bitpos = 7 - srcskipleft;
026aeffc 247 addr = dstaddr + dstskipleft;
e3a4e4b6 248 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
b30d4608 249 col = colors[(bits >> bitpos) & 1];
026aeffc
GH
250 PUTPIXEL(s, addr, col);
251 addr += (DEPTH / 8);
b30d4608 252 bitpos = (bitpos - 1) & 7;
a5082316 253 }
b30d4608 254 pattern_y = (pattern_y + 1) & 7;
026aeffc 255 dstaddr += dstpitch;
a5082316
FB
256 }
257}
258
5fafdf24 259static void
a5082316
FB
260glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
261 (CirrusVGAState *s,
026aeffc 262 uint32_t dstaddr, int dst_pitch,
a5082316
FB
263 int width, int height)
264{
026aeffc 265 uint32_t addr;
a5082316
FB
266 uint32_t col;
267 int x, y;
268
269 col = s->cirrus_blt_fgcol;
270
a5082316 271 for(y = 0; y < height; y++) {
026aeffc 272 addr = dstaddr;
a5082316 273 for(x = 0; x < width; x += (DEPTH / 8)) {
026aeffc
GH
274 PUTPIXEL(s, addr, col);
275 addr += (DEPTH / 8);
a5082316 276 }
026aeffc 277 dstaddr += dst_pitch;
a5082316
FB
278 }
279}
280
281#undef DEPTH
282#undef PUTPIXEL