Corrections to displays (October 18th, 2025) (rebase)

1. In the STG code, separated the STG1703 without its built-in clock as 1702 while keeping the one with the clock as 1703.
2. Added the ICS2494AN-324 clock generator used by the et4000w32 series.
3. Return 0x98 as the ID of the ATT498 ramdac.
4. Corrected the pixel clocks of the IBM RGB528 while keeping its current compatibility and exactness of the refresh rates of its clocks.
5. Added a variable reference clock of the SDAC/GenDAC for future use.
6. The clocks of the TVP3026 have been implemented for a while. Some corrections have been made (plus color key r/w).
7. Mach64 enhanced mode doesn't use scrollcache (bits 0-3 of attrregs 0x13), fixes some pixels being off (mainly in win3.1x)
8. Reorganized the cirrus 54xx built-in clock for proper refresh rates.
9. Proper reorganization of the et4000w32 series of chipsets and their cards supporting them, from cursor to clocks to ramdacs plus a 24bpp acceleration fix for the w32p series (about pixels being processed in bitblt).
10. Removed the PCI videomagic card as its bios doesn't have the PCIR header while making sure the plain ISA/VLB w32 and ISA only w32i (now named Axis Microdevice) support 2mb of vram properly.
11.  Added the Hercules Dynamite VL Pro based on the w32i chip (and VLB).
12. Initialize the et4000w32 cards with misc bit 0 set as well as crtc31 bit 6 for rs2 connection to the ramdac.
13. Refactored the S3 Pre-ViRGE code to have proper refresh rates and clocks and added the 805I as a member of the chips (ID 0xa8).
14. Replaced the S3 805I Elsa Winner 1000 ISA bios with a more supported one for our code using the SDAC.
15. Added proper 24bpp acceleration to the Visionx68 chips.
16. Fixed wrong colors in the 911/924 15/16bpp acceleration when used for the first time.
17. Match the ViRGE mapping to the pre-ViRGE one per manual/datasheet.
18. Correct as best as possible the TGUI9400 clocks.
This commit is contained in:
TC1995
2025-10-18 03:09:34 +02:00
parent a8b4aa0602
commit f7a3ca4ccd
16 changed files with 2072 additions and 934 deletions

View File

@@ -474,6 +474,7 @@ extern uint8_t sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t
extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga);
extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
extern float sdac_getclock(int clock, void *priv);
extern void sdac_set_ref_clock(void *priv, float ref_clock);
extern void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga);
extern uint8_t stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga);
@@ -507,6 +508,7 @@ extern const device_t bt485a_ramdac_device;
extern const device_t gendac_ramdac_device;
extern const device_t ibm_rgb528_ramdac_device;
extern const device_t ics2494an_305_device;
extern const device_t ics2494an_324_device;
extern const device_t ati18810_28800_device;
extern const device_t ati18811_0_28800_device;
extern const device_t ati18811_1_28800_device;
@@ -523,7 +525,8 @@ extern const device_t sc11484_nors2_ramdac_device;
extern const device_t sc1502x_ramdac_device;
extern const device_t sc1502x_rs2_ramdac_device;
extern const device_t sdac_ramdac_device;
extern const device_t stg_ramdac_device;
extern const device_t stg1702_ramdac_device;
extern const device_t stg1703_ramdac_device;
extern const device_t tkd8001_ramdac_device;
extern const device_t tseng_ics5301_ramdac_device;
extern const device_t tseng_ics5341_ramdac_device;

View File

@@ -436,20 +436,20 @@ extern const device_t et4000_kasan_isa_device;
extern const device_t et4000_mca_device;
/* Tseng ET4000-W32x */
extern const device_t et4000w32_device;
extern const device_t et4000w32_machspeed_vga_gui_2400s_isa_device;
extern const device_t et4000w32_machspeed_vga_gui_2400s_vlb_device;
extern const device_t et4000w32_onboard_device;
extern const device_t et4000w32i_isa_device;
extern const device_t et4000w32i_vlb_device;
extern const device_t et4000w32i_axis_microdevice_isa_device;
extern const device_t et4000w32i_hercules_dynamite_pro_vlb_device;
extern const device_t et4000w32p_videomagic_revb_vlb_device;
extern const device_t et4000w32p_videomagic_revb_pci_device;
extern const device_t et4000w32p_revc_vlb_device;
extern const device_t et4000w32p_revc_pci_device;
extern const device_t et4000w32p_vlb_device;
extern const device_t et4000w32p_pci_device;
extern const device_t et4000w32p_noncardex_vlb_device;
extern const device_t et4000w32p_noncardex_pci_device;
extern const device_t et4000w32p_cardex_vlb_device;
extern const device_t et4000w32p_cardex_pci_device;
extern const device_t et4000w32p_cardex_revc_vlb_device;
extern const device_t et4000w32p_cardex_revc_pci_device;
extern const device_t et4000w32p_cardex_revd_vlb_device;
extern const device_t et4000w32p_cardex_revd_pci_device;
extern const device_t et4000w32p_diamond_revd_vlb_device;
extern const device_t et4000w32p_diamond_revd_pci_device;
extern const device_t et4000w32p_generic_revd_vlb_device;
extern const device_t et4000w32p_generic_revd_pci_device;
/* MDSI Genius VHR */
extern const device_t genius_device;

View File

@@ -290,7 +290,7 @@ ics2494_init(const device_t *info)
ics2494->freq[15] = 65000000.0;
break;
case 305:
/* ICS2494A(N)-205 for S3 86C924 */
/* ICS2494A(N)-305 for S3 86C924 */
ics2494->freq[0x0] = 25175000.0;
ics2494->freq[0x1] = 28322000.0;
ics2494->freq[0x2] = 40000000.0;
@@ -308,6 +308,25 @@ ics2494_init(const device_t *info)
ics2494->freq[0xe] = 75000000.0;
ics2494->freq[0xf] = 94500000.0;
break;
case 324:
/* ICS2494A(N)-324 for Tseng ET4000/W32 series */
ics2494->freq[0x0] = 50000000.0;
ics2494->freq[0x1] = 56644000.0;
ics2494->freq[0x2] = 65000000.0;
ics2494->freq[0x3] = 72000000.0;
ics2494->freq[0x4] = 80000000.0;
ics2494->freq[0x5] = 89800000.0;
ics2494->freq[0x6] = 63000000.0;
ics2494->freq[0x7] = 75000000.0;
ics2494->freq[0x8] = 83078000.0;
ics2494->freq[0x9] = 93463000.0;
ics2494->freq[0xa] = 100000000.0;
ics2494->freq[0xb] = 104000000.0;
ics2494->freq[0xc] = 108000000.0;
ics2494->freq[0xd] = 120000000.0;
ics2494->freq[0xe] = 130000000.0;
ics2494->freq[0xf] = 134700000.0;
break;
default:
break;
@@ -339,6 +358,20 @@ const device_t ics2494an_305_device = {
.config = NULL
};
const device_t ics2494an_324_device = {
.name = "ICS2494AN-324 Clock Generator",
.internal_name = "ics2494an_324",
.flags = 0,
.local = 324,
.init = ics2494_init,
.close = ics2494_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ati18810_28800_device = {
.name = "ATI 18810 (ATI 28800) Clock Generator",
.internal_name = "ati18810_28800",

View File

@@ -42,12 +42,6 @@ att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga)
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv;
ramdac->ctrl = val;
switch ((ramdac->ctrl >> 5) & 7) {
case 0:
case 1:
case 2:
case 3:
svga->bpp = 8;
break;
case 4:
case 5:
svga->bpp = 15;
@@ -60,10 +54,12 @@ att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga)
break;
default:
svga->bpp = 8;
break;
}
if (ramdac->type == ATT_490 || ramdac->type == ATT_491)
svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
svga_recalctimings(svga);
}

View File

@@ -45,7 +45,7 @@ att498_ramdac_control(uint8_t val, void *priv, svga_t *svga)
svga->bpp = 8;
break;
case 1:
if (ramdac->ctrl & 4)
if (ramdac->ctrl & 0x04)
svga->bpp = 15;
else
svga->bpp = 8;
@@ -63,7 +63,7 @@ att498_ramdac_control(uint8_t val, void *priv, svga_t *svga)
break;
}
svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
svga_set_ramdac_type(svga, (ramdac->ctrl & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT);
svga_recalctimings(svga);
}
@@ -132,7 +132,7 @@ att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
ramdac->state++;
break;
case 6:
temp = ramdac->ctrl;
temp = 0x98;
ramdac->state = 0;
break;
default:

View File

@@ -366,15 +366,14 @@ bt48x_recalctimings(void *priv, svga_t *svga)
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");
if (ramdac->cmd_r3 & 0x08) /* x2 clock multiplier */
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);
pclog("CR0=%02x, CR1=%02x, CR2=%02x.\n", ramdac->cmd_r0, ramdac->cmd_r1, ramdac->cmd_r2);
}
void

View File

@@ -49,6 +49,7 @@ typedef struct sdac_ramdac_t {
int rs2;
uint8_t type;
uint8_t command;
float ref_clock;
} sdac_ramdac_t;
static void
@@ -275,11 +276,21 @@ sdac_getclock(int clock, void *priv)
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2;
n2 = ((ramdac->regs[clock] >> 13) & 0x07);
n2 = (1 << n2);
t = (14318184.0f * (float) m) / (float) (n1 * n2);
t = (ramdac->ref_clock * (float) m) / (float) (n1 * n2);
//pclog("SDACClock=%d, regs val=%04x.\n", clock, ramdac->regs[clock]);
return t;
}
void
sdac_set_ref_clock(void *priv, float ref_clock)
{
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv;
if (ramdac != NULL)
ramdac->ref_clock = ref_clock;
}
void *
sdac_ramdac_init(const device_t *info)
{
@@ -288,6 +299,7 @@ sdac_ramdac_init(const device_t *info)
ramdac->type = info->local;
ramdac->ref_clock = 14318184.0f;
ramdac->regs[0] = 0x6128;
ramdac->regs[1] = 0x623d;

View File

@@ -31,6 +31,7 @@ typedef struct stg_ramdac_t {
int magic_count, index;
uint8_t regs[256];
uint8_t command;
int type;
} stg_ramdac_t;
static int stg_state_read[2][8] = {
@@ -46,6 +47,8 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac)
switch (ramdac->regs[3]) {
default:
case 0:
svga->bpp = 8;
break;
case 5:
case 7:
svga->bpp = 8;
@@ -176,7 +179,7 @@ stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
temp = 0x44;
break;
case 1:
temp = 0x03;
temp = ramdac->type;
break;
case 7:
temp = 0x88;
@@ -216,22 +219,24 @@ stg_getclock(int clock, void *priv)
float t;
int m;
int n;
int n2;
const uint16_t *c;
int d;
int d2;
uint16_t c;
if (clock == 0)
return 25175000.0;
if (clock == 1)
return 28322000.0;
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)];
m = (*c & 0xff) + 2; /* B+2 */
n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */
n2 = ((*c >> 13) & 0x07); /* D */
n2 = (1 << n2);
t = (14318184.0f * (float) m) / (float) (n * n2);
c = ramdac->regs[0x20 + (clock << 1)];
c |= (ramdac->regs[0x21 + (clock << 1)] << 8);
m = (c & 0xff) + 2; /* B+2 */
n = ((c >> 8) & 0x1f) + 2; /* N1+2 */
d = ((c >> 13) & 0x07); /* D */
d2 = (1 << d);
t = (14318184.0f * (float) m) / (float) (n * d2);
//pclog("RAMDAC vclk val=0x%02x, vclk v=%d low, D=%d, t=%f.\n", ramdac->regs[0x20 + (clock << 1)], clock, d2, t);
return t;
}
@@ -241,6 +246,8 @@ stg_ramdac_init(UNUSED(const device_t *info))
stg_ramdac_t *ramdac = (stg_ramdac_t *) malloc(sizeof(stg_ramdac_t));
memset(ramdac, 0, sizeof(stg_ramdac_t));
ramdac->type = info->local & 0xff;
return ramdac;
}
@@ -253,11 +260,25 @@ stg_ramdac_close(void *priv)
free(ramdac);
}
const device_t stg_ramdac_device = {
.name = "SGS-Thompson STG170x RAMDAC",
const device_t stg1702_ramdac_device = {
.name = "SGS-Thompson STG1702 RAMDAC",
.internal_name = "stg_ramdac",
.flags = 0,
.local = 0,
.local = 2,
.init = stg_ramdac_init,
.close = stg_ramdac_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t stg1703_ramdac_device = {
.name = "SGS-Thompson STG1703 RAMDAC",
.internal_name = "stg_ramdac",
.flags = 0,
.local = 3,
.init = stg_ramdac_init,
.close = stg_ramdac_close,
.reset = NULL,

View File

@@ -9,7 +9,6 @@
* Emulation of the Texas Instruments TVP3026 true colour RAMDAC
* family.
*
* TODO: Clock and other parts.
*
* Authors: TheCollector1995,
*
@@ -49,6 +48,7 @@ typedef struct tvp3026_ramdac_t {
uint8_t mode;
uint8_t pll_addr;
uint8_t clock_sel;
uint8_t color_key_ctrl;
struct {
uint8_t m;
uint8_t n;
@@ -171,25 +171,24 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
svga->dac_hwcursor.ena = !!(val & 0x03);
ramdac->mode = val & 0x03;
//pclog("0x09: DACEna=%02x, MainEna=%02x.\n", svga->dac_hwcursor.ena, svga->hwcursor.ena);
}
break;
case 0x0a: /* Indexed Data (RS value = 1010) */
switch (ramdac->ind_idx) {
case 0x06: /* Indirect Cursor Control */
ramdac->ccr = val;
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
if (!(ramdac->ccr & 0x80)) {
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
svga->dac_hwcursor.ena = !!(val & 0x03);
ramdac->mode = val & 0x03;
} else {
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64;
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
svga->dac_hwcursor.ena = !!(ramdac->dcc & 0x03);
ramdac->mode = ramdac->dcc & 0x03;
}
//pclog("0x0a, indirect 0x06: DACEna=%02x, MainEna=%02x.\n", svga->dac_hwcursor.ena, svga->hwcursor.ena);
break;
case 0x0f: /* Latch Control */
ramdac->latch_cntl = val;
@@ -279,6 +278,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg
}
ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf);
break;
case 0x38: /* Color-Key Control */
ramdac->color_key_ctrl = val;
break;
case 0x39: /* MCLK/Loop Clock Control */
ramdac->mclk = val;
break;
@@ -470,6 +472,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga)
break;
}
break;
case 0x38: /* Color-Key Control */
temp = ramdac->color_key_ctrl;
break;
case 0x39: /* MCLK/Loop Clock Control */
temp = ramdac->mclk;
break;
@@ -516,11 +521,39 @@ tvp3026_recalctimings(void *priv, svga_t *svga)
svga->interlace = !!(ramdac->ccr & 0x40);
/* TODO: Figure out gamma correction for 15/16 bpp color. */
svga->lut_map = !!((svga->bpp >= 15 && (svga->bpp != 24)) && (ramdac->true_color & 0xf0) != 0x00);
svga->clock_multiplier = 0;
//pclog("RAMDAC CLOCKSEL=%02x, MCR=%02x, LoopMCLK=%02x, Latch=%02x.\n", ramdac->clock_sel, ramdac->mcr, ramdac->mclk, ramdac->latch_cntl);
if (!(ramdac->clock_sel & 0x70)) {
if (ramdac->mcr != 0x98) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
switch ((ramdac->clock_sel >> 4) & 7) {
case 0:
svga->clock_multiplier = 1;
break;
case 1:
svga->clock_multiplier = 2;
break;
case 2:
svga->clock_multiplier = 4;
break;
case 3:
svga->clock_multiplier = 8;
break;
case 4:
svga->clock_multiplier = 16;
break;
case 5:
svga->clock_multiplier = 32;
break;
case 6:
svga->clock_multiplier = 64;
break;
case 7:
default:
svga->clock_multiplier = 0;
break;
}
}
}
}

View File

@@ -547,6 +547,7 @@ mach64_recalctimings(svga_t *svga)
svga->rowcount = mach64->crtc_gen_cntl & 1;
svga->lut_map = (mach64->type >= MACH64_VT);
svga->rowoffset <<= 1;
svga->attrregs[0x13] &= ~0x0f;
if (mach64->type == MACH64_GX)
ati68860_ramdac_set_render(svga->ramdac, svga);

View File

@@ -1824,6 +1824,9 @@ gd54xx_recalctimings(svga_t *svga)
uint8_t clocksel;
uint8_t rdmask;
uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
uint8_t m = 0;
int d = 0;
int n = 0;
svga->hblankstart = svga->crtc[2];
@@ -1865,6 +1868,34 @@ gd54xx_recalctimings(svga_t *svga)
svga->interlace = 0;
}
clocksel = (svga->miscout >> 2) & 3;
if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel])
svga->clock = (cpuclock * (float) (1ULL << 32)) /
((svga->miscout & 0xc) ? 28322000.0 : 25175000.0);
else {
n = gd54xx->vclk_n[clocksel] & 0x7f;
d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1;
m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1;
float freq = (14318184.0F * ((float) n / ((float) d * m)));
if (gd54xx_is_5422(svga)) {
switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) {
case 2:
freq /= 2.0F;
break;
case 4:
if (!gd54xx_is_5434(svga))
freq /= 3.0F;
break;
default:
break;
}
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / freq;
}
svga->bpp = 8;
svga->map8 = svga->pallook;
if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) {
if (linedbl)
@@ -1874,6 +1905,7 @@ gd54xx_recalctimings(svga_t *svga)
if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) {
svga->hdisp <<= 1;
svga->dots_per_clock <<= 1;
svga->clock *= 2.0;
}
}
} else if (svga->gdcreg[5] & 0x40)
@@ -1881,8 +1913,6 @@ gd54xx_recalctimings(svga_t *svga)
svga->memaddr_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15);
svga->bpp = 8;
if (gd54xx->ramdac.ctrl & 0x80) {
if (gd54xx->ramdac.ctrl & 0x40) {
if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426))
@@ -2023,33 +2053,6 @@ gd54xx_recalctimings(svga_t *svga)
}
}
clocksel = (svga->miscout >> 2) & 3;
if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel])
svga->clock = (cpuclock * (float) (1ULL << 32)) /
((svga->miscout & 0xc) ? 28322000.0 : 25175000.0);
else {
int n = gd54xx->vclk_n[clocksel] & 0x7f;
int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1;
uint8_t m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1;
float freq = (14318184.0F * ((float) n / ((float) d * m)));
if (gd54xx_is_5422(svga)) {
switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) {
case 2:
freq /= 2.0F;
break;
case 4:
if (!gd54xx_is_5434(svga))
freq /= 3.0F;
break;
default:
break;
}
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / freq;
}
svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1063,32 +1063,49 @@ s3_virge_updatemapping(virge_t *virge)
return;
}
switch (svga->gdcreg[6] & 0xc) { /*Banked framebuffer*/
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
svga->banked_mask = 0xffff;
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
if (xga_active && (svga->xga != NULL)) {
xga->on = 0;
mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel);
}
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
svga->banked_mask = 0x7fff;
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
}
/*Banked framebuffer*/
if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/
{
/* Enhanced mode forces 64kb at 0xa0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
if (xga_active && (svga->xga != NULL)) {
xga->on = 0;
mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel);
}
} else
switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
svga->banked_mask = 0xffff;
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
if (xga_active && (svga->xga != NULL)) {
xga->on = 0;
mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel);
}
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
svga->banked_mask = 0x7fff;
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
default:
break;
}
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/
/*Linear framebuffer*/
mem_mapping_disable(&svga->mapping);
switch (svga->crtc[0x58] & 7) {
case 0: /*64k*/
virge->linear_size = 0x10000;
@@ -1110,11 +1127,19 @@ s3_virge_updatemapping(virge_t *virge)
break;
}
virge->linear_base &= ~(virge->linear_size - 1);
if (virge->linear_base == 0xa0000) {
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
//pclog("CR58 & 7=%x, base=%08x.\n", svga->crtc[0x58] & 7, virge->linear_base);
if ((virge->linear_base == 0xa0000) || (virge->linear_size == 0x10000)) {
mem_mapping_disable(&virge->linear_mapping);
} else
mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size);
if (!(svga->crtc[0x53] & 0x10)) {
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
}
} else {
if (virge->linear_base)
mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size);
else
mem_mapping_disable(&virge->linear_mapping);
}
svga->fb_only = 1;
} else {
mem_mapping_disable(&virge->linear_mapping);
@@ -1122,6 +1147,7 @@ s3_virge_updatemapping(virge_t *virge)
}
if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { /*Old MMIO*/
mem_mapping_disable(&svga->mapping);
if (svga->crtc[0x53] & 0x20)
mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000);
else
@@ -1129,9 +1155,12 @@ s3_virge_updatemapping(virge_t *virge)
} else
mem_mapping_disable(&virge->mmio_mapping);
if (svga->crtc[0x53] & 0x08) /*New MMIO*/
mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000);
else
if (svga->crtc[0x53] & 0x08) { /*New MMIO*/
if (virge->linear_base)
mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000);
else
mem_mapping_disable(&virge->new_mmio_mapping);
} else
mem_mapping_disable(&virge->new_mmio_mapping);
}
@@ -1946,9 +1975,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
break;
case 0x8190:
virge->streams.sec_ctrl = val;
virge->streams.dda_horiz_accumulator = val & 0x7ff;
if (val & 0x800)
virge->streams.dda_horiz_accumulator |= ~0x7ff;
virge->streams.dda_horiz_accumulator = val & 0xfff;
if (val & 0x1000)
virge->streams.dda_horiz_accumulator |= ~0xfff;
virge->streams.sdif = (val >> 24) & 7;
break;
@@ -1961,9 +1990,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
if (val & 0x800)
virge->streams.k1_horiz_scale |= ~0x7ff;
virge->streams.k2_horiz_scale = (val >> 16) & 0x3ff;
if ((val >> 16) & 0x400)
virge->streams.k2_horiz_scale |= ~0x3ff;
virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff;
if ((val >> 16) & 0x800)
virge->streams.k2_horiz_scale |= ~0x7ff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
@@ -2019,14 +2048,14 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
virge->streams.k1_vert_scale |= ~0x7ff;
break;
case 0x81e4:
virge->streams.k2_vert_scale = val & 0x3ff;
if (val & 0x400)
virge->streams.k2_vert_scale |= ~0x3ff;
virge->streams.k2_vert_scale = val & 0x7ff;
if (val & 0x800)
virge->streams.k2_vert_scale |= ~0x7ff;
break;
case 0x81e8:
virge->streams.dda_vert_accumulator = val & 0x7ff;
if (val & 0x800)
virge->streams.dda_vert_accumulator |= ~0x7ff;
virge->streams.dda_vert_accumulator = val & 0xfff;
if (val & 0x1000)
virge->streams.dda_vert_accumulator |= ~0xfff;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
@@ -3124,7 +3153,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
case 0:
case CMD_SET_MS:
READ(src_addr, source);
if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr)
if ((virge->s3d.cmd_set & CMD_SET_TP) && (source == src_fg_clr))
update = 0;
break;
case CMD_SET_IDS:
@@ -3150,7 +3179,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
count = 0;
}
}
if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr)
if ((virge->s3d.cmd_set & CMD_SET_TP) && (source == src_fg_clr))
update = 0;
break;
case CMD_SET_IDS | CMD_SET_MS:
@@ -4829,7 +4858,7 @@ s3_virge_colorkey(virge_t* virge, uint32_t x, uint32_t y)
return true;
else if (!(virge->streams.chroma_ctrl & (1 << 28)))
return true;
comp_r = (virge->streams.chroma_ctrl >> 16) & 0xFF;
comp_g = (virge->streams.chroma_ctrl >> 8) & 0xFF;
comp_b = (virge->streams.chroma_ctrl) & 0xFF;
@@ -4853,7 +4882,7 @@ s3_virge_colorkey(virge_t* virge, uint32_t x, uint32_t y)
*/
uint8_t index = virge->streams.chroma_ctrl & 0xFF;
alpha_key = (virge->chip < S3_VIRGEGX2) ? (virge->streams.chroma_ctrl & (1 << 29)) : ((virge->streams.chroma_ctrl >> 29) & 3) == 1;
if (alpha_key) {
comp_r = comp_g = comp_b = index;
comp_r_h = comp_g_h = comp_b_h = index;
@@ -5188,6 +5217,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
svga->crtc[0x59] = (svga->crtc[0x59] & 0x01) | (val & 0xfe);
else
svga->crtc[0x59] = (svga->crtc[0x59] & 0x03) | (val & 0xfc);
s3_virge_updatemapping(virge);
return;

View File

@@ -134,8 +134,8 @@ video_cards[] = {
{ .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &s3_winner1000_805_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32i_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32_machspeed_vga_gui_2400s_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32i_axis_microdevice_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
/* MCA */
{ .device = &mach32_mca_device, .flags = VIDEO_FLAG_TYPE_8514 },
{ .device = &gd5426_mca_device, .flags = VIDEO_FLAG_TYPE_NONE },
@@ -145,12 +145,13 @@ video_cards[] = {
/* VLB */
{ .device = &mach32_vlb_device, .flags = VIDEO_FLAG_TYPE_8514 },
{ .device = &mach64gx_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32i_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32_machspeed_vga_gui_2400s_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32i_hercules_dynamite_pro_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_videomagic_revb_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_revc_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_cardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_noncardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_cardex_revc_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_generic_revd_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_cardex_revd_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_diamond_revd_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5424_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5426_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5428_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE },
@@ -196,11 +197,10 @@ video_cards[] = {
{ .device = &gd5446_pci_device, .flags = VIDEO_FLAG_TYPE_SECONDARY },
{ .device = &gd5446_stb_pci_device, .flags = VIDEO_FLAG_TYPE_SECONDARY },
{ .device = &gd5480_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_videomagic_revb_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_revc_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_cardex_revc_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_generic_revd_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_cardex_revd_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000w32p_diamond_revd_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &s3_elsa_winner1000_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },

View File

@@ -692,6 +692,7 @@ tgui_recalctimings(svga_t *svga)
const tgui_t *tgui = (tgui_t *) svga->priv;
uint8_t ger22lower = (tgui->accel.ger22 & 0xff);
uint8_t ger22upper = (tgui->accel.ger22 >> 8);
int std_vga_clock = 1;
if (tgui->type >= TGUI_9440) {
if ((svga->crtc[0x38] & 0x19) == 0x09)
@@ -767,10 +768,11 @@ tgui_recalctimings(svga_t *svga)
svga->clock = (cpuclock * (double) (1ULL << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k)));
if (svga->gdcreg[0xf] & 0x08)
svga->clock *= 2;
svga->clock *= 2.0;
else if (svga->gdcreg[0xf] & 0x40)
svga->clock *= 3;
svga->clock *= 3.0;
} else {
//pclog("TGUI9400CXi: Clock double=%d.\n", (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)));
switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) {
case 0x02:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
@@ -816,6 +818,7 @@ tgui_recalctimings(svga_t *svga)
break;
default:
std_vga_clock = 0;
break;
}
@@ -823,6 +826,9 @@ tgui_recalctimings(svga_t *svga)
svga->htotal <<= 1;
svga->hdisp <<= 1;
svga->hdisp_time <<= 1;
svga->dots_per_clock <<= 1;
if (std_vga_clock)
svga->clock /= 2.0;
}
}
@@ -843,6 +849,7 @@ tgui_recalctimings(svga_t *svga)
svga->htotal <<= 1;
svga->hdisp <<= 1;
svga->hdisp_time <<= 1;
svga->dots_per_clock <<= 1;
break;
default:
break;
@@ -866,6 +873,7 @@ tgui_recalctimings(svga_t *svga)
svga->htotal <<= 1;
svga->hdisp <<= 1;
svga->hdisp_time <<= 1;
svga->dots_per_clock <<= 1;
}
switch (svga->hdisp) {
case 640:
@@ -880,18 +888,24 @@ tgui_recalctimings(svga_t *svga)
break;
case 15:
svga->render = svga_render_15bpp_highres;
if (tgui->type < TGUI_9440)
if (tgui->type < TGUI_9440) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
}
break;
case 16:
svga->render = svga_render_16bpp_highres;
if (tgui->type < TGUI_9440)
if (tgui->type < TGUI_9440) {
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
}
break;
case 24:
svga->render = svga_render_24bpp_highres;
if (tgui->type < TGUI_9440)
svga->hdisp = (svga->hdisp << 1) / 3;
if (tgui->type < TGUI_9440) {
svga->hdisp /= 3;
svga->dots_per_clock /= 3;
}
break;
case 32:
if (svga->rowoffset == 0x100)