Merge branch 'master' into pc98x1

This commit is contained in:
TC1995
2025-03-07 13:56:35 +01:00
84 changed files with 4664 additions and 685 deletions

View File

@@ -715,27 +715,13 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len)
break;
case 0x42e8:
if (val & 0x01)
dev->subsys_stat &= ~0x01;
if (val & 0x02)
dev->subsys_stat &= ~0x02;
if (val & 0x04)
dev->subsys_stat &= ~0x04;
if (val & 0x08)
dev->subsys_stat &= ~0x08;
ibm8514_log("VBLANK stat=%02x, val=%02x.\n", dev->subsys_stat, val);
dev->subsys_cntl = (dev->subsys_cntl & 0xff00) | val;
dev->subsys_stat &= ~val;
break;
case 0x42e9:
dev->subsys_cntl = val;
if (val & 0x01)
dev->subsys_stat |= 0x01;
if (val & 0x02)
dev->subsys_stat |= 0x02;
if (val & 0x04)
dev->subsys_stat |= 0x04;
if (val & 0x08)
dev->subsys_stat |= 0x08;
if ((val & 0xc0) == 0xc0) {
dev->subsys_cntl = (dev->subsys_cntl & 0xff) | (val << 8);
if ((val & 0xc0) == 0x80) {
dev->fifo_idx = 0;
dev->force_busy = 0;
dev->force_busy2 = 0;
@@ -882,10 +868,10 @@ ibm8514_accel_in(uint16_t port, svga_t *svga)
switch (port) {
case 0x2e8:
if (dev->vc == dev->v_syncstart)
if (dev->vc == dev->dispend)
temp |= 0x02;
ibm8514_log("0x2E8 read: Display Status=%02x.\n", temp);
ibm8514_log("Read: Display Status1=%02x.\n", temp);
break;
case 0x6e8:
@@ -910,21 +896,25 @@ ibm8514_accel_in(uint16_t port, svga_t *svga)
case 0x42e8:
case 0x42e9:
if (dev->vc == dev->v_syncstart)
dev->subsys_stat |= 0x01;
if ((dev->subsys_cntl & 0x01) && !(dev->subsys_stat & 0x01) && (dev->vc == dev->dispend))
temp |= 0x01;
if (cmd == 6) {
if ((dev->accel.dx >= clip_l) &&
if ((dev->subsys_cntl & 0x02) &&
!(dev->subsys_stat & 0x02) &&
(dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r_ibm) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b_ibm))
dev->subsys_stat |= 0x02;
temp |= 0x02;
} else {
if ((dev->accel.cx >= clip_l) &&
if ((dev->subsys_cntl & 0x02) &&
!(dev->subsys_stat & 0x02) &&
(dev->accel.cx >= clip_l) &&
(dev->accel.cx <= clip_r_ibm) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b_ibm))
dev->subsys_stat |= 0x02;
temp |= 0x02;
}
if (!dev->fifo_idx) {
@@ -932,9 +922,10 @@ ibm8514_accel_in(uint16_t port, svga_t *svga)
temp |= 0x08;
}
if (port & 1)
if (port & 1) {
temp = dev->vram_512k_8514 ? 0x00 : 0x80;
else {
temp |= (dev->subsys_cntl >> 8);
} else {
temp |= (dev->subsys_stat | (dev->vram_512k_8514 ? 0x00 : 0x80));
temp |= 0x20;
}
@@ -1155,6 +1146,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -1250,6 +1242,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -1385,6 +1378,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) {
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
} else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) {
@@ -1543,6 +1537,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (ibm8514_cpu_dest(svga)) {
READ((dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat);
} else
@@ -1634,6 +1629,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) {
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
} else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) {
@@ -1832,6 +1828,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -1989,6 +1986,7 @@ skip_vector_rect_write:
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) {
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
} else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) {
@@ -2150,6 +2148,7 @@ skip_nibble_rect_write:
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -2232,6 +2231,7 @@ skip_nibble_rect_write:
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -2313,6 +2313,7 @@ skip_nibble_rect_write:
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -2424,6 +2425,7 @@ skip_nibble_rect_write:
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -2546,6 +2548,7 @@ skip_nibble_rect_write:
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -2650,9 +2653,10 @@ skip_nibble_rect_write:
dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r);
if ((dev->accel.cx >= clip_l) &&
(dev->accel.cx < clip_r) &&
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -2811,6 +2815,7 @@ skip_nibble_rect_write:
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (pixcntl == 3) {
if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) {
READ(dev->accel.src + dev->accel.cx, mix_dat);
@@ -2978,6 +2983,7 @@ skip_nibble_bitblt_write:
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -3075,6 +3081,7 @@ skip_nibble_bitblt_write:
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -3174,6 +3181,7 @@ skip_nibble_bitblt_write:
(dx <= (((uint64_t)clip_r) * 3)) &&
(dev->accel.dy >= (clip_t << 1)) &&
(dev->accel.dy <= (clip_b << 1))) {
dev->subsys_stat |= 0x02;
READ(dev->accel.src + cx, src_dat);
READ(dev->accel.dest + dx, dest_dat);
@@ -3196,6 +3204,7 @@ skip_nibble_bitblt_write:
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (pixcntl == 3) {
if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) {
READ(dev->accel.src + dev->accel.cx, mix_dat);
@@ -3704,6 +3713,8 @@ ibm8514_poll(void *priv)
dev->vc &= 0xfff;
if (dev->vc == dev->dispend) {
dev->subsys_stat |= 0x01;
ibm8514_log("VBLANK irq.\n");
dev->dispon = 0;
for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) {

View File

@@ -70,20 +70,19 @@ void
ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
{
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
switch (addr) {
case 0:
svga_out((dev && dev->on) ? 0x2ec : 0x3c8, val, svga);
svga_out(0x3c8, val, svga);
break;
case 1:
svga_out((dev && dev->on) ? 0x2ed : 0x3c9, val, svga);
svga_out(0x3c9, val, svga);
break;
case 2:
svga_out((dev && dev->on) ? 0x2ea : 0x3c6, val, svga);
svga_out(0x3c6, val, svga);
break;
case 3:
svga_out((dev && dev->on) ? 0x2eb : 0x3c7, val, svga);
svga_out(0x3c7, val, svga);
break;
default:
ramdac->regs[addr & 0xf] = val;
@@ -176,21 +175,20 @@ uint8_t
ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
{
const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t temp = 0;
switch (addr) {
case 0:
temp = svga_in((dev && dev->on) ? 0x2ec : 0x3c8, svga);
temp = svga_in(0x3c8, svga);
break;
case 1:
temp = svga_in((dev && dev->on) ? 0x2ed : 0x3c9, svga);
temp = svga_in(0x3c9, svga);
break;
case 2:
temp = svga_in((dev && dev->on) ? 0x2ea : 0x3c6, svga);
temp = svga_in(0x3c6, svga);
break;
case 3:
temp = svga_in((dev && dev->on) ? 0x2eb : 0x3c7, svga);
temp = svga_in(0x3c7, svga);
break;
case 4:
case 8:

View File

@@ -28,6 +28,7 @@
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/pci.h>
#include <86box/rom.h>

View File

@@ -27,6 +27,7 @@
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/mca.h>
#include <86box/pci.h>
@@ -437,6 +438,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch (mix ? frgd_sel : bkgd_sel) {
case 0:
src_dat = dev->accel.bkgd_color;
@@ -660,6 +662,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch (mix ? frgd_sel : bkgd_sel) {
case 0:
src_dat = dev->accel.bkgd_color;
@@ -1066,6 +1069,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
if (mach->accel.dp_config & 0x02) {
READ(dev->accel.src + dev->accel.cx, poly_src);
poly_src = ((poly_src & rd_mask) == rd_mask);
@@ -1307,6 +1311,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
mach->accel.clip_overrun = 0;
switch (mix ? frgd_sel : bkgd_sel) {
case 0:
@@ -1440,6 +1445,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
mach->accel.clip_overrun = 0;
if (mach->accel.linedraw_opt & 0x02) {
if (dev->bpp) {
@@ -1598,6 +1604,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
mach->accel.clip_overrun = 0;
switch (mix ? frgd_sel : bkgd_sel) {
case 0:
@@ -1732,6 +1739,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
dev->subsys_stat |= 0x02;
mach->accel.clip_overrun = 0;
switch (mix ? frgd_sel : bkgd_sel) {
case 0:
@@ -2027,6 +2035,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
dev->subsys_stat |= 0x02;
switch (mix ? frgd_sel : bkgd_sel) {
case 0:
src_dat = dev->accel.bkgd_color;
@@ -2332,6 +2341,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
case 0x2ed:
rs2 = !!(mach->accel.ext_ge_config & 0x1000);
rs3 = !!(mach->accel.ext_ge_config & 0x2000);
mach_log("8514/A RS2=%d, RS3=%d, addr=%03x.\n", rs2, rs3, addr);
if ((dev->local & 0xff) >= 0x02) {
if (mach->regs[0xb0] & 0x20) { /*ATI extended 8514/A mode.*/
mach_log("Extended 8514/A mode.\n");
@@ -2340,10 +2350,14 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
mach32_updatemapping(mach, svga);
}
if (mach->pci_bus && !mach->ramdac_type)
ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga);
else
ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga);
if (dev->on)
svga_out(addr, val, svga);
else {
if (mach->pci_bus && !mach->ramdac_type)
ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga);
else
ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga);
}
} else
svga_out(addr, val, svga);
return;
@@ -2354,6 +2368,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
case 0x3C9:
rs2 = !!(mach->regs[0xa0] & 0x20);
rs3 = !!(mach->regs[0xa0] & 0x40);
mach_log("VGA RS2=%d, RS3=%d, addr=%03x.\n", rs2, rs3, addr);
if ((dev->local & 0xff) >= 0x02) {
if (svga->attrregs[0x10] & 0x40) {
mach_log("VGA mode.\n");
@@ -2362,10 +2377,14 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
mach32_updatemapping(mach, svga);
}
if (mach->pci_bus && !mach->ramdac_type)
ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga);
else
ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga);
if (dev->on)
svga_out(addr, val, svga);
else {
if (mach->pci_bus && !mach->ramdac_type)
ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga);
else
ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga);
}
} else
svga_out(addr, val, svga);
return;
@@ -2480,10 +2499,14 @@ mach_in(uint16_t addr, void *priv)
rs2 = !!(mach->accel.ext_ge_config & 0x1000);
rs3 = !!(mach->accel.ext_ge_config & 0x2000);
if ((dev->local & 0xff) >= 0x02) {
if (mach->pci_bus && !mach->ramdac_type)
temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga);
else
temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga);
if (dev->on)
temp = svga_in(addr, svga);
else {
if (mach->pci_bus && !mach->ramdac_type)
temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga);
else
temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga);
}
} else
temp = svga_in(addr, svga);
break;
@@ -3406,7 +3429,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
static void
mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev)
{
if (port != 0x42e8 && port != 0x42e9)
if (port == 0x42e8 || port == 0x42e9)
mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val);
switch (port) {
@@ -3421,7 +3444,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
break;
case 0x42e9:
ibm8514_accel_out(port, val, svga, 2);
if ((val & 0xc0) == 0xc0) {
if ((val & 0xc0) == 0x80) {
dev->ext_fifo_idx = 0;
mach->force_busy = 0;
}
@@ -3512,6 +3535,11 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8
svga_recalctimings(svga);
break;
case 0x46e8:
case 0x46e9:
mach_log("0x%04x write: VGA subsystem enable add-on=%02x.\n", port, val);
break;
case 0x4ae8:
dev->accel.advfunc_cntl = val;
dev->on = dev->accel.advfunc_cntl & 0x01;
@@ -4200,6 +4228,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
switch (port) {
case 0x2e8:
case 0x2e9:
case 0x6e8:
case 0x22e8:
case 0x26e8:
@@ -4211,18 +4240,22 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
case 0x42e8:
case 0x42e9:
if (dev->vc == dev->v_syncstart)
if ((dev->subsys_cntl & 0x01) && !(dev->subsys_stat & 0x01) && (dev->vc == dev->dispend))
temp |= 0x01;
if (mach->accel.cmd_type == -1) {
if (cmd == 6) {
if ((dev->accel.dx >= clip_l) &&
if ((dev->subsys_cntl & 0x02) &&
!(dev->subsys_stat & 0x02) &&
(dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r_ibm) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b_ibm))
temp |= 0x02;
} else {
if ((dev->accel.cx >= clip_l) &&
if ((dev->subsys_cntl & 0x02) &&
!(dev->subsys_stat & 0x02) &&
(dev->accel.cx >= clip_l) &&
(dev->accel.cx <= clip_r_ibm) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b_ibm))
@@ -4233,7 +4266,9 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
case 1:
case 2:
case 5:
if ((dev->accel.dx >= clip_l) &&
if ((dev->subsys_cntl & 0x02) &&
!(dev->subsys_stat & 0x02) &&
(dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b))
@@ -4241,7 +4276,9 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
break;
case 3:
case 4:
if ((dev->accel.cx >= clip_l) &&
if ((dev->subsys_cntl & 0x02) &&
!(dev->subsys_stat & 0x02) &&
(dev->accel.cx >= clip_l) &&
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b))
@@ -4256,16 +4293,17 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
if ((!dev->force_busy && !dev->force_busy2) || !mach->force_busy)
temp |= 0x08;
}
if (port & 1)
if (port & 1) {
temp = dev->vram_512k_8514 ? 0x00 : 0x80;
else {
temp |= (dev->subsys_cntl >> 8);
} else {
temp |= (dev->subsys_stat | (dev->vram_512k_8514 ? 0x00 : 0x80));
if (mach->accel.ext_ge_config & 0x08)
temp |= ((mach->accel.ext_ge_config & 0x07) << 4);
else
temp |= 0x20;
}
mach_log("0x%04x read: Subsystem Status=%02x.\n", port, temp);
mach_log("0x%04x read: Subsystem Status=%02x, monitoralias=%02x.\n", port, temp, mach->accel.ext_ge_config & 0x07);
break;
/*ATI Mach8/32 specific registers*/
@@ -4402,7 +4440,8 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
default:
break;
}
mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp);
if (port == 0x2ee8 || port == 0x2ee9 || port == 0x42e8 || port == 0x42e9)
mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp);
return temp;
}
@@ -5418,6 +5457,10 @@ mach32_updatemapping(mach_t *mach, svga_t *svga)
mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel);
mem_mapping_set_p(&svga->mapping, mach);
} else {
if (!dev->on) {
memset(dev->vram, 0, dev->vram_size);
memset(dev->changedvram, 0, (dev->vram_size >> 12) + 1);
}
mach_log("IBM compatible banked mapping.\n");
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_p(&svga->mapping, svga);

View File

@@ -27,6 +27,7 @@
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/device.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>

View File

@@ -23,6 +23,7 @@
#include <stdatomic.h>
#include <86box/86box.h>
#include <86box/io.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/mem.h>
#include <86box/pci.h>
@@ -4677,6 +4678,7 @@ blit_trap(mystique_t *mystique)
int err_l = (int32_t)mystique->dwgreg.ar[1];
int err_r = (int32_t)mystique->dwgreg.ar[4];
const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT;
bool transc = !!(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC);
switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) {
case DWGCTRL_ATYPE_BLK:
@@ -4699,6 +4701,7 @@ blit_trap(mystique_t *mystique)
int pattern = mystique->dwgreg.pattern[yoff][xoff];
uint32_t dst;
if (!transc || (transc && pattern))
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
case MACCESS_PWIDTH_8:
svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff;
@@ -4770,6 +4773,7 @@ blit_trap(mystique_t *mystique)
uint32_t dst;
uint32_t old_dst;
if (!transc || (transc && pattern))
switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) {
case MACCESS_PWIDTH_8:
dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask];

View File

@@ -30,6 +30,7 @@
#include <86box/io.h>
#include <86box/video.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/mem.h>
#include <86box/pit.h>

View File

@@ -31,6 +31,7 @@
#include <86box/io.h>
#include <86box/video.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/mem.h>
#include <86box/pit.h>

File diff suppressed because it is too large Load Diff

View File

@@ -338,6 +338,7 @@ typedef struct virge_t {
event_t * fifo_not_full_event;
atomic_int virge_busy;
atomic_uint irq_pending;
uint8_t subsys_stat;
uint8_t subsys_cntl;
@@ -375,6 +376,8 @@ typedef struct virge_t {
int pci;
int is_agp;
pc_timer_t irq_timer;
} virge_t;
static __inline void
@@ -471,6 +474,19 @@ s3_virge_update_irqs(virge_t *virge)
pci_clear_irq(virge->pci_slot, PCI_INTA, &virge->irq_state);
}
static void
s3_virge_update_irq_timer(void* priv)
{
virge_t *virge = (virge_t *) priv;
if (virge->irq_pending) {
virge->irq_pending--;
s3_virge_update_irqs(virge);
}
timer_on_auto(&virge->irq_timer, 100.);
}
static void
s3_virge_out(uint16_t addr, uint8_t val, void *priv)
{
@@ -1101,6 +1117,8 @@ static void
s3_virge_vblank_start(svga_t *svga) {
virge_t *virge = (virge_t *) svga->priv;
if (virge->irq_pending)
virge->irq_pending--;
virge->subsys_stat |= INT_VSY;
s3_virge_update_irqs(virge);
}
@@ -1784,18 +1802,18 @@ fifo_thread(void *param)
virge->fifo_read_idx++;
fifo->addr_type = FIFO_INVALID;
if (FIFO_ENTRIES > 0xe000)
thread_set_event(virge->fifo_not_full_event);
if (FIFO_ENTRIES > 0xe000)
thread_set_event(virge->fifo_not_full_event);
end_time = plat_timer_read();
virge_time += end_time - start_time;
}
virge->virge_busy = 0;
virge->subsys_stat |= (INT_FIFO_EMP | INT_3DF_EMP);
if (virge->cmd_dma)
virge->subsys_stat |= (INT_HOST_DONE | INT_CMD_DONE);
end_time = plat_timer_read();
virge_time += end_time - start_time;
}
virge->virge_busy = 0;
virge->subsys_stat |= (INT_FIFO_EMP | INT_3DF_EMP);
if (virge->cmd_dma)
virge->subsys_stat |= (INT_HOST_DONE | INT_CMD_DONE);
s3_virge_update_irqs(virge);
virge->irq_pending++;
}
}
@@ -2175,19 +2193,781 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
} \
} while (0)
#define MIX() \
do { \
int c; \
for (c = 0; c < 24; c++) { \
int d = (dest & (1 << c)) ? 1 : 0; \
if (source & (1 << c)) \
d |= 2; \
if (pattern & (1 << c)) \
d |= 4; \
if (virge->s3d.rop & (1 << d)) \
out |= (1 << c); \
} \
} while (0)
#define ROPMIX(R, D, P, S, out) \
{ \
switch (R) { \
case 0x00: \
out = 0; \
break; \
case 0x01: \
out = ~(D | (P | S)); \
break; \
case 0x02: \
out = D & ~(P | S); \
break; \
case 0x03: \
out = ~(P | S); \
break; \
case 0x04: \
out = S & ~(D | P); \
break; \
case 0x05: \
out = ~(D | P); \
break; \
case 0x06: \
out = ~(P | ~(D ^ S)); \
break; \
case 0x07: \
out = ~(P | (D & S)); \
break; \
case 0x08: \
out = S & (D & ~P); \
break; \
case 0x09: \
out = ~(P | (D ^ S)); \
break; \
case 0x0a: \
out = D & ~P; \
break; \
case 0x0b: \
out = ~(P | (S & ~D)); \
break; \
case 0x0c: \
out = S & ~P; \
break; \
case 0x0d: \
out = ~(P | (D & ~S)); \
break; \
case 0x0e: \
out = ~(P | ~(D | S)); \
break; \
case 0x0f: \
out = ~P; \
break; \
case 0x10: \
out = P & ~(D | S); \
break; \
case 0x11: \
out = ~(D | S); \
break; \
case 0x12: \
out = ~(S | ~(D ^ P)); \
break; \
case 0x13: \
out = ~(S | (D & P)); \
break; \
case 0x14: \
out = ~(D | ~(P ^ S)); \
break; \
case 0x15: \
out = ~(D | (P & S)); \
break; \
case 0x16: \
out = P ^ (S ^ (D & ~(P & S))); \
break; \
case 0x17: \
out = ~(S ^ ((S ^ P) & (D ^ S))); \
break; \
case 0x18: \
out = (S ^ P) & (P ^ D); \
break; \
case 0x19: \
out = ~(S ^ (D & ~(P & S))); \
break; \
case 0x1a: \
out = P ^ (D | (S & P)); \
break; \
case 0x1b: \
out = ~(S ^ (D & (P ^ S))); \
break; \
case 0x1c: \
out = P ^ (S | (D & P)); \
break; \
case 0x1d: \
out = ~(D ^ (S & (P ^ D))); \
break; \
case 0x1e: \
out = P ^ (D | S); \
break; \
case 0x1f: \
out = ~(P & (D | S)); \
break; \
case 0x20: \
out = D & (P & ~S); \
break; \
case 0x21: \
out = ~(S | (D ^ P)); \
break; \
case 0x22: \
out = D & ~S; \
break; \
case 0x23: \
out = ~(S | (P & ~D)); \
break; \
case 0x24: \
out = (S ^ P) & (D ^ S); \
break; \
case 0x25: \
out = ~(P ^ (D & ~(S & P))); \
break; \
case 0x26: \
out = S ^ (D | (P & S)); \
break; \
case 0x27: \
out = S ^ (D | ~(P ^ S)); \
break; \
case 0x28: \
out = D & (P ^ S); \
break; \
case 0x29: \
out = ~(P ^ (S ^ (D | (P & S)))); \
break; \
case 0x2a: \
out = D & ~(P & S); \
break; \
case 0x2b: \
out = ~(S ^ ((S ^ P) & (P ^ D))); \
break; \
case 0x2c: \
out = S ^ (P & (D | S)); \
break; \
case 0x2d: \
out = P ^ (S | ~D); \
break; \
case 0x2e: \
out = P ^ (S | (D ^ P)); \
break; \
case 0x2f: \
out = ~(P & (S | ~D)); \
break; \
case 0x30: \
out = P & ~S; \
break; \
case 0x31: \
out = ~(S | (D & ~P)); \
break; \
case 0x32: \
out = S ^ (D | (P | S)); \
break; \
case 0x33: \
out = ~S; \
break; \
case 0x34: \
out = S ^ (P | (D & S)); \
break; \
case 0x35: \
out = S ^ (P | ~(D ^ S)); \
break; \
case 0x36: \
out = S ^ (D | P); \
break; \
case 0x37: \
out = ~(S & (D | P)); \
break; \
case 0x38: \
out = P ^ (S & (D | P)); \
break; \
case 0x39: \
out = S ^ (P | ~D); \
break; \
case 0x3a: \
out = S ^ (P | (D ^ S)); \
break; \
case 0x3b: \
out = ~(S & (P | ~D)); \
break; \
case 0x3c: \
out = P ^ S; \
break; \
case 0x3d: \
out = S ^ (P | ~(D | S)); \
break; \
case 0x3e: \
out = S ^ (P | (D & ~S)); \
break; \
case 0x3f: \
out = ~(P & S); \
break; \
case 0x40: \
out = P & (S & ~D); \
break; \
case 0x41: \
out = ~(D | (P ^ S)); \
break; \
case 0x42: \
out = (S ^ D) & (P ^ D); \
break; \
case 0x43: \
out = ~(S ^ (P & ~(D & S))); \
break; \
case 0x44: \
out = S & ~D; \
break; \
case 0x45: \
out = ~(D | (P & ~S)); \
break; \
case 0x46: \
out = D ^ (S | (P & D)); \
break; \
case 0x47: \
out = ~(P ^ (S & (D ^ P))); \
break; \
case 0x48: \
out = S & (D ^ P); \
break; \
case 0x49: \
out = ~(P ^ (D ^ (S | (P & D)))); \
break; \
case 0x4a: \
out = D ^ (P & (S | D)); \
break; \
case 0x4b: \
out = P ^ (D | ~S); \
break; \
case 0x4c: \
out = S & ~(D & P); \
break; \
case 0x4d: \
out = ~(S ^ ((S ^ P) | (D ^ S))); \
break; \
case 0x4e: \
out = P ^ (D | (S ^ P)); \
break; \
case 0x4f: \
out = ~(P & (D | ~S)); \
break; \
case 0x50: \
out = P & ~D; \
break; \
case 0x51: \
out = ~(D | (S & ~P)); \
break; \
case 0x52: \
out = D ^ (P | (S & D)); \
break; \
case 0x53: \
out = ~(S ^ (P & (D ^ S))); \
break; \
case 0x54: \
out = ~(D | ~(P | S)); \
break; \
case 0x55: \
out = ~D; \
break; \
case 0x56: \
out = D ^ (P | S); \
break; \
case 0x57: \
out = ~(D & (P | S)); \
break; \
case 0x58: \
out = P ^ (D & (S | P)); \
break; \
case 0x59: \
out = D ^ (P | ~S); \
break; \
case 0x5a: \
out = D ^ P; \
break; \
case 0x5b: \
out = D ^ (P | ~(S | D)); \
break; \
case 0x5c: \
out = D ^ (P | (S ^ D)); \
break; \
case 0x5d: \
out = ~(D & (P | ~S)); \
break; \
case 0x5e: \
out = D ^ (P | (S & ~D)); \
break; \
case 0x5f: \
out = ~(D & P); \
break; \
case 0x60: \
out = P & (D ^ S); \
break; \
case 0x61: \
out = ~(D ^ (S ^ (P | (D & S)))); \
break; \
case 0x62: \
out = D ^ (S & (P | D)); \
break; \
case 0x63: \
out = S ^ (D | ~P); \
break; \
case 0x64: \
out = S ^ (D & (P | S)); \
break; \
case 0x65: \
out = D ^ (S | ~P); \
break; \
case 0x66: \
out = D ^ S; \
break; \
case 0x67: \
out = S ^ (D | ~(P | S)); \
break; \
case 0x68: \
out = ~(D ^ (S ^ (P | ~(D | S)))); \
break; \
case 0x69: \
out = ~(P ^ (D ^ S)); \
break; \
case 0x6a: \
out = D ^ (P & S); \
break; \
case 0x6b: \
out = ~(P ^ (S ^ (D & (P | S)))); \
break; \
case 0x6c: \
out = S ^ (D & P); \
break; \
case 0x6d: \
out = ~(P ^ (D ^ (S & (P | D)))); \
break; \
case 0x6e: \
out = S ^ (D & (P | ~S)); \
break; \
case 0x6f: \
out = ~(P & ~(D ^ S)); \
break; \
case 0x70: \
out = P & ~(D & S); \
break; \
case 0x71: \
out = ~(S ^ ((S ^ D) & (P ^ D))); \
break; \
case 0x72: \
out = S ^ (D | (P ^ S)); \
break; \
case 0x73: \
out = ~(S & (D | ~P)); \
break; \
case 0x74: \
out = D ^ (S | (P ^ D)); \
break; \
case 0x75: \
out = ~(D & (S | ~P)); \
break; \
case 0x76: \
out = S ^ (D | (P & ~S)); \
break; \
case 0x77: \
out = ~(D & S); \
break; \
case 0x78: \
out = P ^ (D & S); \
break; \
case 0x79: \
out = ~(D ^ (S ^ (P & (D | S)))); \
break; \
case 0x7a: \
out = D ^ (P & (S | ~D)); \
break; \
case 0x7b: \
out = ~(S & ~(D ^ P)); \
break; \
case 0x7c: \
out = S ^ (P & (D | ~S)); \
break; \
case 0x7d: \
out = ~(D & ~(P ^ S)); \
break; \
case 0x7e: \
out = (S ^ P) | (D ^ S); \
break; \
case 0x7f: \
out = ~(D & (P & S)); \
break; \
case 0x80: \
out = D & (P & S); \
break; \
case 0x81: \
out = ~((S ^ P) | (D ^ S)); \
break; \
case 0x82: \
out = D & ~(P ^ S); \
break; \
case 0x83: \
out = ~(S ^ (P & (D | ~S))); \
break; \
case 0x84: \
out = S & ~(D ^ P); \
break; \
case 0x85: \
out = ~(P ^ (D & (S | ~P))); \
break; \
case 0x86: \
out = D ^ (S ^ (P & (D | S))); \
break; \
case 0x87: \
out = ~(P ^ (D & S)); \
break; \
case 0x88: \
out = D & S; \
break; \
case 0x89: \
out = ~(S ^ (D | (P & ~S))); \
break; \
case 0x8a: \
out = D & (S | ~P); \
break; \
case 0x8b: \
out = ~(D ^ (S | (P ^ D))); \
break; \
case 0x8c: \
out = S & (D | ~P); \
break; \
case 0x8d: \
out = ~(S ^ (D | (P ^ S))); \
break; \
case 0x8e: \
out = S ^ ((S ^ D) & (P ^ D)); \
break; \
case 0x8f: \
out = ~(P & ~(D & S)); \
break; \
case 0x90: \
out = P & ~(D ^ S); \
break; \
case 0x91: \
out = ~(S ^ (D & (P | ~S))); \
break; \
case 0x92: \
out = D ^ (P ^ (S & (D | P))); \
break; \
case 0x93: \
out = ~(S ^ (P & D)); \
break; \
case 0x94: \
out = P ^ (S ^ (D & (P | S))); \
break; \
case 0x95: \
out = ~(D ^ (P & S)); \
break; \
case 0x96: \
out = D ^ (P ^ S); \
break; \
case 0x97: \
out = P ^ (S ^ (D | ~(P | S))); \
break; \
case 0x98: \
out = ~(S ^ (D | ~(P | S))); \
break; \
case 0x99: \
out = ~(D ^ S); \
break; \
case 0x9a: \
out = D ^ (P & ~S); \
break; \
case 0x9b: \
out = ~(S ^ (D & (P | S))); \
break; \
case 0x9c: \
out = S ^ (P & ~D); \
break; \
case 0x9d: \
out = ~(D ^ (S & (P | D))); \
break; \
case 0x9e: \
out = D ^ (S ^ (P | (D & S))); \
break; \
case 0x9f: \
out = ~(P & (D ^ S)); \
break; \
case 0xa0: \
out = D & P; \
break; \
case 0xa1: \
out = ~(P ^ (D | (S & ~P))); \
break; \
case 0xa2: \
out = D & (P | ~S); \
break; \
case 0xa3: \
out = ~(D ^ (P | (S ^ D))); \
break; \
case 0xa4: \
out = ~(P ^ (D | ~(S | P))); \
break; \
case 0xa5: \
out = ~(P ^ D); \
break; \
case 0xa6: \
out = D ^ (S & ~P); \
break; \
case 0xa7: \
out = ~(P ^ (D & (S | P))); \
break; \
case 0xa8: \
out = D & (P | S); \
break; \
case 0xa9: \
out = ~(D ^ (P | S)); \
break; \
case 0xaa: \
out = D; \
break; \
case 0xab: \
out = D | ~(P | S); \
break; \
case 0xac: \
out = S ^ (P & (D ^ S)); \
break; \
case 0xad: \
out = ~(D ^ (P | (S & D))); \
break; \
case 0xae: \
out = D | (S & ~P); \
break; \
case 0xaf: \
out = D | ~P; \
break; \
case 0xb0: \
out = P & (D | ~S); \
break; \
case 0xb1: \
out = ~(P ^ (D | (S ^ P))); \
break; \
case 0xb2: \
out = S ^ ((S ^ P) | (D ^ S)); \
break; \
case 0xb3: \
out = ~(S & ~(D & P)); \
break; \
case 0xb4: \
out = P ^ (S & ~D); \
break; \
case 0xb5: \
out = ~(D ^ (P & (S | D))); \
break; \
case 0xb6: \
out = D ^ (P ^ (S | (D & P))); \
break; \
case 0xb7: \
out = ~(S & (D ^ P)); \
break; \
case 0xb8: \
out = P ^ (S & (D ^ P)); \
break; \
case 0xb9: \
out = ~(D ^ (S | (P & D))); \
break; \
case 0xba: \
out = D | (P & ~S); \
break; \
case 0xbb: \
out = D | ~S; \
break; \
case 0xbc: \
out = S ^ (P & ~(D & S)); \
break; \
case 0xbd: \
out = ~((S ^ D) & (P ^ D)); \
break; \
case 0xbe: \
out = D | (P ^ S); \
break; \
case 0xbf: \
out = D | ~(P & S); \
break; \
case 0xc0: \
out = P & S; \
break; \
case 0xc1: \
out = ~(S ^ (P | (D & ~S))); \
break; \
case 0xc2: \
out = ~(S ^ (P | ~(D | S))); \
break; \
case 0xc3: \
out = ~(P ^ S); \
break; \
case 0xc4: \
out = S & (P | ~D); \
break; \
case 0xc5: \
out = ~(S ^ (P | (D ^ S))); \
break; \
case 0xc6: \
out = S ^ (D & ~P); \
break; \
case 0xc7: \
out = ~(P ^ (S & (D | P))); \
break; \
case 0xc8: \
out = S & (D | P); \
break; \
case 0xc9: \
out = ~(S ^ (P | D)); \
break; \
case 0xca: \
out = D ^ (P & (S ^ D)); \
break; \
case 0xcb: \
out = ~(S ^ (P | (D & S))); \
break; \
case 0xcc: \
out = S; \
break; \
case 0xcd: \
out = S | ~(D | P); \
break; \
case 0xce: \
out = S | (D & ~P); \
break; \
case 0xcf: \
out = S | ~P; \
break; \
case 0xd0: \
out = P & (S | ~D); \
break; \
case 0xd1: \
out = ~(P ^ (S | (D ^ P))); \
break; \
case 0xd2: \
out = P ^ (D & ~S); \
break; \
case 0xd3: \
out = ~(S ^ (P & (D | S))); \
break; \
case 0xd4: \
out = S ^ ((S ^ P) & (P ^ D)); \
break; \
case 0xd5: \
out = ~(D & ~(P & S)); \
break; \
case 0xd6: \
out = P ^ (S ^ (D | (P & S))); \
break; \
case 0xd7: \
out = ~(D & (P ^ S)); \
break; \
case 0xd8: \
out = P ^ (D & (S ^ P)); \
break; \
case 0xd9: \
out = ~(S ^ (D | (P & S))); \
break; \
case 0xda: \
out = D ^ (P & ~(S & D)); \
break; \
case 0xdb: \
out = ~((S ^ P) & (D ^ S)); \
break; \
case 0xdc: \
out = S | (P & ~D); \
break; \
case 0xdd: \
out = S | ~D; \
break; \
case 0xde: \
out = S | (D ^ P); \
break; \
case 0xdf: \
out = S | ~(D & P); \
break; \
case 0xe0: \
out = P & (D | S); \
break; \
case 0xe1: \
out = ~(P ^ (D | S)); \
break; \
case 0xe2: \
out = D ^ (S & (P ^ D)); \
break; \
case 0xe3: \
out = ~(P ^ (S | (D & P))); \
break; \
case 0xe4: \
out = S ^ (D & (P ^ S)); \
break; \
case 0xe5: \
out = ~(P ^ (D | (S & P))); \
break; \
case 0xe6: \
out = S ^ (D & ~(P & S)); \
break; \
case 0xe7: \
out = ~((S ^ P) & (P ^ D)); \
break; \
case 0xe8: \
out = S ^ ((S ^ P) & (D ^ S)); \
break; \
case 0xe9: \
out = ~(D ^ (S ^ (P & ~(D & S)))); \
break; \
case 0xea: \
out = D | (P & S); \
break; \
case 0xeb: \
out = D | ~(P ^ S); \
break; \
case 0xec: \
out = S | (D & P); \
break; \
case 0xed: \
out = S | ~(D ^ P); \
break; \
case 0xee: \
out = D | S; \
break; \
case 0xef: \
out = S | (D | ~P); \
break; \
case 0xf0: \
out = P; \
break; \
case 0xf1: \
out = P | ~(D | S); \
break; \
case 0xf2: \
out = P | (D & ~S); \
break; \
case 0xf3: \
out = P | ~S; \
break; \
case 0xf4: \
out = P | (S & ~D); \
break; \
case 0xf5: \
out = P | ~D; \
break; \
case 0xf6: \
out = P | (D ^ S); \
break; \
case 0xf7: \
out = P | ~(D & S); \
break; \
case 0xf8: \
out = P | (D & S); \
break; \
case 0xf9: \
out = P | ~(D ^ S); \
break; \
case 0xfa: \
out = D | P; \
break; \
case 0xfb: \
out = D | (P | ~S); \
break; \
case 0xfc: \
out = P | S; \
break; \
case 0xfd: \
out = P | (S | ~D); \
break; \
case 0xfe: \
out = D | (P | S); \
break; \
case 0xff: \
out = ~0; \
break; \
} \
}
#define MIX() do { ROPMIX(virge->s3d.rop & 0xFF, dest, pattern, source, out); out &= 0xFFFFFF; } while (0)
#define WRITE(addr, val) \
do { \
@@ -3642,7 +4422,7 @@ render_thread(void *param)
}
virge->s3d_busy = 0;
virge->subsys_stat |= INT_S3D_DONE;
s3_virge_update_irqs(virge);
virge->irq_pending++;
}
}
@@ -4300,6 +5080,7 @@ s3_virge_disable_handlers(virge_t *dev)
reset_state->svga.timer = dev->svga.timer;
reset_state->svga.timer8514 = dev->svga.timer8514;
reset_state->irq_timer = dev->irq_timer;
}
static void
@@ -4571,6 +5352,8 @@ s3_virge_init(const device_t *info)
virge->fifo_not_full_event = thread_create_event();
virge->fifo_thread = thread_create(fifo_thread, virge);
timer_add(&virge->irq_timer, s3_virge_update_irq_timer, virge, 1);
virge->local = info->local;
*reset_state = *virge;

View File

@@ -141,10 +141,10 @@ video_cards[] = {
{ .device = &chips_69000_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5430_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5434_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5436_pci_device, .flags = VIDEO_FLAG_TYPE_SPECIAL },
{ .device = &gd5436_pci_device, .flags = VIDEO_FLAG_TYPE_SECONDARY },
{ .device = &gd5440_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5446_pci_device, .flags = VIDEO_FLAG_TYPE_SPECIAL },
{ .device = &gd5446_stb_pci_device, .flags = VIDEO_FLAG_TYPE_SPECIAL },
{ .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 },

View File

@@ -1457,18 +1457,784 @@ enum {
else \
dat = vram_l[(addr) & (tgui->vram_mask >> 2)];
#define MIX() \
do { \
out = 0; \
for (c = 0; c < 32; c++) { \
d = (dst_dat & (1 << c)) ? 1 : 0; \
if (src_dat & (1 << c)) \
d |= 2; \
if (pat_dat & (1 << c)) \
d |= 4; \
if (tgui->accel.rop & (1 << d)) \
out |= (1 << c); \
} \
#define ROPMIX(R, D, P, S, out) \
{ \
switch (R) { \
case 0x00: \
out = 0; \
break; \
case 0x01: \
out = ~(D | (P | S)); \
break; \
case 0x02: \
out = D & ~(P | S); \
break; \
case 0x03: \
out = ~(P | S); \
break; \
case 0x04: \
out = S & ~(D | P); \
break; \
case 0x05: \
out = ~(D | P); \
break; \
case 0x06: \
out = ~(P | ~(D ^ S)); \
break; \
case 0x07: \
out = ~(P | (D & S)); \
break; \
case 0x08: \
out = S & (D & ~P); \
break; \
case 0x09: \
out = ~(P | (D ^ S)); \
break; \
case 0x0a: \
out = D & ~P; \
break; \
case 0x0b: \
out = ~(P | (S & ~D)); \
break; \
case 0x0c: \
out = S & ~P; \
break; \
case 0x0d: \
out = ~(P | (D & ~S)); \
break; \
case 0x0e: \
out = ~(P | ~(D | S)); \
break; \
case 0x0f: \
out = ~P; \
break; \
case 0x10: \
out = P & ~(D | S); \
break; \
case 0x11: \
out = ~(D | S); \
break; \
case 0x12: \
out = ~(S | ~(D ^ P)); \
break; \
case 0x13: \
out = ~(S | (D & P)); \
break; \
case 0x14: \
out = ~(D | ~(P ^ S)); \
break; \
case 0x15: \
out = ~(D | (P & S)); \
break; \
case 0x16: \
out = P ^ (S ^ (D & ~(P & S))); \
break; \
case 0x17: \
out = ~(S ^ ((S ^ P) & (D ^ S))); \
break; \
case 0x18: \
out = (S ^ P) & (P ^ D); \
break; \
case 0x19: \
out = ~(S ^ (D & ~(P & S))); \
break; \
case 0x1a: \
out = P ^ (D | (S & P)); \
break; \
case 0x1b: \
out = ~(S ^ (D & (P ^ S))); \
break; \
case 0x1c: \
out = P ^ (S | (D & P)); \
break; \
case 0x1d: \
out = ~(D ^ (S & (P ^ D))); \
break; \
case 0x1e: \
out = P ^ (D | S); \
break; \
case 0x1f: \
out = ~(P & (D | S)); \
break; \
case 0x20: \
out = D & (P & ~S); \
break; \
case 0x21: \
out = ~(S | (D ^ P)); \
break; \
case 0x22: \
out = D & ~S; \
break; \
case 0x23: \
out = ~(S | (P & ~D)); \
break; \
case 0x24: \
out = (S ^ P) & (D ^ S); \
break; \
case 0x25: \
out = ~(P ^ (D & ~(S & P))); \
break; \
case 0x26: \
out = S ^ (D | (P & S)); \
break; \
case 0x27: \
out = S ^ (D | ~(P ^ S)); \
break; \
case 0x28: \
out = D & (P ^ S); \
break; \
case 0x29: \
out = ~(P ^ (S ^ (D | (P & S)))); \
break; \
case 0x2a: \
out = D & ~(P & S); \
break; \
case 0x2b: \
out = ~(S ^ ((S ^ P) & (P ^ D))); \
break; \
case 0x2c: \
out = S ^ (P & (D | S)); \
break; \
case 0x2d: \
out = P ^ (S | ~D); \
break; \
case 0x2e: \
out = P ^ (S | (D ^ P)); \
break; \
case 0x2f: \
out = ~(P & (S | ~D)); \
break; \
case 0x30: \
out = P & ~S; \
break; \
case 0x31: \
out = ~(S | (D & ~P)); \
break; \
case 0x32: \
out = S ^ (D | (P | S)); \
break; \
case 0x33: \
out = ~S; \
break; \
case 0x34: \
out = S ^ (P | (D & S)); \
break; \
case 0x35: \
out = S ^ (P | ~(D ^ S)); \
break; \
case 0x36: \
out = S ^ (D | P); \
break; \
case 0x37: \
out = ~(S & (D | P)); \
break; \
case 0x38: \
out = P ^ (S & (D | P)); \
break; \
case 0x39: \
out = S ^ (P | ~D); \
break; \
case 0x3a: \
out = S ^ (P | (D ^ S)); \
break; \
case 0x3b: \
out = ~(S & (P | ~D)); \
break; \
case 0x3c: \
out = P ^ S; \
break; \
case 0x3d: \
out = S ^ (P | ~(D | S)); \
break; \
case 0x3e: \
out = S ^ (P | (D & ~S)); \
break; \
case 0x3f: \
out = ~(P & S); \
break; \
case 0x40: \
out = P & (S & ~D); \
break; \
case 0x41: \
out = ~(D | (P ^ S)); \
break; \
case 0x42: \
out = (S ^ D) & (P ^ D); \
break; \
case 0x43: \
out = ~(S ^ (P & ~(D & S))); \
break; \
case 0x44: \
out = S & ~D; \
break; \
case 0x45: \
out = ~(D | (P & ~S)); \
break; \
case 0x46: \
out = D ^ (S | (P & D)); \
break; \
case 0x47: \
out = ~(P ^ (S & (D ^ P))); \
break; \
case 0x48: \
out = S & (D ^ P); \
break; \
case 0x49: \
out = ~(P ^ (D ^ (S | (P & D)))); \
break; \
case 0x4a: \
out = D ^ (P & (S | D)); \
break; \
case 0x4b: \
out = P ^ (D | ~S); \
break; \
case 0x4c: \
out = S & ~(D & P); \
break; \
case 0x4d: \
out = ~(S ^ ((S ^ P) | (D ^ S))); \
break; \
case 0x4e: \
out = P ^ (D | (S ^ P)); \
break; \
case 0x4f: \
out = ~(P & (D | ~S)); \
break; \
case 0x50: \
out = P & ~D; \
break; \
case 0x51: \
out = ~(D | (S & ~P)); \
break; \
case 0x52: \
out = D ^ (P | (S & D)); \
break; \
case 0x53: \
out = ~(S ^ (P & (D ^ S))); \
break; \
case 0x54: \
out = ~(D | ~(P | S)); \
break; \
case 0x55: \
out = ~D; \
break; \
case 0x56: \
out = D ^ (P | S); \
break; \
case 0x57: \
out = ~(D & (P | S)); \
break; \
case 0x58: \
out = P ^ (D & (S | P)); \
break; \
case 0x59: \
out = D ^ (P | ~S); \
break; \
case 0x5a: \
out = D ^ P; \
break; \
case 0x5b: \
out = D ^ (P | ~(S | D)); \
break; \
case 0x5c: \
out = D ^ (P | (S ^ D)); \
break; \
case 0x5d: \
out = ~(D & (P | ~S)); \
break; \
case 0x5e: \
out = D ^ (P | (S & ~D)); \
break; \
case 0x5f: \
out = ~(D & P); \
break; \
case 0x60: \
out = P & (D ^ S); \
break; \
case 0x61: \
out = ~(D ^ (S ^ (P | (D & S)))); \
break; \
case 0x62: \
out = D ^ (S & (P | D)); \
break; \
case 0x63: \
out = S ^ (D | ~P); \
break; \
case 0x64: \
out = S ^ (D & (P | S)); \
break; \
case 0x65: \
out = D ^ (S | ~P); \
break; \
case 0x66: \
out = D ^ S; \
break; \
case 0x67: \
out = S ^ (D | ~(P | S)); \
break; \
case 0x68: \
out = ~(D ^ (S ^ (P | ~(D | S)))); \
break; \
case 0x69: \
out = ~(P ^ (D ^ S)); \
break; \
case 0x6a: \
out = D ^ (P & S); \
break; \
case 0x6b: \
out = ~(P ^ (S ^ (D & (P | S)))); \
break; \
case 0x6c: \
out = S ^ (D & P); \
break; \
case 0x6d: \
out = ~(P ^ (D ^ (S & (P | D)))); \
break; \
case 0x6e: \
out = S ^ (D & (P | ~S)); \
break; \
case 0x6f: \
out = ~(P & ~(D ^ S)); \
break; \
case 0x70: \
out = P & ~(D & S); \
break; \
case 0x71: \
out = ~(S ^ ((S ^ D) & (P ^ D))); \
break; \
case 0x72: \
out = S ^ (D | (P ^ S)); \
break; \
case 0x73: \
out = ~(S & (D | ~P)); \
break; \
case 0x74: \
out = D ^ (S | (P ^ D)); \
break; \
case 0x75: \
out = ~(D & (S | ~P)); \
break; \
case 0x76: \
out = S ^ (D | (P & ~S)); \
break; \
case 0x77: \
out = ~(D & S); \
break; \
case 0x78: \
out = P ^ (D & S); \
break; \
case 0x79: \
out = ~(D ^ (S ^ (P & (D | S)))); \
break; \
case 0x7a: \
out = D ^ (P & (S | ~D)); \
break; \
case 0x7b: \
out = ~(S & ~(D ^ P)); \
break; \
case 0x7c: \
out = S ^ (P & (D | ~S)); \
break; \
case 0x7d: \
out = ~(D & ~(P ^ S)); \
break; \
case 0x7e: \
out = (S ^ P) | (D ^ S); \
break; \
case 0x7f: \
out = ~(D & (P & S)); \
break; \
case 0x80: \
out = D & (P & S); \
break; \
case 0x81: \
out = ~((S ^ P) | (D ^ S)); \
break; \
case 0x82: \
out = D & ~(P ^ S); \
break; \
case 0x83: \
out = ~(S ^ (P & (D | ~S))); \
break; \
case 0x84: \
out = S & ~(D ^ P); \
break; \
case 0x85: \
out = ~(P ^ (D & (S | ~P))); \
break; \
case 0x86: \
out = D ^ (S ^ (P & (D | S))); \
break; \
case 0x87: \
out = ~(P ^ (D & S)); \
break; \
case 0x88: \
out = D & S; \
break; \
case 0x89: \
out = ~(S ^ (D | (P & ~S))); \
break; \
case 0x8a: \
out = D & (S | ~P); \
break; \
case 0x8b: \
out = ~(D ^ (S | (P ^ D))); \
break; \
case 0x8c: \
out = S & (D | ~P); \
break; \
case 0x8d: \
out = ~(S ^ (D | (P ^ S))); \
break; \
case 0x8e: \
out = S ^ ((S ^ D) & (P ^ D)); \
break; \
case 0x8f: \
out = ~(P & ~(D & S)); \
break; \
case 0x90: \
out = P & ~(D ^ S); \
break; \
case 0x91: \
out = ~(S ^ (D & (P | ~S))); \
break; \
case 0x92: \
out = D ^ (P ^ (S & (D | P))); \
break; \
case 0x93: \
out = ~(S ^ (P & D)); \
break; \
case 0x94: \
out = P ^ (S ^ (D & (P | S))); \
break; \
case 0x95: \
out = ~(D ^ (P & S)); \
break; \
case 0x96: \
out = D ^ (P ^ S); \
break; \
case 0x97: \
out = P ^ (S ^ (D | ~(P | S))); \
break; \
case 0x98: \
out = ~(S ^ (D | ~(P | S))); \
break; \
case 0x99: \
out = ~(D ^ S); \
break; \
case 0x9a: \
out = D ^ (P & ~S); \
break; \
case 0x9b: \
out = ~(S ^ (D & (P | S))); \
break; \
case 0x9c: \
out = S ^ (P & ~D); \
break; \
case 0x9d: \
out = ~(D ^ (S & (P | D))); \
break; \
case 0x9e: \
out = D ^ (S ^ (P | (D & S))); \
break; \
case 0x9f: \
out = ~(P & (D ^ S)); \
break; \
case 0xa0: \
out = D & P; \
break; \
case 0xa1: \
out = ~(P ^ (D | (S & ~P))); \
break; \
case 0xa2: \
out = D & (P | ~S); \
break; \
case 0xa3: \
out = ~(D ^ (P | (S ^ D))); \
break; \
case 0xa4: \
out = ~(P ^ (D | ~(S | P))); \
break; \
case 0xa5: \
out = ~(P ^ D); \
break; \
case 0xa6: \
out = D ^ (S & ~P); \
break; \
case 0xa7: \
out = ~(P ^ (D & (S | P))); \
break; \
case 0xa8: \
out = D & (P | S); \
break; \
case 0xa9: \
out = ~(D ^ (P | S)); \
break; \
case 0xaa: \
out = D; \
break; \
case 0xab: \
out = D | ~(P | S); \
break; \
case 0xac: \
out = S ^ (P & (D ^ S)); \
break; \
case 0xad: \
out = ~(D ^ (P | (S & D))); \
break; \
case 0xae: \
out = D | (S & ~P); \
break; \
case 0xaf: \
out = D | ~P; \
break; \
case 0xb0: \
out = P & (D | ~S); \
break; \
case 0xb1: \
out = ~(P ^ (D | (S ^ P))); \
break; \
case 0xb2: \
out = S ^ ((S ^ P) | (D ^ S)); \
break; \
case 0xb3: \
out = ~(S & ~(D & P)); \
break; \
case 0xb4: \
out = P ^ (S & ~D); \
break; \
case 0xb5: \
out = ~(D ^ (P & (S | D))); \
break; \
case 0xb6: \
out = D ^ (P ^ (S | (D & P))); \
break; \
case 0xb7: \
out = ~(S & (D ^ P)); \
break; \
case 0xb8: \
out = P ^ (S & (D ^ P)); \
break; \
case 0xb9: \
out = ~(D ^ (S | (P & D))); \
break; \
case 0xba: \
out = D | (P & ~S); \
break; \
case 0xbb: \
out = D | ~S; \
break; \
case 0xbc: \
out = S ^ (P & ~(D & S)); \
break; \
case 0xbd: \
out = ~((S ^ D) & (P ^ D)); \
break; \
case 0xbe: \
out = D | (P ^ S); \
break; \
case 0xbf: \
out = D | ~(P & S); \
break; \
case 0xc0: \
out = P & S; \
break; \
case 0xc1: \
out = ~(S ^ (P | (D & ~S))); \
break; \
case 0xc2: \
out = ~(S ^ (P | ~(D | S))); \
break; \
case 0xc3: \
out = ~(P ^ S); \
break; \
case 0xc4: \
out = S & (P | ~D); \
break; \
case 0xc5: \
out = ~(S ^ (P | (D ^ S))); \
break; \
case 0xc6: \
out = S ^ (D & ~P); \
break; \
case 0xc7: \
out = ~(P ^ (S & (D | P))); \
break; \
case 0xc8: \
out = S & (D | P); \
break; \
case 0xc9: \
out = ~(S ^ (P | D)); \
break; \
case 0xca: \
out = D ^ (P & (S ^ D)); \
break; \
case 0xcb: \
out = ~(S ^ (P | (D & S))); \
break; \
case 0xcc: \
out = S; \
break; \
case 0xcd: \
out = S | ~(D | P); \
break; \
case 0xce: \
out = S | (D & ~P); \
break; \
case 0xcf: \
out = S | ~P; \
break; \
case 0xd0: \
out = P & (S | ~D); \
break; \
case 0xd1: \
out = ~(P ^ (S | (D ^ P))); \
break; \
case 0xd2: \
out = P ^ (D & ~S); \
break; \
case 0xd3: \
out = ~(S ^ (P & (D | S))); \
break; \
case 0xd4: \
out = S ^ ((S ^ P) & (P ^ D)); \
break; \
case 0xd5: \
out = ~(D & ~(P & S)); \
break; \
case 0xd6: \
out = P ^ (S ^ (D | (P & S))); \
break; \
case 0xd7: \
out = ~(D & (P ^ S)); \
break; \
case 0xd8: \
out = P ^ (D & (S ^ P)); \
break; \
case 0xd9: \
out = ~(S ^ (D | (P & S))); \
break; \
case 0xda: \
out = D ^ (P & ~(S & D)); \
break; \
case 0xdb: \
out = ~((S ^ P) & (D ^ S)); \
break; \
case 0xdc: \
out = S | (P & ~D); \
break; \
case 0xdd: \
out = S | ~D; \
break; \
case 0xde: \
out = S | (D ^ P); \
break; \
case 0xdf: \
out = S | ~(D & P); \
break; \
case 0xe0: \
out = P & (D | S); \
break; \
case 0xe1: \
out = ~(P ^ (D | S)); \
break; \
case 0xe2: \
out = D ^ (S & (P ^ D)); \
break; \
case 0xe3: \
out = ~(P ^ (S | (D & P))); \
break; \
case 0xe4: \
out = S ^ (D & (P ^ S)); \
break; \
case 0xe5: \
out = ~(P ^ (D | (S & P))); \
break; \
case 0xe6: \
out = S ^ (D & ~(P & S)); \
break; \
case 0xe7: \
out = ~((S ^ P) & (P ^ D)); \
break; \
case 0xe8: \
out = S ^ ((S ^ P) & (D ^ S)); \
break; \
case 0xe9: \
out = ~(D ^ (S ^ (P & ~(D & S)))); \
break; \
case 0xea: \
out = D | (P & S); \
break; \
case 0xeb: \
out = D | ~(P ^ S); \
break; \
case 0xec: \
out = S | (D & P); \
break; \
case 0xed: \
out = S | ~(D ^ P); \
break; \
case 0xee: \
out = D | S; \
break; \
case 0xef: \
out = S | (D | ~P); \
break; \
case 0xf0: \
out = P; \
break; \
case 0xf1: \
out = P | ~(D | S); \
break; \
case 0xf2: \
out = P | (D & ~S); \
break; \
case 0xf3: \
out = P | ~S; \
break; \
case 0xf4: \
out = P | (S & ~D); \
break; \
case 0xf5: \
out = P | ~D; \
break; \
case 0xf6: \
out = P | (D ^ S); \
break; \
case 0xf7: \
out = P | ~(D & S); \
break; \
case 0xf8: \
out = P | (D & S); \
break; \
case 0xf9: \
out = P | ~(D ^ S); \
break; \
case 0xfa: \
out = D | P; \
break; \
case 0xfb: \
out = D | (P | ~S); \
break; \
case 0xfc: \
out = P | S; \
break; \
case 0xfd: \
out = P | (S | ~D); \
break; \
case 0xfe: \
out = D | (P | S); \
break; \
case 0xff: \
out = ~0; \
break; \
} \
}
#define MIX() \
do { \
out = 0; \
ROPMIX(tgui->accel.rop, dst_dat, pat_dat, src_dat, out); \
} while (0)
#define WRITE(addr, dat) \
@@ -1490,8 +2256,6 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
const uint32_t *pattern_data;
int x;
int y;
int c;
int d;
uint32_t out;
uint32_t src_dat = 0;
uint32_t dst_dat;