]> git.proxmox.com Git - mirror_qemu.git/blame - hw/display/cirrus_vga_rop2.h
Merge remote-tracking branch 'remotes/stsquad/tags/pull-mttcg-fixups-for-rc2-280317...
[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); \
db6cd4c8
GH
32 ROP_OP(s, a + 1, (c >> 8)); \
33 ROP_OP(s, a + 2, (c >> 16)); \
026aeffc 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 43 (CirrusVGAState *s, uint32_t dstaddr,
ffaf8577 44 uint32_t srcaddr,
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;
ffaf8577 51 uint32_t src1addr;
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;
ffaf8577 69 src1addr = srcaddr + pattern_y * pattern_pitch;
e3a4e4b6 70 for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
e69390ce 71#if DEPTH == 8
ffaf8577 72 col = cirrus_src(s, src1addr + pattern_x);
e69390ce
FB
73 pattern_x = (pattern_x + 1) & 7;
74#elif DEPTH == 16
ffaf8577 75 col = cirrus_src16(s, src1addr + pattern_x);
e69390ce 76 pattern_x = (pattern_x + 2) & 15;
b30d4608
FB
77#elif DEPTH == 24
78 {
ffaf8577
GH
79 uint32_t src2addr = src1addr + pattern_x * 3;
80 col = cirrus_src(s, src2addr) |
81 (cirrus_src(s, src2addr + 1) << 8) |
82 (cirrus_src(s, src2addr + 2) << 16);
b30d4608
FB
83 pattern_x = (pattern_x + 1) & 7;
84 }
e69390ce 85#else
ffaf8577 86 col = cirrus_src32(s, src1addr + pattern_x);
e69390ce
FB
87 pattern_x = (pattern_x + 4) & 31;
88#endif
026aeffc
GH
89 PUTPIXEL(s, addr, col);
90 addr += (DEPTH / 8);
e69390ce
FB
91 }
92 pattern_y = (pattern_y + 1) & 7;
026aeffc 93 dstaddr += dstpitch;
e69390ce
FB
94 }
95}
96
4c8732d7 97/* NOTE: srcpitch is ignored */
a5082316
FB
98static void
99glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
026aeffc 100 (CirrusVGAState *s, uint32_t dstaddr,
ffaf8577 101 uint32_t srcaddr,
5fafdf24 102 int dstpitch, int srcpitch,
a5082316
FB
103 int bltwidth, int bltheight)
104{
026aeffc 105 uint32_t addr;
a5082316 106 int x, y;
b30d4608 107 unsigned bits, bits_xor;
a5082316
FB
108 unsigned int col;
109 unsigned bitmask;
110 unsigned index;
ad81218e 111#if DEPTH == 24
4e12cd94 112 int dstskipleft = s->vga.gr[0x2f] & 0x1f;
ad81218e
FB
113 int srcskipleft = dstskipleft / 3;
114#else
4e12cd94 115 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 116 int dstskipleft = srcskipleft * (DEPTH / 8);
ad81218e 117#endif
a5082316 118
b30d4608
FB
119 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
120 bits_xor = 0xff;
121 col = s->cirrus_blt_bgcol;
122 } else {
123 bits_xor = 0x00;
124 col = s->cirrus_blt_fgcol;
125 }
126
a5082316 127 for(y = 0; y < bltheight; y++) {
a5082316 128 bitmask = 0x80 >> srcskipleft;
ffaf8577 129 bits = cirrus_src(s, srcaddr++) ^ bits_xor;
026aeffc 130 addr = dstaddr + dstskipleft;
e3a4e4b6 131 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
a5082316
FB
132 if ((bitmask & 0xff) == 0) {
133 bitmask = 0x80;
ffaf8577 134 bits = cirrus_src(s, srcaddr++) ^ bits_xor;
a5082316
FB
135 }
136 index = (bits & bitmask);
137 if (index) {
026aeffc 138 PUTPIXEL(s, addr, col);
a5082316 139 }
026aeffc 140 addr += (DEPTH / 8);
a5082316
FB
141 bitmask >>= 1;
142 }
026aeffc 143 dstaddr += dstpitch;
4c8732d7
FB
144 }
145}
146
4c8732d7 147static void
b30d4608 148glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
026aeffc 149 (CirrusVGAState *s, uint32_t dstaddr,
ffaf8577 150 uint32_t srcaddr,
5fafdf24 151 int dstpitch, int srcpitch,
4c8732d7
FB
152 int bltwidth, int bltheight)
153{
b30d4608 154 uint32_t colors[2];
026aeffc 155 uint32_t addr;
4c8732d7
FB
156 int x, y;
157 unsigned bits;
158 unsigned int col;
159 unsigned bitmask;
4e12cd94 160 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 161 int dstskipleft = srcskipleft * (DEPTH / 8);
4c8732d7 162
b30d4608
FB
163 colors[0] = s->cirrus_blt_bgcol;
164 colors[1] = s->cirrus_blt_fgcol;
4c8732d7
FB
165 for(y = 0; y < bltheight; y++) {
166 bitmask = 0x80 >> srcskipleft;
ffaf8577 167 bits = cirrus_src(s, srcaddr++);
026aeffc 168 addr = dstaddr + dstskipleft;
e3a4e4b6 169 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
4c8732d7
FB
170 if ((bitmask & 0xff) == 0) {
171 bitmask = 0x80;
ffaf8577 172 bits = cirrus_src(s, srcaddr++);
4c8732d7 173 }
b30d4608 174 col = colors[!!(bits & bitmask)];
026aeffc
GH
175 PUTPIXEL(s, addr, col);
176 addr += (DEPTH / 8);
b30d4608
FB
177 bitmask >>= 1;
178 }
026aeffc 179 dstaddr += dstpitch;
b30d4608
FB
180 }
181}
182
183static void
184glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
026aeffc 185 (CirrusVGAState *s, uint32_t dstaddr,
ffaf8577 186 uint32_t srcaddr,
5fafdf24 187 int dstpitch, int srcpitch,
b30d4608
FB
188 int bltwidth, int bltheight)
189{
026aeffc 190 uint32_t addr;
b30d4608
FB
191 int x, y, bitpos, pattern_y;
192 unsigned int bits, bits_xor;
193 unsigned int col;
ad81218e 194#if DEPTH == 24
4e12cd94 195 int dstskipleft = s->vga.gr[0x2f] & 0x1f;
ad81218e
FB
196 int srcskipleft = dstskipleft / 3;
197#else
4e12cd94 198 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 199 int dstskipleft = srcskipleft * (DEPTH / 8);
ad81218e 200#endif
b30d4608
FB
201
202 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
203 bits_xor = 0xff;
204 col = s->cirrus_blt_bgcol;
205 } else {
206 bits_xor = 0x00;
207 col = s->cirrus_blt_fgcol;
208 }
209 pattern_y = s->cirrus_blt_srcaddr & 7;
210
211 for(y = 0; y < bltheight; y++) {
ffaf8577 212 bits = cirrus_src(s, srcaddr + pattern_y) ^ bits_xor;
e3a4e4b6 213 bitpos = 7 - srcskipleft;
026aeffc 214 addr = dstaddr + dstskipleft;
e3a4e4b6 215 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
b30d4608 216 if ((bits >> bitpos) & 1) {
026aeffc 217 PUTPIXEL(s, addr, col);
4c8732d7 218 }
026aeffc 219 addr += (DEPTH / 8);
b30d4608 220 bitpos = (bitpos - 1) & 7;
4c8732d7 221 }
b30d4608 222 pattern_y = (pattern_y + 1) & 7;
026aeffc 223 dstaddr += dstpitch;
a5082316
FB
224 }
225}
226
227static void
b30d4608 228glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
026aeffc 229 (CirrusVGAState *s, uint32_t dstaddr,
ffaf8577 230 uint32_t srcaddr,
5fafdf24 231 int dstpitch, int srcpitch,
a5082316
FB
232 int bltwidth, int bltheight)
233{
a5082316 234 uint32_t colors[2];
026aeffc 235 uint32_t addr;
b30d4608
FB
236 int x, y, bitpos, pattern_y;
237 unsigned int bits;
a5082316 238 unsigned int col;
4e12cd94 239 int srcskipleft = s->vga.gr[0x2f] & 0x07;
e3a4e4b6 240 int dstskipleft = srcskipleft * (DEPTH / 8);
a5082316
FB
241
242 colors[0] = s->cirrus_blt_bgcol;
243 colors[1] = s->cirrus_blt_fgcol;
b30d4608
FB
244 pattern_y = s->cirrus_blt_srcaddr & 7;
245
a5082316 246 for(y = 0; y < bltheight; y++) {
ffaf8577 247 bits = cirrus_src(s, srcaddr + pattern_y);
e3a4e4b6 248 bitpos = 7 - srcskipleft;
026aeffc 249 addr = dstaddr + dstskipleft;
e3a4e4b6 250 for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
b30d4608 251 col = colors[(bits >> bitpos) & 1];
026aeffc
GH
252 PUTPIXEL(s, addr, col);
253 addr += (DEPTH / 8);
b30d4608 254 bitpos = (bitpos - 1) & 7;
a5082316 255 }
b30d4608 256 pattern_y = (pattern_y + 1) & 7;
026aeffc 257 dstaddr += dstpitch;
a5082316
FB
258 }
259}
260
5fafdf24 261static void
a5082316
FB
262glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
263 (CirrusVGAState *s,
026aeffc 264 uint32_t dstaddr, int dst_pitch,
a5082316
FB
265 int width, int height)
266{
026aeffc 267 uint32_t addr;
a5082316
FB
268 uint32_t col;
269 int x, y;
270
271 col = s->cirrus_blt_fgcol;
272
a5082316 273 for(y = 0; y < height; y++) {
026aeffc 274 addr = dstaddr;
a5082316 275 for(x = 0; x < width; x += (DEPTH / 8)) {
026aeffc
GH
276 PUTPIXEL(s, addr, col);
277 addr += (DEPTH / 8);
a5082316 278 }
026aeffc 279 dstaddr += dst_pitch;
a5082316
FB
280 }
281}
282
283#undef DEPTH
284#undef PUTPIXEL