summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/nmc9306.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/nmc9306.cpp')
-rw-r--r--src/devices/machine/nmc9306.cpp165
1 files changed, 133 insertions, 32 deletions
diff --git a/src/devices/machine/nmc9306.cpp b/src/devices/machine/nmc9306.cpp
index d20e77a398b..2001f58e78d 100644
--- a/src/devices/machine/nmc9306.cpp
+++ b/src/devices/machine/nmc9306.cpp
@@ -43,11 +43,14 @@ enum
enum
{
STATE_IDLE = 0,
+ STATE_START,
STATE_COMMAND,
STATE_ADDRESS,
STATE_DATA_IN,
+ STATE_DUMMY_OUT,
STATE_DATA_OUT,
- STATE_ERASE
+ STATE_ERASE,
+ STATE_WRITE
};
@@ -73,11 +76,11 @@ inline uint16_t nmc9306_device::read(offs_t offset)
// nmc9306_device - constructor
//-------------------------------------------------
-inline void nmc9306_device::write(offs_t offset, uint16_t data)
+inline void nmc9306_device::write(offs_t offset, u16 data)
{
if (m_ewen)
{
- m_register[offset] &= data;
+ m_register[offset] = data;
}
}
@@ -104,11 +107,19 @@ inline void nmc9306_device::erase(offs_t offset)
// nmc9306_device - constructor
//-------------------------------------------------
-nmc9306_device::nmc9306_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, NMC9306, tag, owner, clock),
- device_nvram_interface(mconfig, *this),
- m_state(STATE_IDLE),
- m_ewen(false)
+nmc9306_device::nmc9306_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, NMC9306, tag, owner, clock),
+ device_nvram_interface(mconfig, *this),
+ m_bits(0),
+ m_state(STATE_IDLE),
+ m_command(0),
+ m_address(0),
+ m_data(0),
+ m_ewen(false),
+ m_cs(0),
+ m_sk(0),
+ m_do(0),
+ m_di(0)
{
}
@@ -142,6 +153,8 @@ void nmc9306_device::device_start()
void nmc9306_device::nvram_default()
{
+ for (auto & elem : m_register)
+ elem = 0xffff;
}
@@ -150,9 +163,10 @@ void nmc9306_device::nvram_default()
// .nv file
//-------------------------------------------------
-void nmc9306_device::nvram_read(emu_file &file)
+bool nmc9306_device::nvram_read(util::read_stream &file)
{
- file.read(m_register, RAM_SIZE);
+ auto const [err, actual] = util::read(file, m_register, RAM_SIZE);
+ return !err && (actual == RAM_SIZE);
}
@@ -161,9 +175,10 @@ void nmc9306_device::nvram_read(emu_file &file)
// .nv file
//-------------------------------------------------
-void nmc9306_device::nvram_write(emu_file &file)
+bool nmc9306_device::nvram_write(util::write_stream &file)
{
- file.write(m_register, RAM_SIZE);
+ auto const [err, actual] = util::write(file, m_register, RAM_SIZE);
+ return !err;
}
@@ -171,8 +186,66 @@ void nmc9306_device::nvram_write(emu_file &file)
// cs_w - chip select input
//-------------------------------------------------
-WRITE_LINE_MEMBER( nmc9306_device::cs_w )
+void nmc9306_device::cs_w(int state)
{
+ if (m_cs != state)
+ {
+ LOG("NMC9306 CS %u\n", state);
+
+ if (m_cs && !state)
+ {
+ switch ((m_command >> 2) & 0x03)
+ {
+ case OTHER:
+ switch (m_command & 0x03)
+ {
+ case WRAL:
+ if (m_state == STATE_WRITE)
+ {
+ LOG("NMC9306 WRAL\n");
+ for (int address = 0; address < 16; address++)
+ {
+ write(address, m_data);
+ }
+ }
+ break;
+
+ case ERAL:
+ if (m_state == STATE_ERASE)
+ {
+ LOG("NMC9306 ERAL\n");
+ for (int address = 0; address < 16; address++)
+ {
+ erase(address);
+ }
+ }
+ break;
+ }
+ break;
+
+ case WRITE:
+ if (m_state == STATE_WRITE)
+ {
+ LOG("NMC9306 WRITE %u:%04x\n", m_address, m_data);
+ write(m_address, m_data);
+ }
+ break;
+
+ case ERASE:
+ if (m_state == STATE_ERASE)
+ {
+ LOG("NMC9306 ERASE %u\n", m_address);
+ erase(m_address);
+ }
+ break;
+ }
+
+ m_state = STATE_IDLE;
+ m_bits = 0;
+ m_do = 0;
+ }
+ }
+
m_cs = state;
}
@@ -181,20 +254,35 @@ WRITE_LINE_MEMBER( nmc9306_device::cs_w )
// ck_w - serial clock input
//-------------------------------------------------
-WRITE_LINE_MEMBER( nmc9306_device::sk_w )
+void nmc9306_device::sk_w(int state)
{
+ if (!m_cs) return;
+ if (m_sk == state) return;
+
+ LOG("NMC9306 SK %u\n", state);
+
m_sk = state;
- if (!m_cs || !m_sk) return;
+ if (m_sk && ((m_state == STATE_DUMMY_OUT) || (m_state == STATE_DATA_OUT))) return;
+ if (!m_sk && (m_state != STATE_DUMMY_OUT) && (m_state != STATE_DATA_OUT)) return;
switch (m_state)
{
case STATE_IDLE:
LOG("NMC9306 Idle %u\n", m_di);
- if (m_di)
+ if (!m_di)
{
// start bit received
+ m_state = STATE_START;
+ }
+ break;
+
+ case STATE_START:
+ LOG("NMC9306 Start %u\n", m_di);
+
+ if (m_di)
+ {
m_state = STATE_COMMAND;
m_bits = 0;
}
@@ -205,6 +293,8 @@ WRITE_LINE_MEMBER( nmc9306_device::sk_w )
m_command <<= 1;
m_command |= m_di;
+ m_command &= 0xf;
+
m_bits++;
if (m_bits == 4)
@@ -219,6 +309,8 @@ WRITE_LINE_MEMBER( nmc9306_device::sk_w )
m_address <<= 1;
m_address |= m_di;
+ m_address &= 0xf;
+
m_bits++;
if (m_bits == 4)
@@ -235,11 +327,13 @@ WRITE_LINE_MEMBER( nmc9306_device::sk_w )
break;
case WRAL:
- LOG("NMC9306 WRAL\n");
+ LOG("NMC9306 Command WRAL\n");
+ m_state = STATE_DATA_IN;
break;
case ERAL:
- LOG("NMC9306 ERAL\n");
+ LOG("NMC9306 Command ERAL\n");
+ m_state = ERASE;
break;
case EWEN:
@@ -251,20 +345,19 @@ WRITE_LINE_MEMBER( nmc9306_device::sk_w )
break;
case WRITE:
- LOG("NMC9306 WRITE %u\n", m_address & 0x0f);
+ LOG("NMC9306 Command WRITE %u\n", m_address);
m_state = STATE_DATA_IN;
break;
case READ:
- LOG("NMC9306 READ %u\n", m_address & 0x0f);
- m_data = read(m_address & 0x0f);
- m_state = STATE_DATA_OUT;
+ m_data = read(m_address);
+ LOG("NMC9306 READ %u:%04x\n", m_address, m_data);
+ m_state = STATE_DUMMY_OUT;
break;
case ERASE:
- LOG("NMC9306 ERASE %u\n", m_address & 0x0f);
- erase(m_address & 0x0f);
- m_state = STATE_ERASE;
+ LOG("NMC9306 Command ERASE %u\n", m_address);
+ m_state = ERASE;
break;
}
@@ -277,21 +370,29 @@ WRITE_LINE_MEMBER( nmc9306_device::sk_w )
m_data <<= 1;
m_data |= m_di;
+
m_bits++;
if (m_bits == 16)
{
- write(m_address & 0x0f, m_data);
-
- m_state = STATE_IDLE;
+ m_state = STATE_WRITE;
}
break;
- case STATE_DATA_OUT:
- LOG("NMC9306 Data Bit OUT %u\n", m_di);
+ case STATE_DUMMY_OUT:
+ m_do = 0;
+ LOG("NMC9306 Dummy Bit OUT %u\n", m_do);
+
+ m_state = STATE_DATA_OUT;
+ break;
+
+ case STATE_DATA_OUT:
m_do = BIT(m_data, 15);
m_data <<= 1;
+
+ LOG("NMC9306 Data Bit OUT %u\n", m_do);
+
m_bits++;
if (m_bits == 16)
@@ -307,7 +408,7 @@ WRITE_LINE_MEMBER( nmc9306_device::sk_w )
// di_w - serial data input
//-------------------------------------------------
-WRITE_LINE_MEMBER( nmc9306_device::di_w )
+void nmc9306_device::di_w(int state)
{
m_di = state;
}
@@ -317,7 +418,7 @@ WRITE_LINE_MEMBER( nmc9306_device::di_w )
// do_r - serial data output
//-------------------------------------------------
-READ_LINE_MEMBER( nmc9306_device::do_r )
+int nmc9306_device::do_r()
{
return m_do;
}