diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 0a327d02b..b588a3daf 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -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); diff --git a/src/video/ramdac/vid_ramdac_ibm_rgb528.c b/src/video/ramdac/vid_ramdac_ibm_rgb528.c index 3b59aed70..2f1d57240 100644 --- a/src/video/ramdac/vid_ramdac_ibm_rgb528.c +++ b/src/video/ramdac/vid_ramdac_ibm_rgb528.c @@ -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,23 +613,13 @@ 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; - } - } + ramdac->pix_f_ref_div = val; break; case 0x020: case 0x022: @@ -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,17 +1056,38 @@ 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)) { ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) malloc(sizeof(ibm_rgb528_ramdac_t)); memset(ramdac, 0, sizeof(ibm_rgb528_ramdac_t)); - ramdac->smlc_part = 0x0100; + 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; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index d0a098517..a0f074e70 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -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); diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index e0ebfcb6f..3bd6d694d 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -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)