diff options
Diffstat (limited to 'src/devices/machine/i2cmem.cpp')
-rw-r--r-- | src/devices/machine/i2cmem.cpp | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/src/devices/machine/i2cmem.cpp b/src/devices/machine/i2cmem.cpp index 140e60dc145..94c08716f97 100644 --- a/src/devices/machine/i2cmem.cpp +++ b/src/devices/machine/i2cmem.cpp @@ -4,8 +4,7 @@ I2C Memory -Generic ram/rom/eeprom/flash on an i2c bus. Supports specifying the slave address, -the data size & the page size for writing. +ram/rom/eeprom/flash on an i2c bus. inputs: e0,e1,e2 lower 3 bits of the slave address @@ -16,9 +15,11 @@ inputs: 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. +The memory address is only 8 bits for devices up to 2048 bytes, +devices from 512 to 2048 bytes occupy multiple slave addresses. +The top five address bits are set at manufacture time, +there are two standard values. ***************************************************************************/ #include "emu.h" @@ -59,15 +60,16 @@ static inline void ATTR_PRINTF( 3, 4 ) verboselog( device_t *device, int n_level //************************************************************************** // device type definition -DEFINE_DEVICE_TYPE(I2CMEM, i2cmem_device, "i2cmem", "I2C Memory") -DEFINE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device, "x2404p", "X2404P I2C Memory") DEFINE_DEVICE_TYPE(I2C_24C01, i2c_24c01_device, "24c01", "24C01 I2C Memory") +DEFINE_DEVICE_TYPE(I2C_PCD8572, i2c_pcd8572_device, "pcd8572", "PCD8572 I2C Memory") DEFINE_DEVICE_TYPE(I2C_24C02, i2c_24c02_device, "24c02", "24C02 I2C Memory") +DEFINE_DEVICE_TYPE(I2C_M24C02, i2c_m24c02_device, "m24c02", "M24C02 I2C Memory") DEFINE_DEVICE_TYPE(I2C_24C04, i2c_24c04_device, "24c04", "24C04 I2C Memory") +DEFINE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device, "x2404p", "X2404P I2C Memory") DEFINE_DEVICE_TYPE(I2C_24C08, i2c_24c08_device, "24c08", "24C08 I2C Memory") DEFINE_DEVICE_TYPE(I2C_24C16, i2c_24c16_device, "24c16", "24C16 I2C Memory") -DEFINE_DEVICE_TYPE(I2C_24C16A, i2c_24c16a_device, "24c16a", "24C16A I2C Memory") DEFINE_DEVICE_TYPE(I2C_24C64, i2c_24c64_device, "24c64", "24C64 I2C Memory") +DEFINE_DEVICE_TYPE(I2C_24C512, i2c_24c512_device, "24c512", "24C512 I2C Memory") //************************************************************************** // LIVE DEVICE @@ -83,13 +85,15 @@ i2cmem_device::i2cmem_device( const char *tag, device_t *owner, uint32_t clock, - int page_size, + int read_page_size, + int write_page_size, int data_size) : device_t(mconfig, type, tag, owner, clock), device_nvram_interface(mconfig, *this), m_region(*this, DEVICE_SELF), m_slave_address(I2CMEM_SLAVE_ADDRESS), - m_page_size(page_size), + m_read_page_size(read_page_size), + m_write_page_size(write_page_size), m_data_size(data_size), m_scl(0), m_sdaw(0), @@ -110,48 +114,53 @@ i2cmem_device::i2cmem_device( assert(!clock); } -i2cmem_device::i2cmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2CMEM, tag, owner, clock, 0, 0) +i2c_24c01_device::i2c_24c01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_24C01, tag, owner, clock, 0, 8, 0x80) { } -i2c_x2404p_device::i2c_x2404p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_X2404P, tag, owner, clock, 8, 0x200) +i2c_pcd8572_device::i2c_pcd8572_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_PCD8572, tag, owner, clock, 0, 0, 0x80) { } -i2c_24c01_device::i2c_24c01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C01, tag, owner, clock, 4, 0x80) +i2c_24c02_device::i2c_24c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_24C02, tag, owner, clock, 0, 8, 0x100) { } -i2c_24c02_device::i2c_24c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C02, tag, owner, clock, 4, 0x100) +i2c_m24c02_device::i2c_m24c02_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_M24C02, tag, owner, clock, 0, 16, 0x100) { } i2c_24c04_device::i2c_24c04_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C04, tag, owner, clock, 8, 0x200) + i2cmem_device(mconfig, I2C_24C04, tag, owner, clock, 0, 16, 0x200) +{ +} + +i2c_x2404p_device::i2c_x2404p_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_X2404P, tag, owner, clock, 0x100, 8, 0x200) { } i2c_24c08_device::i2c_24c08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C08, tag, owner, clock, 0, 0x400) + i2cmem_device(mconfig, I2C_24C08, tag, owner, clock, 0, 16, 0x400) { } i2c_24c16_device::i2c_24c16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C16, tag, owner, clock, 8, 0x800) + i2cmem_device(mconfig, I2C_24C16, tag, owner, clock, 0, 16, 0x800) { } -i2c_24c16a_device::i2c_24c16a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C16A, tag, owner, clock, 0, 0x800) +i2c_24c64_device::i2c_24c64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_24C64, tag, owner, clock, 0, 32, 0x2000) { } -i2c_24c64_device::i2c_24c64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - i2cmem_device(mconfig, I2C_24C64, tag, owner, clock, 8, 0x2000) +i2c_24c512_device::i2c_24c512_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) : + i2cmem_device(mconfig, I2C_24C512, tag, owner, clock, 0, 128, 0x10000) { } @@ -162,7 +171,7 @@ i2c_24c64_device::i2c_24c64_device(const machine_config &mconfig, const char *ta void i2cmem_device::device_start() { m_data = std::make_unique<uint8_t []>(m_data_size); - m_page.resize( m_page_size ); + m_page.resize( m_write_page_size ); save_item( NAME(m_scl) ); save_item( NAME(m_sdaw) ); @@ -181,7 +190,7 @@ void i2cmem_device::device_start() save_item( NAME(m_page_offset) ); save_item( NAME(m_page_written_size) ); save_pointer( &m_data[0], "m_data", m_data_size ); - if ( m_page_size > 0 ) + if ( m_write_page_size > 0 ) { save_item( NAME(m_page) ); } @@ -286,13 +295,15 @@ WRITE_LINE_MEMBER( i2cmem_device::write_sda ) { if( m_sdaw ) { - if( m_state == STATE_DATAIN && m_page_size > 0 ) + if( m_page_written_size > 0 ) { int base = data_offset(); - int root = base & ~( m_page_size - 1); - for( int i=0; i < m_page_written_size; i++) - m_data[root | ((base + i) & (m_page_size - 1))] = m_page[i]; - verboselog( this, 1, "data[ %04x to %04x ] = %x bytes\n", base, root | ((base + m_page_written_size - 1) & (m_page_size - 1)), m_page_written_size ); + int root = base & ~( m_write_page_size - 1 ); + for( int i = 0; i < m_page_written_size; i++ ) + m_data[root | ((base + i) & (m_write_page_size - 1))] = m_page[i]; + verboselog( this, 1, "data[ %04x to %04x ] = %x bytes\n", base, root | ((base + m_page_written_size - 1) & (m_write_page_size - 1)), m_page_written_size ); + + m_page_written_size = 0; } verboselog( this, 1, "stop\n" ); m_state = STATE_IDLE; @@ -373,7 +384,7 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) break; case STATE_ADDRESSLOW: - m_byteaddr = m_shift | (skip_addresshigh() ? (m_devsel & DEVSEL_ADDRESS) << 7 : m_addresshigh << 8); + m_byteaddr = m_shift | (skip_addresshigh() ? ((m_devsel & DEVSEL_ADDRESS) << 7) & address_mask() : m_addresshigh << 8); m_page_offset = 0; m_page_written_size = 0; @@ -388,17 +399,17 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) verboselog( this, 0, "write not enabled\n" ); m_state = STATE_IDLE; } - else if( m_page_size > 0 ) + else if( m_write_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 ) + if( m_page_offset == m_write_page_size ) m_page_offset = 0; m_page_written_size++; - if( m_page_written_size > m_page_size) - m_page_written_size = m_page_size; + if( m_page_written_size > m_write_page_size) + m_page_written_size = m_write_page_size; } else { @@ -440,7 +451,7 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) m_shift = m_data[offset]; verboselog( this, 1, "data[ %04x ] -> %02x\n", offset, m_shift ); - m_byteaddr++; + m_byteaddr = (m_byteaddr & ~(m_read_page_size - 1)) | ((m_byteaddr + 1) & (m_read_page_size - 1)); } m_sdar = ( m_shift >> 7 ) & 1; |