mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
vt100, la120: Make ER1400 non-volatile storage actually work
This commit is contained in:
parent
8b0d71b98f
commit
96c76cc3a7
@ -16,6 +16,8 @@
|
||||
be left at logic zero when the device is in standby.
|
||||
|
||||
Write and erase times are 10 ms (min), 15 ms (typical), 24 ms (max).
|
||||
The data retention capability of the actual chip can be greatly
|
||||
degraded by frequent reprogramming.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -71,6 +73,8 @@ void er1400_device::device_start()
|
||||
|
||||
m_data_array = std::make_unique<u16[]>(100);
|
||||
save_pointer(m_data_array.get(), "m_data_array", 100);
|
||||
|
||||
m_data_propagation_timer = timer_alloc(PROPAGATION_TIMER);
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +97,7 @@ void er1400_device::nvram_default()
|
||||
|
||||
void er1400_device::nvram_read(emu_file &file)
|
||||
{
|
||||
file.read(&m_data_array[0], 200);
|
||||
file.read(&m_data_array[0], 100 * sizeof(m_data_array[0]));
|
||||
}
|
||||
|
||||
|
||||
@ -104,7 +108,23 @@ void er1400_device::nvram_read(emu_file &file)
|
||||
|
||||
void er1400_device::nvram_write(emu_file &file)
|
||||
{
|
||||
file.write(&m_data_array[0], 200);
|
||||
file.write(&m_data_array[0], 100 * sizeof(m_data_array[0]));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// address_binary_format - logging helper
|
||||
//-------------------------------------------------
|
||||
|
||||
std::string er1400_device::address_binary_format() const
|
||||
{
|
||||
std::ostringstream result;
|
||||
for (int i = 19; i >= 10; i--)
|
||||
result << (BIT(m_address_register, i) ? '1' : '0');
|
||||
result << ':';
|
||||
for (int i = 9; i >= 0; i--)
|
||||
result << (BIT(m_address_register, i) ? '1' : '0');
|
||||
return result.str();
|
||||
}
|
||||
|
||||
|
||||
@ -158,7 +178,8 @@ void er1400_device::write_data()
|
||||
offs_t offset = 10 * (tens - 10) + units;
|
||||
if ((m_data_array[offset] & ~m_data_register) != 0)
|
||||
{
|
||||
LOG("Writing data %04X at %d\n", m_data_register, offset);
|
||||
LOG("Writing data at %d (%04X changed to %04X)\n", offset,
|
||||
m_data_array[offset], m_data_array[offset] & m_data_register);
|
||||
m_data_array[offset] &= m_data_register;
|
||||
}
|
||||
selected++;
|
||||
@ -211,7 +232,7 @@ void er1400_device::erase_data()
|
||||
|
||||
WRITE_LINE_MEMBER(er1400_device::data_w)
|
||||
{
|
||||
m_data_input = state;
|
||||
m_data_input = bool(state);
|
||||
}
|
||||
|
||||
|
||||
@ -221,7 +242,12 @@ WRITE_LINE_MEMBER(er1400_device::data_w)
|
||||
|
||||
WRITE_LINE_MEMBER(er1400_device::c1_w)
|
||||
{
|
||||
m_code_input = (m_code_input & 3) | (state << 2);
|
||||
if (bool(state) == BIT(m_code_input, 2))
|
||||
return;
|
||||
|
||||
m_code_input = (m_code_input & 3) | (bool(state) << 2);
|
||||
if (!m_data_propagation_timer->enabled())
|
||||
m_data_propagation_timer->adjust(attotime::from_usec(20));
|
||||
}
|
||||
|
||||
|
||||
@ -231,7 +257,12 @@ WRITE_LINE_MEMBER(er1400_device::c1_w)
|
||||
|
||||
WRITE_LINE_MEMBER(er1400_device::c2_w)
|
||||
{
|
||||
m_code_input = (m_code_input & 5) | (state << 1);
|
||||
if (bool(state) == BIT(m_code_input, 1))
|
||||
return;
|
||||
|
||||
m_code_input = (m_code_input & 5) | (bool(state) << 1);
|
||||
if (!m_data_propagation_timer->enabled())
|
||||
m_data_propagation_timer->adjust(attotime::from_usec(20));
|
||||
}
|
||||
|
||||
|
||||
@ -241,7 +272,28 @@ WRITE_LINE_MEMBER(er1400_device::c2_w)
|
||||
|
||||
WRITE_LINE_MEMBER(er1400_device::c3_w)
|
||||
{
|
||||
m_code_input = (m_code_input & 6) | state;
|
||||
if (bool(state) == BIT(m_code_input, 0))
|
||||
return;
|
||||
|
||||
m_code_input = (m_code_input & 6) | bool(state);
|
||||
if (!m_data_propagation_timer->enabled())
|
||||
m_data_propagation_timer->adjust(attotime::from_usec(20));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - called whenever a device timer
|
||||
// fires
|
||||
//-------------------------------------------------
|
||||
|
||||
void er1400_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case PROPAGATION_TIMER:
|
||||
m_data_output = (m_code_input == 5) ? BIT(m_data_register, 13) : false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -258,17 +310,23 @@ WRITE_LINE_MEMBER(er1400_device::clock_w)
|
||||
// Commands are clocked by a logical 1 -> 0 transition (i.e. rising edge)
|
||||
if (!state)
|
||||
{
|
||||
m_data_output = false;
|
||||
|
||||
if (machine().time() >= m_write_time)
|
||||
write_data();
|
||||
if (m_code_input != 6)
|
||||
{
|
||||
if (m_write_time != attotime::never && machine().time() < m_write_time)
|
||||
logerror("Write not completed in time\n");
|
||||
m_write_time = attotime::never;
|
||||
}
|
||||
|
||||
if (machine().time() >= m_erase_time)
|
||||
erase_data();
|
||||
if (m_code_input != 2)
|
||||
{
|
||||
if (m_erase_time != attotime::never && machine().time() < m_erase_time)
|
||||
logerror("Erase not completed in time\n");
|
||||
m_erase_time = attotime::never;
|
||||
}
|
||||
|
||||
switch (m_code_input)
|
||||
{
|
||||
@ -281,7 +339,7 @@ WRITE_LINE_MEMBER(er1400_device::clock_w)
|
||||
case 2: // erase
|
||||
if (m_erase_time == attotime::never)
|
||||
{
|
||||
LOG("Entering erase command\n");
|
||||
LOG("Entering erase command (address = %s)\n", address_binary_format());
|
||||
m_erase_time = machine().time() + attotime::from_msec(15);
|
||||
}
|
||||
break;
|
||||
@ -296,14 +354,14 @@ WRITE_LINE_MEMBER(er1400_device::clock_w)
|
||||
break;
|
||||
|
||||
case 5: // shift data out
|
||||
m_data_output = BIT(m_data_register, 13);
|
||||
m_data_register = (m_data_register & 0x1fff) << 1;
|
||||
m_data_propagation_timer->adjust(attotime::from_usec(20));
|
||||
break;
|
||||
|
||||
case 6: // write
|
||||
if (m_write_time == attotime::never)
|
||||
{
|
||||
LOG("Entering write command\n");
|
||||
LOG("Entering write command (address = %s, data = %04X)\n", address_binary_format(), m_data_register);
|
||||
m_write_time = machine().time() + attotime::from_msec(15);
|
||||
}
|
||||
break;
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual void nvram_default() override;
|
||||
@ -52,6 +53,14 @@ protected:
|
||||
virtual void nvram_write(emu_file &file) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
PROPAGATION_TIMER
|
||||
};
|
||||
|
||||
// logging helper
|
||||
std::string address_binary_format() const;
|
||||
|
||||
// internal helpers
|
||||
void read_data();
|
||||
void write_data();
|
||||
@ -69,6 +78,7 @@ private:
|
||||
// timing
|
||||
attotime m_write_time;
|
||||
attotime m_erase_time;
|
||||
emu_timer *m_data_propagation_timer;
|
||||
|
||||
// internal registers
|
||||
u16 m_data_register;
|
||||
|
@ -144,7 +144,7 @@ READ8_MEMBER( decwriter_state::la120_NVR_r )
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->adjust_icount(-1);
|
||||
|
||||
return (m_nvm->data_r() << 7) | 0x7e;
|
||||
return (!m_nvm->data_r() << 7) | 0x7f;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( decwriter_state::la120_NVR_w )
|
||||
@ -154,11 +154,13 @@ WRITE8_MEMBER( decwriter_state::la120_NVR_w )
|
||||
m_maincpu->adjust_icount(-1);
|
||||
|
||||
// ER1400 has negative logic, but 7406 inverters are used
|
||||
m_nvm->clock_w(BIT(offset, 0));
|
||||
m_nvm->c3_w(BIT(offset, 10));
|
||||
m_nvm->c2_w(BIT(offset, 9));
|
||||
m_nvm->c1_w(BIT(offset, 8));
|
||||
|
||||
// FIXME: clock line shouldn't be inverted relative to C1-C3, but accesses only seems to work this way
|
||||
m_nvm->clock_w(!BIT(offset, 0));
|
||||
|
||||
// C2 is used to disable pullup on data line
|
||||
m_nvm->data_w(!BIT(offset, 9) ? 0 : !BIT(data, 7));
|
||||
}
|
||||
@ -180,6 +182,10 @@ WRITE8_MEMBER( decwriter_state::la120_NVR_w )
|
||||
*/
|
||||
READ8_MEMBER( decwriter_state::la120_DC305_r )
|
||||
{
|
||||
// one wait state inserted
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->adjust_icount(-1);
|
||||
|
||||
uint8_t data = 0x00;
|
||||
if (DC305_VERBOSE)
|
||||
logerror("DC305 Read from offset %01x, returning %02X\n", offset, data);
|
||||
@ -197,6 +203,10 @@ READ8_MEMBER( decwriter_state::la120_DC305_r )
|
||||
*/
|
||||
WRITE8_MEMBER( decwriter_state::la120_DC305_w )
|
||||
{
|
||||
// one wait state inserted
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->adjust_icount(-1);
|
||||
|
||||
if (DC305_VERBOSE)
|
||||
logerror("DC305 Write of %02X to offset %01X\n", data, offset);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user