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