(S)VGA: Fix overscan.

This commit is contained in:
OBattler
2025-06-06 20:05:04 +02:00
parent 6dabd3dc34
commit a1a9407629
2 changed files with 29 additions and 17 deletions

View File

@@ -116,6 +116,7 @@ typedef struct svga_t {
int lastline_draw;
int displine;
int fullchange;
int left_overscan;
int x_add;
int y_add;
int pan;

View File

@@ -692,9 +692,9 @@ svga_recalctimings(svga_t *svga)
double _dispofftime_xga = 0.0;
double disptime_xga = 0.0;
int vblankend;
int hdispend;
#ifdef ENABLE_SVGA_LOG
int vsyncend;
int hdispend;
int hdispstart;
int hsyncstart;
int hsyncend;
@@ -915,14 +915,12 @@ svga_recalctimings(svga_t *svga)
if (vblankend <= svga->vblankstart)
vblankend += 0x00000080;
hdispend = svga->crtc[1] + 1;
if (svga->hoverride) {
if (svga->hdisp >= 2048)
svga->monitor->mon_overscan_x = 0;
svga->y_add = (svga->monitor->mon_overscan_y >> 1);
svga->x_add = (svga->monitor->mon_overscan_x >> 1);
svga->left_overscan = svga->x_add = (svga->monitor->mon_overscan_x >> 1);
} else {
uint32_t dot = svga->hblankstart;
uint32_t adj_dot = svga->hblankstart;
@@ -931,7 +929,9 @@ svga_recalctimings(svga_t *svga)
uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f;
svga->hblank_sub = 0;
svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1, svga->hblankstart, svga->hblank_end_val,
svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, "
"Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1,
svga->hblankstart, svga->hblank_end_val,
svga->htotal, eff_mask, adj_dot);
while (adj_dot < (svga->htotal << 1)) {
@@ -941,7 +941,10 @@ svga_recalctimings(svga_t *svga)
if (adj_dot >= svga->htotal)
svga->hblank_sub++;
svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask, svga->hblank_end_val);
svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, "
"hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot,
svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask,
svga->hblank_end_val);
if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask))
break;
@@ -949,17 +952,23 @@ svga_recalctimings(svga_t *svga)
adj_dot++;
}
uint32_t hd = svga->hdisp;
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
svga->y_add = svga->vtotal + vblankend + 1;
svga->monitor->mon_overscan_y = svga->y_add + svga->vblankstart - svga->dispend;
svga->left_overscan = svga->x_add = (svga->htotal - adj_dot - 1) * svga->dots_per_clock;
svga->monitor->mon_overscan_x = svga->x_add + (svga->hblankstart * svga->dots_per_clock) - hd;
if (svga->hdisp >= 2048) {
svga->x_add = 0;
if ((svga->hdisp >= 2048) || (svga->left_overscan < 0)) {
svga->left_overscan = svga->x_add = 0;
svga->monitor->mon_overscan_x = 0;
} else {
svga->x_add = (svga->htotal + svga->hblank_end_val - 1) * svga->dots_per_clock;
svga->monitor->mon_overscan_x = svga->x_add + ((svga->hblankstart - hdispend) * svga->dots_per_clock);
}
svga->y_add = svga->vtotal - vblankend + 1;
svga->monitor->mon_overscan_y = svga->y_add + abs(svga->vblankstart - svga->dispend);
if ((svga->dispend >= 2048) || (svga->y_add < 0)) {
svga->y_add = 0;
svga->monitor->mon_overscan_y = 0;
}
}
@@ -1010,6 +1019,7 @@ svga_recalctimings(svga_t *svga)
if (vsyncend <= svga->vsyncstart)
vsyncend += 0x00000010;
hdispend = svga->crtc[1] + 1;
hdispstart = ((svga->crtc[3] >> 5) & 3);
hsyncstart = svga->crtc[4] + ((svga->crtc[5] >> 5) & 3) + 1;
hsyncend = (hsyncstart & 0xffffffe0) | (svga->crtc[5] & 0x1f);
@@ -1191,10 +1201,10 @@ svga_do_render(svga_t *svga)
if (!svga->override) {
svga->render(svga);
svga->x_add = (svga->monitor->mon_overscan_x >> 1);
svga->x_add = svga->left_overscan;
svga_render_overscan_left(svga);
svga_render_overscan_right(svga);
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
svga->x_add = svga->left_overscan - svga->scrollcache;
}
if (svga->overlay_on) {
@@ -1373,7 +1383,7 @@ svga_poll(void *priv)
svga->sc = 0;
if (svga->attrregs[0x10] & 0x20) {
svga->scrollcache = 0;
svga->x_add = (svga->monitor->mon_overscan_x >> 1);
svga->x_add = svga->left_overscan;
}
}
}
@@ -1479,7 +1489,7 @@ svga_poll(void *priv)
if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres))
svga->scrollcache <<= 1;
svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache;
svga->x_add = svga->left_overscan - svga->scrollcache;
svga->linecountff = 0;
@@ -1529,6 +1539,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
svga->attrregs[0x11] = 0;
svga->overscan_color = 0x000000;
svga->left_overscan = 8;
svga->monitor->mon_overscan_x = 16;
svga->monitor->mon_overscan_y = 32;
svga->x_add = 8;