mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
Properly validate blit bounds, if it is out of VRAM bounds, reduce height to prevent crashes.
This commit is contained in:
parent
fb41b9c8f1
commit
9c1757f479
@ -173,19 +173,49 @@
|
||||
|
||||
#define CIRRUS_PNPMMIO_SIZE 0x1000
|
||||
|
||||
#define BLTUNSAFE(s) \
|
||||
( \
|
||||
( /* check dst is within bounds */ \
|
||||
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \
|
||||
+ ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
|
||||
(s)->vga.vram_size \
|
||||
) || \
|
||||
( /* check src is within bounds */ \
|
||||
(s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \
|
||||
+ ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
|
||||
(s)->vga.vram_size \
|
||||
) \
|
||||
)
|
||||
// If blit is out of bounds, reduce height.
|
||||
static void check_blit(int32_t addr, uint32_t mask, int pitch, int width, int *height, int depth, int dir)
|
||||
{
|
||||
int h = *height;
|
||||
int32_t off;
|
||||
if (!h || !width)
|
||||
return;
|
||||
addr &= mask;
|
||||
off = addr + pitch * (h - 1);
|
||||
if (dir > 0) {
|
||||
off += width * (depth / 8);
|
||||
} else {
|
||||
off -= width * (depth / 8);
|
||||
}
|
||||
if (off > mask + 1) {
|
||||
h -= (off - (mask + 1) + pitch - 1) / pitch;
|
||||
} else if (off < 0) {
|
||||
h -= ((-off) + pitch - 1) / pitch;
|
||||
}
|
||||
if (h < 0)
|
||||
h = 0;
|
||||
*height = h;
|
||||
}
|
||||
|
||||
#define INITBLIT \
|
||||
dst += (dstaddr & dstmask); \
|
||||
src += (srcaddr & srcmask);
|
||||
|
||||
#define INITBLIT_DST \
|
||||
dst += (dstaddr & dstmask);
|
||||
|
||||
#define BLTCHECK_DST(skip) \
|
||||
check_blit(dstaddr, dstmask, dstpitch, bltwidth - skip, &bltheight, DEPTH, 1);
|
||||
|
||||
#define BLTCHECK_FWD \
|
||||
check_blit(dstaddr, dstmask, dstpitch, bltwidth, &bltheight, 8, 1); \
|
||||
check_blit(srcaddr, srcmask, srcpitch, bltwidth, &bltheight, 8, 1); \
|
||||
INITBLIT;
|
||||
|
||||
#define BLTCHECK_BKWD \
|
||||
check_blit(dstaddr, dstmask, dstpitch, bltwidth, &bltheight, 8, -1); \
|
||||
check_blit(srcaddr, srcmask, srcpitch, bltwidth, &bltheight, 8, -1); \
|
||||
INITBLIT;
|
||||
|
||||
#if 0
|
||||
typedef struct PCICirrusVGAState {
|
||||
@ -223,15 +253,16 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
|
||||
***************************************/
|
||||
|
||||
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
}
|
||||
|
||||
static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
|
||||
uint8_t *dst,
|
||||
int dstpitch, int bltwidth,int bltheight)
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
int dstpitch, int bltwidth,int bltheight)
|
||||
{
|
||||
}
|
||||
|
||||
@ -578,16 +609,11 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
|
||||
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
|
||||
const uint8_t * src)
|
||||
{
|
||||
uint8_t *dst;
|
||||
|
||||
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
|
||||
|
||||
// if (BLTUNSAFE(s))
|
||||
// return 0;
|
||||
|
||||
(*s->cirrus_rop) (s, dst, src,
|
||||
s->cirrus_blt_dstpitch, 0,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
(*s->cirrus_rop) (s,
|
||||
s->vga.vram_ptr, s->cirrus_blt_dstaddr, s->cirrus_addr_mask,
|
||||
src, 0, s->cirrus_addr_mask,
|
||||
s->cirrus_blt_dstpitch, 0,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
||||
s->cirrus_blt_dstpitch, s->cirrus_blt_width,
|
||||
s->cirrus_blt_height);
|
||||
@ -600,10 +626,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
|
||||
{
|
||||
cirrus_fill_t rop_func;
|
||||
|
||||
// if (BLTUNSAFE(s))
|
||||
// return 0;
|
||||
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
|
||||
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
rop_func(s, s->vga.vram_ptr, s->cirrus_blt_dstaddr, s->cirrus_addr_mask,
|
||||
s->cirrus_blt_dstpitch,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
||||
@ -677,12 +701,11 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
if (notify)
|
||||
graphic_hw_update(s->vga.con);
|
||||
|
||||
(*s->cirrus_rop) (s, s->vga.vram_ptr +
|
||||
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
s->vga.vram_ptr +
|
||||
(s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
|
||||
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
(*s->cirrus_rop) (s,
|
||||
s->vga.vram_ptr, s->cirrus_blt_dstaddr, s->cirrus_addr_mask,
|
||||
s->vga.vram_ptr, s->cirrus_blt_srcaddr, s->cirrus_addr_mask,
|
||||
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
|
||||
if (notify) {
|
||||
qemu_console_copy(s->vga.con,
|
||||
@ -701,9 +724,6 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
|
||||
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
|
||||
{
|
||||
// if (BLTUNSAFE(s))
|
||||
// return 0;
|
||||
|
||||
cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
|
||||
s->cirrus_blt_srcaddr - s->vga.start_addr,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
@ -731,9 +751,10 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
|
||||
} else {
|
||||
/* at least one scan line */
|
||||
do {
|
||||
(*s->cirrus_rop)(s, s->vga.vram_ptr +
|
||||
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
|
||||
(*s->cirrus_rop)(s,
|
||||
s->vga.vram_ptr, s->cirrus_blt_dstaddr, s->cirrus_addr_mask,
|
||||
s->cirrus_bltbuf, 0, 0,
|
||||
0, 0, s->cirrus_blt_width, 1);
|
||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
|
||||
s->cirrus_blt_width, 1);
|
||||
s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
|
||||
|
||||
@ -44,22 +44,18 @@ STATIC_INLINE void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
|
||||
|
||||
static void
|
||||
glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
int x,y;
|
||||
|
||||
BLTCHECK_FWD
|
||||
|
||||
dstpitch -= bltwidth;
|
||||
srcpitch -= bltwidth;
|
||||
|
||||
#if 0
|
||||
/* Invalid test! TW */
|
||||
if (dstpitch < 0 || srcpitch < 0) {
|
||||
/* is 0 valid? srcpitch == 0 could be useful */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < (bltwidth & ~3); x += 4) {
|
||||
ROP_OP_32((uint32_t*)dst, *((uint32_t*)src));
|
||||
@ -78,14 +74,19 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
|
||||
|
||||
static void
|
||||
glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
int dstpitch,int srcpitch,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
int x,y;
|
||||
dstpitch += bltwidth;
|
||||
BLTCHECK_BKWD
|
||||
|
||||
int x,y;
|
||||
|
||||
dstpitch += bltwidth;
|
||||
srcpitch += bltwidth;
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < (bltwidth & ~3); x += 4) {
|
||||
dst -= 3;
|
||||
src -= 3;
|
||||
@ -105,15 +106,20 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
|
||||
|
||||
static void
|
||||
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
int x,y;
|
||||
BLTCHECK_FWD
|
||||
|
||||
int x,y;
|
||||
uint8_t p;
|
||||
dstpitch -= bltwidth;
|
||||
|
||||
dstpitch -= bltwidth;
|
||||
srcpitch -= bltwidth;
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < bltwidth; x++) {
|
||||
p = *dst;
|
||||
ROP_OP(&p, *src);
|
||||
@ -128,15 +134,20 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||
|
||||
static void
|
||||
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
int x,y;
|
||||
BLTCHECK_BKWD
|
||||
|
||||
int x,y;
|
||||
uint8_t p;
|
||||
dstpitch += bltwidth;
|
||||
|
||||
dstpitch += bltwidth;
|
||||
srcpitch += bltwidth;
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < bltwidth; x++) {
|
||||
p = *dst;
|
||||
ROP_OP(&p, *src);
|
||||
@ -151,15 +162,20 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||
|
||||
static void
|
||||
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
int x,y;
|
||||
BLTCHECK_FWD
|
||||
|
||||
int x,y;
|
||||
uint8_t p1, p2;
|
||||
dstpitch -= bltwidth;
|
||||
|
||||
dstpitch -= bltwidth;
|
||||
srcpitch -= bltwidth;
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < bltwidth; x+=2) {
|
||||
p1 = *dst;
|
||||
p2 = *(dst+1);
|
||||
@ -179,15 +195,20 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
||||
|
||||
static void
|
||||
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
||||
uint8_t *dst,const uint8_t *src,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch,int srcpitch,
|
||||
int bltwidth,int bltheight)
|
||||
{
|
||||
int x,y;
|
||||
BLTCHECK_BKWD
|
||||
|
||||
int x,y;
|
||||
uint8_t p1, p2;
|
||||
dstpitch += bltwidth;
|
||||
|
||||
dstpitch += bltwidth;
|
||||
srcpitch += bltwidth;
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
|
||||
for (y = 0; y < bltheight; y++) {
|
||||
for (x = 0; x < bltwidth; x+=2) {
|
||||
p1 = *(dst-1);
|
||||
p2 = *dst;
|
||||
|
||||
@ -38,12 +38,13 @@
|
||||
|
||||
static void
|
||||
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
|
||||
(CirrusVGAState * s, uint8_t * dst,
|
||||
const uint8_t * src,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
(CirrusVGAState * s,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
{
|
||||
uint8_t *d;
|
||||
uint8_t *d;
|
||||
int x, y, pattern_y, pattern_pitch, pattern_x;
|
||||
unsigned int col;
|
||||
const uint8_t *src1;
|
||||
@ -53,6 +54,9 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
|
||||
int skipleft = (s->vga.gr[0x2f] & 0x07) * (DEPTH / 8);
|
||||
#endif
|
||||
|
||||
BLTCHECK_DST(skipleft)
|
||||
INITBLIT
|
||||
|
||||
#if DEPTH == 8
|
||||
pattern_pitch = 8;
|
||||
#elif DEPTH == 16
|
||||
@ -93,12 +97,13 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
|
||||
/* NOTE: srcpitch is ignored */
|
||||
static void
|
||||
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
|
||||
(CirrusVGAState * s, uint8_t * dst,
|
||||
const uint8_t * src,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
(CirrusVGAState * s,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
{
|
||||
uint8_t *d;
|
||||
uint8_t *d;
|
||||
int x, y;
|
||||
unsigned bits, bits_xor;
|
||||
unsigned int col;
|
||||
@ -112,7 +117,10 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
|
||||
int dstskipleft = srcskipleft * (DEPTH / 8);
|
||||
#endif
|
||||
|
||||
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
|
||||
BLTCHECK_DST(dstskipleft)
|
||||
INITBLIT
|
||||
|
||||
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
|
||||
bits_xor = 0xff;
|
||||
// Color expansion + transparency: fgcol, not bgcol. TW.
|
||||
col = s->cirrus_blt_fgcol;
|
||||
@ -143,12 +151,13 @@ 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 * src,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
(CirrusVGAState * s,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
{
|
||||
uint32_t colors[2];
|
||||
uint32_t colors[2];
|
||||
uint8_t *d;
|
||||
int x, y;
|
||||
unsigned bits;
|
||||
@ -157,7 +166,10 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
|
||||
int srcskipleft = s->vga.gr[0x2f] & 0x07;
|
||||
int dstskipleft = srcskipleft * (DEPTH / 8);
|
||||
|
||||
colors[0] = s->cirrus_blt_bgcol;
|
||||
BLTCHECK_DST(dstskipleft)
|
||||
INITBLIT
|
||||
|
||||
colors[0] = s->cirrus_blt_bgcol;
|
||||
colors[1] = s->cirrus_blt_fgcol;
|
||||
for(y = 0; y < bltheight; y++) {
|
||||
bitmask = 0x80 >> srcskipleft;
|
||||
@ -179,12 +191,13 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
|
||||
|
||||
static void
|
||||
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
|
||||
(CirrusVGAState * s, uint8_t * dst,
|
||||
const uint8_t * src,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
(CirrusVGAState * s,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
{
|
||||
uint8_t *d;
|
||||
uint8_t *d;
|
||||
int x, y, bitpos, pattern_y;
|
||||
unsigned int bits, bits_xor;
|
||||
unsigned int col;
|
||||
@ -196,7 +209,10 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
|
||||
int dstskipleft = srcskipleft * (DEPTH / 8);
|
||||
#endif
|
||||
|
||||
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
|
||||
BLTCHECK_DST(dstskipleft)
|
||||
INITBLIT
|
||||
|
||||
if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
|
||||
bits_xor = 0xff;
|
||||
// Color expansion + transparency: fgcol, not bgcol. TW.
|
||||
col = s->cirrus_blt_fgcol;
|
||||
@ -224,10 +240,11 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
|
||||
|
||||
static void
|
||||
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
||||
(CirrusVGAState * s, uint8_t * dst,
|
||||
const uint8_t * src,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
(CirrusVGAState * s,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight)
|
||||
{
|
||||
uint32_t colors[2];
|
||||
uint8_t *d;
|
||||
@ -237,6 +254,9 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
||||
int srcskipleft = s->vga.gr[0x2f] & 0x07;
|
||||
int dstskipleft = srcskipleft * (DEPTH / 8);
|
||||
|
||||
BLTCHECK_DST(dstskipleft)
|
||||
INITBLIT
|
||||
|
||||
colors[0] = s->cirrus_blt_bgcol;
|
||||
colors[1] = s->cirrus_blt_fgcol;
|
||||
pattern_y = s->cirrus_blt_srcaddr & 7;
|
||||
@ -258,24 +278,28 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
||||
|
||||
static void
|
||||
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
|
||||
(CirrusVGAState *s,
|
||||
uint8_t *dst, int dst_pitch,
|
||||
int width, int height)
|
||||
(CirrusVGAState *s,
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
int dstpitch,
|
||||
int bltwidth, int bltheight)
|
||||
{
|
||||
uint8_t *d, *d1;
|
||||
uint32_t col;
|
||||
int x, y;
|
||||
|
||||
col = s->cirrus_blt_fgcol;
|
||||
BLTCHECK_DST(0)
|
||||
INITBLIT_DST
|
||||
|
||||
col = s->cirrus_blt_fgcol;
|
||||
|
||||
d1 = dst;
|
||||
for(y = 0; y < height; y++) {
|
||||
for(y = 0; y < bltheight; y++) {
|
||||
d = d1;
|
||||
for(x = 0; x < width; x += (DEPTH / 8)) {
|
||||
for(x = 0; x < bltwidth; x += (DEPTH / 8)) {
|
||||
PUTPIXEL();
|
||||
d += (DEPTH / 8);
|
||||
}
|
||||
d1 += dst_pitch;
|
||||
d1 += dstpitch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -242,11 +242,13 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
||||
typedef struct CirrusVGAState CirrusVGAState;
|
||||
|
||||
typedef void (*cirrus_bitblt_rop_t) (CirrusVGAState *s,
|
||||
uint8_t * dst, const uint8_t * src,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight);
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
const uint8_t *src, uint32_t srcaddr, uint32_t srcmask,
|
||||
int dstpitch, int srcpitch,
|
||||
int bltwidth, int bltheight);
|
||||
typedef void (*cirrus_fill_t)(CirrusVGAState *s,
|
||||
uint8_t *dst, int dst_pitch, int width, int height);
|
||||
uint8_t *dst, uint32_t dstaddr, uint32_t dstmask,
|
||||
int dst_pitch, int width, int height);
|
||||
|
||||
struct CirrusVGAState {
|
||||
VGACommonState vga;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user