S3 changes of the day (December 25th 2024, Christmas 2024 gift)

1. Initialize Multifunction indexes 0x0D and 0x0E properly, should fix inverted colors on S3 OS/2 Warp drivers.
2. Make the remaining Vision868/968 only ports handle the 32-bit toggling properly.
3. Cleanups
This commit is contained in:
TC1995
2024-12-25 19:47:23 +01:00
parent e8cb5dc0fe
commit 4c9fb63c74

View File

@@ -1461,17 +1461,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
case 0xe548:
case 0xe6e8:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val;
} else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val;
break;
case 0xe549:
case 0xe6e9:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
} else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
@@ -1495,6 +1502,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
@@ -1516,17 +1524,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
case 0xed48:
case 0xeee8:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val;
} else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val;
break;
case 0xed49:
case 0xeee9:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
} else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
@@ -1550,6 +1565,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
@@ -2759,18 +2775,18 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
} else if (svga->seqaddr == 9) {
svga->seqregs[svga->seqaddr] = val & 0x80;
svga->seqregs[9] = val & 0x80;
s3_io_set(s3);
return;
} else if (svga->seqaddr == 0xa) {
svga->seqregs[svga->seqaddr] = val & 0x80;
svga->seqregs[0xa] = val & 0x80;
return;
} else if (s3->chip >= S3_VISION964) {
if (svga->seqaddr == 0x08) {
svga->seqregs[svga->seqaddr] = val & 0x0f;
if (svga->seqaddr == 8) {
svga->seqregs[8] = val & 0x0f;
return;
} else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) {
svga->seqregs[svga->seqaddr] = val;
} else if ((svga->seqaddr == 0xd) && (svga->seqregs[8] == 0x06)) {
svga->seqregs[0xd] = val;
svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20));
svga_recalctimings(svga);
return;
@@ -3162,7 +3178,7 @@ s3_in(uint16_t addr, void *priv)
case 0x51:
return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3);
case 0x5c: /* General Output Port Register */
temp = svga->crtc[svga->crtcreg] & 0xa0;
temp = svga->crtc[0x5c] & 0xa0;
if (((svga->miscout >> 2) & 3) == 3)
temp |= svga->crtc[0x42] & 0x0f;
else
@@ -3183,20 +3199,19 @@ s3_in(uint16_t addr, void *priv)
case 0x6b:
s3_log("[%04X:%08X]: Read CRTC6b=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]);
if (s3->chip != S3_TRIO64V2) {
if (svga->crtc[0x53] & 0x08) {
if (svga->crtc[0x53] & 0x08)
return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe);
} else {
else
return svga->crtc[0x59];
}
} else
return svga->crtc[0x6b];
break;
case 0x6c:
s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6c]);
if (s3->chip != S3_TRIO64V2) {
if (svga->crtc[0x53] & 0x08) {
if (svga->crtc[0x53] & 0x08)
return 0x00;
} else
else
return (svga->crtc[0x5a] & 0x80);
} else
return svga->crtc[0x6c];
@@ -4305,6 +4320,7 @@ s3_recalctimings(svga_t *svga)
svga->vram_display_mask = s3->vram_mask;
} else {
svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask;
s3_log("CRTC31 bit 0=%x, CRTC32 bit 6=%02x.\n", (svga->crtc[0x31] & 0x01), svga->crtc[0x32] & 0x40);
if (!(svga->crtc[0x31] & 0x01)) { /*Bank Enable bit*/
svga->write_bank = 0;
svga->read_bank = 0;
@@ -4625,6 +4641,7 @@ s3_updatemapping(s3_t *s3)
}
/* Memory mapped I/O. */
s3_log("CRTC53=%02x, SEQREG9=%02x.\n", svga->crtc[0x53] & 0x18, svga->seqregs[9] & 0x80);
if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) {
mem_mapping_disable(&svga->mapping);
if (s3->chip >= S3_TRIO64V) {
@@ -4644,8 +4661,7 @@ s3_updatemapping(s3_t *s3)
mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000);
else
mem_mapping_disable(&s3->new_mmio_mapping);
}
else
} else
mem_mapping_disable(&s3->new_mmio_mapping);
}
}
@@ -5501,21 +5517,27 @@ s3_accel_in(uint16_t port, void *priv)
case 0xd2e8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.ropmix & 0xff;
case 0xd149:
case 0xd2e9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.ropmix >> 8;
case 0xe548:
case 0xe6e8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 16;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 16;
else
temp2 = s3->accel.pat_bg_color & 0xff;
} else
temp2 = s3->accel.pat_bg_color & 0xff;
return temp2;
@@ -5524,37 +5546,53 @@ s3_accel_in(uint16_t port, void *priv)
case 0xe6e9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 24;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 24;
else
temp2 = s3->accel.pat_bg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
} else
temp2 = s3->accel.pat_bg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xe54a:
case 0xe6ea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color & 0xff;
else
temp2 = s3->accel.pat_bg_color >> 16;
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_bg_color >> 16;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_bg_color & 0xff;
else
temp2 = s3->accel.pat_bg_color >> 16;
}
return temp2;
case 0xe54b:
case 0xe6eb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 8;
else
temp2 = s3->accel.pat_bg_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_bg_color >> 24;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_bg_color >> 8;
else
temp2 = s3->accel.pat_bg_color >> 24;
s3->accel.multifunc[0xe] ^= 0x10;
}
return temp2;
case 0xe948:
@@ -5585,9 +5623,13 @@ s3_accel_in(uint16_t port, void *priv)
case 0xeee8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 16;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 16;
else
temp2 = s3->accel.pat_fg_color & 0xff;
} else
temp2 = s3->accel.pat_fg_color & 0xff;
return temp2;
@@ -5596,37 +5638,53 @@ s3_accel_in(uint16_t port, void *priv)
case 0xeee9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 24;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 24;
else
temp2 = s3->accel.pat_fg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
} else
temp2 = s3->accel.pat_fg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xed4a:
case 0xeeea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color & 0xff;
else
temp2 = s3->accel.pat_fg_color >> 16;
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_fg_color >> 16;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_fg_color & 0xff;
else
temp2 = s3->accel.pat_fg_color >> 16;
}
return temp2;
case 0xed4b:
case 0xeeeb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 8;
else
temp2 = s3->accel.pat_fg_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_fg_color >> 24;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_fg_color >> 8;
else
temp2 = s3->accel.pat_fg_color >> 24;
s3->accel.multifunc[0xe] ^= 0x10;
}
return temp2;
case 0xe148:
@@ -7916,8 +7974,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
/*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled.
When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on
the NOP command)*/
if (s3->accel.cmd == 0x41b3 || (cmd == 6))
s3_log("CMD=%d, full=%04x, s3bpp=%x, multifuncE=%03x, sourcedisplay=%x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, svgabpp=%d.\n", cmd, s3->accel.cmd, s3->bpp, s3->accel.multifunc[0x0e], vram_mask, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, svga->bpp);
s3_log("CMD=%d, full=%04x, s3bpp=%x, multifuncE=%03x, sourcedisplay=%x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, svgabpp=%d.\n", cmd, s3->accel.cmd, s3->bpp, s3->accel.multifunc[0x0e], vram_mask, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, svga->bpp);
switch (cmd) {
case 0: /*NOP (Short Stroke Vectors)*/
@@ -8671,7 +8728,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
}
break;
case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/
case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/
if (!cpu_input) /*!cpu_input is trigger to start operation*/
{
s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff;
@@ -8693,12 +8750,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width);
}
if ((s3->accel.cmd & 0x100) && !cpu_input) {
if ((s3->accel.cmd & 0x100) && !cpu_input)
return; /*Wait for data from CPU*/
}
while (count-- && s3->accel.sy >= 0) {
if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && (s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b) {
while (count-- && (s3->accel.sy >= 0)) {
if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) {
if (vram_mask) {
READ(s3->accel.src + s3->accel.cx, mix_dat);
mix_dat = ((mix_dat & rd_mask) == rd_mask);
@@ -8706,10 +8762,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
}
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = s3->accel.bkgd_color;
src_dat = bkgd_color;
break;
case 1:
src_dat = s3->accel.frgd_color;
src_dat = frgd_color;
break;
case 2:
src_dat = cpu_dat;
@@ -8784,15 +8840,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3->accel.dy--;
}
s3->accel.dy &= 0xfff;
s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width);
s3->accel.dest = dstbase + s3->accel.dy * s3->width;
s3->accel.sy--;
if (cpu_input) {
if (cpu_input)
return;
}
if (s3->accel.sy < 0) {
s3->accel.destx_distp = s3->accel.dx;
s3->accel.desty_axstp = s3->accel.dy;
@@ -10230,6 +10285,8 @@ s3_init(const device_t *info)
s3->i2c = i2c_gpio_init("ddc_s3");
s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c));
s3->accel.multifunc[0xd] = 0xd000;
s3->accel.multifunc[0xe] = 0xe000;
s3->wake_fifo_thread = thread_create_event();
s3->fifo_not_full_event = thread_create_event();