summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/dimm_spd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/dimm_spd.cpp')
-rw-r--r--src/devices/machine/dimm_spd.cpp230
1 files changed, 6 insertions, 224 deletions
diff --git a/src/devices/machine/dimm_spd.cpp b/src/devices/machine/dimm_spd.cpp
index b6736e71ade..3bbebd9778a 100644
--- a/src/devices/machine/dimm_spd.cpp
+++ b/src/devices/machine/dimm_spd.cpp
@@ -6,8 +6,6 @@
Each DIMM contains a small EEPROM with information about the capacity and
timings of the module. The EEPROM speaks a version of I2C called SMBus.
-
- This does not attempt to be a generalized I2C/SMBus solution.
*/
@@ -19,35 +17,12 @@
#define VERBOSE (0)
#include "logmacro.h"
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
-
DEFINE_DEVICE_TYPE(DIMM_SPD, dimm_spd_device, "dimm_spd", "DIMM Serial Presence Detect")
-constexpr int STATE_IDLE = 0;
-constexpr int STATE_GET_ADDRESS = 1;
-constexpr int STATE_GET_SUBADDRESS = 2;
-constexpr int STATE_READ_DATA = 3;
-constexpr int STATE_WAIT_ACK = 4;
-
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
-//-------------------------------------------------
-// dimm_spd_device - constructor
-//-------------------------------------------------
-
dimm_spd_device::dimm_spd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, DIMM_SPD, tag, owner, clock),
- write_sda(*this)
+ i2c_hle_interface(mconfig, *this, 0) // address will be overridden by set_address as before
{
- m_data_offset = 0;
- m_sda = m_scl = 1;
- m_state = m_state_next = STATE_IDLE;
- m_last_address = 0;
- m_just_acked = false;
}
//-------------------------------------------------
@@ -68,21 +43,6 @@ void dimm_spd_device::device_start()
m_data[7] = 0; // data bus width high byte
m_data[11] = 0; // non-ECC (1=parity, 2=ECC)
m_data[62] = 0x12; // SPD version 1.2
-
- m_latch = m_bit = 0;
- m_state = STATE_IDLE;
- m_sda = m_scl = 1;
- m_last_address = 0;
- m_data_offset = 0;
-
- save_item(NAME(m_latch));
- save_item(NAME(m_bit));
- save_item(NAME(m_state));
- save_item(NAME(m_state_next));
- save_item(NAME(m_data_offset));
- save_item(NAME(m_just_acked));
-
- write_sda(1);
}
void dimm_spd_device::set_dimm_size(dimm_size_t size)
@@ -138,191 +98,13 @@ void dimm_spd_device::set_dimm_size(dimm_size_t size)
}
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void dimm_spd_device::device_reset()
-{
-}
-
-void dimm_spd_device::sda_write(int state)
+u8 dimm_spd_device::read_data(u16 offset)
{
- if (m_size == SIZE_SLOT_EMPTY)
+ // i2c_hle_interface auto-increments the address but doesn't wrap it around
+ if (offset >= m_size)
{
- return;
+ m_data_offset = 0;
}
- if (m_sda != state)
- {
- m_sda = state & 1;
-
- if (m_scl)
- {
- if (m_sda)
- {
- LOG("%s: stop\n", tag());
- m_state = STATE_IDLE;
- m_last_address = 0;
- m_just_acked = false;
- m_data_offset = 0;
- }
- else
- {
- LOG("%s: start\n", tag());
- m_state = STATE_GET_ADDRESS;
- m_bit = 0;
- m_latch = 0;
- m_just_acked = false;
- }
- }
- }
-}
-
-void dimm_spd_device::scl_write(int state)
-{
- if (m_size == SIZE_SLOT_EMPTY)
- {
- return;
- }
-
- if (m_scl != state)
- {
- m_scl = state & 1;
-
- switch (m_state)
- {
- case STATE_IDLE:
- // just ignore everything until a START
- break;
-
- case STATE_GET_ADDRESS:
- case STATE_GET_SUBADDRESS:
- if (m_bit < 8)
- {
- if (m_scl)
- {
- m_latch <<= 1;
- m_latch |= m_sda;
- m_bit++;
- }
- }
- else
- {
- if (m_scl)
- {
- m_bit++;
- }
- else
- {
- if (m_bit == 8)
- {
- if (m_state == STATE_GET_ADDRESS)
- {
- LOG("%s: Got address %02x (ours is %02x r/w %d)\n", tag(), m_latch >> 1, m_address, m_latch & 1);
- // check if reading
- if (m_latch & 1)
- {
- if ((m_latch >> 1) == m_address)
- {
- LOG("%s: address matches, ACKing\n", tag());
- write_sda(0);
- m_bit = 0;
- m_latch = 0;
- m_state_next = STATE_READ_DATA;
- m_state = STATE_WAIT_ACK;
- }
- else
- {
- LOG("%s: address doesn't match, ignoring\n", tag());
- m_state = STATE_IDLE;
- write_sda(1);
- }
- }
- else
- {
- LOGMASKED(LOG_DATAOUT, "%s: write: getting subaddress\n", tag());
- m_last_address = m_latch >> 1;
- write_sda(0);
- m_bit = 0;
- m_latch = 0;
- m_state_next = STATE_GET_SUBADDRESS;
- m_state = STATE_WAIT_ACK;
- }
- }
- else if (m_state == STATE_GET_SUBADDRESS)
- {
- LOGMASKED(LOG_DATAOUT, "%s: subaddress is %02x\n", tag(), m_latch);
- m_data_offset = m_latch;
- write_sda(0);
- m_bit = 0;
- m_latch = 0;
- m_state_next = STATE_IDLE; // is this correct?
- m_state = STATE_WAIT_ACK;
- }
- }
- }
- }
- break;
-
- case STATE_WAIT_ACK:
- if (!m_scl)
- {
- m_state = m_state_next;
- write_sda(1);
- }
- break;
-
- case STATE_READ_DATA:
- if (m_bit < 8)
- {
- if (!m_scl)
- {
- m_bit++;
- write_sda(1);
- }
- else
- {
- if (m_bit == 0)
- {
- m_latch = m_data[m_data_offset++];
- m_data_offset &= 0xff;
- LOGMASKED(LOG_DATAOUT, "%s: outputting byte %02x\n", tag(), m_latch);
- }
-
- write_sda(BIT(m_latch, 7));
- m_latch <<= 1;
- }
- }
- else
- {
- if (m_scl)
- {
- // did the master ACK or NACK?
- if (m_sda)
- {
- LOGMASKED(LOG_DATAOUT, "%s: master NACK\n", tag());
- m_state = STATE_IDLE;
- write_sda(1);
- }
- else
- {
- LOGMASKED(LOG_DATAOUT, "%s: master ACK\n", tag());
- m_just_acked = true;
- }
- }
- else
- {
- write_sda(1);
- if (m_just_acked)
- {
- m_bit = 0;
- m_just_acked = false;
- }
- }
- }
- break;
- }
-
- }
+ return m_data[offset];
}