mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
turned i2cmem into a c++ device & ditched the unused legacy device.
This commit is contained in:
parent
c35336557d
commit
c13eb4d193
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -707,8 +707,6 @@ src/emu/machine/generic.c svneol=native#text/plain
|
||||
src/emu/machine/generic.h svneol=native#text/plain
|
||||
src/emu/machine/i2cmem.c svneol=native#text/plain
|
||||
src/emu/machine/i2cmem.h svneol=native#text/plain
|
||||
src/emu/machine/i2cmemdev.c svneol=native#text/plain
|
||||
src/emu/machine/i2cmemdev.h svneol=native#text/plain
|
||||
src/emu/machine/i8243.c svneol=native#text/plain
|
||||
src/emu/machine/i8243.h svneol=native#text/plain
|
||||
src/emu/machine/i8255a.c svneol=native#text/plain
|
||||
|
@ -160,7 +160,6 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/i8243.o \
|
||||
$(EMUMACHINE)/i8255a.o \
|
||||
$(EMUMACHINE)/i2cmem.o \
|
||||
$(EMUMACHINE)/i2cmemdev.o \
|
||||
$(EMUMACHINE)/idectrl.o \
|
||||
$(EMUMACHINE)/ins8154.o \
|
||||
$(EMUMACHINE)/ins8250.o \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/***************************************************************************
|
||||
|
||||
I2C Memory
|
||||
|
||||
@ -18,48 +18,11 @@ The memory address is only 8 bits, devices larger than this have multiple slave
|
||||
The top five address bits are set at manufacture time, two values are standard.
|
||||
Up to 4096 bytes can be addressed.
|
||||
|
||||
*/
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/i2cmem.h"
|
||||
|
||||
#define VERBOSE_LEVEL ( 0 )
|
||||
|
||||
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... )
|
||||
{
|
||||
if( VERBOSE_LEVEL >= n_level )
|
||||
{
|
||||
va_list v;
|
||||
char buf[ 32768 ];
|
||||
va_start( v, s_fmt );
|
||||
vsprintf( buf, s_fmt, v );
|
||||
va_end( v );
|
||||
logerror( "%s: %s", cpuexec_describe_context(machine), buf );
|
||||
}
|
||||
}
|
||||
|
||||
struct i2cmem_chip
|
||||
{
|
||||
int slave_address;
|
||||
int scl;
|
||||
int sdaw;
|
||||
int e0;
|
||||
int e1;
|
||||
int e2;
|
||||
int wc;
|
||||
int sdar;
|
||||
int state;
|
||||
int bits;
|
||||
int shift;
|
||||
int devsel;
|
||||
int byteaddr;
|
||||
UINT8 *data;
|
||||
int data_size;
|
||||
UINT8 *page;
|
||||
int page_offset;
|
||||
int page_size;
|
||||
};
|
||||
|
||||
#define STATE_IDLE ( 0 )
|
||||
#define STATE_DEVSEL ( 1 )
|
||||
#define STATE_BYTEADDR ( 2 )
|
||||
@ -69,71 +32,571 @@ struct i2cmem_chip
|
||||
#define DEVSEL_RW ( 1 )
|
||||
#define DEVSEL_ADDRESS ( 0xfe )
|
||||
|
||||
static struct i2cmem_chip i2cmem[ I2CMEM_MAXCHIP ];
|
||||
//**************************************************************************
|
||||
// DEBUGGING
|
||||
//**************************************************************************
|
||||
|
||||
void i2cmem_init( running_machine *machine, int chip, int slave_address, int page_size, int data_size, UINT8 *data )
|
||||
#define VERBOSE_LEVEL ( 0 )
|
||||
|
||||
INLINE void ATTR_PRINTF( 3, 4 ) verboselog( running_device *device, int n_level, const char *s_fmt, ... )
|
||||
{
|
||||
struct i2cmem_chip *c;
|
||||
UINT8 *page = NULL;
|
||||
|
||||
if( chip >= I2CMEM_MAXCHIP )
|
||||
if( VERBOSE_LEVEL >= n_level )
|
||||
{
|
||||
verboselog( machine, 0, "i2cmem_init( %d ) invalid chip\n", chip );
|
||||
return;
|
||||
va_list v;
|
||||
char buf[ 32768 ];
|
||||
va_start( v, s_fmt );
|
||||
vsprintf( buf, s_fmt, v );
|
||||
va_end( v );
|
||||
logerror( "%s: I2CMEM(%s) %s", cpuexec_describe_context( device->machine ), device->tag(), buf );
|
||||
}
|
||||
|
||||
c = &i2cmem[ chip ];
|
||||
|
||||
if( data == NULL )
|
||||
{
|
||||
data = auto_alloc_array( machine, UINT8, data_size );
|
||||
}
|
||||
|
||||
if( page_size > 0 )
|
||||
{
|
||||
page = auto_alloc_array( machine, UINT8, page_size );
|
||||
}
|
||||
|
||||
c->slave_address = slave_address;
|
||||
c->data_size = data_size;
|
||||
c->page_size = page_size;
|
||||
|
||||
c->scl = 0;
|
||||
c->sdaw = 0;
|
||||
c->e0 = 0;
|
||||
c->e1 = 0;
|
||||
c->e2 = 0;
|
||||
c->wc = 0;
|
||||
c->sdar = 1;
|
||||
c->state = STATE_IDLE;
|
||||
c->bits = 0;
|
||||
c->shift = 0;
|
||||
c->devsel = 0;
|
||||
c->byteaddr = 0;
|
||||
c->data = data;
|
||||
c->page = page;
|
||||
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->scl );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->sdaw );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->e0 );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->e1 );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->e2 );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->wc );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->sdar );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->state );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->bits );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->shift );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->devsel );
|
||||
state_save_register_item( machine, "i2cmem", NULL, chip, c->byteaddr );
|
||||
state_save_register_item_pointer( machine, "i2cmem", NULL, chip, c->data, c->data_size );
|
||||
}
|
||||
|
||||
static int select_device( struct i2cmem_chip *c )
|
||||
{
|
||||
int device = ( c->slave_address & 0xf0 ) | ( c->e2 << 3 ) | ( c->e1 << 2 ) | ( c->e0 << 1 );
|
||||
int mask = DEVSEL_ADDRESS & ~( ( c->data_size - 1 ) >> 7 );
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
if( ( c->devsel & mask ) == ( device & mask ) )
|
||||
|
||||
static ADDRESS_MAP_START( i2cmem_map8, ADDRESS_SPACE_PROGRAM, 8 )
|
||||
AM_RANGE(0x0000, 0x0fff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE CONFIGURATION
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// i2cmem_device_config - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
i2cmem_device_config::i2cmem_device_config( const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock ) :
|
||||
device_config( mconfig, static_alloc_device_config, "I2CMEM", tag, owner, clock),
|
||||
device_config_memory_interface(mconfig, *this),
|
||||
device_config_nvram_interface(mconfig, *this)
|
||||
{
|
||||
m_address_bits = 0;
|
||||
|
||||
int i = m_data_size - 1;
|
||||
while( i > 0 )
|
||||
{
|
||||
m_address_bits++;
|
||||
i >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// static_alloc_device_config - allocate a new
|
||||
// configuration object
|
||||
//-------------------------------------------------
|
||||
|
||||
device_config *i2cmem_device_config::static_alloc_device_config( const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock )
|
||||
{
|
||||
return global_alloc( i2cmem_device_config( mconfig, tag, owner, clock ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// alloc_device - allocate a new device object
|
||||
//-------------------------------------------------
|
||||
|
||||
device_t *i2cmem_device_config::alloc_device( running_machine &machine ) const
|
||||
{
|
||||
return auto_alloc( &machine, i2cmem_device( machine, *this ) );
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void i2cmem_device_config::device_config_complete()
|
||||
{
|
||||
// extract inline configuration from raw data
|
||||
const i2cmem_interface *intf = reinterpret_cast<const i2cmem_interface *>( m_inline_data[ INLINE_INTERFACE ] );
|
||||
|
||||
// inherit a copy of the static data
|
||||
if( intf != NULL )
|
||||
{
|
||||
*static_cast<i2cmem_interface *>(this) = *intf;
|
||||
}
|
||||
|
||||
m_space_config = address_space_config( "ic2mem", ENDIANNESS_BIG, 8, m_address_bits, 0, *ADDRESS_MAP_NAME( i2cmem_map8 ) );
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_validity_check - perform validity checks
|
||||
// on this device
|
||||
//-------------------------------------------------
|
||||
|
||||
bool i2cmem_device_config::device_validity_check( const game_driver &driver ) const
|
||||
{
|
||||
bool error = false;
|
||||
|
||||
if( m_inline_data[ INLINE_INTERFACE ] == 0 )
|
||||
{
|
||||
mame_printf_error( "%s: %s i2cmem device '%s' did not specify an interface\n", driver.source_file, driver.name, tag() );
|
||||
error = true;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// memory_space_config - return a description of
|
||||
// any address spaces owned by this device
|
||||
//-------------------------------------------------
|
||||
|
||||
const address_space_config *i2cmem_device_config::memory_space_config( int spacenum ) const
|
||||
{
|
||||
return ( spacenum == 0 ) ? &m_space_config : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// i2cmem_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
i2cmem_device::i2cmem_device( running_machine &_machine, const i2cmem_device_config &config ) :
|
||||
device_t( _machine, config ),
|
||||
device_memory_interface( _machine, config, *this ),
|
||||
device_nvram_interface( _machine, config, *this ),
|
||||
m_config( config ),
|
||||
m_scl( 0 ),
|
||||
m_sdaw( 0 ),
|
||||
m_e0( 0 ),
|
||||
m_e1( 0 ),
|
||||
m_e2( 0 ),
|
||||
m_wc( 0 ),
|
||||
m_sdar( 1 ),
|
||||
m_state( STATE_IDLE )
|
||||
{
|
||||
if( m_page_size > 0 )
|
||||
{
|
||||
m_page = auto_alloc_array( machine, UINT8, m_page_size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void i2cmem_device::device_start()
|
||||
{
|
||||
state_save_register_device_item( this, 0, m_scl );
|
||||
state_save_register_device_item( this, 0, m_sdaw );
|
||||
state_save_register_device_item( this, 0, m_e0 );
|
||||
state_save_register_device_item( this, 0, m_e1 );
|
||||
state_save_register_device_item( this, 0, m_e2 );
|
||||
state_save_register_device_item( this, 0, m_wc );
|
||||
state_save_register_device_item( this, 0, m_sdar );
|
||||
state_save_register_device_item( this, 0, m_state );
|
||||
state_save_register_device_item( this, 0, m_bits );
|
||||
state_save_register_device_item( this, 0, m_shift );
|
||||
state_save_register_device_item( this, 0, m_devsel );
|
||||
state_save_register_device_item( this, 0, m_byteaddr );
|
||||
state_save_register_device_item_pointer( this, 0, m_page, m_page_size );
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void i2cmem_device::device_reset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_default - called to initialize NVRAM to
|
||||
// its default state
|
||||
//-------------------------------------------------
|
||||
|
||||
void i2cmem_device::nvram_default()
|
||||
{
|
||||
int i2cmem_bytes = m_config.m_data_size;
|
||||
|
||||
UINT16 default_value = 0xff;
|
||||
for( offs_t offs = 0; offs < i2cmem_bytes; offs++ )
|
||||
{
|
||||
memory_write_byte( m_addrspace[ 0 ], offs, default_value );
|
||||
}
|
||||
|
||||
/* populate from a memory region if present */
|
||||
if( m_region != NULL )
|
||||
{
|
||||
if( m_region->bytes() != i2cmem_bytes )
|
||||
{
|
||||
fatalerror( "i2cmem region '%s' wrong size (expected size = 0x%X)", tag(), i2cmem_bytes );
|
||||
}
|
||||
|
||||
if( m_region->width() != 1 )
|
||||
{
|
||||
fatalerror( "i2cmem region '%s' needs to be an 8-bit region", tag() );
|
||||
}
|
||||
|
||||
for( offs_t offs = 0; offs < i2cmem_bytes; offs++ )
|
||||
{
|
||||
memory_write_byte( m_addrspace[ 0 ], offs, m_region->u8( offs ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_read - called to read NVRAM from the
|
||||
// .nv file
|
||||
//-------------------------------------------------
|
||||
|
||||
void i2cmem_device::nvram_read( mame_file &file )
|
||||
{
|
||||
int i2cmem_bytes = m_config.m_data_size;
|
||||
UINT8 *buffer = auto_alloc_array( &m_machine, UINT8, i2cmem_bytes );
|
||||
|
||||
mame_fread( &file, buffer, i2cmem_bytes );
|
||||
|
||||
for( offs_t offs = 0; offs < i2cmem_bytes; offs++ )
|
||||
{
|
||||
memory_write_byte( m_addrspace[ 0 ], offs, buffer[ offs ] );
|
||||
}
|
||||
|
||||
auto_free( &m_machine, buffer );
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_write - called to write NVRAM to the
|
||||
// .nv file
|
||||
//-------------------------------------------------
|
||||
|
||||
void i2cmem_device::nvram_write( mame_file &file )
|
||||
{
|
||||
int i2cmem_bytes = m_config.m_data_size;
|
||||
UINT8 *buffer = auto_alloc_array( &m_machine, UINT8, i2cmem_bytes );
|
||||
|
||||
for( offs_t offs = 0; offs < i2cmem_bytes; offs++ )
|
||||
{
|
||||
buffer[ offs ] = memory_read_byte( m_addrspace[ 0 ], offs );
|
||||
}
|
||||
|
||||
mame_fwrite( &file, buffer, i2cmem_bytes );
|
||||
|
||||
auto_free( &m_machine, buffer );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_e0_write )
|
||||
{
|
||||
downcast<i2cmem_device *>( device )->set_e0_line( state );
|
||||
}
|
||||
|
||||
void i2cmem_device::set_e0_line( int state )
|
||||
{
|
||||
state &= 1;
|
||||
if( m_e0 != state )
|
||||
{
|
||||
verboselog( this, 2, "set e0 %d\n", state );
|
||||
m_e0 = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_e1_write )
|
||||
{
|
||||
downcast<i2cmem_device *>( device )->set_e1_line( state );
|
||||
}
|
||||
|
||||
void i2cmem_device::set_e1_line( int state )
|
||||
{
|
||||
state &= 1;
|
||||
if( m_e1 != state )
|
||||
{
|
||||
verboselog( this, 2, "set e1 %d\n", state );
|
||||
m_e1 = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_e2_write )
|
||||
{
|
||||
downcast<i2cmem_device *>( device )->set_e2_line( state );
|
||||
}
|
||||
|
||||
void i2cmem_device::set_e2_line( int state )
|
||||
{
|
||||
state &= 1;
|
||||
if( m_e2 != state )
|
||||
{
|
||||
verboselog( this, 2, "set e2 %d\n", state );
|
||||
m_e2 = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_sda_write )
|
||||
{
|
||||
downcast<i2cmem_device *>( device )->set_sda_line( state );
|
||||
}
|
||||
|
||||
void i2cmem_device::set_sda_line( int state )
|
||||
{
|
||||
state &= 1;
|
||||
if( m_sdaw != state )
|
||||
{
|
||||
verboselog( this, 2, "set sda %d\n", state );
|
||||
m_sdaw = state;
|
||||
|
||||
if( m_scl )
|
||||
{
|
||||
if( m_sdaw )
|
||||
{
|
||||
verboselog( this, 1, "stop\n" );
|
||||
m_state = STATE_IDLE;
|
||||
m_byteaddr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( this, 2, "start\n" );
|
||||
m_state = STATE_DEVSEL;
|
||||
m_bits = 0;
|
||||
}
|
||||
|
||||
m_sdar = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_scl_write )
|
||||
{
|
||||
downcast<i2cmem_device *>( device )->set_scl_line( state );
|
||||
}
|
||||
|
||||
void i2cmem_device::set_scl_line( int state )
|
||||
{
|
||||
if( m_scl != state )
|
||||
{
|
||||
m_scl = state;
|
||||
verboselog( this, 2, "set_scl_line %d\n", m_scl );
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
case STATE_DEVSEL:
|
||||
case STATE_BYTEADDR:
|
||||
case STATE_DATAIN:
|
||||
if( m_bits < 8 )
|
||||
{
|
||||
if( m_scl )
|
||||
{
|
||||
m_shift = ( ( m_shift << 1 ) | m_sdaw ) & 0xff;
|
||||
m_bits++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_scl )
|
||||
{
|
||||
switch( m_state )
|
||||
{
|
||||
case STATE_DEVSEL:
|
||||
m_devsel = m_shift;
|
||||
|
||||
if( !select_device() )
|
||||
{
|
||||
verboselog( this, 1, "devsel %02x: not this device\n", m_devsel );
|
||||
m_state = STATE_IDLE;
|
||||
}
|
||||
else if( ( m_devsel & DEVSEL_RW ) == 0 )
|
||||
{
|
||||
verboselog( this, 1, "devsel %02x: write\n", m_devsel );
|
||||
m_state = STATE_BYTEADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( this, 1, "devsel %02x: read\n", m_devsel );
|
||||
m_state = STATE_DATAOUT;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_BYTEADDR:
|
||||
m_byteaddr = m_shift;
|
||||
m_page_offset = 0;
|
||||
|
||||
verboselog( this, 1, "byteaddr %02x\n", m_byteaddr );
|
||||
|
||||
m_state = STATE_DATAIN;
|
||||
break;
|
||||
|
||||
case STATE_DATAIN:
|
||||
if( m_wc )
|
||||
{
|
||||
verboselog( this, 0, "write not enabled\n" );
|
||||
m_state = STATE_IDLE;
|
||||
}
|
||||
else if( m_page_size > 0 )
|
||||
{
|
||||
m_page[ m_page_offset ] = m_shift;
|
||||
verboselog( this, 1, "page[ %04x ] <- %02x\n", m_page_offset, m_page[ m_page_offset ] );
|
||||
|
||||
m_page_offset++;
|
||||
if( m_page_offset == m_page_size )
|
||||
{
|
||||
int offset = data_offset() & ~( m_page_size - 1 );
|
||||
|
||||
verboselog( this, 1, "data[ %04x to %04x ] = page\n", offset, offset + m_page_size - 1 );
|
||||
|
||||
for( int i = 0; i < m_page_size; i++ )
|
||||
{
|
||||
memory_write_byte( m_addrspace[ 0 ], offset + i, m_page[ i ] );
|
||||
}
|
||||
|
||||
m_page_offset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = data_offset();
|
||||
|
||||
verboselog( this, 1, "data[ %04x ] <- %02x\n", offset, m_shift );
|
||||
memory_write_byte( m_addrspace[ 0 ], offset, m_shift );
|
||||
|
||||
m_byteaddr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_bits == 8 )
|
||||
{
|
||||
m_sdar = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bits = 0;
|
||||
m_sdar = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_DATAOUT:
|
||||
if( m_bits < 8 )
|
||||
{
|
||||
if( m_scl )
|
||||
{
|
||||
if( m_bits == 0 )
|
||||
{
|
||||
int offset = data_offset();
|
||||
|
||||
m_shift = memory_read_byte( m_addrspace[ 0 ], offset );
|
||||
verboselog( this, 1, "data[ %04x ] -> %02x\n", offset, m_shift );
|
||||
m_byteaddr++;
|
||||
}
|
||||
|
||||
m_sdar = ( m_shift >> 7 ) & 1;
|
||||
|
||||
m_shift = ( m_shift << 1 ) & 0xff;
|
||||
m_bits++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_scl )
|
||||
{
|
||||
if( m_sdaw )
|
||||
{
|
||||
verboselog( this, 1, "sleep\n" );
|
||||
m_state = STATE_IDLE;
|
||||
m_sdar = 0;
|
||||
}
|
||||
|
||||
m_bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_bits == 8 )
|
||||
{
|
||||
m_sdar = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_wc_write )
|
||||
{
|
||||
downcast<i2cmem_device *>( device )->set_wc_line( state );
|
||||
}
|
||||
|
||||
void i2cmem_device::set_wc_line( int state )
|
||||
{
|
||||
state &= 1;
|
||||
if( m_wc != state )
|
||||
{
|
||||
verboselog( this, 2, "set wc %d\n", state );
|
||||
m_wc = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ_LINE_DEVICE_HANDLER( i2cmem_sda_read )
|
||||
{
|
||||
return downcast<i2cmem_device *>( device )->read_sda_line();
|
||||
}
|
||||
|
||||
int i2cmem_device::read_sda_line()
|
||||
{
|
||||
int res = m_sdar & m_sdaw & 1;
|
||||
|
||||
verboselog( this, 2, "read sda %d\n", res );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERNAL HELPERS
|
||||
//**************************************************************************
|
||||
|
||||
int i2cmem_device::address_mask()
|
||||
{
|
||||
return ( 1 << m_config.m_address_bits ) - 1;
|
||||
}
|
||||
|
||||
int i2cmem_device::select_device()
|
||||
{
|
||||
int device = ( m_config.m_slave_address & 0xf0 ) | ( m_e2 << 3 ) | ( m_e1 << 2 ) | ( m_e0 << 1 );
|
||||
int mask = DEVSEL_ADDRESS & ~( address_mask() >> 7 );
|
||||
|
||||
if( ( m_devsel & mask ) == ( device & mask ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -141,291 +604,9 @@ static int select_device( struct i2cmem_chip *c )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int data_offset( struct i2cmem_chip *c )
|
||||
int i2cmem_device::data_offset()
|
||||
{
|
||||
return ( ( ( c->devsel << 7 ) & 0xff00 ) | ( c->byteaddr & 0xff ) ) & ( c->data_size - 1 );
|
||||
return ( ( ( m_devsel << 7 ) & 0xff00 ) | ( m_byteaddr & 0xff ) ) & address_mask();
|
||||
}
|
||||
|
||||
void i2cmem_write( running_machine *machine, int chip, int line, int data )
|
||||
{
|
||||
struct i2cmem_chip *c;
|
||||
|
||||
if( chip >= I2CMEM_MAXCHIP )
|
||||
{
|
||||
verboselog( machine, 0, "i2cmem_write( %d, %d, %d ) invalid chip\n", chip, line, data );
|
||||
return;
|
||||
}
|
||||
|
||||
c = &i2cmem[ chip ];
|
||||
|
||||
data &= 1;
|
||||
|
||||
switch( line )
|
||||
{
|
||||
case I2CMEM_E0:
|
||||
if( c->e0 != data )
|
||||
{
|
||||
c->e0 = data;
|
||||
verboselog( machine, 2, "i2cmem_write( %d, I2CMEM_E0, %d )\n", chip, c->e0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_E1:
|
||||
if( c->e1 != data )
|
||||
{
|
||||
c->e1 = data;
|
||||
verboselog( machine, 2, "i2cmem_write( %d, I2CMEM_E1, %d )\n", chip, c->e1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_E2:
|
||||
if( c->e2 != data )
|
||||
{
|
||||
c->e2 = data;
|
||||
verboselog( machine, 2, "i2cmem_write( %d, I2CMEM_E2, %d )\n", chip, c->e2 );
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_SDA:
|
||||
if( c->sdaw != data )
|
||||
{
|
||||
c->sdaw = data;
|
||||
verboselog( machine, 2, "i2cmem_write( %d, I2CMEM_SDA, %d )\n", chip, c->sdaw );
|
||||
|
||||
if( c->scl )
|
||||
{
|
||||
if( c->sdaw )
|
||||
{
|
||||
verboselog( machine, 1, "i2cmem(%d) stop\n", chip );
|
||||
c->state = STATE_IDLE;
|
||||
c->byteaddr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( machine, 2, "i2cmem(%d) start\n", chip );
|
||||
c->state = STATE_DEVSEL;
|
||||
c->bits = 0;
|
||||
}
|
||||
|
||||
c->sdar = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_SCL:
|
||||
if( c->scl != data )
|
||||
{
|
||||
c->scl = data;
|
||||
verboselog( machine, 2, "i2cmem_write( %d, I2CMEM_SCL, %d )\n", chip, c->scl );
|
||||
|
||||
switch( c->state )
|
||||
{
|
||||
case STATE_DEVSEL:
|
||||
case STATE_BYTEADDR:
|
||||
case STATE_DATAIN:
|
||||
if( c->bits < 8 )
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
c->shift = ( ( c->shift << 1 ) | c->sdaw ) & 0xff;
|
||||
c->bits++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
switch( c->state )
|
||||
{
|
||||
case STATE_DEVSEL:
|
||||
c->devsel = c->shift;
|
||||
|
||||
if( !select_device( c ) )
|
||||
{
|
||||
verboselog( machine, 1, "i2cmem(%d) devsel %02x: not this device\n", chip, c->devsel );
|
||||
c->state = STATE_IDLE;
|
||||
}
|
||||
else if( ( c->devsel & DEVSEL_RW ) == 0 )
|
||||
{
|
||||
verboselog( machine, 1, "i2cmem(%d) devsel %02x: write\n", chip, c->devsel );
|
||||
c->state = STATE_BYTEADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( machine, 1, "i2cmem(%d) devsel %02x: read\n", chip, c->devsel );
|
||||
c->state = STATE_DATAOUT;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_BYTEADDR:
|
||||
c->byteaddr = c->shift;
|
||||
c->page_offset = 0;
|
||||
|
||||
verboselog( machine, 1, "i2cmem(%d) byteaddr %02x\n", chip, c->byteaddr );
|
||||
|
||||
c->state = STATE_DATAIN;
|
||||
break;
|
||||
|
||||
case STATE_DATAIN:
|
||||
if( c->wc )
|
||||
{
|
||||
verboselog( machine, 0, "i2cmem(%d) write not enabled\n", chip );
|
||||
c->state = STATE_IDLE;
|
||||
}
|
||||
else if( c->page_size > 0 )
|
||||
{
|
||||
c->page[ c->page_offset ] = c->shift;
|
||||
verboselog( machine, 1, "i2cmem(%d) page[ %04x ] <- %02x\n", chip, c->page_offset, c->page[ c->page_offset ] );
|
||||
|
||||
c->page_offset++;
|
||||
if( c->page_offset == c->page_size )
|
||||
{
|
||||
int offset = data_offset( c ) & ~( c->page_size - 1 );
|
||||
|
||||
memcpy( &c->data[ offset ], c->page, c->page_size );
|
||||
verboselog( machine, 1, "i2cmem(%d) data[ %04x to %04x ] = page\n", chip, offset, offset + c->page_size - 1 );
|
||||
|
||||
c->page_offset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = data_offset( c );
|
||||
|
||||
c->data[ offset ] = c->shift;
|
||||
verboselog( machine, 1, "i2cmem(%d) data[ %04x ] <- %02x\n", chip, offset, c->data[ offset ] );
|
||||
|
||||
c->byteaddr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
c->bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->bits == 8 )
|
||||
{
|
||||
c->sdar = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->bits = 0;
|
||||
c->sdar = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_DATAOUT:
|
||||
if( c->bits < 8 )
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
if( c->bits == 0 )
|
||||
{
|
||||
int offset = data_offset( c );
|
||||
|
||||
c->shift = c->data[ offset ];
|
||||
verboselog( machine, 1, "i2cmem(%d) data[ %04x ] -> %02x\n", chip, offset, c->data[ offset ] );
|
||||
c->byteaddr++;
|
||||
}
|
||||
|
||||
c->sdar = ( c->shift >> 7 ) & 1;
|
||||
|
||||
c->shift = ( c->shift << 1 ) & 0xff;
|
||||
c->bits++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
if( c->sdaw )
|
||||
{
|
||||
verboselog( machine, 1, "i2cmem(%d) sleep\n", chip );
|
||||
c->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
c->bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->bits == 8 )
|
||||
{
|
||||
c->sdar = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->bits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_WC:
|
||||
if( c->wc != data )
|
||||
{
|
||||
c->wc = data;
|
||||
verboselog( machine, 2, "i2cmem_write( %d, I2CMEM_WC, %d )\n", chip, c->wc );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
verboselog( machine, 0, "i2cmem_write( %d, %d, %d ) invalid line\n", chip, line, data );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i2cmem_read( running_machine *machine, int chip, int line )
|
||||
{
|
||||
struct i2cmem_chip *c;
|
||||
|
||||
if( chip >= I2CMEM_MAXCHIP )
|
||||
{
|
||||
verboselog( machine, 0, "i2cmem_read( %d, %d ) invalid chip\n", chip, line );
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = &i2cmem[ chip ];
|
||||
|
||||
switch( line )
|
||||
{
|
||||
case I2CMEM_SDA:
|
||||
verboselog( machine, 2, "i2cmem_read( %d, I2CMEM_SDA ) %d\n", chip, c->sdar & c->sdaw );
|
||||
return c->sdar & c->sdaw;
|
||||
|
||||
default:
|
||||
verboselog( machine, 0, "i2cmem_read( %d, %d ) invalid line\n", chip, line );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvram_handler_i2cmem( running_machine *machine, mame_file *file, int read_or_write, int chip )
|
||||
{
|
||||
struct i2cmem_chip *c;
|
||||
|
||||
if( chip >= I2CMEM_MAXCHIP )
|
||||
{
|
||||
verboselog( machine, 0, "nvram_handler_i2cmem( %d ) invalid chip\n", chip );
|
||||
return;
|
||||
}
|
||||
|
||||
c = &i2cmem[ chip ];
|
||||
|
||||
if( read_or_write )
|
||||
{
|
||||
mame_fwrite( file, c->data, c->data_size );
|
||||
}
|
||||
else if( file )
|
||||
{
|
||||
mame_fread( file, c->data, c->data_size );
|
||||
}
|
||||
}
|
||||
|
||||
NVRAM_HANDLER( i2cmem_0 ) { nvram_handler_i2cmem( machine, file, read_or_write, 0 ); }
|
||||
const device_type I2CMEM = i2cmem_device_config::static_alloc_device_config;
|
||||
|
@ -1,27 +1,158 @@
|
||||
/*
|
||||
/***************************************************************************
|
||||
|
||||
I2C Memory
|
||||
i2cmem.h
|
||||
|
||||
*/
|
||||
I2C Memory
|
||||
|
||||
#if !defined( I2CMEM_H )
|
||||
#define I2CMEM_H ( 1 )
|
||||
***************************************************************************/
|
||||
|
||||
#define I2CMEM_E0 ( 1 )
|
||||
#define I2CMEM_E1 ( 2 )
|
||||
#define I2CMEM_E2 ( 3 )
|
||||
#define I2CMEM_SDA ( 5 )
|
||||
#define I2CMEM_SCL ( 6 )
|
||||
#define I2CMEM_WC ( 7 )
|
||||
#pragma once
|
||||
|
||||
#define I2CMEM_MAXCHIP ( 1 )
|
||||
#ifndef __I2CMEM_H__
|
||||
#define __I2CMEM_H__
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define I2CMEM_SLAVE_ADDRESS ( 0xa0 )
|
||||
#define I2CMEM_SLAVE_ADDRESS_ALT ( 0xb0 )
|
||||
|
||||
extern void i2cmem_init( running_machine *machine, int chip, int slave_address, int page_size, int data_size, unsigned char *data );
|
||||
extern void i2cmem_write( running_machine *machine, int chip, int line, int data );
|
||||
extern int i2cmem_read( running_machine *machine, int chip, int line );
|
||||
extern NVRAM_HANDLER( i2cmem_0 );
|
||||
|
||||
#endif
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MDRV_I2CMEM_ADD( _tag, _interface ) \
|
||||
MDRV_DEVICE_ADD( _tag, I2CMEM, 0 ) \
|
||||
MDRV_DEVICE_INLINE_DATAPTR( i2cmem_device_config::INLINE_INTERFACE, &_interface )
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> i2cmem_interface
|
||||
|
||||
struct i2cmem_interface
|
||||
{
|
||||
int m_slave_address;
|
||||
int m_page_size;
|
||||
int m_data_size;
|
||||
};
|
||||
|
||||
|
||||
// ======================> i2cmem_device_config
|
||||
|
||||
class i2cmem_device_config :
|
||||
public device_config,
|
||||
public device_config_memory_interface,
|
||||
public device_config_nvram_interface,
|
||||
public i2cmem_interface
|
||||
{
|
||||
friend class i2cmem_device;
|
||||
|
||||
// construction/destruction
|
||||
i2cmem_device_config( const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock );
|
||||
|
||||
public:
|
||||
// allocators
|
||||
static device_config *static_alloc_device_config( const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock );
|
||||
virtual device_t *alloc_device( running_machine &machine ) const;
|
||||
|
||||
// inline configuration indexes
|
||||
enum
|
||||
{
|
||||
INLINE_INTERFACE
|
||||
};
|
||||
|
||||
protected:
|
||||
// device_config overrides
|
||||
virtual void device_config_complete();
|
||||
virtual bool device_validity_check( const game_driver &driver ) const;
|
||||
|
||||
// device_config_memory_interface overrides
|
||||
virtual const address_space_config *memory_space_config( int spacenum = 0 ) const;
|
||||
|
||||
// device-specific configuration
|
||||
address_space_config m_space_config;
|
||||
int m_address_bits;
|
||||
};
|
||||
|
||||
|
||||
// ======================> i2cmem_device
|
||||
|
||||
class i2cmem_device :
|
||||
public device_t,
|
||||
public device_memory_interface,
|
||||
public device_nvram_interface
|
||||
{
|
||||
friend class i2cmem_device_config;
|
||||
|
||||
// construction/destruction
|
||||
i2cmem_device( running_machine &_machine, const i2cmem_device_config &config );
|
||||
|
||||
public:
|
||||
// I/O operations
|
||||
void set_e0_line( int state );
|
||||
void set_e1_line( int state );
|
||||
void set_e2_line( int state );
|
||||
void set_sda_line( int state );
|
||||
void set_scl_line( int state );
|
||||
void set_wc_line( int state );
|
||||
int read_sda_line();
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual void nvram_default();
|
||||
virtual void nvram_read( mame_file &file );
|
||||
virtual void nvram_write( mame_file &file );
|
||||
|
||||
// internal helpers
|
||||
int address_mask();
|
||||
int select_device();
|
||||
int data_offset();
|
||||
|
||||
// internal state
|
||||
const i2cmem_device_config &m_config;
|
||||
|
||||
int m_scl;
|
||||
int m_sdaw;
|
||||
int m_e0;
|
||||
int m_e1;
|
||||
int m_e2;
|
||||
int m_wc;
|
||||
int m_sdar;
|
||||
int m_state;
|
||||
int m_bits;
|
||||
int m_shift;
|
||||
int m_devsel;
|
||||
int m_byteaddr;
|
||||
UINT8 *m_page;
|
||||
int m_page_offset;
|
||||
int m_page_size;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type I2CMEM;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_e0_write );
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_e1_write );
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_e2_write );
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_sda_write );
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_scl_write );
|
||||
WRITE_LINE_DEVICE_HANDLER( i2cmem_wc_write );
|
||||
READ_LINE_DEVICE_HANDLER( i2cmem_sda_read );
|
||||
|
||||
#endif /* __I2CMEM_H__ */
|
||||
|
@ -1,479 +0,0 @@
|
||||
/*
|
||||
I2C Memory
|
||||
|
||||
Generic ram/rom/eeprom/flash on an i2c bus. Supports specifying the slave address,
|
||||
the data size & the page size for writing.
|
||||
|
||||
inputs:
|
||||
e0,e1,e2 lower 3 bits of the slave address
|
||||
sda serial data
|
||||
scl serial clock
|
||||
wc write protect
|
||||
|
||||
outputs:
|
||||
sda serial data
|
||||
|
||||
The memory address is only 8 bits, devices larger than this have multiple slave addresses.
|
||||
The top five address bits are set at manufacture time, two values are standard.
|
||||
Up to 4096 bytes can be addressed.
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/i2cmemdev.h"
|
||||
|
||||
#define VERBOSE_LEVEL ( 0 )
|
||||
|
||||
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... )
|
||||
{
|
||||
if( VERBOSE_LEVEL >= n_level )
|
||||
{
|
||||
va_list v;
|
||||
char buf[ 32768 ];
|
||||
va_start( v, s_fmt );
|
||||
vsprintf( buf, s_fmt, v );
|
||||
va_end( v );
|
||||
logerror( "%s: %s", cpuexec_describe_context(machine), buf );
|
||||
}
|
||||
}
|
||||
|
||||
#define STATE_IDLE ( 0 )
|
||||
#define STATE_DEVSEL ( 1 )
|
||||
#define STATE_BYTEADDR ( 2 )
|
||||
#define STATE_DATAIN ( 3 )
|
||||
#define STATE_DATAOUT ( 4 )
|
||||
|
||||
#define DEVSEL_RW ( 1 )
|
||||
#define DEVSEL_ADDRESS ( 0xfe )
|
||||
|
||||
typedef struct _i2cmem_state i2cmem_state;
|
||||
struct _i2cmem_state
|
||||
{
|
||||
int slave_address;
|
||||
int scl;
|
||||
int sdaw;
|
||||
int e0;
|
||||
int e1;
|
||||
int e2;
|
||||
int wc;
|
||||
int sdar;
|
||||
int state;
|
||||
int bits;
|
||||
int shift;
|
||||
int devsel;
|
||||
int byteaddr;
|
||||
unsigned char *data;
|
||||
int data_size;
|
||||
unsigned char *page;
|
||||
int page_offset;
|
||||
int page_size;
|
||||
int readmode;
|
||||
};
|
||||
|
||||
/*-------------------------------------------------
|
||||
get_safe_token - makes sure that the passed
|
||||
in device is, in fact, an I2C memory
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE i2cmem_state *get_safe_token( running_device *device )
|
||||
{
|
||||
assert( device != NULL );
|
||||
assert( device->type() == I2CMEM );
|
||||
|
||||
return (i2cmem_state *)downcast<legacy_device_base *>(device)->token();
|
||||
}
|
||||
|
||||
static int select_device( i2cmem_state *c )
|
||||
{
|
||||
int device = ( c->slave_address & 0xf0 ) | ( c->e2 << 3 ) | ( c->e1 << 2 ) | ( c->e0 << 1 );
|
||||
int mask = DEVSEL_ADDRESS & ~( ( c->data_size - 1 ) >> 7 );
|
||||
|
||||
if( ( c->devsel & mask ) == ( device & mask ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int data_offset( i2cmem_state *c )
|
||||
{
|
||||
return ( ( ( c->devsel << 7 ) & 0xff00 ) | ( c->byteaddr & 0xff ) ) & ( c->data_size - 1 );
|
||||
}
|
||||
|
||||
void i2cmemdev_write( running_device *device, int line, int data )
|
||||
{
|
||||
i2cmem_state *c = get_safe_token( device );
|
||||
|
||||
switch( line )
|
||||
{
|
||||
case I2CMEM_E0:
|
||||
if( c->e0 != data )
|
||||
{
|
||||
c->e0 = data;
|
||||
verboselog( device->machine, 2, "i2cmem_write( I2CMEM_E0, %d )\n", c->e0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_E1:
|
||||
if( c->e1 != data )
|
||||
{
|
||||
c->e1 = data;
|
||||
verboselog( device->machine, 2, "i2cmem_write( I2CMEM_E1, %d )\n", c->e1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_E2:
|
||||
if( c->e2 != data )
|
||||
{
|
||||
c->e2 = data;
|
||||
verboselog( device->machine, 2, "i2cmem_write( I2CMEM_E2, %d )\n", c->e2 );
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_SDA:
|
||||
if( c->sdaw != data )
|
||||
{
|
||||
c->sdaw = data;
|
||||
verboselog( device->machine, 2, "i2cmem_write( I2CMEM_SDA, %d )\n", c->sdaw );
|
||||
|
||||
if( c->scl )
|
||||
{
|
||||
if( c->sdaw )
|
||||
{
|
||||
verboselog( device->machine, 1, "i2cmem stop\n");
|
||||
c->state = STATE_IDLE;
|
||||
c->byteaddr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( device->machine, 2, "i2cmem start\n");
|
||||
c->state = STATE_DEVSEL;
|
||||
c->bits = 0;
|
||||
}
|
||||
|
||||
c->sdar = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_SCL:
|
||||
if( c->scl != data )
|
||||
{
|
||||
c->scl = data;
|
||||
verboselog( device->machine, 2, "i2cmem_write( I2CMEM_SCL, %d )\n", c->scl );
|
||||
|
||||
switch( c->state )
|
||||
{
|
||||
case STATE_DEVSEL:
|
||||
case STATE_BYTEADDR:
|
||||
case STATE_DATAIN:
|
||||
if( c->bits < 8 )
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
c->shift = ( ( c->shift << 1 ) | c->sdaw ) & 0xff;
|
||||
c->bits++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
switch( c->state )
|
||||
{
|
||||
case STATE_DEVSEL:
|
||||
c->devsel = c->shift;
|
||||
|
||||
if( !select_device( c ) )
|
||||
{
|
||||
verboselog( device->machine, 1, "i2cmem devsel %02x: not this device\n", c->devsel );
|
||||
c->state = STATE_IDLE;
|
||||
}
|
||||
else if( ( c->devsel & DEVSEL_RW ) == 0 )
|
||||
{
|
||||
verboselog( device->machine, 1, "i2cmem devsel %02x: write\n", c->devsel );
|
||||
c->state = STATE_BYTEADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( device->machine, 1, "i2cmem devsel %02x: read\n", c->devsel );
|
||||
c->state = STATE_DATAOUT;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_BYTEADDR:
|
||||
c->byteaddr = c->shift;
|
||||
c->page_offset = 0;
|
||||
|
||||
verboselog( device->machine, 1, "i2cmem byteaddr %02x\n", c->byteaddr );
|
||||
|
||||
c->state = STATE_DATAIN;
|
||||
break;
|
||||
|
||||
case STATE_DATAIN:
|
||||
if( c->wc )
|
||||
{
|
||||
verboselog( device->machine, 0, "i2cmem write not enabled\n");
|
||||
c->state = STATE_IDLE;
|
||||
}
|
||||
else if( c->page_size > 0 )
|
||||
{
|
||||
c->page[ c->page_offset ] = c->shift;
|
||||
verboselog( device->machine, 1, "i2cmem page[ %04x ] <- %02x\n", c->page_offset, c->page[ c->page_offset ] );
|
||||
|
||||
c->page_offset++;
|
||||
if( c->page_offset == c->page_size )
|
||||
{
|
||||
int offset = data_offset( c ) & ~( c->page_size - 1 );
|
||||
|
||||
memcpy( &c->data[ offset ], c->page, c->page_size );
|
||||
verboselog( device->machine, 1, "i2cmem data[ %04x to %04x ] = page\n", offset, offset + c->page_size - 1 );
|
||||
|
||||
c->page_offset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = data_offset( c );
|
||||
|
||||
c->data[ offset ] = c->shift;
|
||||
verboselog( device->machine, 1, "i2cmem data[ %04x ] <- %02x\n", offset, c->data[ offset ] );
|
||||
|
||||
c->byteaddr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
c->bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->bits == 8 )
|
||||
{
|
||||
c->sdar = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->bits = 0;
|
||||
c->sdar = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_DATAOUT:
|
||||
if( c->bits < 8 )
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
if( c->bits == 0 )
|
||||
{
|
||||
int offset = data_offset( c );
|
||||
|
||||
c->shift = c->data[ offset ];
|
||||
verboselog( device->machine, 1, "i2cmem data[ %04x ] -> %02x\n", offset, c->data[ offset ] );
|
||||
c->byteaddr++;
|
||||
}
|
||||
|
||||
c->sdar = ( c->shift >> 7 ) & 1;
|
||||
|
||||
c->shift = ( c->shift << 1 ) & 0xff;
|
||||
c->bits++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->scl )
|
||||
{
|
||||
if( c->sdaw )
|
||||
{
|
||||
verboselog( device->machine, 1, "i2cmem sleep\n");
|
||||
c->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
c->bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( c->bits == 8 )
|
||||
{
|
||||
c->sdar = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->bits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case I2CMEM_WC:
|
||||
if( c->wc != data )
|
||||
{
|
||||
c->wc = data;
|
||||
verboselog( device->machine, 2, "i2cmem_write( I2CMEM_WC, %d )\n", c->wc );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
verboselog( device->machine, 0, "i2cmem_write( %d, %d ) invalid line\n", line, data );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i2cmemdev_read( running_device *device, int line )
|
||||
{
|
||||
i2cmem_state *c = get_safe_token( device );
|
||||
|
||||
switch( line )
|
||||
{
|
||||
case I2CMEM_SDA:
|
||||
if (c->readmode == 0)
|
||||
{
|
||||
verboselog( device->machine, 2, "i2cmem_read( I2CMEM_SDA ) %d\n", c->sdar & c->sdaw );
|
||||
return c->sdar & c->sdaw;
|
||||
}
|
||||
else
|
||||
{
|
||||
verboselog( device->machine, 2, "i2cmem_read( I2CMEM_SDA ) %d\n", c->sdar );
|
||||
return c->sdar;
|
||||
}
|
||||
|
||||
default:
|
||||
verboselog( device->machine, 0, "i2cmem_read( %d ) invalid line\n", line );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2cmemdev_set_read_mode( running_device *device, int mode )
|
||||
{
|
||||
i2cmem_state *c = get_safe_token( device );
|
||||
|
||||
c->readmode = mode;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
device start callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START( i2cmem )
|
||||
{
|
||||
i2cmem_state *c = get_safe_token( device );
|
||||
const i2cmem_config *config;
|
||||
unsigned char *page = NULL;
|
||||
|
||||
/* validate some basic stuff */
|
||||
assert( device != NULL );
|
||||
assert( downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config() != NULL );
|
||||
assert( device->machine != NULL );
|
||||
assert( device->machine->config != NULL );
|
||||
|
||||
config = (const i2cmem_config *)downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
|
||||
|
||||
c->scl = 0;
|
||||
c->sdaw = 0;
|
||||
c->e0 = 0;
|
||||
c->e1 = 0;
|
||||
c->e2 = 0;
|
||||
c->wc = 0;
|
||||
c->sdar = 1;
|
||||
c->state = STATE_IDLE;
|
||||
c->bits = 0;
|
||||
c->shift = 0;
|
||||
c->devsel = 0;
|
||||
c->byteaddr = 0;
|
||||
c->readmode = 0;
|
||||
|
||||
if( config != NULL )
|
||||
{
|
||||
c->data = auto_alloc_array( device->machine, UINT8, config->data_size );
|
||||
memcpy(c->data, config->data, config->data_size);
|
||||
|
||||
if( config->page_size > 0 )
|
||||
page = auto_alloc_array( device->machine, UINT8, config->page_size );
|
||||
|
||||
c->slave_address = config->slave_address;
|
||||
c->data_size = config->data_size;
|
||||
c->page_size = config->page_size;
|
||||
c->page = page;
|
||||
}
|
||||
|
||||
state_save_register_device_item( device, 0, c->scl );
|
||||
state_save_register_device_item( device, 0, c->sdaw );
|
||||
state_save_register_device_item( device, 0, c->e0 );
|
||||
state_save_register_device_item( device, 0, c->e1 );
|
||||
state_save_register_device_item( device, 0, c->e2 );
|
||||
state_save_register_device_item( device, 0, c->wc );
|
||||
state_save_register_device_item( device, 0, c->sdar );
|
||||
state_save_register_device_item( device, 0, c->state );
|
||||
state_save_register_device_item( device, 0, c->bits );
|
||||
state_save_register_device_item( device, 0, c->shift );
|
||||
state_save_register_device_item( device, 0, c->devsel );
|
||||
state_save_register_device_item( device, 0, c->byteaddr );
|
||||
state_save_register_device_item_pointer( device, 0, c->data, c->data_size );
|
||||
state_save_register_device_item( device, 0, c->readmode );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
device reset callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_RESET( i2cmem )
|
||||
{
|
||||
}
|
||||
|
||||
static DEVICE_NVRAM( i2cmem )
|
||||
{
|
||||
const i2cmem_config *config = (const i2cmem_config *)downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
|
||||
i2cmem_state *c = get_safe_token( device );
|
||||
|
||||
if( read_or_write )
|
||||
{
|
||||
mame_fwrite( file, c->data, c->data_size );
|
||||
}
|
||||
else if( file )
|
||||
{
|
||||
mame_fread( file, c->data, c->data_size );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( config->data != NULL )
|
||||
memcpy( c->data, config->data, config->data_size );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
device get info callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
DEVICE_GET_INFO( i2cmem )
|
||||
{
|
||||
switch ( state )
|
||||
{
|
||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof( i2cmem_state ); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof( i2cmem_config ); break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( i2cmem ); break;
|
||||
case DEVINFO_FCT_STOP: /* nothing */ break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( i2cmem ); break;
|
||||
case DEVINFO_FCT_NVRAM: info->nvram = DEVICE_NVRAM_NAME( i2cmem ); break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy( info->s, "I2CMEM" ); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy( info->s, "EEPROM" ); break;
|
||||
case DEVINFO_STR_VERSION: strcpy( info->s, "1.0" ); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy( info->s, __FILE__ ); break;
|
||||
case DEVINFO_STR_CREDITS: strcpy( info->s, "Copyright Nicola Salmoria and the MAME Team" ); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEFINE_LEGACY_NVRAM_DEVICE(I2CMEM, i2cmem);
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* I2C Memory
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined( I2CMEMDEV_H )
|
||||
#define I2CMEMDEV_H ( 1 )
|
||||
|
||||
#include "devlegcy.h"
|
||||
|
||||
#define I2CMEM_E0 ( 1 )
|
||||
#define I2CMEM_E1 ( 2 )
|
||||
#define I2CMEM_E2 ( 3 )
|
||||
#define I2CMEM_SDA ( 5 )
|
||||
#define I2CMEM_SCL ( 6 )
|
||||
#define I2CMEM_WC ( 7 )
|
||||
|
||||
#define I2CMEM_SLAVE_ADDRESS ( 0xa0 )
|
||||
#define I2CMEM_SLAVE_ADDRESS_ALT ( 0xb0 )
|
||||
|
||||
typedef struct _i2cmem_config i2cmem_config;
|
||||
struct _i2cmem_config
|
||||
{
|
||||
const int slave_address;
|
||||
const int page_size;
|
||||
const int data_size;
|
||||
const char *data;
|
||||
};
|
||||
|
||||
DECLARE_LEGACY_NVRAM_DEVICE(I2CMEM, i2cmem);
|
||||
|
||||
#define MDRV_I2CMEM_ADD(_tag, _slave_address, _page_size, _data_size, _data) \
|
||||
MDRV_DEVICE_ADD(_tag, I2CMEM, 0) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(i2cmem_config, slave_address, _slave_address) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(i2cmem_config, page_size, _page_size) \
|
||||
MDRV_DEVICE_CONFIG_DATA32(i2cmem_config, data_size, _data_size) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(i2cmem_config, data, _data)
|
||||
|
||||
|
||||
void i2cmemdev_write( running_device *device, int line, int data );
|
||||
int i2cmemdev_read( running_device *device, int line );
|
||||
void i2cmemdev_set_read_mode( running_device *device, int mode );
|
||||
|
||||
#endif
|
@ -330,6 +330,7 @@ routines :
|
||||
#include "includes/amiga.h"
|
||||
#include "includes/cubocd32.h"
|
||||
#include "machine/6526cia.h"
|
||||
#include "machine/i2cmem.h"
|
||||
|
||||
|
||||
/* set to 0 to use control panel with only buttons (as in quiz games) - joy is default in dispenser setup */
|
||||
@ -1042,6 +1043,14 @@ static const mos6526_interface cia_1_intf =
|
||||
DEVCB_NULL
|
||||
};
|
||||
|
||||
#define NVRAM_SIZE 1024
|
||||
#define NVRAM_PAGE_SIZE 16 /* max size of one write request */
|
||||
|
||||
static const i2cmem_interface i2cmem_interface =
|
||||
{
|
||||
I2CMEM_SLAVE_ADDRESS, NVRAM_PAGE_SIZE, NVRAM_SIZE
|
||||
};
|
||||
|
||||
static MACHINE_DRIVER_START( cd32 )
|
||||
|
||||
/* basic machine hardware */
|
||||
@ -1049,7 +1058,8 @@ static MACHINE_DRIVER_START( cd32 )
|
||||
MDRV_CPU_PROGRAM_MAP(cd32_map)
|
||||
|
||||
MDRV_MACHINE_RESET(amiga)
|
||||
MDRV_NVRAM_HANDLER(cd32)
|
||||
|
||||
MDRV_I2CMEM_ADD("i2cmem",i2cmem_interface)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
|
||||
|
@ -217,6 +217,12 @@ static int sda_dir = 0;
|
||||
#define CMOS_NVRAM_SIZE 0x2000
|
||||
#define eeprom_NVRAM_SIZE 0x200 // 4k Bit
|
||||
|
||||
/* EEPROM is a X2404P 4K-bit Serial I2C Bus */
|
||||
static const i2cmem_interface i2cmem_interface =
|
||||
{
|
||||
I2CMEM_SLAVE_ADDRESS, 8, eeprom_NVRAM_SIZE
|
||||
};
|
||||
|
||||
/* prototypes */
|
||||
static WRITE_LINE_DEVICE_HANDLER(crtc_vsync);
|
||||
static MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr);
|
||||
@ -275,8 +281,6 @@ static NVRAM_HANDLER( peplus )
|
||||
memset(cmos_ram, 0, CMOS_NVRAM_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
NVRAM_HANDLER_CALL(i2cmem_0);
|
||||
}
|
||||
|
||||
|
||||
@ -457,11 +461,11 @@ static WRITE8_HANDLER( peplus_output_bank_c_w )
|
||||
output_set_value("pe_bnkc7",(data >> 7) & 1); /* Game Meter */
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER(i2c_nvram_w)
|
||||
static WRITE8_DEVICE_HANDLER(i2c_nvram_w)
|
||||
{
|
||||
i2cmem_write(space->machine, 0, I2CMEM_SCL, BIT(data, 2));
|
||||
i2cmem_scl_write(device,BIT(data, 2));
|
||||
sda_dir = BIT(data, 1);
|
||||
i2cmem_write(space->machine, 0, I2CMEM_SDA, BIT(data, 0));
|
||||
i2cmem_sda_write(device,BIT(data, 0));
|
||||
}
|
||||
|
||||
|
||||
@ -531,7 +535,7 @@ static READ8_HANDLER( peplus_watchdog_r )
|
||||
return 0x00; // Watchdog
|
||||
}
|
||||
|
||||
static READ8_HANDLER( peplus_input_bank_a_r )
|
||||
static READ8_DEVICE_HANDLER( peplus_input_bank_a_r )
|
||||
{
|
||||
/*
|
||||
Bit 0 = COIN DETECTOR A
|
||||
@ -546,25 +550,25 @@ static READ8_HANDLER( peplus_input_bank_a_r )
|
||||
UINT8 bank_a = 0x50; // Turn Off Low Battery and Hopper Full Statuses
|
||||
UINT8 coin_optics = 0x00;
|
||||
UINT8 coin_out = 0x00;
|
||||
UINT64 curr_cycles = space->machine->firstcpu->total_cycles();
|
||||
UINT64 curr_cycles = device->machine->firstcpu->total_cycles();
|
||||
UINT16 door_wait = 500;
|
||||
|
||||
UINT8 sda = 0;
|
||||
if(!sda_dir)
|
||||
{
|
||||
sda = i2cmem_read(space->machine, 0, I2CMEM_SDA);
|
||||
sda = i2cmem_sda_read(device);
|
||||
}
|
||||
|
||||
if ((input_port_read_safe(space->machine, "SENSOR",0x00) & 0x01) == 0x01 && coin_state == 0) {
|
||||
if ((input_port_read_safe(device->machine, "SENSOR",0x00) & 0x01) == 0x01 && coin_state == 0) {
|
||||
coin_state = 1; // Start Coin Cycle
|
||||
last_cycles = space->machine->firstcpu->total_cycles();
|
||||
last_cycles = device->machine->firstcpu->total_cycles();
|
||||
} else {
|
||||
/* Process Next Coin Optic State */
|
||||
if (curr_cycles - last_cycles > 600000/6 && coin_state != 0) {
|
||||
coin_state++;
|
||||
if (coin_state > 5)
|
||||
coin_state = 0;
|
||||
last_cycles = space->machine->firstcpu->total_cycles();
|
||||
last_cycles = device->machine->firstcpu->total_cycles();
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,12 +598,12 @@ static READ8_HANDLER( peplus_input_bank_a_r )
|
||||
door_wait = 12345;
|
||||
|
||||
if (curr_cycles - last_door > door_wait) {
|
||||
if ((input_port_read_safe(space->machine, "DOOR",0xff) & 0x01) == 0x01) {
|
||||
if ((input_port_read_safe(device->machine, "DOOR",0xff) & 0x01) == 0x01) {
|
||||
door_open = (!door_open & 0x01);
|
||||
} else {
|
||||
door_open = 1;
|
||||
}
|
||||
last_door = space->machine->firstcpu->total_cycles();
|
||||
last_door = device->machine->firstcpu->total_cycles();
|
||||
}
|
||||
|
||||
if (curr_cycles - last_coin_out > 600000/12 && coin_out_state != 0) { // Guessing with 600000
|
||||
@ -609,7 +613,7 @@ static READ8_HANDLER( peplus_input_bank_a_r )
|
||||
coin_out_state = 3; // Coin-Out On
|
||||
}
|
||||
|
||||
last_coin_out = space->machine->firstcpu->total_cycles();
|
||||
last_coin_out = device->machine->firstcpu->total_cycles();
|
||||
}
|
||||
|
||||
switch (coin_out_state)
|
||||
@ -757,10 +761,10 @@ static ADDRESS_MAP_START( peplus_iomap, ADDRESS_SPACE_IO, 8 )
|
||||
AM_RANGE(0x7000, 0x7fff) AM_READWRITE(peplus_s7000_r, peplus_s7000_w) AM_BASE(&s7000_ram)
|
||||
|
||||
// Input Bank A, Output Bank C
|
||||
AM_RANGE(0x8000, 0x8000) AM_READ(peplus_input_bank_a_r) AM_WRITE(peplus_output_bank_c_w)
|
||||
AM_RANGE(0x8000, 0x8000) AM_DEVREAD("i2cmem",peplus_input_bank_a_r) AM_WRITE(peplus_output_bank_c_w)
|
||||
|
||||
// Drop Door, I2C EEPROM Writes
|
||||
AM_RANGE(0x9000, 0x9000) AM_READ(peplus_dropdoor_r) AM_WRITE(i2c_nvram_w)
|
||||
AM_RANGE(0x9000, 0x9000) AM_READ(peplus_dropdoor_r) AM_DEVWRITE("i2cmem",i2c_nvram_w)
|
||||
|
||||
// Input Banks B & C, Output Bank B
|
||||
AM_RANGE(0xa000, 0xa000) AM_READ_PORT("IN0") AM_WRITE(peplus_output_bank_b_w)
|
||||
@ -1037,6 +1041,7 @@ static MACHINE_DRIVER_START( peplus )
|
||||
MDRV_PALETTE_LENGTH(16*16*2)
|
||||
|
||||
MDRV_MC6845_ADD("crtc", R6545_1, MC6845_CLOCK, mc6845_intf)
|
||||
MDRV_I2CMEM_ADD("i2cmem", i2cmem_interface)
|
||||
|
||||
MDRV_PALETTE_INIT(peplus)
|
||||
MDRV_VIDEO_START(peplus)
|
||||
@ -1057,9 +1062,6 @@ MACHINE_DRIVER_END
|
||||
/* Normal board */
|
||||
static void peplus_init(running_machine *machine)
|
||||
{
|
||||
/* EEPROM is a X2404P 4K-bit Serial I2C Bus */
|
||||
i2cmem_init(machine, 0, I2CMEM_SLAVE_ADDRESS, 8, eeprom_NVRAM_SIZE, NULL);
|
||||
|
||||
/* default : no address to patch in program RAM to enable autohold feature */
|
||||
autohold_addr = 0;
|
||||
}
|
||||
|
@ -578,16 +578,16 @@ static WRITE32_HANDLER(serial_w)
|
||||
*/
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER(security_w)
|
||||
static WRITE32_DEVICE_HANDLER(security_w)
|
||||
{
|
||||
i2cmem_write( space->machine, 0, I2CMEM_SCL, ( data >> 4 ) & 1 );
|
||||
i2cmem_write( space->machine, 0, I2CMEM_SDA, ( data >> 3 ) & 1 );
|
||||
i2cmem_scl_write( device, ( data >> 4 ) & 1 );
|
||||
i2cmem_sda_write( device, ( data >> 3 ) & 1 );
|
||||
}
|
||||
|
||||
static READ32_HANDLER(security_r)
|
||||
static READ32_DEVICE_HANDLER(security_r)
|
||||
{
|
||||
/* 0x4000 ?? */
|
||||
return i2cmem_read( space->machine, 0, I2CMEM_SDA ) << 12;
|
||||
return i2cmem_sda_read( device ) << 12;
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER(shared_psx_w)
|
||||
@ -636,8 +636,8 @@ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 32 )
|
||||
|
||||
|
||||
AM_RANGE(0x1f260000, 0x1f260003) AM_WRITE(serial_w)
|
||||
AM_RANGE(0x1f270000, 0x1f270003) AM_WRITE(security_w)
|
||||
AM_RANGE(0x1f280000, 0x1f280003) AM_READ(security_r)
|
||||
AM_RANGE(0x1f270000, 0x1f270003) AM_DEVWRITE("security",security_w)
|
||||
AM_RANGE(0x1f280000, 0x1f280003) AM_DEVREAD("security",security_r)
|
||||
AM_RANGE(0x1f290000, 0x1f29007f) AM_DEVREADWRITE8("rtc", rtc65271_rtc_r, rtc65271_rtc_w, 0x00ff00ff)
|
||||
AM_RANGE(0x1f2a0000, 0x1f2a007f) AM_DEVREADWRITE8("rtc", rtc65271_xram_r, rtc65271_xram_w, 0x00ff00ff)
|
||||
AM_RANGE(0x1f2b0000, 0x1f2b00ff) AM_WRITE(twinkle_output_w)
|
||||
@ -875,11 +875,11 @@ static DRIVER_INIT( twinkle )
|
||||
psx_dma_install_read_handler(5, scsi_dma_read);
|
||||
psx_dma_install_write_handler(5, scsi_dma_write);
|
||||
|
||||
i2cmem_init( machine, 0, I2CMEM_SLAVE_ADDRESS, 0, memory_region_length( machine, "user2" ), memory_region( machine, "user2" ) );
|
||||
i2cmem_write( machine, 0, I2CMEM_E0, 0 );
|
||||
i2cmem_write( machine, 0, I2CMEM_E1, 0 );
|
||||
i2cmem_write( machine, 0, I2CMEM_E2, 0 );
|
||||
i2cmem_write( machine, 0, I2CMEM_WC, 0 );
|
||||
running_device *i2cmem = devtag_get_device(machine, "security");
|
||||
i2cmem_e0_write( i2cmem, 0 );
|
||||
i2cmem_e1_write( i2cmem, 0 );
|
||||
i2cmem_e2_write( i2cmem, 0 );
|
||||
i2cmem_wc_write( i2cmem, 0 );
|
||||
}
|
||||
|
||||
static MACHINE_RESET( twinkle )
|
||||
@ -903,6 +903,11 @@ static const psx_spu_interface twinkle_psxspu_interface =
|
||||
psx_dma_install_write_handler
|
||||
};
|
||||
|
||||
static const i2cmem_interface i2cmem_interface =
|
||||
{
|
||||
I2CMEM_SLAVE_ADDRESS, 0, 0x100
|
||||
};
|
||||
|
||||
static MACHINE_DRIVER_START( twinkle )
|
||||
/* basic machine hardware */
|
||||
MDRV_CPU_ADD("maincpu", PSXCPU, XTAL_67_7376MHz )
|
||||
@ -915,7 +920,7 @@ static MACHINE_DRIVER_START( twinkle )
|
||||
MDRV_WATCHDOG_TIME_INIT(MSEC(1200)) /* check TD pin on LTC1232 */
|
||||
|
||||
MDRV_MACHINE_RESET( twinkle )
|
||||
MDRV_NVRAM_HANDLER( i2cmem_0 )
|
||||
MDRV_I2CMEM_ADD("security",i2cmem_interface)
|
||||
|
||||
MDRV_IDE_CONTROLLER_ADD("ide", ide_interrupt)
|
||||
MDRV_RTC65271_ADD("rtc", NULL)
|
||||
@ -1015,7 +1020,7 @@ ROM_END
|
||||
ROM_START( bmiidx )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", ROMREGION_ERASE00 ) /* security */
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
|
||||
DISK_REGION( "cdrom0" ) // program
|
||||
DISK_IMAGE_READONLY("863jaa01", 0, SHA1(aee12de1dc5dd44e5bf7b62133ed695b80999390) )
|
||||
@ -1028,13 +1033,13 @@ ROM_START( bmiidx )
|
||||
ROM_END
|
||||
|
||||
ROM_START( bmiidx3 )
|
||||
TWINKLE_BIOS
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_LOAD( "992j.pd", 0x000000, 0x000100, BAD_DUMP CRC(51f24913) SHA1(574b555e3d0c234011198d218d7ae5e95091acb1) )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "992j.pd", 0x000000, 0x000100, BAD_DUMP CRC(51f24913) SHA1(574b555e3d0c234011198d218d7ae5e95091acb1) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
DISK_IMAGE_READONLY( "992jaa01", 0, BAD_DUMP SHA1(7e5389735dff379bb286ba3744edf59b7dfcc74b) )
|
||||
DISK_REGION( "cdrom0" )
|
||||
DISK_IMAGE_READONLY( "992jaa01", 0, BAD_DUMP SHA1(7e5389735dff379bb286ba3744edf59b7dfcc74b) )
|
||||
// DISK_IMAGE_READONLY( "992jaahd", 1, NO_DUMP )
|
||||
// DISK_IMAGE_READONLY( "992jaa02", 2, NO_DUMP )
|
||||
ROM_END
|
||||
@ -1042,7 +1047,7 @@ ROM_END
|
||||
ROM_START( bmiidx4 )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "a03j.pd", 0x000000, 0x000100, CRC(8860cfb6) SHA1(85a5b27f24d4baa7960e692b91c0cf3dc5388e72) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1054,7 +1059,7 @@ ROM_END
|
||||
ROM_START( bmiidx6 )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "b4uj.pd", 0x000000, 0x000100, BAD_DUMP CRC(0ab15633) SHA1(df004ff41f35b16089f69808ccf53a5e5cc13ac3) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1066,7 +1071,7 @@ ROM_END
|
||||
ROM_START( bmiidx7 )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "b44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(5baf4761) SHA1(aa7e07eb2cada03b85bdf11ac6a3de65f4253eef) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1078,7 +1083,7 @@ ROM_END
|
||||
ROM_START( bmiidx8 )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "c44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(04c22349) SHA1(d1cb78911cb1ca660d393a81ed3ed07b24c51525) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1090,7 +1095,7 @@ ROM_END
|
||||
ROM_START( bmiidxc )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1102,7 +1107,7 @@ ROM_END
|
||||
ROM_START( bmiidxc2 )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "984j.pd", 0x000000, 0x000100, BAD_DUMP CRC(213843e5) SHA1(5571db155a60fa4087dd996af48e8e27fc1c518c) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1114,7 +1119,7 @@ ROM_END
|
||||
ROM_START( bmiidxca )
|
||||
TWINKLE_BIOS
|
||||
|
||||
ROM_REGION( 0x100, "user2", 0 )
|
||||
ROM_REGION( 0x100, "security", 0 )
|
||||
ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) )
|
||||
|
||||
DISK_REGION( "cdrom0" )
|
||||
@ -1123,7 +1128,7 @@ ROM_START( bmiidxca )
|
||||
// DISK_IMAGE_READONLY( "abmjaa02", 2, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
GAME( 1999, gq863, 0, twinkle, twinkle, twinkle, ROT0, "Konami", "Twinkle System", GAME_IS_BIOS_ROOT )
|
||||
GAME( 1999, gq863, 0, twinkle, twinkle, twinkle, ROT0, "Konami", "Twinkle System", GAME_IS_BIOS_ROOT )
|
||||
|
||||
/* VCD */
|
||||
GAME( 1999, bmiidx, gq863, twinkle, twinkle, twinkle, ROT0, "Konami", "beatmania IIDX (863 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )
|
||||
|
@ -27,9 +27,6 @@ TODO: Add CDDA support
|
||||
#define CD_SECTOR_TIME (1000/((150*1024)/2048)) /* 1X CDROM sector time in msec (300KBps) */
|
||||
|
||||
|
||||
#define NVRAM_SIZE 1024
|
||||
#define NVRAM_PAGE_SIZE 16 /* max size of one write request */
|
||||
|
||||
static struct akiko_def
|
||||
{
|
||||
/* chunky to planar converter */
|
||||
@ -63,6 +60,7 @@ static struct akiko_def
|
||||
UINT8 * cdrom_toc;
|
||||
emu_timer *dma_timer;
|
||||
emu_timer *frame_timer;
|
||||
running_device *i2cmem;
|
||||
} akiko;
|
||||
|
||||
static TIMER_CALLBACK(akiko_dma_proc);
|
||||
@ -78,8 +76,6 @@ static void amiga_akiko_exit(running_machine& machine)
|
||||
|
||||
void amiga_akiko_init(running_machine* machine)
|
||||
{
|
||||
i2cmem_init( machine, 0, I2CMEM_SLAVE_ADDRESS, NVRAM_PAGE_SIZE, NVRAM_SIZE, NULL );
|
||||
|
||||
akiko.c2p_input_index = 0;
|
||||
akiko.c2p_output_index = 0;
|
||||
|
||||
@ -106,6 +102,7 @@ void amiga_akiko_init(running_machine* machine)
|
||||
akiko.cdrom_toc = NULL;
|
||||
akiko.dma_timer = timer_alloc(machine, akiko_dma_proc, NULL);
|
||||
akiko.frame_timer = timer_alloc(machine, akiko_frame_proc, NULL);
|
||||
akiko.i2cmem = devtag_get_device(machine, "i2cmem");
|
||||
|
||||
machine->add_notifier(MACHINE_NOTIFY_EXIT, amiga_akiko_exit);
|
||||
|
||||
@ -166,8 +163,8 @@ static void akiko_nvram_write(running_machine *machine, UINT32 data)
|
||||
akiko.i2c_scl_dir = BIT(data,15);
|
||||
akiko.i2c_sda_dir = BIT(data,14);
|
||||
|
||||
i2cmem_write( machine, 0, I2CMEM_SCL, akiko.i2c_scl_out );
|
||||
i2cmem_write( machine, 0, I2CMEM_SDA, akiko.i2c_sda_out );
|
||||
i2cmem_scl_write( akiko.i2cmem, akiko.i2c_scl_out );
|
||||
i2cmem_sda_write( akiko.i2cmem, akiko.i2c_sda_out );
|
||||
}
|
||||
|
||||
static UINT32 akiko_nvram_read(running_machine *machine)
|
||||
@ -189,7 +186,7 @@ static UINT32 akiko_nvram_read(running_machine *machine)
|
||||
}
|
||||
else
|
||||
{
|
||||
v |= i2cmem_read( machine, 0, I2CMEM_SDA ) << 30;
|
||||
v |= i2cmem_sda_read( akiko.i2cmem ) << 30;
|
||||
}
|
||||
|
||||
v |= akiko.i2c_scl_dir << 15;
|
||||
@ -198,11 +195,6 @@ static UINT32 akiko_nvram_read(running_machine *machine)
|
||||
return v;
|
||||
}
|
||||
|
||||
NVRAM_HANDLER( cd32 )
|
||||
{
|
||||
NVRAM_HANDLER_CALL(i2cmem_0);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Akiko Chunky to Planar converter
|
||||
|
Loading…
Reference in New Issue
Block a user