aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/cirrus_vga.c31
-rw-r--r--hw/cirrus_vga_rop2.h48
2 files changed, 68 insertions, 11 deletions
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index f0b22e77c1..55a866a2e4 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -136,6 +136,7 @@
// control 0x33
#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
+#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
// memory-mapped IO
@@ -325,7 +326,7 @@ static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
#include "cirrus_vga_rop.h"
#define ROP_NAME 1
-#define ROP_OP(d, s) d = 0xff
+#define ROP_OP(d, s) d = ~0
#include "cirrus_vga_rop.h"
#define ROP_NAME notsrc_and_dst
@@ -435,6 +436,25 @@ static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
};
+static const cirrus_bitblt_rop_t cirrus_colorexpand_transp_inv[16][4] = {
+ ROP2(cirrus_colorexpand_transp_inv_0),
+ ROP2(cirrus_colorexpand_transp_inv_src_and_dst),
+ ROP_NOP2(cirrus_bitblt_rop_nop),
+ ROP2(cirrus_colorexpand_transp_inv_src_and_notdst),
+ ROP2(cirrus_colorexpand_transp_inv_notdst),
+ ROP2(cirrus_colorexpand_transp_inv_src),
+ ROP2(cirrus_colorexpand_transp_inv_1),
+ ROP2(cirrus_colorexpand_transp_inv_notsrc_and_dst),
+ ROP2(cirrus_colorexpand_transp_inv_src_xor_dst),
+ ROP2(cirrus_colorexpand_transp_inv_src_or_dst),
+ ROP2(cirrus_colorexpand_transp_inv_notsrc_or_notdst),
+ ROP2(cirrus_colorexpand_transp_inv_src_notxor_dst),
+ ROP2(cirrus_colorexpand_transp_inv_src_or_notdst),
+ ROP2(cirrus_colorexpand_transp_inv_notsrc),
+ ROP2(cirrus_colorexpand_transp_inv_notsrc_or_dst),
+ ROP2(cirrus_colorexpand_transp_inv_notsrc_and_notdst),
+};
+
static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
ROP2(cirrus_colorexpand_0),
ROP2(cirrus_colorexpand_src_and_dst),
@@ -820,8 +840,13 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
CIRRUS_BLTMODE_COLOREXPAND) {
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+ if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+ cirrus_bitblt_bgcol(s);
+ s->cirrus_rop = cirrus_colorexpand_transp_inv[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+ } else {
+ cirrus_bitblt_fgcol(s);
+ s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+ }
} else {
cirrus_bitblt_fgcol(s);
cirrus_bitblt_bgcol(s);
diff --git a/hw/cirrus_vga_rop2.h b/hw/cirrus_vga_rop2.h
index 682662741e..c7514d3161 100644
--- a/hw/cirrus_vga_rop2.h
+++ b/hw/cirrus_vga_rop2.h
@@ -36,14 +36,14 @@
#error unsupported DEPTH
#endif
+/* NOTE: srcpitch is ignored */
static void
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src1,
+ const uint8_t * src,
int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
- const uint8_t *src;
uint8_t *d;
int x, y;
unsigned bits;
@@ -54,7 +54,6 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
col = s->cirrus_blt_fgcol;
for(y = 0; y < bltheight; y++) {
- src = src1;
bitmask = 0x80 >> srcskipleft;
bits = *src++;
d = dst;
@@ -70,7 +69,43 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
d += (DEPTH / 8);
bitmask >>= 1;
}
- src1 += srcpitch;
+ dst += dstpitch;
+ }
+}
+
+/* NOTE: srcpitch is ignored */
+static void
+glue(glue(glue(cirrus_colorexpand_transp_inv_, ROP_NAME), _),DEPTH)
+ (CirrusVGAState * s, uint8_t * dst,
+ const uint8_t * src,
+ int dstpitch, int srcpitch,
+ int bltwidth, int bltheight)
+{
+ uint8_t *d;
+ int x, y;
+ unsigned bits;
+ unsigned int col;
+ unsigned bitmask;
+ unsigned index;
+ int srcskipleft = 0;
+
+ col = s->cirrus_blt_bgcol;
+ for(y = 0; y < bltheight; y++) {
+ bitmask = 0x80 >> srcskipleft;
+ bits = *src++;
+ d = dst;
+ for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
+ if ((bitmask & 0xff) == 0) {
+ bitmask = 0x80;
+ bits = *src++;
+ }
+ index = (bits & bitmask);
+ if (!index) {
+ PUTPIXEL();
+ }
+ d += (DEPTH / 8);
+ bitmask >>= 1;
+ }
dst += dstpitch;
}
}
@@ -78,11 +113,10 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
static void
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
(CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src1,
+ const uint8_t * src,
int dstpitch, int srcpitch,
int bltwidth, int bltheight)
{
- const uint8_t *src;
uint32_t colors[2];
uint8_t *d;
int x, y;
@@ -94,7 +128,6 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
colors[0] = s->cirrus_blt_bgcol;
colors[1] = s->cirrus_blt_fgcol;
for(y = 0; y < bltheight; y++) {
- src = src1;
bitmask = 0x80 >> srcskipleft;
bits = *src++;
d = dst;
@@ -108,7 +141,6 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
d += (DEPTH / 8);
bitmask >>= 1;
}
- src1 += srcpitch;
dst += dstpitch;
}
}