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;
|