mirror of
https://github.com/holub/mame
synced 2025-07-04 09:28:51 +03:00
ymfm: Also explicitly sync writes to the mode register to ensure timer control bits are handled in sync.
This commit is contained in:
parent
9afa0d3db2
commit
e6320fd823
@ -1388,25 +1388,19 @@ void ymfm_engine_base<RegisterType>::output(s32 &lsum, s32 &rsum, u8 rshift, s16
|
|||||||
template<class RegisterType>
|
template<class RegisterType>
|
||||||
void ymfm_engine_base<RegisterType>::write(u16 regnum, u8 data)
|
void ymfm_engine_base<RegisterType>::write(u16 regnum, u8 data)
|
||||||
{
|
{
|
||||||
|
// special case: writes to the mode register can impact IRQs;
|
||||||
|
// schedule these writes to ensure ordering with timers
|
||||||
|
if (regnum == RegisterType::REG_MODE)
|
||||||
|
{
|
||||||
|
m_device.machine().scheduler().synchronize(timer_expired_delegate(FUNC(ymfm_engine_base<RegisterType>::synced_mode_w), this), data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// most writes are passive, consumed only when needed
|
// most writes are passive, consumed only when needed
|
||||||
m_regs.write(regnum, data);
|
m_regs.write(regnum, data);
|
||||||
|
|
||||||
// handle writes to the mode register
|
|
||||||
if (regnum == RegisterType::REG_MODE)
|
|
||||||
{
|
|
||||||
// reset timer status
|
|
||||||
if (m_regs.reset_timer_b())
|
|
||||||
set_reset_status(0, STATUS_TIMERB);
|
|
||||||
if (m_regs.reset_timer_a())
|
|
||||||
set_reset_status(0, STATUS_TIMERA);
|
|
||||||
|
|
||||||
// load timers
|
|
||||||
update_timer(1, m_regs.load_timer_b());
|
|
||||||
update_timer(0, m_regs.load_timer_a());
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle writes to the keyon registers
|
// handle writes to the keyon registers
|
||||||
else if (regnum == RegisterType::REG_KEYON)
|
if (regnum == RegisterType::REG_KEYON)
|
||||||
{
|
{
|
||||||
u8 chnum = m_regs.keyon_channel();
|
u8 chnum = m_regs.keyon_channel();
|
||||||
if (chnum < RegisterType::CHANNELS)
|
if (chnum < RegisterType::CHANNELS)
|
||||||
@ -1654,6 +1648,29 @@ TIMER_CALLBACK_MEMBER(ymfm_engine_base<RegisterType>::check_interrupts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// synced_mode_w - handle a mode register write
|
||||||
|
// via timer callback
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<class RegisterType>
|
||||||
|
TIMER_CALLBACK_MEMBER(ymfm_engine_base<RegisterType>::synced_mode_w)
|
||||||
|
{
|
||||||
|
// actually write the mode register now
|
||||||
|
m_regs.write(RegisterType::REG_MODE, param);
|
||||||
|
|
||||||
|
// reset timer status
|
||||||
|
if (m_regs.reset_timer_b())
|
||||||
|
set_reset_status(0, STATUS_TIMERB);
|
||||||
|
if (m_regs.reset_timer_a())
|
||||||
|
set_reset_status(0, STATUS_TIMERA);
|
||||||
|
|
||||||
|
// load timers
|
||||||
|
update_timer(1, m_regs.load_timer_b());
|
||||||
|
update_timer(0, m_regs.load_timer_a());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Explicit template instantiation
|
// Explicit template instantiation
|
||||||
template class ymfm_engine_base<ymopm_registers>;
|
template class ymfm_engine_base<ymopm_registers>;
|
||||||
template class ymfm_engine_base<ymopn_registers>;
|
template class ymfm_engine_base<ymopn_registers>;
|
||||||
|
@ -790,6 +790,9 @@ private:
|
|||||||
// check interrupts
|
// check interrupts
|
||||||
TIMER_CALLBACK_MEMBER(check_interrupts);
|
TIMER_CALLBACK_MEMBER(check_interrupts);
|
||||||
|
|
||||||
|
// handle a mode register write
|
||||||
|
TIMER_CALLBACK_MEMBER(synced_mode_w);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
device_t &m_device; // reference to the owning device
|
device_t &m_device; // reference to the owning device
|
||||||
u32 m_env_counter; // envelope counter; low 2 bits are sub-counter
|
u32 m_env_counter; // envelope counter; low 2 bits are sub-counter
|
||||||
|
Loading…
Reference in New Issue
Block a user