mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 10:28:19 -07:00
S3 and 8514/A compatible fixes for various stuff.
1. Correct some more clock bugs of the ELSA Winner NeXTSTEP/OPENSTEP third party driver (please report any regressions if possible on other stuff). 2. Line Vector command with flag 0x211x (r/w) is now more usable (not perfect yet) and fill brushes now have correct colors (but also not perfect either) in Windows 2.x' 8514/a drivers.
This commit is contained in:
@@ -164,8 +164,11 @@ typedef struct ibm8514_t {
|
||||
int y_count;
|
||||
int input;
|
||||
int input2;
|
||||
int input3;
|
||||
int output;
|
||||
int output2;
|
||||
int output3;
|
||||
int init_cx;
|
||||
|
||||
int ssv_len;
|
||||
int ssv_len_back;
|
||||
|
||||
@@ -289,9 +289,9 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in
|
||||
val = (val >> 8) | (val << 8);
|
||||
}
|
||||
if ((cmd <= 2) || (cmd == 4) || (cmd == 6)) {
|
||||
if ((dev->accel.cmd & 0x08) && (cmd >= 2))
|
||||
if ((dev->accel.cmd & 0x08) && (cmd >= 1)) {
|
||||
monoxfer = val;
|
||||
else {
|
||||
} else {
|
||||
if (val & 0x02)
|
||||
nibble |= 0x80;
|
||||
if (val & 0x04)
|
||||
@@ -893,8 +893,12 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len)
|
||||
READ_HIGH(dev->accel.dest + dev->accel.cx, temp);
|
||||
}
|
||||
ibm8514_accel_out_pixtrans(svga, port, (temp >> 8) & 0xff, len);
|
||||
} else
|
||||
} else {
|
||||
if (dev->accel.input3)
|
||||
temp = 0xffff;
|
||||
|
||||
ibm8514_accel_out_pixtrans(svga, port, temp, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1393,8 +1397,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
|
||||
case 1: /*Draw line*/
|
||||
if (!cpu_input) {
|
||||
dev->accel.init_cx = 0;
|
||||
dev->accel.input3 = 0;
|
||||
dev->accel.output = 0;
|
||||
dev->accel.output3 = 0;
|
||||
dev->accel.x_count = 0;
|
||||
dev->accel.xx_count = 0;
|
||||
|
||||
dev->accel.cx = dev->accel.cur_x;
|
||||
if (dev->accel.cur_x >= 0x600)
|
||||
@@ -1406,12 +1414,20 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
|
||||
dev->accel.sy = dev->accel.maj_axis_pcnt;
|
||||
|
||||
ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x, and3=%d, sy=%d.\n",
|
||||
cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix, and3, dev->accel.sy);
|
||||
|
||||
ibm8514_log("Line Draw 8514/A CMD=%04x, frgdmix=%d, bkgdmix=%d, c(%d,%d), pixcntl=%d, sy=%d, polyfill=%x, selfrmix=%02x, selbkmix=%02x, bkgdcol=%02x, frgdcol=%02x, clipt=%d, clipb=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.multifunc[0x0a] & 6, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, bkgd_color, frgd_color, dev->accel.clip_top, clip_b);
|
||||
if (ibm8514_cpu_src(svga)) {
|
||||
if (dev->accel.cmd & 0x02) {
|
||||
if (!(dev->accel.cmd & 0x1000)) {
|
||||
if (dev->accel.cmd & 0x08)
|
||||
dev->accel.output = 1;
|
||||
if (dev->accel.cmd & 0x08) {
|
||||
if (dev->accel.cmd == 0x211b) {
|
||||
dev->accel.x_count = dev->accel.cx - (and3 + 3);
|
||||
dev->accel.sy += (and3 + 3);
|
||||
} else
|
||||
dev->accel.output = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev->force_busy = 1;
|
||||
@@ -1420,11 +1436,20 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
dev->data_available2 = 0;
|
||||
return; /*Wait for data from CPU*/
|
||||
} else if (ibm8514_cpu_dest(svga)) {
|
||||
if (dev->accel.cmd & 0x02) {
|
||||
if (!(dev->accel.cmd & 0x1000)) {
|
||||
if (dev->accel.cmd & 0x08) {
|
||||
if ((frgd_mix == 3) && (bkgd_mix == 3) && (pixcntl == 0) &&
|
||||
((dev->accel.multifunc[0x0a] & 0x06) == 0x04) && (dev->accel.frgd_mix != 0x07)) /*Kinda of a workaround for fill brushes on 8514/A using Windows 2.x*/
|
||||
dev->accel.input3 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev->force_busy = 1;
|
||||
dev->force_busy2 = 1;
|
||||
dev->data_available = 1;
|
||||
dev->data_available2 = 1;
|
||||
return;
|
||||
return; /*Wait for data from CPU*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1432,10 +1457,17 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
if (ibm8514_cpu_dest(svga) && cpu_input && (dev->accel.cmd & 0x02))
|
||||
count >>= 1;
|
||||
|
||||
if (dev->accel.cmd & 0x02)
|
||||
ibm8514_log("Line Draw Vector Single pixtrans=%04x, count=%d.\n", mix_dat, count);
|
||||
if (dev->accel.cmd == 0x211b) {
|
||||
if (and3 >= 2) {
|
||||
if (dev->accel.sy < (count << 1))
|
||||
count <<= 1;
|
||||
}
|
||||
}
|
||||
if (dev->accel.cmd & 0x1000)
|
||||
ibm8514_log("Vector Line %d: full=%04x, odd=%d, c(%d,%d), frgdmix=%d, bkgdmix=%d, xcount=%d, and3=%d, len(%d,%d), CURX=%d, Width=%d, pixcntl=%d, mix_dat=%08x, count=%d, cpu_data=%08x, cpu_input=%d.\n", cmd, dev->accel.cmd, dev->accel.input, dev->accel.cx, dev->accel.cy, frgd_mix, bkgd_mix, dev->accel.x_count, and3, dev->accel.sx, dev->accel.sy, dev->accel.cur_x, dev->accel.maj_axis_pcnt, pixcntl, mix_dat, count, cpu_dat, cpu_input);
|
||||
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
ibm8514_log("CurrentX=%d, CurrentY=%d, Count=%d.\n", dev->accel.cx, dev->accel.cy, count);
|
||||
if ((dev->accel.cx >= clip_l) &&
|
||||
(dev->accel.cx <= clip_r) &&
|
||||
(dev->accel.cy >= clip_t) &&
|
||||
@@ -1455,6 +1487,17 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
if (pixcntl == 3)
|
||||
src_dat = ((src_dat & rd_mask) == rd_mask);
|
||||
} else {
|
||||
if (dev->accel.cmd == 0x211b) {
|
||||
if (dev->accel.x_count != dev->accel.cx) {
|
||||
dev->accel.output3 = 1;
|
||||
} else {
|
||||
dev->accel.output3 = 0;
|
||||
}
|
||||
|
||||
if (dev->accel.output3 == 1)
|
||||
goto skip_vector_line_write;
|
||||
}
|
||||
|
||||
if (dev->accel.output) {
|
||||
switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) {
|
||||
case 0:
|
||||
@@ -1523,6 +1566,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
} else if (!(dev->accel.cmd & 0x04)) {
|
||||
WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat);
|
||||
}
|
||||
} else if (dev->accel.input3) {
|
||||
if ((dev->accel.cmd & 0x04) && dev->accel.sy) {
|
||||
WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat ? dest_dat : 0xff);
|
||||
} else if (!(dev->accel.cmd & 0x04)) {
|
||||
WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat ? dest_dat : 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1542,13 +1591,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->accel.output)
|
||||
mix_dat >>= 1;
|
||||
else {
|
||||
mix_dat <<= 1;
|
||||
mix_dat |= 1;
|
||||
}
|
||||
|
||||
if (dev->bpp)
|
||||
cpu_dat >>= 16;
|
||||
else
|
||||
@@ -1560,37 +1602,90 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
break;
|
||||
case 0x20:
|
||||
dev->accel.cx++;
|
||||
dev->accel.cy--;
|
||||
if (!dev->accel.output3)
|
||||
dev->accel.cy--;
|
||||
break;
|
||||
case 0x40:
|
||||
dev->accel.cy--;
|
||||
if (!dev->accel.output3)
|
||||
dev->accel.cy--;
|
||||
break;
|
||||
case 0x60:
|
||||
dev->accel.cx--;
|
||||
dev->accel.cy--;
|
||||
if (!dev->accel.output3)
|
||||
dev->accel.cy--;
|
||||
break;
|
||||
case 0x80:
|
||||
dev->accel.cx--;
|
||||
break;
|
||||
case 0xa0:
|
||||
dev->accel.cx--;
|
||||
dev->accel.cy++;
|
||||
if (!dev->accel.output3)
|
||||
dev->accel.cy++;
|
||||
break;
|
||||
case 0xc0:
|
||||
dev->accel.cy++;
|
||||
if (!dev->accel.output3)
|
||||
dev->accel.cy++;
|
||||
break;
|
||||
case 0xe0:
|
||||
dev->accel.cx++;
|
||||
dev->accel.cy++;
|
||||
if (!dev->accel.output3)
|
||||
dev->accel.cy++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
skip_vector_line_write:
|
||||
switch (dev->accel.cmd & 0xe0) {
|
||||
case 0x00:
|
||||
dev->accel.x_count++;
|
||||
break;
|
||||
case 0x20:
|
||||
dev->accel.x_count++;
|
||||
if (dev->accel.output3)
|
||||
dev->accel.cy--;
|
||||
break;
|
||||
case 0x40:
|
||||
if (dev->accel.output3)
|
||||
dev->accel.cy--;
|
||||
break;
|
||||
case 0x60:
|
||||
dev->accel.x_count--;
|
||||
if (dev->accel.output3)
|
||||
dev->accel.cy--;
|
||||
break;
|
||||
case 0x80:
|
||||
dev->accel.x_count--;
|
||||
break;
|
||||
case 0xa0:
|
||||
dev->accel.x_count--;
|
||||
if (dev->accel.output3)
|
||||
dev->accel.cy++;
|
||||
break;
|
||||
case 0xc0:
|
||||
if (dev->accel.output3)
|
||||
dev->accel.cy++;
|
||||
break;
|
||||
case 0xe0:
|
||||
dev->accel.x_count++;
|
||||
if (dev->accel.output3)
|
||||
dev->accel.cy++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->accel.output)
|
||||
mix_dat >>= 1;
|
||||
else {
|
||||
mix_dat <<= 1;
|
||||
mix_dat |= 1;
|
||||
}
|
||||
|
||||
dev->accel.sy--;
|
||||
}
|
||||
dev->accel.x_count = 0;
|
||||
dev->accel.output = 0;
|
||||
} else { /*Bresenham Line*/
|
||||
if (pixcntl == 1) {
|
||||
@@ -1819,6 +1914,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
dev->accel.output = 0;
|
||||
dev->accel.input = 0;
|
||||
dev->accel.input2 = 0;
|
||||
dev->accel.input3 = 0;
|
||||
dev->accel.odd_in = 0;
|
||||
|
||||
dev->accel.cx = dev->accel.cur_x;
|
||||
@@ -1832,6 +1928,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
|
||||
dev->accel.sy = dev->accel.multifunc[0] & 0x7ff;
|
||||
|
||||
ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x.\n",
|
||||
cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix);
|
||||
|
||||
dev->accel.dest = dev->accel.ge_offset + (dev->accel.cy * dev->pitch);
|
||||
|
||||
if (cmd == 4)
|
||||
@@ -1883,9 +1982,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
dev->accel.sx -= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((dev->accel.cmd == 0x41f0) && (frgd_mix == 3) && (bkgd_mix == 3) &&
|
||||
(pixcntl == 0))
|
||||
dev->accel.input3 = 1;
|
||||
}
|
||||
}
|
||||
ibm8514_log("INPUT=%d.\n", dev->accel.input);
|
||||
ibm8514_log("INPUT1=%d, INPUT2=%d.\n", dev->accel.input, dev->accel.input2);
|
||||
dev->force_busy = 1;
|
||||
dev->force_busy2 = 1;
|
||||
dev->data_available = 1;
|
||||
@@ -2056,7 +2159,7 @@ skip_vector_rect_write:
|
||||
ibm8514_log("Vectored Rectangle with normal processing (TODO).\n");
|
||||
} else { /*Normal Rectangle*/
|
||||
if (cpu_input) {
|
||||
ibm8514_log("Normal Pixel Rectangle Fill Transfer SY=%d.\n", dev->accel.sy);
|
||||
ibm8514_log("Normal Pixel Rectangle Fill Transfer SY=%d, fullcmd=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, polygontype=%02x, pixcntl=%x, curx=%d, cury=%d.\n", dev->accel.sy, dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.multifunc[0x0a] & 0x06, pixcntl, dev->accel.cx, dev->accel.cy);
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if ((dev->accel.cx >= clip_l) &&
|
||||
(dev->accel.cx <= clip_r) &&
|
||||
@@ -2844,6 +2947,9 @@ skip_nibble_rect_write:
|
||||
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
|
||||
dev->accel.sy = dev->accel.multifunc[0] & 0x7ff;
|
||||
|
||||
ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, destx=%d, desty=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x.\n",
|
||||
cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.dx, dev->accel.dy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix);
|
||||
|
||||
dev->accel.src = dev->accel.ge_offset + (dev->accel.cy * dev->pitch);
|
||||
dev->accel.dest = dev->accel.ge_offset + (dev->accel.dy * dev->pitch);
|
||||
dev->accel.fill_state = 0;
|
||||
|
||||
@@ -915,7 +915,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
|
||||
if (dev->accel.cx > 0)
|
||||
dev->accel.cx--;
|
||||
mach_log("BitBLT: Src Negative X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n",
|
||||
mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config
|
||||
mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config,
|
||||
mach->accel.src_width & 1);
|
||||
} else {
|
||||
mach->accel.src_stepx = 1;
|
||||
@@ -4717,6 +4717,11 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
|
||||
dev->force_busy = 1;
|
||||
dev->data_available = 1;
|
||||
}
|
||||
if (dev->accel.input3)
|
||||
temp = 0xffff;
|
||||
|
||||
mach_log("Opcode=%d, Len=%d, port=%04x, input=%d, temp=%04x, fullcmd=%04x, crx=%d, cry=%d, frgdsel=%x, bkgdsel=%x.\n", cmd, len, port, dev->accel.input, temp, dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.frgd_sel, dev->accel.bkgd_sel);
|
||||
|
||||
if (dev->accel.input) {
|
||||
ibm8514_accel_out_pixtrans(svga, port, temp & 0xff, len);
|
||||
if (dev->accel.odd_in) { /*WORDs on odd destination scan lengths.*/
|
||||
|
||||
@@ -1924,7 +1924,9 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
||||
static void
|
||||
s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val)
|
||||
{
|
||||
if ((port != 0x9ee8) && (port != 0x9d48)) {
|
||||
int port_pixtrans = ((port != 0x9ae8) && (port != 0x9948) && (port != 0x9ee8) && (port != 0x9d48));
|
||||
|
||||
if (port_pixtrans) {
|
||||
s3_log("[%04X:%08X] OUT PORTW=%04x, val=%04x, CMD=%04x, C(%d,%d), WRTMASK=%04x.\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y, s3->accel.wrt_mask);
|
||||
s3_log(".\n");
|
||||
if ((port == 0xb2e8) || (port == 0xb148)) {
|
||||
@@ -1946,18 +1948,30 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s3->accel.short_stroke = val;
|
||||
s3->accel.ssv_state = 1;
|
||||
switch (port) {
|
||||
case 0x9948:
|
||||
case 0x9ae8:
|
||||
s3_accel_out_fifo(s3, port, val);
|
||||
s3_accel_out_fifo(s3, port + 1, val >> 8);
|
||||
break;
|
||||
case 0x9d48:
|
||||
case 0x9ee8:
|
||||
s3->accel.short_stroke = val;
|
||||
s3->accel.ssv_state = 1;
|
||||
|
||||
s3->accel.cx = s3->accel.cur_x & 0xfff;
|
||||
s3->accel.cy = s3->accel.cur_y & 0xfff;
|
||||
s3->accel.cx = s3->accel.cur_x & 0xfff;
|
||||
s3->accel.cy = s3->accel.cur_y & 0xfff;
|
||||
|
||||
if (s3->accel.cmd & 0x1000) {
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
} else {
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
if (s3->accel.cmd & 0x1000) {
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
} else {
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2857,7 +2871,7 @@ s3_io_remove_alt(s3_t *s3)
|
||||
io_removehandler(0x8d48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x9948, 0x0004, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
io_removehandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
io_removehandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
@@ -2883,6 +2897,7 @@ s3_io_remove(s3_t *s3)
|
||||
io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3);
|
||||
io_removehandler(0x82ec, 0x0002, s3_in, NULL, NULL, s3_out, NULL, NULL, s3);
|
||||
|
||||
io_removehandler(0x02e8, 0x0002, s3_in, NULL, NULL, NULL, NULL, NULL, s3);
|
||||
io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
@@ -2892,7 +2907,7 @@ s3_io_remove(s3_t *s3)
|
||||
io_removehandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0x9ae8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
io_removehandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
@@ -2946,9 +2961,10 @@ s3_io_set_alt(s3_t *s3)
|
||||
io_sethandler(0x9548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
}
|
||||
if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868)
|
||||
io_sethandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0x9948, 0x0004, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
else
|
||||
io_sethandler(0x9948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0x9948, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
|
||||
io_sethandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
io_sethandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
@@ -2984,6 +3000,8 @@ s3_io_set(s3_t *s3)
|
||||
}
|
||||
|
||||
io_sethandler(0x82ec, 0x0002, s3_in, NULL, NULL, s3_out, NULL, NULL, s3);
|
||||
|
||||
io_sethandler(0x02e8, 0x0002, s3_in, NULL, NULL, NULL, NULL, NULL, s3);
|
||||
io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
@@ -3003,9 +3021,10 @@ s3_io_set(s3_t *s3)
|
||||
io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
}
|
||||
if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868)
|
||||
io_sethandler(0x9ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0x9ae8, 0x0004, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
else
|
||||
io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0x9ae8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
|
||||
io_sethandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3);
|
||||
io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
|
||||
@@ -3085,6 +3104,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
|
||||
else
|
||||
svga->write_bank = svga->read_bank = s3->bank << 14;
|
||||
|
||||
s3_log("Chain4=%02x.\n", svga->chain4);
|
||||
svga_recalctimings(svga);
|
||||
} else if (svga->seqaddr == 9) {
|
||||
svga->seqregs[9] = val & 0x80;
|
||||
@@ -3432,6 +3452,14 @@ s3_in(uint16_t addr, void *priv)
|
||||
s3_log("%04X:%08X: %03X: s3_in.\n", CS, cpu_state.pc, addr);
|
||||
|
||||
switch (addr) {
|
||||
case 0x2e8:
|
||||
temp = 0;
|
||||
if (svga->vc == svga->vsyncstart) {
|
||||
if (s3->accel.advfunc_cntl & 0x04)
|
||||
temp |= 0x02;
|
||||
}
|
||||
return temp;
|
||||
|
||||
case 0x3c1:
|
||||
if (svga->attraddr > 0x14)
|
||||
return 0xff;
|
||||
@@ -4114,8 +4142,10 @@ s3_recalctimings(svga_t *svga)
|
||||
svga->dots_per_clock >>= 1;
|
||||
svga->clock *= 2.0;
|
||||
} else {
|
||||
svga->hdisp >>= 1;
|
||||
svga->dots_per_clock >>= 1;
|
||||
if (clk_sel != 2) {
|
||||
svga->hdisp >>= 1;
|
||||
svga->dots_per_clock >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -4197,6 +4227,9 @@ s3_recalctimings(svga_t *svga)
|
||||
if (!s3->elsa_eeprom) {
|
||||
if (svga->hdisp == 832)
|
||||
svga->hdisp -= 32;
|
||||
} else {
|
||||
if (clk_sel > 7)
|
||||
svga->clock *= 2.0;
|
||||
}
|
||||
break;
|
||||
case TVP3026: /*TVP3026 RAMDAC and clock chip*/
|
||||
@@ -4316,8 +4349,10 @@ s3_recalctimings(svga_t *svga)
|
||||
svga->dots_per_clock >>= 1;
|
||||
svga->clock *= 2.0;
|
||||
} else {
|
||||
svga->hdisp >>= 1;
|
||||
svga->dots_per_clock >>= 1;
|
||||
if (clk_sel != 2) {
|
||||
svga->hdisp >>= 1;
|
||||
svga->dots_per_clock >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -4655,6 +4690,9 @@ s3_recalctimings(svga_t *svga)
|
||||
if (!s3->elsa_eeprom) {
|
||||
if (svga->hdisp == 832)
|
||||
svga->hdisp -= 32;
|
||||
} else {
|
||||
if (clk_sel > 7)
|
||||
svga->clock *= 2.0;
|
||||
}
|
||||
break;
|
||||
case TVP3026: /*TVP3026 RAMDAC and clock chip*/
|
||||
@@ -4989,7 +5027,7 @@ s3_updatemapping(s3_t *s3)
|
||||
/*Linear framebuffer*/
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
|
||||
switch (svga->crtc[0x58] & 3) {
|
||||
switch (svga->crtc[0x58] & 0x03) {
|
||||
case 0: /*64k*/
|
||||
s3->linear_size = 0x10000;
|
||||
break;
|
||||
@@ -4999,7 +5037,7 @@ s3_updatemapping(s3_t *s3)
|
||||
case 2: /*2mb*/
|
||||
s3->linear_size = 0x200000;
|
||||
break;
|
||||
case 3: /*8mb*/
|
||||
case 3: /*8mb*/
|
||||
switch (s3->chip) { /* Not on video cards that don't support 4MB*/
|
||||
case S3_TRIO64:
|
||||
case S3_TRIO64V:
|
||||
@@ -5098,7 +5136,7 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv)
|
||||
s3_t *s3 = (s3_t *) priv;
|
||||
svga_t *svga = &s3->svga;
|
||||
|
||||
s3_log("%04X:%08X: OUTB FIFO=%04x, val=%02x.\n", CS, cpu_state.pc, port, val);
|
||||
s3_log("%04X:%08X: OUTB FIFO=%04x, val=%02x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, val, s3->enable_8514);
|
||||
|
||||
if (port >= 0x8000) {
|
||||
if (!s3->enable_8514)
|
||||
@@ -5121,9 +5159,11 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv)
|
||||
s3->accel.subsys_cntl = (s3->accel.subsys_cntl & 0xff) | (val << 8);
|
||||
s3_update_irqs(s3);
|
||||
break;
|
||||
case 0x45e8:
|
||||
case 0x46e8:
|
||||
s3->accel.setup_md = (s3->accel.setup_md & 0xff00) | val;
|
||||
break;
|
||||
case 0x45e9:
|
||||
case 0x46e9:
|
||||
s3->accel.setup_md = (s3->accel.setup_md & 0xff) | (val << 8);
|
||||
break;
|
||||
@@ -5151,7 +5191,7 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
s3_t *s3 = (s3_t *) priv;
|
||||
|
||||
s3_log("%04X:%08X: OUTW FIFO=%04x, val=%04x.\n", CS, cpu_state.pc, port, val);
|
||||
s3_log("%04X:%08X: OUTW FIFO=%04x, val=%04x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, val, s3->enable_8514);
|
||||
|
||||
if (!s3->enable_8514)
|
||||
return;
|
||||
@@ -5185,8 +5225,9 @@ s3_accel_in(uint16_t port, void *priv)
|
||||
svga_t *svga = &s3->svga;
|
||||
int temp;
|
||||
uint8_t temp2 = 0x00;
|
||||
int enhanced_8bpp_modes = !!((svga->crtc[0x3a] & 0x10) && !svga->lowres);
|
||||
|
||||
s3_log("%04X:%08X: INB=%04x.\n", CS, cpu_state.pc, port);
|
||||
s3_log("%04X:%08X: INB=%04x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, s3->enable_8514);
|
||||
|
||||
if (!s3->enable_8514)
|
||||
return 0xff;
|
||||
@@ -5194,7 +5235,7 @@ s3_accel_in(uint16_t port, void *priv)
|
||||
switch (port) {
|
||||
case 0x4148:
|
||||
case 0x42e8:
|
||||
return s3->subsys_stat;
|
||||
return s3->subsys_stat | (enhanced_8bpp_modes ? 0x80 : 0x00);
|
||||
case 0x4149:
|
||||
case 0x42e9:
|
||||
return s3->accel.subsys_cntl >> 8;
|
||||
@@ -5331,20 +5372,10 @@ s3_accel_in(uint16_t port, void *priv)
|
||||
if (s3->force_busy)
|
||||
temp |= 0x02; /*Hardware busy*/
|
||||
else {
|
||||
switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn on FIFO empty bits!*/
|
||||
switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn FIFO empty bits on!*/
|
||||
case 0:
|
||||
if (s3->accel.cmd & 0x100) {
|
||||
if (!s3->accel.ssv_len)
|
||||
temp |= 0x04;
|
||||
} else
|
||||
temp |= 0x04;
|
||||
break;
|
||||
case 1:
|
||||
if (s3->accel.cmd & 0x100) {
|
||||
if (!s3->accel.sy)
|
||||
temp |= 0x04;
|
||||
} else
|
||||
temp |= 0x04;
|
||||
temp |= 0x04;
|
||||
break;
|
||||
case 2:
|
||||
case 6:
|
||||
@@ -6305,11 +6336,14 @@ s3_accel_in_w(uint16_t port, void *priv)
|
||||
uint16_t temp1 = 0x0000;
|
||||
uint16_t temp2 = 0x0000;
|
||||
const uint16_t *vram_w = (uint16_t *) svga->vram;
|
||||
int port_pixtrans = ((port != 0x9ae8) && (port != 0x9948) && (port != 0x9ee8) && (port != 0x9d48));
|
||||
|
||||
s3_log("%04X:%08X: INW=%04x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, s3->enable_8514);
|
||||
|
||||
if (!s3->enable_8514)
|
||||
return 0xffff;
|
||||
|
||||
if (port != 0x9ee8 && port != 0x9d48) {
|
||||
if (port_pixtrans) {
|
||||
if (s3_cpu_dest(s3)) {
|
||||
READ_PIXTRANS_WORD
|
||||
|
||||
@@ -6377,10 +6411,8 @@ s3_accel_in_w(uint16_t port, void *priv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (s3_enable_fifo(s3))
|
||||
s3_wait_fifo_idle(s3);
|
||||
|
||||
temp = s3->accel.short_stroke;
|
||||
temp = s3_accel_in(port, s3);
|
||||
temp |= (s3_accel_in(port + 1, s3) << 8);
|
||||
}
|
||||
|
||||
return temp;
|
||||
@@ -6451,6 +6483,8 @@ s3_accel_write(uint32_t addr, uint8_t val, void *priv)
|
||||
const svga_t *svga = &s3->svga;
|
||||
uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff;
|
||||
|
||||
s3_log("%04X:%08X: WRITEB, 8514/A functions=%x.\n", CS, cpu_state.pc, s3->enable_8514);
|
||||
|
||||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
@@ -6494,6 +6528,8 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *priv)
|
||||
const svga_t *svga = &s3->svga;
|
||||
uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff;
|
||||
|
||||
s3_log("%04X:%08X: WRITEW, 8514/A functions=%x.\n", CS, cpu_state.pc, s3->enable_8514);
|
||||
|
||||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
@@ -6528,6 +6564,8 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
svga_t *svga = &s3->svga;
|
||||
uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff;
|
||||
|
||||
s3_log("%04X:%08X: WRITEL, 8514/A functions=%x.\n", CS, cpu_state.pc, s3->enable_8514);
|
||||
|
||||
if (!s3->enable_8514)
|
||||
return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user