@@ -86,8 +86,8 @@ static void ati_vga_switch_mode(ATIVGAState *s)
86
86
break ;
87
87
default :
88
88
qemu_log_mask (LOG_UNIMP , "Unsupported bpp value\n" );
89
+ return ;
89
90
}
90
- assert (bpp != 0 );
91
91
DPRINTF ("Switching to %dx%d %d %d @ %x\n" , h , v , stride , bpp , offs );
92
92
vbe_ioport_write_index (& s -> vga , 0 , VBE_DISPI_INDEX_ENABLE );
93
93
vbe_ioport_write_data (& s -> vga , 0 , VBE_DISPI_DISABLED );
@@ -361,6 +361,11 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
361
361
case MC_STATUS :
362
362
val = 5 ;
363
363
break ;
364
+ case MEM_SDRAM_MODE_REG :
365
+ if (s -> dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF ) {
366
+ val = BIT (28 ) | BIT (20 );
367
+ }
368
+ break ;
364
369
case RBBM_STATUS :
365
370
case GUI_STAT :
366
371
val = 64 ; /* free CMDFIFO entries */
@@ -389,22 +394,28 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
389
394
case 0xf00 ... 0xfff :
390
395
val = pci_default_read_config (& s -> dev , addr - 0xf00 , size );
391
396
break ;
392
- case CUR_OFFSET :
393
- val = s -> regs .cur_offset ;
397
+ case CUR_OFFSET ... CUR_OFFSET + 3 :
398
+ val = ati_reg_read_offs ( s -> regs .cur_offset , addr - CUR_OFFSET , size ) ;
394
399
break ;
395
- case CUR_HORZ_VERT_POSN :
396
- val = s -> regs .cur_hv_pos ;
397
- val |= s -> regs .cur_offset & BIT (31 );
400
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3 :
401
+ val = ati_reg_read_offs (s -> regs .cur_hv_pos ,
402
+ addr - CUR_HORZ_VERT_POSN , size );
403
+ if (addr + size > CUR_HORZ_VERT_POSN + 3 ) {
404
+ val |= (s -> regs .cur_offset & BIT (31 )) >> (4 - size );
405
+ }
398
406
break ;
399
- case CUR_HORZ_VERT_OFF :
400
- val = s -> regs .cur_hv_offs ;
401
- val |= s -> regs .cur_offset & BIT (31 );
407
+ case CUR_HORZ_VERT_OFF ... CUR_HORZ_VERT_OFF + 3 :
408
+ val = ati_reg_read_offs (s -> regs .cur_hv_offs ,
409
+ addr - CUR_HORZ_VERT_OFF , size );
410
+ if (addr + size > CUR_HORZ_VERT_OFF + 3 ) {
411
+ val |= (s -> regs .cur_offset & BIT (31 )) >> (4 - size );
412
+ }
402
413
break ;
403
- case CUR_CLR0 :
404
- val = s -> regs .cur_color0 ;
414
+ case CUR_CLR0 ... CUR_CLR0 + 3 :
415
+ val = ati_reg_read_offs ( s -> regs .cur_color0 , addr - CUR_CLR0 , size ) ;
405
416
break ;
406
- case CUR_CLR1 :
407
- val = s -> regs .cur_color1 ;
417
+ case CUR_CLR1 ... CUR_CLR1 + 3 :
418
+ val = ati_reg_read_offs ( s -> regs .cur_color1 , addr - CUR_CLR1 , size ) ;
408
419
break ;
409
420
case DST_OFFSET :
410
421
val = s -> regs .dst_offset ;
@@ -679,48 +690,71 @@ static void ati_mm_write(void *opaque, hwaddr addr,
679
690
case 0xf00 ... 0xfff :
680
691
/* read-only copy of PCI config space so ignore writes */
681
692
break ;
682
- case CUR_OFFSET :
683
- if (s -> regs .cur_offset != (data & 0x87fffff0 )) {
684
- s -> regs .cur_offset = data & 0x87fffff0 ;
693
+ case CUR_OFFSET ... CUR_OFFSET + 3 :
694
+ {
695
+ uint32_t t = s -> regs .cur_offset ;
696
+
697
+ ati_reg_write_offs (& t , addr - CUR_OFFSET , data , size );
698
+ t &= 0x87fffff0 ;
699
+ if (s -> regs .cur_offset != t ) {
700
+ s -> regs .cur_offset = t ;
685
701
ati_cursor_define (s );
686
702
}
687
703
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 );
704
+ }
705
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3 :
706
+ {
707
+ uint32_t t = s -> regs .cur_hv_pos | (s -> regs .cur_offset & BIT (31 ));
708
+
709
+ ati_reg_write_offs (& t , addr - CUR_HORZ_VERT_POSN , data , size );
710
+ s -> regs .cur_hv_pos = t & 0x3fff0fff ;
711
+ if (t & BIT (31 )) {
712
+ s -> regs .cur_offset |= t & BIT (31 );
692
713
} else if (s -> regs .cur_offset & BIT (31 )) {
693
714
s -> regs .cur_offset &= ~BIT (31 );
694
715
ati_cursor_define (s );
695
716
}
696
717
if (!s -> cursor_guest_mode &&
697
- (s -> regs .crtc_gen_cntl & CRTC2_CUR_EN ) && !(data & BIT (31 ))) {
718
+ (s -> regs .crtc_gen_cntl & CRTC2_CUR_EN ) && !(t & BIT (31 ))) {
698
719
dpy_mouse_set (s -> vga .con , s -> regs .cur_hv_pos >> 16 ,
699
720
s -> regs .cur_hv_pos & 0xffff , 1 );
700
721
}
701
722
break ;
723
+ }
702
724
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 );
725
+ {
726
+ uint32_t t = s -> regs .cur_hv_offs | (s -> regs .cur_offset & BIT (31 ));
727
+
728
+ ati_reg_write_offs (& t , addr - CUR_HORZ_VERT_OFF , data , size );
729
+ s -> regs .cur_hv_offs = t & 0x3f003f ;
730
+ if (t & BIT (31 )) {
731
+ s -> regs .cur_offset |= t & BIT (31 );
706
732
} else if (s -> regs .cur_offset & BIT (31 )) {
707
733
s -> regs .cur_offset &= ~BIT (31 );
708
734
ati_cursor_define (s );
709
735
}
710
736
break ;
711
- case CUR_CLR0 :
712
- if (s -> regs .cur_color0 != (data & 0xffffff )) {
713
- s -> regs .cur_color0 = data & 0xffffff ;
737
+ }
738
+ case CUR_CLR0 ... CUR_CLR0 + 3 :
739
+ {
740
+ uint32_t t = s -> regs .cur_color0 ;
741
+
742
+ ati_reg_write_offs (& t , addr - CUR_CLR0 , data , size );
743
+ t &= 0xffffff ;
744
+ if (s -> regs .cur_color0 != t ) {
745
+ s -> regs .cur_color0 = t ;
714
746
ati_cursor_define (s );
715
747
}
716
748
break ;
717
- case CUR_CLR1 :
749
+ }
750
+ case CUR_CLR1 ... CUR_CLR1 + 3 :
718
751
/*
719
752
* Update cursor unconditionally here because some clients set up
720
753
* other registers before actually writing cursor data to memory at
721
754
* offset so we would miss cursor change unless always updating here
722
755
*/
723
- s -> regs .cur_color1 = data & 0xffffff ;
756
+ ati_reg_write_offs (& s -> regs .cur_color1 , addr - CUR_CLR1 , data , size );
757
+ s -> regs .cur_color1 &= 0xffffff ;
724
758
ati_cursor_define (s );
725
759
break ;
726
760
case DST_OFFSET :
0 commit comments