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)(uint8_t *dst, uint8_t src) 26 { 27 *dst = ROP_FN(*dst, src); 28 } 29 30 static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) 31 { 32 *dst = ROP_FN(*dst, src); 33 } 34 35 static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) 36 { 37 *dst = ROP_FN(*dst, src); 38 } 39 40 #define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s) 41 #define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s) 42 #define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s) 43 #undef ROP_FN 44 45 static void 46 glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, 47 uint8_t *dst,const uint8_t *src, 48 int dstpitch,int srcpitch, 49 int bltwidth,int bltheight) 50 { 51 int x,y; 52 dstpitch -= bltwidth; 53 srcpitch -= bltwidth; 54 55 if (dstpitch < 0 || srcpitch < 0) { 56 /* is 0 valid? srcpitch == 0 could be useful */ 57 return; 58 } 59 60 for (y = 0; y < bltheight; y++) { 61 for (x = 0; x < bltwidth; x++) { 62 ROP_OP(dst, *src); 63 dst++; 64 src++; 65 } 66 dst += dstpitch; 67 src += srcpitch; 68 } 69 } 70 71 static void 72 glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s, 73 uint8_t *dst,const uint8_t *src, 74 int dstpitch,int srcpitch, 75 int bltwidth,int bltheight) 76 { 77 int x,y; 78 dstpitch += bltwidth; 79 srcpitch += bltwidth; 80 for (y = 0; y < bltheight; y++) { 81 for (x = 0; x < bltwidth; x++) { 82 ROP_OP(dst, *src); 83 dst--; 84 src--; 85 } 86 dst += dstpitch; 87 src += srcpitch; 88 } 89 } 90 91 static void 92 glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, 93 uint8_t *dst,const uint8_t *src, 94 int dstpitch,int srcpitch, 95 int bltwidth,int bltheight) 96 { 97 int x,y; 98 uint8_t p; 99 dstpitch -= bltwidth; 100 srcpitch -= bltwidth; 101 for (y = 0; y < bltheight; y++) { 102 for (x = 0; x < bltwidth; x++) { 103 p = *dst; 104 ROP_OP(&p, *src); 105 if (p != s->vga.gr[0x34]) *dst = p; 106 dst++; 107 src++; 108 } 109 dst += dstpitch; 110 src += srcpitch; 111 } 112 } 113 114 static void 115 glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s, 116 uint8_t *dst,const uint8_t *src, 117 int dstpitch,int srcpitch, 118 int bltwidth,int bltheight) 119 { 120 int x,y; 121 uint8_t p; 122 dstpitch += bltwidth; 123 srcpitch += bltwidth; 124 for (y = 0; y < bltheight; y++) { 125 for (x = 0; x < bltwidth; x++) { 126 p = *dst; 127 ROP_OP(&p, *src); 128 if (p != s->vga.gr[0x34]) *dst = p; 129 dst--; 130 src--; 131 } 132 dst += dstpitch; 133 src += srcpitch; 134 } 135 } 136 137 static void 138 glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, 139 uint8_t *dst,const uint8_t *src, 140 int dstpitch,int srcpitch, 141 int bltwidth,int bltheight) 142 { 143 int x,y; 144 uint8_t p1, p2; 145 dstpitch -= bltwidth; 146 srcpitch -= bltwidth; 147 for (y = 0; y < bltheight; y++) { 148 for (x = 0; x < bltwidth; x+=2) { 149 p1 = *dst; 150 p2 = *(dst+1); 151 ROP_OP(&p1, *src); 152 ROP_OP(&p2, *(src + 1)); 153 if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) { 154 *dst = p1; 155 *(dst+1) = p2; 156 } 157 dst+=2; 158 src+=2; 159 } 160 dst += dstpitch; 161 src += srcpitch; 162 } 163 } 164 165 static void 166 glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, 167 uint8_t *dst,const uint8_t *src, 168 int dstpitch,int srcpitch, 169 int bltwidth,int bltheight) 170 { 171 int x,y; 172 uint8_t p1, p2; 173 dstpitch += bltwidth; 174 srcpitch += bltwidth; 175 for (y = 0; y < bltheight; y++) { 176 for (x = 0; x < bltwidth; x+=2) { 177 p1 = *(dst-1); 178 p2 = *dst; 179 ROP_OP(&p1, *(src - 1)); 180 ROP_OP(&p2, *src); 181 if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) { 182 *(dst-1) = p1; 183 *dst = p2; 184 } 185 dst-=2; 186 src-=2; 187 } 188 dst += dstpitch; 189 src += srcpitch; 190 } 191 } 192 193 #define DEPTH 8 194 #include "cirrus_vga_rop2.h" 195 196 #define DEPTH 16 197 #include "cirrus_vga_rop2.h" 198 199 #define DEPTH 24 200 #include "cirrus_vga_rop2.h" 201 202 #define DEPTH 32 203 #include "cirrus_vga_rop2.h" 204 205 #undef ROP_NAME 206 #undef ROP_OP 207 #undef ROP_OP_16 208 #undef ROP_OP_32 209