diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index c2ede4d45..8ac7e0292 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -503,7 +503,7 @@ ati28800_recalctimings(svga_t *svga) } if (ati28800->regs[0xad] & 0x08) - svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = ((ati28800->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; } static void diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 587341538..9704a432c 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -113,6 +113,7 @@ typedef struct mach64_t { uint32_t crtc_gen_cntl; uint8_t crtc_int_cntl; + uint32_t crtc_h_sync_strt_wid; uint32_t crtc_h_total_disp; uint32_t crtc_v_sync_strt_wid; uint32_t crtc_v_total_disp; @@ -515,6 +516,10 @@ mach64_recalctimings(svga_t *svga) svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; + svga->hblankstart = (mach64->crtc_h_sync_strt_wid & 255) + + ((mach64->crtc_h_sync_strt_wid >> 8) & 7) + 1; + svga->hblank_end_val = (svga->hblankstart + + ((mach64->crtc_h_sync_strt_wid >> 16) & 31) - 1) & 63; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen); @@ -2350,6 +2355,12 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x03: READ8(addr, mach64->crtc_h_total_disp); break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + READ8(addr, mach64->crtc_h_sync_strt_wid); + break; case 0x08: case 0x09: case 0x0a: @@ -3052,6 +3063,14 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) svga_recalctimings(&mach64->svga); svga->fullchange = svga->monitor->mon_changeframecount; break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + WRITE8(addr, mach64->crtc_h_sync_strt_wid, val); + svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; + break; case 0x08: case 0x09: case 0x0a: diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 365a03cee..f24ca9c4c 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2843,7 +2843,7 @@ mach_recalctimings(svga_t *svga) } if (mach->regs[0xad] & 0x08) - svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = ((mach->regs[0x0d] >> 2) << 8) + svga->crtc[2] + 1; } static void diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 1b868ecd7..cb44e9383 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -616,7 +616,7 @@ et4000_recalctimings(svga_t *svga) if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 3ba134342..69a995208 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -448,7 +448,7 @@ et4000w32p_recalctimings(svga_t *svga) if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x3f] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d386bdb71..c101b272c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -944,7 +944,9 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) svga->htotal |= 0x100; - svga->hblankstart = (((mystique->crtcext_regs[1] & 0x04) >> 2) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((mystique->crtcext_regs[1] & 0x02) >> 2) << 8) + svga->crtc[2] + 1; + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | + (((mystique->crtcext_regs[1] & 0x40) >> 6) << 6); if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) svga->vtotal |= 0x400; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 073b8523f..5242652e8 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3988,7 +3988,7 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; if (svga->crtc[0x5d] & 0x04) svga->hblankstart += 0x100; @@ -4150,7 +4150,7 @@ s3_trio64v_recalctimings(svga_t *svga) } } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; /* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6? The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index f398aa80b..fdac95bac 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -912,7 +912,7 @@ s3_virge_recalctimings(svga_t *svga) svga->vram_display_mask = virge->vram_mask; } - svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[4] + 1; + svga->hblankstart = (((svga->crtc[0x5d] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x5d] & 0x08) >> 3) << 6); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 39d6a2e22..692bfef27 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -738,7 +738,7 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - svga->hblankstart = svga->crtc[4] + 1; + svga->hblankstart = svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00); svga_log("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 31e0d34d4..03db89d2e 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -540,44 +540,60 @@ banshee_recalctimings(svga_t *svga) banshee_t *banshee = (banshee_t *) svga->priv; const voodoo_t *voodoo = banshee->voodoo; - if (banshee->vgaInit0 & 0x40) { - /*7 R/W Horizontal Retrace End bit 5. - - 6 R/W Horizontal Retrace Start bit 8 0x4 - 5 R/W Horizontal Blank End bit 6. - - 4 R/W Horizontal Blank Start bit 8. 0x3 ---- Erratum: Actually, 0x02! - 3 R/W Reserved. - - 2 R/W Horizontal Display Enable End bit 8. 0x1 - 1 R/W Reserved. - - 0 R/W Horizontal Total bit 8. 0x0*/ - if (svga->crtc[0x1a] & 0x01) - svga->htotal += 0x100; - if (svga->crtc[0x1a] & 0x04) - svga->hdisp += 0x100; + /*7 R/W Horizontal Retrace End bit 5. - + 6 R/W Horizontal Retrace Start bit 8 0x4 + 5 R/W Horizontal Blank End bit 6. - + 4 R/W Horizontal Blank Start bit 8. 0x3 ---- Erratum: Actually, 0x02! + 3 R/W Reserved. - + 2 R/W Horizontal Display Enable End bit 8. 0x1 + 1 R/W Reserved. - + 0 R/W Horizontal Total bit 8. 0x0*/ + if (svga->crtc[0x1a] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x1a] & 0x04) + svga->hdisp += 0x100; - svga->hblankstart = (((svga->crtc[0x1a] & 0x40) >> 6) << 8) + svga->crtc[4] + 1; + if (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE) { + /* Video processing mode - assume timings akin to Cirrus' special blanking mode, + that is, no overscan and relying on display end to blank. */ + svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + + (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; + svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + } else { + svga->hblankstart = (((svga->crtc[0x1a] & 0x10) >> 4) << 8) + svga->crtc[2] + 1; svga->hblank_end_val = (svga->crtc[3] & 0x1f) | (((svga->crtc[5] & 0x80) >> 7) << 5) | (((svga->crtc[0x1a] & 0x20) >> 5) << 6); - - /*6 R/W Vertical Retrace Start bit 10 0x10 - 5 R/W Reserved. - - 4 R/W Vertical Blank Start bit 10. 0x15 - 3 R/W Reserved. - - 2 R/W Vertical Display Enable End bit 10 0x12 - 1 R/W Reserved. - - 0 R/W Vertical Total bit 10. 0x6*/ - if (svga->crtc[0x1b] & 0x01) - svga->vtotal += 0x400; - if (svga->crtc[0x1b] & 0x04) - svga->dispend += 0x400; - if (svga->crtc[0x1b] & 0x10) - svga->vblankstart += 0x400; - if (svga->crtc[0x1b] & 0x40) - svga->vsyncstart += 0x400; } + + /*6 R/W Vertical Retrace Start bit 10 0x10 + 5 R/W Reserved. - + 4 R/W Vertical Blank Start bit 10. 0x15 + 3 R/W Reserved. - + 2 R/W Vertical Display Enable End bit 10 0x12 + 1 R/W Reserved. - + 0 R/W Vertical Total bit 10. 0x6*/ + if (svga->crtc[0x1b] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x1b] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x1b] & 0x10) + svga->vblankstart += 0x400; + if (svga->crtc[0x1b] & 0x40) + svga->vsyncstart += 0x400; + #if 0 banshee_log("svga->hdisp=%i\n", svga->hdisp); #endif + if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) + svga->dots_per_clock *= 2; + svga->interlace = 0; if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) {