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

                        

                                                                            
               





                                                                            
 
                

                    

                              
 
                                                           
 
                                                                                                               
                                                                                                                                                                               
                                                                                            

 
 
                                                   

                                                   
 
                                   
 













                                         

 


                                                   
 



















                                                                            
 
                                                   
        
                                                   
 
                                         
 
                     
 
 
                                                   
        
                                                   
 
                                         
 
                     

 
                                                   
        
                                                   
 
                                         
 
                          
         
                             
 
                          
                 

                                                                   
 

                                                                        
                         
                                                     

                         
                                 



                 
                                                   
            

                                                   
                                             
 
                              
         
                                 
 
                             
                 
                                       
                 
         
 
 
                                                   
            

                                                   
                                             
 
                              
         
                                 
 
                             
                 
                                       



                 
                                                   
         

                                                   
                                          
 
                                   
         
                            
 
                         
                 
                                 
                 
         


                                                   
         

                                                   
                                          
 
                                   
         
                            
 
                         
                 
                                 



                 
                                                   
                

                                                   
                                                 
 
                          
 
 
                                                   
       

                                                   
                                    
 
                 
 
                 



                            
                 
         
                                


            
                                

         
                                      
 
                 








                                   
                                                   
        
                                                   
 
                                        
 
                                                          






                         
                                                   
        
                                                   
 
                                        
 
                    
 
// license:BSD-3-Clause
// copyright-holders:smf
/***************************************************************************

    NEC uPD4701

    Incremental Encoder Control

    2009-06 Converted to be a device

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

#include "emu.h"
#include "upd4701.h"

#define MASK_SWITCHES ( 7 )
#define MASK_COUNTER ( 0xfff )

const device_type UPD4701 = device_creator<upd4701_device>;

upd4701_device::upd4701_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, UPD4701, "uPD4701 Encoder", tag, owner, clock, "upd4701", __FILE__), m_cs(0), m_xy(0), m_ul(0), m_resetx(0), m_resety(0), m_latchx(0), m_latchy(0),
	m_startx(0), m_starty(0), m_x(0), m_y(0), m_switches(0), m_latchswitches(0), m_cf(0)
{
}

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

void upd4701_device::device_start()
{
	save_item(NAME(m_cs));
	save_item(NAME(m_xy));
	save_item(NAME(m_ul));
	save_item(NAME(m_resetx));
	save_item(NAME(m_resety));
	save_item(NAME(m_latchx));
	save_item(NAME(m_latchy));
	save_item(NAME(m_startx));
	save_item(NAME(m_starty));
	save_item(NAME(m_x));
	save_item(NAME(m_y));
	save_item(NAME(m_switches));
	save_item(NAME(m_latchswitches));
	save_item(NAME(m_cf));
}

//-------------------------------------------------
//  device_reset - device-specific reset
//-------------------------------------------------

void upd4701_device::device_reset()
{
	m_cs = 1;
	m_xy = 0;
	m_ul = 0;
	m_resetx = 0;
	m_resety = 0;
	m_latchx = 0;
	m_latchy = 0;
	m_startx = 0;
	m_starty = 0;
	m_x = 0;
	m_y = 0;
	m_switches = 0;
	m_latchswitches = 0;
	m_cf = 1;
}

/* x,y increments can be 12bit (see MASK_COUNTER), hence we need a couple of
16bit handlers in the following  */

/*-------------------------------------------------
    ul_w
-------------------------------------------------*/

WRITE_LINE_MEMBER( upd4701_device::ul_w )
{
	m_ul = state;
}

/*-------------------------------------------------
    xy_w
-------------------------------------------------*/

WRITE_LINE_MEMBER( upd4701_device::xy_w )
{
	m_xy = state;
}

/*-------------------------------------------------
    cs_w
-------------------------------------------------*/

WRITE_LINE_MEMBER( upd4701_device::cs_w )
{
	if (m_cs != state)
	{
		m_cs = state;

		if (!m_cs)
		{
			m_latchx = (m_x - m_startx) & MASK_COUNTER;
			m_latchy = (m_y - m_starty) & MASK_COUNTER;

			m_latchswitches = (~m_switches) & MASK_SWITCHES;
			if (m_latchswitches != 0)
			{
				m_latchswitches |= 8;
			}

			m_cf = 1;
		}
	}
}

/*-------------------------------------------------
    resetx_w
-------------------------------------------------*/

WRITE_LINE_MEMBER( upd4701_device::resetx_w )
{
	if (m_resetx != state)
	{
		m_resetx = state;

		if (m_resetx)
		{
			m_startx = m_x;
		}
	}
}

/*-------------------------------------------------
    resety_w
-------------------------------------------------*/

WRITE_LINE_MEMBER( upd4701_device::resety_w )
{
	if (m_resety != state)
	{
		m_resety = state;

		if (m_resety)
		{
			m_starty = m_y;
		}
	}
}

/*-------------------------------------------------
    x_add
-------------------------------------------------*/

void upd4701_device::x_add( int16_t data )
{
	if (!m_resetx && data != 0)
	{
		m_x += data;

		if (m_cs)
		{
			m_cf = 0;
		}
	}
}

/*-------------------------------------------------
    y_add
-------------------------------------------------*/

void upd4701_device::y_add( int16_t data )
{
	if (!m_resety && data != 0)
	{
		m_y += data;

		if (m_cs)
		{
			m_cf = 0;
		}
	}
}

/*-------------------------------------------------
    switches_set
-------------------------------------------------*/

void upd4701_device::switches_set( uint8_t data )
{
	m_switches = data;
}

/*-------------------------------------------------
    d_r
-------------------------------------------------*/

READ16_MEMBER( upd4701_device::d_r )
{
	int data;

	if (m_cs)
	{
		return 0xff;
	}

	if (m_xy)
	{
		data = m_latchy;
	}
	else
	{
		data = m_latchx;
	}

	data |= m_latchswitches << 12;

	if (m_ul)
	{
		return data >> 8;
	}
	else
	{
		return data & 0xff;
	}
}

/*-------------------------------------------------
    sf_r
-------------------------------------------------*/

READ_LINE_MEMBER( upd4701_device::sf_r )
{
	if ((m_switches & MASK_SWITCHES) != MASK_SWITCHES)
	{
		return 0;
	}

	return 1;
}

/*-------------------------------------------------
    cf_r
-------------------------------------------------*/

READ_LINE_MEMBER( upd4701_device::cf_r )
{
	return m_cf;
}