Fix the timings of the non-Elsa S3 Vision cards with the IBM RGB528 RAMDAC.

This commit is contained in:
OBattler
2025-08-31 20:44:40 +02:00
parent 28d678476d
commit 1b173963fe
4 changed files with 40 additions and 15 deletions

View File

@@ -445,6 +445,7 @@ extern uint8_t ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *
extern void ibm_rgb528_recalctimings(void *priv, svga_t *svga);
extern void ibm_rgb528_hwcursor_draw(svga_t *svga, int displine);
extern float ibm_rgb528_getclock(int clock, void *priv);
extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float ref_clock);
extern void icd2061_write(void *priv, int val);
extern float icd2061_getclock(int clock, void *priv);

View File

@@ -88,6 +88,7 @@ typedef struct ibm_rgb528_ramdac_t {
uint8_t pix_f[16];
uint8_t pix_n[8];
uint8_t pix_m[8];
float ref_clock;
} ibm_rgb528_ramdac_t;
void
@@ -612,24 +613,14 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *s
if ((ramdac->index < 0x0100) || (ramdac->index > 0x04ff) || ramdac->cursor_array)
ramdac->indexed_data[ramdac->index] = val;
switch (ramdac->index) {
case 0x00a:
case 0x00c:
ibm_rgb528_set_bpp(ramdac, svga);
break;
case 0x014:
if (ramdac->indexed_data[0x0002] & 0x01) {
switch (ramdac->indexed_data[0x0010]) {
case 0x00:
case 0x02:
ramdac->pix_f_ref_div = val;
break;
default:
break;
}
}
break;
case 0x020:
case 0x022:
case 0x024:
@@ -955,7 +946,7 @@ ibm_rgb528_getclock(int clock, void *priv)
pll_ref_div_cnt = ramdac->indexed_data[0x0015] & 0x1f;
}
f_pll = 28322000.0f * (float) (pll_vco_div_cnt + 65) / (float) (pll_ref_div_cnt * pll_df);
f_pll = ramdac->ref_clock * (float) (pll_vco_div_cnt + 65) / (float) (pll_ref_div_cnt * pll_df);
f_pll /= (float) ddot_div;
return f_pll;
@@ -1065,6 +1056,17 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine)
svga->dac_hwcursor_latch.addr += pitch;
}
void
ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float ref_clock)
{
ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv;
if (ramdac)
ramdac->ref_clock = ref_clock;
svga_recalctimings(svga);
}
void *
ibm_rgb528_ramdac_init(UNUSED(const device_t *info))
{
@@ -1072,10 +1074,20 @@ ibm_rgb528_ramdac_init(UNUSED(const device_t *info))
memset(ramdac, 0, sizeof(ibm_rgb528_ramdac_t));
ramdac->smlc_part = 0x0100;
ramdac->ref_clock = 14318184.0f;
ramdac->indexed_data[0x0008] = 0x0001;
ramdac->indexed_data[0x0014] = 0x0005;
ramdac->indexed_data[0x0015] = 0x0008;
ramdac->indexed_data[0x0016] = 0x0041;
ramdac->indexed_data[0x0020] = 0x0005;
ramdac->indexed_data[0x0021] = 0x000e;
ramdac->pix_f_ref_div = 0x0005;
ramdac->pix_f[0] = 0x0005;
ramdac->pix_f[1] = 0x000e;
ramdac->pix_m[0] = 0x0005;
ramdac->pix_n[0] = 0x000e;
return ramdac;
}

View File

@@ -3627,6 +3627,7 @@ s3_recalctimings(svga_t *svga)
svga->vblankstart = svga->dispend; /*Applies only to Enhanced modes*/
if (svga->crtc[0x5e] & 0x10)
svga->vsyncstart |= 0x400;
svga->split = svga->crtc[0x18];
if (svga->crtc[7] & 0x10)
svga->split |= 0x100;
if (svga->crtc[9] & 0x40)
@@ -3849,6 +3850,7 @@ s3_recalctimings(svga_t *svga)
case S3_SPEA_MERCURY_P64V:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
if (svga->hdisp == 832)
svga->hdisp -= 32;
break;
@@ -4015,6 +4017,7 @@ s3_recalctimings(svga_t *svga)
case S3_SPEA_MERCURY_P64V:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
/* TODO: Is this still needed? */
if (svga->hdisp == 832)
svga->hdisp -= 32;
@@ -4183,6 +4186,7 @@ s3_recalctimings(svga_t *svga)
case S3_SPEA_MERCURY_P64V:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
/* TODO: Is this still needed? */
if (svga->hdisp == 832)
svga->hdisp -= 32;
@@ -4354,6 +4358,7 @@ s3_recalctimings(svga_t *svga)
case S3_SPEA_MERCURY_P64V:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
/* TODO: Is this still needed? */
if (svga->hdisp == 832)
svga->hdisp -= 32;
@@ -4446,6 +4451,7 @@ s3_trio64v_recalctimings(svga_t *svga)
svga->vblankstart |= 0x400;
if (svga->crtc[0x5e] & 0x10)
svga->vsyncstart |= 0x400;
svga->split = svga->crtc[0x18];
if (svga->crtc[7] & 0x10)
svga->split |= 0x100;
if (svga->crtc[9] & 0x40)
@@ -10335,8 +10341,8 @@ s3_init(const device_t *info)
case S3_VISION968:
switch (info->local) {
case S3_DIAMOND_STEALTH64_968:
case S3_ELSAWIN2KPROX:
case S3_DIAMOND_STEALTH64_968:
case S3_PHOENIX_VISION968:
case S3_NUMBER9_9FX_771:
svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw;
@@ -10578,6 +10584,7 @@ s3_init(const device_t *info)
svga->clock_gen = svga->ramdac;
svga->getclock = ibm_rgb528_getclock;
s3->elsa_eeprom = 1;
ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 28322000.0f);
break;
default:
svga->ramdac = device_add(&bt485_ramdac_device);
@@ -10620,7 +10627,11 @@ s3_init(const device_t *info)
svga->getclock = ibm_rgb528_getclock;
if (info->local == S3_ELSAWIN2KPROX) {
s3->elsa_eeprom = 1;
}
ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 28322000.0f);
} else if (info->local != S3_DIAMOND_STEALTH64_968)
ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 16000000.0f);
else
ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 14318184.0f);
break;
default:
svga->ramdac = device_add(&tvp3026_ramdac_device);

View File

@@ -853,6 +853,7 @@ s3_virge_recalctimings(svga_t *svga)
svga->vblankstart |= 0x400;
if (svga->crtc[0x5e] & 0x10)
svga->vsyncstart |= 0x400;
svga->split = svga->crtc[0x18];
if (svga->crtc[7] & 0x10)
svga->split |= 0x100;
if (svga->crtc[9] & 0x40)