Revision b2eb849d hw/cirrus_vga.c
b/hw/cirrus_vga.c | ||
---|---|---|
220 | 220 |
#define CIRRUS_HOOK_NOT_HANDLED 0 |
221 | 221 |
#define CIRRUS_HOOK_HANDLED 1 |
222 | 222 |
|
223 |
#define BLTUNSAFE(s) \ |
|
224 |
( \ |
|
225 |
( /* check dst is within bounds */ \ |
|
226 |
(s)->cirrus_blt_height * (s)->cirrus_blt_dstpitch \ |
|
227 |
+ ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \ |
|
228 |
(s)->vram_size \ |
|
229 |
) || \ |
|
230 |
( /* check src is within bounds */ \ |
|
231 |
(s)->cirrus_blt_height * (s)->cirrus_blt_srcpitch \ |
|
232 |
+ ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \ |
|
233 |
(s)->vram_size \ |
|
234 |
) \ |
|
235 |
) |
|
236 |
|
|
223 | 237 |
struct CirrusVGAState; |
224 | 238 |
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, |
225 | 239 |
uint8_t * dst, const uint8_t * src, |
... | ... | |
639 | 653 |
|
640 | 654 |
for (y = 0; y < lines; y++) { |
641 | 655 |
off_cur = off_begin; |
642 |
off_cur_end = off_cur + bytesperline;
|
|
656 |
off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
|
|
643 | 657 |
off_cur &= TARGET_PAGE_MASK; |
644 | 658 |
while (off_cur < off_cur_end) { |
645 | 659 |
cpu_physical_memory_set_dirty(s->vram_offset + off_cur); |
... | ... | |
654 | 668 |
{ |
655 | 669 |
uint8_t *dst; |
656 | 670 |
|
657 |
dst = s->vram_ptr + s->cirrus_blt_dstaddr; |
|
671 |
dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); |
|
672 |
|
|
673 |
if (BLTUNSAFE(s)) |
|
674 |
return 0; |
|
675 |
|
|
658 | 676 |
(*s->cirrus_rop) (s, dst, src, |
659 | 677 |
s->cirrus_blt_dstpitch, 0, |
660 | 678 |
s->cirrus_blt_width, s->cirrus_blt_height); |
... | ... | |
670 | 688 |
{ |
671 | 689 |
cirrus_fill_t rop_func; |
672 | 690 |
|
691 |
if (BLTUNSAFE(s)) |
|
692 |
return 0; |
|
673 | 693 |
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; |
674 |
rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
|
|
694 |
rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
|
675 | 695 |
s->cirrus_blt_dstpitch, |
676 | 696 |
s->cirrus_blt_width, s->cirrus_blt_height); |
677 | 697 |
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, |
... | ... | |
690 | 710 |
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) |
691 | 711 |
{ |
692 | 712 |
return cirrus_bitblt_common_patterncopy(s, |
693 |
s->vram_ptr + |
|
694 |
(s->cirrus_blt_srcaddr & ~7));
|
|
713 |
s->vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
|
|
714 |
s->cirrus_addr_mask));
|
|
695 | 715 |
} |
696 | 716 |
|
697 | 717 |
static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) |
... | ... | |
741 | 761 |
if (notify) |
742 | 762 |
vga_hw_update(); |
743 | 763 |
|
744 |
(*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr, |
|
745 |
s->vram_ptr + s->cirrus_blt_srcaddr, |
|
764 |
(*s->cirrus_rop) (s, s->vram_ptr + |
|
765 |
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask), |
|
766 |
s->vram_ptr + |
|
767 |
(s->cirrus_blt_srcaddr & s->cirrus_addr_mask), |
|
746 | 768 |
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, |
747 | 769 |
s->cirrus_blt_width, s->cirrus_blt_height); |
748 | 770 |
|
... | ... | |
768 | 790 |
s->cirrus_blt_srcaddr - s->start_addr, |
769 | 791 |
s->cirrus_blt_width, s->cirrus_blt_height); |
770 | 792 |
} else { |
771 |
(*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr, |
|
772 |
s->vram_ptr + s->cirrus_blt_srcaddr, |
|
793 |
|
|
794 |
if (BLTUNSAFE(s)) |
|
795 |
return 0; |
|
796 |
|
|
797 |
(*s->cirrus_rop) (s, s->vram_ptr + |
|
798 |
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask), |
|
799 |
s->vram_ptr + |
|
800 |
(s->cirrus_blt_srcaddr & s->cirrus_addr_mask), |
|
773 | 801 |
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, |
774 | 802 |
s->cirrus_blt_width, s->cirrus_blt_height); |
775 | 803 |
|
... | ... | |
801 | 829 |
} else { |
802 | 830 |
/* at least one scan line */ |
803 | 831 |
do { |
804 |
(*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr, |
|
805 |
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); |
|
832 |
(*s->cirrus_rop)(s, s->vram_ptr + |
|
833 |
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask), |
|
834 |
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); |
|
806 | 835 |
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, |
807 | 836 |
s->cirrus_blt_width, 1); |
808 | 837 |
s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch; |
... | ... | |
1920 | 1949 |
unsigned val = mem_value; |
1921 | 1950 |
uint8_t *dst; |
1922 | 1951 |
|
1923 |
dst = s->vram_ptr + offset;
|
|
1952 |
dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
|
|
1924 | 1953 |
for (x = 0; x < 8; x++) { |
1925 | 1954 |
if (val & 0x80) { |
1926 | 1955 |
*dst = s->cirrus_shadow_gr1; |
... | ... | |
1943 | 1972 |
unsigned val = mem_value; |
1944 | 1973 |
uint8_t *dst; |
1945 | 1974 |
|
1946 |
dst = s->vram_ptr + offset;
|
|
1975 |
dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
|
|
1947 | 1976 |
for (x = 0; x < 8; x++) { |
1948 | 1977 |
if (val & 0x80) { |
1949 | 1978 |
*dst = s->cirrus_shadow_gr1; |
Also available in: Unified diff