PCem

changeset 85:3b1a61addfa4

ViRGE: Preliminary stream processor emulation - enough to fix double buffering in DirectX. Implemented transparent blit mode with colour sources. Implemented old style MMIO.
author TomW
date Thu Mar 20 16:33:31 2014 +0000
parents b53e148867e5
children 42ac4acbb4c5
files src/vid_s3_virge.c
diffstat 1 files changed, 274 insertions(+), 99 deletions(-) [+]
line diff
     1.1 --- a/src/vid_s3_virge.c	Thu Mar 20 14:03:55 2014 +0000
     1.2 +++ b/src/vid_s3_virge.c	Thu Mar 20 16:33:31 2014 +0000
     1.3 @@ -70,6 +70,33 @@
     1.4                  uint32_t pattern_16[8*8];
     1.5                  uint32_t pattern_32[8*8];
     1.6          } s3d;
     1.7 +        
     1.8 +        struct
     1.9 +        {
    1.10 +                uint32_t pri_ctrl;
    1.11 +                uint32_t chroma_ctrl;
    1.12 +                uint32_t sec_ctrl;
    1.13 +                uint32_t chroma_upper_bound;
    1.14 +                uint32_t sec_filter;
    1.15 +                uint32_t blend_ctrl;
    1.16 +                uint32_t pri_fb0, pri_fb1;
    1.17 +                uint32_t pri_stride;
    1.18 +                uint32_t buffer_ctrl;
    1.19 +                uint32_t sec_fb0, sec_fb1;
    1.20 +                uint32_t sec_stride;
    1.21 +                uint32_t overlay_ctrl;
    1.22 +                uint32_t k1_vert_scale;
    1.23 +                uint32_t k2_vert_scale;
    1.24 +                uint32_t dda_vert_accumulator;
    1.25 +                uint32_t fifo_ctrl;
    1.26 +                uint32_t pri_start;
    1.27 +                uint32_t pri_size;
    1.28 +                uint32_t sec_start;
    1.29 +                uint32_t sec_size;
    1.30 +                
    1.31 +                int pri_x, pri_y, pri_w, pri_h;
    1.32 +                int sec_x, sec_y, sec_w, sec_h;
    1.33 +        } streams;
    1.34  } virge_t;
    1.35  
    1.36  static void s3_virge_updatemapping(virge_t *virge);
    1.37 @@ -83,13 +110,6 @@
    1.38  static void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p);
    1.39  static void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p);
    1.40  
    1.41 -static uint8_t  s3_virge_new_mmio_read(uint32_t addr, void *p);
    1.42 -static uint16_t s3_virge_new_mmio_read_w(uint32_t addr, void *p);
    1.43 -static uint32_t s3_virge_new_mmio_read_l(uint32_t addr, void *p);
    1.44 -static void     s3_virge_new_mmio_write(uint32_t addr, uint8_t val, void *p);
    1.45 -static void     s3_virge_new_mmio_write_w(uint32_t addr, uint16_t val, void *p);
    1.46 -static void     s3_virge_new_mmio_write_l(uint32_t addr, uint32_t val, void *p);
    1.47 -
    1.48  enum
    1.49  {
    1.50          CMD_SET_AE = 1,
    1.51 @@ -159,7 +179,7 @@
    1.52                  svga->crtcreg = val & 0x7f;
    1.53                  return;
    1.54                  case 0x3d5:
    1.55 -                //pclog("Write CRTC R%02X %02X\n", svga->crtcreg, val);
    1.56 +//                pclog("Write CRTC R%02X %02X\n", svga->crtcreg, val);
    1.57                  if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) 
    1.58                          return;
    1.59                  if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) 
    1.60 @@ -218,7 +238,6 @@
    1.61                          case 0x46: case 0x47: case 0x48: case 0x49:
    1.62                          case 0x4c: case 0x4d: case 0x4e: case 0x4f:
    1.63                          svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff;
    1.64 -                        if (svga->bpp == 32) svga->hwcursor.x >>= 1;
    1.65                          svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff;
    1.66                          svga->hwcursor.xoff = svga->crtc[0x4e] & 63;
    1.67                          svga->hwcursor.yoff = svga->crtc[0x4f] & 63;
    1.68 @@ -235,8 +254,8 @@
    1.69                          {
    1.70                                  case 3:  svga->bpp = 15; break;
    1.71                                  case 5:  svga->bpp = 16; break;
    1.72 -//                                case 7:  svga->bpp = 24; break;
    1.73 -                                case 13: svga->bpp = 24; break;
    1.74 +                                case 7:  svga->bpp = 24; break;
    1.75 +                                case 13: svga->bpp = 32; break;
    1.76                                  default: svga->bpp = 8;  break;
    1.77                          }
    1.78                          break;
    1.79 @@ -301,61 +320,86 @@
    1.80  static void s3_virge_recalctimings(svga_t *svga)
    1.81  {
    1.82          virge_t *virge = (virge_t *)svga->p;
    1.83 -//        pclog("recalctimings\n");
    1.84 -        svga->ma_latch |= (virge->ma_ext << 16);
    1.85 -//        pclog("SVGA_MA %08X\n", svga_ma);
    1.86 -//        if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10);
    1.87 -        if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
    1.88 -        {
    1.89 -                switch (svga->bpp)
    1.90 -                {
    1.91 -                        case 8: 
    1.92 -                        svga->render = svga_render_8bpp_highres; 
    1.93 -                        break;
    1.94 -                        case 15: 
    1.95 -                        svga->render = svga_render_15bpp_highres; 
    1.96 -                        break;
    1.97 -                        case 16: 
    1.98 -                        svga->render = svga_render_16bpp_highres; 
    1.99 -                        break;
   1.100 -                        case 24: 
   1.101 -                        svga->render = svga_render_24bpp_highres; 
   1.102 -                        break;
   1.103 -                        case 32: 
   1.104 -                        svga->render = svga_render_32bpp_highres; 
   1.105 -                        break;
   1.106 -                }
   1.107 -        }
   1.108 -        
   1.109 +
   1.110          if (svga->crtc[0x5d] & 0x01) svga->htotal     += 0x100;
   1.111          if (svga->crtc[0x5d] & 0x02) svga->hdisp      += 0x100;
   1.112          if (svga->crtc[0x5e] & 0x01) svga->vtotal     += 0x400;
   1.113          if (svga->crtc[0x5e] & 0x02) svga->dispend    += 0x400;
   1.114          if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400;
   1.115          if (svga->crtc[0x5e] & 0x40) svga->split      += 0x400;
   1.116 -        if (svga->crtc[0x51] & 0x30)      svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
   1.117 -        else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
   1.118 -        if (!svga->rowoffset) svga->rowoffset = 256;
   1.119          svga->interlace = svga->crtc[0x42] & 0x20;
   1.120 -//        pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp);
   1.121 -        if (svga->bpp == 15 || svga->bpp == 16)
   1.122 +
   1.123 +        if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/
   1.124          {
   1.125 -                svga->htotal >>= 1;
   1.126 -                svga->hdisp >>= 1;
   1.127 +                svga->ma_latch |= (virge->ma_ext << 16);
   1.128 +
   1.129 +                if (svga->crtc[0x51] & 0x30)      svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
   1.130 +                else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
   1.131 +                if (!svga->rowoffset) svga->rowoffset = 256;
   1.132 +
   1.133 +                if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
   1.134 +                {
   1.135 +                        switch (svga->bpp)
   1.136 +                        {
   1.137 +                                case 8: 
   1.138 +                                svga->render = svga_render_8bpp_highres; 
   1.139 +                                break;
   1.140 +                                case 15: 
   1.141 +                                svga->render = svga_render_15bpp_highres; 
   1.142 +                                break;
   1.143 +                                case 16: 
   1.144 +                                svga->render = svga_render_16bpp_highres; 
   1.145 +                                break;
   1.146 +                                case 24: 
   1.147 +                                svga->render = svga_render_24bpp_highres; 
   1.148 +                                break;
   1.149 +                                case 32: 
   1.150 +                                svga->render = svga_render_32bpp_highres; 
   1.151 +                                break;
   1.152 +                        }
   1.153 +                }
   1.154 +        
   1.155 +//                pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp);
   1.156 +                if (svga->bpp == 15 || svga->bpp == 16)
   1.157 +                {
   1.158 +                        svga->htotal >>= 1;
   1.159 +                        svga->hdisp >>= 1;
   1.160 +                }
   1.161 +                if (svga->bpp == 24)
   1.162 +                {
   1.163 +                        svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
   1.164 +                }
   1.165          }
   1.166 -        if (svga->bpp == 24)
   1.167 +        else /*Streams mode*/
   1.168          {
   1.169 -                svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
   1.170 +                if (virge->streams.buffer_ctrl & 1)
   1.171 +                        svga->ma_latch = virge->streams.pri_fb1 >> 2;
   1.172 +                else
   1.173 +                        svga->ma_latch = virge->streams.pri_fb0 >> 2;
   1.174 +                
   1.175 +                svga->rowoffset = virge->streams.pri_stride >> 3;
   1.176 +
   1.177 +                switch ((virge->streams.pri_ctrl >> 24) & 0x7)
   1.178 +                {
   1.179 +                        case 0: /*RGB-8 (CLUT)*/
   1.180 +                        svga->render = svga_render_8bpp_highres; 
   1.181 +                        break;
   1.182 +                        case 3: /*KRGB-16 (1.5.5.5)*/ 
   1.183 +                        svga->render = svga_render_15bpp_highres; 
   1.184 +                        break;
   1.185 +                        case 5: /*RGB-16 (5.6.5)*/ 
   1.186 +                        svga->render = svga_render_16bpp_highres; 
   1.187 +                        break;
   1.188 +                        case 6: /*RGB-24 (8.8.8)*/ 
   1.189 +                        svga->render = svga_render_24bpp_highres; 
   1.190 +                        break;
   1.191 +                        case 7: /*XRGB-32 (X.8.8.8)*/
   1.192 +                        svga->render = svga_render_32bpp_highres; 
   1.193 +                        break;
   1.194 +                }
   1.195          }
   1.196  
   1.197 -/*        if (svga->bpp == 32)
   1.198 -        {
   1.199 -                svga->htotal <<= 2;
   1.200 -                svga->hdisp <<= 2;
   1.201 -        }*/
   1.202 -        //svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
   1.203 -//        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
   1.204 -        //if (bpp > 8) svga_clock /= 2;
   1.205 +
   1.206  }
   1.207  
   1.208  static void s3_virge_updatemapping(virge_t *virge)
   1.209 @@ -433,7 +477,7 @@
   1.210                  if (svga->crtc[0x53] & 0x20)
   1.211                          mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000);
   1.212                  else
   1.213 -                        mem_mapping_set_addr(&virge->mmio_mapping, 0xa8000, 0x8000);
   1.214 +                        mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000);
   1.215          }
   1.216          else
   1.217                  mem_mapping_disable(&virge->mmio_mapping);
   1.218 @@ -448,34 +492,6 @@
   1.219  
   1.220  static uint8_t s3_virge_mmio_read(uint32_t addr, void *p)
   1.221  {
   1.222 -//        pclog("MMIO readb %08X\n", addr);
   1.223 -        return 0xff;
   1.224 -}
   1.225 -static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p)
   1.226 -{
   1.227 -//        pclog("MMIO readw %08X\n", addr);
   1.228 -        return 0xffff;
   1.229 -}
   1.230 -static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
   1.231 -{
   1.232 -//        pclog("MMIO readl %08X\n", addr);
   1.233 -        return 0xffffffff;
   1.234 -}
   1.235 -static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
   1.236 -{
   1.237 -//        pclog("MMIO writeb %08X %02X\n", addr, val);
   1.238 -}
   1.239 -static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
   1.240 -{
   1.241 -//        pclog("MMIO writew %08X %04X\n", addr, val);
   1.242 -}
   1.243 -static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
   1.244 -{
   1.245 -//        pclog("MMIO writel %08X %08X\n", addr, val);
   1.246 -}
   1.247 -
   1.248 -static uint8_t s3_virge_new_mmio_read(uint32_t addr, void *p)
   1.249 -{
   1.250  //        pclog("New MMIO readb %08X\n", addr);
   1.251          switch (addr & 0xffff)
   1.252          {
   1.253 @@ -495,23 +511,90 @@
   1.254          }
   1.255          return 0xff;
   1.256  }
   1.257 -static uint16_t s3_virge_new_mmio_read_w(uint32_t addr, void *p)
   1.258 +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p)
   1.259  {
   1.260  //        pclog("New MMIO readw %08X\n", addr);
   1.261          switch (addr & 0xfffe)
   1.262          {
   1.263                  default:
   1.264 -                return s3_virge_new_mmio_read(addr, p) | (s3_virge_new_mmio_read(addr + 1, p) << 8);
   1.265 +                return s3_virge_mmio_read(addr, p) | (s3_virge_mmio_read(addr + 1, p) << 8);
   1.266          }
   1.267          return 0xffff;
   1.268  }
   1.269 -static uint32_t s3_virge_new_mmio_read_l(uint32_t addr, void *p)
   1.270 +static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
   1.271  {
   1.272          virge_t *virge = (virge_t *)p;
   1.273          uint32_t ret = 0xffffffff;
   1.274  //        pclog("New MMIO readl %08X\n", addr);
   1.275          switch (addr & 0xfffc)
   1.276          {
   1.277 +                case 0x8180:
   1.278 +                ret = virge->streams.pri_ctrl;
   1.279 +                break;
   1.280 +                case 0x8184:
   1.281 +                ret = virge->streams.chroma_ctrl;
   1.282 +                break;
   1.283 +                case 0x8190:
   1.284 +                ret = virge->streams.sec_ctrl;
   1.285 +                break;
   1.286 +                case 0x8194:
   1.287 +                ret = virge->streams.chroma_upper_bound;
   1.288 +                break;
   1.289 +                case 0x8198:
   1.290 +                ret = virge->streams.sec_filter;
   1.291 +                break;
   1.292 +                case 0x81a0:
   1.293 +                ret = virge->streams.blend_ctrl;
   1.294 +                break;
   1.295 +                case 0x81c0:
   1.296 +                ret = virge->streams.pri_fb0;
   1.297 +                break;
   1.298 +                case 0x81c4:
   1.299 +                ret = virge->streams.pri_fb1;
   1.300 +                break;
   1.301 +                case 0x81c8:
   1.302 +                ret = virge->streams.pri_stride;
   1.303 +                break;
   1.304 +                case 0x81cc:
   1.305 +                ret = virge->streams.buffer_ctrl;
   1.306 +                break;
   1.307 +                case 0x81d0:
   1.308 +                ret = virge->streams.sec_fb0;
   1.309 +                break;
   1.310 +                case 0x81d4:
   1.311 +                ret = virge->streams.sec_fb1;
   1.312 +                break;
   1.313 +                case 0x81d8:
   1.314 +                ret = virge->streams.sec_stride;
   1.315 +                break;
   1.316 +                case 0x81dc:
   1.317 +                ret = virge->streams.overlay_ctrl;
   1.318 +                break;
   1.319 +                case 0x81e0:
   1.320 +                ret = virge->streams.k1_vert_scale;
   1.321 +                break;
   1.322 +                case 0x81e4:
   1.323 +                ret = virge->streams.k2_vert_scale;
   1.324 +                break;
   1.325 +                case 0x81e8:
   1.326 +                ret = virge->streams.dda_vert_accumulator;
   1.327 +                break;
   1.328 +                case 0x81ec:
   1.329 +                ret = virge->streams.fifo_ctrl;
   1.330 +                break;
   1.331 +                case 0x81f0:
   1.332 +                ret = virge->streams.pri_start;
   1.333 +                break;
   1.334 +                case 0x81f4:
   1.335 +                ret = virge->streams.pri_size;
   1.336 +                break;
   1.337 +                case 0x81f8:
   1.338 +                ret = virge->streams.sec_start;
   1.339 +                break;
   1.340 +                case 0x81fc:
   1.341 +                ret = virge->streams.sec_size;
   1.342 +                break;
   1.343 +                
   1.344                  case 0x8504:
   1.345                  ret = (0x1f << 8) | (1 << 13);
   1.346                  break;
   1.347 @@ -562,11 +645,11 @@
   1.348                  break;
   1.349                  
   1.350                  default:
   1.351 -                return s3_virge_new_mmio_read_w(addr, p) | (s3_virge_new_mmio_read_w(addr + 2, p) << 16);
   1.352 +                return s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16);
   1.353          }
   1.354          return ret;
   1.355  }
   1.356 -static void s3_virge_new_mmio_write(uint32_t addr, uint8_t val, void *p)
   1.357 +static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
   1.358  {
   1.359          virge_t *virge = (virge_t *)p;
   1.360          svga_t *svga = &virge->svga;
   1.361 @@ -595,7 +678,7 @@
   1.362  
   1.363                  
   1.364  }
   1.365 -static void s3_virge_new_mmio_write_w(uint32_t addr, uint16_t val, void *p)
   1.366 +static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
   1.367  {
   1.368          virge_t *virge = (virge_t *)p;
   1.369  //        pclog("New MMIO writew %08X %04X\n", addr, val);
   1.370 @@ -609,15 +692,15 @@
   1.371          else switch (addr & 0xfffe)
   1.372          {
   1.373                  case 0x83d4:
   1.374 -                s3_virge_new_mmio_write(addr, val, p);
   1.375 -                s3_virge_new_mmio_write(addr + 1, val >> 8, p);
   1.376 +                s3_virge_mmio_write(addr, val, p);
   1.377 +                s3_virge_mmio_write(addr + 1, val >> 8, p);
   1.378                  break;
   1.379          }
   1.380  }
   1.381 -static void s3_virge_new_mmio_write_l(uint32_t addr, uint32_t val, void *p)
   1.382 +static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
   1.383  {
   1.384          virge_t *virge = (virge_t *)p;
   1.385 -
   1.386 +        svga_t *svga = &virge->svga;
   1.387  //        if ((addr & 0xfffc) >= 0x8000)
   1.388  //                pclog("New MMIO writel %08X %08X\n", addr, val);
   1.389  
   1.390 @@ -630,6 +713,94 @@
   1.391          }
   1.392          else switch (addr & 0xfffc)
   1.393          {
   1.394 +                case 0x8180:
   1.395 +                virge->streams.pri_ctrl = val;
   1.396 +                s3_virge_recalctimings(svga);
   1.397 +                svga->fullchange = changeframecount;
   1.398 +                break;
   1.399 +                case 0x8184:
   1.400 +                virge->streams.chroma_ctrl = val;
   1.401 +                break;
   1.402 +                case 0x8190:
   1.403 +                virge->streams.sec_ctrl = val;
   1.404 +                break;
   1.405 +                case 0x8194:
   1.406 +                virge->streams.chroma_upper_bound = val;
   1.407 +                break;
   1.408 +                case 0x8198:
   1.409 +                virge->streams.sec_filter = val;
   1.410 +                break;
   1.411 +                case 0x81a0:
   1.412 +                virge->streams.blend_ctrl = val;
   1.413 +                break;
   1.414 +                case 0x81c0:
   1.415 +                virge->streams.pri_fb0 = val & 0x3fffff;
   1.416 +                s3_virge_recalctimings(svga);
   1.417 +                svga->fullchange = changeframecount;
   1.418 +                break;
   1.419 +                case 0x81c4:
   1.420 +                virge->streams.pri_fb1 = val & 0x3fffff;
   1.421 +                s3_virge_recalctimings(svga);
   1.422 +                svga->fullchange = changeframecount;
   1.423 +                break;
   1.424 +                case 0x81c8:
   1.425 +                virge->streams.pri_stride = val & 0xfff;
   1.426 +                s3_virge_recalctimings(svga);
   1.427 +                svga->fullchange = changeframecount;
   1.428 +                break;
   1.429 +                case 0x81cc:
   1.430 +                virge->streams.buffer_ctrl = val;
   1.431 +                s3_virge_recalctimings(svga);
   1.432 +                break;
   1.433 +                case 0x81d0:
   1.434 +                virge->streams.sec_fb0 = val;
   1.435 +                break;
   1.436 +                case 0x81d4:
   1.437 +                virge->streams.sec_fb1 = val;
   1.438 +                break;
   1.439 +                case 0x81d8:
   1.440 +                virge->streams.sec_stride = val;
   1.441 +                break;
   1.442 +                case 0x81dc:
   1.443 +                virge->streams.overlay_ctrl = val;
   1.444 +                break;
   1.445 +                case 0x81e0:
   1.446 +                virge->streams.k1_vert_scale = val;
   1.447 +                break;
   1.448 +                case 0x81e4:
   1.449 +                virge->streams.k2_vert_scale = val;
   1.450 +                break;
   1.451 +                case 0x81e8:
   1.452 +                virge->streams.dda_vert_accumulator = val;
   1.453 +                break;
   1.454 +                case 0x81ec:
   1.455 +                virge->streams.fifo_ctrl = val;
   1.456 +                break;
   1.457 +                case 0x81f0:
   1.458 +                virge->streams.pri_start = val;
   1.459 +                virge->streams.pri_x = (val >> 16) & 0x7ff;
   1.460 +                virge->streams.pri_y = val & 0x7ff;                
   1.461 +                s3_virge_recalctimings(svga);
   1.462 +                svga->fullchange = changeframecount;
   1.463 +                break;
   1.464 +                case 0x81f4:
   1.465 +                virge->streams.pri_size = val;
   1.466 +                virge->streams.pri_w = (val >> 16) & 0x7ff;
   1.467 +                virge->streams.pri_h = val & 0x7ff;                
   1.468 +                s3_virge_recalctimings(svga);
   1.469 +                svga->fullchange = changeframecount;
   1.470 +                break;
   1.471 +                case 0x81f8:
   1.472 +                virge->streams.sec_start = val;
   1.473 +                virge->streams.sec_x = (val >> 16) & 0x7ff;
   1.474 +                virge->streams.sec_y = val & 0x7ff;                
   1.475 +                break;
   1.476 +                case 0x81fc:
   1.477 +                virge->streams.sec_size = val;
   1.478 +                virge->streams.sec_w = (val >> 16) & 0x7ff;
   1.479 +                virge->streams.sec_h = val & 0x7ff;                
   1.480 +                break;
   1.481 +                
   1.482                  case 0xa000: case 0xa004: case 0xa008: case 0xa00c:
   1.483                  case 0xa010: case 0xa014: case 0xa018: case 0xa01c:
   1.484                  case 0xa020: case 0xa024: case 0xa028: case 0xa02c:
   1.485 @@ -931,6 +1102,8 @@
   1.486                                  case 0:
   1.487                                  case CMD_SET_MS:
   1.488                                  READ(src_addr, source);
   1.489 +                                if ((virge->s3d.cmd_set & CMD_SET_TP) && source == virge->s3d.src_fg_clr)
   1.490 +                                        update = 0;
   1.491                                  break;
   1.492                                  case CMD_SET_IDS:
   1.493                                  if (virge->s3d.data_left_count)
   1.494 @@ -960,6 +1133,8 @@
   1.495                                                  count = 0;
   1.496                                          }
   1.497                                  }
   1.498 +                                if ((virge->s3d.cmd_set & CMD_SET_TP) && source == virge->s3d.src_fg_clr)
   1.499 +                                        update = 0;
   1.500                                  break;
   1.501                                  case CMD_SET_IDS | CMD_SET_MS:
   1.502                                  source = (cpu_dat & (1 << 31)) ? virge->s3d.src_fg_clr : virge->s3d.src_bg_clr;
   1.503 @@ -1287,12 +1462,12 @@
   1.504                                                          NULL,
   1.505                                                          0,
   1.506                                                          virge);
   1.507 -        mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_new_mmio_read,
   1.508 -                                                        s3_virge_new_mmio_read_w,
   1.509 -                                                        s3_virge_new_mmio_read_l,
   1.510 -                                                        s3_virge_new_mmio_write,
   1.511 -                                                        s3_virge_new_mmio_write_w,
   1.512 -                                                        s3_virge_new_mmio_write_l,
   1.513 +        mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read,
   1.514 +                                                        s3_virge_mmio_read_w,
   1.515 +                                                        s3_virge_mmio_read_l,
   1.516 +                                                        s3_virge_mmio_write,
   1.517 +                                                        s3_virge_mmio_write_w,
   1.518 +                                                        s3_virge_mmio_write_l,
   1.519                                                          NULL,
   1.520                                                          0,
   1.521                                                          virge);