2 * QEMU Cirrus CLGD 54xx VGA Emulator.
4 * Copyright (c) 2004 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
26 #define PUTPIXEL(s, a, c) ROP_OP(s, a, c)
28 #define PUTPIXEL(s, a, c) ROP_OP_16(s, a, c)
30 #define PUTPIXEL(s, a, c) do { \
32 ROP_OP(s, a + 1, (c >> 8)); \
33 ROP_OP(s, a + 2, (c >> 16)); \
36 #define PUTPIXEL(s, a, c) ROP_OP_32(s, a, c)
38 #error unsupported DEPTH
42 glue(glue(glue(cirrus_patternfill_
, ROP_NAME
), _
),DEPTH
)
43 (CirrusVGAState
*s
, uint32_t dstaddr
,
45 int dstpitch
, int srcpitch
,
46 int bltwidth
, int bltheight
)
49 int x
, y
, pattern_y
, pattern_pitch
, pattern_x
;
53 int skipleft
= s
->vga
.gr
[0x2f] & 0x1f;
55 int skipleft
= (s
->vga
.gr
[0x2f] & 0x07) * (DEPTH
/ 8);
65 pattern_y
= s
->cirrus_blt_srcaddr
& 7;
66 for(y
= 0; y
< bltheight
; y
++) {
68 addr
= dstaddr
+ skipleft
;
69 src1addr
= srcaddr
+ pattern_y
* pattern_pitch
;
70 for (x
= skipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
72 col
= cirrus_src(s
, src1addr
+ pattern_x
);
73 pattern_x
= (pattern_x
+ 1) & 7;
75 col
= cirrus_src16(s
, src1addr
+ pattern_x
);
76 pattern_x
= (pattern_x
+ 2) & 15;
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);
83 pattern_x
= (pattern_x
+ 1) & 7;
86 col
= cirrus_src32(s
, src1addr
+ pattern_x
);
87 pattern_x
= (pattern_x
+ 4) & 31;
89 PUTPIXEL(s
, addr
, col
);
92 pattern_y
= (pattern_y
+ 1) & 7;
97 /* NOTE: srcpitch is ignored */
99 glue(glue(glue(cirrus_colorexpand_transp_
, ROP_NAME
), _
),DEPTH
)
100 (CirrusVGAState
*s
, uint32_t dstaddr
,
102 int dstpitch
, int srcpitch
,
103 int bltwidth
, int bltheight
)
107 unsigned bits
, bits_xor
;
112 int dstskipleft
= s
->vga
.gr
[0x2f] & 0x1f;
113 int srcskipleft
= dstskipleft
/ 3;
115 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
116 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
119 if (s
->cirrus_blt_modeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
121 col
= s
->cirrus_blt_bgcol
;
124 col
= s
->cirrus_blt_fgcol
;
127 for(y
= 0; y
< bltheight
; y
++) {
128 bitmask
= 0x80 >> srcskipleft
;
129 bits
= cirrus_src(s
, srcaddr
++) ^ bits_xor
;
130 addr
= dstaddr
+ dstskipleft
;
131 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
132 if ((bitmask
& 0xff) == 0) {
134 bits
= cirrus_src(s
, srcaddr
++) ^ bits_xor
;
136 index
= (bits
& bitmask
);
138 PUTPIXEL(s
, addr
, col
);
148 glue(glue(glue(cirrus_colorexpand_
, ROP_NAME
), _
),DEPTH
)
149 (CirrusVGAState
*s
, uint32_t dstaddr
,
151 int dstpitch
, int srcpitch
,
152 int bltwidth
, int bltheight
)
160 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
161 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
163 colors
[0] = s
->cirrus_blt_bgcol
;
164 colors
[1] = s
->cirrus_blt_fgcol
;
165 for(y
= 0; y
< bltheight
; y
++) {
166 bitmask
= 0x80 >> srcskipleft
;
167 bits
= cirrus_src(s
, srcaddr
++);
168 addr
= dstaddr
+ dstskipleft
;
169 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
170 if ((bitmask
& 0xff) == 0) {
172 bits
= cirrus_src(s
, srcaddr
++);
174 col
= colors
[!!(bits
& bitmask
)];
175 PUTPIXEL(s
, addr
, col
);
184 glue(glue(glue(cirrus_colorexpand_pattern_transp_
, ROP_NAME
), _
),DEPTH
)
185 (CirrusVGAState
*s
, uint32_t dstaddr
,
187 int dstpitch
, int srcpitch
,
188 int bltwidth
, int bltheight
)
191 int x
, y
, bitpos
, pattern_y
;
192 unsigned int bits
, bits_xor
;
195 int dstskipleft
= s
->vga
.gr
[0x2f] & 0x1f;
196 int srcskipleft
= dstskipleft
/ 3;
198 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
199 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
202 if (s
->cirrus_blt_modeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
204 col
= s
->cirrus_blt_bgcol
;
207 col
= s
->cirrus_blt_fgcol
;
209 pattern_y
= s
->cirrus_blt_srcaddr
& 7;
211 for(y
= 0; y
< bltheight
; y
++) {
212 bits
= cirrus_src(s
, srcaddr
+ pattern_y
) ^ bits_xor
;
213 bitpos
= 7 - srcskipleft
;
214 addr
= dstaddr
+ dstskipleft
;
215 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
216 if ((bits
>> bitpos
) & 1) {
217 PUTPIXEL(s
, addr
, col
);
220 bitpos
= (bitpos
- 1) & 7;
222 pattern_y
= (pattern_y
+ 1) & 7;
228 glue(glue(glue(cirrus_colorexpand_pattern_
, ROP_NAME
), _
),DEPTH
)
229 (CirrusVGAState
*s
, uint32_t dstaddr
,
231 int dstpitch
, int srcpitch
,
232 int bltwidth
, int bltheight
)
236 int x
, y
, bitpos
, pattern_y
;
239 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
240 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
242 colors
[0] = s
->cirrus_blt_bgcol
;
243 colors
[1] = s
->cirrus_blt_fgcol
;
244 pattern_y
= s
->cirrus_blt_srcaddr
& 7;
246 for(y
= 0; y
< bltheight
; y
++) {
247 bits
= cirrus_src(s
, srcaddr
+ pattern_y
);
248 bitpos
= 7 - srcskipleft
;
249 addr
= dstaddr
+ dstskipleft
;
250 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
251 col
= colors
[(bits
>> bitpos
) & 1];
252 PUTPIXEL(s
, addr
, col
);
254 bitpos
= (bitpos
- 1) & 7;
256 pattern_y
= (pattern_y
+ 1) & 7;
262 glue(glue(glue(cirrus_fill_
, ROP_NAME
), _
),DEPTH
)
264 uint32_t dstaddr
, int dst_pitch
,
265 int width
, int height
)
271 col
= s
->cirrus_blt_fgcol
;
273 for(y
= 0; y
< height
; y
++) {
275 for(x
= 0; x
< width
; x
+= (DEPTH
/ 8)) {
276 PUTPIXEL(s
, addr
, col
);
279 dstaddr
+= dst_pitch
;