From 3f8952a558ddfaf1adda3b92b8604a35add52c67 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Feb 2024 18:02:33 +0100 Subject: [PATCH] More (S)VGA horizontal blanking fixes and CPU CR0 bit 4 fixes. --- src/cpu/x86.c | 2 ++ src/cpu/x86_ops_mov_ctrl.h | 4 ++-- src/include/86box/vid_svga.h | 2 ++ src/video/vid_cl54xx.c | 6 +++--- src/video/vid_s3.c | 22 +++++++++------------- src/video/vid_s3_virge.c | 34 +++++++++++++++++++--------------- src/video/vid_svga.c | 34 ++++++++++++++++++---------------- src/video/vid_voodoo_banshee.c | 6 +++--- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 8e4a5b547..2c8c29d49 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -270,6 +270,8 @@ reset_common(int hard) cr0 = 1 << 30; else cr0 = 0; + if (is386 && !is486 && (fpu_type == FPU_387)) + cr0 |= 0x10; cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index eafe3cdde..b0c841f83 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -124,7 +124,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) + if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; @@ -181,7 +181,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; cr0 = cpu_state.regs[cpu_rm].l; - if ((cpu_s->cpu_type != CPU_386DX) || (fpu_type == FPU_387)) + if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) mmu_perm = 4; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 624e85a1b..2f8a83a1d 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -171,6 +171,8 @@ typedef struct svga_t { double clock; double clock8514; + double multiplier; + hwcursor_t hwcursor; hwcursor_t hwcursor_latch; hwcursor_t dac_hwcursor; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 49899b7b4..b8db0440d 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1762,11 +1762,11 @@ gd54xx_recalctimings(svga_t *svga) svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | (((svga->crtc[0x1a] >> 4) & 3) << 6); - svga->hblank_end_mask = 0x0000007f; + svga->hblank_end_mask = 0x000000ff; if (svga->crtc[0x1b] & 0x20) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index d8691ad77..ca737e7fe 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3262,9 +3262,9 @@ s3_recalctimings(svga_t *svga) if (svga->crtc[0x33] & 0x20) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4108,11 +4108,11 @@ s3_trio64v_recalctimings(svga_t *svga) break; } - if ((svga->crtc[0x33] & 0x20) ||((svga->crtc[0x67] & 0xc) == 0xc)) { + if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -4204,15 +4204,11 @@ s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->multiplier = 0.5; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 3184a1ccd..1cb6424fb 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -826,9 +826,9 @@ s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ - svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1] + - ((svga->crtc[3] >> 5) & 3) + 1; - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + + ((svga->crtc[3] >> 5) & 3)*/ + 1; + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; svga->monitor->mon_overscan_y = 0; svga->monitor->mon_overscan_x = 0; @@ -862,19 +862,21 @@ s3_virge_recalctimings(svga_t *svga) case 15: svga->render = svga_render_15bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } break; case 16: svga->render = svga_render_16bpp_highres; if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - svga->htotal >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; svga->hdisp >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + svga->dots_per_clock >>= 1; } break; case 24: @@ -921,15 +923,17 @@ s3_virge_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->hblankstart >>= 1; - svga->hblank_end_val >>= 1; + // svga->htotal >>= 1; + // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) + // svga->hblank_end_val = svga->htotal - 1; + // svga->dots_per_clock >>= 1; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index edb05086a..a3ad2edd8 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -773,6 +773,8 @@ svga_recalctimings(svga_t *svga) } else svga->dots_per_clock = 1; + svga->multiplier = 1.0; + if (svga->recalctimings_ex) svga->recalctimings_ex(svga); @@ -813,26 +815,26 @@ svga_recalctimings(svga_t *svga) if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on[0] || dev->on[1]) { - uint32_t dot8514 = dev->h_blankstart; - uint32_t adj_dot8514 = dev->h_blankstart; - uint32_t eff_mask8514 = 0x0000003f; - dev->hblank_sub = 0; + uint32_t dot8514 = dev->h_blankstart; + uint32_t adj_dot8514 = dev->h_blankstart; + uint32_t eff_mask8514 = 0x0000003f; + dev->hblank_sub = 0; - while (1) { - if (dot8514 == dev->h_total) - dot = 0; + while (1) { + if (dot8514 == dev->h_total) + dot = 0; - if (adj_dot8514 >= dev->h_total) - dev->hblank_sub++; + if (adj_dot8514 >= dev->h_total) + dev->hblank_sub++; - if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) - break; + if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + break; - dot8514++; - adj_dot8514++; - } + dot8514++; + adj_dot8514++; + } - dev->h_disp -= dev->hblank_sub; + dev->h_disp -= dev->hblank_sub; } } } @@ -889,7 +891,7 @@ svga_recalctimings(svga_t *svga) svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend, svga->hblankstart, svga->hblankend); - disptime = svga->htotal; + disptime = svga->htotal * svga->multiplier; _dispontime = svga->hdisp_time; if (ibm8514_active && (svga->dev8514 != NULL)) { diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 9fec8c073..f03f6efd4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -557,14 +557,14 @@ banshee_recalctimings(svga_t *svga) /* Video processing mode - assume timings akin to Cirrus' special blanking mode, that is, no overscan and relying on display end to blank. */ if (banshee->vgaInit0 & 0x40) { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + (((svga->crtc[0x1a] & 0x04) >> 2) << 8) + 1; svga->hblank_end_mask = 0x0000007f; } else { - svga->hblankstart = svga->crtc[1] + ((svga->crtc[3] >> 5) & 3) + 1; + svga->hblankstart = svga->crtc[1]/* + ((svga->crtc[3] >> 5) & 3)*/ + 1; svga->hblank_end_mask = 0x0000003f; } - svga->hblank_end_val = ((svga->crtc[3] >> 5) & 3); + svga->hblank_end_val = svga->htotal - 1 /* + ((svga->crtc[3] >> 5) & 3)*/; /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ if (!svga->scrblank && svga->attr_palette_enable)