mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
mcs51.cpp: Eliminate atrocious hack for breaking out of INT0 polling loops (nw)
This commit is contained in:
parent
f1f51408d2
commit
2321d8eeb3
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user