diff options
Diffstat (limited to 'src/devices/machine/mc14411.cpp')
-rw-r--r-- | src/devices/machine/mc14411.cpp | 115 |
1 files changed, 55 insertions, 60 deletions
diff --git a/src/devices/machine/mc14411.cpp b/src/devices/machine/mc14411.cpp index d8ce720a0f3..66f53b2ec67 100644 --- a/src/devices/machine/mc14411.cpp +++ b/src/devices/machine/mc14411.cpp @@ -33,23 +33,15 @@ MACROS ***************************************************************************/ -//#define LOG_GENERAL (1U << 0) // Already defined in logmacro.h -#define LOG_SETUP (1U << 1) +#define LOG_SETUP (1U << 1) //#define VERBOSE (LOG_GENERAL|LOG_SETUP) //#define LOG_OUTPUT_STREAM std::cout #include "logmacro.h" -//#define LOG(...) LOGMASKED(LOG_GENERAL, __VA_ARGS__) // Already defined in logmacro.h #define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) -#ifdef _MSC_VER -#define FUNCNAME __func__ -#else -#define FUNCNAME __PRETTY_FUNCTION__ -#endif - /*************************************************************************** INTERNAL TABLES @@ -102,7 +94,7 @@ mc14411_device::mc14411_device(const machine_config &mconfig, const char *tag, d mc14411_device::mc14411_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) - , m_out_fx_cbs{*this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this } + , m_out_fx_cbs(*this) , m_divider(0) , m_reset(CLEAR_LINE) { @@ -115,20 +107,20 @@ mc14411_device::mc14411_device(const machine_config &mconfig, device_type type, void mc14411_device::device_start() { - LOGSETUP("%s\n", FUNCNAME); + LOGSETUP("mc14411_device::device_start\n"); for (int i = TIMER_F1; i <= TIMER_F16; i++) { - m_out_fx_cbs[i].resolve(); - m_fx_timer[i] = timer_alloc(i); - m_timer_enabled[i] = !m_out_fx_cbs[i].isnull(); + m_fx_timers[i].timer = timer_alloc(FUNC(mc14411_device::timer_tick), this); + m_fx_timers[i].enabled = true; } save_item(NAME(m_divider)); save_item(NAME(m_reset)); - save_item(NAME(m_timer_enabled)); + save_item(STRUCT_MEMBER(m_fx_timers, state)); + save_item(STRUCT_MEMBER(m_fx_timers, enabled)); - m_reset_timer = timer_alloc(TIMER_ID_RESET); + m_reset_timer = timer_alloc(FUNC(mc14411_device::reset_tick), this); } @@ -141,7 +133,7 @@ void mc14411_device::device_clock_changed() { for (int i = TIMER_F1; i <= TIMER_F16; i++) { - if (m_timer_enabled[i]) + if (m_fx_timers[i].enabled) arm_timer(i); } } @@ -154,18 +146,18 @@ void mc14411_device::device_clock_changed() void mc14411_device::timer_enable(timer_id i, bool enable) { assert(i >= TIMER_F1 && i <= TIMER_F16); - m_timer_enabled[i] = enable; + m_fx_timers[i].enabled = enable; if (!enable) - m_fx_timer[i]->enable(false); - else if (!m_fx_timer[i]->enabled()) + m_fx_timers[i].timer->enable(false); + else if (!m_fx_timers[i].timer->enabled()) arm_timer(i); } void mc14411_device::timer_disable_all() { for (int i = TIMER_F1; i <= TIMER_F16; i++) - timer_enable((timer_id) i, false); + timer_enable((timer_id)i, false); } //------------------------------------------------- @@ -175,13 +167,13 @@ void mc14411_device::timer_disable_all() void mc14411_device::arm_timer(int i) { - assert(!m_out_fx_cbs[i].isnull()); - + if (m_out_fx_cbs[i].isunset()) + return; int divider = s_counter_divider[i]; if (i < TIMER_F15) divider *= s_divider_select[m_divider]; attotime half_cycle = clocks_to_attotime(divider) / 2; // 2 flanks per cycle - m_fx_timer[i]->adjust(half_cycle, i, half_cycle); + m_fx_timers[i].timer->adjust(half_cycle, i, half_cycle); LOGSETUP(" - arming timer for F%d at %fHz (/%d)\n", i + 1, double(clock()) / divider, divider); } @@ -193,47 +185,47 @@ void mc14411_device::arm_timer(int i) void mc14411_device::device_reset() { - LOGSETUP("%s\n", FUNCNAME); + LOGSETUP("mc14411_device::device_reset\n"); for (int i = TIMER_F1; i <= TIMER_F16; i++) { - if (!m_out_fx_cbs[i].isnull()) - { - // Reset line according to datasheet and remember it for transitions to come - (m_out_fx_cbs[i])(m_fx_state[i] = (i < TIMER_F15 ? 0 : 1)); - } + // Reset line according to datasheet and remember it for transitions to come + m_fx_timers[i].state = !(i < TIMER_F15); + if (!m_out_fx_cbs[i].isunset()) + m_out_fx_cbs[i](m_fx_timers[i].state); } if (m_reset == ASSERT_LINE) { - m_reset_timer->adjust(attotime::from_nsec((double)900), TIMER_ID_RESET, attotime::from_nsec((double)900)); + m_reset_timer->adjust(attotime::from_nsec(900)); } } //------------------------------------------------- -// device_timer - handler timer events +// timer_tick - update the output state for a +// given Fx timer //------------------------------------------------- -void mc14411_device::device_timer(emu_timer &timer, device_timer_id id, int32_t param, void *ptr) +TIMER_CALLBACK_MEMBER(mc14411_device::timer_tick) { - if (id >= TIMER_F1 && id <= TIMER_F16) - { - (m_out_fx_cbs[id])(m_fx_state[id]++ & 1); - } - else if (id == TIMER_ID_RESET) - { - // NOTE: This check could be triggered by either faulty hardware design or non accurate emulation so is just informative if the reset line is handled - // explicitelly instead of relying on calling device_reset - if (!(m_reset == ASSERT_LINE)) - { - LOG("Reset pulse is too short, should be 900nS minimum"); - logerror("Reset pulse is too short, should be 900nS minimum"); - } - } - else + m_out_fx_cbs[param](m_fx_timers[param].state); + m_fx_timers[param].state = !m_fx_timers[param].state; +} + + +//------------------------------------------------- +// reset_tick - log information if the device's +// reset pulse is too short +//------------------------------------------------- + +TIMER_CALLBACK_MEMBER(mc14411_device::reset_tick) +{ + // NOTE: This check could be triggered by either faulty hardware design or non accurate emulation so is just informative if the reset line is handled + // explicitelly instead of relying on calling device_reset + if (!(m_reset == ASSERT_LINE)) { - LOG("Unhandled Timer ID %d\n", id); + LOG("Reset pulse is too short, should be 900nS minimum"); } } @@ -244,14 +236,15 @@ void mc14411_device::device_timer(emu_timer &timer, device_timer_id id, int32_t // divider at run time affects wave forms //-------------------------------------------------------- -WRITE8_MEMBER(mc14411_device::rate_select_w) +void mc14411_device::rate_select_w(uint8_t data) { - LOGSETUP("%s %02x\n", FUNCNAME, data); + LOGSETUP("mc14411_device::rate_select_w %02x\n", data); if (m_divider != (data & 3)) { m_divider = data & 3; - notify_clock_changed(); + if (started()) + notify_clock_changed(); } } @@ -260,14 +253,15 @@ WRITE8_MEMBER(mc14411_device::rate_select_w) // rsa_w - set RSA input line //------------------------------------------------ -WRITE_LINE_MEMBER(mc14411_device::rsa_w) +void mc14411_device::rsa_w(int state) { - LOGSETUP("%s %02x\n", FUNCNAME, state); + LOGSETUP("mc14411_device::rsa_w %02x\n", state); if ((m_divider & RSA) != (state == ASSERT_LINE ? RSA : 0)) { m_divider = (m_divider & ~RSA) | (state == ASSERT_LINE ? RSA : 0); - notify_clock_changed(); + if (started()) + notify_clock_changed(); } } @@ -276,14 +270,15 @@ WRITE_LINE_MEMBER(mc14411_device::rsa_w) // rsb_w - set RSB input line //------------------------------------------------ -WRITE_LINE_MEMBER(mc14411_device::rsb_w) +void mc14411_device::rsb_w(int state) { - LOGSETUP("%s %02x\n", FUNCNAME, state); + LOGSETUP("mc14411_device::rsb_w %02x\n", state); if ((m_divider & RSB) != (state == ASSERT_LINE ? RSB : 0)) { m_divider = (m_divider & ~RSB) | (state == ASSERT_LINE ? RSB : 0); - notify_clock_changed(); + if (started()) + notify_clock_changed(); } } @@ -292,9 +287,9 @@ WRITE_LINE_MEMBER(mc14411_device::rsb_w) // reset_w - software controlled reset //------------------------------------------------ -WRITE_LINE_MEMBER(mc14411_device::reset_w) +void mc14411_device::reset_w(int state) { - LOGSETUP("%s %02x\n", FUNCNAME, state); + LOGSETUP("mc14411_device::reset_w %02x\n", state); m_reset = state; |