]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Cirrus logic blitter fix
authorToni Wilen <twilen@winuae.net>
Mon, 21 Dec 2020 19:28:28 +0000 (21:28 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 21 Dec 2020 19:28:28 +0000 (21:28 +0200)
pcem/vid_cl5429.cpp
pcem/vid_svga.cpp

index 5215490d28492bdb50ecb407347185a47c396e57..17986862e549bf47d91218c30ed70d8c137a964f 100644 (file)
@@ -2048,7 +2048,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
                         {
                                 case 0x00:
                                 src = svga->vram[gd5429->blt.src_addr & svga->vram_mask];
-                                gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1);
+                                gd5429->blt.src_addr += (gd5429->blt.mode & 0x01) ? -1 : 1;
                                 mask = 1;
                                 break;
                                 case 0x40:
@@ -2114,18 +2114,26 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
                                         {
                                         case BLIT_DEPTH_8:
                                             mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> gd5429->blt.x_count);
+                                            if (gd5429->blt.extensions & 2)
+                                                mask = mask == 0;
                                             src = mask ? fg_col : bg_col;
                                             break;
                                         case BLIT_DEPTH_16:
                                             mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1));
+                                            if (gd5429->blt.extensions & 2)
+                                                mask = mask == 0;
                                             src = mask ? (fg_col >> shift) : (bg_col >> shift);
                                             break;
                                         case BLIT_DEPTH_24:
                                             mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count / 3));
+                                            if (gd5429->blt.extensions & 2)
+                                                mask = mask == 0;
                                             src = mask ? (fg_col >> shift) : (bg_col >> shift);
                                             break;
                                         case BLIT_DEPTH_32:
                                             mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 2));
+                                            if (gd5429->blt.extensions & 2)
+                                                mask = mask == 0;
                                             src = mask ? (fg_col >> shift) : (bg_col >> shift);
                                             break;
                                         }
@@ -2135,7 +2143,6 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
                         count--;                        
                 }
                 dst = svga->vram[(gd5429->blt.dst_addr + bplcnt) & svga->vram_mask];
-                svga->changedvram[((gd5429->blt.dst_addr + bplcnt) & svga->vram_mask) >> 12] = changeframecount;
                
                 //pclog("Blit %i,%i %06X %06X  %06X %02X %02X  %02X %02X\n", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst);
                 switch (gd5429->blt.rop)
@@ -2165,11 +2172,14 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
                         if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
                             !((gd5429->blt.mode & 0x08) && !mask))
                             svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst;
+                            svga->changedvram[((gd5429->blt.dst_addr) & svga->vram_mask) >> 12] = changeframecount;
                     } else if (bpp == 2) {
                         if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
                             !((gd5429->blt.mode & 0x08) && !maskstore)) {
                             svga->vram[(gd5429->blt.dst_addr + 0) & svga->vram_mask] = dststore[0];
                             svga->vram[(gd5429->blt.dst_addr + 1) & svga->vram_mask] = dststore[1];
+                            svga->changedvram[((gd5429->blt.dst_addr + 0) & svga->vram_mask) >> 12] = changeframecount;
+                            svga->changedvram[((gd5429->blt.dst_addr + 1) & svga->vram_mask) >> 12] = changeframecount;
                         }
                     } else if (bpp == 3) {
                         if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
@@ -2177,17 +2187,24 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
                             svga->vram[(gd5429->blt.dst_addr + 0) & svga->vram_mask] = dststore[0];
                             svga->vram[(gd5429->blt.dst_addr + 1) & svga->vram_mask] = dststore[1];
                             svga->vram[(gd5429->blt.dst_addr + 2) & svga->vram_mask] = dststore[2];
+                            svga->changedvram[((gd5429->blt.dst_addr + 0) & svga->vram_mask) >> 12] = changeframecount;
+                            svga->changedvram[((gd5429->blt.dst_addr + 1) & svga->vram_mask) >> 12] = changeframecount;
+                            svga->changedvram[((gd5429->blt.dst_addr + 2) & svga->vram_mask) >> 12] = changeframecount;
                         }
-                    } else if (bpp == 3) {
+                    } else if (bpp == 4) {
                         if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask &&
                             !((gd5429->blt.mode & 0x08) && !maskstore)) {
                             svga->vram[(gd5429->blt.dst_addr + 0) & svga->vram_mask] = dststore[0];
                             svga->vram[(gd5429->blt.dst_addr + 1) & svga->vram_mask] = dststore[1];
                             svga->vram[(gd5429->blt.dst_addr + 2) & svga->vram_mask] = dststore[2];
                             svga->vram[(gd5429->blt.dst_addr + 3) & svga->vram_mask] = dststore[3];
+                            svga->changedvram[((gd5429->blt.dst_addr + 0) & svga->vram_mask) >> 12] = changeframecount;
+                            svga->changedvram[((gd5429->blt.dst_addr + 1) & svga->vram_mask) >> 12] = changeframecount;
+                            svga->changedvram[((gd5429->blt.dst_addr + 2) & svga->vram_mask) >> 12] = changeframecount;
+                            svga->changedvram[((gd5429->blt.dst_addr + 3) & svga->vram_mask) >> 12] = changeframecount;
                         }
                     }
-                    gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -bpp : bpp);
+                    gd5429->blt.dst_addr += (gd5429->blt.mode & 0x01) ? -bpp : bpp;
                     bplcnt = 0;
                     maskstore = 0;
                 }
index 2daee6611b50e01d1b2f170a861ff1e29a21da0a..62523a0d5182f3e13abe442e8705d99bbc1748c3 100644 (file)
@@ -21,6 +21,12 @@ uint8_t svga_rotate[8][256];
   only SVGA device.*/
 static svga_t *svga_pri;
 
+bool svga_on(void *p)
+{
+    svga_t* svga = (svga_t*)p;
+    return svga->scrblank == 0;
+}
+
 int svga_get_vtotal(void)
 {
     int v = svga_pri->vtotal;
@@ -38,6 +44,7 @@ svga_t *svga_get_pri()
 {
         return svga_pri;
 }
+
 void svga_set_override(svga_t *svga, int val)
 {
         if (svga->override && !val)
@@ -93,9 +100,9 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
                 case 0x3C2:
                 svga->miscout = val;
                 svga->vidclock = val & 4;// printf("3C2 write %02X\n",val);
-                io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
+                io_removehandlerx(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
                 if (!(val & 1))
-                        io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
+                        io_sethandlerx(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
                 svga_recalctimings(svga);
                 break;
                 case 0x3C4: 
@@ -195,19 +202,19 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
                                 switch (val&0xC)
                                 {
                                         case 0x0: /*128k at A0000*/
-                                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
+                                        mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x20000);
                                         svga->banked_mask = 0xffff;
                                         break;
                                         case 0x4: /*64k at A0000*/
-                                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
+                                        mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000);
                                         svga->banked_mask = 0xffff;
                                         break;
                                         case 0x8: /*32k at B0000*/
-                                        mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
+                                        mem_mapping_set_addrx(&svga->mapping, 0xb0000, 0x08000);
                                         svga->banked_mask = 0x7fff;
                                         break;
                                         case 0xC: /*32k at B8000*/
-                                        mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
+                                        mem_mapping_set_addrx(&svga->mapping, 0xb8000, 0x08000);
                                         svga->banked_mask = 0x7fff;
                                         break;
                                 }
@@ -349,7 +356,7 @@ void svga_recalctimings(svga_t *svga)
             svga->vblankstart |= 0x200;
         svga->vblankstart++;
         
-        svga->hdisp = svga->crtc[1];
+        svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
         svga->hdisp++;
 
         svga->htotal = svga->crtc[0];
@@ -365,7 +372,11 @@ void svga_recalctimings(svga_t *svga)
         
         svga->interlace = 0;
         
-        svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd];
+        svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
+        svga->ca_adj = 0;
+
+        svga->rowcount = svga->crtc[9] & 31;
+        svga->linedbl = svga->crtc[9] & 0x80;
 
         svga->hdisp_time = svga->hdisp;
         svga->render = svga_render_blank;
@@ -442,8 +453,6 @@ void svga_recalctimings(svga_t *svga)
 
 //pclog("svga_render %08X : %08X %08X %08X %08X %08X  %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8);
         
-        svga->linedbl = svga->crtc[9] & 0x80;
-        svga->rowcount = svga->crtc[9] & 31;
         svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9;
         if (svga->recalctimings_ex) 
                 svga->recalctimings_ex(svga);
@@ -703,32 +712,32 @@ int svga_poll(void *p)
                         changeframecount = svga->interlace ? 3 : 2;
                         svga->vslines = 0;
                         
-                        if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1);
-                        else                                  svga->ma = svga->maback = svga->ma_latch;
-                        svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf];
+                        if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
+                        else                                  svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5);
+                        svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj;
 
                         svga->ma <<= 2;
                         svga->maback <<= 2;
                         svga->ca <<= 2;
 
-                        svga->video_res_x = wx;
-                        svga->video_res_y = wy + 1;
-//                        pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres);
-                        if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/
+                        if (!svga->video_res_override)
                         {
+                            svga->video_res_x = wx;
+                            svga->video_res_y = wy + 1;
+                            if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/
+                            {
                                 svga->video_res_x /= svga->char_width;
                                 svga->video_res_y /= (svga->crtc[9] & 31) + 1;
                                 svga->video_bpp = 0;
-                        }
-                        else
-                        {
+                            } else
+                            {
                                 if (svga->crtc[9] & 0x80)
-                                   svga->video_res_y /= 2;
+                                    svga->video_res_y /= 2;
                                 if (!(svga->crtc[0x17] & 2))
-                                   svga->video_res_y *= 4;
+                                    svga->video_res_y *= 4;
                                 else if (!(svga->crtc[0x17] & 1))
-                                   svga->video_res_y *= 2;
-                                svga->video_res_y /= (svga->crtc[9] & 31) + 1;                                   
+                                    svga->video_res_y *= 2;
+                                svga->video_res_y /= (svga->crtc[9] & 31) + 1;
                                 if (svga->render == svga_render_8bpp_lowres ||
                                     svga->render == svga_render_15bpp_lowres ||
                                     svga->render == svga_render_16bpp_lowres ||
@@ -742,10 +751,11 @@ int svga_poll(void *p)
 
                                 switch (svga->gdcreg[5] & 0x60)
                                 {
-                                        case 0x00:            svga->video_bpp = 4;   break;
-                                        case 0x20:            svga->video_bpp = 2;   break;
-                                        case 0x40: case 0x60: svga->video_bpp = svga->bpp; break;
+                                case 0x00:            svga->video_bpp = 4;   break;
+                                case 0x20:            svga->video_bpp = 2;   break;
+                                case 0x40: case 0x60: svga->video_bpp = svga->bpp; break;
                                 }
+                            }
                         }
 //                        if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2);
                         
@@ -785,6 +795,12 @@ int svga_poll(void *p)
         return eod;
 }
 
+void svga_setvram(void *p, uint8_t *vram)
+{
+    svga_t* svga = (svga_t*)p;
+    svga->vram = vram;
+}
+
 int svga_init(svga_t *svga, void *p, int memsize, 
                void (*recalctimings_ex)(struct svga_t *svga),
                uint8_t (*video_in) (uint16_t addr, void *p),
@@ -823,7 +839,7 @@ int svga_init(svga_t *svga, void *p, int memsize,
         svga->vram_display_mask = memsize - 1;
         svga->vram_mask = memsize - 1;
         svga->decode_mask = 0x7fffff;
-        svga->changedvram = (uint8_t*)malloc(/*(memsize >> 12) << 1*/0x800000 >> 12);
+        svga->changedvram = (uint8_t*)malloc(/*(memsize >> 12) << 1*/0x1000000 >> 12);
         svga->recalctimings_ex = recalctimings_ex;
         svga->video_in  = video_in;
         svga->video_out = video_out;
@@ -1071,6 +1087,11 @@ uint8_t svga_read(uint32_t addr, void *p)
                 addr &= svga->decode_mask;
                 if (addr >= svga->vram_max)
                         return 0xff;
+                latch_addr = addr & svga->vram_mask & ~3;
+                svga->la = svga->vram[latch_addr];
+                svga->lb = svga->vram[latch_addr | 0x1];
+                svga->lc = svga->vram[latch_addr | 0x2];
+                svga->ld = svga->vram[latch_addr | 0x3];
                 return svga->vram[addr & svga->vram_mask];
         }
         else if (svga->chain2_read)
@@ -1119,7 +1140,6 @@ uint8_t svga_read(uint32_t addr, void *p)
                 return ~(temp | temp2 | temp3 | temp4);
         }
 //pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
-
         return svga->vram[addr | readplane];
 }