1 /* 2 * QEMU Cirrus CLGD 54xx VGA Emulator. 3 * 4 * Copyright (c) 2004 Fabrice Bellard 5 * Copyright (c) 2004 Makoto Suzuki (suzu) 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 /* 26 * Reference: Finn Thogersons' VGADOC4b 27 * available at http://home.worldonline.dk/~finth/ 28 */ 29 #include "qemu/osdep.h" 30 #include "qemu/units.h" 31 #include "qapi/error.h" 32 #include "trace.h" 33 #include "hw/hw.h" 34 #include "hw/pci/pci.h" 35 #include "ui/pixel_ops.h" 36 #include "hw/loader.h" 37 #include "cirrus_vga_internal.h" 38 39 /* 40 * TODO: 41 * - destination write mask support not complete (bits 5..7) 42 * - optimize linear mappings 43 * - optimize bitblt functions 44 */ 45 46 //#define DEBUG_CIRRUS 47 //#define DEBUG_BITBLT 48 49 /*************************************** 50 * 51 * definitions 52 * 53 ***************************************/ 54 55 // sequencer 0x07 56 #define CIRRUS_SR7_BPP_VGA 0x00 57 #define CIRRUS_SR7_BPP_SVGA 0x01 58 #define CIRRUS_SR7_BPP_MASK 0x0e 59 #define CIRRUS_SR7_BPP_8 0x00 60 #define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 61 #define CIRRUS_SR7_BPP_24 0x04 62 #define CIRRUS_SR7_BPP_16 0x06 63 #define CIRRUS_SR7_BPP_32 0x08 64 #define CIRRUS_SR7_ISAADDR_MASK 0xe0 65 66 // sequencer 0x0f 67 #define CIRRUS_MEMSIZE_512k 0x08 68 #define CIRRUS_MEMSIZE_1M 0x10 69 #define CIRRUS_MEMSIZE_2M 0x18 70 #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled. 71 72 // sequencer 0x12 73 #define CIRRUS_CURSOR_SHOW 0x01 74 #define CIRRUS_CURSOR_HIDDENPEL 0x02 75 #define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear 76 77 // sequencer 0x17 78 #define CIRRUS_BUSTYPE_VLBFAST 0x10 79 #define CIRRUS_BUSTYPE_PCI 0x20 80 #define CIRRUS_BUSTYPE_VLBSLOW 0x30 81 #define CIRRUS_BUSTYPE_ISA 0x38 82 #define CIRRUS_MMIO_ENABLE 0x04 83 #define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared. 84 #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 85 86 // control 0x0b 87 #define CIRRUS_BANKING_DUAL 0x01 88 #define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k 89 90 // control 0x30 91 #define CIRRUS_BLTMODE_BACKWARDS 0x01 92 #define CIRRUS_BLTMODE_MEMSYSDEST 0x02 93 #define CIRRUS_BLTMODE_MEMSYSSRC 0x04 94 #define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 95 #define CIRRUS_BLTMODE_PATTERNCOPY 0x40 96 #define CIRRUS_BLTMODE_COLOREXPAND 0x80 97 #define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 98 #define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 99 #define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 100 #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 101 #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 102 103 // control 0x31 104 #define CIRRUS_BLT_BUSY 0x01 105 #define CIRRUS_BLT_START 0x02 106 #define CIRRUS_BLT_RESET 0x04 107 #define CIRRUS_BLT_FIFOUSED 0x10 108 #define CIRRUS_BLT_AUTOSTART 0x80 109 110 // control 0x32 111 #define CIRRUS_ROP_0 0x00 112 #define CIRRUS_ROP_SRC_AND_DST 0x05 113 #define CIRRUS_ROP_NOP 0x06 114 #define CIRRUS_ROP_SRC_AND_NOTDST 0x09 115 #define CIRRUS_ROP_NOTDST 0x0b 116 #define CIRRUS_ROP_SRC 0x0d 117 #define CIRRUS_ROP_1 0x0e 118 #define CIRRUS_ROP_NOTSRC_AND_DST 0x50 119 #define CIRRUS_ROP_SRC_XOR_DST 0x59 120 #define CIRRUS_ROP_SRC_OR_DST 0x6d 121 #define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90 122 #define CIRRUS_ROP_SRC_NOTXOR_DST 0x95 123 #define CIRRUS_ROP_SRC_OR_NOTDST 0xad 124 #define CIRRUS_ROP_NOTSRC 0xd0 125 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6 126 #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda 127 128 #define CIRRUS_ROP_NOP_INDEX 2 129 #define CIRRUS_ROP_SRC_INDEX 5 130 131 // control 0x33 132 #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 133 #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 134 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 135 136 // memory-mapped IO 137 #define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword 138 #define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword 139 #define CIRRUS_MMIO_BLTWIDTH 0x08 // word 140 #define CIRRUS_MMIO_BLTHEIGHT 0x0a // word 141 #define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word 142 #define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word 143 #define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword 144 #define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword 145 #define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte 146 #define CIRRUS_MMIO_BLTMODE 0x18 // byte 147 #define CIRRUS_MMIO_BLTROP 0x1a // byte 148 #define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte 149 #define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word? 150 #define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word? 151 #define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word 152 #define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word 153 #define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word 154 #define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word 155 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte 156 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte 157 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte 158 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte 159 #define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word 160 #define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word 161 #define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word 162 #define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word 163 #define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte 164 #define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte 165 #define CIRRUS_MMIO_BLTSTATUS 0x40 // byte 166 167 #define CIRRUS_PNPMMIO_SIZE 0x1000 168 169 typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, 170 uint32_t dstaddr, int dst_pitch, 171 int width, int height); 172 173 typedef struct PCICirrusVGAState { 174 PCIDevice dev; 175 CirrusVGAState cirrus_vga; 176 } PCICirrusVGAState; 177 178 #define TYPE_PCI_CIRRUS_VGA "cirrus-vga" 179 #define PCI_CIRRUS_VGA(obj) \ 180 OBJECT_CHECK(PCICirrusVGAState, (obj), TYPE_PCI_CIRRUS_VGA) 181 182 static uint8_t rop_to_index[256]; 183 184 /*************************************** 185 * 186 * prototypes. 187 * 188 ***************************************/ 189 190 191 static void cirrus_bitblt_reset(CirrusVGAState *s); 192 static void cirrus_update_memory_access(CirrusVGAState *s); 193 194 /*************************************** 195 * 196 * raster operations 197 * 198 ***************************************/ 199 200 static bool blit_region_is_unsafe(struct CirrusVGAState *s, 201 int32_t pitch, int32_t addr) 202 { 203 if (!pitch) { 204 return true; 205 } 206 if (pitch < 0) { 207 int64_t min = addr 208 + ((int64_t)s->cirrus_blt_height - 1) * pitch 209 - s->cirrus_blt_width; 210 if (min < -1 || addr >= s->vga.vram_size) { 211 return true; 212 } 213 } else { 214 int64_t max = addr 215 + ((int64_t)s->cirrus_blt_height-1) * pitch 216 + s->cirrus_blt_width; 217 if (max > s->vga.vram_size) { 218 return true; 219 } 220 } 221 return false; 222 } 223 224 static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) 225 { 226 /* should be the case, see cirrus_bitblt_start */ 227 assert(s->cirrus_blt_width > 0); 228 assert(s->cirrus_blt_height > 0); 229 230 if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) { 231 return true; 232 } 233 234 if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, 235 s->cirrus_blt_dstaddr)) { 236 return true; 237 } 238 if (dst_only) { 239 return false; 240 } 241 if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, 242 s->cirrus_blt_srcaddr)) { 243 return true; 244 } 245 246 return false; 247 } 248 249 static void cirrus_bitblt_rop_nop(CirrusVGAState *s, 250 uint32_t dstaddr, uint32_t srcaddr, 251 int dstpitch,int srcpitch, 252 int bltwidth,int bltheight) 253 { 254 } 255 256 static void cirrus_bitblt_fill_nop(CirrusVGAState *s, 257 uint32_t dstaddr, 258 int dstpitch, int bltwidth,int bltheight) 259 { 260 } 261 262 static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr) 263 { 264 if (s->cirrus_srccounter) { 265 /* cputovideo */ 266 return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)]; 267 } else { 268 /* videotovideo */ 269 return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask]; 270 } 271 } 272 273 static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr) 274 { 275 uint16_t *src; 276 277 if (s->cirrus_srccounter) { 278 /* cputovideo */ 279 src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1]; 280 } else { 281 /* videotovideo */ 282 src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1]; 283 } 284 return *src; 285 } 286 287 static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr) 288 { 289 uint32_t *src; 290 291 if (s->cirrus_srccounter) { 292 /* cputovideo */ 293 src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3]; 294 } else { 295 /* videotovideo */ 296 src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3]; 297 } 298 return *src; 299 } 300 301 #define ROP_NAME 0 302 #define ROP_FN(d, s) 0 303 #include "cirrus_vga_rop.h" 304 305 #define ROP_NAME src_and_dst 306 #define ROP_FN(d, s) (s) & (d) 307 #include "cirrus_vga_rop.h" 308 309 #define ROP_NAME src_and_notdst 310 #define ROP_FN(d, s) (s) & (~(d)) 311 #include "cirrus_vga_rop.h" 312 313 #define ROP_NAME notdst 314 #define ROP_FN(d, s) ~(d) 315 #include "cirrus_vga_rop.h" 316 317 #define ROP_NAME src 318 #define ROP_FN(d, s) s 319 #include "cirrus_vga_rop.h" 320 321 #define ROP_NAME 1 322 #define ROP_FN(d, s) ~0 323 #include "cirrus_vga_rop.h" 324 325 #define ROP_NAME notsrc_and_dst 326 #define ROP_FN(d, s) (~(s)) & (d) 327 #include "cirrus_vga_rop.h" 328 329 #define ROP_NAME src_xor_dst 330 #define ROP_FN(d, s) (s) ^ (d) 331 #include "cirrus_vga_rop.h" 332 333 #define ROP_NAME src_or_dst 334 #define ROP_FN(d, s) (s) | (d) 335 #include "cirrus_vga_rop.h" 336 337 #define ROP_NAME notsrc_or_notdst 338 #define ROP_FN(d, s) (~(s)) | (~(d)) 339 #include "cirrus_vga_rop.h" 340 341 #define ROP_NAME src_notxor_dst 342 #define ROP_FN(d, s) ~((s) ^ (d)) 343 #include "cirrus_vga_rop.h" 344 345 #define ROP_NAME src_or_notdst 346 #define ROP_FN(d, s) (s) | (~(d)) 347 #include "cirrus_vga_rop.h" 348 349 #define ROP_NAME notsrc 350 #define ROP_FN(d, s) (~(s)) 351 #include "cirrus_vga_rop.h" 352 353 #define ROP_NAME notsrc_or_dst 354 #define ROP_FN(d, s) (~(s)) | (d) 355 #include "cirrus_vga_rop.h" 356 357 #define ROP_NAME notsrc_and_notdst 358 #define ROP_FN(d, s) (~(s)) & (~(d)) 359 #include "cirrus_vga_rop.h" 360 361 static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = { 362 cirrus_bitblt_rop_fwd_0, 363 cirrus_bitblt_rop_fwd_src_and_dst, 364 cirrus_bitblt_rop_nop, 365 cirrus_bitblt_rop_fwd_src_and_notdst, 366 cirrus_bitblt_rop_fwd_notdst, 367 cirrus_bitblt_rop_fwd_src, 368 cirrus_bitblt_rop_fwd_1, 369 cirrus_bitblt_rop_fwd_notsrc_and_dst, 370 cirrus_bitblt_rop_fwd_src_xor_dst, 371 cirrus_bitblt_rop_fwd_src_or_dst, 372 cirrus_bitblt_rop_fwd_notsrc_or_notdst, 373 cirrus_bitblt_rop_fwd_src_notxor_dst, 374 cirrus_bitblt_rop_fwd_src_or_notdst, 375 cirrus_bitblt_rop_fwd_notsrc, 376 cirrus_bitblt_rop_fwd_notsrc_or_dst, 377 cirrus_bitblt_rop_fwd_notsrc_and_notdst, 378 }; 379 380 static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { 381 cirrus_bitblt_rop_bkwd_0, 382 cirrus_bitblt_rop_bkwd_src_and_dst, 383 cirrus_bitblt_rop_nop, 384 cirrus_bitblt_rop_bkwd_src_and_notdst, 385 cirrus_bitblt_rop_bkwd_notdst, 386 cirrus_bitblt_rop_bkwd_src, 387 cirrus_bitblt_rop_bkwd_1, 388 cirrus_bitblt_rop_bkwd_notsrc_and_dst, 389 cirrus_bitblt_rop_bkwd_src_xor_dst, 390 cirrus_bitblt_rop_bkwd_src_or_dst, 391 cirrus_bitblt_rop_bkwd_notsrc_or_notdst, 392 cirrus_bitblt_rop_bkwd_src_notxor_dst, 393 cirrus_bitblt_rop_bkwd_src_or_notdst, 394 cirrus_bitblt_rop_bkwd_notsrc, 395 cirrus_bitblt_rop_bkwd_notsrc_or_dst, 396 cirrus_bitblt_rop_bkwd_notsrc_and_notdst, 397 }; 398 399 #define TRANSP_ROP(name) {\ 400 name ## _8,\ 401 name ## _16,\ 402 } 403 #define TRANSP_NOP(func) {\ 404 func,\ 405 func,\ 406 } 407 408 static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = { 409 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0), 410 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst), 411 TRANSP_NOP(cirrus_bitblt_rop_nop), 412 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst), 413 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst), 414 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src), 415 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1), 416 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst), 417 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst), 418 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst), 419 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst), 420 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst), 421 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst), 422 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc), 423 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst), 424 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst), 425 }; 426 427 static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = { 428 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0), 429 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst), 430 TRANSP_NOP(cirrus_bitblt_rop_nop), 431 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst), 432 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst), 433 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src), 434 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1), 435 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst), 436 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst), 437 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst), 438 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst), 439 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst), 440 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst), 441 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc), 442 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst), 443 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst), 444 }; 445 446 #define ROP2(name) {\ 447 name ## _8,\ 448 name ## _16,\ 449 name ## _24,\ 450 name ## _32,\ 451 } 452 453 #define ROP_NOP2(func) {\ 454 func,\ 455 func,\ 456 func,\ 457 func,\ 458 } 459 460 static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = { 461 ROP2(cirrus_patternfill_0), 462 ROP2(cirrus_patternfill_src_and_dst), 463 ROP_NOP2(cirrus_bitblt_rop_nop), 464 ROP2(cirrus_patternfill_src_and_notdst), 465 ROP2(cirrus_patternfill_notdst), 466 ROP2(cirrus_patternfill_src), 467 ROP2(cirrus_patternfill_1), 468 ROP2(cirrus_patternfill_notsrc_and_dst), 469 ROP2(cirrus_patternfill_src_xor_dst), 470 ROP2(cirrus_patternfill_src_or_dst), 471 ROP2(cirrus_patternfill_notsrc_or_notdst), 472 ROP2(cirrus_patternfill_src_notxor_dst), 473 ROP2(cirrus_patternfill_src_or_notdst), 474 ROP2(cirrus_patternfill_notsrc), 475 ROP2(cirrus_patternfill_notsrc_or_dst), 476 ROP2(cirrus_patternfill_notsrc_and_notdst), 477 }; 478 479 static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { 480 ROP2(cirrus_colorexpand_transp_0), 481 ROP2(cirrus_colorexpand_transp_src_and_dst), 482 ROP_NOP2(cirrus_bitblt_rop_nop), 483 ROP2(cirrus_colorexpand_transp_src_and_notdst), 484 ROP2(cirrus_colorexpand_transp_notdst), 485 ROP2(cirrus_colorexpand_transp_src), 486 ROP2(cirrus_colorexpand_transp_1), 487 ROP2(cirrus_colorexpand_transp_notsrc_and_dst), 488 ROP2(cirrus_colorexpand_transp_src_xor_dst), 489 ROP2(cirrus_colorexpand_transp_src_or_dst), 490 ROP2(cirrus_colorexpand_transp_notsrc_or_notdst), 491 ROP2(cirrus_colorexpand_transp_src_notxor_dst), 492 ROP2(cirrus_colorexpand_transp_src_or_notdst), 493 ROP2(cirrus_colorexpand_transp_notsrc), 494 ROP2(cirrus_colorexpand_transp_notsrc_or_dst), 495 ROP2(cirrus_colorexpand_transp_notsrc_and_notdst), 496 }; 497 498 static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { 499 ROP2(cirrus_colorexpand_0), 500 ROP2(cirrus_colorexpand_src_and_dst), 501 ROP_NOP2(cirrus_bitblt_rop_nop), 502 ROP2(cirrus_colorexpand_src_and_notdst), 503 ROP2(cirrus_colorexpand_notdst), 504 ROP2(cirrus_colorexpand_src), 505 ROP2(cirrus_colorexpand_1), 506 ROP2(cirrus_colorexpand_notsrc_and_dst), 507 ROP2(cirrus_colorexpand_src_xor_dst), 508 ROP2(cirrus_colorexpand_src_or_dst), 509 ROP2(cirrus_colorexpand_notsrc_or_notdst), 510 ROP2(cirrus_colorexpand_src_notxor_dst), 511 ROP2(cirrus_colorexpand_src_or_notdst), 512 ROP2(cirrus_colorexpand_notsrc), 513 ROP2(cirrus_colorexpand_notsrc_or_dst), 514 ROP2(cirrus_colorexpand_notsrc_and_notdst), 515 }; 516 517 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = { 518 ROP2(cirrus_colorexpand_pattern_transp_0), 519 ROP2(cirrus_colorexpand_pattern_transp_src_and_dst), 520 ROP_NOP2(cirrus_bitblt_rop_nop), 521 ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst), 522 ROP2(cirrus_colorexpand_pattern_transp_notdst), 523 ROP2(cirrus_colorexpand_pattern_transp_src), 524 ROP2(cirrus_colorexpand_pattern_transp_1), 525 ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst), 526 ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst), 527 ROP2(cirrus_colorexpand_pattern_transp_src_or_dst), 528 ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst), 529 ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst), 530 ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst), 531 ROP2(cirrus_colorexpand_pattern_transp_notsrc), 532 ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst), 533 ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst), 534 }; 535 536 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = { 537 ROP2(cirrus_colorexpand_pattern_0), 538 ROP2(cirrus_colorexpand_pattern_src_and_dst), 539 ROP_NOP2(cirrus_bitblt_rop_nop), 540 ROP2(cirrus_colorexpand_pattern_src_and_notdst), 541 ROP2(cirrus_colorexpand_pattern_notdst), 542 ROP2(cirrus_colorexpand_pattern_src), 543 ROP2(cirrus_colorexpand_pattern_1), 544 ROP2(cirrus_colorexpand_pattern_notsrc_and_dst), 545 ROP2(cirrus_colorexpand_pattern_src_xor_dst), 546 ROP2(cirrus_colorexpand_pattern_src_or_dst), 547 ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst), 548 ROP2(cirrus_colorexpand_pattern_src_notxor_dst), 549 ROP2(cirrus_colorexpand_pattern_src_or_notdst), 550 ROP2(cirrus_colorexpand_pattern_notsrc), 551 ROP2(cirrus_colorexpand_pattern_notsrc_or_dst), 552 ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst), 553 }; 554 555 static const cirrus_fill_t cirrus_fill[16][4] = { 556 ROP2(cirrus_fill_0), 557 ROP2(cirrus_fill_src_and_dst), 558 ROP_NOP2(cirrus_bitblt_fill_nop), 559 ROP2(cirrus_fill_src_and_notdst), 560 ROP2(cirrus_fill_notdst), 561 ROP2(cirrus_fill_src), 562 ROP2(cirrus_fill_1), 563 ROP2(cirrus_fill_notsrc_and_dst), 564 ROP2(cirrus_fill_src_xor_dst), 565 ROP2(cirrus_fill_src_or_dst), 566 ROP2(cirrus_fill_notsrc_or_notdst), 567 ROP2(cirrus_fill_src_notxor_dst), 568 ROP2(cirrus_fill_src_or_notdst), 569 ROP2(cirrus_fill_notsrc), 570 ROP2(cirrus_fill_notsrc_or_dst), 571 ROP2(cirrus_fill_notsrc_and_notdst), 572 }; 573 574 static inline void cirrus_bitblt_fgcol(CirrusVGAState *s) 575 { 576 unsigned int color; 577 switch (s->cirrus_blt_pixelwidth) { 578 case 1: 579 s->cirrus_blt_fgcol = s->cirrus_shadow_gr1; 580 break; 581 case 2: 582 color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8); 583 s->cirrus_blt_fgcol = le16_to_cpu(color); 584 break; 585 case 3: 586 s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 | 587 (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16); 588 break; 589 default: 590 case 4: 591 color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) | 592 (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24); 593 s->cirrus_blt_fgcol = le32_to_cpu(color); 594 break; 595 } 596 } 597 598 static inline void cirrus_bitblt_bgcol(CirrusVGAState *s) 599 { 600 unsigned int color; 601 switch (s->cirrus_blt_pixelwidth) { 602 case 1: 603 s->cirrus_blt_bgcol = s->cirrus_shadow_gr0; 604 break; 605 case 2: 606 color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8); 607 s->cirrus_blt_bgcol = le16_to_cpu(color); 608 break; 609 case 3: 610 s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 | 611 (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16); 612 break; 613 default: 614 case 4: 615 color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) | 616 (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24); 617 s->cirrus_blt_bgcol = le32_to_cpu(color); 618 break; 619 } 620 } 621 622 static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, 623 int off_pitch, int bytesperline, 624 int lines) 625 { 626 int y; 627 int off_cur; 628 int off_cur_end; 629 630 if (off_pitch < 0) { 631 off_begin -= bytesperline - 1; 632 } 633 634 for (y = 0; y < lines; y++) { 635 off_cur = off_begin; 636 off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1; 637 assert(off_cur_end >= off_cur); 638 memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); 639 off_begin += off_pitch; 640 } 641 } 642 643 static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s) 644 { 645 uint32_t patternsize; 646 bool videosrc = !s->cirrus_srccounter; 647 648 if (videosrc) { 649 switch (s->vga.get_bpp(&s->vga)) { 650 case 8: 651 patternsize = 64; 652 break; 653 case 15: 654 case 16: 655 patternsize = 128; 656 break; 657 case 24: 658 case 32: 659 default: 660 patternsize = 256; 661 break; 662 } 663 s->cirrus_blt_srcaddr &= ~(patternsize - 1); 664 if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) { 665 return 0; 666 } 667 } 668 669 if (blit_is_unsafe(s, true)) { 670 return 0; 671 } 672 673 (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, 674 videosrc ? s->cirrus_blt_srcaddr : 0, 675 s->cirrus_blt_dstpitch, 0, 676 s->cirrus_blt_width, s->cirrus_blt_height); 677 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 678 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 679 s->cirrus_blt_height); 680 return 1; 681 } 682 683 /* fill */ 684 685 static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) 686 { 687 cirrus_fill_t rop_func; 688 689 if (blit_is_unsafe(s, true)) { 690 return 0; 691 } 692 rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 693 rop_func(s, s->cirrus_blt_dstaddr, 694 s->cirrus_blt_dstpitch, 695 s->cirrus_blt_width, s->cirrus_blt_height); 696 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 697 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 698 s->cirrus_blt_height); 699 cirrus_bitblt_reset(s); 700 return 1; 701 } 702 703 /*************************************** 704 * 705 * bitblt (video-to-video) 706 * 707 ***************************************/ 708 709 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) 710 { 711 return cirrus_bitblt_common_patterncopy(s); 712 } 713 714 static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) 715 { 716 int sx = 0, sy = 0; 717 int dx = 0, dy = 0; 718 int depth = 0; 719 int notify = 0; 720 721 /* make sure to only copy if it's a plain copy ROP */ 722 if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src || 723 *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) { 724 725 int width, height; 726 727 depth = s->vga.get_bpp(&s->vga) / 8; 728 if (!depth) { 729 return 0; 730 } 731 s->vga.get_resolution(&s->vga, &width, &height); 732 733 /* extra x, y */ 734 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth; 735 sy = (src / ABS(s->cirrus_blt_srcpitch)); 736 dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth; 737 dy = (dst / ABS(s->cirrus_blt_dstpitch)); 738 739 /* normalize width */ 740 w /= depth; 741 742 /* if we're doing a backward copy, we have to adjust 743 our x/y to be the upper left corner (instead of the lower 744 right corner) */ 745 if (s->cirrus_blt_dstpitch < 0) { 746 sx -= (s->cirrus_blt_width / depth) - 1; 747 dx -= (s->cirrus_blt_width / depth) - 1; 748 sy -= s->cirrus_blt_height - 1; 749 dy -= s->cirrus_blt_height - 1; 750 } 751 752 /* are we in the visible portion of memory? */ 753 if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && 754 (sx + w) <= width && (sy + h) <= height && 755 (dx + w) <= width && (dy + h) <= height) { 756 notify = 1; 757 } 758 } 759 760 (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, 761 s->cirrus_blt_srcaddr, 762 s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, 763 s->cirrus_blt_width, s->cirrus_blt_height); 764 765 if (notify) { 766 dpy_gfx_update(s->vga.con, dx, dy, 767 s->cirrus_blt_width / depth, 768 s->cirrus_blt_height); 769 } 770 771 /* we don't have to notify the display that this portion has 772 changed since qemu_console_copy implies this */ 773 774 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 775 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 776 s->cirrus_blt_height); 777 778 return 1; 779 } 780 781 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) 782 { 783 if (blit_is_unsafe(s, false)) 784 return 0; 785 786 return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, 787 s->cirrus_blt_srcaddr - s->vga.start_addr, 788 s->cirrus_blt_width, s->cirrus_blt_height); 789 } 790 791 /*************************************** 792 * 793 * bitblt (cpu-to-video) 794 * 795 ***************************************/ 796 797 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) 798 { 799 int copy_count; 800 uint8_t *end_ptr; 801 802 if (s->cirrus_srccounter > 0) { 803 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 804 cirrus_bitblt_common_patterncopy(s); 805 the_end: 806 s->cirrus_srccounter = 0; 807 cirrus_bitblt_reset(s); 808 } else { 809 /* at least one scan line */ 810 do { 811 (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr, 812 0, 0, 0, s->cirrus_blt_width, 1); 813 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, 814 s->cirrus_blt_width, 1); 815 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch; 816 s->cirrus_srccounter -= s->cirrus_blt_srcpitch; 817 if (s->cirrus_srccounter <= 0) 818 goto the_end; 819 /* more bytes than needed can be transferred because of 820 word alignment, so we keep them for the next line */ 821 /* XXX: keep alignment to speed up transfer */ 822 end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; 823 copy_count = s->cirrus_srcptr_end - end_ptr; 824 memmove(s->cirrus_bltbuf, end_ptr, copy_count); 825 s->cirrus_srcptr = s->cirrus_bltbuf + copy_count; 826 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; 827 } while (s->cirrus_srcptr >= s->cirrus_srcptr_end); 828 } 829 } 830 } 831 832 /*************************************** 833 * 834 * bitblt wrapper 835 * 836 ***************************************/ 837 838 static void cirrus_bitblt_reset(CirrusVGAState * s) 839 { 840 int need_update; 841 842 s->vga.gr[0x31] &= 843 ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED); 844 need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0] 845 || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0]; 846 s->cirrus_srcptr = &s->cirrus_bltbuf[0]; 847 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; 848 s->cirrus_srccounter = 0; 849 if (!need_update) 850 return; 851 cirrus_update_memory_access(s); 852 } 853 854 static int cirrus_bitblt_cputovideo(CirrusVGAState * s) 855 { 856 int w; 857 858 if (blit_is_unsafe(s, true)) { 859 return 0; 860 } 861 862 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC; 863 s->cirrus_srcptr = &s->cirrus_bltbuf[0]; 864 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; 865 866 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 867 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 868 s->cirrus_blt_srcpitch = 8; 869 } else { 870 /* XXX: check for 24 bpp */ 871 s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; 872 } 873 s->cirrus_srccounter = s->cirrus_blt_srcpitch; 874 } else { 875 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 876 w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth; 877 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) 878 s->cirrus_blt_srcpitch = ((w + 31) >> 5); 879 else 880 s->cirrus_blt_srcpitch = ((w + 7) >> 3); 881 } else { 882 /* always align input size to 32 bits */ 883 s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3; 884 } 885 s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height; 886 } 887 888 /* the blit_is_unsafe call above should catch this */ 889 assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE); 890 891 s->cirrus_srcptr = s->cirrus_bltbuf; 892 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; 893 cirrus_update_memory_access(s); 894 return 1; 895 } 896 897 static int cirrus_bitblt_videotocpu(CirrusVGAState * s) 898 { 899 /* XXX */ 900 #ifdef DEBUG_BITBLT 901 printf("cirrus: bitblt (video to cpu) is not implemented yet\n"); 902 #endif 903 return 0; 904 } 905 906 static int cirrus_bitblt_videotovideo(CirrusVGAState * s) 907 { 908 int ret; 909 910 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 911 ret = cirrus_bitblt_videotovideo_patterncopy(s); 912 } else { 913 ret = cirrus_bitblt_videotovideo_copy(s); 914 } 915 if (ret) 916 cirrus_bitblt_reset(s); 917 return ret; 918 } 919 920 static void cirrus_bitblt_start(CirrusVGAState * s) 921 { 922 uint8_t blt_rop; 923 924 if (!s->enable_blitter) { 925 goto bitblt_ignore; 926 } 927 928 s->vga.gr[0x31] |= CIRRUS_BLT_BUSY; 929 930 s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1; 931 s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1; 932 s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8)); 933 s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8)); 934 s->cirrus_blt_dstaddr = 935 (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16)); 936 s->cirrus_blt_srcaddr = 937 (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16)); 938 s->cirrus_blt_mode = s->vga.gr[0x30]; 939 s->cirrus_blt_modeext = s->vga.gr[0x33]; 940 blt_rop = s->vga.gr[0x32]; 941 942 s->cirrus_blt_dstaddr &= s->cirrus_addr_mask; 943 s->cirrus_blt_srcaddr &= s->cirrus_addr_mask; 944 945 #ifdef DEBUG_BITBLT 946 printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n", 947 blt_rop, 948 s->cirrus_blt_mode, 949 s->cirrus_blt_modeext, 950 s->cirrus_blt_width, 951 s->cirrus_blt_height, 952 s->cirrus_blt_dstpitch, 953 s->cirrus_blt_srcpitch, 954 s->cirrus_blt_dstaddr, 955 s->cirrus_blt_srcaddr, 956 s->vga.gr[0x2f]); 957 #endif 958 959 switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { 960 case CIRRUS_BLTMODE_PIXELWIDTH8: 961 s->cirrus_blt_pixelwidth = 1; 962 break; 963 case CIRRUS_BLTMODE_PIXELWIDTH16: 964 s->cirrus_blt_pixelwidth = 2; 965 break; 966 case CIRRUS_BLTMODE_PIXELWIDTH24: 967 s->cirrus_blt_pixelwidth = 3; 968 break; 969 case CIRRUS_BLTMODE_PIXELWIDTH32: 970 s->cirrus_blt_pixelwidth = 4; 971 break; 972 default: 973 #ifdef DEBUG_BITBLT 974 printf("cirrus: bitblt - pixel width is unknown\n"); 975 #endif 976 goto bitblt_ignore; 977 } 978 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK; 979 980 if ((s-> 981 cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC | 982 CIRRUS_BLTMODE_MEMSYSDEST)) 983 == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) { 984 #ifdef DEBUG_BITBLT 985 printf("cirrus: bitblt - memory-to-memory copy is requested\n"); 986 #endif 987 goto bitblt_ignore; 988 } 989 990 if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) && 991 (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST | 992 CIRRUS_BLTMODE_TRANSPARENTCOMP | 993 CIRRUS_BLTMODE_PATTERNCOPY | 994 CIRRUS_BLTMODE_COLOREXPAND)) == 995 (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) { 996 cirrus_bitblt_fgcol(s); 997 cirrus_bitblt_solidfill(s, blt_rop); 998 } else { 999 if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND | 1000 CIRRUS_BLTMODE_PATTERNCOPY)) == 1001 CIRRUS_BLTMODE_COLOREXPAND) { 1002 1003 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { 1004 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) 1005 cirrus_bitblt_bgcol(s); 1006 else 1007 cirrus_bitblt_fgcol(s); 1008 s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1009 } else { 1010 cirrus_bitblt_fgcol(s); 1011 cirrus_bitblt_bgcol(s); 1012 s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1013 } 1014 } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 1015 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 1016 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { 1017 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) 1018 cirrus_bitblt_bgcol(s); 1019 else 1020 cirrus_bitblt_fgcol(s); 1021 s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1022 } else { 1023 cirrus_bitblt_fgcol(s); 1024 cirrus_bitblt_bgcol(s); 1025 s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1026 } 1027 } else { 1028 s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1029 } 1030 } else { 1031 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { 1032 if (s->cirrus_blt_pixelwidth > 2) { 1033 printf("src transparent without colorexpand must be 8bpp or 16bpp\n"); 1034 goto bitblt_ignore; 1035 } 1036 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { 1037 s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; 1038 s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; 1039 s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1040 } else { 1041 s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1042 } 1043 } else { 1044 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { 1045 s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; 1046 s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; 1047 s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; 1048 } else { 1049 s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; 1050 } 1051 } 1052 } 1053 // setup bitblt engine. 1054 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) { 1055 if (!cirrus_bitblt_cputovideo(s)) 1056 goto bitblt_ignore; 1057 } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) { 1058 if (!cirrus_bitblt_videotocpu(s)) 1059 goto bitblt_ignore; 1060 } else { 1061 if (!cirrus_bitblt_videotovideo(s)) 1062 goto bitblt_ignore; 1063 } 1064 } 1065 return; 1066 bitblt_ignore:; 1067 cirrus_bitblt_reset(s); 1068 } 1069 1070 static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value) 1071 { 1072 unsigned old_value; 1073 1074 old_value = s->vga.gr[0x31]; 1075 s->vga.gr[0x31] = reg_value; 1076 1077 if (((old_value & CIRRUS_BLT_RESET) != 0) && 1078 ((reg_value & CIRRUS_BLT_RESET) == 0)) { 1079 cirrus_bitblt_reset(s); 1080 } else if (((old_value & CIRRUS_BLT_START) == 0) && 1081 ((reg_value & CIRRUS_BLT_START) != 0)) { 1082 cirrus_bitblt_start(s); 1083 } 1084 } 1085 1086 1087 /*************************************** 1088 * 1089 * basic parameters 1090 * 1091 ***************************************/ 1092 1093 static void cirrus_get_offsets(VGACommonState *s1, 1094 uint32_t *pline_offset, 1095 uint32_t *pstart_addr, 1096 uint32_t *pline_compare) 1097 { 1098 CirrusVGAState * s = container_of(s1, CirrusVGAState, vga); 1099 uint32_t start_addr, line_offset, line_compare; 1100 1101 line_offset = s->vga.cr[0x13] 1102 | ((s->vga.cr[0x1b] & 0x10) << 4); 1103 line_offset <<= 3; 1104 *pline_offset = line_offset; 1105 1106 start_addr = (s->vga.cr[0x0c] << 8) 1107 | s->vga.cr[0x0d] 1108 | ((s->vga.cr[0x1b] & 0x01) << 16) 1109 | ((s->vga.cr[0x1b] & 0x0c) << 15) 1110 | ((s->vga.cr[0x1d] & 0x80) << 12); 1111 *pstart_addr = start_addr; 1112 1113 line_compare = s->vga.cr[0x18] | 1114 ((s->vga.cr[0x07] & 0x10) << 4) | 1115 ((s->vga.cr[0x09] & 0x40) << 3); 1116 *pline_compare = line_compare; 1117 } 1118 1119 static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s) 1120 { 1121 uint32_t ret = 16; 1122 1123 switch (s->cirrus_hidden_dac_data & 0xf) { 1124 case 0: 1125 ret = 15; 1126 break; /* Sierra HiColor */ 1127 case 1: 1128 ret = 16; 1129 break; /* XGA HiColor */ 1130 default: 1131 #ifdef DEBUG_CIRRUS 1132 printf("cirrus: invalid DAC value %x in 16bpp\n", 1133 (s->cirrus_hidden_dac_data & 0xf)); 1134 #endif 1135 ret = 15; /* XXX */ 1136 break; 1137 } 1138 return ret; 1139 } 1140 1141 static int cirrus_get_bpp(VGACommonState *s1) 1142 { 1143 CirrusVGAState * s = container_of(s1, CirrusVGAState, vga); 1144 uint32_t ret = 8; 1145 1146 if ((s->vga.sr[0x07] & 0x01) != 0) { 1147 /* Cirrus SVGA */ 1148 switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) { 1149 case CIRRUS_SR7_BPP_8: 1150 ret = 8; 1151 break; 1152 case CIRRUS_SR7_BPP_16_DOUBLEVCLK: 1153 ret = cirrus_get_bpp16_depth(s); 1154 break; 1155 case CIRRUS_SR7_BPP_24: 1156 ret = 24; 1157 break; 1158 case CIRRUS_SR7_BPP_16: 1159 ret = cirrus_get_bpp16_depth(s); 1160 break; 1161 case CIRRUS_SR7_BPP_32: 1162 ret = 32; 1163 break; 1164 default: 1165 #ifdef DEBUG_CIRRUS 1166 printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]); 1167 #endif 1168 ret = 8; 1169 break; 1170 } 1171 } else { 1172 /* VGA */ 1173 ret = 0; 1174 } 1175 1176 return ret; 1177 } 1178 1179 static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight) 1180 { 1181 int width, height; 1182 1183 width = (s->cr[0x01] + 1) * 8; 1184 height = s->cr[0x12] | 1185 ((s->cr[0x07] & 0x02) << 7) | 1186 ((s->cr[0x07] & 0x40) << 3); 1187 height = (height + 1); 1188 /* interlace support */ 1189 if (s->cr[0x1a] & 0x01) 1190 height = height * 2; 1191 *pwidth = width; 1192 *pheight = height; 1193 } 1194 1195 /*************************************** 1196 * 1197 * bank memory 1198 * 1199 ***************************************/ 1200 1201 static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) 1202 { 1203 unsigned offset; 1204 unsigned limit; 1205 1206 if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */ 1207 offset = s->vga.gr[0x09 + bank_index]; 1208 else /* single bank */ 1209 offset = s->vga.gr[0x09]; 1210 1211 if ((s->vga.gr[0x0b] & 0x20) != 0) 1212 offset <<= 14; 1213 else 1214 offset <<= 12; 1215 1216 if (s->real_vram_size <= offset) 1217 limit = 0; 1218 else 1219 limit = s->real_vram_size - offset; 1220 1221 if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) { 1222 if (limit > 0x8000) { 1223 offset += 0x8000; 1224 limit -= 0x8000; 1225 } else { 1226 limit = 0; 1227 } 1228 } 1229 1230 if (limit > 0) { 1231 s->cirrus_bank_base[bank_index] = offset; 1232 s->cirrus_bank_limit[bank_index] = limit; 1233 } else { 1234 s->cirrus_bank_base[bank_index] = 0; 1235 s->cirrus_bank_limit[bank_index] = 0; 1236 } 1237 } 1238 1239 /*************************************** 1240 * 1241 * I/O access between 0x3c4-0x3c5 1242 * 1243 ***************************************/ 1244 1245 static int cirrus_vga_read_sr(CirrusVGAState * s) 1246 { 1247 switch (s->vga.sr_index) { 1248 case 0x00: // Standard VGA 1249 case 0x01: // Standard VGA 1250 case 0x02: // Standard VGA 1251 case 0x03: // Standard VGA 1252 case 0x04: // Standard VGA 1253 return s->vga.sr[s->vga.sr_index]; 1254 case 0x06: // Unlock Cirrus extensions 1255 return s->vga.sr[s->vga.sr_index]; 1256 case 0x10: 1257 case 0x30: 1258 case 0x50: 1259 case 0x70: // Graphics Cursor X 1260 case 0x90: 1261 case 0xb0: 1262 case 0xd0: 1263 case 0xf0: // Graphics Cursor X 1264 return s->vga.sr[0x10]; 1265 case 0x11: 1266 case 0x31: 1267 case 0x51: 1268 case 0x71: // Graphics Cursor Y 1269 case 0x91: 1270 case 0xb1: 1271 case 0xd1: 1272 case 0xf1: // Graphics Cursor Y 1273 return s->vga.sr[0x11]; 1274 case 0x05: // ??? 1275 case 0x07: // Extended Sequencer Mode 1276 case 0x08: // EEPROM Control 1277 case 0x09: // Scratch Register 0 1278 case 0x0a: // Scratch Register 1 1279 case 0x0b: // VCLK 0 1280 case 0x0c: // VCLK 1 1281 case 0x0d: // VCLK 2 1282 case 0x0e: // VCLK 3 1283 case 0x0f: // DRAM Control 1284 case 0x12: // Graphics Cursor Attribute 1285 case 0x13: // Graphics Cursor Pattern Address 1286 case 0x14: // Scratch Register 2 1287 case 0x15: // Scratch Register 3 1288 case 0x16: // Performance Tuning Register 1289 case 0x17: // Configuration Readback and Extended Control 1290 case 0x18: // Signature Generator Control 1291 case 0x19: // Signal Generator Result 1292 case 0x1a: // Signal Generator Result 1293 case 0x1b: // VCLK 0 Denominator & Post 1294 case 0x1c: // VCLK 1 Denominator & Post 1295 case 0x1d: // VCLK 2 Denominator & Post 1296 case 0x1e: // VCLK 3 Denominator & Post 1297 case 0x1f: // BIOS Write Enable and MCLK select 1298 #ifdef DEBUG_CIRRUS 1299 printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index); 1300 #endif 1301 return s->vga.sr[s->vga.sr_index]; 1302 default: 1303 #ifdef DEBUG_CIRRUS 1304 printf("cirrus: inport sr_index %02x\n", s->vga.sr_index); 1305 #endif 1306 return 0xff; 1307 break; 1308 } 1309 } 1310 1311 static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val) 1312 { 1313 switch (s->vga.sr_index) { 1314 case 0x00: // Standard VGA 1315 case 0x01: // Standard VGA 1316 case 0x02: // Standard VGA 1317 case 0x03: // Standard VGA 1318 case 0x04: // Standard VGA 1319 s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index]; 1320 if (s->vga.sr_index == 1) 1321 s->vga.update_retrace_info(&s->vga); 1322 break; 1323 case 0x06: // Unlock Cirrus extensions 1324 val &= 0x17; 1325 if (val == 0x12) { 1326 s->vga.sr[s->vga.sr_index] = 0x12; 1327 } else { 1328 s->vga.sr[s->vga.sr_index] = 0x0f; 1329 } 1330 break; 1331 case 0x10: 1332 case 0x30: 1333 case 0x50: 1334 case 0x70: // Graphics Cursor X 1335 case 0x90: 1336 case 0xb0: 1337 case 0xd0: 1338 case 0xf0: // Graphics Cursor X 1339 s->vga.sr[0x10] = val; 1340 s->vga.hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5); 1341 break; 1342 case 0x11: 1343 case 0x31: 1344 case 0x51: 1345 case 0x71: // Graphics Cursor Y 1346 case 0x91: 1347 case 0xb1: 1348 case 0xd1: 1349 case 0xf1: // Graphics Cursor Y 1350 s->vga.sr[0x11] = val; 1351 s->vga.hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5); 1352 break; 1353 case 0x07: // Extended Sequencer Mode 1354 cirrus_update_memory_access(s); 1355 /* fall through */ 1356 case 0x08: // EEPROM Control 1357 case 0x09: // Scratch Register 0 1358 case 0x0a: // Scratch Register 1 1359 case 0x0b: // VCLK 0 1360 case 0x0c: // VCLK 1 1361 case 0x0d: // VCLK 2 1362 case 0x0e: // VCLK 3 1363 case 0x0f: // DRAM Control 1364 case 0x13: // Graphics Cursor Pattern Address 1365 case 0x14: // Scratch Register 2 1366 case 0x15: // Scratch Register 3 1367 case 0x16: // Performance Tuning Register 1368 case 0x18: // Signature Generator Control 1369 case 0x19: // Signature Generator Result 1370 case 0x1a: // Signature Generator Result 1371 case 0x1b: // VCLK 0 Denominator & Post 1372 case 0x1c: // VCLK 1 Denominator & Post 1373 case 0x1d: // VCLK 2 Denominator & Post 1374 case 0x1e: // VCLK 3 Denominator & Post 1375 case 0x1f: // BIOS Write Enable and MCLK select 1376 s->vga.sr[s->vga.sr_index] = val; 1377 #ifdef DEBUG_CIRRUS 1378 printf("cirrus: handled outport sr_index %02x, sr_value %02x\n", 1379 s->vga.sr_index, val); 1380 #endif 1381 break; 1382 case 0x12: // Graphics Cursor Attribute 1383 s->vga.sr[0x12] = val; 1384 s->vga.force_shadow = !!(val & CIRRUS_CURSOR_SHOW); 1385 #ifdef DEBUG_CIRRUS 1386 printf("cirrus: cursor ctl SR12=%02x (force shadow: %d)\n", 1387 val, s->vga.force_shadow); 1388 #endif 1389 break; 1390 case 0x17: // Configuration Readback and Extended Control 1391 s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38) 1392 | (val & 0xc7); 1393 cirrus_update_memory_access(s); 1394 break; 1395 default: 1396 #ifdef DEBUG_CIRRUS 1397 printf("cirrus: outport sr_index %02x, sr_value %02x\n", 1398 s->vga.sr_index, val); 1399 #endif 1400 break; 1401 } 1402 } 1403 1404 /*************************************** 1405 * 1406 * I/O access at 0x3c6 1407 * 1408 ***************************************/ 1409 1410 static int cirrus_read_hidden_dac(CirrusVGAState * s) 1411 { 1412 if (++s->cirrus_hidden_dac_lockindex == 5) { 1413 s->cirrus_hidden_dac_lockindex = 0; 1414 return s->cirrus_hidden_dac_data; 1415 } 1416 return 0xff; 1417 } 1418 1419 static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value) 1420 { 1421 if (s->cirrus_hidden_dac_lockindex == 4) { 1422 s->cirrus_hidden_dac_data = reg_value; 1423 #if defined(DEBUG_CIRRUS) 1424 printf("cirrus: outport hidden DAC, value %02x\n", reg_value); 1425 #endif 1426 } 1427 s->cirrus_hidden_dac_lockindex = 0; 1428 } 1429 1430 /*************************************** 1431 * 1432 * I/O access at 0x3c9 1433 * 1434 ***************************************/ 1435 1436 static int cirrus_vga_read_palette(CirrusVGAState * s) 1437 { 1438 int val; 1439 1440 if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) { 1441 val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 + 1442 s->vga.dac_sub_index]; 1443 } else { 1444 val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index]; 1445 } 1446 if (++s->vga.dac_sub_index == 3) { 1447 s->vga.dac_sub_index = 0; 1448 s->vga.dac_read_index++; 1449 } 1450 return val; 1451 } 1452 1453 static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value) 1454 { 1455 s->vga.dac_cache[s->vga.dac_sub_index] = reg_value; 1456 if (++s->vga.dac_sub_index == 3) { 1457 if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) { 1458 memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3], 1459 s->vga.dac_cache, 3); 1460 } else { 1461 memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3); 1462 } 1463 /* XXX update cursor */ 1464 s->vga.dac_sub_index = 0; 1465 s->vga.dac_write_index++; 1466 } 1467 } 1468 1469 /*************************************** 1470 * 1471 * I/O access between 0x3ce-0x3cf 1472 * 1473 ***************************************/ 1474 1475 static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index) 1476 { 1477 switch (reg_index) { 1478 case 0x00: // Standard VGA, BGCOLOR 0x000000ff 1479 return s->cirrus_shadow_gr0; 1480 case 0x01: // Standard VGA, FGCOLOR 0x000000ff 1481 return s->cirrus_shadow_gr1; 1482 case 0x02: // Standard VGA 1483 case 0x03: // Standard VGA 1484 case 0x04: // Standard VGA 1485 case 0x06: // Standard VGA 1486 case 0x07: // Standard VGA 1487 case 0x08: // Standard VGA 1488 return s->vga.gr[s->vga.gr_index]; 1489 case 0x05: // Standard VGA, Cirrus extended mode 1490 default: 1491 break; 1492 } 1493 1494 if (reg_index < 0x3a) { 1495 return s->vga.gr[reg_index]; 1496 } else { 1497 #ifdef DEBUG_CIRRUS 1498 printf("cirrus: inport gr_index %02x\n", reg_index); 1499 #endif 1500 return 0xff; 1501 } 1502 } 1503 1504 static void 1505 cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) 1506 { 1507 #if defined(DEBUG_BITBLT) && 0 1508 printf("gr%02x: %02x\n", reg_index, reg_value); 1509 #endif 1510 switch (reg_index) { 1511 case 0x00: // Standard VGA, BGCOLOR 0x000000ff 1512 s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; 1513 s->cirrus_shadow_gr0 = reg_value; 1514 break; 1515 case 0x01: // Standard VGA, FGCOLOR 0x000000ff 1516 s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; 1517 s->cirrus_shadow_gr1 = reg_value; 1518 break; 1519 case 0x02: // Standard VGA 1520 case 0x03: // Standard VGA 1521 case 0x04: // Standard VGA 1522 case 0x06: // Standard VGA 1523 case 0x07: // Standard VGA 1524 case 0x08: // Standard VGA 1525 s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; 1526 break; 1527 case 0x05: // Standard VGA, Cirrus extended mode 1528 s->vga.gr[reg_index] = reg_value & 0x7f; 1529 cirrus_update_memory_access(s); 1530 break; 1531 case 0x09: // bank offset #0 1532 case 0x0A: // bank offset #1 1533 s->vga.gr[reg_index] = reg_value; 1534 cirrus_update_bank_ptr(s, 0); 1535 cirrus_update_bank_ptr(s, 1); 1536 cirrus_update_memory_access(s); 1537 break; 1538 case 0x0B: 1539 s->vga.gr[reg_index] = reg_value; 1540 cirrus_update_bank_ptr(s, 0); 1541 cirrus_update_bank_ptr(s, 1); 1542 cirrus_update_memory_access(s); 1543 break; 1544 case 0x10: // BGCOLOR 0x0000ff00 1545 case 0x11: // FGCOLOR 0x0000ff00 1546 case 0x12: // BGCOLOR 0x00ff0000 1547 case 0x13: // FGCOLOR 0x00ff0000 1548 case 0x14: // BGCOLOR 0xff000000 1549 case 0x15: // FGCOLOR 0xff000000 1550 case 0x20: // BLT WIDTH 0x0000ff 1551 case 0x22: // BLT HEIGHT 0x0000ff 1552 case 0x24: // BLT DEST PITCH 0x0000ff 1553 case 0x26: // BLT SRC PITCH 0x0000ff 1554 case 0x28: // BLT DEST ADDR 0x0000ff 1555 case 0x29: // BLT DEST ADDR 0x00ff00 1556 case 0x2c: // BLT SRC ADDR 0x0000ff 1557 case 0x2d: // BLT SRC ADDR 0x00ff00 1558 case 0x2f: // BLT WRITEMASK 1559 case 0x30: // BLT MODE 1560 case 0x32: // RASTER OP 1561 case 0x33: // BLT MODEEXT 1562 case 0x34: // BLT TRANSPARENT COLOR 0x00ff 1563 case 0x35: // BLT TRANSPARENT COLOR 0xff00 1564 case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff 1565 case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00 1566 s->vga.gr[reg_index] = reg_value; 1567 break; 1568 case 0x21: // BLT WIDTH 0x001f00 1569 case 0x23: // BLT HEIGHT 0x001f00 1570 case 0x25: // BLT DEST PITCH 0x001f00 1571 case 0x27: // BLT SRC PITCH 0x001f00 1572 s->vga.gr[reg_index] = reg_value & 0x1f; 1573 break; 1574 case 0x2a: // BLT DEST ADDR 0x3f0000 1575 s->vga.gr[reg_index] = reg_value & 0x3f; 1576 /* if auto start mode, starts bit blt now */ 1577 if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) { 1578 cirrus_bitblt_start(s); 1579 } 1580 break; 1581 case 0x2e: // BLT SRC ADDR 0x3f0000 1582 s->vga.gr[reg_index] = reg_value & 0x3f; 1583 break; 1584 case 0x31: // BLT STATUS/START 1585 cirrus_write_bitblt(s, reg_value); 1586 break; 1587 default: 1588 #ifdef DEBUG_CIRRUS 1589 printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index, 1590 reg_value); 1591 #endif 1592 break; 1593 } 1594 } 1595 1596 /*************************************** 1597 * 1598 * I/O access between 0x3d4-0x3d5 1599 * 1600 ***************************************/ 1601 1602 static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index) 1603 { 1604 switch (reg_index) { 1605 case 0x00: // Standard VGA 1606 case 0x01: // Standard VGA 1607 case 0x02: // Standard VGA 1608 case 0x03: // Standard VGA 1609 case 0x04: // Standard VGA 1610 case 0x05: // Standard VGA 1611 case 0x06: // Standard VGA 1612 case 0x07: // Standard VGA 1613 case 0x08: // Standard VGA 1614 case 0x09: // Standard VGA 1615 case 0x0a: // Standard VGA 1616 case 0x0b: // Standard VGA 1617 case 0x0c: // Standard VGA 1618 case 0x0d: // Standard VGA 1619 case 0x0e: // Standard VGA 1620 case 0x0f: // Standard VGA 1621 case 0x10: // Standard VGA 1622 case 0x11: // Standard VGA 1623 case 0x12: // Standard VGA 1624 case 0x13: // Standard VGA 1625 case 0x14: // Standard VGA 1626 case 0x15: // Standard VGA 1627 case 0x16: // Standard VGA 1628 case 0x17: // Standard VGA 1629 case 0x18: // Standard VGA 1630 return s->vga.cr[s->vga.cr_index]; 1631 case 0x24: // Attribute Controller Toggle Readback (R) 1632 return (s->vga.ar_flip_flop << 7); 1633 case 0x19: // Interlace End 1634 case 0x1a: // Miscellaneous Control 1635 case 0x1b: // Extended Display Control 1636 case 0x1c: // Sync Adjust and Genlock 1637 case 0x1d: // Overlay Extended Control 1638 case 0x22: // Graphics Data Latches Readback (R) 1639 case 0x25: // Part Status 1640 case 0x27: // Part ID (R) 1641 return s->vga.cr[s->vga.cr_index]; 1642 case 0x26: // Attribute Controller Index Readback (R) 1643 return s->vga.ar_index & 0x3f; 1644 break; 1645 default: 1646 #ifdef DEBUG_CIRRUS 1647 printf("cirrus: inport cr_index %02x\n", reg_index); 1648 #endif 1649 return 0xff; 1650 } 1651 } 1652 1653 static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value) 1654 { 1655 switch (s->vga.cr_index) { 1656 case 0x00: // Standard VGA 1657 case 0x01: // Standard VGA 1658 case 0x02: // Standard VGA 1659 case 0x03: // Standard VGA 1660 case 0x04: // Standard VGA 1661 case 0x05: // Standard VGA 1662 case 0x06: // Standard VGA 1663 case 0x07: // Standard VGA 1664 case 0x08: // Standard VGA 1665 case 0x09: // Standard VGA 1666 case 0x0a: // Standard VGA 1667 case 0x0b: // Standard VGA 1668 case 0x0c: // Standard VGA 1669 case 0x0d: // Standard VGA 1670 case 0x0e: // Standard VGA 1671 case 0x0f: // Standard VGA 1672 case 0x10: // Standard VGA 1673 case 0x11: // Standard VGA 1674 case 0x12: // Standard VGA 1675 case 0x13: // Standard VGA 1676 case 0x14: // Standard VGA 1677 case 0x15: // Standard VGA 1678 case 0x16: // Standard VGA 1679 case 0x17: // Standard VGA 1680 case 0x18: // Standard VGA 1681 /* handle CR0-7 protection */ 1682 if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) { 1683 /* can always write bit 4 of CR7 */ 1684 if (s->vga.cr_index == 7) 1685 s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10); 1686 return; 1687 } 1688 s->vga.cr[s->vga.cr_index] = reg_value; 1689 switch(s->vga.cr_index) { 1690 case 0x00: 1691 case 0x04: 1692 case 0x05: 1693 case 0x06: 1694 case 0x07: 1695 case 0x11: 1696 case 0x17: 1697 s->vga.update_retrace_info(&s->vga); 1698 break; 1699 } 1700 break; 1701 case 0x19: // Interlace End 1702 case 0x1a: // Miscellaneous Control 1703 case 0x1b: // Extended Display Control 1704 case 0x1c: // Sync Adjust and Genlock 1705 case 0x1d: // Overlay Extended Control 1706 s->vga.cr[s->vga.cr_index] = reg_value; 1707 #ifdef DEBUG_CIRRUS 1708 printf("cirrus: handled outport cr_index %02x, cr_value %02x\n", 1709 s->vga.cr_index, reg_value); 1710 #endif 1711 break; 1712 case 0x22: // Graphics Data Latches Readback (R) 1713 case 0x24: // Attribute Controller Toggle Readback (R) 1714 case 0x26: // Attribute Controller Index Readback (R) 1715 case 0x27: // Part ID (R) 1716 break; 1717 case 0x25: // Part Status 1718 default: 1719 #ifdef DEBUG_CIRRUS 1720 printf("cirrus: outport cr_index %02x, cr_value %02x\n", 1721 s->vga.cr_index, reg_value); 1722 #endif 1723 break; 1724 } 1725 } 1726 1727 /*************************************** 1728 * 1729 * memory-mapped I/O (bitblt) 1730 * 1731 ***************************************/ 1732 1733 static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address) 1734 { 1735 int value = 0xff; 1736 1737 switch (address) { 1738 case (CIRRUS_MMIO_BLTBGCOLOR + 0): 1739 value = cirrus_vga_read_gr(s, 0x00); 1740 break; 1741 case (CIRRUS_MMIO_BLTBGCOLOR + 1): 1742 value = cirrus_vga_read_gr(s, 0x10); 1743 break; 1744 case (CIRRUS_MMIO_BLTBGCOLOR + 2): 1745 value = cirrus_vga_read_gr(s, 0x12); 1746 break; 1747 case (CIRRUS_MMIO_BLTBGCOLOR + 3): 1748 value = cirrus_vga_read_gr(s, 0x14); 1749 break; 1750 case (CIRRUS_MMIO_BLTFGCOLOR + 0): 1751 value = cirrus_vga_read_gr(s, 0x01); 1752 break; 1753 case (CIRRUS_MMIO_BLTFGCOLOR + 1): 1754 value = cirrus_vga_read_gr(s, 0x11); 1755 break; 1756 case (CIRRUS_MMIO_BLTFGCOLOR + 2): 1757 value = cirrus_vga_read_gr(s, 0x13); 1758 break; 1759 case (CIRRUS_MMIO_BLTFGCOLOR + 3): 1760 value = cirrus_vga_read_gr(s, 0x15); 1761 break; 1762 case (CIRRUS_MMIO_BLTWIDTH + 0): 1763 value = cirrus_vga_read_gr(s, 0x20); 1764 break; 1765 case (CIRRUS_MMIO_BLTWIDTH + 1): 1766 value = cirrus_vga_read_gr(s, 0x21); 1767 break; 1768 case (CIRRUS_MMIO_BLTHEIGHT + 0): 1769 value = cirrus_vga_read_gr(s, 0x22); 1770 break; 1771 case (CIRRUS_MMIO_BLTHEIGHT + 1): 1772 value = cirrus_vga_read_gr(s, 0x23); 1773 break; 1774 case (CIRRUS_MMIO_BLTDESTPITCH + 0): 1775 value = cirrus_vga_read_gr(s, 0x24); 1776 break; 1777 case (CIRRUS_MMIO_BLTDESTPITCH + 1): 1778 value = cirrus_vga_read_gr(s, 0x25); 1779 break; 1780 case (CIRRUS_MMIO_BLTSRCPITCH + 0): 1781 value = cirrus_vga_read_gr(s, 0x26); 1782 break; 1783 case (CIRRUS_MMIO_BLTSRCPITCH + 1): 1784 value = cirrus_vga_read_gr(s, 0x27); 1785 break; 1786 case (CIRRUS_MMIO_BLTDESTADDR + 0): 1787 value = cirrus_vga_read_gr(s, 0x28); 1788 break; 1789 case (CIRRUS_MMIO_BLTDESTADDR + 1): 1790 value = cirrus_vga_read_gr(s, 0x29); 1791 break; 1792 case (CIRRUS_MMIO_BLTDESTADDR + 2): 1793 value = cirrus_vga_read_gr(s, 0x2a); 1794 break; 1795 case (CIRRUS_MMIO_BLTSRCADDR + 0): 1796 value = cirrus_vga_read_gr(s, 0x2c); 1797 break; 1798 case (CIRRUS_MMIO_BLTSRCADDR + 1): 1799 value = cirrus_vga_read_gr(s, 0x2d); 1800 break; 1801 case (CIRRUS_MMIO_BLTSRCADDR + 2): 1802 value = cirrus_vga_read_gr(s, 0x2e); 1803 break; 1804 case CIRRUS_MMIO_BLTWRITEMASK: 1805 value = cirrus_vga_read_gr(s, 0x2f); 1806 break; 1807 case CIRRUS_MMIO_BLTMODE: 1808 value = cirrus_vga_read_gr(s, 0x30); 1809 break; 1810 case CIRRUS_MMIO_BLTROP: 1811 value = cirrus_vga_read_gr(s, 0x32); 1812 break; 1813 case CIRRUS_MMIO_BLTMODEEXT: 1814 value = cirrus_vga_read_gr(s, 0x33); 1815 break; 1816 case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): 1817 value = cirrus_vga_read_gr(s, 0x34); 1818 break; 1819 case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): 1820 value = cirrus_vga_read_gr(s, 0x35); 1821 break; 1822 case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): 1823 value = cirrus_vga_read_gr(s, 0x38); 1824 break; 1825 case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): 1826 value = cirrus_vga_read_gr(s, 0x39); 1827 break; 1828 case CIRRUS_MMIO_BLTSTATUS: 1829 value = cirrus_vga_read_gr(s, 0x31); 1830 break; 1831 default: 1832 #ifdef DEBUG_CIRRUS 1833 printf("cirrus: mmio read - address 0x%04x\n", address); 1834 #endif 1835 break; 1836 } 1837 1838 trace_vga_cirrus_write_blt(address, value); 1839 return (uint8_t) value; 1840 } 1841 1842 static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, 1843 uint8_t value) 1844 { 1845 trace_vga_cirrus_write_blt(address, value); 1846 switch (address) { 1847 case (CIRRUS_MMIO_BLTBGCOLOR + 0): 1848 cirrus_vga_write_gr(s, 0x00, value); 1849 break; 1850 case (CIRRUS_MMIO_BLTBGCOLOR + 1): 1851 cirrus_vga_write_gr(s, 0x10, value); 1852 break; 1853 case (CIRRUS_MMIO_BLTBGCOLOR + 2): 1854 cirrus_vga_write_gr(s, 0x12, value); 1855 break; 1856 case (CIRRUS_MMIO_BLTBGCOLOR + 3): 1857 cirrus_vga_write_gr(s, 0x14, value); 1858 break; 1859 case (CIRRUS_MMIO_BLTFGCOLOR + 0): 1860 cirrus_vga_write_gr(s, 0x01, value); 1861 break; 1862 case (CIRRUS_MMIO_BLTFGCOLOR + 1): 1863 cirrus_vga_write_gr(s, 0x11, value); 1864 break; 1865 case (CIRRUS_MMIO_BLTFGCOLOR + 2): 1866 cirrus_vga_write_gr(s, 0x13, value); 1867 break; 1868 case (CIRRUS_MMIO_BLTFGCOLOR + 3): 1869 cirrus_vga_write_gr(s, 0x15, value); 1870 break; 1871 case (CIRRUS_MMIO_BLTWIDTH + 0): 1872 cirrus_vga_write_gr(s, 0x20, value); 1873 break; 1874 case (CIRRUS_MMIO_BLTWIDTH + 1): 1875 cirrus_vga_write_gr(s, 0x21, value); 1876 break; 1877 case (CIRRUS_MMIO_BLTHEIGHT + 0): 1878 cirrus_vga_write_gr(s, 0x22, value); 1879 break; 1880 case (CIRRUS_MMIO_BLTHEIGHT + 1): 1881 cirrus_vga_write_gr(s, 0x23, value); 1882 break; 1883 case (CIRRUS_MMIO_BLTDESTPITCH + 0): 1884 cirrus_vga_write_gr(s, 0x24, value); 1885 break; 1886 case (CIRRUS_MMIO_BLTDESTPITCH + 1): 1887 cirrus_vga_write_gr(s, 0x25, value); 1888 break; 1889 case (CIRRUS_MMIO_BLTSRCPITCH + 0): 1890 cirrus_vga_write_gr(s, 0x26, value); 1891 break; 1892 case (CIRRUS_MMIO_BLTSRCPITCH + 1): 1893 cirrus_vga_write_gr(s, 0x27, value); 1894 break; 1895 case (CIRRUS_MMIO_BLTDESTADDR + 0): 1896 cirrus_vga_write_gr(s, 0x28, value); 1897 break; 1898 case (CIRRUS_MMIO_BLTDESTADDR + 1): 1899 cirrus_vga_write_gr(s, 0x29, value); 1900 break; 1901 case (CIRRUS_MMIO_BLTDESTADDR + 2): 1902 cirrus_vga_write_gr(s, 0x2a, value); 1903 break; 1904 case (CIRRUS_MMIO_BLTDESTADDR + 3): 1905 /* ignored */ 1906 break; 1907 case (CIRRUS_MMIO_BLTSRCADDR + 0): 1908 cirrus_vga_write_gr(s, 0x2c, value); 1909 break; 1910 case (CIRRUS_MMIO_BLTSRCADDR + 1): 1911 cirrus_vga_write_gr(s, 0x2d, value); 1912 break; 1913 case (CIRRUS_MMIO_BLTSRCADDR + 2): 1914 cirrus_vga_write_gr(s, 0x2e, value); 1915 break; 1916 case CIRRUS_MMIO_BLTWRITEMASK: 1917 cirrus_vga_write_gr(s, 0x2f, value); 1918 break; 1919 case CIRRUS_MMIO_BLTMODE: 1920 cirrus_vga_write_gr(s, 0x30, value); 1921 break; 1922 case CIRRUS_MMIO_BLTROP: 1923 cirrus_vga_write_gr(s, 0x32, value); 1924 break; 1925 case CIRRUS_MMIO_BLTMODEEXT: 1926 cirrus_vga_write_gr(s, 0x33, value); 1927 break; 1928 case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): 1929 cirrus_vga_write_gr(s, 0x34, value); 1930 break; 1931 case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): 1932 cirrus_vga_write_gr(s, 0x35, value); 1933 break; 1934 case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): 1935 cirrus_vga_write_gr(s, 0x38, value); 1936 break; 1937 case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): 1938 cirrus_vga_write_gr(s, 0x39, value); 1939 break; 1940 case CIRRUS_MMIO_BLTSTATUS: 1941 cirrus_vga_write_gr(s, 0x31, value); 1942 break; 1943 default: 1944 #ifdef DEBUG_CIRRUS 1945 printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n", 1946 address, value); 1947 #endif 1948 break; 1949 } 1950 } 1951 1952 /*************************************** 1953 * 1954 * write mode 4/5 1955 * 1956 ***************************************/ 1957 1958 static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, 1959 unsigned mode, 1960 unsigned offset, 1961 uint32_t mem_value) 1962 { 1963 int x; 1964 unsigned val = mem_value; 1965 uint8_t *dst; 1966 1967 for (x = 0; x < 8; x++) { 1968 dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask); 1969 if (val & 0x80) { 1970 *dst = s->cirrus_shadow_gr1; 1971 } else if (mode == 5) { 1972 *dst = s->cirrus_shadow_gr0; 1973 } 1974 val <<= 1; 1975 } 1976 memory_region_set_dirty(&s->vga.vram, offset, 8); 1977 } 1978 1979 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, 1980 unsigned mode, 1981 unsigned offset, 1982 uint32_t mem_value) 1983 { 1984 int x; 1985 unsigned val = mem_value; 1986 uint8_t *dst; 1987 1988 for (x = 0; x < 8; x++) { 1989 dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1); 1990 if (val & 0x80) { 1991 *dst = s->cirrus_shadow_gr1; 1992 *(dst + 1) = s->vga.gr[0x11]; 1993 } else if (mode == 5) { 1994 *dst = s->cirrus_shadow_gr0; 1995 *(dst + 1) = s->vga.gr[0x10]; 1996 } 1997 val <<= 1; 1998 } 1999 memory_region_set_dirty(&s->vga.vram, offset, 16); 2000 } 2001 2002 /*************************************** 2003 * 2004 * memory access between 0xa0000-0xbffff 2005 * 2006 ***************************************/ 2007 2008 static uint64_t cirrus_vga_mem_read(void *opaque, 2009 hwaddr addr, 2010 uint32_t size) 2011 { 2012 CirrusVGAState *s = opaque; 2013 unsigned bank_index; 2014 unsigned bank_offset; 2015 uint32_t val; 2016 2017 if ((s->vga.sr[0x07] & 0x01) == 0) { 2018 return vga_mem_readb(&s->vga, addr); 2019 } 2020 2021 if (addr < 0x10000) { 2022 /* XXX handle bitblt */ 2023 /* video memory */ 2024 bank_index = addr >> 15; 2025 bank_offset = addr & 0x7fff; 2026 if (bank_offset < s->cirrus_bank_limit[bank_index]) { 2027 bank_offset += s->cirrus_bank_base[bank_index]; 2028 if ((s->vga.gr[0x0B] & 0x14) == 0x14) { 2029 bank_offset <<= 4; 2030 } else if (s->vga.gr[0x0B] & 0x02) { 2031 bank_offset <<= 3; 2032 } 2033 bank_offset &= s->cirrus_addr_mask; 2034 val = *(s->vga.vram_ptr + bank_offset); 2035 } else 2036 val = 0xff; 2037 } else if (addr >= 0x18000 && addr < 0x18100) { 2038 /* memory-mapped I/O */ 2039 val = 0xff; 2040 if ((s->vga.sr[0x17] & 0x44) == 0x04) { 2041 val = cirrus_mmio_blt_read(s, addr & 0xff); 2042 } 2043 } else { 2044 val = 0xff; 2045 #ifdef DEBUG_CIRRUS 2046 printf("cirrus: mem_readb " TARGET_FMT_plx "\n", addr); 2047 #endif 2048 } 2049 return val; 2050 } 2051 2052 static void cirrus_vga_mem_write(void *opaque, 2053 hwaddr addr, 2054 uint64_t mem_value, 2055 uint32_t size) 2056 { 2057 CirrusVGAState *s = opaque; 2058 unsigned bank_index; 2059 unsigned bank_offset; 2060 unsigned mode; 2061 2062 if ((s->vga.sr[0x07] & 0x01) == 0) { 2063 vga_mem_writeb(&s->vga, addr, mem_value); 2064 return; 2065 } 2066 2067 if (addr < 0x10000) { 2068 if (s->cirrus_srcptr != s->cirrus_srcptr_end) { 2069 /* bitblt */ 2070 *s->cirrus_srcptr++ = (uint8_t) mem_value; 2071 if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { 2072 cirrus_bitblt_cputovideo_next(s); 2073 } 2074 } else { 2075 /* video memory */ 2076 bank_index = addr >> 15; 2077 bank_offset = addr & 0x7fff; 2078 if (bank_offset < s->cirrus_bank_limit[bank_index]) { 2079 bank_offset += s->cirrus_bank_base[bank_index]; 2080 if ((s->vga.gr[0x0B] & 0x14) == 0x14) { 2081 bank_offset <<= 4; 2082 } else if (s->vga.gr[0x0B] & 0x02) { 2083 bank_offset <<= 3; 2084 } 2085 bank_offset &= s->cirrus_addr_mask; 2086 mode = s->vga.gr[0x05] & 0x7; 2087 if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { 2088 *(s->vga.vram_ptr + bank_offset) = mem_value; 2089 memory_region_set_dirty(&s->vga.vram, bank_offset, 2090 sizeof(mem_value)); 2091 } else { 2092 if ((s->vga.gr[0x0B] & 0x14) != 0x14) { 2093 cirrus_mem_writeb_mode4and5_8bpp(s, mode, 2094 bank_offset, 2095 mem_value); 2096 } else { 2097 cirrus_mem_writeb_mode4and5_16bpp(s, mode, 2098 bank_offset, 2099 mem_value); 2100 } 2101 } 2102 } 2103 } 2104 } else if (addr >= 0x18000 && addr < 0x18100) { 2105 /* memory-mapped I/O */ 2106 if ((s->vga.sr[0x17] & 0x44) == 0x04) { 2107 cirrus_mmio_blt_write(s, addr & 0xff, mem_value); 2108 } 2109 } else { 2110 #ifdef DEBUG_CIRRUS 2111 printf("cirrus: mem_writeb " TARGET_FMT_plx " value 0x%02" PRIu64 "\n", addr, 2112 mem_value); 2113 #endif 2114 } 2115 } 2116 2117 static const MemoryRegionOps cirrus_vga_mem_ops = { 2118 .read = cirrus_vga_mem_read, 2119 .write = cirrus_vga_mem_write, 2120 .endianness = DEVICE_LITTLE_ENDIAN, 2121 .impl = { 2122 .min_access_size = 1, 2123 .max_access_size = 1, 2124 }, 2125 }; 2126 2127 /*************************************** 2128 * 2129 * hardware cursor 2130 * 2131 ***************************************/ 2132 2133 static inline void invalidate_cursor1(CirrusVGAState *s) 2134 { 2135 if (s->last_hw_cursor_size) { 2136 vga_invalidate_scanlines(&s->vga, 2137 s->last_hw_cursor_y + s->last_hw_cursor_y_start, 2138 s->last_hw_cursor_y + s->last_hw_cursor_y_end); 2139 } 2140 } 2141 2142 static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s) 2143 { 2144 const uint8_t *src; 2145 uint32_t content; 2146 int y, y_min, y_max; 2147 2148 src = s->vga.vram_ptr + s->real_vram_size - 16 * KiB; 2149 if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) { 2150 src += (s->vga.sr[0x13] & 0x3c) * 256; 2151 y_min = 64; 2152 y_max = -1; 2153 for(y = 0; y < 64; y++) { 2154 content = ((uint32_t *)src)[0] | 2155 ((uint32_t *)src)[1] | 2156 ((uint32_t *)src)[2] | 2157 ((uint32_t *)src)[3]; 2158 if (content) { 2159 if (y < y_min) 2160 y_min = y; 2161 if (y > y_max) 2162 y_max = y; 2163 } 2164 src += 16; 2165 } 2166 } else { 2167 src += (s->vga.sr[0x13] & 0x3f) * 256; 2168 y_min = 32; 2169 y_max = -1; 2170 for(y = 0; y < 32; y++) { 2171 content = ((uint32_t *)src)[0] | 2172 ((uint32_t *)(src + 128))[0]; 2173 if (content) { 2174 if (y < y_min) 2175 y_min = y; 2176 if (y > y_max) 2177 y_max = y; 2178 } 2179 src += 4; 2180 } 2181 } 2182 if (y_min > y_max) { 2183 s->last_hw_cursor_y_start = 0; 2184 s->last_hw_cursor_y_end = 0; 2185 } else { 2186 s->last_hw_cursor_y_start = y_min; 2187 s->last_hw_cursor_y_end = y_max + 1; 2188 } 2189 } 2190 2191 /* NOTE: we do not currently handle the cursor bitmap change, so we 2192 update the cursor only if it moves. */ 2193 static void cirrus_cursor_invalidate(VGACommonState *s1) 2194 { 2195 CirrusVGAState *s = container_of(s1, CirrusVGAState, vga); 2196 int size; 2197 2198 if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) { 2199 size = 0; 2200 } else { 2201 if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) 2202 size = 64; 2203 else 2204 size = 32; 2205 } 2206 /* invalidate last cursor and new cursor if any change */ 2207 if (s->last_hw_cursor_size != size || 2208 s->last_hw_cursor_x != s->vga.hw_cursor_x || 2209 s->last_hw_cursor_y != s->vga.hw_cursor_y) { 2210 2211 invalidate_cursor1(s); 2212 2213 s->last_hw_cursor_size = size; 2214 s->last_hw_cursor_x = s->vga.hw_cursor_x; 2215 s->last_hw_cursor_y = s->vga.hw_cursor_y; 2216 /* compute the real cursor min and max y */ 2217 cirrus_cursor_compute_yrange(s); 2218 invalidate_cursor1(s); 2219 } 2220 } 2221 2222 static void vga_draw_cursor_line(uint8_t *d1, 2223 const uint8_t *src1, 2224 int poffset, int w, 2225 unsigned int color0, 2226 unsigned int color1, 2227 unsigned int color_xor) 2228 { 2229 const uint8_t *plane0, *plane1; 2230 int x, b0, b1; 2231 uint8_t *d; 2232 2233 d = d1; 2234 plane0 = src1; 2235 plane1 = src1 + poffset; 2236 for (x = 0; x < w; x++) { 2237 b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1; 2238 b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1; 2239 switch (b0 | (b1 << 1)) { 2240 case 0: 2241 break; 2242 case 1: 2243 ((uint32_t *)d)[0] ^= color_xor; 2244 break; 2245 case 2: 2246 ((uint32_t *)d)[0] = color0; 2247 break; 2248 case 3: 2249 ((uint32_t *)d)[0] = color1; 2250 break; 2251 } 2252 d += 4; 2253 } 2254 } 2255 2256 static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) 2257 { 2258 CirrusVGAState *s = container_of(s1, CirrusVGAState, vga); 2259 int w, h, x1, x2, poffset; 2260 unsigned int color0, color1; 2261 const uint8_t *palette, *src; 2262 uint32_t content; 2263 2264 if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) 2265 return; 2266 /* fast test to see if the cursor intersects with the scan line */ 2267 if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) { 2268 h = 64; 2269 } else { 2270 h = 32; 2271 } 2272 if (scr_y < s->vga.hw_cursor_y || 2273 scr_y >= (s->vga.hw_cursor_y + h)) { 2274 return; 2275 } 2276 2277 src = s->vga.vram_ptr + s->real_vram_size - 16 * KiB; 2278 if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) { 2279 src += (s->vga.sr[0x13] & 0x3c) * 256; 2280 src += (scr_y - s->vga.hw_cursor_y) * 16; 2281 poffset = 8; 2282 content = ((uint32_t *)src)[0] | 2283 ((uint32_t *)src)[1] | 2284 ((uint32_t *)src)[2] | 2285 ((uint32_t *)src)[3]; 2286 } else { 2287 src += (s->vga.sr[0x13] & 0x3f) * 256; 2288 src += (scr_y - s->vga.hw_cursor_y) * 4; 2289 2290 2291 poffset = 128; 2292 content = ((uint32_t *)src)[0] | 2293 ((uint32_t *)(src + 128))[0]; 2294 } 2295 /* if nothing to draw, no need to continue */ 2296 if (!content) 2297 return; 2298 w = h; 2299 2300 x1 = s->vga.hw_cursor_x; 2301 if (x1 >= s->vga.last_scr_width) 2302 return; 2303 x2 = s->vga.hw_cursor_x + w; 2304 if (x2 > s->vga.last_scr_width) 2305 x2 = s->vga.last_scr_width; 2306 w = x2 - x1; 2307 palette = s->cirrus_hidden_palette; 2308 color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]), 2309 c6_to_8(palette[0x0 * 3 + 1]), 2310 c6_to_8(palette[0x0 * 3 + 2])); 2311 color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]), 2312 c6_to_8(palette[0xf * 3 + 1]), 2313 c6_to_8(palette[0xf * 3 + 2])); 2314 d1 += x1 * 4; 2315 vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff); 2316 } 2317 2318 /*************************************** 2319 * 2320 * LFB memory access 2321 * 2322 ***************************************/ 2323 2324 static uint64_t cirrus_linear_read(void *opaque, hwaddr addr, 2325 unsigned size) 2326 { 2327 CirrusVGAState *s = opaque; 2328 uint32_t ret; 2329 2330 addr &= s->cirrus_addr_mask; 2331 2332 if (((s->vga.sr[0x17] & 0x44) == 0x44) && 2333 ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { 2334 /* memory-mapped I/O */ 2335 ret = cirrus_mmio_blt_read(s, addr & 0xff); 2336 } else if (0) { 2337 /* XXX handle bitblt */ 2338 ret = 0xff; 2339 } else { 2340 /* video memory */ 2341 if ((s->vga.gr[0x0B] & 0x14) == 0x14) { 2342 addr <<= 4; 2343 } else if (s->vga.gr[0x0B] & 0x02) { 2344 addr <<= 3; 2345 } 2346 addr &= s->cirrus_addr_mask; 2347 ret = *(s->vga.vram_ptr + addr); 2348 } 2349 2350 return ret; 2351 } 2352 2353 static void cirrus_linear_write(void *opaque, hwaddr addr, 2354 uint64_t val, unsigned size) 2355 { 2356 CirrusVGAState *s = opaque; 2357 unsigned mode; 2358 2359 addr &= s->cirrus_addr_mask; 2360 2361 if (((s->vga.sr[0x17] & 0x44) == 0x44) && 2362 ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { 2363 /* memory-mapped I/O */ 2364 cirrus_mmio_blt_write(s, addr & 0xff, val); 2365 } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { 2366 /* bitblt */ 2367 *s->cirrus_srcptr++ = (uint8_t) val; 2368 if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { 2369 cirrus_bitblt_cputovideo_next(s); 2370 } 2371 } else { 2372 /* video memory */ 2373 if ((s->vga.gr[0x0B] & 0x14) == 0x14) { 2374 addr <<= 4; 2375 } else if (s->vga.gr[0x0B] & 0x02) { 2376 addr <<= 3; 2377 } 2378 addr &= s->cirrus_addr_mask; 2379 2380 mode = s->vga.gr[0x05] & 0x7; 2381 if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { 2382 *(s->vga.vram_ptr + addr) = (uint8_t) val; 2383 memory_region_set_dirty(&s->vga.vram, addr, 1); 2384 } else { 2385 if ((s->vga.gr[0x0B] & 0x14) != 0x14) { 2386 cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); 2387 } else { 2388 cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val); 2389 } 2390 } 2391 } 2392 } 2393 2394 /*************************************** 2395 * 2396 * system to screen memory access 2397 * 2398 ***************************************/ 2399 2400 2401 static uint64_t cirrus_linear_bitblt_read(void *opaque, 2402 hwaddr addr, 2403 unsigned size) 2404 { 2405 CirrusVGAState *s = opaque; 2406 uint32_t ret; 2407 2408 /* XXX handle bitblt */ 2409 (void)s; 2410 ret = 0xff; 2411 return ret; 2412 } 2413 2414 static void cirrus_linear_bitblt_write(void *opaque, 2415 hwaddr addr, 2416 uint64_t val, 2417 unsigned size) 2418 { 2419 CirrusVGAState *s = opaque; 2420 2421 if (s->cirrus_srcptr != s->cirrus_srcptr_end) { 2422 /* bitblt */ 2423 *s->cirrus_srcptr++ = (uint8_t) val; 2424 if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { 2425 cirrus_bitblt_cputovideo_next(s); 2426 } 2427 } 2428 } 2429 2430 static const MemoryRegionOps cirrus_linear_bitblt_io_ops = { 2431 .read = cirrus_linear_bitblt_read, 2432 .write = cirrus_linear_bitblt_write, 2433 .endianness = DEVICE_LITTLE_ENDIAN, 2434 .impl = { 2435 .min_access_size = 1, 2436 .max_access_size = 1, 2437 }, 2438 }; 2439 2440 static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank) 2441 { 2442 MemoryRegion *mr = &s->cirrus_bank[bank]; 2443 bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end) 2444 && !((s->vga.sr[0x07] & 0x01) == 0) 2445 && !((s->vga.gr[0x0B] & 0x14) == 0x14) 2446 && !(s->vga.gr[0x0B] & 0x02); 2447 2448 memory_region_set_enabled(mr, enabled); 2449 memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]); 2450 } 2451 2452 static void map_linear_vram(CirrusVGAState *s) 2453 { 2454 if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) { 2455 s->linear_vram = true; 2456 memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1); 2457 } 2458 map_linear_vram_bank(s, 0); 2459 map_linear_vram_bank(s, 1); 2460 } 2461 2462 static void unmap_linear_vram(CirrusVGAState *s) 2463 { 2464 if (s->bustype == CIRRUS_BUSTYPE_PCI && s->linear_vram) { 2465 s->linear_vram = false; 2466 memory_region_del_subregion(&s->pci_bar, &s->vga.vram); 2467 } 2468 memory_region_set_enabled(&s->cirrus_bank[0], false); 2469 memory_region_set_enabled(&s->cirrus_bank[1], false); 2470 } 2471 2472 /* Compute the memory access functions */ 2473 static void cirrus_update_memory_access(CirrusVGAState *s) 2474 { 2475 unsigned mode; 2476 2477 memory_region_transaction_begin(); 2478 if ((s->vga.sr[0x17] & 0x44) == 0x44) { 2479 goto generic_io; 2480 } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { 2481 goto generic_io; 2482 } else { 2483 if ((s->vga.gr[0x0B] & 0x14) == 0x14) { 2484 goto generic_io; 2485 } else if (s->vga.gr[0x0B] & 0x02) { 2486 goto generic_io; 2487 } 2488 2489 mode = s->vga.gr[0x05] & 0x7; 2490 if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { 2491 map_linear_vram(s); 2492 } else { 2493 generic_io: 2494 unmap_linear_vram(s); 2495 } 2496 } 2497 memory_region_transaction_commit(); 2498 } 2499 2500 2501 /* I/O ports */ 2502 2503 static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr, 2504 unsigned size) 2505 { 2506 CirrusVGAState *c = opaque; 2507 VGACommonState *s = &c->vga; 2508 int val, index; 2509 2510 addr += 0x3b0; 2511 2512 if (vga_ioport_invalid(s, addr)) { 2513 val = 0xff; 2514 } else { 2515 switch (addr) { 2516 case 0x3c0: 2517 if (s->ar_flip_flop == 0) { 2518 val = s->ar_index; 2519 } else { 2520 val = 0; 2521 } 2522 break; 2523 case 0x3c1: 2524 index = s->ar_index & 0x1f; 2525 if (index < 21) 2526 val = s->ar[index]; 2527 else 2528 val = 0; 2529 break; 2530 case 0x3c2: 2531 val = s->st00; 2532 break; 2533 case 0x3c4: 2534 val = s->sr_index; 2535 break; 2536 case 0x3c5: 2537 val = cirrus_vga_read_sr(c); 2538 break; 2539 #ifdef DEBUG_VGA_REG 2540 printf("vga: read SR%x = 0x%02x\n", s->sr_index, val); 2541 #endif 2542 break; 2543 case 0x3c6: 2544 val = cirrus_read_hidden_dac(c); 2545 break; 2546 case 0x3c7: 2547 val = s->dac_state; 2548 break; 2549 case 0x3c8: 2550 val = s->dac_write_index; 2551 c->cirrus_hidden_dac_lockindex = 0; 2552 break; 2553 case 0x3c9: 2554 val = cirrus_vga_read_palette(c); 2555 break; 2556 case 0x3ca: 2557 val = s->fcr; 2558 break; 2559 case 0x3cc: 2560 val = s->msr; 2561 break; 2562 case 0x3ce: 2563 val = s->gr_index; 2564 break; 2565 case 0x3cf: 2566 val = cirrus_vga_read_gr(c, s->gr_index); 2567 #ifdef DEBUG_VGA_REG 2568 printf("vga: read GR%x = 0x%02x\n", s->gr_index, val); 2569 #endif 2570 break; 2571 case 0x3b4: 2572 case 0x3d4: 2573 val = s->cr_index; 2574 break; 2575 case 0x3b5: 2576 case 0x3d5: 2577 val = cirrus_vga_read_cr(c, s->cr_index); 2578 #ifdef DEBUG_VGA_REG 2579 printf("vga: read CR%x = 0x%02x\n", s->cr_index, val); 2580 #endif 2581 break; 2582 case 0x3ba: 2583 case 0x3da: 2584 /* just toggle to fool polling */ 2585 val = s->st01 = s->retrace(s); 2586 s->ar_flip_flop = 0; 2587 break; 2588 default: 2589 val = 0x00; 2590 break; 2591 } 2592 } 2593 trace_vga_cirrus_read_io(addr, val); 2594 return val; 2595 } 2596 2597 static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val, 2598 unsigned size) 2599 { 2600 CirrusVGAState *c = opaque; 2601 VGACommonState *s = &c->vga; 2602 int index; 2603 2604 addr += 0x3b0; 2605 2606 /* check port range access depending on color/monochrome mode */ 2607 if (vga_ioport_invalid(s, addr)) { 2608 return; 2609 } 2610 trace_vga_cirrus_write_io(addr, val); 2611 2612 switch (addr) { 2613 case 0x3c0: 2614 if (s->ar_flip_flop == 0) { 2615 val &= 0x3f; 2616 s->ar_index = val; 2617 } else { 2618 index = s->ar_index & 0x1f; 2619 switch (index) { 2620 case 0x00 ... 0x0f: 2621 s->ar[index] = val & 0x3f; 2622 break; 2623 case 0x10: 2624 s->ar[index] = val & ~0x10; 2625 break; 2626 case 0x11: 2627 s->ar[index] = val; 2628 break; 2629 case 0x12: 2630 s->ar[index] = val & ~0xc0; 2631 break; 2632 case 0x13: 2633 s->ar[index] = val & ~0xf0; 2634 break; 2635 case 0x14: 2636 s->ar[index] = val & ~0xf0; 2637 break; 2638 default: 2639 break; 2640 } 2641 } 2642 s->ar_flip_flop ^= 1; 2643 break; 2644 case 0x3c2: 2645 s->msr = val & ~0x10; 2646 s->update_retrace_info(s); 2647 break; 2648 case 0x3c4: 2649 s->sr_index = val; 2650 break; 2651 case 0x3c5: 2652 #ifdef DEBUG_VGA_REG 2653 printf("vga: write SR%x = 0x%02" PRIu64 "\n", s->sr_index, val); 2654 #endif 2655 cirrus_vga_write_sr(c, val); 2656 break; 2657 case 0x3c6: 2658 cirrus_write_hidden_dac(c, val); 2659 break; 2660 case 0x3c7: 2661 s->dac_read_index = val; 2662 s->dac_sub_index = 0; 2663 s->dac_state = 3; 2664 break; 2665 case 0x3c8: 2666 s->dac_write_index = val; 2667 s->dac_sub_index = 0; 2668 s->dac_state = 0; 2669 break; 2670 case 0x3c9: 2671 cirrus_vga_write_palette(c, val); 2672 break; 2673 case 0x3ce: 2674 s->gr_index = val; 2675 break; 2676 case 0x3cf: 2677 #ifdef DEBUG_VGA_REG 2678 printf("vga: write GR%x = 0x%02" PRIu64 "\n", s->gr_index, val); 2679 #endif 2680 cirrus_vga_write_gr(c, s->gr_index, val); 2681 break; 2682 case 0x3b4: 2683 case 0x3d4: 2684 s->cr_index = val; 2685 break; 2686 case 0x3b5: 2687 case 0x3d5: 2688 #ifdef DEBUG_VGA_REG 2689 printf("vga: write CR%x = 0x%02"PRIu64"\n", s->cr_index, val); 2690 #endif 2691 cirrus_vga_write_cr(c, val); 2692 break; 2693 case 0x3ba: 2694 case 0x3da: 2695 s->fcr = val & 0x10; 2696 break; 2697 } 2698 } 2699 2700 /*************************************** 2701 * 2702 * memory-mapped I/O access 2703 * 2704 ***************************************/ 2705 2706 static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr, 2707 unsigned size) 2708 { 2709 CirrusVGAState *s = opaque; 2710 2711 if (addr >= 0x100) { 2712 return cirrus_mmio_blt_read(s, addr - 0x100); 2713 } else { 2714 return cirrus_vga_ioport_read(s, addr + 0x10, size); 2715 } 2716 } 2717 2718 static void cirrus_mmio_write(void *opaque, hwaddr addr, 2719 uint64_t val, unsigned size) 2720 { 2721 CirrusVGAState *s = opaque; 2722 2723 if (addr >= 0x100) { 2724 cirrus_mmio_blt_write(s, addr - 0x100, val); 2725 } else { 2726 cirrus_vga_ioport_write(s, addr + 0x10, val, size); 2727 } 2728 } 2729 2730 static const MemoryRegionOps cirrus_mmio_io_ops = { 2731 .read = cirrus_mmio_read, 2732 .write = cirrus_mmio_write, 2733 .endianness = DEVICE_LITTLE_ENDIAN, 2734 .impl = { 2735 .min_access_size = 1, 2736 .max_access_size = 1, 2737 }, 2738 }; 2739 2740 /* load/save state */ 2741 2742 static int cirrus_post_load(void *opaque, int version_id) 2743 { 2744 CirrusVGAState *s = opaque; 2745 2746 s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f; 2747 s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f; 2748 2749 cirrus_update_bank_ptr(s, 0); 2750 cirrus_update_bank_ptr(s, 1); 2751 cirrus_update_memory_access(s); 2752 /* force refresh */ 2753 s->vga.graphic_mode = -1; 2754 2755 return 0; 2756 } 2757 2758 const VMStateDescription vmstate_cirrus_vga = { 2759 .name = "cirrus_vga", 2760 .version_id = 2, 2761 .minimum_version_id = 1, 2762 .post_load = cirrus_post_load, 2763 .fields = (VMStateField[]) { 2764 VMSTATE_UINT32(vga.latch, CirrusVGAState), 2765 VMSTATE_UINT8(vga.sr_index, CirrusVGAState), 2766 VMSTATE_BUFFER(vga.sr, CirrusVGAState), 2767 VMSTATE_UINT8(vga.gr_index, CirrusVGAState), 2768 VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState), 2769 VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState), 2770 VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2), 2771 VMSTATE_UINT8(vga.ar_index, CirrusVGAState), 2772 VMSTATE_BUFFER(vga.ar, CirrusVGAState), 2773 VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState), 2774 VMSTATE_UINT8(vga.cr_index, CirrusVGAState), 2775 VMSTATE_BUFFER(vga.cr, CirrusVGAState), 2776 VMSTATE_UINT8(vga.msr, CirrusVGAState), 2777 VMSTATE_UINT8(vga.fcr, CirrusVGAState), 2778 VMSTATE_UINT8(vga.st00, CirrusVGAState), 2779 VMSTATE_UINT8(vga.st01, CirrusVGAState), 2780 VMSTATE_UINT8(vga.dac_state, CirrusVGAState), 2781 VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState), 2782 VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState), 2783 VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState), 2784 VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState), 2785 VMSTATE_BUFFER(vga.palette, CirrusVGAState), 2786 VMSTATE_INT32(vga.bank_offset, CirrusVGAState), 2787 VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState), 2788 VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState), 2789 VMSTATE_UINT32(vga.hw_cursor_x, CirrusVGAState), 2790 VMSTATE_UINT32(vga.hw_cursor_y, CirrusVGAState), 2791 /* XXX: we do not save the bitblt state - we assume we do not save 2792 the state when the blitter is active */ 2793 VMSTATE_END_OF_LIST() 2794 } 2795 }; 2796 2797 static const VMStateDescription vmstate_pci_cirrus_vga = { 2798 .name = "cirrus_vga", 2799 .version_id = 2, 2800 .minimum_version_id = 2, 2801 .fields = (VMStateField[]) { 2802 VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState), 2803 VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0, 2804 vmstate_cirrus_vga, CirrusVGAState), 2805 VMSTATE_END_OF_LIST() 2806 } 2807 }; 2808 2809 /*************************************** 2810 * 2811 * initialize 2812 * 2813 ***************************************/ 2814 2815 static void cirrus_reset(void *opaque) 2816 { 2817 CirrusVGAState *s = opaque; 2818 2819 vga_common_reset(&s->vga); 2820 unmap_linear_vram(s); 2821 s->vga.sr[0x06] = 0x0f; 2822 if (s->device_id == CIRRUS_ID_CLGD5446) { 2823 /* 4MB 64 bit memory config, always PCI */ 2824 s->vga.sr[0x1F] = 0x2d; // MemClock 2825 s->vga.gr[0x18] = 0x0f; // fastest memory configuration 2826 s->vga.sr[0x0f] = 0x98; 2827 s->vga.sr[0x17] = 0x20; 2828 s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */ 2829 } else { 2830 s->vga.sr[0x1F] = 0x22; // MemClock 2831 s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M; 2832 s->vga.sr[0x17] = s->bustype; 2833 s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */ 2834 } 2835 s->vga.cr[0x27] = s->device_id; 2836 2837 s->cirrus_hidden_dac_lockindex = 5; 2838 s->cirrus_hidden_dac_data = 0; 2839 } 2840 2841 static const MemoryRegionOps cirrus_linear_io_ops = { 2842 .read = cirrus_linear_read, 2843 .write = cirrus_linear_write, 2844 .endianness = DEVICE_LITTLE_ENDIAN, 2845 .impl = { 2846 .min_access_size = 1, 2847 .max_access_size = 1, 2848 }, 2849 }; 2850 2851 static const MemoryRegionOps cirrus_vga_io_ops = { 2852 .read = cirrus_vga_ioport_read, 2853 .write = cirrus_vga_ioport_write, 2854 .endianness = DEVICE_LITTLE_ENDIAN, 2855 .impl = { 2856 .min_access_size = 1, 2857 .max_access_size = 1, 2858 }, 2859 }; 2860 2861 void cirrus_init_common(CirrusVGAState *s, Object *owner, 2862 int device_id, int is_pci, 2863 MemoryRegion *system_memory, MemoryRegion *system_io) 2864 { 2865 int i; 2866 static int inited; 2867 2868 if (!inited) { 2869 inited = 1; 2870 for(i = 0;i < 256; i++) 2871 rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */ 2872 rop_to_index[CIRRUS_ROP_0] = 0; 2873 rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1; 2874 rop_to_index[CIRRUS_ROP_NOP] = 2; 2875 rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3; 2876 rop_to_index[CIRRUS_ROP_NOTDST] = 4; 2877 rop_to_index[CIRRUS_ROP_SRC] = 5; 2878 rop_to_index[CIRRUS_ROP_1] = 6; 2879 rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7; 2880 rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8; 2881 rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9; 2882 rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10; 2883 rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11; 2884 rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12; 2885 rop_to_index[CIRRUS_ROP_NOTSRC] = 13; 2886 rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14; 2887 rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15; 2888 s->device_id = device_id; 2889 if (is_pci) 2890 s->bustype = CIRRUS_BUSTYPE_PCI; 2891 else 2892 s->bustype = CIRRUS_BUSTYPE_ISA; 2893 } 2894 2895 /* Register ioport 0x3b0 - 0x3df */ 2896 memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s, 2897 "cirrus-io", 0x30); 2898 memory_region_set_flush_coalesced(&s->cirrus_vga_io); 2899 memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io); 2900 2901 memory_region_init(&s->low_mem_container, owner, 2902 "cirrus-lowmem-container", 2903 0x20000); 2904 2905 memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s, 2906 "cirrus-low-memory", 0x20000); 2907 memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem); 2908 for (i = 0; i < 2; ++i) { 2909 static const char *names[] = { "vga.bank0", "vga.bank1" }; 2910 MemoryRegion *bank = &s->cirrus_bank[i]; 2911 memory_region_init_alias(bank, owner, names[i], &s->vga.vram, 2912 0, 0x8000); 2913 memory_region_set_enabled(bank, false); 2914 memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000, 2915 bank, 1); 2916 } 2917 memory_region_add_subregion_overlap(system_memory, 2918 0x000a0000, 2919 &s->low_mem_container, 2920 1); 2921 memory_region_set_coalescing(&s->low_mem); 2922 2923 /* I/O handler for LFB */ 2924 memory_region_init_io(&s->cirrus_linear_io, owner, &cirrus_linear_io_ops, s, 2925 "cirrus-linear-io", s->vga.vram_size_mb * MiB); 2926 memory_region_set_flush_coalesced(&s->cirrus_linear_io); 2927 2928 /* I/O handler for LFB */ 2929 memory_region_init_io(&s->cirrus_linear_bitblt_io, owner, 2930 &cirrus_linear_bitblt_io_ops, 2931 s, 2932 "cirrus-bitblt-mmio", 2933 0x400000); 2934 memory_region_set_flush_coalesced(&s->cirrus_linear_bitblt_io); 2935 2936 /* I/O handler for memory-mapped I/O */ 2937 memory_region_init_io(&s->cirrus_mmio_io, owner, &cirrus_mmio_io_ops, s, 2938 "cirrus-mmio", CIRRUS_PNPMMIO_SIZE); 2939 memory_region_set_flush_coalesced(&s->cirrus_mmio_io); 2940 2941 s->real_vram_size = 2942 (s->device_id == CIRRUS_ID_CLGD5446) ? 4 * MiB : 2 * MiB; 2943 2944 /* XXX: s->vga.vram_size must be a power of two */ 2945 s->cirrus_addr_mask = s->real_vram_size - 1; 2946 s->linear_mmio_mask = s->real_vram_size - 256; 2947 2948 s->vga.get_bpp = cirrus_get_bpp; 2949 s->vga.get_offsets = cirrus_get_offsets; 2950 s->vga.get_resolution = cirrus_get_resolution; 2951 s->vga.cursor_invalidate = cirrus_cursor_invalidate; 2952 s->vga.cursor_draw_line = cirrus_cursor_draw_line; 2953 2954 qemu_register_reset(cirrus_reset, s); 2955 } 2956 2957 /*************************************** 2958 * 2959 * PCI bus support 2960 * 2961 ***************************************/ 2962 2963 static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp) 2964 { 2965 PCICirrusVGAState *d = PCI_CIRRUS_VGA(dev); 2966 CirrusVGAState *s = &d->cirrus_vga; 2967 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); 2968 int16_t device_id = pc->device_id; 2969 2970 /* follow real hardware, cirrus card emulated has 4 MB video memory. 2971 Also accept 8 MB/16 MB for backward compatibility. */ 2972 if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 && 2973 s->vga.vram_size_mb != 16) { 2974 error_setg(errp, "Invalid cirrus_vga ram size '%u'", 2975 s->vga.vram_size_mb); 2976 return; 2977 } 2978 /* setup VGA */ 2979 vga_common_init(&s->vga, OBJECT(dev)); 2980 cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev), 2981 pci_address_space_io(dev)); 2982 s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga); 2983 2984 /* setup PCI */ 2985 2986 memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000); 2987 2988 /* XXX: add byte swapping apertures */ 2989 memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io); 2990 memory_region_add_subregion(&s->pci_bar, 0x1000000, 2991 &s->cirrus_linear_bitblt_io); 2992 2993 /* setup memory space */ 2994 /* memory #0 LFB */ 2995 /* memory #1 memory-mapped I/O */ 2996 /* XXX: s->vga.vram_size must be a power of two */ 2997 pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar); 2998 if (device_id == CIRRUS_ID_CLGD5446) { 2999 pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io); 3000 } 3001 } 3002 3003 static Property pci_vga_cirrus_properties[] = { 3004 DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState, 3005 cirrus_vga.vga.vram_size_mb, 4), 3006 DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState, 3007 cirrus_vga.enable_blitter, true), 3008 DEFINE_PROP_BOOL("global-vmstate", struct PCICirrusVGAState, 3009 cirrus_vga.vga.global_vmstate, false), 3010 DEFINE_PROP_END_OF_LIST(), 3011 }; 3012 3013 static void cirrus_vga_class_init(ObjectClass *klass, void *data) 3014 { 3015 DeviceClass *dc = DEVICE_CLASS(klass); 3016 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 3017 3018 k->realize = pci_cirrus_vga_realize; 3019 k->romfile = VGABIOS_CIRRUS_FILENAME; 3020 k->vendor_id = PCI_VENDOR_ID_CIRRUS; 3021 k->device_id = CIRRUS_ID_CLGD5446; 3022 k->class_id = PCI_CLASS_DISPLAY_VGA; 3023 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); 3024 dc->desc = "Cirrus CLGD 54xx VGA"; 3025 dc->vmsd = &vmstate_pci_cirrus_vga; 3026 dc->props = pci_vga_cirrus_properties; 3027 dc->hotpluggable = false; 3028 } 3029 3030 static const TypeInfo cirrus_vga_info = { 3031 .name = TYPE_PCI_CIRRUS_VGA, 3032 .parent = TYPE_PCI_DEVICE, 3033 .instance_size = sizeof(PCICirrusVGAState), 3034 .class_init = cirrus_vga_class_init, 3035 .interfaces = (InterfaceInfo[]) { 3036 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 3037 { }, 3038 }, 3039 }; 3040 3041 static void cirrus_vga_register_types(void) 3042 { 3043 type_register_static(&cirrus_vga_info); 3044 } 3045 3046 type_init(cirrus_vga_register_types) 3047