turned i2cmem into a c++ device & ditched the unused legacy device.

This commit is contained in:
smf- 2010-07-07 13:05:02 +00:00
parent c35336557d
commit c13eb4d193
10 changed files with 780 additions and 985 deletions

2
.gitattributes vendored
View File

@ -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/generic.h svneol=native#text/plain
src/emu/machine/i2cmem.c 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/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.c svneol=native#text/plain
src/emu/machine/i8243.h svneol=native#text/plain src/emu/machine/i8243.h svneol=native#text/plain
src/emu/machine/i8255a.c svneol=native#text/plain src/emu/machine/i8255a.c svneol=native#text/plain

View File

@ -160,7 +160,6 @@ EMUMACHINEOBJS = \
$(EMUMACHINE)/i8243.o \ $(EMUMACHINE)/i8243.o \
$(EMUMACHINE)/i8255a.o \ $(EMUMACHINE)/i8255a.o \
$(EMUMACHINE)/i2cmem.o \ $(EMUMACHINE)/i2cmem.o \
$(EMUMACHINE)/i2cmemdev.o \
$(EMUMACHINE)/idectrl.o \ $(EMUMACHINE)/idectrl.o \
$(EMUMACHINE)/ins8154.o \ $(EMUMACHINE)/ins8154.o \
$(EMUMACHINE)/ins8250.o \ $(EMUMACHINE)/ins8250.o \

View File

@ -1,4 +1,4 @@
/* /***************************************************************************
I2C Memory 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. The top five address bits are set at manufacture time, two values are standard.
Up to 4096 bytes can be addressed. Up to 4096 bytes can be addressed.
*/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "machine/i2cmem.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_IDLE ( 0 )
#define STATE_DEVSEL ( 1 ) #define STATE_DEVSEL ( 1 )
#define STATE_BYTEADDR ( 2 ) #define STATE_BYTEADDR ( 2 )
@ -69,71 +32,571 @@ struct i2cmem_chip
#define DEVSEL_RW ( 1 ) #define DEVSEL_RW ( 1 )
#define DEVSEL_ADDRESS ( 0xfe ) #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; if( VERBOSE_LEVEL >= n_level )
UINT8 *page = NULL;
if( chip >= I2CMEM_MAXCHIP )
{ {
verboselog( machine, 0, "i2cmem_init( %d ) invalid chip\n", chip ); va_list v;
return; 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 ) //**************************************************************************
{ // GLOBAL VARIABLES
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 ) )
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; return 1;
} }
@ -141,291 +604,9 @@ static int select_device( struct i2cmem_chip *c )
return 0; 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 ) const device_type I2CMEM = i2cmem_device_config::static_alloc_device_config;
{
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 ); }

View File

@ -1,27 +1,158 @@
/* /***************************************************************************
I2C Memory i2cmem.h
*/ I2C Memory
#if !defined( I2CMEM_H ) ***************************************************************************/
#define I2CMEM_H ( 1 )
#define I2CMEM_E0 ( 1 ) #pragma once
#define I2CMEM_E1 ( 2 )
#define I2CMEM_E2 ( 3 )
#define I2CMEM_SDA ( 5 )
#define I2CMEM_SCL ( 6 )
#define I2CMEM_WC ( 7 )
#define I2CMEM_MAXCHIP ( 1 ) #ifndef __I2CMEM_H__
#define __I2CMEM_H__
/***************************************************************************
CONSTANTS
***************************************************************************/
#define I2CMEM_SLAVE_ADDRESS ( 0xa0 ) #define I2CMEM_SLAVE_ADDRESS ( 0xa0 )
#define I2CMEM_SLAVE_ADDRESS_ALT ( 0xb0 ) #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__ */

View File

@ -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);

View File

@ -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

View File

@ -330,6 +330,7 @@ routines :
#include "includes/amiga.h" #include "includes/amiga.h"
#include "includes/cubocd32.h" #include "includes/cubocd32.h"
#include "machine/6526cia.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 */ /* 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 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 ) static MACHINE_DRIVER_START( cd32 )
/* basic machine hardware */ /* basic machine hardware */
@ -1049,7 +1058,8 @@ static MACHINE_DRIVER_START( cd32 )
MDRV_CPU_PROGRAM_MAP(cd32_map) MDRV_CPU_PROGRAM_MAP(cd32_map)
MDRV_MACHINE_RESET(amiga) MDRV_MACHINE_RESET(amiga)
MDRV_NVRAM_HANDLER(cd32)
MDRV_I2CMEM_ADD("i2cmem",i2cmem_interface)
/* video hardware */ /* video hardware */
MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)

View File

@ -217,6 +217,12 @@ static int sda_dir = 0;
#define CMOS_NVRAM_SIZE 0x2000 #define CMOS_NVRAM_SIZE 0x2000
#define eeprom_NVRAM_SIZE 0x200 // 4k Bit #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 */ /* prototypes */
static WRITE_LINE_DEVICE_HANDLER(crtc_vsync); static WRITE_LINE_DEVICE_HANDLER(crtc_vsync);
static MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr); static MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr);
@ -275,8 +281,6 @@ static NVRAM_HANDLER( peplus )
memset(cmos_ram, 0, CMOS_NVRAM_SIZE); 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 */ 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); 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 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 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 bank_a = 0x50; // Turn Off Low Battery and Hopper Full Statuses
UINT8 coin_optics = 0x00; UINT8 coin_optics = 0x00;
UINT8 coin_out = 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; UINT16 door_wait = 500;
UINT8 sda = 0; UINT8 sda = 0;
if(!sda_dir) 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 coin_state = 1; // Start Coin Cycle
last_cycles = space->machine->firstcpu->total_cycles(); last_cycles = device->machine->firstcpu->total_cycles();
} else { } else {
/* Process Next Coin Optic State */ /* Process Next Coin Optic State */
if (curr_cycles - last_cycles > 600000/6 && coin_state != 0) { if (curr_cycles - last_cycles > 600000/6 && coin_state != 0) {
coin_state++; coin_state++;
if (coin_state > 5) if (coin_state > 5)
coin_state = 0; 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; door_wait = 12345;
if (curr_cycles - last_door > door_wait) { 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); door_open = (!door_open & 0x01);
} else { } else {
door_open = 1; 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 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 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) 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) AM_RANGE(0x7000, 0x7fff) AM_READWRITE(peplus_s7000_r, peplus_s7000_w) AM_BASE(&s7000_ram)
// Input Bank A, Output Bank C // 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 // 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 // Input Banks B & C, Output Bank B
AM_RANGE(0xa000, 0xa000) AM_READ_PORT("IN0") AM_WRITE(peplus_output_bank_b_w) 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_PALETTE_LENGTH(16*16*2)
MDRV_MC6845_ADD("crtc", R6545_1, MC6845_CLOCK, mc6845_intf) MDRV_MC6845_ADD("crtc", R6545_1, MC6845_CLOCK, mc6845_intf)
MDRV_I2CMEM_ADD("i2cmem", i2cmem_interface)
MDRV_PALETTE_INIT(peplus) MDRV_PALETTE_INIT(peplus)
MDRV_VIDEO_START(peplus) MDRV_VIDEO_START(peplus)
@ -1057,9 +1062,6 @@ MACHINE_DRIVER_END
/* Normal board */ /* Normal board */
static void peplus_init(running_machine *machine) 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 */ /* default : no address to patch in program RAM to enable autohold feature */
autohold_addr = 0; autohold_addr = 0;
} }

View File

@ -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_scl_write( device, ( data >> 4 ) & 1 );
i2cmem_write( space->machine, 0, I2CMEM_SDA, ( data >> 3 ) & 1 ); i2cmem_sda_write( device, ( data >> 3 ) & 1 );
} }
static READ32_HANDLER(security_r) static READ32_DEVICE_HANDLER(security_r)
{ {
/* 0x4000 ?? */ /* 0x4000 ?? */
return i2cmem_read( space->machine, 0, I2CMEM_SDA ) << 12; return i2cmem_sda_read( device ) << 12;
} }
static WRITE32_HANDLER(shared_psx_w) 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(0x1f260000, 0x1f260003) AM_WRITE(serial_w)
AM_RANGE(0x1f270000, 0x1f270003) AM_WRITE(security_w) AM_RANGE(0x1f270000, 0x1f270003) AM_DEVWRITE("security",security_w)
AM_RANGE(0x1f280000, 0x1f280003) AM_READ(security_r) 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(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(0x1f2a0000, 0x1f2a007f) AM_DEVREADWRITE8("rtc", rtc65271_xram_r, rtc65271_xram_w, 0x00ff00ff)
AM_RANGE(0x1f2b0000, 0x1f2b00ff) AM_WRITE(twinkle_output_w) 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_read_handler(5, scsi_dma_read);
psx_dma_install_write_handler(5, scsi_dma_write); 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" ) ); running_device *i2cmem = devtag_get_device(machine, "security");
i2cmem_write( machine, 0, I2CMEM_E0, 0 ); i2cmem_e0_write( i2cmem, 0 );
i2cmem_write( machine, 0, I2CMEM_E1, 0 ); i2cmem_e1_write( i2cmem, 0 );
i2cmem_write( machine, 0, I2CMEM_E2, 0 ); i2cmem_e2_write( i2cmem, 0 );
i2cmem_write( machine, 0, I2CMEM_WC, 0 ); i2cmem_wc_write( i2cmem, 0 );
} }
static MACHINE_RESET( twinkle ) static MACHINE_RESET( twinkle )
@ -903,6 +903,11 @@ static const psx_spu_interface twinkle_psxspu_interface =
psx_dma_install_write_handler psx_dma_install_write_handler
}; };
static const i2cmem_interface i2cmem_interface =
{
I2CMEM_SLAVE_ADDRESS, 0, 0x100
};
static MACHINE_DRIVER_START( twinkle ) static MACHINE_DRIVER_START( twinkle )
/* basic machine hardware */ /* basic machine hardware */
MDRV_CPU_ADD("maincpu", PSXCPU, XTAL_67_7376MHz ) 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_WATCHDOG_TIME_INIT(MSEC(1200)) /* check TD pin on LTC1232 */
MDRV_MACHINE_RESET( twinkle ) MDRV_MACHINE_RESET( twinkle )
MDRV_NVRAM_HANDLER( i2cmem_0 ) MDRV_I2CMEM_ADD("security",i2cmem_interface)
MDRV_IDE_CONTROLLER_ADD("ide", ide_interrupt) MDRV_IDE_CONTROLLER_ADD("ide", ide_interrupt)
MDRV_RTC65271_ADD("rtc", NULL) MDRV_RTC65271_ADD("rtc", NULL)
@ -1015,7 +1020,7 @@ ROM_END
ROM_START( bmiidx ) ROM_START( bmiidx )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", ROMREGION_ERASE00 ) /* security */ ROM_REGION( 0x100, "security", 0 )
DISK_REGION( "cdrom0" ) // program DISK_REGION( "cdrom0" ) // program
DISK_IMAGE_READONLY("863jaa01", 0, SHA1(aee12de1dc5dd44e5bf7b62133ed695b80999390) ) DISK_IMAGE_READONLY("863jaa01", 0, SHA1(aee12de1dc5dd44e5bf7b62133ed695b80999390) )
@ -1028,13 +1033,13 @@ ROM_START( bmiidx )
ROM_END ROM_END
ROM_START( bmiidx3 ) ROM_START( bmiidx3 )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "992j.pd", 0x000000, 0x000100, BAD_DUMP CRC(51f24913) SHA1(574b555e3d0c234011198d218d7ae5e95091acb1) ) ROM_LOAD( "992j.pd", 0x000000, 0x000100, BAD_DUMP CRC(51f24913) SHA1(574b555e3d0c234011198d218d7ae5e95091acb1) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
DISK_IMAGE_READONLY( "992jaa01", 0, BAD_DUMP SHA1(7e5389735dff379bb286ba3744edf59b7dfcc74b) ) DISK_IMAGE_READONLY( "992jaa01", 0, BAD_DUMP SHA1(7e5389735dff379bb286ba3744edf59b7dfcc74b) )
// DISK_IMAGE_READONLY( "992jaahd", 1, NO_DUMP ) // DISK_IMAGE_READONLY( "992jaahd", 1, NO_DUMP )
// DISK_IMAGE_READONLY( "992jaa02", 2, NO_DUMP ) // DISK_IMAGE_READONLY( "992jaa02", 2, NO_DUMP )
ROM_END ROM_END
@ -1042,7 +1047,7 @@ ROM_END
ROM_START( bmiidx4 ) ROM_START( bmiidx4 )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "a03j.pd", 0x000000, 0x000100, CRC(8860cfb6) SHA1(85a5b27f24d4baa7960e692b91c0cf3dc5388e72) ) ROM_LOAD( "a03j.pd", 0x000000, 0x000100, CRC(8860cfb6) SHA1(85a5b27f24d4baa7960e692b91c0cf3dc5388e72) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1054,7 +1059,7 @@ ROM_END
ROM_START( bmiidx6 ) ROM_START( bmiidx6 )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "b4uj.pd", 0x000000, 0x000100, BAD_DUMP CRC(0ab15633) SHA1(df004ff41f35b16089f69808ccf53a5e5cc13ac3) ) ROM_LOAD( "b4uj.pd", 0x000000, 0x000100, BAD_DUMP CRC(0ab15633) SHA1(df004ff41f35b16089f69808ccf53a5e5cc13ac3) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1066,7 +1071,7 @@ ROM_END
ROM_START( bmiidx7 ) ROM_START( bmiidx7 )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "b44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(5baf4761) SHA1(aa7e07eb2cada03b85bdf11ac6a3de65f4253eef) ) ROM_LOAD( "b44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(5baf4761) SHA1(aa7e07eb2cada03b85bdf11ac6a3de65f4253eef) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1078,7 +1083,7 @@ ROM_END
ROM_START( bmiidx8 ) ROM_START( bmiidx8 )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "c44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(04c22349) SHA1(d1cb78911cb1ca660d393a81ed3ed07b24c51525) ) ROM_LOAD( "c44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(04c22349) SHA1(d1cb78911cb1ca660d393a81ed3ed07b24c51525) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1090,7 +1095,7 @@ ROM_END
ROM_START( bmiidxc ) ROM_START( bmiidxc )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) ) ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1102,7 +1107,7 @@ ROM_END
ROM_START( bmiidxc2 ) ROM_START( bmiidxc2 )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "984j.pd", 0x000000, 0x000100, BAD_DUMP CRC(213843e5) SHA1(5571db155a60fa4087dd996af48e8e27fc1c518c) ) ROM_LOAD( "984j.pd", 0x000000, 0x000100, BAD_DUMP CRC(213843e5) SHA1(5571db155a60fa4087dd996af48e8e27fc1c518c) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1114,7 +1119,7 @@ ROM_END
ROM_START( bmiidxca ) ROM_START( bmiidxca )
TWINKLE_BIOS TWINKLE_BIOS
ROM_REGION( 0x100, "user2", 0 ) ROM_REGION( 0x100, "security", 0 )
ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) ) ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) )
DISK_REGION( "cdrom0" ) DISK_REGION( "cdrom0" )
@ -1123,7 +1128,7 @@ ROM_START( bmiidxca )
// DISK_IMAGE_READONLY( "abmjaa02", 2, NO_DUMP ) // DISK_IMAGE_READONLY( "abmjaa02", 2, NO_DUMP )
ROM_END 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 */ /* VCD */
GAME( 1999, bmiidx, gq863, twinkle, twinkle, twinkle, ROT0, "Konami", "beatmania IIDX (863 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING ) GAME( 1999, bmiidx, gq863, twinkle, twinkle, twinkle, ROT0, "Konami", "beatmania IIDX (863 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )

View File

@ -27,9 +27,6 @@ TODO: Add CDDA support
#define CD_SECTOR_TIME (1000/((150*1024)/2048)) /* 1X CDROM sector time in msec (300KBps) */ #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 static struct akiko_def
{ {
/* chunky to planar converter */ /* chunky to planar converter */
@ -63,6 +60,7 @@ static struct akiko_def
UINT8 * cdrom_toc; UINT8 * cdrom_toc;
emu_timer *dma_timer; emu_timer *dma_timer;
emu_timer *frame_timer; emu_timer *frame_timer;
running_device *i2cmem;
} akiko; } akiko;
static TIMER_CALLBACK(akiko_dma_proc); 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) 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_input_index = 0;
akiko.c2p_output_index = 0; akiko.c2p_output_index = 0;
@ -106,6 +102,7 @@ void amiga_akiko_init(running_machine* machine)
akiko.cdrom_toc = NULL; akiko.cdrom_toc = NULL;
akiko.dma_timer = timer_alloc(machine, akiko_dma_proc, NULL); akiko.dma_timer = timer_alloc(machine, akiko_dma_proc, NULL);
akiko.frame_timer = timer_alloc(machine, akiko_frame_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); 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_scl_dir = BIT(data,15);
akiko.i2c_sda_dir = BIT(data,14); akiko.i2c_sda_dir = BIT(data,14);
i2cmem_write( machine, 0, I2CMEM_SCL, akiko.i2c_scl_out ); i2cmem_scl_write( akiko.i2cmem, akiko.i2c_scl_out );
i2cmem_write( machine, 0, I2CMEM_SDA, akiko.i2c_sda_out ); i2cmem_sda_write( akiko.i2cmem, akiko.i2c_sda_out );
} }
static UINT32 akiko_nvram_read(running_machine *machine) static UINT32 akiko_nvram_read(running_machine *machine)
@ -189,7 +186,7 @@ static UINT32 akiko_nvram_read(running_machine *machine)
} }
else else
{ {
v |= i2cmem_read( machine, 0, I2CMEM_SDA ) << 30; v |= i2cmem_sda_read( akiko.i2cmem ) << 30;
} }
v |= akiko.i2c_scl_dir << 15; v |= akiko.i2c_scl_dir << 15;
@ -198,11 +195,6 @@ static UINT32 akiko_nvram_read(running_machine *machine)
return v; return v;
} }
NVRAM_HANDLER( cd32 )
{
NVRAM_HANDLER_CALL(i2cmem_0);
}
/************************************* /*************************************
* *
* Akiko Chunky to Planar converter * Akiko Chunky to Planar converter