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

                        





                                                                            
 
                

                            


                                                                     
 







                                                                            
                                                                       





                                                                            
               

                                                                            

                                                            

                                                   
                                

                                                   
                                                                                                               
                                                                                        




                                                        
 

 
 





                                                   
                                             
 
                                                                                                                         
 
 
 




                                                   
                                                                         
 

 
 




                                                   
                                                                                                  
 
                                                             

 
 





                                                   
                                       
 


                                        







                                                   
 
 
 









                                                                  
         
                                                                    
         

                                                      
                                 
         
                                                             
                 
                                                                                                                                   
                 
 
                                                
                 
                                                                                                         
                 
 

                                                       
                                                                         
                                                                                 
         

 
 




                                                   
                                                 
 
                                                     
 
                                                     

                                                                  
         
                                                                     


         




                                                   
                                                  
 
                                                      
 

                                                                  
                                                                     
         
 
                                                      

 
 
 



                                                                            
                                      


                               
                                                                                                        


                           
                                                                                                         



                                                                                  
                                                                           
                         
 
                                            
                                                                            







                                                             
 
                                                                                                   
                                                                                       
                 
                                                                     
                                            
                                                                            

                 

 
 
                                    
 
                               
         
                                                 
                                                                                                              
                            


            
                                                             
                 
                                                   
                 
 
                                                                   
                                                                                                      




                            
                                               



                               
                                                                                         
                                 


         
 
                                               
 

                               
         
                                                                                         
                                 

         

 
                                                                                             
 





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

    16K ( 2K x 8 ) Parallel EEPROM

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

#include "emu.h"
#include "machine/at28c16.h"

#define AT28C16_DATA_BYTES ( 0x800 )
#define AT28C16_ID_BYTES ( 0x20 )
#define AT28C16_TOTAL_BYTES ( AT28C16_DATA_BYTES + AT28C16_ID_BYTES )

#define AT28C16_ID_OFFSET ( AT28C16_DATA_BYTES - AT28C16_ID_BYTES )



//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

static ADDRESS_MAP_START( at28c16_map8, AS_PROGRAM, 8, at28c16_device )
	AM_RANGE(0x0000, 0x081f) AM_RAM
ADDRESS_MAP_END



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

// device type definition
const device_type AT28C16 = &device_creator<at28c16_device>;

//-------------------------------------------------
//  at28c16_device - constructor
//-------------------------------------------------

at28c16_device::at28c16_device( const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock )
	: device_t(mconfig, AT28C16, "AT28C16", tag, owner, clock, "at28c16", __FILE__),
		device_memory_interface(mconfig, *this),
		device_nvram_interface(mconfig, *this),
		m_a9_12v( 0 ),
		m_oe_12v( 0 ),
		m_last_write( -1 )
{
}


//-------------------------------------------------
//  device_config_complete - perform any
//  operations now that the configuration is
//  complete
//-------------------------------------------------

void at28c16_device::device_config_complete()
{
	m_space_config = address_space_config( "at28c16", ENDIANNESS_BIG, 8,  12, 0, *ADDRESS_MAP_NAME( at28c16_map8 ) );
}


//-------------------------------------------------
//  device_validity_check - perform validity checks
//  on this device
//-------------------------------------------------

void at28c16_device::device_validity_check(validity_checker &valid) const
{
}


//-------------------------------------------------
//  memory_space_config - return a description of
//  any address spaces owned by this device
//-------------------------------------------------

const address_space_config *at28c16_device::memory_space_config( address_spacenum spacenum ) const
{
	return ( spacenum == 0 ) ? &m_space_config : nullptr;
}


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

void at28c16_device::device_start()
{
	m_write_timer = timer_alloc(0);

	save_item( NAME(m_a9_12v) );
	save_item( NAME(m_oe_12v) );
	save_item( NAME(m_last_write) );
}


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

void at28c16_device::device_reset()
{
}


//-------------------------------------------------
//  nvram_default - called to initialize NVRAM to
//  its default state
//-------------------------------------------------

void at28c16_device::nvram_default()
{
	UINT16 default_value = 0xff;
	for( offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++ )
	{
		m_addrspace[ 0 ]->write_byte( offs, default_value );
	}

	/* populate from a memory region if present */
	if( m_region != nullptr )
	{
		if( m_region->bytes() != AT28C16_DATA_BYTES )
		{
			fatalerror( "at28c16 region '%s' wrong size (expected size = 0x%X)\n", tag().c_str(), AT28C16_DATA_BYTES );
		}

		if( m_region->bytewidth() != 1 )
		{
			fatalerror( "at28c16 region '%s' needs to be an 8-bit region\n", tag().c_str() );
		}

		UINT8 *default_data = m_region->base();

		for( offs_t offs = 0; offs < AT28C16_DATA_BYTES; offs++ )
			m_addrspace[ 0 ]->write_byte( offs, default_data[offs] );
	}
}


//-------------------------------------------------
//  nvram_read - called to read NVRAM from the
//  .nv file
//-------------------------------------------------

void at28c16_device::nvram_read( emu_file &file )
{
	dynamic_buffer buffer( AT28C16_TOTAL_BYTES );

	file.read( &buffer[0], AT28C16_TOTAL_BYTES );

	for( offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++ )
	{
		m_addrspace[ 0 ]->write_byte( offs, buffer[ offs ] );
	}
}

//-------------------------------------------------
//  nvram_write - called to write NVRAM to the
//  .nv file
//-------------------------------------------------

void at28c16_device::nvram_write( emu_file &file )
{
	dynamic_buffer buffer ( AT28C16_TOTAL_BYTES );

	for( offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++ )
	{
		buffer[ offs ] = m_addrspace[ 0 ]->read_byte( offs );
	}

	file.write( &buffer[0], AT28C16_TOTAL_BYTES );
}



//**************************************************************************
//  READ/WRITE HANDLERS
//**************************************************************************

WRITE8_MEMBER( at28c16_device::write )
{
	if( m_last_write >= 0 )
	{
//      logerror( "%s: AT28C16: write( %04x, %02x ) busy\n", machine.describe_context(), offset, data );
	}
	else if( m_oe_12v )
	{
//      logerror( "%s: AT28C16: write( %04x, %02x ) erase\n", machine.describe_context(), offset, data );
		if( m_last_write < 0 )
		{
			for( offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++ )
			{
				m_addrspace[ 0 ]->write_byte( offs, 0xff );
			}

			m_last_write = 0xff;
			m_write_timer->adjust( attotime::from_usec( 200 ) );
		}
	}
	else
	{
		if( m_a9_12v && offset >= AT28C16_ID_OFFSET )
		{
			offset += AT28C16_ID_BYTES;
		}

//      logerror( "%s: AT28C16: write( %04x, %02x )\n", machine.describe_context(), offset, data );
		if( m_last_write < 0 && m_addrspace[ 0 ]->read_byte( offset ) != data )
		{
			m_addrspace[ 0 ]->write_byte( offset, data );
			m_last_write = data;
			m_write_timer->adjust( attotime::from_usec( 200 ) );
		}
	}
}


READ8_MEMBER( at28c16_device::read )
{
	if( m_last_write >= 0 )
	{
		UINT8 data = m_last_write ^ 0x80;
//      logerror( "%s: AT28C16: read( %04x ) write status %02x\n", machine.describe_context(), offset, data );
		return data;
	}
	else
	{
		if( m_a9_12v && offset >= AT28C16_ID_OFFSET )
		{
			offset += AT28C16_ID_BYTES;
		}

		UINT8 data = m_addrspace[ 0 ]->read_byte( offset );
//      logerror( "%s: AT28C16: read( %04x ) data %02x\n", machine.describe_context(), offset, data );
		return data;
	}
}


WRITE_LINE_MEMBER( at28c16_device::set_a9_12v )
{
	state &= 1;
	if( m_a9_12v != state )
	{
//      logerror( "%s: AT28C16: set_a9_12v( %d )\n", machine.describe_context(), state );
		m_a9_12v = state;
	}
}


WRITE_LINE_MEMBER( at28c16_device::set_oe_12v )
{
	state &= 1;
	if( m_oe_12v != state )
	{
//      logerror( "%s: AT28C16: set_oe_12v( %d )\n", machine.describe_context(), state );
		m_oe_12v = state;
	}
}


void at28c16_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch( id )
	{
	case 0:
		m_last_write = -1;
		break;
	}
}