S3 928 and icd2061 mode rework (September 15th, 2025)

The rework resolves around implementing the clock multiplier and multiplexing rate of the bt485 ramdac alongside existing additional flags for eventual fixes (like cr31 bit 1) as well as the true color bypass (for 16-bit and true color modes). These, together, allow proper rendering of the generic VESA S3 drivers alongside non-VESA ELSA OEM drivers on various guests.
This commit is contained in:
TC1995
2025-09-15 17:48:24 +02:00
parent 110fe81643
commit c3a6e826b4
7 changed files with 301 additions and 301 deletions

View File

@@ -0,0 +1,38 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* ICD2061 clock generator emulation.
* Also emulates the ICS9161 which is the same as the ICD2016,
* but without the need for tuning (which is irrelevant in
* emulation anyway).
*
* Used by ET4000w32/p (Diamond Stealth 32) and the S3
* Vision964 family.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
*/
#ifndef VIDEO_CLOCKGEN_ICD2061_H
#define VIDEO_CLOCKGEN_ICD2061_H
typedef struct icd2061_t {
float freq[3];
float ref_clock;
int count;
int bit_count;
int unlocked;
int state;
uint32_t data;
uint32_t ctrl;
} icd2061_t;
#endif // VIDEO_CLOCKGEN_ICD2061_H

View File

@@ -142,6 +142,9 @@ typedef struct svga_t {
int start_retrace_latch;
int vga_mode;
int half_pixel;
int clock_multiplier;
int true_color_bypass;
int multiplexing_rate;
/*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
0MB-1MB - VRAM
@@ -450,7 +453,7 @@ extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float r
extern void icd2061_write(void *priv, int val);
extern float icd2061_getclock(int clock, void *priv);
extern void icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock);
extern void icd2061_set_ref_clock(void *priv, float ref_clock);
/* The code is the same, the #define's are so that the correct name can be used. */
# define ics9161_write icd2061_write

View File

@@ -33,20 +33,9 @@
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_clockgen_icd2061.h>
#include <86box/plat_unused.h>
typedef struct icd2061_t {
float freq[3];
float ref_clock;
int count;
int bit_count;
int unlocked;
int state;
uint32_t data;
uint32_t ctrl;
} icd2061_t;
#ifdef ENABLE_ICD2061_LOG
int icd2061_do_log = ENABLE_ICD2061_LOG;
@@ -155,14 +144,12 @@ icd2061_getclock(int clock, void *priv)
}
void
icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock)
icd2061_set_ref_clock(void *priv, float ref_clock)
{
icd2061_t *icd2061 = (icd2061_t *) priv;
if (icd2061)
if (icd2061 != NULL)
icd2061->ref_clock = ref_clock;
svga_recalctimings(svga);
}
static void *

View File

@@ -101,7 +101,7 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
case 0x03:
case 0x03: /* Palette Read Index Register (RS value = 0011) */
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
svga->dac_pos = 0;
svga->dac_status = addr & 0x03;
@@ -362,14 +362,21 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga)
void
bt48x_recalctimings(void *priv, svga_t *svga)
{
const bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv;
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv;
svga->interlace = ramdac->cmd_r2 & 0x08;
if (ramdac->cmd_r3 & 0x08) {
svga->hdisp <<= 1; /* x2 clock multiplier */
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
svga->interlace = !!(ramdac->cmd_r2 & 0x08);
svga->clock_multiplier = 0;
svga->multiplexing_rate = 0;
svga->true_color_bypass = 0;
if (ramdac->cmd_r3 & 0x08) { /* x2 clock multiplier */
//pclog("2x multiplier.\n");
svga->clock_multiplier = 1;
}
svga->multiplexing_rate = (ramdac->cmd_r1 & 0x60) >> 5;
if (svga->bpp >= 15)
svga->true_color_bypass = !!(ramdac->cmd_r1 & 0x10);
//pclog("CR0=%02x, CR1=%02x, CR2=%02x.\n", ramdac->cmd_r0, ramdac->cmd_r1, ramdac->cmd_r2);
}
void

View File

@@ -44,6 +44,7 @@ static void
sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga)
{
int oldbpp = svga->bpp;
//pclog("BPP Val=%02x, truecolortype=%02x.\n", ramdac->ctrl, ramdac->regs[0x10] & 0x01);
if (ramdac->ctrl & 0x80) {
if (ramdac->ctrl & 0x40) {
svga->bpp = 16;
@@ -60,6 +61,7 @@ sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga)
} else
svga->bpp = 8;
}
//pclog("SVGA BPP=%d.\n", svga->bpp);
if (oldbpp != svga->bpp)
svga_recalctimings(svga);
}
@@ -135,9 +137,11 @@ sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
//pclog("RS=%02x, Write=%02x.\n", rs, val);
switch (rs) {
case 0x00:
if (ramdac->ctrl & 0x10) {
//pclog("RAMDAC IDX=%02x, Write=%02x.\n", ramdac->idx, val);
switch (ramdac->idx) {
case 8:
ramdac->regs[8] = val;

View File

@@ -2845,6 +2845,8 @@ et4000w32p_init(const device_t *info)
et4000->svga.ramdac = device_add(&stg_ramdac_device);
et4000->svga.clock_gen = device_add(&icd2061_device);
et4000->svga.getclock = icd2061_getclock;
icd2061_set_ref_clock(et4000->svga.ramdac, 14318184.0f);
svga_recalctimings(&et4000->svga);
break;
default:

View File

@@ -16,6 +16,7 @@
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
@@ -3000,6 +3001,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
if (svga->getclock == icd2061_getclock) {
if (((val >> 2) & 3) != 3)
icd2061_write(svga->clock_gen, (val >> 2) & 3);
else
icd2061_write(svga->clock_gen, svga->crtc[0x42] & 0x0f);
}
break;
@@ -3026,7 +3029,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
}
if (svga->seqaddr == 4) /*Chain-4 - update banking*/
{
if (val & 0x08)
svga->chain2_write = !(val & 4);
svga->chain4 = (svga->chain4 & ~8) | (val & 8);
if (svga->chain4)
svga->write_bank = svga->read_bank = s3->bank << 16;
else
svga->write_bank = svga->read_bank = s3->bank << 14;
@@ -3212,7 +3217,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16);
if ((s3->chip >= S3_TRIO32) && (svga->bpp == 32))
svga->hwcursor.x <<= 1;
else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && ((svga->bpp == 15) || (svga->bpp == 16))) {
else if ((s3->chip >= S3_86C928) && (s3->chip <= S3_86C805) && ((svga->bpp == 15) || (svga->bpp == 16))) {
if ((s3->card_type == S3_MIROCRYSTAL10SD_805) && !(svga->crtc[0x45] & 0x04) && (svga->bpp == 16))
svga->hwcursor.x >>= 2;
else
@@ -3787,7 +3792,6 @@ s3_recalctimings(svga_t *svga)
case 0xc0:
s3->width = 1280;
break;
default:
break;
}
@@ -3823,112 +3827,51 @@ s3_recalctimings(svga_t *svga)
if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) {
s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, "
"attr=%02x, hdisp=%d.\n", svga->bpp, s3->width, svga->crtc[0x50],
svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4,
svga->attrregs[0x10] & 0x40, svga->hdisp);
"attr=%02x, hdisp=%d, dotsperclock=%x, clksel=%x, clockmultiplier=%d, multiplexingrate=%d.\n", svga->bpp, s3->width, svga->crtc[0x50],
svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 0x04,
svga->attrregs[0x10] & 0x40, svga->hdisp, svga->dots_per_clock, clk_sel, svga->clock_multiplier, svga->multiplexing_rate);
switch (svga->bpp) {
case 8:
svga->render = svga_render_8bpp_highres;
switch (s3->chip) {
case S3_86C928:
switch (s3->card_type) {
case S3_METHEUS_86C928:
s3_log("928 8bpp: ClockSel=%02x, width=%d, hdisp=%d, dotsperclock=%d.\n", clk_sel, s3->width, svga->hdisp, svga->dots_per_clock);
switch (s3->width) {
case 1280: /*Account for the 1280x1024 resolution*/
switch (svga->hdisp) {
case 320:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 640:
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case BT48X: /*BT485 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) {
if (svga->multiplexing_rate == 2) {
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
} else {
if (!svga->clock_multiplier) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
}
}
break;
case 2048: /*Account for the 1280x1024 resolution*/
switch (svga->hdisp) {
case 320:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 640:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
svga->clock *= 2.0;
} else {
if (svga->multiplexing_rate == 0) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
break;
default:
break;
}
break;
case S3_ELSAWIN1K_86C928:
case S3_ELSAWIN2K_86C928:
switch (s3->width) {
case 1024:
switch (svga->hdisp) {
case 256:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 512:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
}
} else if (svga->getclock == ics2494_getclock) { /*ICS2494 clock chip*/
if (svga->clock_multiplier == 1) {
if (svga->multiplexing_rate == 2) {
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
}
break;
case 1280: /*Account for the 1280x1024 resolution*/
switch (svga->hdisp) {
case 320:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 640:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
svga->clock *= 2.0;
} else {
if (svga->multiplexing_rate == 2) {
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
svga->clock *= 4.0;
}
break;
case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/
switch (svga->hdisp) {
case 320:
case 384:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 576:
case 640:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
if (s3->ramdac_type == BT48X) {
if (!svga->interlace) {
if (svga->dispend >= 1024) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
}
} else {
if (svga->dispend >= 512) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
}
}
}
break;
}
break;
default:
break;
}
}
break;
default:
@@ -3936,72 +3879,8 @@ s3_recalctimings(svga_t *svga)
}
break;
case S3_86C928PCI:
switch (s3->card_type) {
case S3_ELSAWIN1KPCI_86C928:
switch (s3->width) {
case 1024:
switch (svga->hdisp) {
case 256:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 512:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
}
break;
case 1280: /*Account for the 1280x1024 resolution*/
switch (svga->hdisp) {
case 320:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 640:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
}
break;
case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/
switch (svga->hdisp) {
case 320:
case 384:
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
break;
case 576:
case 640:
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
}
break;
default:
break;
}
break;
case S3_SPEA_MERCURY_LITE_PCI:
switch (s3->width) {
case 640:
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
}
break;
default:
break;
}
if (!svga->chain4)
svga->chain4 |= 0x08;
break;
case S3_VISION964:
switch (s3->card_type) {
@@ -4126,69 +4005,82 @@ s3_recalctimings(svga_t *svga)
}
break;
case S3_86C928:
switch (s3->card_type) {
case S3_METHEUS_86C928:
if (!s3->color_16bit) {
s3_log("928 15bpp: ClockSel=%02x, width=%d, hdisp=%d, dotsperclock=%d.\n", clk_sel, s3->width, svga->hdisp, svga->dots_per_clock);
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
switch (svga->hdisp) { /*This might be a driver issue*/
case 800:
s3->width = 1024;
break;
case 1280:
s3->width = 2048;
break;
default:
break;
}
break;
case S3_ELSAWIN1K_86C928:
case S3_ELSAWIN2K_86C928:
switch (s3->width) {
case 2048:
if (s3->ramdac_type == SC1502X) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
} else {
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case BT48X: /*BT485 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) {
if (svga->multiplexing_rate == 1) {
if (svga->true_color_bypass) {
if (svga->crtc[0x31] & 0x02) {
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
} else {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
}
svga->clock *= 2.0;
} else {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
if (!svga->clock_multiplier)
svga->clock *= 2.0;
}
}
} else {
if (svga->multiplexing_rate == 1) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
break;
default:
if (s3->ramdac_type == BT48X)
svga->clock /= 2.0;
else if (s3->ramdac_type == SC1502X) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
}
break;
}
} else if (svga->getclock == ics2494_getclock) { /*ICS2494 clock chip*/
if (svga->multiplexing_rate == 1) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
}
break;
case SC1502X: /*SC15025 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->clock *= 2.0;
} else {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
}
}
break;
default:
break;
}
break;
case S3_86C928PCI:
switch (s3->card_type) {
case S3_ELSAWIN1KPCI_86C928:
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_SPEA_MERCURY_LITE_PCI:
switch (s3->width) {
case 640:
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case SC1502X: /*SC15025 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->clock *= 2.0;
} else {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
}
} else if (svga->getclock == av9194_getclock) { /*AV9194 clock chip*/
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->clock *= 2.0;
} else {
if (s3->width == 640)
svga->hdisp >>= 1;
}
}
break;
default:
break;
}
@@ -4350,67 +4242,82 @@ s3_recalctimings(svga_t *svga)
}
break;
case S3_86C928:
switch (s3->card_type) {
case S3_METHEUS_86C928:
s3_log("928 16bpp: ClockSel=%02x, width=%d, hdisp=%d, dotsperclock=%d.\n", clk_sel, s3->width, svga->hdisp, svga->dots_per_clock);
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
switch (svga->hdisp) { /*This might be a driver issue*/
case 800:
s3->width = 1024;
break;
case 1280:
s3->width = 2048;
break;
default:
break;
}
break;
case S3_ELSAWIN1K_86C928:
case S3_ELSAWIN2K_86C928:
switch (s3->width) {
case 2048:
if (s3->ramdac_type == SC1502X) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
} else {
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case BT48X: /*BT485 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) {
if (svga->multiplexing_rate == 1) {
if (svga->true_color_bypass) {
if (svga->crtc[0x31] & 0x02) {
svga->hdisp <<= 2;
svga->dots_per_clock <<= 2;
} else {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
}
svga->clock *= 2.0;
} else {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
if (!svga->clock_multiplier)
svga->clock *= 2.0;
}
}
} else {
if (svga->multiplexing_rate == 1) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
break;
default:
if (s3->ramdac_type == BT48X)
svga->clock /= 2.0;
else if (s3->ramdac_type == SC1502X) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
}
break;
}
} else if (svga->getclock == ics2494_getclock) { /*ICS2494 clock chip*/
if (svga->multiplexing_rate == 1) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
}
break;
case SC1502X: /*SC15025 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->clock *= 2.0;
} else {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
}
}
break;
default:
break;
}
break;
case S3_86C928PCI:
switch (s3->card_type) {
case S3_ELSAWIN1KPCI_86C928:
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
break;
case S3_SPEA_MERCURY_LITE_PCI:
switch (s3->width) {
case 640:
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case SC1502X: /*SC15025 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->clock *= 2.0;
} else {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
break;
default:
break;
}
} else if (svga->getclock == av9194_getclock) { /*AV9194 clock chip*/
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->clock *= 2.0;
} else {
if (s3->width == 640)
svga->hdisp >>= 1;
}
}
break;
default:
break;
}
@@ -4561,8 +4468,22 @@ s3_recalctimings(svga_t *svga)
break;
}
break;
case S3_86C928PCI:
case S3_86C928: /*Technically the 928 cards don't support 24bpp.*/
if (!svga->chain4)
svga->chain4 |= 0x08;
break;
case S3_86C928PCI: /*Technically the 928 cards don't support 24bpp.*/
switch (s3->card_type) {
case S3_ELSAWIN1KPCI_86C928:
if (svga->dots_per_clock == 16) {
svga->dots_per_clock >>= 1;
svga->hdisp = (svga->hdisp << 1) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
svga->clock /= (2.0 / 3.0);
if (svga->hdisp == 640)
s3->width = 640;
}
break;
case S3_SPEA_MERCURY_LITE_PCI:
svga->hdisp = (svga->hdisp << 1) / 3;
svga->dots_per_clock = (svga->dots_per_clock << 1) / 3;
@@ -4602,22 +4523,54 @@ s3_recalctimings(svga_t *svga)
svga->render = svga_render_32bpp_highres;
switch (s3->chip) {
case S3_86C928:
switch (s3->card_type) {
case S3_ELSAWIN1K_86C928:
svga->hdisp >>= 2;
svga->dots_per_clock >>= 2;
svga->clock *= 2.0;
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case BT48X: /*BT485 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) {
if (svga->true_color_bypass) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
}
if (svga->hdisp == 800)
s3->width = 1024;
}
break;
case SC1502X: /*SC15025 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if (svga->crtc[0x31] & 0x02) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
if (svga->hdisp == 640)
s3->width = 1024;
} else {
svga->hdisp >>= 2;
svga->dots_per_clock >>= 2;
if (svga->hdisp == 800)
s3->width = 1024;
}
}
break;
default:
break;
}
break;
case S3_86C928PCI:
switch (s3->card_type) {
case S3_ELSAWIN1KPCI_86C928:
svga->hdisp >>= 2;
svga->dots_per_clock >>= 2;
svga->clock *= 2.0;
if (!svga->chain4)
svga->chain4 |= 0x08;
switch (s3->ramdac_type) {
case SC1502X: /*SC15025 RAMDAC*/
if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/
if (!(svga->crtc[0x31] & 0x02)) {
svga->hdisp >>= 2;
svga->dots_per_clock >>= 2;
if (s3->width >= 800)
svga->clock *= 2.0;
}
}
break;
default:
break;
@@ -10792,7 +10745,8 @@ s3_init(const device_t *info)
/* DCS2824-0 = Diamond ICD2061A-compatible. */
svga->clock_gen = device_add(&icd2061_device);
svga->getclock = icd2061_getclock;
icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f);
icd2061_set_ref_clock(svga->ramdac, 14318184.0f);
svga_recalctimings(svga);
}
break;
@@ -10890,7 +10844,8 @@ s3_init(const device_t *info)
svga->clock_gen = device_add(&icd2061_device);
svga->getclock = icd2061_getclock;
s3->elsa_eeprom = 1;
icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f);
icd2061_set_ref_clock(svga->ramdac, 28322000.0f);
svga_recalctimings(svga);
break;
case S3_ELSAWIN2K_86C928:
@@ -10906,7 +10861,8 @@ s3_init(const device_t *info)
svga->clock_gen = device_add(&ics9161_device);
svga->getclock = ics9161_getclock;
s3->elsa_eeprom = 1;
icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f);
icd2061_set_ref_clock(svga->ramdac, 28322000.0f);
svga_recalctimings(svga);
break;
case S3_METHEUS_86C928:
@@ -10936,7 +10892,8 @@ s3_init(const device_t *info)
svga->clock_gen = device_add(&icd2061_device);
svga->getclock = icd2061_getclock;
s3->elsa_eeprom = 1;
icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f);
icd2061_set_ref_clock(svga->ramdac, 28322000.0f);
svga_recalctimings(svga);
break;
case S3_SPEA_MERCURY_LITE_PCI:
@@ -10996,7 +10953,8 @@ s3_init(const device_t *info)
s3->ramdac_type = BT48X;
svga->clock_gen = device_add(&icd2061_device);
svga->getclock = icd2061_getclock;
icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f);
icd2061_set_ref_clock(svga->ramdac, 14318184.0f);
svga_recalctimings(svga);
break;
}
break;
@@ -11075,7 +11033,8 @@ s3_init(const device_t *info)
s3->ramdac_type = ATT498;
svga->clock_gen = device_add(&icd2061_device);
svga->getclock = icd2061_getclock;
icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f);
icd2061_set_ref_clock(svga->ramdac, 14318184.0f);
svga_recalctimings(svga);
} else {
svga->ramdac = device_add(&sdac_ramdac_device);
s3->ramdac_type = S3_SDAC;