voodoo: Separate vblank (external) and pci interrupt (internal) callbacks. (nw)

This commit is contained in:
Ted Green 2017-06-14 08:58:31 -06:00
parent debee6c3a9
commit 0a6e3d9022
3 changed files with 40 additions and 17 deletions

View File

@ -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");
// 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;
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);
// 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)
{
}

View File

@ -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<voodoo_device &>(device).m_cputag = tag; }
template <class Object> static devcb_base &static_set_vblank_callback(device_t &device, Object &&cb) { return downcast<voodoo_device &>(device).m_vblank.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &static_set_stall_callback(device_t &device, Object &&cb) { return downcast<voodoo_device &>(device).m_stall.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &static_set_pciint_callback(device_t &device, Object &&cb) { return downcast<voodoo_device &>(device).m_pciint.set_callback(std::forward<Object>(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 );

View File

@ -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)