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, (col >> 8)); \
33 ROP_OP(s, a + 2, (col >> 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 src1
= src
+ pattern_y
* pattern_pitch
;
70 for (x
= skipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
72 col
= src1
[pattern_x
];
73 pattern_x
= (pattern_x
+ 1) & 7;
75 col
= ((uint16_t *)(src1
+ pattern_x
))[0];
76 pattern_x
= (pattern_x
+ 2) & 15;
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;
84 col
= ((uint32_t *)(src1
+ pattern_x
))[0];
85 pattern_x
= (pattern_x
+ 4) & 31;
87 PUTPIXEL(s
, addr
, col
);
90 pattern_y
= (pattern_y
+ 1) & 7;
95 /* NOTE: srcpitch is ignored */
97 glue(glue(glue(cirrus_colorexpand_transp_
, ROP_NAME
), _
),DEPTH
)
98 (CirrusVGAState
*s
, uint32_t dstaddr
,
100 int dstpitch
, int srcpitch
,
101 int bltwidth
, int bltheight
)
105 unsigned bits
, bits_xor
;
110 int dstskipleft
= s
->vga
.gr
[0x2f] & 0x1f;
111 int srcskipleft
= dstskipleft
/ 3;
113 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
114 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
117 if (s
->cirrus_blt_modeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
119 col
= s
->cirrus_blt_bgcol
;
122 col
= s
->cirrus_blt_fgcol
;
125 for(y
= 0; y
< bltheight
; y
++) {
126 bitmask
= 0x80 >> srcskipleft
;
127 bits
= *src
++ ^ bits_xor
;
128 addr
= dstaddr
+ dstskipleft
;
129 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
130 if ((bitmask
& 0xff) == 0) {
132 bits
= *src
++ ^ bits_xor
;
134 index
= (bits
& bitmask
);
136 PUTPIXEL(s
, addr
, col
);
146 glue(glue(glue(cirrus_colorexpand_
, ROP_NAME
), _
),DEPTH
)
147 (CirrusVGAState
*s
, uint32_t dstaddr
,
149 int dstpitch
, int srcpitch
,
150 int bltwidth
, int bltheight
)
158 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
159 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
161 colors
[0] = s
->cirrus_blt_bgcol
;
162 colors
[1] = s
->cirrus_blt_fgcol
;
163 for(y
= 0; y
< bltheight
; y
++) {
164 bitmask
= 0x80 >> srcskipleft
;
166 addr
= dstaddr
+ dstskipleft
;
167 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
168 if ((bitmask
& 0xff) == 0) {
172 col
= colors
[!!(bits
& bitmask
)];
173 PUTPIXEL(s
, addr
, col
);
182 glue(glue(glue(cirrus_colorexpand_pattern_transp_
, ROP_NAME
), _
),DEPTH
)
183 (CirrusVGAState
*s
, uint32_t dstaddr
,
185 int dstpitch
, int srcpitch
,
186 int bltwidth
, int bltheight
)
189 int x
, y
, bitpos
, pattern_y
;
190 unsigned int bits
, bits_xor
;
193 int dstskipleft
= s
->vga
.gr
[0x2f] & 0x1f;
194 int srcskipleft
= dstskipleft
/ 3;
196 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
197 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
200 if (s
->cirrus_blt_modeext
& CIRRUS_BLTMODEEXT_COLOREXPINV
) {
202 col
= s
->cirrus_blt_bgcol
;
205 col
= s
->cirrus_blt_fgcol
;
207 pattern_y
= s
->cirrus_blt_srcaddr
& 7;
209 for(y
= 0; y
< bltheight
; y
++) {
210 bits
= src
[pattern_y
] ^ bits_xor
;
211 bitpos
= 7 - srcskipleft
;
212 addr
= dstaddr
+ dstskipleft
;
213 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
214 if ((bits
>> bitpos
) & 1) {
215 PUTPIXEL(s
, addr
, col
);
218 bitpos
= (bitpos
- 1) & 7;
220 pattern_y
= (pattern_y
+ 1) & 7;
226 glue(glue(glue(cirrus_colorexpand_pattern_
, ROP_NAME
), _
),DEPTH
)
227 (CirrusVGAState
*s
, uint32_t dstaddr
,
229 int dstpitch
, int srcpitch
,
230 int bltwidth
, int bltheight
)
234 int x
, y
, bitpos
, pattern_y
;
237 int srcskipleft
= s
->vga
.gr
[0x2f] & 0x07;
238 int dstskipleft
= srcskipleft
* (DEPTH
/ 8);
240 colors
[0] = s
->cirrus_blt_bgcol
;
241 colors
[1] = s
->cirrus_blt_fgcol
;
242 pattern_y
= s
->cirrus_blt_srcaddr
& 7;
244 for(y
= 0; y
< bltheight
; y
++) {
245 bits
= src
[pattern_y
];
246 bitpos
= 7 - srcskipleft
;
247 addr
= dstaddr
+ dstskipleft
;
248 for (x
= dstskipleft
; x
< bltwidth
; x
+= (DEPTH
/ 8)) {
249 col
= colors
[(bits
>> bitpos
) & 1];
250 PUTPIXEL(s
, addr
, col
);
252 bitpos
= (bitpos
- 1) & 7;
254 pattern_y
= (pattern_y
+ 1) & 7;
260 glue(glue(glue(cirrus_fill_
, ROP_NAME
), _
),DEPTH
)
262 uint32_t dstaddr
, int dst_pitch
,
263 int width
, int height
)
269 col
= s
->cirrus_blt_fgcol
;
271 for(y
= 0; y
< height
; y
++) {
273 for(x
= 0; x
< width
; x
+= (DEPTH
/ 8)) {
274 PUTPIXEL(s
, addr
, col
);
277 dstaddr
+= dst_pitch
;