summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/74157.cpp
blob: 1dc7eb1289b66f76850968c7dc2ff41a60333a1d (plain) (tree)
1
2
3
4
5
6
7
8
9
10




                                                                            
                                                                       
 


                                                                          


                                                           






                                                                           









                                                                            

                                                                                                 




                                                   
                                                                                                      
                                                               


 
                                                                                                                                 
                                                    

                          
                         
                           








                                                   


                                                   
                                                                                                            





                                                                  






                                                   

                            
                           
















                                                                            
                               
 
                                 







                                                   
                               
 
                                 








                                                   
                                
 
                                    










                                                   
                                
 
                                    










                                                   
                                        
 
                                    

                                           



                        

















                                                                
                                                                 






















                                                                
                                                                




                                      




























                                                                            
                                                   

                                    
                                        












                                                   
                                            

                             
                                                                                         
                    
                                                                                         







                                                                            
                           



                          
                                                                              
            
                                                                              






                                                                            
                                                                                   
 
                                                                                                      
                                                               
 
 





                                                                            
                                                                                       
 
                                                                                                        
                                                                

 
// license:BSD-3-Clause
// copyright-holders:AJR

/***************************************************************************

    74LS157/74HCT157 Quad 2 to 1-Line Data Selectors/Multiplexers (TTL)

    Often used to help feed 8-bit ROM data into a MSM5205 (which may
    require additional pullups for CMOS compatibility), and for many other
    purposes.

    74LS158 has inverted outputs; 74LS157 is non-inverting.

    74LS257 and 74LS258 have three-state outputs with an active-low enable,
    making these devices popular for bus-compatible applications which the
    emulation here is not particularly suitable for. When pin 15 is tied to
    GND, however, these devices become pin-compatible replacements for
    74LS157 and 74LS158; this substitution is somewhat common on arcade
    bootlegs.

***************************************************************************/

#include "emu.h"
#include "74157.h"


//**************************************************************************
//  74LS157 DEVICE
//**************************************************************************

DEFINE_DEVICE_TYPE(LS157, ls157_device, "ls157", "74LS157 Quad 2-to-1 Multiplexer")
DEFINE_DEVICE_TYPE(LS157_X2, ls157_x2_device, "ls157_x2", "74LS157 Quad 2-to-1 Multiplexer (x2)")

//-------------------------------------------------
//  ls157_device - constructor
//-------------------------------------------------

ls157_device::ls157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: ls157_device(mconfig, LS157, tag, owner, clock, 0x0f)
{
}

ls157_device::ls157_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 mask)
	: device_t(mconfig, type, tag, owner, clock)
	, m_a_in_cb(*this)
	, m_b_in_cb(*this)
	, m_out_cb(*this)
	, m_data_mask(mask)
{
	m_a = 0;
	m_b = 0;
	m_select = false;
	m_strobe = false;
}


//-------------------------------------------------
//  ls157_x2_device - constructor
//-------------------------------------------------

ls157_x2_device::ls157_x2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: ls157_device(mconfig, LS157_X2, tag, owner, clock, 0xff)
{
}


//-------------------------------------------------
//  device_start - perform device-specific
//  startup
//-------------------------------------------------

void ls157_device::device_start()
{
	// resolve callbacks
	m_a_in_cb.resolve();
	m_b_in_cb.resolve();
	m_out_cb.resolve();

	// register items for save state
	save_item(NAME(m_a));
	save_item(NAME(m_b));
	save_item(NAME(m_select));
	save_item(NAME(m_strobe));
}


//**************************************************************************
//  DATA INPUTS
//**************************************************************************

//-------------------------------------------------
//  a_w -- write nibble to A1-A4
//-------------------------------------------------

void ls157_device::a_w(u8 data)
{
	m_a = data & m_data_mask;
	update_output();
}


//-------------------------------------------------
//  b_w -- write nibble to B1-B4
//-------------------------------------------------

void ls157_device::b_w(u8 data)
{
	m_b = data & m_data_mask;
	update_output();
}


//-------------------------------------------------
//  ab_w -- write high nibble to A1-A4 and write
//  low nibble to B1-B4
//-------------------------------------------------

void ls157_device::ab_w(u8 data)
{
	assert(m_data_mask == 0x0f);
	m_a = data >> 4;
	m_b = data & 0xf;
	update_output();
}


//-------------------------------------------------
//  ba_w -- write high nibble to B1-B4 and write
//  low nibble to A1-A4
//-------------------------------------------------

void ls157_device::ba_w(u8 data)
{
	assert(m_data_mask == 0x0f);
	m_b = data >> 4;
	m_a = data & 0xf;
	update_output();
}


//-------------------------------------------------
//  interleave_w -- write even-numbered bits to
//  A1-A4 and write odd-numbered bits to B1-B4
//-------------------------------------------------

void ls157_device::interleave_w(u8 data)
{
	assert(m_data_mask == 0x0f);
	m_b = bitswap<4>(data, 7, 5, 3, 1);
	m_a = bitswap<4>(data, 6, 4, 2, 0);
	update_output();
}


//-------------------------------------------------
//  aN_w -- update one bit of first data input
//-------------------------------------------------

WRITE_LINE_MEMBER(ls157_device::a0_w) { write_a_bit(0, state); }
WRITE_LINE_MEMBER(ls157_device::a1_w) { write_a_bit(1, state); }
WRITE_LINE_MEMBER(ls157_device::a2_w) { write_a_bit(2, state); }
WRITE_LINE_MEMBER(ls157_device::a3_w) { write_a_bit(3, state); }

void ls157_device::write_a_bit(int bit, bool state)
{
	if (BIT(m_a, bit) != state)
	{
		if (state)
			m_a |= (1 << bit);
		else
			m_a &= ~(1 << bit);

		if (!m_strobe && !m_select && !m_out_cb.isnull())
			m_out_cb(m_a);
	}
}


//-------------------------------------------------
//  bN_w -- update one bit of second data input
//-------------------------------------------------

WRITE_LINE_MEMBER(ls157_device::b0_w) { write_b_bit(0, state); }
WRITE_LINE_MEMBER(ls157_device::b1_w) { write_b_bit(1, state); }
WRITE_LINE_MEMBER(ls157_device::b2_w) { write_b_bit(2, state); }
WRITE_LINE_MEMBER(ls157_device::b3_w) { write_b_bit(3, state); }

void ls157_device::write_b_bit(int bit, bool state)
{
	if (BIT(m_b, bit) != state)
	{
		if (state)
			m_b |= (1 << bit);
		else
			m_b &= ~(1 << bit);

		if (!m_strobe && m_select && !m_out_cb.isnull())
			m_out_cb(m_b);
	}
}


//**************************************************************************
//  CONTROL LINE INPUTS
//**************************************************************************

//-------------------------------------------------
//  select_w -- set select input
//-------------------------------------------------

WRITE_LINE_MEMBER(ls157_device::select_w)
{
	if (m_select != bool(state))
	{
		m_select = bool(state);
		update_output();
	}
}


//-------------------------------------------------
//  strobe_w -- set strobe input (active low)
//-------------------------------------------------

WRITE_LINE_MEMBER(ls157_device::strobe_w)
{
	if (m_strobe != bool(state))
	{
		m_strobe = bool(state);

		// Clear output when strobe goes high
		if (m_strobe && !m_out_cb.isnull())
			m_out_cb(0);
		else
			update_output();
	}
}


//-------------------------------------------------
//  update_output -- update output lines Y1-Y4
//  unless strobe is high
//-------------------------------------------------

void ls157_device::update_output()
{
	// S high, strobe low: Y1-Y4 = B1-B4
	// S low, strobe low:  Y1-Y4 = A1-A4
	if (!m_strobe && !m_out_cb.isnull())
	{
		if (m_select)
			m_out_cb(m_b_in_cb.isnull() ? m_b : (m_b_in_cb() & m_data_mask));
		else
			m_out_cb(m_a_in_cb.isnull() ? m_a : (m_a_in_cb() & m_data_mask));
	}
}


//**************************************************************************
//  DATA OUTPUTS
//**************************************************************************

u8 ls157_device::output_r()
{
	if (m_strobe)
		return 0;
	else if (m_select)
		return m_b_in_cb.isnull() ? m_b : (m_b_in_cb() & m_data_mask);
	else
		return m_a_in_cb.isnull() ? m_a : (m_a_in_cb() & m_data_mask);
}


//**************************************************************************
//  74HC157 DEVICE
//**************************************************************************

DEFINE_DEVICE_TYPE(HC157, hc157_device, "hc157", "74HC157 Quad 2-to-1 Multiplexer")

hc157_device::hc157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: ls157_device(mconfig, HC157, tag, owner, clock, 0x0f)
{
}


//**************************************************************************
//  74HCT157 DEVICE
//**************************************************************************

DEFINE_DEVICE_TYPE(HCT157, hct157_device, "hct157", "74HCT157 Quad 2-to-1 Multiplexer")

hct157_device::hct157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: ls157_device(mconfig, HCT157, tag, owner, clock, 0x0f)
{
}