mcs51.cpp: Eliminate atrocious hack for breaking out of INT0 polling loops (nw)

This commit is contained in:
AJR 2018-05-09 15:22:13 -04:00
parent f1f51408d2
commit 2321d8eeb3
5 changed files with 22 additions and 41 deletions

View File

@ -1770,10 +1770,6 @@ void mcs51_cpu_device::check_irqs()
return;
}
/* also break out of jb int0,<self> loops */
if (ROP(PC) == 0x20 && ROP_ARG(PC+1) == 0xb2 && ROP_ARG(PC+2) == 0xfd)
PC += 3;
//Save current pc to stack, set pc to new interrupt vector
push_pc();
PC = int_vec;

View File

@ -570,32 +570,19 @@ READ8_MEMBER( segas16a_state::mcu_io_r )
//**************************************************************************
//-------------------------------------------------
// mcu_irq_assert - signal an interrupt to the
// I8751 MCU, and boost interleave to ensure
// good synchronization with the main CPU
//-------------------------------------------------
INTERRUPT_GEN_MEMBER( segas16a_state::mcu_irq_assert )
{
// toggle the INT0 line on the MCU
m_mcu->set_input_line(MCS51_INT0_LINE, ASSERT_LINE);
m_mcu->set_input_line(MCS51_INT0_LINE, CLEAR_LINE);
// boost interleave to ensure that the MCU can break the M68000 out of a STOP
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100));
}
//-------------------------------------------------
// i8751_main_cpu_vblank - if we have a fake
// i8751_main_cpu_vblank_w - if we have a fake
// handler, we hook this to execute it
//-------------------------------------------------
INTERRUPT_GEN_MEMBER( segas16a_state::i8751_main_cpu_vblank )
WRITE_LINE_MEMBER(segas16a_state::i8751_main_cpu_vblank_w)
{
// if we have a fake 8751 handler, call it on VBLANK
if (!m_i8751_vblank_hook.isnull())
if (state && !m_i8751_vblank_hook.isnull())
m_i8751_vblank_hook();
// if we have a 8751, toggle the INT0 line on the MCU
if (m_mcu.found())
m_mcu->set_input_line(MCS51_INT0_LINE, state);
}
@ -2060,12 +2047,14 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(segas16a_state::system16a_i8751)
system16a(config);
MCFG_DEVICE_MODIFY("maincpu")
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", segas16a_state, i8751_main_cpu_vblank)
MCFG_DEVICE_VBLANK_INT_REMOVE()
MCFG_DEVICE_ADD("mcu", I8751, 8000000)
MCFG_DEVICE_IO_MAP(mcu_io_map)
MCFG_MCS51_PORT_P1_OUT_CB(WRITE8(*this, segas16a_state, mcu_control_w))
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", segas16a_state, mcu_irq_assert)
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, segas16a_state, i8751_main_cpu_vblank_w))
MACHINE_CONFIG_END

View File

@ -583,6 +583,11 @@ WRITE8_MEMBER(system1_state::mcu_control_w)
Bit 1 -> n/c
Bit 0 -> Directly connected to Z80 /INT line
*/
/* boost interleave to ensure that the MCU can break the Z80 out of a HALT */
if (!BIT(m_mcu_control, 6) && BIT(data, 6))
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(10));
m_mcu_control = data;
m_maincpu->set_input_line(INPUT_LINE_HALT, (data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(0, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
@ -630,17 +635,6 @@ READ8_MEMBER(system1_state::mcu_io_r)
}
INTERRUPT_GEN_MEMBER(system1_state::mcu_irq_assert)
{
/* toggle the INT0 line on the MCU */
device.execute().set_input_line(MCS51_INT0_LINE, ASSERT_LINE);
device.execute().set_input_line(MCS51_INT0_LINE, CLEAR_LINE);
/* boost interleave to ensure that the MCU can break the Z80 out of a HALT */
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(10));
}
TIMER_DEVICE_CALLBACK_MEMBER(system1_state::mcu_t0_callback)
{
/* The T0 line is clocked by something; if it is not clocked fast
@ -2455,7 +2449,11 @@ MACHINE_CONFIG_START(system1_state::mcu)
MCFG_DEVICE_ADD("mcu", I8751, SOUND_CLOCK)
MCFG_DEVICE_IO_MAP(mcu_io_map)
MCFG_MCS51_PORT_P1_OUT_CB(WRITE8(*this, system1_state, mcu_control_w))
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", system1_state, mcu_irq_assert)
MCFG_DEVICE_MODIFY("screen")
MCFG_SCREEN_VBLANK_CALLBACK(INPUTLINE("mcu", MCS51_INT0_LINE))
// This interrupt is driven by pin 15 of a PAL16R4 (315-5138 on Choplifter), based on the vertical count.
// The actual duty cycle likely differs from VBLANK, which is another output from the same PAL.
MCFG_TIMER_DRIVER_ADD_PERIODIC("mcu_t0", system1_state, mcu_t0_callback, attotime::from_usec(2500))
MACHINE_CONFIG_END

View File

@ -83,8 +83,7 @@ public:
DECLARE_READ8_MEMBER( mcu_io_r );
// I8751-related VBLANK interrupt handlers
INTERRUPT_GEN_MEMBER( mcu_irq_assert );
INTERRUPT_GEN_MEMBER( i8751_main_cpu_vblank );
DECLARE_WRITE_LINE_MEMBER(i8751_main_cpu_vblank_w);
// game-specific driver init
DECLARE_DRIVER_INIT(generic);

View File

@ -119,7 +119,6 @@ public:
uint32_t screen_update_system1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_system2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_system2_rowscroll(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(mcu_irq_assert);
TIMER_DEVICE_CALLBACK_MEMBER(soundirq_gen);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_t0_callback);
DECLARE_WRITE8_MEMBER(system1_videoram_bank_w);