Commit b30d4608dae994cf57cab4824f3307de026fd373
1 parent
81ca7991
24 bpp fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@984 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
129 additions
and
69 deletions
hw/cirrus_vga.c
| ... | ... | @@ -456,25 +456,6 @@ static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = { |
| 456 | 456 | ROP2(cirrus_colorexpand_transp_notsrc_and_notdst), |
| 457 | 457 | }; |
| 458 | 458 | |
| 459 | -static const cirrus_bitblt_rop_t cirrus_colorexpand_transp_inv[16][4] = { | |
| 460 | - ROP2(cirrus_colorexpand_transp_inv_0), | |
| 461 | - ROP2(cirrus_colorexpand_transp_inv_src_and_dst), | |
| 462 | - ROP_NOP2(cirrus_bitblt_rop_nop), | |
| 463 | - ROP2(cirrus_colorexpand_transp_inv_src_and_notdst), | |
| 464 | - ROP2(cirrus_colorexpand_transp_inv_notdst), | |
| 465 | - ROP2(cirrus_colorexpand_transp_inv_src), | |
| 466 | - ROP2(cirrus_colorexpand_transp_inv_1), | |
| 467 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_and_dst), | |
| 468 | - ROP2(cirrus_colorexpand_transp_inv_src_xor_dst), | |
| 469 | - ROP2(cirrus_colorexpand_transp_inv_src_or_dst), | |
| 470 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_or_notdst), | |
| 471 | - ROP2(cirrus_colorexpand_transp_inv_src_notxor_dst), | |
| 472 | - ROP2(cirrus_colorexpand_transp_inv_src_or_notdst), | |
| 473 | - ROP2(cirrus_colorexpand_transp_inv_notsrc), | |
| 474 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_or_dst), | |
| 475 | - ROP2(cirrus_colorexpand_transp_inv_notsrc_and_notdst), | |
| 476 | -}; | |
| 477 | - | |
| 478 | 459 | static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { |
| 479 | 460 | ROP2(cirrus_colorexpand_0), |
| 480 | 461 | ROP2(cirrus_colorexpand_src_and_dst), |
| ... | ... | @@ -494,6 +475,44 @@ static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = { |
| 494 | 475 | ROP2(cirrus_colorexpand_notsrc_and_notdst), |
| 495 | 476 | }; |
| 496 | 477 | |
| 478 | +static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = { | |
| 479 | + ROP2(cirrus_colorexpand_pattern_transp_0), | |
| 480 | + ROP2(cirrus_colorexpand_pattern_transp_src_and_dst), | |
| 481 | + ROP_NOP2(cirrus_bitblt_rop_nop), | |
| 482 | + ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst), | |
| 483 | + ROP2(cirrus_colorexpand_pattern_transp_notdst), | |
| 484 | + ROP2(cirrus_colorexpand_pattern_transp_src), | |
| 485 | + ROP2(cirrus_colorexpand_pattern_transp_1), | |
| 486 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst), | |
| 487 | + ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst), | |
| 488 | + ROP2(cirrus_colorexpand_pattern_transp_src_or_dst), | |
| 489 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst), | |
| 490 | + ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst), | |
| 491 | + ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst), | |
| 492 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc), | |
| 493 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst), | |
| 494 | + ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst), | |
| 495 | +}; | |
| 496 | + | |
| 497 | +static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = { | |
| 498 | + ROP2(cirrus_colorexpand_pattern_0), | |
| 499 | + ROP2(cirrus_colorexpand_pattern_src_and_dst), | |
| 500 | + ROP_NOP2(cirrus_bitblt_rop_nop), | |
| 501 | + ROP2(cirrus_colorexpand_pattern_src_and_notdst), | |
| 502 | + ROP2(cirrus_colorexpand_pattern_notdst), | |
| 503 | + ROP2(cirrus_colorexpand_pattern_src), | |
| 504 | + ROP2(cirrus_colorexpand_pattern_1), | |
| 505 | + ROP2(cirrus_colorexpand_pattern_notsrc_and_dst), | |
| 506 | + ROP2(cirrus_colorexpand_pattern_src_xor_dst), | |
| 507 | + ROP2(cirrus_colorexpand_pattern_src_or_dst), | |
| 508 | + ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst), | |
| 509 | + ROP2(cirrus_colorexpand_pattern_src_notxor_dst), | |
| 510 | + ROP2(cirrus_colorexpand_pattern_src_or_notdst), | |
| 511 | + ROP2(cirrus_colorexpand_pattern_notsrc), | |
| 512 | + ROP2(cirrus_colorexpand_pattern_notsrc_or_dst), | |
| 513 | + ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst), | |
| 514 | +}; | |
| 515 | + | |
| 497 | 516 | static const cirrus_fill_t cirrus_fill[16][4] = { |
| 498 | 517 | ROP2(cirrus_fill_0), |
| 499 | 518 | ROP2(cirrus_fill_src_and_dst), |
| ... | ... | @@ -584,27 +603,8 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, |
| 584 | 603 | static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, |
| 585 | 604 | const uint8_t * src) |
| 586 | 605 | { |
| 587 | - uint8_t work_colorexp[256]; | |
| 588 | 606 | uint8_t *dst; |
| 589 | - int patternbytes = s->cirrus_blt_pixelwidth * 8; | |
| 590 | 607 | |
| 591 | - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { | |
| 592 | - cirrus_bitblt_rop_t rop_func; | |
| 593 | - cirrus_bitblt_fgcol(s); | |
| 594 | - cirrus_bitblt_bgcol(s); | |
| 595 | - rop_func = cirrus_colorexpand[CIRRUS_ROP_SRC_INDEX][s->cirrus_blt_pixelwidth - 1]; | |
| 596 | - rop_func(s, work_colorexp, src, patternbytes, 1, patternbytes, 8); | |
| 597 | - src = work_colorexp; | |
| 598 | - s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_COLOREXPAND; | |
| 599 | - } | |
| 600 | - if (s->cirrus_blt_mode & ~CIRRUS_BLTMODE_PATTERNCOPY) { | |
| 601 | -#ifdef DEBUG_BITBLT | |
| 602 | - printf("cirrus: blt mode %02x (pattercopy) - unimplemented\n", | |
| 603 | - s->cirrus_blt_mode); | |
| 604 | -#endif | |
| 605 | - return 0; | |
| 606 | - } | |
| 607 | - | |
| 608 | 608 | dst = s->vram_ptr + s->cirrus_blt_dstaddr; |
| 609 | 609 | (*s->cirrus_rop) (s, dst, src, |
| 610 | 610 | s->cirrus_blt_dstpitch, 0, |
| ... | ... | @@ -728,6 +728,7 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) |
| 728 | 728 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { |
| 729 | 729 | s->cirrus_blt_srcpitch = 8; |
| 730 | 730 | } else { |
| 731 | + /* XXX: check for 24 bpp */ | |
| 731 | 732 | s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; |
| 732 | 733 | } |
| 733 | 734 | s->cirrus_srccounter = s->cirrus_blt_srcpitch; |
| ... | ... | @@ -848,20 +849,32 @@ static void cirrus_bitblt_start(CirrusVGAState * s) |
| 848 | 849 | CIRRUS_BLTMODE_COLOREXPAND) { |
| 849 | 850 | |
| 850 | 851 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { |
| 851 | - if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
| 852 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) | |
| 852 | 853 | cirrus_bitblt_bgcol(s); |
| 853 | - s->cirrus_rop = cirrus_colorexpand_transp_inv[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 854 | - } else { | |
| 854 | + else | |
| 855 | 855 | cirrus_bitblt_fgcol(s); |
| 856 | - s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 857 | - } | |
| 856 | + s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 858 | 857 | } else { |
| 859 | 858 | cirrus_bitblt_fgcol(s); |
| 860 | 859 | cirrus_bitblt_bgcol(s); |
| 861 | 860 | s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; |
| 862 | 861 | } |
| 863 | 862 | } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { |
| 864 | - s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 863 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { | |
| 864 | + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { | |
| 865 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) | |
| 866 | + cirrus_bitblt_bgcol(s); | |
| 867 | + else | |
| 868 | + cirrus_bitblt_fgcol(s); | |
| 869 | + s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 870 | + } else { | |
| 871 | + cirrus_bitblt_fgcol(s); | |
| 872 | + cirrus_bitblt_bgcol(s); | |
| 873 | + s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 874 | + } | |
| 875 | + } else { | |
| 876 | + s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; | |
| 877 | + } | |
| 865 | 878 | } else { |
| 866 | 879 | if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { |
| 867 | 880 | s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; |
| ... | ... | @@ -2793,9 +2806,10 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) |
| 2793 | 2806 | vga_io_memory); |
| 2794 | 2807 | |
| 2795 | 2808 | s->sr[0x06] = 0x0f; |
| 2796 | - s->sr[0x1F] = 0x22; // MemClock | |
| 2797 | 2809 | if (device_id == CIRRUS_ID_CLGD5446) { |
| 2798 | 2810 | /* 4MB 64 bit memory config, always PCI */ |
| 2811 | + s->sr[0x1F] = 0x2d; // MemClock | |
| 2812 | + s->gr[0x18] = 0x0f; // fastest memory configuration | |
| 2799 | 2813 | #if 1 |
| 2800 | 2814 | s->sr[0x0f] = 0x98; |
| 2801 | 2815 | s->sr[0x17] = 0x20; |
| ... | ... | @@ -2808,6 +2822,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) |
| 2808 | 2822 | s->real_vram_size = 2048 * 1024; |
| 2809 | 2823 | #endif |
| 2810 | 2824 | } else { |
| 2825 | + s->sr[0x1F] = 0x22; // MemClock | |
| 2811 | 2826 | s->sr[0x0F] = CIRRUS_MEMSIZE_2M; |
| 2812 | 2827 | if (is_pci) |
| 2813 | 2828 | s->sr[0x17] = CIRRUS_BUSTYPE_PCI; | ... | ... |
hw/cirrus_vga_rop2.h
| ... | ... | @@ -67,6 +67,12 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) |
| 67 | 67 | #elif DEPTH == 16 |
| 68 | 68 | col = ((uint16_t *)(src1 + pattern_x))[0]; |
| 69 | 69 | pattern_x = (pattern_x + 2) & 15; |
| 70 | +#elif DEPTH == 24 | |
| 71 | + { | |
| 72 | + const uint8_t *src2 = src1 + pattern_x * 3; | |
| 73 | + col = src2[0] | (src2[1] << 8) | (src2[2] << 16); | |
| 74 | + pattern_x = (pattern_x + 1) & 7; | |
| 75 | + } | |
| 70 | 76 | #else |
| 71 | 77 | col = ((uint32_t *)(src1 + pattern_x))[0]; |
| 72 | 78 | pattern_x = (pattern_x + 4) & 31; |
| ... | ... | @@ -89,21 +95,28 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) |
| 89 | 95 | { |
| 90 | 96 | uint8_t *d; |
| 91 | 97 | int x, y; |
| 92 | - unsigned bits; | |
| 98 | + unsigned bits, bits_xor; | |
| 93 | 99 | unsigned int col; |
| 94 | 100 | unsigned bitmask; |
| 95 | 101 | unsigned index; |
| 96 | 102 | int srcskipleft = 0; |
| 97 | 103 | |
| 98 | - col = s->cirrus_blt_fgcol; | |
| 104 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
| 105 | + bits_xor = 0xff; | |
| 106 | + col = s->cirrus_blt_bgcol; | |
| 107 | + } else { | |
| 108 | + bits_xor = 0x00; | |
| 109 | + col = s->cirrus_blt_fgcol; | |
| 110 | + } | |
| 111 | + | |
| 99 | 112 | for(y = 0; y < bltheight; y++) { |
| 100 | 113 | bitmask = 0x80 >> srcskipleft; |
| 101 | - bits = *src++; | |
| 114 | + bits = *src++ ^ bits_xor; | |
| 102 | 115 | d = dst; |
| 103 | 116 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { |
| 104 | 117 | if ((bitmask & 0xff) == 0) { |
| 105 | 118 | bitmask = 0x80; |
| 106 | - bits = *src++; | |
| 119 | + bits = *src++ ^ bits_xor; | |
| 107 | 120 | } |
| 108 | 121 | index = (bits & bitmask); |
| 109 | 122 | if (index) { |
| ... | ... | @@ -116,23 +129,23 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) |
| 116 | 129 | } |
| 117 | 130 | } |
| 118 | 131 | |
| 119 | -/* NOTE: srcpitch is ignored */ | |
| 120 | 132 | static void |
| 121 | -glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH) | |
| 133 | +glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) | |
| 122 | 134 | (CirrusVGAState * s, uint8_t * dst, |
| 123 | 135 | const uint8_t * src, |
| 124 | 136 | int dstpitch, int srcpitch, |
| 125 | 137 | int bltwidth, int bltheight) |
| 126 | 138 | { |
| 139 | + uint32_t colors[2]; | |
| 127 | 140 | uint8_t *d; |
| 128 | 141 | int x, y; |
| 129 | 142 | unsigned bits; |
| 130 | 143 | unsigned int col; |
| 131 | 144 | unsigned bitmask; |
| 132 | - unsigned index; | |
| 133 | 145 | int srcskipleft = 0; |
| 134 | 146 | |
| 135 | - col = s->cirrus_blt_bgcol; | |
| 147 | + colors[0] = s->cirrus_blt_bgcol; | |
| 148 | + colors[1] = s->cirrus_blt_fgcol; | |
| 136 | 149 | for(y = 0; y < bltheight; y++) { |
| 137 | 150 | bitmask = 0x80 >> srcskipleft; |
| 138 | 151 | bits = *src++; |
| ... | ... | @@ -142,19 +155,54 @@ glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH) |
| 142 | 155 | bitmask = 0x80; |
| 143 | 156 | bits = *src++; |
| 144 | 157 | } |
| 145 | - index = (bits & bitmask); | |
| 146 | - if (!index) { | |
| 158 | + col = colors[!!(bits & bitmask)]; | |
| 159 | + PUTPIXEL(); | |
| 160 | + d += (DEPTH / 8); | |
| 161 | + bitmask >>= 1; | |
| 162 | + } | |
| 163 | + dst += dstpitch; | |
| 164 | + } | |
| 165 | +} | |
| 166 | + | |
| 167 | +static void | |
| 168 | +glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) | |
| 169 | + (CirrusVGAState * s, uint8_t * dst, | |
| 170 | + const uint8_t * src, | |
| 171 | + int dstpitch, int srcpitch, | |
| 172 | + int bltwidth, int bltheight) | |
| 173 | +{ | |
| 174 | + uint8_t *d; | |
| 175 | + int x, y, bitpos, pattern_y; | |
| 176 | + unsigned int bits, bits_xor; | |
| 177 | + unsigned int col; | |
| 178 | + | |
| 179 | + if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { | |
| 180 | + bits_xor = 0xff; | |
| 181 | + col = s->cirrus_blt_bgcol; | |
| 182 | + } else { | |
| 183 | + bits_xor = 0x00; | |
| 184 | + col = s->cirrus_blt_fgcol; | |
| 185 | + } | |
| 186 | + pattern_y = s->cirrus_blt_srcaddr & 7; | |
| 187 | + | |
| 188 | + for(y = 0; y < bltheight; y++) { | |
| 189 | + bits = src[pattern_y] ^ bits_xor; | |
| 190 | + bitpos = 7; | |
| 191 | + d = dst; | |
| 192 | + for (x = 0; x < bltwidth; x += (DEPTH / 8)) { | |
| 193 | + if ((bits >> bitpos) & 1) { | |
| 147 | 194 | PUTPIXEL(); |
| 148 | 195 | } |
| 149 | 196 | d += (DEPTH / 8); |
| 150 | - bitmask >>= 1; | |
| 197 | + bitpos = (bitpos - 1) & 7; | |
| 151 | 198 | } |
| 199 | + pattern_y = (pattern_y + 1) & 7; | |
| 152 | 200 | dst += dstpitch; |
| 153 | 201 | } |
| 154 | 202 | } |
| 155 | 203 | |
| 156 | 204 | static void |
| 157 | -glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) | |
| 205 | +glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) | |
| 158 | 206 | (CirrusVGAState * s, uint8_t * dst, |
| 159 | 207 | const uint8_t * src, |
| 160 | 208 | int dstpitch, int srcpitch, |
| ... | ... | @@ -162,28 +210,25 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) |
| 162 | 210 | { |
| 163 | 211 | uint32_t colors[2]; |
| 164 | 212 | uint8_t *d; |
| 165 | - int x, y; | |
| 166 | - unsigned bits; | |
| 213 | + int x, y, bitpos, pattern_y; | |
| 214 | + unsigned int bits; | |
| 167 | 215 | unsigned int col; |
| 168 | - unsigned bitmask; | |
| 169 | - int srcskipleft = 0; | |
| 170 | 216 | |
| 171 | 217 | colors[0] = s->cirrus_blt_bgcol; |
| 172 | 218 | colors[1] = s->cirrus_blt_fgcol; |
| 219 | + pattern_y = s->cirrus_blt_srcaddr & 7; | |
| 220 | + | |
| 173 | 221 | for(y = 0; y < bltheight; y++) { |
| 174 | - bitmask = 0x80 >> srcskipleft; | |
| 175 | - bits = *src++; | |
| 222 | + bits = src[pattern_y]; | |
| 223 | + bitpos = 7; | |
| 176 | 224 | d = dst; |
| 177 | 225 | for (x = 0; x < bltwidth; x += (DEPTH / 8)) { |
| 178 | - if ((bitmask & 0xff) == 0) { | |
| 179 | - bitmask = 0x80; | |
| 180 | - bits = *src++; | |
| 181 | - } | |
| 182 | - col = colors[!!(bits & bitmask)]; | |
| 226 | + col = colors[(bits >> bitpos) & 1]; | |
| 183 | 227 | PUTPIXEL(); |
| 184 | 228 | d += (DEPTH / 8); |
| 185 | - bitmask >>= 1; | |
| 229 | + bitpos = (bitpos - 1) & 7; | |
| 186 | 230 | } |
| 231 | + pattern_y = (pattern_y + 1) & 7; | |
| 187 | 232 | dst += dstpitch; |
| 188 | 233 | } |
| 189 | 234 | } | ... | ... |