@@ -389,22 +389,28 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
389
389
case 0xf00 ... 0xfff :
390
390
val = pci_default_read_config (& s -> dev , addr - 0xf00 , size );
391
391
break ;
392
- case CUR_OFFSET :
393
- val = s -> regs .cur_offset ;
394
- break ;
395
- case CUR_HORZ_VERT_POSN :
396
- val = s -> regs .cur_hv_pos ;
397
- val |= s -> regs .cur_offset & BIT (31 );
392
+ case CUR_OFFSET ... CUR_OFFSET + 3 :
393
+ val = ati_reg_read_offs (s -> regs .cur_offset , addr - CUR_OFFSET , size );
394
+ break ;
395
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3 :
396
+ val = ati_reg_read_offs (s -> regs .cur_hv_pos ,
397
+ addr - CUR_HORZ_VERT_POSN , size );
398
+ if (addr + size > CUR_HORZ_VERT_POSN + 3 ) {
399
+ val |= (s -> regs .cur_offset & BIT (31 )) >> (4 - size );
400
+ }
398
401
break ;
399
- case CUR_HORZ_VERT_OFF :
400
- val = s -> regs .cur_hv_offs ;
401
- val |= s -> regs .cur_offset & BIT (31 );
402
+ case CUR_HORZ_VERT_OFF ... CUR_HORZ_VERT_OFF + 3 :
403
+ val = ati_reg_read_offs (s -> regs .cur_hv_offs ,
404
+ addr - CUR_HORZ_VERT_OFF , size );
405
+ if (addr + size > CUR_HORZ_VERT_OFF + 3 ) {
406
+ val |= (s -> regs .cur_offset & BIT (31 )) >> (4 - size );
407
+ }
402
408
break ;
403
- case CUR_CLR0 :
404
- val = s -> regs .cur_color0 ;
409
+ case CUR_CLR0 ... CUR_CLR0 + 3 :
410
+ val = ati_reg_read_offs ( s -> regs .cur_color0 , addr - CUR_CLR0 , size ) ;
405
411
break ;
406
- case CUR_CLR1 :
407
- val = s -> regs .cur_color1 ;
412
+ case CUR_CLR1 ... CUR_CLR1 + 3 :
413
+ val = ati_reg_read_offs ( s -> regs .cur_color1 , addr - CUR_CLR1 , size ) ;
408
414
break ;
409
415
case DST_OFFSET :
410
416
val = s -> regs .dst_offset ;
@@ -679,48 +685,71 @@ static void ati_mm_write(void *opaque, hwaddr addr,
679
685
case 0xf00 ... 0xfff :
680
686
/* read-only copy of PCI config space so ignore writes */
681
687
break ;
682
- case CUR_OFFSET :
683
- if (s -> regs .cur_offset != (data & 0x87fffff0 )) {
684
- s -> regs .cur_offset = data & 0x87fffff0 ;
688
+ case CUR_OFFSET ... CUR_OFFSET + 3 :
689
+ {
690
+ uint32_t t = s -> regs .cur_offset ;
691
+
692
+ ati_reg_write_offs (& t , addr - CUR_OFFSET , data , size );
693
+ t &= 0x87fffff0 ;
694
+ if (s -> regs .cur_offset != t ) {
695
+ s -> regs .cur_offset = t ;
685
696
ati_cursor_define (s );
686
697
}
687
698
break ;
688
- case CUR_HORZ_VERT_POSN :
689
- s -> regs .cur_hv_pos = data & 0x3fff0fff ;
690
- if (data & BIT (31 )) {
691
- s -> regs .cur_offset |= data & BIT (31 );
699
+ }
700
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3 :
701
+ {
702
+ uint32_t t = s -> regs .cur_hv_pos | (s -> regs .cur_offset & BIT (31 ));
703
+
704
+ ati_reg_write_offs (& t , addr - CUR_HORZ_VERT_POSN , data , size );
705
+ s -> regs .cur_hv_pos = t & 0x3fff0fff ;
706
+ if (t & BIT (31 )) {
707
+ s -> regs .cur_offset |= t & BIT (31 );
692
708
} else if (s -> regs .cur_offset & BIT (31 )) {
693
709
s -> regs .cur_offset &= ~BIT (31 );
694
710
ati_cursor_define (s );
695
711
}
696
712
if (!s -> cursor_guest_mode &&
697
- (s -> regs .crtc_gen_cntl & CRTC2_CUR_EN ) && !(data & BIT (31 ))) {
713
+ (s -> regs .crtc_gen_cntl & CRTC2_CUR_EN ) && !(t & BIT (31 ))) {
698
714
dpy_mouse_set (s -> vga .con , s -> regs .cur_hv_pos >> 16 ,
699
715
s -> regs .cur_hv_pos & 0xffff , 1 );
700
716
}
701
717
break ;
718
+ }
702
719
case CUR_HORZ_VERT_OFF :
703
- s -> regs .cur_hv_offs = data & 0x3f003f ;
704
- if (data & BIT (31 )) {
705
- s -> regs .cur_offset |= data & BIT (31 );
720
+ {
721
+ uint32_t t = s -> regs .cur_hv_offs | (s -> regs .cur_offset & BIT (31 ));
722
+
723
+ ati_reg_write_offs (& t , addr - CUR_HORZ_VERT_OFF , data , size );
724
+ s -> regs .cur_hv_offs = t & 0x3f003f ;
725
+ if (t & BIT (31 )) {
726
+ s -> regs .cur_offset |= t & BIT (31 );
706
727
} else if (s -> regs .cur_offset & BIT (31 )) {
707
728
s -> regs .cur_offset &= ~BIT (31 );
708
729
ati_cursor_define (s );
709
730
}
710
731
break ;
711
- case CUR_CLR0 :
712
- if (s -> regs .cur_color0 != (data & 0xffffff )) {
713
- s -> regs .cur_color0 = data & 0xffffff ;
732
+ }
733
+ case CUR_CLR0 ... CUR_CLR0 + 3 :
734
+ {
735
+ uint32_t t = s -> regs .cur_color0 ;
736
+
737
+ ati_reg_write_offs (& t , addr - CUR_CLR0 , data , size );
738
+ t &= 0xffffff ;
739
+ if (s -> regs .cur_color0 != t ) {
740
+ s -> regs .cur_color0 = t ;
714
741
ati_cursor_define (s );
715
742
}
716
743
break ;
717
- case CUR_CLR1 :
744
+ }
745
+ case CUR_CLR1 ... CUR_CLR1 + 3 :
718
746
/*
719
747
* Update cursor unconditionally here because some clients set up
720
748
* other registers before actually writing cursor data to memory at
721
749
* offset so we would miss cursor change unless always updating here
722
750
*/
723
- s -> regs .cur_color1 = data & 0xffffff ;
751
+ ati_reg_write_offs (& s -> regs .cur_color1 , addr - CUR_CLR1 , data , size );
752
+ s -> regs .cur_color1 &= 0xffffff ;
724
753
ati_cursor_define (s );
725
754
break ;
726
755
case DST_OFFSET :
0 commit comments