From 4cb71c31d2b49c6cb20ebe23d3d119503a3cae7a Mon Sep 17 00:00:00 2001 From: Paul-Arnold <98924583+Paul-Arnold@users.noreply.github.com> Date: Wed, 27 Apr 2022 15:27:06 +0100 Subject: i2cmem.cpp and derived devices: Only acknowledge correct I2C device-id. (#9630) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated machine/acorn_bmu.cpp, machine/i2cmem.cpp, machine/pcf8573.cpp and machine/machine/pcf8583.cpp. * Check device ID and only acknowledge device’s own ID. * Release SDA line to be pulled up when idle. * aa310.cpp: Combine SDA lines with logical AND. --- src/devices/machine/acorn_bmu.cpp | 108 ++++++++++---------- src/devices/machine/acorn_bmu.h | 2 +- src/devices/machine/i2cmem.cpp | 205 ++++++++++++++++++++------------------ src/devices/machine/pcf8573.cpp | 168 ++++++++++++++++--------------- src/devices/machine/pcf8573.h | 2 +- src/devices/machine/pcf8583.cpp | 156 +++++++++++++++-------------- src/devices/machine/pcf8583.h | 2 +- src/mame/drivers/aa310.cpp | 42 +++++--- 8 files changed, 357 insertions(+), 328 deletions(-) diff --git a/src/devices/machine/acorn_bmu.cpp b/src/devices/machine/acorn_bmu.cpp index 3ff529525ff..96e0759f200 100644 --- a/src/devices/machine/acorn_bmu.cpp +++ b/src/devices/machine/acorn_bmu.cpp @@ -96,57 +96,60 @@ WRITE_LINE_MEMBER(acorn_bmu_device::scl_w) { if (m_scl) { - switch (m_state) + m_bits++; + } + else + { + if (m_bits == 8) { - case STATE_DEVSEL: - m_devsel = m_shift; - - if ((m_devsel & 0xfe) != m_slave_address) + switch (m_state) { - LOGMASKED(LOG_DATA, "devsel %02x: not this device\n", m_devsel); - m_state = STATE_IDLE; - } - else if ((m_devsel & 1) == 0) - { - LOGMASKED(LOG_DATA, "devsel %02x: write\n", m_devsel); - m_state = STATE_REGISTER; - } - else - { - LOGMASKED(LOG_DATA, "devsel %02x: read\n", m_devsel); - m_state = STATE_DATAOUT; - } - break; + case STATE_DEVSEL: + m_devsel = m_shift; + + if ((m_devsel & 0xfe) != m_slave_address) + { + LOGMASKED(LOG_DATA, "devsel %02x: not this device\n", m_devsel); + m_state = STATE_IDLE; + } + else if ((m_devsel & 1) == 0) + { + LOGMASKED(LOG_DATA, "devsel %02x: write\n", m_devsel); + m_state = STATE_REGISTER; + } + else + { + LOGMASKED(LOG_DATA, "devsel %02x: read\n", m_devsel); + m_state = STATE_READSELACK; + } + break; - case STATE_REGISTER: - m_register = m_shift; + case STATE_REGISTER: + m_register = m_shift; - LOGMASKED(LOG_DATA, "register %02x\n", m_register); + LOGMASKED(LOG_DATA, "register %02x\n", m_register); - m_state = STATE_DATAIN; - break; + m_state = STATE_DATAIN; + break; - case STATE_DATAIN: - LOGMASKED(LOG_DATA, "register[ %02x ] <- %02x\n", m_register, m_shift); + case STATE_DATAIN: + LOGMASKED(LOG_DATA, "register[ %02x ] <- %02x\n", m_register, m_shift); - switch (m_register) - { - case BMU_CHARGE_ESTIMATE: - m_estimate = m_shift; + switch (m_register) + { + case BMU_CHARGE_ESTIMATE: + m_estimate = m_shift; + break; + } + + m_register++; break; } - - m_register++; - break; - } - - m_bits++; - } - else - { - if (m_bits == 8) - { - m_sdar = 0; + + if( m_state != STATE_IDLE ) + { + m_sdar = 0 ; + } } else { @@ -157,10 +160,19 @@ WRITE_LINE_MEMBER(acorn_bmu_device::scl_w) } break; + case STATE_READSELACK: + m_bits = 0; + m_state = STATE_DATAOUT; + break; + case STATE_DATAOUT: if (m_bits < 8) { if (m_scl) + { + m_bits++; + } + else { if (m_bits == 0) { @@ -194,7 +206,6 @@ WRITE_LINE_MEMBER(acorn_bmu_device::scl_w) m_sdar = (m_shift >> 7) & 1; m_shift = (m_shift << 1) & 0xff; - m_bits++; } } else @@ -207,18 +218,11 @@ WRITE_LINE_MEMBER(acorn_bmu_device::scl_w) m_state = STATE_IDLE; } - m_bits++; + m_bits = 0; } else { - if (m_bits == 8) - { - m_sdar = 1; - } - else - { - m_bits = 0; - } + m_sdar = 1; } } break; diff --git a/src/devices/machine/acorn_bmu.h b/src/devices/machine/acorn_bmu.h index 56c6c32a3df..52ff13db040 100644 --- a/src/devices/machine/acorn_bmu.h +++ b/src/devices/machine/acorn_bmu.h @@ -45,7 +45,7 @@ private: int m_devsel; int m_register; - enum { STATE_IDLE, STATE_DEVSEL, STATE_REGISTER, STATE_DATAIN, STATE_DATAOUT }; + enum { STATE_IDLE, STATE_DEVSEL, STATE_REGISTER, STATE_DATAIN, STATE_DATAOUT, STATE_READSELACK }; // registers enum diff --git a/src/devices/machine/i2cmem.cpp b/src/devices/machine/i2cmem.cpp index e21d8c6b6ee..8b6358eceac 100644 --- a/src/devices/machine/i2cmem.cpp +++ b/src/devices/machine/i2cmem.cpp @@ -30,8 +30,9 @@ constexpr int STATE_DEVSEL(1); constexpr int STATE_ADDRESSHIGH(2); constexpr int STATE_ADDRESSLOW(3); constexpr int STATE_DATAIN(4); -constexpr int STATE_DATAOUT(5); -constexpr int STATE_RESET(6); +constexpr int STATE_READSELACK(5); +constexpr int STATE_DATAOUT(6); +constexpr int STATE_RESET(7); constexpr int DEVSEL_RW(1); constexpr int DEVSEL_ADDRESS(0xfe); @@ -368,110 +369,112 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) { if( m_scl ) { - switch( m_state ) + m_bits++; + } + else + { + if( m_bits == 8 ) { - case STATE_DEVSEL: - m_devsel = m_shift; - - if( m_devsel == 0 && !m_devsel_address_low ) - { - // TODO: Atmel datasheets document 2-wire software reset, but doesn't mention it will lower sda only that it will release it. - // ltv_naru however requires it to be lowered, but we don't currently know the manufacturer of the chip used. - verboselog( this, 1, "software reset\n" ); - m_state = STATE_RESET; - m_sdar = 0; - } - else if( !select_device() ) + switch( m_state ) { - verboselog( this, 1, "devsel %02x: not this device\n", m_devsel ); - m_state = STATE_IDLE; - } - else if( ( m_devsel & DEVSEL_RW ) == 0 ) - { - if (m_devsel_address_low) + case STATE_DEVSEL: + m_devsel = m_shift; + + if( m_devsel == 0 && !m_devsel_address_low ) { - verboselog( this, 1, "devsel %02x: write (Xicor special, address %02x)\n", m_devsel, m_devsel >> 1); - m_byteaddr = (m_devsel & DEVSEL_ADDRESS) >> 1; - m_page_offset = 0; - m_page_written_size = 0; - m_state = STATE_DATAIN; + // TODO: Atmel datasheets document 2-wire software reset, but doesn't mention it will lower sda only that it will release it. + // ltv_naru however requires it to be lowered, but we don't currently know the manufacturer of the chip used. + verboselog( this, 1, "software reset\n" ); + m_state = STATE_RESET; } - else + else if( !select_device() ) { - verboselog( this, 1, "devsel %02x: write\n", m_devsel ); - m_state = skip_addresshigh() ? STATE_ADDRESSLOW : STATE_ADDRESSHIGH; + verboselog( this, 1, "devsel %02x: not this device\n", m_devsel ); + m_state = STATE_IDLE; } - } - else - { - if (m_devsel_address_low) + else if( ( m_devsel & DEVSEL_RW ) == 0 ) { - verboselog( this, 1, "devsel %02x: read (Xicor special, address %02x)\n", m_devsel, m_devsel >> 1); - m_byteaddr = (m_devsel & DEVSEL_ADDRESS) >> 1; + if (m_devsel_address_low) + { + verboselog( this, 1, "devsel %02x: write (Xicor special, address %02x)\n", m_devsel, m_devsel >> 1); + m_byteaddr = (m_devsel & DEVSEL_ADDRESS) >> 1; + m_page_offset = 0; + m_page_written_size = 0; + m_state = STATE_DATAIN; + } + else + { + verboselog( this, 1, "devsel %02x: write\n", m_devsel ); + m_state = skip_addresshigh() ? STATE_ADDRESSLOW : STATE_ADDRESSHIGH; + } } else { - verboselog( this, 1, "devsel %02x: read\n", m_devsel ); + if (m_devsel_address_low) + { + verboselog( this, 1, "devsel %02x: read (Xicor special, address %02x)\n", m_devsel, m_devsel >> 1); + m_byteaddr = (m_devsel & DEVSEL_ADDRESS) >> 1; + } + else + { + verboselog( this, 1, "devsel %02x: read\n", m_devsel ); + } + m_state = STATE_READSELACK; } - m_state = STATE_DATAOUT; - } - break; + break; - case STATE_ADDRESSHIGH: - m_addresshigh = m_shift; + case STATE_ADDRESSHIGH: + m_addresshigh = m_shift; - verboselog(this, 1, "addresshigh %02x\n", m_addresshigh); + verboselog(this, 1, "addresshigh %02x\n", m_addresshigh); - m_state = STATE_ADDRESSLOW; - break; + m_state = STATE_ADDRESSLOW; + break; - case STATE_ADDRESSLOW: - 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; + case STATE_ADDRESSLOW: + 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; - verboselog( this, 1, "addresslow %02x (byteaddr %04x)\n", m_shift, m_byteaddr ); + verboselog( this, 1, "addresslow %02x (byteaddr %04x)\n", m_shift, m_byteaddr ); - m_state = STATE_DATAIN; - break; + 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_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_write_page_size ) - m_page_offset = 0; - m_page_written_size++; - if( m_page_written_size > m_write_page_size) - m_page_written_size = m_write_page_size; - } - else - { - int offset = data_offset(); + case STATE_DATAIN: + if( m_wc ) + { + verboselog( this, 0, "write not enabled\n" ); + m_state = STATE_IDLE; + } + 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_write_page_size ) + m_page_offset = 0; + m_page_written_size++; + if( m_page_written_size > m_write_page_size) + m_page_written_size = m_write_page_size; + } + else + { + int offset = data_offset(); - verboselog( this, 1, "data[ %04x ] <- %02x\n", offset, m_shift ); - m_data[ offset ] = m_shift; + verboselog( this, 1, "data[ %04x ] <- %02x\n", offset, m_shift ); + m_data[ offset ] = m_shift; - m_byteaddr++; + m_byteaddr++; + } + break; + } + + if( m_state != STATE_IDLE ) + { + m_sdar = 0 ; } - break; - } - - m_bits++; - } - else - { - if( m_bits == 8 ) - { - m_sdar = 0; } else { @@ -482,10 +485,19 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) } break; + case STATE_READSELACK: + m_bits = 0; + m_state = STATE_DATAOUT; + break; + case STATE_DATAOUT: if( m_bits < 8 ) { if( m_scl ) + { + m_bits++; + } + else { if( m_bits == 0 ) { @@ -499,7 +511,6 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) m_sdar = ( m_shift >> 7 ) & 1; m_shift = ( m_shift << 1 ) & 0xff; - m_bits++; } } else @@ -512,18 +523,11 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) m_state = STATE_IDLE; } - m_bits++; + m_bits = 0; } else { - if( m_bits == 8 ) - { - m_sdar = 1; - } - else - { - m_bits = 0; - } + m_sdar = 1; } } break; @@ -531,9 +535,13 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl ) case STATE_RESET: if( m_scl ) { - verboselog(this, 1, "software reset ack\n"); - m_state = STATE_IDLE; - m_sdar = 1; + if( m_bits > 8 ) + { + verboselog(this, 1, "software reset ack\n"); + m_state = STATE_IDLE; + m_sdar = 1; + } + m_bits++; } break; } @@ -555,7 +563,6 @@ WRITE_LINE_MEMBER( i2cmem_device::write_wc ) READ_LINE_MEMBER( i2cmem_device::read_sda ) { int res = m_sdar & 1; - verboselog( this, 2, "read sda %d\n", res ); return res; diff --git a/src/devices/machine/pcf8573.cpp b/src/devices/machine/pcf8573.cpp index e7b8d514373..133fa5a5d7b 100644 --- a/src/devices/machine/pcf8573.cpp +++ b/src/devices/machine/pcf8573.cpp @@ -167,91 +167,94 @@ WRITE_LINE_MEMBER(pcf8573_device::scl_w) { if (m_scl) { - switch (m_state) + m_bits++; + } + else + { + if (m_bits == 8) { - case STATE_ADDRESS: - m_devsel = m_shift; - - if ((m_devsel & 0xfe) != m_slave_address) - { - LOGMASKED(LOG_DATA, "address %02x: not this device\n", m_devsel); - m_state = STATE_IDLE; - } - else if ((m_devsel & 1) == 0) + switch (m_state) { - LOGMASKED(LOG_DATA, "address %02x: write\n", m_devsel); - m_state = STATE_MODE; - } - else - { - LOGMASKED(LOG_DATA, "address %02x: read\n", m_devsel); - m_state = STATE_DATAOUT; - } - break; + case STATE_ADDRESS: + m_devsel = m_shift; - case STATE_MODE: - m_mode_pointer = m_shift; + if ((m_devsel & 0xfe) != m_slave_address) + { + LOGMASKED(LOG_DATA, "address %02x: not this device\n", m_devsel); + m_state = STATE_IDLE; + } + else if ((m_devsel & 1) == 0) + { + LOGMASKED(LOG_DATA, "address %02x: write\n", m_devsel); + m_state = STATE_MODE; + } + else + { + LOGMASKED(LOG_DATA, "address %02x: read\n", m_devsel); + m_state = STATE_READSELACK; + } + break; - LOGMASKED(LOG_DATA, "mode pointer %02x\n", m_shift); + case STATE_MODE: + m_mode_pointer = m_shift; - switch (m_mode_pointer & 0x70) - { - case 0x00: // execute address - m_address = m_mode_pointer & 0x07; - break; - case 0x10: // read control/status flags - break; - case 0x20: // reset prescaler - set_clock_register(RTC_SECOND, 0); - adjust_seconds(); - break; - case 0x30: // time adjust - adjust_seconds(); - break; - case 0x40: // reset NODA flag - m_status &= ~(1 << 2); - break; - case 0x50: // set NODA flag - m_status |= 1 << 2; - break; - case 0x60: // reset COMP flag - m_status &= ~(1 << 1); - m_comp_cb(0); + LOGMASKED(LOG_DATA, "mode pointer %02x\n", m_shift); + + switch (m_mode_pointer & 0x70) + { + case 0x00: // execute address + m_address = m_mode_pointer & 0x07; + break; + case 0x10: // read control/status flags + break; + case 0x20: // reset prescaler + set_clock_register(RTC_SECOND, 0); + adjust_seconds(); + break; + case 0x30: // time adjust + adjust_seconds(); + break; + case 0x40: // reset NODA flag + m_status &= ~(1 << 2); + break; + case 0x50: // set NODA flag + m_status |= 1 << 2; + break; + case 0x60: // reset COMP flag + m_status &= ~(1 << 1); + m_comp_cb(0); + break; + } + + m_state = STATE_DATAIN; break; - } - m_state = STATE_DATAIN; - break; + case STATE_DATAIN: + switch (m_mode_pointer & 0x70) + { + case 0x00: // execute address + m_data[m_address] = m_shift; - case STATE_DATAIN: - switch (m_mode_pointer & 0x70) - { - case 0x00: // execute address - m_data[m_address] = m_shift; + LOGMASKED(LOG_DATA, "data[ %02x ] <- %02x\n", m_address, m_shift); - LOGMASKED(LOG_DATA, "data[ %02x ] <- %02x\n", m_address, m_shift); + switch (m_address) + { + case REG_HOURS: set_clock_register(RTC_HOUR, bcd_to_integer(m_data[REG_HOURS])); break; + case REG_MINUTES: set_clock_register(RTC_MINUTE, bcd_to_integer(m_data[REG_MINUTES])); break; + case REG_DAYS: set_clock_register(RTC_DAY, bcd_to_integer(m_data[REG_DAYS])); break; + case REG_MONTHS: set_clock_register(RTC_MONTH, bcd_to_integer(m_data[REG_MONTHS])); break; + } - switch (m_address) - { - case REG_HOURS: set_clock_register(RTC_HOUR, bcd_to_integer(m_data[REG_HOURS])); break; - case REG_MINUTES: set_clock_register(RTC_MINUTE, bcd_to_integer(m_data[REG_MINUTES])); break; - case REG_DAYS: set_clock_register(RTC_DAY, bcd_to_integer(m_data[REG_DAYS])); break; - case REG_MONTHS: set_clock_register(RTC_MONTH, bcd_to_integer(m_data[REG_MONTHS])); break; + m_address = (m_address & 0x04) | ((m_address + 1) & 0x03); + break; } - - m_address = (m_address & 0x04) | ((m_address + 1) & 0x03); break; } - break; - } - - m_bits++; - } - else - { - if (m_bits == 8) - { - m_sdar = 0; + + if( m_state != STATE_IDLE ) + { + m_sdar = 0 ; + } } else { @@ -262,10 +265,19 @@ WRITE_LINE_MEMBER(pcf8573_device::scl_w) } break; + case STATE_READSELACK: + m_bits = 0; + m_state = STATE_DATAOUT; + break; + case STATE_DATAOUT: if (m_bits < 8) { if (m_scl) + { + m_bits++; + } + else { if (m_bits == 0) { @@ -287,7 +299,6 @@ WRITE_LINE_MEMBER(pcf8573_device::scl_w) m_sdar = (m_shift >> 7) & 1; m_shift = (m_shift << 1) & 0xff; - m_bits++; } } else @@ -300,18 +311,11 @@ WRITE_LINE_MEMBER(pcf8573_device::scl_w) m_state = STATE_IDLE; } - m_bits++; + m_bits = 0; } else { - if (m_bits == 8) - { - m_sdar = 1; - } - else - { - m_bits = 0; - } + m_sdar = 1; } } break; diff --git a/src/devices/machine/pcf8573.h b/src/devices/machine/pcf8573.h index 63d0da0502e..d5b3bc5283e 100644 --- a/src/devices/machine/pcf8573.h +++ b/src/devices/machine/pcf8573.h @@ -117,7 +117,7 @@ private: int m_address; int m_status; - enum { STATE_IDLE, STATE_ADDRESS, STATE_MODE, STATE_DATAIN, STATE_DATAOUT }; + enum { STATE_IDLE, STATE_ADDRESS, STATE_MODE, STATE_DATAIN, STATE_DATAOUT, STATE_READSELACK }; }; // device type definition diff --git a/src/devices/machine/pcf8583.cpp b/src/devices/machine/pcf8583.cpp index ebad0d9e90e..4e5a81085d3 100644 --- a/src/devices/machine/pcf8583.cpp +++ b/src/devices/machine/pcf8583.cpp @@ -242,80 +242,83 @@ WRITE_LINE_MEMBER(pcf8583_device::scl_w) { if (m_scl) { - switch (m_state) + m_bits++; + } + else + { + if( m_bits == 8 ) { - case STATE_DEVSEL: - m_devsel = m_shift; - - if ((m_devsel & 0xfe) != m_slave_address) - { - LOGMASKED(LOG_DATA, "devsel %02x: not this device\n", m_devsel); - m_state = STATE_IDLE; - } - else if ((m_devsel & 1) == 0) - { - LOGMASKED(LOG_DATA, "devsel %02x: write\n", m_devsel); - m_state = STATE_REGISTER; - } - else + switch (m_state) { - LOGMASKED(LOG_DATA, "devsel %02x: read\n", m_devsel); - m_state = STATE_DATAOUT; - } - break; - - case STATE_REGISTER: - m_register = m_shift; - - LOGMASKED(LOG_DATA, "register %02x\n", m_register); - - m_state = STATE_DATAIN; - break; + case STATE_DEVSEL: + m_devsel = m_shift; + + if ((m_devsel & 0xfe) != m_slave_address) + { + LOGMASKED(LOG_DATA, "devsel %02x: not this device\n", m_devsel); + m_state = STATE_IDLE; + } + else if ((m_devsel & 1) == 0) + { + LOGMASKED(LOG_DATA, "devsel %02x: write\n", m_devsel); + m_state = STATE_REGISTER; + } + else + { + LOGMASKED(LOG_DATA, "devsel %02x: read\n", m_devsel); + m_state = STATE_READSELACK; + } + break; - case STATE_DATAIN: - LOGMASKED(LOG_DATA, "data[ %02x ] <- %02x\n", m_register, m_shift); + case STATE_REGISTER: + m_register = m_shift; - m_data[m_register] = m_shift; + LOGMASKED(LOG_DATA, "register %02x\n", m_register); - switch (m_register) - { - case REG_CONTROL: - if ((m_shift & 0x24) == 0x04) - logerror("Timer not implemented"); - break; - case REG_SECONDS: - set_clock_register(RTC_SECOND, bcd_to_integer(m_data[REG_SECONDS])); - break; - case REG_MINUTES: - set_clock_register(RTC_MINUTE, bcd_to_integer(m_data[REG_MINUTES])); + m_state = STATE_DATAIN; break; - case REG_HOURS: - set_clock_register(RTC_HOUR, bcd_to_integer(m_data[REG_HOURS])); - break; - case REG_YEAR_DATE: - set_clock_register(RTC_DAY, bcd_to_integer(m_data[REG_YEAR_DATE] & 0x3f)); - set_clock_register(RTC_YEAR, bcd_to_integer(m_data[REG_YEAR_DATE] >> 6)); - break; - case REG_MONTH_DAY: - set_clock_register(RTC_MONTH, bcd_to_integer(m_data[REG_MONTH_DAY] & 0x1f)); - set_clock_register(RTC_DAY_OF_WEEK, bcd_to_integer((m_data[REG_MONTH_DAY] >> 5) + 1)); - break; - case REG_ALARM_CONTROL: - m_irq_cb(m_data[REG_ALARM_CONTROL] & 0x88 ? 1 : 0); + + case STATE_DATAIN: + LOGMASKED(LOG_DATA, "data[ %02x ] <- %02x\n", m_register, m_shift); + + m_data[m_register] = m_shift; + + switch (m_register) + { + case REG_CONTROL: + if ((m_shift & 0x24) == 0x04) + logerror("Timer not implemented"); + break; + case REG_SECONDS: + set_clock_register(RTC_SECOND, bcd_to_integer(m_data[REG_SECONDS])); + break; + case REG_MINUTES: + set_clock_register(RTC_MINUTE, bcd_to_integer(m_data[REG_MINUTES])); + break; + case REG_HOURS: + set_clock_register(RTC_HOUR, bcd_to_integer(m_data[REG_HOURS])); + break; + case REG_YEAR_DATE: + set_clock_register(RTC_DAY, bcd_to_integer(m_data[REG_YEAR_DATE] & 0x3f)); + set_clock_register(RTC_YEAR, bcd_to_integer(m_data[REG_YEAR_DATE] >> 6)); + break; + case REG_MONTH_DAY: + set_clock_register(RTC_MONTH, bcd_to_integer(m_data[REG_MONTH_DAY] & 0x1f)); + set_clock_register(RTC_DAY_OF_WEEK, bcd_to_integer((m_data[REG_MONTH_DAY] >> 5) + 1)); + break; + case REG_ALARM_CONTROL: + m_irq_cb(m_data[REG_ALARM_CONTROL] & 0x88 ? 1 : 0); + break; + } + + m_register++; break; } - - m_register++; - break; - } - - m_bits++; - } - else - { - if (m_bits == 8) - { - m_sdar = 0; + + if (m_state != STATE_IDLE) + { + m_sdar = 0 ; + } } else { @@ -326,10 +329,19 @@ WRITE_LINE_MEMBER(pcf8583_device::scl_w) } break; + case STATE_READSELACK: + m_bits = 0; + m_state = STATE_DATAOUT; + break; + case STATE_DATAOUT: if (m_bits < 8) { if (m_scl) + { + m_bits++; + } + else { if (m_bits == 0) { @@ -354,7 +366,6 @@ WRITE_LINE_MEMBER(pcf8583_device::scl_w) m_sdar = (m_shift >> 7) & 1; m_shift = (m_shift << 1) & 0xff; - m_bits++; } } else @@ -367,18 +378,11 @@ WRITE_LINE_MEMBER(pcf8583_device::scl_w) m_state = STATE_IDLE; } - m_bits++; + m_bits = 0; } else { - if (m_bits == 8) - { - m_sdar = 1; - } - else - { - m_bits = 0; - } + m_sdar = 1; } } break; diff --git a/src/devices/machine/pcf8583.h b/src/devices/machine/pcf8583.h index 0a2b45696b7..900ea145c10 100644 --- a/src/devices/machine/pcf8583.h +++ b/src/devices/machine/pcf8583.h @@ -166,7 +166,7 @@ private: bool m_irq; emu_timer * m_timer; - enum { STATE_IDLE, STATE_DEVSEL, STATE_REGISTER, STATE_DATAIN, STATE_DATAOUT }; + enum { STATE_IDLE, STATE_DEVSEL, STATE_REGISTER, STATE_DATAIN, STATE_DATAOUT, STATE_READSELACK }; }; // device type definition diff --git a/src/mame/drivers/aa310.cpp b/src/mame/drivers/aa310.cpp index 93079648c96..3f4237471fe 100644 --- a/src/mame/drivers/aa310.cpp +++ b/src/mame/drivers/aa310.cpp @@ -219,6 +219,8 @@ public: , m_adlc(*this, "adlc") , m_centronics(*this, "centronics") , m_cent_data_out(*this, "cent_data_out") + , m_i2cmem(*this, "i2cmem") + , m_rtc(*this, "rtc") { } void aa500(machine_config &config); @@ -238,6 +240,8 @@ private: required_device m_adlc; required_device m_centronics; required_device m_cent_data_out; + required_device m_i2cmem; + required_device m_rtc; }; @@ -326,6 +330,7 @@ class aa4000_state : public aabase_state public: aa4000_state(const machine_config &mconfig, device_type type, const char *tag) : aabase_state(mconfig, type, tag) + , m_i2cmem(*this,"i2cmem") , m_floppy(*this, "upc:fdc:%u", 0U) //, m_test(*this, "test") , m_ioeb_control(0) @@ -334,6 +339,8 @@ public: void aa3010(machine_config &config); void aa3020(machine_config &config); void aa4000(machine_config &config); + + required_device m_i2cmem; protected: virtual void machine_reset() override; @@ -347,6 +354,7 @@ protected: //required_device m_test; u8 m_ioeb_control; + }; @@ -377,6 +385,7 @@ public: aa4_state(const machine_config &mconfig, device_type type, const char *tag) : aa5000_state(mconfig, type, tag) , m_lc(*this, "lc") + , m_bmu(*this, "bmu") { } void aa4(machine_config &config); @@ -386,6 +395,8 @@ protected: private: required_device m_lc; + required_device m_bmu; + }; @@ -1076,12 +1087,11 @@ void aa500_state::aa500(machine_config &config) m_ioc->peripheral_w<5>().set(FUNC(aa500_state::peripheral5_w)); m_ioc->peripheral_r<6>().set_constant(0xff); m_ioc->peripheral_w<6>().set(FUNC(aa500_state::peripheral6_w)); - m_ioc->gpio_r<0>().set("i2cmem", FUNC(i2c_pcf8570_device::read_sda)); - m_ioc->gpio_r<0>().append("rtc", FUNC(pcf8573_device::sda_r)); - m_ioc->gpio_w<0>().set("i2cmem", FUNC(i2c_pcf8570_device::write_sda)); - m_ioc->gpio_w<0>().append("rtc", FUNC(pcf8573_device::sda_w)); - m_ioc->gpio_w<1>().set("i2cmem", FUNC(i2c_pcf8570_device::write_scl)); - m_ioc->gpio_w<1>().append("rtc", FUNC(pcf8573_device::scl_w)); + m_ioc->gpio_r<0>().set([this]() { return m_i2cmem->read_sda() & m_rtc->sda_r(); }); + m_ioc->gpio_w<0>().set(m_i2cmem, FUNC(i2c_pcf8570_device::write_sda)); + m_ioc->gpio_w<0>().append(m_rtc, FUNC(pcf8573_device::sda_w)); + m_ioc->gpio_w<1>().set(m_i2cmem, FUNC(i2c_pcf8570_device::write_scl)); + m_ioc->gpio_w<1>().append(m_rtc, FUNC(pcf8573_device::scl_w)); //m_ioc->gpio_r<2>().set("rtc", FUNC(pcf8573_device::min_r)); //m_ioc->gpio_r<3>().set("rtc", FUNC(pcf8573_device::sec_r)); m_ioc->gpio_r<4>().set([this] { return m_selected_floppy ? m_selected_floppy->dskchg_r() : 1; }); @@ -1097,8 +1107,8 @@ void aa500_state::aa500(machine_config &config) m_ram->set_default_size("4M"); // PCF8570 and PCF8573 (pre PCF8583) - I2C_PCF8570(config, "i2cmem"); - PCF8573(config, "rtc", 32.768_kHz_XTAL); + I2C_PCF8570(config, m_i2cmem); + PCF8573(config, m_rtc, 32.768_kHz_XTAL); FD1793(config, m_fdc, 24_MHz_XTAL / 24); m_fdc->intrq_wr_callback().set(m_ioc, FUNC(acorn_ioc_device::fh1_w)); @@ -1468,9 +1478,9 @@ void aa4000_state::aa3010(machine_config &config) m_ioc->peripheral_w<3>().set_log("IOC: Peripheral Select 3 W"); m_ioc->peripheral_r<5>().set(FUNC(aa4000_state::ioeb_r)); m_ioc->peripheral_w<5>().set(FUNC(aa4000_state::ioeb_w)); - m_ioc->gpio_r<0>().set("i2cmem", FUNC(pcf8583_device::sda_r)); - m_ioc->gpio_w<0>().set("i2cmem", FUNC(pcf8583_device::sda_w)); - m_ioc->gpio_w<1>().set("i2cmem", FUNC(pcf8583_device::scl_w)); + m_ioc->gpio_r<0>().set(m_i2cmem, FUNC(pcf8583_device::sda_r)); + m_ioc->gpio_w<0>().set(m_i2cmem, FUNC(pcf8583_device::sda_w)); + m_ioc->gpio_w<1>().set(m_i2cmem, FUNC(pcf8583_device::scl_w)); m_ioc->gpio_r<2>().set_constant(1); // FDHden m_ioc->gpio_r<3>().set("idrom", FUNC(ds2401_device::read)); m_ioc->gpio_w<3>().set("idrom", FUNC(ds2401_device::write)); @@ -1479,7 +1489,7 @@ void aa4000_state::aa3010(machine_config &config) m_ram->set_default_size("1M").set_extra_options("2M"); - PCF8583(config, "i2cmem", 32.768_kHz_XTAL); + PCF8583(config, m_i2cmem, 32.768_kHz_XTAL); DS2401(config, "idrom", 0); // DS2400 @@ -1616,14 +1626,14 @@ void aa4_state::aa4(machine_config &config) m_maincpu->set_clock(24_MHz_XTAL); // ARM3 m_maincpu->set_copro_type(arm_cpu_device::copro_type::VL86C020); - ACORN_BMU(config, "bmu", 4.194304_MHz_XTAL); + ACORN_BMU(config, m_bmu, 4.194304_MHz_XTAL); //bmu.battlo_callback().set(m_ioc, FUNC(acorn_ioc_device::il7_w)); //m_ioc->peripheral_r<2>().set("lc", FUNC(lc_device::read)); //m_ioc->peripheral_w<2>().set("lc", FUNC(lc_device::write)); - m_ioc->gpio_r<0>().append("bmu", FUNC(acorn_bmu_device::sda_r)); - m_ioc->gpio_w<0>().append("bmu", FUNC(acorn_bmu_device::sda_w)); - m_ioc->gpio_w<1>().append("bmu", FUNC(acorn_bmu_device::scl_w)); + m_ioc->gpio_r<0>().set([this]() { return m_i2cmem->sda_r() & m_bmu->sda_r(); }); + m_ioc->gpio_w<0>().append(m_bmu, FUNC(acorn_bmu_device::sda_w)); + m_ioc->gpio_w<1>().append(m_bmu, FUNC(acorn_bmu_device::scl_w)); // video hardware screen_device &screen(SCREEN(config.replace(), "screen", SCREEN_TYPE_LCD)); -- cgit v1.2.3