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 "qapi/error.h" 31 #include "hw/hw.h" 32 #include "hw/pci/pci.h" 33 #include "ui/console.h" 34 #include "ui/pixel_ops.h" 35 #include "vga_int.h" 36 #include "hw/loader.h" 37 38 /* 39 * TODO: 40 * - destination write mask support not complete (bits 5..7) 41 * - optimize linear mappings 42 * - optimize bitblt functions 43 */ 44 45 //#define DEBUG_CIRRUS 46 //#define DEBUG_BITBLT 47 48 /*************************************** 49 * 50 * definitions 51 * 52 ***************************************/ 53 54 // ID 55 #define CIRRUS_ID_CLGD5422 (0x23<<2) 56 #define CIRRUS_ID_CLGD5426 (0x24<<2) 57 #define CIRRUS_ID_CLGD5424 (0x25<<2) 58 #define CIRRUS_ID_CLGD5428 (0x26<<2) 59 #define CIRRUS_ID_CLGD5430 (0x28<<2) 60 #define CIRRUS_ID_CLGD5434 (0x2A<<2) 61 #define CIRRUS_ID_CLGD5436 (0x2B<<2) 62 #define CIRRUS_ID_CLGD5446 (0x2E<<2) 63 64 // sequencer 0x07 65 #define CIRRUS_SR7_BPP_VGA 0x00 66 #define CIRRUS_SR7_BPP_SVGA 0x01 67 #define CIRRUS_SR7_BPP_MASK 0x0e 68 #define CIRRUS_SR7_BPP_8 0x00 69 #define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 70 #define CIRRUS_SR7_BPP_24 0x04 71 #define CIRRUS_SR7_BPP_16 0x06 72 #define CIRRUS_SR7_BPP_32 0x08 73 #define CIRRUS_SR7_ISAADDR_MASK 0xe0 74 75 // sequencer 0x0f 76 #define CIRRUS_MEMSIZE_512k 0x08 77 #define CIRRUS_MEMSIZE_1M 0x10 78 #define CIRRUS_MEMSIZE_2M 0x18 79 #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled. 80 81 // sequencer 0x12 82 #define CIRRUS_CURSOR_SHOW 0x01 83 #define CIRRUS_CURSOR_HIDDENPEL 0x02 84 #define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear 85 86 // sequencer 0x17 87 #define CIRRUS_BUSTYPE_VLBFAST 0x10 88 #define CIRRUS_BUSTYPE_PCI 0x20 89 #define CIRRUS_BUSTYPE_VLBSLOW 0x30 90 #define CIRRUS_BUSTYPE_ISA 0x38 91 #define CIRRUS_MMIO_ENABLE 0x04 92 #define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared. 93 #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 94 95 // control 0x0b 96 #define CIRRUS_BANKING_DUAL 0x01 97 #define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k 98 99 // control 0x30 100 #define CIRRUS_BLTMODE_BACKWARDS 0x01 101 #define CIRRUS_BLTMODE_MEMSYSDEST 0x02 102 #define CIRRUS_BLTMODE_MEMSYSSRC 0x04 103 #define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 104 #define CIRRUS_BLTMODE_PATTERNCOPY 0x40 105 #define CIRRUS_BLTMODE_COLOREXPAND 0x80 106 #define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 107 #define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 108 #define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 109 #define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 110 #define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 111 112 // control 0x31 113 #define CIRRUS_BLT_BUSY 0x01 114 #define CIRRUS_BLT_START 0x02 115 #define CIRRUS_BLT_RESET 0x04 116 #define CIRRUS_BLT_FIFOUSED 0x10 117 #define CIRRUS_BLT_AUTOSTART 0x80 118 119 // control 0x32 120 #define CIRRUS_ROP_0 0x00 121 #define CIRRUS_ROP_SRC_AND_DST 0x05 122 #define CIRRUS_ROP_NOP 0x06 123 #define CIRRUS_ROP_SRC_AND_NOTDST 0x09 124 #define CIRRUS_ROP_NOTDST 0x0b 125 #define CIRRUS_ROP_SRC 0x0d 126 #define CIRRUS_ROP_1 0x0e 127 #define CIRRUS_ROP_NOTSRC_AND_DST 0x50 128 #define CIRRUS_ROP_SRC_XOR_DST 0x59 129 #define CIRRUS_ROP_SRC_OR_DST 0x6d 130 #define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90 131 #define CIRRUS_ROP_SRC_NOTXOR_DST 0x95 132 #define CIRRUS_ROP_SRC_OR_NOTDST 0xad 133 #define CIRRUS_ROP_NOTSRC 0xd0 134 #define CIRRUS_ROP_NOTSRC_OR_DST 0xd6 135 #define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda 136 137 #define CIRRUS_ROP_NOP_INDEX 2 138 #define CIRRUS_ROP_SRC_INDEX 5 139 140 // control 0x33 141 #define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 142 #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 143 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 144 145 // memory-mapped IO 146 #define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword 147 #define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword 148 #define CIRRUS_MMIO_BLTWIDTH 0x08 // word 149 #define CIRRUS_MMIO_BLTHEIGHT 0x0a // word 150 #define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word 151 #define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word 152 #define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword 153 #define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword 154 #define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte 155 #define CIRRUS_MMIO_BLTMODE 0x18 // byte 156 #define CIRRUS_MMIO_BLTROP 0x1a // byte 157 #define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte 158 #define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word? 159 #define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word? 160 #define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word 161 #define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word 162 #define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word 163 #define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word 164 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte 165 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte 166 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte 167 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte 168 #define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word 169 #define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word 170 #define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word 171 #define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word 172 #define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte 173 #define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte 174 #define CIRRUS_MMIO_BLTSTATUS 0x40 // byte 175 176 #define CIRRUS_PNPMMIO_SIZE 0x1000 177 178 struct CirrusVGAState; 179 typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, 180 uint8_t * dst, const uint8_t * src, 181 int dstpitch, int srcpitch, 182 int bltwidth, int bltheight); 183 typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, 184 uint8_t *dst, int dst_pitch, int width, int height); 185 186 typedef struct CirrusVGAState { 187 VGACommonState vga; 188 189 MemoryRegion cirrus_vga_io; 190 MemoryRegion cirrus_linear_io; 191 MemoryRegion cirrus_linear_bitblt_io; 192 MemoryRegion cirrus_mmio_io; 193 MemoryRegion pci_bar; 194 bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ 195 MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */ 196 MemoryRegion low_mem; /* always mapped, overridden by: */ 197 MemoryRegion cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ 198 uint32_t cirrus_addr_mask; 199 uint32_t linear_mmio_mask; 200 uint8_t cirrus_shadow_gr0; 201 uint8_t cirrus_shadow_gr1; 202 uint8_t cirrus_hidden_dac_lockindex; 203 uint8_t cirrus_hidden_dac_data; 204 uint32_t cirrus_bank_base[2]; 205 uint32_t cirrus_bank_limit[2]; 206 uint8_t cirrus_hidden_palette[48]; 207 int cirrus_blt_pixelwidth; 208 int cirrus_blt_width; 209 int cirrus_blt_height; 210 int cirrus_blt_dstpitch; 211 int cirrus_blt_srcpitch; 212 uint32_t cirrus_blt_fgcol; 213 uint32_t cirrus_blt_bgcol; 214 uint32_t cirrus_blt_dstaddr; 215 uint32_t cirrus_blt_srcaddr; 216 uint8_t cirrus_blt_mode; 217 uint8_t cirrus_blt_modeext; 218 cirrus_bitblt_rop_t cirrus_rop; 219 #define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */ 220 uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE]; 221 uint8_t *cirrus_srcptr; 222 uint8_t *cirrus_srcptr_end; 223 uint32_t cirrus_srccounter; 224 /* hwcursor display state */ 225 int last_hw_cursor_size; 226 int last_hw_cursor_x; 227 int last_hw_cursor_y; 228 int last_hw_cursor_y_start; 229 int last_hw_cursor_y_end; 230 int real_vram_size; /* XXX: suppress that */ 231 int device_id; 232 int bustype; 233 } CirrusVGAState; 234 235 typedef struct PCICirrusVGAState { 236 PCIDevice dev; 237 CirrusVGAState cirrus_vga; 238 } PCICirrusVGAState; 239 240 #define TYPE_PCI_CIRRUS_VGA "cirrus-vga" 241 #define PCI_CIRRUS_VGA(obj) \ 242 OBJECT_CHECK(PCICirrusVGAState, (obj), TYPE_PCI_CIRRUS_VGA) 243 244 #define TYPE_ISA_CIRRUS_VGA "isa-cirrus-vga" 245 #define ISA_CIRRUS_VGA(obj) \ 246 OBJECT_CHECK(ISACirrusVGAState, (obj), TYPE_ISA_CIRRUS_VGA) 247 248 typedef struct ISACirrusVGAState { 249 ISADevice parent_obj; 250 251 CirrusVGAState cirrus_vga; 252 } ISACirrusVGAState; 253 254 static uint8_t rop_to_index[256]; 255 256 /*************************************** 257 * 258 * prototypes. 259 * 260 ***************************************/ 261 262 263 static void cirrus_bitblt_reset(CirrusVGAState *s); 264 static void cirrus_update_memory_access(CirrusVGAState *s); 265 266 /*************************************** 267 * 268 * raster operations 269 * 270 ***************************************/ 271 272 static bool blit_region_is_unsafe(struct CirrusVGAState *s, 273 int32_t pitch, int32_t addr) 274 { 275 if (!pitch) { 276 return true; 277 } 278 if (pitch < 0) { 279 int64_t min = addr 280 + ((int64_t)s->cirrus_blt_height-1) * pitch; 281 int32_t max = addr 282 + s->cirrus_blt_width; 283 if (min < 0 || max > s->vga.vram_size) { 284 return true; 285 } 286 } else { 287 int64_t max = addr 288 + ((int64_t)s->cirrus_blt_height-1) * pitch 289 + s->cirrus_blt_width; 290 if (max > s->vga.vram_size) { 291 return true; 292 } 293 } 294 return false; 295 } 296 297 static bool blit_is_unsafe(struct CirrusVGAState *s) 298 { 299 /* should be the case, see cirrus_bitblt_start */ 300 assert(s->cirrus_blt_width > 0); 301 assert(s->cirrus_blt_height > 0); 302 303 if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) { 304 return true; 305 } 306 307 if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, 308 s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { 309 return true; 310 } 311 if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, 312 s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { 313 return true; 314 } 315 316 return false; 317 } 318 319 static void cirrus_bitblt_rop_nop(CirrusVGAState *s, 320 uint8_t *dst,const uint8_t *src, 321 int dstpitch,int srcpitch, 322 int bltwidth,int bltheight) 323 { 324 } 325 326 static void cirrus_bitblt_fill_nop(CirrusVGAState *s, 327 uint8_t *dst, 328 int dstpitch, int bltwidth,int bltheight) 329 { 330 } 331 332 #define ROP_NAME 0 333 #define ROP_FN(d, s) 0 334 #include "cirrus_vga_rop.h" 335 336 #define ROP_NAME src_and_dst 337 #define ROP_FN(d, s) (s) & (d) 338 #include "cirrus_vga_rop.h" 339 340 #define ROP_NAME src_and_notdst 341 #define ROP_FN(d, s) (s) & (~(d)) 342 #include "cirrus_vga_rop.h" 343 344 #define ROP_NAME notdst 345 #define ROP_FN(d, s) ~(d) 346 #include "cirrus_vga_rop.h" 347 348 #define ROP_NAME src 349 #define ROP_FN(d, s) s 350 #include "cirrus_vga_rop.h" 351 352 #define ROP_NAME 1 353 #define ROP_FN(d, s) ~0 354 #include "cirrus_vga_rop.h" 355 356 #define ROP_NAME notsrc_and_dst 357 #define ROP_FN(d, s) (~(s)) & (d) 358 #include "cirrus_vga_rop.h" 359 360 #define ROP_NAME src_xor_dst 361 #define ROP_FN(d, s) (s) ^ (d) 362 #include "cirrus_vga_rop.h" 363 364 #define ROP_NAME src_or_dst 365 #define ROP_FN(d, s) (s) | (d) 366 #include "cirrus_vga_rop.h" 367 368 #define ROP_NAME notsrc_or_notdst 369 #define ROP_FN(d, s) (~(s)) | (~(d)) 370 #include "cirrus_vga_rop.h" 371 372 #define ROP_NAME src_notxor_dst 373 #define ROP_FN(d, s) ~((s) ^ (d)) 374 #include "cirrus_vga_rop.h" 375 376 #define ROP_NAME src_or_notdst 377 #define ROP_FN(d, s) (s) | (~(d)) 378 #include "cirrus_vga_rop.h" 379 380 #define ROP_NAME notsrc 381 #define ROP_FN(d, s) (~(s)) 382 #include "cirrus_vga_rop.h" 383 384 #define ROP_NAME notsrc_or_dst 385 #define ROP_FN(d, s) (~(s)) | (d) 386 #include "cirrus_vga_rop.h" 387 388 #define ROP_NAME notsrc_and_notdst 389 #define ROP_FN(d, s) (~(s)) & (~(d)) 390 #include "cirrus_vga_rop.h" 391 392 static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = { 393 cirrus_bitblt_rop_fwd_0, 394 cirrus_bitblt_rop_fwd_src_and_dst, 395 cirrus_bitblt_rop_nop, 396 cirrus_bitblt_rop_fwd_src_and_notdst, 397 cirrus_bitblt_rop_fwd_notdst, 398 cirrus_bitblt_rop_fwd_src, 399 cirrus_bitblt_rop_fwd_1, 400 cirrus_bitblt_rop_fwd_notsrc_and_dst, 401 cirrus_bitblt_rop_fwd_src_xor_dst, 402 cirrus_bitblt_rop_fwd_src_or_dst, 403 cirrus_bitblt_rop_fwd_notsrc_or_notdst, 404 cirrus_bitblt_rop_fwd_src_notxor_dst, 405 cirrus_bitblt_rop_fwd_src_or_notdst, 406 cirrus_bitblt_rop_fwd_notsrc, 407 cirrus_bitblt_rop_fwd_notsrc_or_dst, 408 cirrus_bitblt_rop_fwd_notsrc_and_notdst, 409 }; 410 411 static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = { 412 cirrus_bitblt_rop_bkwd_0, 413 cirrus_bitblt_rop_bkwd_src_and_dst, 414 cirrus_bitblt_rop_nop, 415 cirrus_bitblt_rop_bkwd_src_and_notdst, 416 cirrus_bitblt_rop_bkwd_notdst, 417 cirrus_bitblt_rop_bkwd_src, 418 cirrus_bitblt_rop_bkwd_1, 419 cirrus_bitblt_rop_bkwd_notsrc_and_dst, 420 cirrus_bitblt_rop_bkwd_src_xor_dst, 421 cirrus_bitblt_rop_bkwd_src_or_dst, 422 cirrus_bitblt_rop_bkwd_notsrc_or_notdst, 423 cirrus_bitblt_rop_bkwd_src_notxor_dst, 424 cirrus_bitblt_rop_bkwd_src_or_notdst, 425 cirrus_bitblt_rop_bkwd_notsrc, 426 cirrus_bitblt_rop_bkwd_notsrc_or_dst, 427 cirrus_bitblt_rop_bkwd_notsrc_and_notdst, 428 }; 429 430 #define TRANSP_ROP(name) {\ 431 name ## _8,\ 432 name ## _16,\ 433 } 434 #define TRANSP_NOP(func) {\ 435 func,\ 436 func,\ 437 } 438 439 static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = { 440 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0), 441 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst), 442 TRANSP_NOP(cirrus_bitblt_rop_nop), 443 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst), 444 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst), 445 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src), 446 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1), 447 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst), 448 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst), 449 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst), 450 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst), 451 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst), 452 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst), 453 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc), 454 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst), 455 TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst), 456 }; 457 458 static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = { 459 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0), 460 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst), 461 TRANSP_NOP(cirrus_bitblt_rop_nop), 462 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst), 463 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst), 464 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src), 465 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1), 466 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst), 467 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst), 468 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst), 469 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst), 470 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst), 471 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst), 472 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc), 473 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst), 474 TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst), 475 }; 476 477 #define ROP2(name) {\ 478 name ## _8,\ 479 name ## _16,\ 480 name ## _24,\ 481 name ## _32,\ 482 } 483 484 #define ROP_NOP2(func) {\ 485 func,\ 486 func,\ 487 func,\ 488 func,\ 489 } 490 491 static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = { 492 ROP2(cirrus_patternfill_0), 493 ROP2(cirrus_patternfill_src_and_dst), 494 ROP_NOP2(cirrus_bitblt_rop_nop), 495 ROP2(cirrus_patternfill_src_and_notdst), 496 ROP2(cirrus_patternfill_notdst), 497 ROP2(cirrus_patternfill_src), 498 ROP2(cirrus_patternfill_1), 499 ROP2(cirrus_patternfill_notsrc_and_dst), 500 ROP2(cirrus_patternfill_src_xor_dst), 501 ROP2(cirrus_patternfill_src_or_dst), 502 ROP2(cirrus_patternfill_notsrc_or_notdst), 503 ROP2(cirrus_patternfill_src_notxor_dst), 504 ROP2(cirrus_patternfill_src_or_notdst), 505 ROP2(cirrus_patternfill_notsrc), 506 ROP2(cirrus_patternfill_notsrc_or_dst), 507 ROP2(cirrus_patternfill_notsrc_and_notdst), 508 }; 509 510 static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { 511 ROP2(cirrus_colorexpand_transp_0), 512 ROP2(cirrus_colorexpand_transp_src_and_dst), 513 ROP_NOP2(cirrus_bitblt_rop_nop), 514 ROP2(cirrus_colorexpand_transp_src_and_notdst), 515 ROP2(cirrus_colorexpand_transp_notdst), 516 ROP2(cirrus_colorexpand_transp_src), 517 ROP2(cirrus_colorexpand_transp_1), 518 ROP2(cirrus_colorexpand_transp_notsrc_and_dst), 519 ROP2(cirrus_colorexpand_transp_src_xor_dst), 520 ROP2(cirrus_colorexpand_transp_src_or_dst), 521 ROP2(cirrus_colorexpand_transp_notsrc_or_notdst), 522 ROP2(cirrus_colorexpand_transp_src_notxor_dst), 523 ROP2(cirrus_colorexpand_transp_src_or_notdst), 524 ROP2(cirrus_colorexpand_transp_notsrc), 525 ROP2(cirrus_colorexpand_transp_notsrc_or_dst), 526 ROP2(cirrus_colorexpand_transp_notsrc_and_notdst), 527 }; 528 529 static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { 530 ROP2(cirrus_colorexpand_0), 531 ROP2(cirrus_colorexpand_src_and_dst), 532 ROP_NOP2(cirrus_bitblt_rop_nop), 533 ROP2(cirrus_colorexpand_src_and_notdst), 534 ROP2(cirrus_colorexpand_notdst), 535 ROP2(cirrus_colorexpand_src), 536 ROP2(cirrus_colorexpand_1), 537 ROP2(cirrus_colorexpand_notsrc_and_dst), 538 ROP2(cirrus_colorexpand_src_xor_dst), 539 ROP2(cirrus_colorexpand_src_or_dst), 540 ROP2(cirrus_colorexpand_notsrc_or_notdst), 541 ROP2(cirrus_colorexpand_src_notxor_dst), 542 ROP2(cirrus_colorexpand_src_or_notdst), 543 ROP2(cirrus_colorexpand_notsrc), 544 ROP2(cirrus_colorexpand_notsrc_or_dst), 545 ROP2(cirrus_colorexpand_notsrc_and_notdst), 546 }; 547 548 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = { 549 ROP2(cirrus_colorexpand_pattern_transp_0), 550 ROP2(cirrus_colorexpand_pattern_transp_src_and_dst), 551 ROP_NOP2(cirrus_bitblt_rop_nop), 552 ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst), 553 ROP2(cirrus_colorexpand_pattern_transp_notdst), 554 ROP2(cirrus_colorexpand_pattern_transp_src), 555 ROP2(cirrus_colorexpand_pattern_transp_1), 556 ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst), 557 ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst), 558 ROP2(cirrus_colorexpand_pattern_transp_src_or_dst), 559 ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst), 560 ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst), 561 ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst), 562 ROP2(cirrus_colorexpand_pattern_transp_notsrc), 563 ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst), 564 ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst), 565 }; 566 567 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = { 568 ROP2(cirrus_colorexpand_pattern_0), 569 ROP2(cirrus_colorexpand_pattern_src_and_dst), 570 ROP_NOP2(cirrus_bitblt_rop_nop), 571 ROP2(cirrus_colorexpand_pattern_src_and_notdst), 572 ROP2(cirrus_colorexpand_pattern_notdst), 573 ROP2(cirrus_colorexpand_pattern_src), 574 ROP2(cirrus_colorexpand_pattern_1), 575 ROP2(cirrus_colorexpand_pattern_notsrc_and_dst), 576 ROP2(cirrus_colorexpand_pattern_src_xor_dst), 577 ROP2(cirrus_colorexpand_pattern_src_or_dst), 578 ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst), 579 ROP2(cirrus_colorexpand_pattern_src_notxor_dst), 580 ROP2(cirrus_colorexpand_pattern_src_or_notdst), 581 ROP2(cirrus_colorexpand_pattern_notsrc), 582 ROP2(cirrus_colorexpand_pattern_notsrc_or_dst), 583 ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst), 584 }; 585 586 static const cirrus_fill_t cirrus_fill[16][4] = { 587 ROP2(cirrus_fill_0), 588 ROP2(cirrus_fill_src_and_dst), 589 ROP_NOP2(cirrus_bitblt_fill_nop), 590 ROP2(cirrus_fill_src_and_notdst), 591 ROP2(cirrus_fill_notdst), 592 ROP2(cirrus_fill_src), 593 ROP2(cirrus_fill_1), 594 ROP2(cirrus_fill_notsrc_and_dst), 595 ROP2(cirrus_fill_src_xor_dst), 596 ROP2(cirrus_fill_src_or_dst), 597 ROP2(cirrus_fill_notsrc_or_notdst), 598 ROP2(cirrus_fill_src_notxor_dst), 599 ROP2(cirrus_fill_src_or_notdst), 600 ROP2(cirrus_fill_notsrc), 601 ROP2(cirrus_fill_notsrc_or_dst), 602 ROP2(cirrus_fill_notsrc_and_notdst), 603 }; 604 605 static inline void cirrus_bitblt_fgcol(CirrusVGAState *s) 606 { 607 unsigned int color; 608 switch (s->cirrus_blt_pixelwidth) { 609 case 1: 610 s->cirrus_blt_fgcol = s->cirrus_shadow_gr1; 611 break; 612 case 2: 613 color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8); 614 s->cirrus_blt_fgcol = le16_to_cpu(color); 615 break; 616 case 3: 617 s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 | 618 (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16); 619 break; 620 default: 621 case 4: 622 color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) | 623 (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24); 624 s->cirrus_blt_fgcol = le32_to_cpu(color); 625 break; 626 } 627 } 628 629 static inline void cirrus_bitblt_bgcol(CirrusVGAState *s) 630 { 631 unsigned int color; 632 switch (s->cirrus_blt_pixelwidth) { 633 case 1: 634 s->cirrus_blt_bgcol = s->cirrus_shadow_gr0; 635 break; 636 case 2: 637 color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8); 638 s->cirrus_blt_bgcol = le16_to_cpu(color); 639 break; 640 case 3: 641 s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 | 642 (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16); 643 break; 644 default: 645 case 4: 646 color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) | 647 (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24); 648 s->cirrus_blt_bgcol = le32_to_cpu(color); 649 break; 650 } 651 } 652 653 static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, 654 int off_pitch, int bytesperline, 655 int lines) 656 { 657 int y; 658 int off_cur; 659 int off_cur_end; 660 661 for (y = 0; y < lines; y++) { 662 off_cur = off_begin; 663 off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; 664 memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); 665 off_begin += off_pitch; 666 } 667 } 668 669 static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, 670 const uint8_t * src) 671 { 672 uint8_t *dst; 673 674 dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); 675 676 if (blit_is_unsafe(s)) 677 return 0; 678 679 (*s->cirrus_rop) (s, dst, src, 680 s->cirrus_blt_dstpitch, 0, 681 s->cirrus_blt_width, s->cirrus_blt_height); 682 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 683 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 684 s->cirrus_blt_height); 685 return 1; 686 } 687 688 /* fill */ 689 690 static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) 691 { 692 cirrus_fill_t rop_func; 693 694 if (blit_is_unsafe(s)) { 695 return 0; 696 } 697 rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 698 rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), 699 s->cirrus_blt_dstpitch, 700 s->cirrus_blt_width, s->cirrus_blt_height); 701 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 702 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 703 s->cirrus_blt_height); 704 cirrus_bitblt_reset(s); 705 return 1; 706 } 707 708 /*************************************** 709 * 710 * bitblt (video-to-video) 711 * 712 ***************************************/ 713 714 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) 715 { 716 return cirrus_bitblt_common_patterncopy(s, 717 s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) & 718 s->cirrus_addr_mask)); 719 } 720 721 static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) 722 { 723 int sx = 0, sy = 0; 724 int dx = 0, dy = 0; 725 int depth = 0; 726 int notify = 0; 727 728 /* make sure to only copy if it's a plain copy ROP */ 729 if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src || 730 *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) { 731 732 int width, height; 733 734 depth = s->vga.get_bpp(&s->vga) / 8; 735 if (!depth) { 736 return 0; 737 } 738 s->vga.get_resolution(&s->vga, &width, &height); 739 740 /* extra x, y */ 741 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth; 742 sy = (src / ABS(s->cirrus_blt_srcpitch)); 743 dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth; 744 dy = (dst / ABS(s->cirrus_blt_dstpitch)); 745 746 /* normalize width */ 747 w /= depth; 748 749 /* if we're doing a backward copy, we have to adjust 750 our x/y to be the upper left corner (instead of the lower 751 right corner) */ 752 if (s->cirrus_blt_dstpitch < 0) { 753 sx -= (s->cirrus_blt_width / depth) - 1; 754 dx -= (s->cirrus_blt_width / depth) - 1; 755 sy -= s->cirrus_blt_height - 1; 756 dy -= s->cirrus_blt_height - 1; 757 } 758 759 /* are we in the visible portion of memory? */ 760 if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && 761 (sx + w) <= width && (sy + h) <= height && 762 (dx + w) <= width && (dy + h) <= height) { 763 notify = 1; 764 } 765 } 766 767 /* we have to flush all pending changes so that the copy 768 is generated at the appropriate moment in time */ 769 if (notify) 770 graphic_hw_update(s->vga.con); 771 772 (*s->cirrus_rop) (s, s->vga.vram_ptr + 773 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), 774 s->vga.vram_ptr + 775 (s->cirrus_blt_srcaddr & s->cirrus_addr_mask), 776 s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, 777 s->cirrus_blt_width, s->cirrus_blt_height); 778 779 if (notify) { 780 qemu_console_copy(s->vga.con, 781 sx, sy, dx, dy, 782 s->cirrus_blt_width / depth, 783 s->cirrus_blt_height); 784 } 785 786 /* we don't have to notify the display that this portion has 787 changed since qemu_console_copy implies this */ 788 789 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 790 s->cirrus_blt_dstpitch, s->cirrus_blt_width, 791 s->cirrus_blt_height); 792 793 return 1; 794 } 795 796 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) 797 { 798 if (blit_is_unsafe(s)) 799 return 0; 800 801 return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, 802 s->cirrus_blt_srcaddr - s->vga.start_addr, 803 s->cirrus_blt_width, s->cirrus_blt_height); 804 } 805 806 /*************************************** 807 * 808 * bitblt (cpu-to-video) 809 * 810 ***************************************/ 811 812 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) 813 { 814 int copy_count; 815 uint8_t *end_ptr; 816 817 if (s->cirrus_srccounter > 0) { 818 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 819 cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf); 820 the_end: 821 s->cirrus_srccounter = 0; 822 cirrus_bitblt_reset(s); 823 } else { 824 /* at least one scan line */ 825 do { 826 (*s->cirrus_rop)(s, s->vga.vram_ptr + 827 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), 828 s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); 829 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, 830 s->cirrus_blt_width, 1); 831 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch; 832 s->cirrus_srccounter -= s->cirrus_blt_srcpitch; 833 if (s->cirrus_srccounter <= 0) 834 goto the_end; 835 /* more bytes than needed can be transferred because of 836 word alignment, so we keep them for the next line */ 837 /* XXX: keep alignment to speed up transfer */ 838 end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; 839 copy_count = s->cirrus_srcptr_end - end_ptr; 840 memmove(s->cirrus_bltbuf, end_ptr, copy_count); 841 s->cirrus_srcptr = s->cirrus_bltbuf + copy_count; 842 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; 843 } while (s->cirrus_srcptr >= s->cirrus_srcptr_end); 844 } 845 } 846 } 847 848 /*************************************** 849 * 850 * bitblt wrapper 851 * 852 ***************************************/ 853 854 static void cirrus_bitblt_reset(CirrusVGAState * s) 855 { 856 int need_update; 857 858 s->vga.gr[0x31] &= 859 ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED); 860 need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0] 861 || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0]; 862 s->cirrus_srcptr = &s->cirrus_bltbuf[0]; 863 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; 864 s->cirrus_srccounter = 0; 865 if (!need_update) 866 return; 867 cirrus_update_memory_access(s); 868 } 869 870 static int cirrus_bitblt_cputovideo(CirrusVGAState * s) 871 { 872 int w; 873 874 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC; 875 s->cirrus_srcptr = &s->cirrus_bltbuf[0]; 876 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; 877 878 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 879 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 880 s->cirrus_blt_srcpitch = 8; 881 } else { 882 /* XXX: check for 24 bpp */ 883 s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; 884 } 885 s->cirrus_srccounter = s->cirrus_blt_srcpitch; 886 } else { 887 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 888 w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth; 889 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) 890 s->cirrus_blt_srcpitch = ((w + 31) >> 5); 891 else 892 s->cirrus_blt_srcpitch = ((w + 7) >> 3); 893 } else { 894 /* always align input size to 32 bits */ 895 s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3; 896 } 897 s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height; 898 } 899 s->cirrus_srcptr = s->cirrus_bltbuf; 900 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; 901 cirrus_update_memory_access(s); 902 return 1; 903 } 904 905 static int cirrus_bitblt_videotocpu(CirrusVGAState * s) 906 { 907 /* XXX */ 908 #ifdef DEBUG_BITBLT 909 printf("cirrus: bitblt (video to cpu) is not implemented yet\n"); 910 #endif 911 return 0; 912 } 913 914 static int cirrus_bitblt_videotovideo(CirrusVGAState * s) 915 { 916 int ret; 917 918 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 919 ret = cirrus_bitblt_videotovideo_patterncopy(s); 920 } else { 921 ret = cirrus_bitblt_videotovideo_copy(s); 922 } 923 if (ret) 924 cirrus_bitblt_reset(s); 925 return ret; 926 } 927 928 static void cirrus_bitblt_start(CirrusVGAState * s) 929 { 930 uint8_t blt_rop; 931 932 s->vga.gr[0x31] |= CIRRUS_BLT_BUSY; 933 934 s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1; 935 s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1; 936 s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8)); 937 s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8)); 938 s->cirrus_blt_dstaddr = 939 (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16)); 940 s->cirrus_blt_srcaddr = 941 (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16)); 942 s->cirrus_blt_mode = s->vga.gr[0x30]; 943 s->cirrus_blt_modeext = s->vga.gr[0x33]; 944 blt_rop = s->vga.gr[0x32]; 945 946 #ifdef DEBUG_BITBLT 947 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", 948 blt_rop, 949 s->cirrus_blt_mode, 950 s->cirrus_blt_modeext, 951 s->cirrus_blt_width, 952 s->cirrus_blt_height, 953 s->cirrus_blt_dstpitch, 954 s->cirrus_blt_srcpitch, 955 s->cirrus_blt_dstaddr, 956 s->cirrus_blt_srcaddr, 957 s->vga.gr[0x2f]); 958 #endif 959 960 switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { 961 case CIRRUS_BLTMODE_PIXELWIDTH8: 962 s->cirrus_blt_pixelwidth = 1; 963 break; 964 case CIRRUS_BLTMODE_PIXELWIDTH16: 965 s->cirrus_blt_pixelwidth = 2; 966 break; 967 case CIRRUS_BLTMODE_PIXELWIDTH24: 968 s->cirrus_blt_pixelwidth = 3; 969 break; 970 case CIRRUS_BLTMODE_PIXELWIDTH32: 971 s->cirrus_blt_pixelwidth = 4; 972 break; 973 default: 974 #ifdef DEBUG_BITBLT 975 printf("cirrus: bitblt - pixel width is unknown\n"); 976 #endif 977 goto bitblt_ignore; 978 } 979 s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK; 980 981 if ((s-> 982 cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC | 983 CIRRUS_BLTMODE_MEMSYSDEST)) 984 == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) { 985 #ifdef DEBUG_BITBLT 986 printf("cirrus: bitblt - memory-to-memory copy is requested\n"); 987 #endif 988 goto bitblt_ignore; 989 } 990 991 if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) && 992 (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST | 993 CIRRUS_BLTMODE_TRANSPARENTCOMP | 994 CIRRUS_BLTMODE_PATTERNCOPY | 995 CIRRUS_BLTMODE_COLOREXPAND)) == 996 (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) { 997 cirrus_bitblt_fgcol(s); 998 cirrus_bitblt_solidfill(s, blt_rop); 999 } else { 1000 if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND | 1001 CIRRUS_BLTMODE_PATTERNCOPY)) == 1002 CIRRUS_BLTMODE_COLOREXPAND) { 1003 1004 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { 1005 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) 1006 cirrus_bitblt_bgcol(s); 1007 else 1008 cirrus_bitblt_fgcol(s); 1009 s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1010 } else { 1011 cirrus_bitblt_fgcol(s); 1012 cirrus_bitblt_bgcol(s); 1013 s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1014 } 1015 } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 1016 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { 1017 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { 1018 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) 1019 cirrus_bitblt_bgcol(s); 1020 else 1021 cirrus_bitblt_fgcol(s); 1022 s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1023 } else { 1024 cirrus_bitblt_fgcol(s); 1025 cirrus_bitblt_bgcol(s); 1026 s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1027 } 1028 } else { 1029 s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1030 } 1031 } else { 1032 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { 1033 if (s->cirrus_blt_pixelwidth > 2) { 1034 printf("src transparent without colorexpand must be 8bpp or 16bpp\n"); 1035 goto bitblt_ignore; 1036 } 1037 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { 1038 s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; 1039 s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; 1040 s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1041 } else { 1042 s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; 1043 } 1044 } else { 1045 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { 1046 s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; 1047 s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; 1048 s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; 1049 } else { 1050 s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; 1051 } 1052 } 1053 } 1054 // setup bitblt engine. 1055 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) { 1056 if (!cirrus_bitblt_cputovideo(s)) 1057 goto bitblt_ignore; 1058 } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) { 1059 if (!cirrus_bitblt_videotocpu(s)) 1060 goto bitblt_ignore; 1061 } else { 1062 if (!cirrus_bitblt_videotovideo(s)) 1063 goto bitblt_ignore; 1064 } 1065 } 1066 return; 1067 bitblt_ignore:; 1068 cirrus_bitblt_reset(s); 1069 } 1070 1071 static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value) 1072 { 1073 unsigned old_value; 1074 1075 old_value = s->vga.gr[0x31]; 1076 s->vga.gr[0x31] = reg_value; 1077 1078 if (((old_value & CIRRUS_BLT_RESET) != 0) && 1079 ((reg_value & CIRRUS_BLT_RESET) == 0)) { 1080 cirrus_bitblt_reset(s); 1081 } else if (((old_value & CIRRUS_BLT_START) == 0) && 1082 ((reg_value & CIRRUS_BLT_START) != 0)) { 1083 cirrus_bitblt_start(s); 1084 } 1085 } 1086 1087 1088 /*************************************** 1089 * 1090 * basic parameters 1091 * 1092 ***************************************/ 1093 1094 static void cirrus_get_offsets(VGACommonState *s1, 1095 uint32_t *pline_offset, 1096 uint32_t *pstart_addr, 1097 uint32_t *pline_compare) 1098 { 1099 CirrusVGAState * s = container_of(s1, CirrusVGAState, vga); 1100 uint32_t start_addr, line_offset, line_compare; 1101 1102 line_offset = s->vga.cr[0x13] 1103 | ((s->vga.cr[0x1b] & 0x10) << 4); 1104 line_offset <<= 3; 1105 *pline_offset = line_offset; 1106 1107 start_addr = (s->vga.cr[0x0c] << 8) 1108 | s->vga.cr[0x0d] 1109 | ((s->vga.cr[0x1b] & 0x01) << 16) 1110 | ((s->vga.cr[0x1b] & 0x0c) << 15) 1111 | ((s->vga.cr[0x1d] & 0x80) << 12); 1112 *pstart_addr = start_addr; 1113 1114 line_compare = s->vga.cr[0x18] | 1115 ((s->vga.cr[0x07] & 0x10) << 4) | 1116 ((s->vga.cr[0x09] & 0x40) << 3); 1117 *pline_compare = line_compare; 1118 } 1119 1120 static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s) 1121 { 1122 uint32_t ret = 16; 1123 1124 switch (s->cirrus_hidden_dac_data & 0xf) { 1125 case 0: 1126 ret = 15; 1127 break; /* Sierra HiColor */ 1128 case 1: 1129 ret = 16; 1130 break; /* XGA HiColor */ 1131 default: 1132 #ifdef DEBUG_CIRRUS 1133 printf("cirrus: invalid DAC value %x in 16bpp\n", 1134 (s->cirrus_hidden_dac_data & 0xf)); 1135 #endif 1136 ret = 15; /* XXX */ 1137 break; 1138 } 1139 return ret; 1140 } 1141 1142 static int cirrus_get_bpp(VGACommonState *s1) 1143 { 1144 CirrusVGAState * s = container_of(s1, CirrusVGAState, vga); 1145 uint32_t ret = 8; 1146 1147 if ((s->vga.sr[0x07] & 0x01) != 0) { 1148 /* Cirrus SVGA */ 1149 switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) { 1150 case CIRRUS_SR7_BPP_8: 1151 ret = 8; 1152 break; 1153 case CIRRUS_SR7_BPP_16_DOUBLEVCLK: 1154 ret = cirrus_get_bpp16_depth(s); 1155 break; 1156 case CIRRUS_SR7_BPP_24: 1157 ret = 24; 1158 break; 1159 case CIRRUS_SR7_BPP_16: 1160 ret = cirrus_get_bpp16_depth(s); 1161 break; 1162 case CIRRUS_SR7_BPP_32: 1163 ret = 32; 1164 break; 1165 default: 1166 #ifdef DEBUG_CIRRUS 1167 printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]); 1168 #endif 1169 ret = 8; 1170 break; 1171 } 1172 } else { 1173 /* VGA */ 1174 ret = 0; 1175 } 1176 1177 return ret; 1178 } 1179 1180 static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight) 1181 { 1182 int width, height; 1183 1184 width = (s->cr[0x01] + 1) * 8; 1185 height = s->cr[0x12] | 1186 ((s->cr[0x07] & 0x02) << 7) | 1187 ((s->cr[0x07] & 0x40) << 3); 1188 height = (height + 1); 1189 /* interlace support */ 1190 if (s->cr[0x1a] & 0x01) 1191 height = height * 2; 1192 *pwidth = width; 1193 *pheight = height; 1194 } 1195 1196 /*************************************** 1197 * 1198 * bank memory 1199 * 1200 ***************************************/ 1201 1202 static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) 1203 { 1204 unsigned offset; 1205 unsigned limit; 1206 1207 if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */ 1208 offset = s->vga.gr[0x09 + bank_index]; 1209 else /* single bank */ 1210 offset = s->vga.gr[0x09]; 1211 1212 if ((s->vga.gr[0x0b] & 0x20) != 0) 1213 offset <<= 14; 1214 else 1215 offset <<= 12; 1216 1217 if (s->real_vram_size <= offset) 1218 limit = 0; 1219 else 1220 limit = s->real_vram_size - offset; 1221 1222 if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) { 1223 if (limit > 0x8000) { 1224 offset += 0x8000; 1225 limit -= 0x8000; 1226 } else { 1227 limit = 0; 1228 } 1229 } 1230 1231 if (limit > 0) { 1232 s->cirrus_bank_base[bank_index] = offset; 1233 s->cirrus_bank_limit[bank_index] = limit; 1234 } else { 1235 s->cirrus_bank_base[bank_index] = 0; 1236 s->cirrus_bank_limit[bank_index] = 0; 1237 } 1238 } 1239 1240 /*************************************** 1241 * 1242 * I/O access between 0x3c4-0x3c5 1243 * 1244 ***************************************/ 1245 1246 static int cirrus_vga_read_sr(CirrusVGAState * s) 1247 { 1248 switch (s->vga.sr_index) { 1249 case 0x00: // Standard VGA 1250 case 0x01: // Standard VGA 1251 case 0x02: // Standard VGA 1252 case 0x03: // Standard VGA 1253 case 0x04: // Standard VGA 1254 return s->vga.sr[s->vga.sr_index]; 1255 case 0x06: // Unlock Cirrus extensions 1256 return s->vga.sr[s->vga.sr_index]; 1257 case 0x10: 1258 case 0x30: 1259 case 0x50: 1260 case 0x70: // Graphics Cursor X 1261 case 0x90: 1262 case 0xb0: 1263 case 0xd0: 1264 case 0xf0: // Graphics Cursor X 1265 return s->vga.sr[0x10]; 1266 case 0x11: 1267 case 0x31: 1268 case 0x51: 1269 case 0x71: // Graphics Cursor Y 1270 case 0x91: 1271 case 0xb1: 1272 case 0xd1: 1273 case 0xf1: // Graphics Cursor Y 1274 return s->vga.sr[0x11]; 1275 case 0x05: // ??? 1276 case 0x07: // Extended Sequencer Mode 1277 case 0x08: // EEPROM Control 1278 case 0x09: // Scratch Register 0 1279 case 0x0a: // Scratch Register 1 1280 case 0x0b: // VCLK 0 1281 case 0x0c: // VCLK 1 1282 case 0x0d: // VCLK 2 1283 case 0x0e: // VCLK 3 1284 case 0x0f: // DRAM Control 1285 case 0x12: // Graphics Cursor Attribute 1286 case 0x13: // Graphics Cursor Pattern Address 1287 case 0x14: // Scratch Register 2 1288 case 0x15: // Scratch Register 3 1289 case 0x16: // Performance Tuning Register 1290 case 0x17: // Configuration Readback and Extended Control 1291 case 0x18: // Signature Generator Control 1292 case 0x19: // Signal Generator Result 1293 case 0x1a: // Signal Generator Result 1294 case 0x1b: // VCLK 0 Denominator & Post 1295 case 0x1c: // VCLK 1 Denominator & Post 1296 case 0x1d: // VCLK 2 Denominator & Post 1297 case 0x1e: // VCLK 3 Denominator & Post 1298 case 0x1f: // BIOS Write Enable and MCLK select 1299 #ifdef DEBUG_CIRRUS 1300 printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index); 1301 #endif 1302 return s->vga.sr[s->vga.sr_index]; 1303 default: 1304 #ifdef DEBUG_CIRRUS 1305 printf("cirrus: inport sr_index %02x\n", s->vga.sr_index); 1306 #endif 1307 return 0xff; 1308 break; 1309 } 1310 } 1311 1312 static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val) 1313 { 1314 switch (s->vga.sr_index) { 1315 case 0x00: // Standard VGA 1316 case 0x01: // Standard VGA 1317 case 0x02: // Standard VGA 1318 case 0x03: // Standard VGA 1319 case 0x04: // Standard VGA 1320 s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index]; 1321 if (s->vga.sr_index == 1) 1322 s->vga.update_retrace_info(&s->vga); 1323 break; 1324 case 0x06: // Unlock Cirrus extensions 1325 val &= 0x17; 1326 if (val == 0x12) { 1327 s->vga.sr[s->vga.sr_index] = 0x12; 1328 } else { 1329 s->vga.sr[s->vga.sr_index] = 0x0f; 1330 } 1331 break; 1332 case 0x10: 1333 case 0x30: 1334 case 0x50: 1335 case 0x70: // Graphics Cursor X 1336 case 0x90: 1337 case 0xb0: 1338 case 0xd0: 1339 case 0xf0: // Graphics Cursor X 1340 s->vga.sr[0x10] = val; 1341 s->vga.hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5); 1342 break; 1343 case 0x11: 1344 case 0x31: 1345 case 0x51: 1346 case 0x71: // Graphics Cursor Y 1347 case 0x91: 1348 case 0xb1: 1349 case 0xd1: 1350 case 0xf1: // Graphics Cursor Y 1351 s->vga.sr[0x11] = val; 1352 s->vga.hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5); 1353 break; 1354 case 0x07: // Extended Sequencer Mode 1355 cirrus_update_memory_access(s); 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 return (uint8_t) value; 1839 } 1840 1841 static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, 1842 uint8_t value) 1843 { 1844 switch (address) { 1845 case (CIRRUS_MMIO_BLTBGCOLOR + 0): 1846 cirrus_vga_write_gr(s, 0x00, value); 1847 break; 1848 case (CIRRUS_MMIO_BLTBGCOLOR + 1): 1849 cirrus_vga_write_gr(s, 0x10, value); 1850 break; 1851 case (CIRRUS_MMIO_BLTBGCOLOR + 2): 1852 cirrus_vga_write_gr(s, 0x12, value); 1853 break; 1854 case (CIRRUS_MMIO_BLTBGCOLOR + 3): 1855 cirrus_vga_write_gr(s, 0x14, value); 1856 break; 1857 case (CIRRUS_MMIO_BLTFGCOLOR + 0): 1858 cirrus_vga_write_gr(s, 0x01, value); 1859 break; 1860 case (CIRRUS_MMIO_BLTFGCOLOR + 1): 1861 cirrus_vga_write_gr(s, 0x11, value); 1862 break; 1863 case (CIRRUS_MMIO_BLTFGCOLOR + 2): 1864 cirrus_vga_write_gr(s, 0x13, value); 1865 break; 1866 case (CIRRUS_MMIO_BLTFGCOLOR + 3): 1867 cirrus_vga_write_gr(s, 0x15, value); 1868 break; 1869 case (CIRRUS_MMIO_BLTWIDTH + 0): 1870 cirrus_vga_write_gr(s, 0x20, value); 1871 break; 1872 case (CIRRUS_MMIO_BLTWIDTH + 1): 1873 cirrus_vga_write_gr(s, 0x21, value); 1874 break; 1875 case (CIRRUS_MMIO_BLTHEIGHT + 0): 1876 cirrus_vga_write_gr(s, 0x22, value); 1877 break; 1878 case (CIRRUS_MMIO_BLTHEIGHT + 1): 1879 cirrus_vga_write_gr(s, 0x23, value); 1880 break; 1881 case (CIRRUS_MMIO_BLTDESTPITCH + 0): 1882 cirrus_vga_write_gr(s, 0x24, value); 1883 break; 1884 case (CIRRUS_MMIO_BLTDESTPITCH + 1): 1885 cirrus_vga_write_gr(s, 0x25, value); 1886 break; 1887 case (CIRRUS_MMIO_BLTSRCPITCH + 0): 1888 cirrus_vga_write_gr(s, 0x26, value); 1889 break; 1890 case (CIRRUS_MMIO_BLTSRCPITCH + 1): 1891 cirrus_vga_write_gr(s, 0x27, value); 1892 break; 1893 case (CIRRUS_MMIO_BLTDESTADDR + 0): 1894 cirrus_vga_write_gr(s, 0x28, value); 1895 break; 1896 case (CIRRUS_MMIO_BLTDESTADDR + 1): 1897 cirrus_vga_write_gr(s, 0x29, value); 1898 break; 1899 case (CIRRUS_MMIO_BLTDESTADDR + 2): 1900 cirrus_vga_write_gr(s, 0x2a, value); 1901 break; 1902 case (CIRRUS_MMIO_BLTDESTADDR + 3): 1903 /* ignored */ 1904 break; 1905 case (CIRRUS_MMIO_BLTSRCADDR + 0): 1906 cirrus_vga_write_gr(s, 0x2c, value); 1907 break; 1908 case (CIRRUS_MMIO_BLTSRCADDR + 1): 1909 cirrus_vga_write_gr(s, 0x2d, value); 1910 break; 1911 case (CIRRUS_MMIO_BLTSRCADDR + 2): 1912 cirrus_vga_write_gr(s, 0x2e, value); 1913 break; 1914 case CIRRUS_MMIO_BLTWRITEMASK: 1915 cirrus_vga_write_gr(s, 0x2f, value); 1916 break; 1917 case CIRRUS_MMIO_BLTMODE: 1918 cirrus_vga_write_gr(s, 0x30, value); 1919 break; 1920 case CIRRUS_MMIO_BLTROP: 1921 cirrus_vga_write_gr(s, 0x32, value); 1922 break; 1923 case CIRRUS_MMIO_BLTMODEEXT: 1924 cirrus_vga_write_gr(s, 0x33, value); 1925 break; 1926 case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): 1927 cirrus_vga_write_gr(s, 0x34, value); 1928 break; 1929 case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): 1930 cirrus_vga_write_gr(s, 0x35, value); 1931 break; 1932 case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): 1933 cirrus_vga_write_gr(s, 0x38, value); 1934 break; 1935 case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): 1936 cirrus_vga_write_gr(s, 0x39, value); 1937 break; 1938 case CIRRUS_MMIO_BLTSTATUS: 1939 cirrus_vga_write_gr(s, 0x31, value); 1940 break; 1941 default: 1942 #ifdef DEBUG_CIRRUS 1943 printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n", 1944 address, value); 1945 #endif 1946 break; 1947 } 1948 } 1949 1950 /*************************************** 1951 * 1952 * write mode 4/5 1953 * 1954 ***************************************/ 1955 1956 static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, 1957 unsigned mode, 1958 unsigned offset, 1959 uint32_t mem_value) 1960 { 1961 int x; 1962 unsigned val = mem_value; 1963 uint8_t *dst; 1964 1965 dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask); 1966 for (x = 0; x < 8; x++) { 1967 if (val & 0x80) { 1968 *dst = s->cirrus_shadow_gr1; 1969 } else if (mode == 5) { 1970 *dst = s->cirrus_shadow_gr0; 1971 } 1972 val <<= 1; 1973 dst++; 1974 } 1975 memory_region_set_dirty(&s->vga.vram, offset, 8); 1976 } 1977 1978 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, 1979 unsigned mode, 1980 unsigned offset, 1981 uint32_t mem_value) 1982 { 1983 int x; 1984 unsigned val = mem_value; 1985 uint8_t *dst; 1986 1987 dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask); 1988 for (x = 0; x < 8; x++) { 1989 if (val & 0x80) { 1990 *dst = s->cirrus_shadow_gr1; 1991 *(dst + 1) = s->vga.gr[0x11]; 1992 } else if (mode == 5) { 1993 *dst = s->cirrus_shadow_gr0; 1994 *(dst + 1) = s->vga.gr[0x10]; 1995 } 1996 val <<= 1; 1997 dst += 2; 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 * 1024; 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 * 1024; 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 #if defined(DEBUG_VGA) 2594 printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val); 2595 #endif 2596 return val; 2597 } 2598 2599 static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val, 2600 unsigned size) 2601 { 2602 CirrusVGAState *c = opaque; 2603 VGACommonState *s = &c->vga; 2604 int index; 2605 2606 addr += 0x3b0; 2607 2608 /* check port range access depending on color/monochrome mode */ 2609 if (vga_ioport_invalid(s, addr)) { 2610 return; 2611 } 2612 #ifdef DEBUG_VGA 2613 printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val); 2614 #endif 2615 2616 switch (addr) { 2617 case 0x3c0: 2618 if (s->ar_flip_flop == 0) { 2619 val &= 0x3f; 2620 s->ar_index = val; 2621 } else { 2622 index = s->ar_index & 0x1f; 2623 switch (index) { 2624 case 0x00 ... 0x0f: 2625 s->ar[index] = val & 0x3f; 2626 break; 2627 case 0x10: 2628 s->ar[index] = val & ~0x10; 2629 break; 2630 case 0x11: 2631 s->ar[index] = val; 2632 break; 2633 case 0x12: 2634 s->ar[index] = val & ~0xc0; 2635 break; 2636 case 0x13: 2637 s->ar[index] = val & ~0xf0; 2638 break; 2639 case 0x14: 2640 s->ar[index] = val & ~0xf0; 2641 break; 2642 default: 2643 break; 2644 } 2645 } 2646 s->ar_flip_flop ^= 1; 2647 break; 2648 case 0x3c2: 2649 s->msr = val & ~0x10; 2650 s->update_retrace_info(s); 2651 break; 2652 case 0x3c4: 2653 s->sr_index = val; 2654 break; 2655 case 0x3c5: 2656 #ifdef DEBUG_VGA_REG 2657 printf("vga: write SR%x = 0x%02" PRIu64 "\n", s->sr_index, val); 2658 #endif 2659 cirrus_vga_write_sr(c, val); 2660 break; 2661 case 0x3c6: 2662 cirrus_write_hidden_dac(c, val); 2663 break; 2664 case 0x3c7: 2665 s->dac_read_index = val; 2666 s->dac_sub_index = 0; 2667 s->dac_state = 3; 2668 break; 2669 case 0x3c8: 2670 s->dac_write_index = val; 2671 s->dac_sub_index = 0; 2672 s->dac_state = 0; 2673 break; 2674 case 0x3c9: 2675 cirrus_vga_write_palette(c, val); 2676 break; 2677 case 0x3ce: 2678 s->gr_index = val; 2679 break; 2680 case 0x3cf: 2681 #ifdef DEBUG_VGA_REG 2682 printf("vga: write GR%x = 0x%02" PRIu64 "\n", s->gr_index, val); 2683 #endif 2684 cirrus_vga_write_gr(c, s->gr_index, val); 2685 break; 2686 case 0x3b4: 2687 case 0x3d4: 2688 s->cr_index = val; 2689 break; 2690 case 0x3b5: 2691 case 0x3d5: 2692 #ifdef DEBUG_VGA_REG 2693 printf("vga: write CR%x = 0x%02"PRIu64"\n", s->cr_index, val); 2694 #endif 2695 cirrus_vga_write_cr(c, val); 2696 break; 2697 case 0x3ba: 2698 case 0x3da: 2699 s->fcr = val & 0x10; 2700 break; 2701 } 2702 } 2703 2704 /*************************************** 2705 * 2706 * memory-mapped I/O access 2707 * 2708 ***************************************/ 2709 2710 static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr, 2711 unsigned size) 2712 { 2713 CirrusVGAState *s = opaque; 2714 2715 if (addr >= 0x100) { 2716 return cirrus_mmio_blt_read(s, addr - 0x100); 2717 } else { 2718 return cirrus_vga_ioport_read(s, addr + 0x10, size); 2719 } 2720 } 2721 2722 static void cirrus_mmio_write(void *opaque, hwaddr addr, 2723 uint64_t val, unsigned size) 2724 { 2725 CirrusVGAState *s = opaque; 2726 2727 if (addr >= 0x100) { 2728 cirrus_mmio_blt_write(s, addr - 0x100, val); 2729 } else { 2730 cirrus_vga_ioport_write(s, addr + 0x10, val, size); 2731 } 2732 } 2733 2734 static const MemoryRegionOps cirrus_mmio_io_ops = { 2735 .read = cirrus_mmio_read, 2736 .write = cirrus_mmio_write, 2737 .endianness = DEVICE_LITTLE_ENDIAN, 2738 .impl = { 2739 .min_access_size = 1, 2740 .max_access_size = 1, 2741 }, 2742 }; 2743 2744 /* load/save state */ 2745 2746 static int cirrus_post_load(void *opaque, int version_id) 2747 { 2748 CirrusVGAState *s = opaque; 2749 2750 s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f; 2751 s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f; 2752 2753 cirrus_update_memory_access(s); 2754 /* force refresh */ 2755 s->vga.graphic_mode = -1; 2756 cirrus_update_bank_ptr(s, 0); 2757 cirrus_update_bank_ptr(s, 1); 2758 return 0; 2759 } 2760 2761 static const VMStateDescription vmstate_cirrus_vga = { 2762 .name = "cirrus_vga", 2763 .version_id = 2, 2764 .minimum_version_id = 1, 2765 .post_load = cirrus_post_load, 2766 .fields = (VMStateField[]) { 2767 VMSTATE_UINT32(vga.latch, CirrusVGAState), 2768 VMSTATE_UINT8(vga.sr_index, CirrusVGAState), 2769 VMSTATE_BUFFER(vga.sr, CirrusVGAState), 2770 VMSTATE_UINT8(vga.gr_index, CirrusVGAState), 2771 VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState), 2772 VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState), 2773 VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2), 2774 VMSTATE_UINT8(vga.ar_index, CirrusVGAState), 2775 VMSTATE_BUFFER(vga.ar, CirrusVGAState), 2776 VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState), 2777 VMSTATE_UINT8(vga.cr_index, CirrusVGAState), 2778 VMSTATE_BUFFER(vga.cr, CirrusVGAState), 2779 VMSTATE_UINT8(vga.msr, CirrusVGAState), 2780 VMSTATE_UINT8(vga.fcr, CirrusVGAState), 2781 VMSTATE_UINT8(vga.st00, CirrusVGAState), 2782 VMSTATE_UINT8(vga.st01, CirrusVGAState), 2783 VMSTATE_UINT8(vga.dac_state, CirrusVGAState), 2784 VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState), 2785 VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState), 2786 VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState), 2787 VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState), 2788 VMSTATE_BUFFER(vga.palette, CirrusVGAState), 2789 VMSTATE_INT32(vga.bank_offset, CirrusVGAState), 2790 VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState), 2791 VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState), 2792 VMSTATE_UINT32(vga.hw_cursor_x, CirrusVGAState), 2793 VMSTATE_UINT32(vga.hw_cursor_y, CirrusVGAState), 2794 /* XXX: we do not save the bitblt state - we assume we do not save 2795 the state when the blitter is active */ 2796 VMSTATE_END_OF_LIST() 2797 } 2798 }; 2799 2800 static const VMStateDescription vmstate_pci_cirrus_vga = { 2801 .name = "cirrus_vga", 2802 .version_id = 2, 2803 .minimum_version_id = 2, 2804 .fields = (VMStateField[]) { 2805 VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState), 2806 VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0, 2807 vmstate_cirrus_vga, CirrusVGAState), 2808 VMSTATE_END_OF_LIST() 2809 } 2810 }; 2811 2812 /*************************************** 2813 * 2814 * initialize 2815 * 2816 ***************************************/ 2817 2818 static void cirrus_reset(void *opaque) 2819 { 2820 CirrusVGAState *s = opaque; 2821 2822 vga_common_reset(&s->vga); 2823 unmap_linear_vram(s); 2824 s->vga.sr[0x06] = 0x0f; 2825 if (s->device_id == CIRRUS_ID_CLGD5446) { 2826 /* 4MB 64 bit memory config, always PCI */ 2827 s->vga.sr[0x1F] = 0x2d; // MemClock 2828 s->vga.gr[0x18] = 0x0f; // fastest memory configuration 2829 s->vga.sr[0x0f] = 0x98; 2830 s->vga.sr[0x17] = 0x20; 2831 s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */ 2832 } else { 2833 s->vga.sr[0x1F] = 0x22; // MemClock 2834 s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M; 2835 s->vga.sr[0x17] = s->bustype; 2836 s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */ 2837 } 2838 s->vga.cr[0x27] = s->device_id; 2839 2840 s->cirrus_hidden_dac_lockindex = 5; 2841 s->cirrus_hidden_dac_data = 0; 2842 } 2843 2844 static const MemoryRegionOps cirrus_linear_io_ops = { 2845 .read = cirrus_linear_read, 2846 .write = cirrus_linear_write, 2847 .endianness = DEVICE_LITTLE_ENDIAN, 2848 .impl = { 2849 .min_access_size = 1, 2850 .max_access_size = 1, 2851 }, 2852 }; 2853 2854 static const MemoryRegionOps cirrus_vga_io_ops = { 2855 .read = cirrus_vga_ioport_read, 2856 .write = cirrus_vga_ioport_write, 2857 .endianness = DEVICE_LITTLE_ENDIAN, 2858 .impl = { 2859 .min_access_size = 1, 2860 .max_access_size = 1, 2861 }, 2862 }; 2863 2864 static void cirrus_init_common(CirrusVGAState *s, Object *owner, 2865 int device_id, int is_pci, 2866 MemoryRegion *system_memory, 2867 MemoryRegion *system_io) 2868 { 2869 int i; 2870 static int inited; 2871 2872 if (!inited) { 2873 inited = 1; 2874 for(i = 0;i < 256; i++) 2875 rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */ 2876 rop_to_index[CIRRUS_ROP_0] = 0; 2877 rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1; 2878 rop_to_index[CIRRUS_ROP_NOP] = 2; 2879 rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3; 2880 rop_to_index[CIRRUS_ROP_NOTDST] = 4; 2881 rop_to_index[CIRRUS_ROP_SRC] = 5; 2882 rop_to_index[CIRRUS_ROP_1] = 6; 2883 rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7; 2884 rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8; 2885 rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9; 2886 rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10; 2887 rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11; 2888 rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12; 2889 rop_to_index[CIRRUS_ROP_NOTSRC] = 13; 2890 rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14; 2891 rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15; 2892 s->device_id = device_id; 2893 if (is_pci) 2894 s->bustype = CIRRUS_BUSTYPE_PCI; 2895 else 2896 s->bustype = CIRRUS_BUSTYPE_ISA; 2897 } 2898 2899 /* Register ioport 0x3b0 - 0x3df */ 2900 memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s, 2901 "cirrus-io", 0x30); 2902 memory_region_set_flush_coalesced(&s->cirrus_vga_io); 2903 memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io); 2904 2905 memory_region_init(&s->low_mem_container, owner, 2906 "cirrus-lowmem-container", 2907 0x20000); 2908 2909 memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s, 2910 "cirrus-low-memory", 0x20000); 2911 memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem); 2912 for (i = 0; i < 2; ++i) { 2913 static const char *names[] = { "vga.bank0", "vga.bank1" }; 2914 MemoryRegion *bank = &s->cirrus_bank[i]; 2915 memory_region_init_alias(bank, owner, names[i], &s->vga.vram, 2916 0, 0x8000); 2917 memory_region_set_enabled(bank, false); 2918 memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000, 2919 bank, 1); 2920 } 2921 memory_region_add_subregion_overlap(system_memory, 2922 0x000a0000, 2923 &s->low_mem_container, 2924 1); 2925 memory_region_set_coalescing(&s->low_mem); 2926 2927 /* I/O handler for LFB */ 2928 memory_region_init_io(&s->cirrus_linear_io, owner, &cirrus_linear_io_ops, s, 2929 "cirrus-linear-io", s->vga.vram_size_mb 2930 * 1024 * 1024); 2931 memory_region_set_flush_coalesced(&s->cirrus_linear_io); 2932 2933 /* I/O handler for LFB */ 2934 memory_region_init_io(&s->cirrus_linear_bitblt_io, owner, 2935 &cirrus_linear_bitblt_io_ops, 2936 s, 2937 "cirrus-bitblt-mmio", 2938 0x400000); 2939 memory_region_set_flush_coalesced(&s->cirrus_linear_bitblt_io); 2940 2941 /* I/O handler for memory-mapped I/O */ 2942 memory_region_init_io(&s->cirrus_mmio_io, owner, &cirrus_mmio_io_ops, s, 2943 "cirrus-mmio", CIRRUS_PNPMMIO_SIZE); 2944 memory_region_set_flush_coalesced(&s->cirrus_mmio_io); 2945 2946 s->real_vram_size = 2947 (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024; 2948 2949 /* XXX: s->vga.vram_size must be a power of two */ 2950 s->cirrus_addr_mask = s->real_vram_size - 1; 2951 s->linear_mmio_mask = s->real_vram_size - 256; 2952 2953 s->vga.get_bpp = cirrus_get_bpp; 2954 s->vga.get_offsets = cirrus_get_offsets; 2955 s->vga.get_resolution = cirrus_get_resolution; 2956 s->vga.cursor_invalidate = cirrus_cursor_invalidate; 2957 s->vga.cursor_draw_line = cirrus_cursor_draw_line; 2958 2959 qemu_register_reset(cirrus_reset, s); 2960 } 2961 2962 /*************************************** 2963 * 2964 * ISA bus support 2965 * 2966 ***************************************/ 2967 2968 static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) 2969 { 2970 ISADevice *isadev = ISA_DEVICE(dev); 2971 ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev); 2972 VGACommonState *s = &d->cirrus_vga.vga; 2973 2974 /* follow real hardware, cirrus card emulated has 4 MB video memory. 2975 Also accept 8 MB/16 MB for backward compatibility. */ 2976 if (s->vram_size_mb != 4 && s->vram_size_mb != 8 && 2977 s->vram_size_mb != 16) { 2978 error_setg(errp, "Invalid cirrus_vga ram size '%u'", 2979 s->vram_size_mb); 2980 return; 2981 } 2982 vga_common_init(s, OBJECT(dev), true); 2983 cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, 2984 isa_address_space(isadev), 2985 isa_address_space_io(isadev)); 2986 s->con = graphic_console_init(dev, 0, s->hw_ops, s); 2987 rom_add_vga(VGABIOS_CIRRUS_FILENAME); 2988 /* XXX ISA-LFB support */ 2989 /* FIXME not qdev yet */ 2990 } 2991 2992 static Property isa_cirrus_vga_properties[] = { 2993 DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, 2994 cirrus_vga.vga.vram_size_mb, 8), 2995 DEFINE_PROP_END_OF_LIST(), 2996 }; 2997 2998 static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data) 2999 { 3000 DeviceClass *dc = DEVICE_CLASS(klass); 3001 3002 dc->vmsd = &vmstate_cirrus_vga; 3003 dc->realize = isa_cirrus_vga_realizefn; 3004 dc->props = isa_cirrus_vga_properties; 3005 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); 3006 } 3007 3008 static const TypeInfo isa_cirrus_vga_info = { 3009 .name = TYPE_ISA_CIRRUS_VGA, 3010 .parent = TYPE_ISA_DEVICE, 3011 .instance_size = sizeof(ISACirrusVGAState), 3012 .class_init = isa_cirrus_vga_class_init, 3013 }; 3014 3015 /*************************************** 3016 * 3017 * PCI bus support 3018 * 3019 ***************************************/ 3020 3021 static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp) 3022 { 3023 PCICirrusVGAState *d = PCI_CIRRUS_VGA(dev); 3024 CirrusVGAState *s = &d->cirrus_vga; 3025 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); 3026 int16_t device_id = pc->device_id; 3027 3028 /* follow real hardware, cirrus card emulated has 4 MB video memory. 3029 Also accept 8 MB/16 MB for backward compatibility. */ 3030 if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 && 3031 s->vga.vram_size_mb != 16) { 3032 error_setg(errp, "Invalid cirrus_vga ram size '%u'", 3033 s->vga.vram_size_mb); 3034 return; 3035 } 3036 /* setup VGA */ 3037 vga_common_init(&s->vga, OBJECT(dev), true); 3038 cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev), 3039 pci_address_space_io(dev)); 3040 s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga); 3041 3042 /* setup PCI */ 3043 3044 memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000); 3045 3046 /* XXX: add byte swapping apertures */ 3047 memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io); 3048 memory_region_add_subregion(&s->pci_bar, 0x1000000, 3049 &s->cirrus_linear_bitblt_io); 3050 3051 /* setup memory space */ 3052 /* memory #0 LFB */ 3053 /* memory #1 memory-mapped I/O */ 3054 /* XXX: s->vga.vram_size must be a power of two */ 3055 pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar); 3056 if (device_id == CIRRUS_ID_CLGD5446) { 3057 pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io); 3058 } 3059 } 3060 3061 static Property pci_vga_cirrus_properties[] = { 3062 DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState, 3063 cirrus_vga.vga.vram_size_mb, 8), 3064 DEFINE_PROP_END_OF_LIST(), 3065 }; 3066 3067 static void cirrus_vga_class_init(ObjectClass *klass, void *data) 3068 { 3069 DeviceClass *dc = DEVICE_CLASS(klass); 3070 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 3071 3072 k->realize = pci_cirrus_vga_realize; 3073 k->romfile = VGABIOS_CIRRUS_FILENAME; 3074 k->vendor_id = PCI_VENDOR_ID_CIRRUS; 3075 k->device_id = CIRRUS_ID_CLGD5446; 3076 k->class_id = PCI_CLASS_DISPLAY_VGA; 3077 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); 3078 dc->desc = "Cirrus CLGD 54xx VGA"; 3079 dc->vmsd = &vmstate_pci_cirrus_vga; 3080 dc->props = pci_vga_cirrus_properties; 3081 dc->hotpluggable = false; 3082 } 3083 3084 static const TypeInfo cirrus_vga_info = { 3085 .name = TYPE_PCI_CIRRUS_VGA, 3086 .parent = TYPE_PCI_DEVICE, 3087 .instance_size = sizeof(PCICirrusVGAState), 3088 .class_init = cirrus_vga_class_init, 3089 }; 3090 3091 static void cirrus_vga_register_types(void) 3092 { 3093 type_register_static(&isa_cirrus_vga_info); 3094 type_register_static(&cirrus_vga_info); 3095 } 3096 3097 type_init(cirrus_vga_register_types) 3098