From d2674c8dbbcc095a3241e9a1a71fe8c6c90917aa Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 12 Jan 2024 21:07:21 +0100 Subject: [PATCH] Fixed the Cirrus horizontal blanking calculation, fixes #4029. --- src/video/vid_cl54xx.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index e960e631c..638413ac7 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1943,21 +1943,32 @@ gd54xx_recalctimings(svga_t *svga) svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) - svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); + svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07); + + svga->hblankstart = svga->crtc[2] + 1; if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { - /* Special blanking mode: the blank start and end become components of the window generator, - and the actual blanking comes from the display enable signal. */ - /* Start blanking at the first character clock after the last active one. */ - svga->hblankstart = svga->crtc[1] + 1; - svga->hblank_end_val = (svga->htotal + 5) & 0x3f; - /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ - if (!svga->scrblank && svga->attr_palette_enable) - svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; - /* No overscan in this mode. */ - svga->hblank_overscan = 0; - /* Also make sure vertical blanking starts on display end. */ - svga->vblankstart = svga->dispend; + /* Special blanking mode: the blank start and end become components of the window generator, + and the actual blanking comes from the display enable signal. */ + /* This means blanking during overscan, we already calculate it that way, so just use the + same calculation and force otvercan to 0. */ + svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | + (((svga->crtc[0x1a] >> 4) & 3) << 6); + + if (svga->crtc[0x1b] & 0x20) { + /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ + if (!svga->scrblank && svga->attr_palette_enable) + svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8; + + /* No overscan in this mode. */ + svga->hblank_overscan = 0; + + svga->monitor->mon_overscan_y = 0; + svga->monitor->mon_overscan_x = 0; + + /* Also make sure vertical blanking starts on display end. */ + svga->vblankstart = svga->dispend; + } } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/