// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/*****************************************************************************
54/74161 4-bit binary counter
*****************************************************************************/
#include "emu.h"
#include "74161.h"
DEFINE_DEVICE_TYPE(TTL74160, ttl74160_device, "ttl74160", "54/74160 Decade Counter")
DEFINE_DEVICE_TYPE(TTL74161, ttl74161_device, "ttl74161", "54/74161 Binary Counter")
DEFINE_DEVICE_TYPE(TTL74162, ttl74162_device, "ttl74162", "54/74162 Decade Counter")
DEFINE_DEVICE_TYPE(TTL74163, ttl74163_device, "ttl74163", "54/74163 Binary Counter")
ttl7416x_device::ttl7416x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool synchronous_reset, uint8_t limit)
: device_t(mconfig, type, tag, owner, clock)
, m_qa_func(*this)
, m_qb_func(*this)
, m_qc_func(*this)
, m_qd_func(*this)
, m_output_func(*this)
, m_tc_func(*this)
, m_clear(0)
, m_pe(0)
, m_cet(0)
, m_cep(0)
, m_clock(0)
, m_p(0)
, m_out(0)
, m_tc(0)
, m_synchronous_reset(synchronous_reset)
, m_limit(limit)
{
}
ttl74160_device::ttl74160_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7416x_device(mconfig, TTL74160, tag, owner, clock, false, 10)
{
}
ttl74161_device::ttl74161_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7416x_device(mconfig, TTL74161, tag, owner, clock, false, 16)
{
}
ttl74162_device::ttl74162_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7416x_device(mconfig, TTL74162, tag, owner, clock, true, 10)
{
}
ttl74163_device::ttl74163_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7416x_device(mconfig, TTL74163, tag, owner, clock, true, 16)
{
}
void ttl7416x_device::device_start()
{
save_item(NAME(m_clear));
save_item(NAME(m_pe));
save_item(NAME(m_cet));
save_item(NAME(m_cep));
save_item(NAME(m_clock));
save_item(NAME(m_p));
save_item(NAME(m_out));
save_item(NAME(m_tc));
m_output_func.resolve_safe();
m_tc_func.resolve_safe();
}
void ttl7416x_device::device_reset()
{
init();
}
void ttl7416x_device::init()
{
m_clear = 0;
m_pe = 1;
m_cet = 0;
m_cep = 0;
m_clock = 0;
m_p = 0;
m_out = 0;
m_tc = 0;
m_tc = 0;
}
void ttl7416x_device::tick()
{
if (m_synchronous_reset && m_clear)
{
init();
return;
}
uint8_t last_out = m_out;
uint8_t last_tc = m_tc;
if (m_pe)
{
m_out = m_p & 0xf;
}
else
{
if (bool(m_cet) && bool(m_cep))
{
increment();
}
}
if (m_out != last_out)
{
m_output_func(m_out);
}
if (m_tc != last_tc)
{
m_tc_func(m_tc);
}
}
void ttl7416x_device::increment()
{
m_out = (m_out + 1) % (m_limit + 1);
if (m_out == m_limit)
m_tc = 1;
else
m_tc = 0;
}
WRITE_LINE_MEMBER( ttl7416x_device::clear_w )
{
m_clear = state;
if (!m_synchronous_reset)
init();
}
WRITE_LINE_MEMBER( ttl7416x_device::pe_w )
{
m_pe = state ^ 1;
}
WRITE_LINE_MEMBER( ttl7416x_device::cet_w )
{
m_cet = state;
}
WRITE_LINE_MEMBER( ttl7416x_device::cep_w )
{
m_cep = state;
}
WRITE_LINE_MEMBER( ttl7416x_device::clock_w )
{
uint8_t last_clock = m_clock;
m_clock = state;
if (m_clock != last_clock && m_clock != 0)
{
tick();
}
}
WRITE8_MEMBER( ttl7416x_device::p_w )
{
m_p = data & 0xf;
}
WRITE_LINE_MEMBER( ttl7416x_device::p1_w )
{
m_p &= ~(1 << 0);
m_p |= (state << 0);
}
WRITE_LINE_MEMBER( ttl7416x_device::p2_w )
{
m_p &= ~(1 << 1);
m_p |= (state << 1);
}
WRITE_LINE_MEMBER( ttl7416x_device::p3_w )
{
m_p &= ~(1 << 2);
m_p |= (state << 2);
}
WRITE_LINE_MEMBER( ttl7416x_device::p4_w )
{
m_p &= ~(1 << 3);
m_p |= (state << 3);
}
READ_LINE_MEMBER( ttl7416x_device::output_r )
{
return m_out;
}
READ_LINE_MEMBER( ttl7416x_device::tc_r )
{
return m_tc;
}