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

                               



                                                                       



                                                                       


 

                                                        
 
 
                                                                            
                      

                                                                            
             



                                                                            
           


                                                                            
                       

                                                   
                                               
 
                                                                           


                    
                                                     


                                   
                        
 
                             

                                 



                                                   
                     

                                                   
                                    
 
                                                    
 
                                                




                                         
                                                             





















                                                                            
                                                                                                           









                                                                                 




                                                   





                                                   

                                    
 
                      
                   
 



                                    
                                          






                                                   
         

                                                   
                           
 
                               
 
                                                            





                                                   
         

                                                   
                                    
 
                                       
 
                                                                           




                                  
                        





                                                   

                                      

                                                   
                                           
 
                                                                      
 

                               





                                                   
           



                                                   
                                                                







                                                   
            



                                                   
                                                                 





                                                   
            



                                                   
                                                                 


                       
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Intel 8214 Priority Interrupt Controller emulation

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

#include "emu.h"
#include "i8214.h"



// device type definition
const device_type I8214 = &device_creator<i8214_device>;


//**************************************************************************
//  MACROS / CONSTANTS
//**************************************************************************

#define LOG 0



//**************************************************************************
//  HELPERS
//**************************************************************************

//-------------------------------------------------
//  trigger_interrupt -
//-------------------------------------------------

void i8214_device::trigger_interrupt(int level)
{
	if (LOG) logerror("I8214 '%s' Interrupt Level %u\n", tag(), level);

	m_a = level;

	// disable more interrupts from being latched
	m_int_dis = 1;

	// disable next level group
	m_write_enlg(0);

	// set interrupt line
	m_write_irq(ASSERT_LINE);
	m_write_irq(CLEAR_LINE);
}


//-------------------------------------------------
//  check_interrupt -
//-------------------------------------------------

void i8214_device::check_interrupt()
{
	if (m_int_dis || !m_etlg || !m_inte) return;

	for (int level = 7; level >= 0; level--)
	{
		if (!BIT(m_r, 7 - level))
		{
			if (m_sgs)
			{
				if (level > m_current_status)
				{
					trigger_interrupt(level);
				}
			}
			else
			{
				trigger_interrupt(level);
			}
		}
	}
}



//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  i8214_device - constructor
//-------------------------------------------------

i8214_device::i8214_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, I8214, "I8214", tag, owner, clock, "i8214", __FILE__)
	, m_write_irq(*this)
	, m_write_enlg(*this)
	, m_inte(0)
	, m_int_dis(0)
	, m_a(0)
	, m_current_status(0)
	, m_r(0xff)
	, m_sgs(0)
	, m_etlg(1)
{
}


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

void i8214_device::device_start()
{
	// resolve callbacks
	m_write_irq.resolve_safe();
	m_write_enlg.resolve_safe();

	m_int_dis = 0;
	m_etlg = 1;

	// register for state saving
	save_item(NAME(m_inte));
	save_item(NAME(m_int_dis));
	save_item(NAME(m_a));
	save_item(NAME(m_current_status));
	save_item(NAME(m_r));
	save_item(NAME(m_sgs));
	save_item(NAME(m_etlg));
}


//-------------------------------------------------
//  a_r -
//-------------------------------------------------

uint8_t i8214_device::a_r()
{
	uint8_t a = m_a & 0x07;

	if (LOG) logerror("I8214 '%s' A: %01x\n", tag(), a);

	return a;
}


//-------------------------------------------------
//  b_w -
//-------------------------------------------------

void i8214_device::b_w(uint8_t data)
{
	m_current_status = data & 0x07;

	if (LOG) logerror("I8214 '%s' B: %01x\n", tag(), m_current_status);

	// enable interrupts
	m_int_dis = 0;

	// enable next level group
	m_write_enlg(1);

	check_interrupt();
}


//-------------------------------------------------
//  r_w - update the interrupt request
//  state for a given line
//-------------------------------------------------

void i8214_device::r_w(int line, int state)
{
	if (LOG) logerror("I8214 '%s' R%d: %d\n", tag(), line, state);

	m_r &= ~(1 << line);
	m_r |= (state << line);

	check_interrupt();
}


//-------------------------------------------------
//  sgs_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( i8214_device::sgs_w )
{
	if (LOG) logerror("I8214 '%s' SGS: %u\n", tag(), state);

	m_sgs = state;

	check_interrupt();
}


//-------------------------------------------------
//  etlg_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( i8214_device::etlg_w )
{
	if (LOG) logerror("I8214 '%s' ETLG: %u\n", tag(), state);

	m_etlg = state;
}


//-------------------------------------------------
//  inte_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( i8214_device::inte_w )
{
	if (LOG) logerror("I8214 '%s' INTE: %u\n", tag(), state);

	m_inte = state;
}