1 | /* |
2 | * QEMU Cirrus CLGD 54xx VGA Emulator. |
3 | * |
4 | * Copyright (c) 2004 Fabrice Bellard |
5 | * |
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 | static inline void glue(rop_8_, ROP_NAME)(CirrusVGAState *s, |
26 | uint32_t dstaddr, uint8_t src) |
27 | { |
28 | uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask]; |
29 | *dst = ROP_FN(*dst, src); |
30 | } |
31 | |
32 | static inline void glue(rop_tr_8_, ROP_NAME)(CirrusVGAState *s, |
33 | uint32_t dstaddr, uint8_t src, |
34 | uint8_t transp) |
35 | { |
36 | uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask]; |
37 | uint8_t pixel = ROP_FN(*dst, src); |
38 | if (pixel != transp) { |
39 | *dst = pixel; |
40 | } |
41 | } |
42 | |
43 | static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s, |
44 | uint32_t dstaddr, uint16_t src) |
45 | { |
46 | uint16_t *dst = (uint16_t *) |
47 | (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]); |
48 | *dst = ROP_FN(*dst, src); |
49 | } |
50 | |
51 | static inline void glue(rop_tr_16_, ROP_NAME)(CirrusVGAState *s, |
52 | uint32_t dstaddr, uint16_t src, |
53 | uint16_t transp) |
54 | { |
55 | uint16_t *dst = (uint16_t *) |
56 | (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]); |
57 | uint16_t pixel = ROP_FN(*dst, src); |
58 | if (pixel != transp) { |
59 | *dst = pixel; |
60 | } |
61 | } |
62 | |
63 | static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s, |
64 | uint32_t dstaddr, uint32_t src) |
65 | { |
66 | uint32_t *dst = (uint32_t *) |
67 | (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]); |
68 | *dst = ROP_FN(*dst, src); |
69 | } |
70 | |
71 | #define ROP_OP(st, d, s) glue(rop_8_, ROP_NAME)(st, d, s) |
72 | #define ROP_OP_TR(st, d, s, t) glue(rop_tr_8_, ROP_NAME)(st, d, s, t) |
73 | #define ROP_OP_16(st, d, s) glue(rop_16_, ROP_NAME)(st, d, s) |
74 | #define ROP_OP_TR_16(st, d, s, t) glue(rop_tr_16_, ROP_NAME)(st, d, s, t) |
75 | #define ROP_OP_32(st, d, s) glue(rop_32_, ROP_NAME)(st, d, s) |
76 | #undef ROP_FN |
77 | |
78 | static void |
79 | glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, |
80 | uint32_t dstaddr, |
81 | uint32_t srcaddr, |
82 | int dstpitch, int srcpitch, |
83 | int bltwidth, int bltheight) |
84 | { |
85 | int x,y; |
86 | dstpitch -= bltwidth; |
87 | srcpitch -= bltwidth; |
88 | |
89 | if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { |
90 | return; |
91 | } |
92 | |
93 | for (y = 0; y < bltheight; y++) { |
94 | for (x = 0; x < bltwidth; x++) { |
95 | ROP_OP(s, dstaddr, cirrus_src(s, srcaddr)); |
96 | dstaddr++; |
97 | srcaddr++; |
98 | } |
99 | dstaddr += dstpitch; |
100 | srcaddr += srcpitch; |
101 | } |
102 | } |
103 | |
104 | static void |
105 | glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, |
106 | uint32_t dstaddr, |
107 | uint32_t srcaddr, |
108 | int dstpitch, int srcpitch, |
109 | int bltwidth, int bltheight) |
110 | { |
111 | int x,y; |
112 | dstpitch += bltwidth; |
113 | srcpitch += bltwidth; |
114 | for (y = 0; y < bltheight; y++) { |
115 | for (x = 0; x < bltwidth; x++) { |
116 | ROP_OP(s, dstaddr, cirrus_src(s, srcaddr)); |
117 | dstaddr--; |
118 | srcaddr--; |
119 | } |
120 | dstaddr += dstpitch; |
121 | srcaddr += srcpitch; |
122 | } |
123 | } |
124 | |
125 | static void |
126 | glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, |
127 | uint32_t dstaddr, |
128 | uint32_t srcaddr, |
129 | int dstpitch, |
130 | int srcpitch, |
131 | int bltwidth, |
132 | int bltheight) |
133 | { |
134 | int x,y; |
135 | uint8_t transp = s->vga.gr[0x34]; |
136 | dstpitch -= bltwidth; |
137 | srcpitch -= bltwidth; |
138 | |
139 | if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { |
140 | return; |
141 | } |
142 | |
143 | for (y = 0; y < bltheight; y++) { |
144 | for (x = 0; x < bltwidth; x++) { |
145 | ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp); |
146 | dstaddr++; |
147 | srcaddr++; |
148 | } |
149 | dstaddr += dstpitch; |
150 | srcaddr += srcpitch; |
151 | } |
152 | } |
153 | |
154 | static void |
155 | glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, |
156 | uint32_t dstaddr, |
157 | uint32_t srcaddr, |
158 | int dstpitch, |
159 | int srcpitch, |
160 | int bltwidth, |
161 | int bltheight) |
162 | { |
163 | int x,y; |
164 | uint8_t transp = s->vga.gr[0x34]; |
165 | dstpitch += bltwidth; |
166 | srcpitch += bltwidth; |
167 | for (y = 0; y < bltheight; y++) { |
168 | for (x = 0; x < bltwidth; x++) { |
169 | ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp); |
170 | dstaddr--; |
171 | srcaddr--; |
172 | } |
173 | dstaddr += dstpitch; |
174 | srcaddr += srcpitch; |
175 | } |
176 | } |
177 | |
178 | static void |
179 | glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, |
180 | uint32_t dstaddr, |
181 | uint32_t srcaddr, |
182 | int dstpitch, |
183 | int srcpitch, |
184 | int bltwidth, |
185 | int bltheight) |
186 | { |
187 | int x,y; |
188 | uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8; |
189 | dstpitch -= bltwidth; |
190 | srcpitch -= bltwidth; |
191 | |
192 | if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { |
193 | return; |
194 | } |
195 | |
196 | for (y = 0; y < bltheight; y++) { |
197 | for (x = 0; x < bltwidth; x+=2) { |
198 | ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); |
199 | dstaddr += 2; |
200 | srcaddr += 2; |
201 | } |
202 | dstaddr += dstpitch; |
203 | srcaddr += srcpitch; |
204 | } |
205 | } |
206 | |
207 | static void |
208 | glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, |
209 | uint32_t dstaddr, |
210 | uint32_t srcaddr, |
211 | int dstpitch, |
212 | int srcpitch, |
213 | int bltwidth, |
214 | int bltheight) |
215 | { |
216 | int x,y; |
217 | uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8; |
218 | dstpitch += bltwidth; |
219 | srcpitch += bltwidth; |
220 | for (y = 0; y < bltheight; y++) { |
221 | for (x = 0; x < bltwidth; x+=2) { |
222 | ROP_OP_TR_16(s, dstaddr - 1, cirrus_src16(s, srcaddr - 1), transp); |
223 | dstaddr -= 2; |
224 | srcaddr -= 2; |
225 | } |
226 | dstaddr += dstpitch; |
227 | srcaddr += srcpitch; |
228 | } |
229 | } |
230 | |
231 | #define DEPTH 8 |
232 | #include "cirrus_vga_rop2.h" |
233 | |
234 | #define DEPTH 16 |
235 | #include "cirrus_vga_rop2.h" |
236 | |
237 | #define DEPTH 24 |
238 | #include "cirrus_vga_rop2.h" |
239 | |
240 | #define DEPTH 32 |
241 | #include "cirrus_vga_rop2.h" |
242 | |
243 | #undef ROP_NAME |
244 | #undef ROP_OP |
245 | #undef ROP_OP_16 |
246 | #undef ROP_OP_32 |
247 | |