From 0a6e3d902295442504ba994546c528ace60bce6f Mon Sep 17 00:00:00 2001 From: Ted Green Date: Wed, 14 Jun 2017 08:58:31 -0600 Subject: voodoo: Separate vblank (external) and pci interrupt (internal) callbacks. (nw) --- src/devices/video/voodoo.cpp | 46 ++++++++++++++++++++++++++++++-------------- src/devices/video/voodoo.h | 5 +++++ src/mame/drivers/viper.cpp | 8 ++++---- 3 files changed, 41 insertions(+), 18 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) { } diff --git a/src/devices/video/voodoo.h b/src/devices/video/voodoo.h index 95b690e1b2c..5b90ba5f947 100644 --- a/src/devices/video/voodoo.h +++ b/src/devices/video/voodoo.h @@ -1428,6 +1428,8 @@ enum #define MCFG_VOODOO_STALL_CB(_devcb) \ devcb = &voodoo_device::static_set_stall_callback(*device, DEVCB_##_devcb); +#define MCFG_VOODOO_PCIINT_CB(_devcb) \ + devcb = &voodoo_device::static_set_pciint_callback(*device, DEVCB_##_devcb); /*************************************************************************** FUNCTION PROTOTYPES @@ -1446,6 +1448,7 @@ public: static void static_set_cpu_tag(device_t &device, const char *tag) { downcast(device).m_cputag = tag; } template static devcb_base &static_set_vblank_callback(device_t &device, Object &&cb) { return downcast(device).m_vblank.set_callback(std::forward(cb)); } template static devcb_base &static_set_stall_callback(device_t &device, Object &&cb) { return downcast(device).m_stall.set_callback(std::forward(cb)); } + template static devcb_base &static_set_pciint_callback(device_t &device, Object &&cb) { return downcast(device).m_pciint.set_callback(std::forward(cb)); } DECLARE_READ32_MEMBER( voodoo_r ); DECLARE_WRITE32_MEMBER( voodoo_w ); @@ -1457,6 +1460,8 @@ public: const char * m_cputag; devcb_write_line m_vblank; devcb_write_line m_stall; + // This is for internally generated PCI interrupts in Voodoo3 + devcb_write_line m_pciint; TIMER_CALLBACK_MEMBER( vblank_off_callback ); TIMER_CALLBACK_MEMBER( stall_cpu_callback ); diff --git a/src/mame/drivers/viper.cpp b/src/mame/drivers/viper.cpp index 632385f2a9f..c6632440e02 100644 --- a/src/mame/drivers/viper.cpp +++ b/src/mame/drivers/viper.cpp @@ -433,7 +433,7 @@ public: virtual void machine_start() override; virtual void machine_reset() override; uint32_t screen_update_viper(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(viper_vblank); + WRITE_LINE_MEMBER(voodoo_pciint); TIMER_CALLBACK_MEMBER(epic_global_timer_callback); TIMER_CALLBACK_MEMBER(ds2430_timer_callback); #if VIPER_DEBUG_EPIC_REGS @@ -2279,13 +2279,13 @@ INPUT_PORTS_END /*****************************************************************************/ -INTERRUPT_GEN_MEMBER(viper_state::viper_vblank) +WRITE_LINE_MEMBER(viper_state::voodoo_vblank) { mpc8240_interrupt(MPC8240_IRQ0); //mpc8240_interrupt(MPC8240_IRQ3); } -WRITE_LINE_MEMBER(viper_state::voodoo_vblank) +WRITE_LINE_MEMBER(viper_state::voodoo_pciint) { mpc8240_interrupt(MPC8240_IRQ4); } @@ -2325,7 +2325,6 @@ static MACHINE_CONFIG_START( viper ) MCFG_CPU_ADD("maincpu", MPC8240, 200000000) MCFG_PPC_BUS_FREQUENCY(100000000) MCFG_CPU_PROGRAM_MAP(viper_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", viper_state, viper_vblank) MCFG_PCI_BUS_LEGACY_ADD("pcibus", 0) MCFG_PCI_BUS_LEGACY_DEVICE(0, "mpc8240", mpc8240_pci_r, mpc8240_pci_w) @@ -2338,6 +2337,7 @@ static MACHINE_CONFIG_START( viper ) MCFG_VOODOO_SCREEN_TAG("screen") MCFG_VOODOO_CPU_TAG("maincpu") MCFG_VOODOO_VBLANK_CB(WRITELINE(viper_state,voodoo_vblank)) + MCFG_VOODOO_PCIINT_CB(WRITELINE(viper_state, voodoo_pciint)) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) -- cgit v1.2.3