|
1
2
|
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
|
ths
authored
|
3
|
*
|
|
4
|
* Copyright (c) 2004 Fabrice Bellard
|
ths
authored
|
5
|
*
|
|
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if DEPTH == 8
#define PUTPIXEL() ROP_OP(d[0], col)
#elif DEPTH == 16
#define PUTPIXEL() ROP_OP(((uint16_t *)d)[0], col);
#elif DEPTH == 24
#define PUTPIXEL() ROP_OP(d[0], col); \
ROP_OP(d[1], (col >> 8)); \
ROP_OP(d[2], (col >> 16))
#elif DEPTH == 32
#define PUTPIXEL() ROP_OP(((uint32_t *)d)[0], col)
#else
#error unsupported DEPTH
|
ths
authored
|
37
|
#endif
|
|
38
|
|
|
39
40
41
|
static void
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst,
|
ths
authored
|
42
43
|
const uint8_t * src,
int dstpitch, int srcpitch,
|
|
44
45
46
47
48
49
|
int bltwidth, int bltheight)
{
uint8_t *d;
int x, y, pattern_y, pattern_pitch, pattern_x;
unsigned int col;
const uint8_t *src1;
|
|
50
51
52
|
#if DEPTH == 24
int skipleft = s->gr[0x2f] & 0x1f;
#else
|
|
53
|
int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8);
|
|
54
|
#endif
|
|
55
56
57
58
59
60
61
62
63
64
|
#if DEPTH == 8
pattern_pitch = 8;
#elif DEPTH == 16
pattern_pitch = 16;
#else
pattern_pitch = 32;
#endif
pattern_y = s->cirrus_blt_srcaddr & 7;
for(y = 0; y < bltheight; y++) {
|
|
65
|
pattern_x = skipleft;
|
|
66
|
d = dst + skipleft;
|
|
67
|
src1 = src + pattern_y * pattern_pitch;
|
|
68
|
for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
|
|
69
70
71
72
73
74
|
#if DEPTH == 8
col = src1[pattern_x];
pattern_x = (pattern_x + 1) & 7;
#elif DEPTH == 16
col = ((uint16_t *)(src1 + pattern_x))[0];
pattern_x = (pattern_x + 2) & 15;
|
|
75
76
77
78
79
80
|
#elif DEPTH == 24
{
const uint8_t *src2 = src1 + pattern_x * 3;
col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
pattern_x = (pattern_x + 1) & 7;
}
|
|
81
82
83
84
85
86
87
88
89
90
91
92
|
#else
col = ((uint32_t *)(src1 + pattern_x))[0];
pattern_x = (pattern_x + 4) & 31;
#endif
PUTPIXEL();
d += (DEPTH / 8);
}
pattern_y = (pattern_y + 1) & 7;
dst += dstpitch;
}
}
|
|
93
|
/* NOTE: srcpitch is ignored */
|
|
94
95
96
|
static void
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst,
|
ths
authored
|
97
98
|
const uint8_t * src,
int dstpitch, int srcpitch,
|
|
99
100
101
102
|
int bltwidth, int bltheight)
{
uint8_t *d;
int x, y;
|
|
103
|
unsigned bits, bits_xor;
|
|
104
105
106
|
unsigned int col;
unsigned bitmask;
unsigned index;
|
|
107
108
109
110
|
#if DEPTH == 24
int dstskipleft = s->gr[0x2f] & 0x1f;
int srcskipleft = dstskipleft / 3;
#else
|
|
111
112
|
int srcskipleft = s->gr[0x2f] & 0x07;
int dstskipleft = srcskipleft * (DEPTH / 8);
|
|
113
|
#endif
|
|
114
|
|
|
115
116
117
118
119
120
121
122
|
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
bits_xor = 0xff;
col = s->cirrus_blt_bgcol;
} else {
bits_xor = 0x00;
col = s->cirrus_blt_fgcol;
}
|
|
123
124
|
for(y = 0; y < bltheight; y++) {
bitmask = 0x80 >> srcskipleft;
|
|
125
|
bits = *src++ ^ bits_xor;
|
|
126
127
|
d = dst + dstskipleft;
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
|
128
129
|
if ((bitmask & 0xff) == 0) {
bitmask = 0x80;
|
|
130
|
bits = *src++ ^ bits_xor;
|
|
131
132
133
134
135
136
137
138
|
}
index = (bits & bitmask);
if (index) {
PUTPIXEL();
}
d += (DEPTH / 8);
bitmask >>= 1;
}
|
|
139
140
141
142
143
|
dst += dstpitch;
}
}
static void
|
|
144
|
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
|
|
145
|
(CirrusVGAState * s, uint8_t * dst,
|
ths
authored
|
146
147
|
const uint8_t * src,
int dstpitch, int srcpitch,
|
|
148
149
|
int bltwidth, int bltheight)
{
|
|
150
|
uint32_t colors[2];
|
|
151
152
153
154
155
|
uint8_t *d;
int x, y;
unsigned bits;
unsigned int col;
unsigned bitmask;
|
|
156
157
|
int srcskipleft = s->gr[0x2f] & 0x07;
int dstskipleft = srcskipleft * (DEPTH / 8);
|
|
158
|
|
|
159
160
|
colors[0] = s->cirrus_blt_bgcol;
colors[1] = s->cirrus_blt_fgcol;
|
|
161
162
163
|
for(y = 0; y < bltheight; y++) {
bitmask = 0x80 >> srcskipleft;
bits = *src++;
|
|
164
165
|
d = dst + dstskipleft;
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
|
166
167
168
169
|
if ((bitmask & 0xff) == 0) {
bitmask = 0x80;
bits = *src++;
}
|
|
170
171
172
173
174
175
176
177
178
179
180
181
|
col = colors[!!(bits & bitmask)];
PUTPIXEL();
d += (DEPTH / 8);
bitmask >>= 1;
}
dst += dstpitch;
}
}
static void
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst,
|
ths
authored
|
182
183
|
const uint8_t * src,
int dstpitch, int srcpitch,
|
|
184
185
186
187
188
189
|
int bltwidth, int bltheight)
{
uint8_t *d;
int x, y, bitpos, pattern_y;
unsigned int bits, bits_xor;
unsigned int col;
|
|
190
191
192
193
|
#if DEPTH == 24
int dstskipleft = s->gr[0x2f] & 0x1f;
int srcskipleft = dstskipleft / 3;
#else
|
|
194
195
|
int srcskipleft = s->gr[0x2f] & 0x07;
int dstskipleft = srcskipleft * (DEPTH / 8);
|
|
196
|
#endif
|
|
197
198
199
200
201
202
203
204
205
206
207
208
|
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
bits_xor = 0xff;
col = s->cirrus_blt_bgcol;
} else {
bits_xor = 0x00;
col = s->cirrus_blt_fgcol;
}
pattern_y = s->cirrus_blt_srcaddr & 7;
for(y = 0; y < bltheight; y++) {
bits = src[pattern_y] ^ bits_xor;
|
|
209
210
211
|
bitpos = 7 - srcskipleft;
d = dst + dstskipleft;
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
|
212
|
if ((bits >> bitpos) & 1) {
|
|
213
214
215
|
PUTPIXEL();
}
d += (DEPTH / 8);
|
|
216
|
bitpos = (bitpos - 1) & 7;
|
|
217
|
}
|
|
218
|
pattern_y = (pattern_y + 1) & 7;
|
|
219
220
221
222
223
|
dst += dstpitch;
}
}
static void
|
|
224
|
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
|
225
|
(CirrusVGAState * s, uint8_t * dst,
|
ths
authored
|
226
227
|
const uint8_t * src,
int dstpitch, int srcpitch,
|
|
228
229
230
231
|
int bltwidth, int bltheight)
{
uint32_t colors[2];
uint8_t *d;
|
|
232
233
|
int x, y, bitpos, pattern_y;
unsigned int bits;
|
|
234
|
unsigned int col;
|
|
235
236
|
int srcskipleft = s->gr[0x2f] & 0x07;
int dstskipleft = srcskipleft * (DEPTH / 8);
|
|
237
238
239
|
colors[0] = s->cirrus_blt_bgcol;
colors[1] = s->cirrus_blt_fgcol;
|
|
240
241
|
pattern_y = s->cirrus_blt_srcaddr & 7;
|
|
242
|
for(y = 0; y < bltheight; y++) {
|
|
243
|
bits = src[pattern_y];
|
|
244
245
246
|
bitpos = 7 - srcskipleft;
d = dst + dstskipleft;
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
|
247
|
col = colors[(bits >> bitpos) & 1];
|
|
248
249
|
PUTPIXEL();
d += (DEPTH / 8);
|
|
250
|
bitpos = (bitpos - 1) & 7;
|
|
251
|
}
|
|
252
|
pattern_y = (pattern_y + 1) & 7;
|
|
253
254
255
256
|
dst += dstpitch;
}
}
|
ths
authored
|
257
|
static void
|
|
258
259
|
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
(CirrusVGAState *s,
|
ths
authored
|
260
|
uint8_t *dst, int dst_pitch,
|
|
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
int width, int height)
{
uint8_t *d, *d1;
uint32_t col;
int x, y;
col = s->cirrus_blt_fgcol;
d1 = dst;
for(y = 0; y < height; y++) {
d = d1;
for(x = 0; x < width; x += (DEPTH / 8)) {
PUTPIXEL();
d += (DEPTH / 8);
}
d1 += dst_pitch;
}
}
#undef DEPTH
#undef PUTPIXEL
|