More horizontal blanking calculation fixes (and actually use blank start, not retrace start), fixes graphics cut-off on Voodoo on Windows 98 SE.

This commit is contained in:
OBattler
2024-01-13 00:41:45 +01:00
parent 38ef7fa1c3
commit ca4f5bad13
10 changed files with 76 additions and 39 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);

View File

@@ -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",

View File

@@ -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) {