summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/voodoo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/voodoo.cpp')
-rw-r--r--src/devices/video/voodoo.cpp46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp
index e0aaccf152d..7b4ef712931 100644
--- a/src/devices/video/voodoo.cpp
+++ b/src/devices/video/voodoo.cpp
@@ -943,11 +943,14 @@ TIMER_CALLBACK_MEMBER( voodoo_device::vblank_off_callback )
if (reg[intrCtrl].u & 0x8) // call IRQ handler if VSYNC interrupt (falling) is enabled
{
reg[intrCtrl].u |= 0x200; // VSYNC int (falling) active
-
- if (!m_vblank.isnull())
- m_vblank(false);
+ reg[intrCtrl].u &= ~0x80000000;
+ if (!m_pciint.isnull())
+ m_pciint(true);
}
+ // External vblank handler
+ if (!m_vblank.isnull())
+ m_vblank(false);
}
else
{
@@ -999,10 +1002,13 @@ TIMER_CALLBACK_MEMBER( voodoo_device::vblank_callback )
if (reg[intrCtrl].u & 0x4) // call IRQ handler if VSYNC interrupt (rising) is enabled
{
reg[intrCtrl].u |= 0x100; // VSYNC int (rising) active
-
- if (!m_vblank.isnull())
- m_vblank(true);
+ reg[intrCtrl].u &= ~0x80000000;
+ if (!m_pciint.isnull())
+ m_pciint(true);
}
+ // External vblank handler
+ if (!m_vblank.isnull())
+ m_vblank(true);
}
else
{
@@ -2188,6 +2194,14 @@ int32_t voodoo_device::register_w(voodoo_device *vd, offs_t offset, uint32_t dat
/* switch off the register */
switch (regnum)
{
+ case intrCtrl:
+ // Setting bit 31 clears the PCI interrupts
+ if (data & 0x80000000) {
+ // Clear pci interrupt
+ if (!vd->m_pciint.isnull())
+ vd->m_pciint(false);
+ }
+ break;
/* Vertex data is 12.4 formatted fixed point */
case fvertexAx:
data = float_to_int32(data, 4);
@@ -2490,14 +2504,16 @@ int32_t voodoo_device::register_w(voodoo_device *vd, offs_t offset, uint32_t dat
case userIntrCMD:
poly_wait(vd->poly, vd->regnames[regnum]);
- //fatalerror("userIntrCMD\n");
-
- vd->reg[intrCtrl].u |= 0x1800;
- vd->reg[intrCtrl].u &= ~0x80000000;
-
- // TODO: rename vblank_client for less confusion?
- if (!vd->m_vblank.isnull())
- vd->m_vblank(true);
+ // Bit 5 of intrCtrl enables user interrupts
+ if (vd->reg[intrCtrl].u & 0x20) {
+ // Bits 19:12 are set to cmd 9:2, bit 11 is user interrupt flag
+ vd->reg[intrCtrl].u |= ((data << 10) & 0x000ff000) | 0x800;
+ vd->reg[intrCtrl].u &= ~0x80000000;
+
+ // Signal pci interrupt handler
+ if (!vd->m_pciint.isnull())
+ vd->m_pciint(true);
+ }
break;
/* gamma table access -- Voodoo/Voodoo2 only */
@@ -4956,6 +4972,7 @@ void voodoo_device::device_start()
freq = clock();
m_vblank.resolve();
m_stall.resolve();
+ m_pciint.resolve();
/* create a multiprocessor work queue */
poly = poly_alloc(machine(), 64, sizeof(poly_extra_data), 0);
@@ -5767,6 +5784,7 @@ voodoo_device::voodoo_device(const machine_config &mconfig, device_type type, co
, m_cputag(nullptr)
, m_vblank(*this)
, m_stall(*this)
+ , m_pciint(*this)
, vd_type(vdt)
{
}