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