summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author grullosgo <42551661+grullosgo@users.noreply.github.com>2019-05-14 17:07:02 -0300
committer R. Belmont <rb6502@users.noreply.github.com>2019-05-14 16:07:02 -0400
commitaff42a99693d24b5234e7cba6584678fddd85b6e (patch)
treea5de6cb1f0c84a81ec7f51b93d67f61606626fde /src
parentbbb32eb832ba2cc75c7067dbea9c60971231703b (diff)
Add DS1994 device (#5054)
Add DS1994 device amaticmg driver: added ds1994 device, modified prom load, added ds1994 to romload
Diffstat (limited to 'src')
-rw-r--r--src/devices/machine/ds1994.cpp798
-rw-r--r--src/devices/machine/ds1994.h134
-rw-r--r--src/mame/drivers/amaticmg.cpp36
3 files changed, 963 insertions, 5 deletions
diff --git a/src/devices/machine/ds1994.cpp b/src/devices/machine/ds1994.cpp
new file mode 100644
index 00000000000..5d325753b14
--- /dev/null
+++ b/src/devices/machine/ds1994.cpp
@@ -0,0 +1,798 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, smf, Grull Osgo
+/*
+ * DS1994
+ *
+ * Dallas Semiconductor
+ * 1-Wire Protocol
+ * RTC + BACKUP RAM
+ *
+ */
+
+#include "emu.h"
+#include "machine/ds1994.h"
+
+#include <time.h>
+
+#define VERBOSE_LEVEL 0
+
+inline void ds1994_device::verboselog(int n_level, const char *s_fmt, ...)
+{
+ if ( VERBOSE_LEVEL >= n_level )
+ {
+ va_list v;
+ char buf[32768];
+ va_start(v, s_fmt);
+ vsprintf(buf, s_fmt, v);
+ va_end(v);
+ logerror("ds1994 %s %s: %s", tag(), machine().describe_context(), buf);
+ }
+}
+
+// device type definition
+DEFINE_DEVICE_TYPE(DS1994, ds1994_device, "ds1994", "DS1994 RTC + BACKUP RAM")
+
+ds1994_device::ds1994_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, DS1994, tag, owner, clock), device_nvram_interface(mconfig, *this)
+ , m_timer_main(nullptr)
+ , m_timer_reset(nullptr)
+ , m_timer_clock(nullptr)
+ , m_ref_year(0)
+ , m_ref_month(0)
+ , m_ref_day(0)
+ , m_address(0)
+ , m_offset(0)
+ , m_a1(0)
+ , m_a2(0)
+ , m_bit(0)
+ , m_shift(0)
+ , m_byte(0)
+ , m_rx(false)
+ , m_tx(false)
+ , m_state_ptr(0)
+{
+ memset(m_ram, 0, sizeof(m_ram));
+}
+
+void ds1994_device::device_start()
+{
+ // Reference time setup
+ struct tm ref_tm;
+
+ memset(&ref_tm, 0, sizeof(ref_tm));
+ ref_tm.tm_year = m_ref_year - 1900;
+ ref_tm.tm_mon = m_ref_month - 1;
+ ref_tm.tm_mday = m_ref_day;
+
+ time_t ref_time = mktime(&ref_tm);
+
+ time_t current_time;
+ time(&current_time);
+ current_time -= ref_time;
+
+ m_rtc[0] = 0x0;
+ m_rtc[1] = (current_time >> 0) & 0xff;
+ m_rtc[2] = (current_time >> 8) & 0xff;
+ m_rtc[3] = (current_time >> 16) & 0xff;
+ m_rtc[4] = (current_time >> 24) & 0xff;
+
+ // 1-wire timmings
+ t_samp = attotime::from_usec(30);
+ t_rdv = attotime::from_usec(30);
+ t_rstl = attotime::from_usec(480);
+ t_pdh = attotime::from_usec(30);
+ t_pdl = attotime::from_usec(120);
+
+ // 1-wire states
+ m_rx = true;
+ m_tx = true;
+
+ // 1-Wire related
+ save_item(NAME(m_bit));
+ save_item(NAME(m_byte));
+ save_item(NAME(m_shift));
+ save_item(NAME(m_rx));
+ save_item(NAME(m_tx));
+
+ // ds1994 specific
+ save_item(NAME(m_rom));
+ save_item(NAME(m_sram));
+ save_item(NAME(m_ram));
+ save_item(NAME(m_rtc));
+ save_item(NAME(m_address));
+ save_item(NAME(m_a1));
+ save_item(NAME(m_a2));
+ save_item(NAME(m_offset));
+
+ // state machine
+ save_item(NAME(m_state));
+ save_item(NAME(m_state_ptr));
+ for (auto & elem : m_state)
+ elem = STATE_IDLE;
+
+ // timers
+ m_timer_main = timer_alloc(TIMER_MAIN);
+ m_timer_reset = timer_alloc(TIMER_RESET);
+ m_timer_clock = timer_alloc(TIMER_CLOCK);
+
+ m_timer_clock->adjust(attotime::from_hz(256), 0, attotime::from_hz(256));
+}
+
+void ds1994_device::device_reset()
+{
+ m_bit = 0;
+ m_byte = 0;
+ m_shift = 0;
+ m_rx = true;
+ m_tx = true;
+ m_state_ptr = 0;
+ m_state[m_state_ptr] = STATE_IDLE;
+
+ memory_region *region = memregion(DEVICE_SELF);
+ if (region != nullptr)
+ {
+ if (region->bytes() == ROM_SIZE+SPD_SIZE+DATA_SIZE+RTC_SIZE+REGS_SIZE)
+ {
+ memcpy(m_rom, region->base(), ROM_SIZE);
+ memcpy(m_ram , region->base() + ROM_SIZE, SPD_SIZE);
+ memcpy(m_sram, region->base() + ROM_SIZE+SPD_SIZE, DATA_SIZE);
+ memcpy(m_rtc , region->base() + ROM_SIZE+SPD_SIZE+DATA_SIZE, RTC_SIZE);
+ memcpy(m_regs, region->base() + ROM_SIZE+SPD_SIZE+DATA_SIZE+RTC_SIZE, REGS_SIZE);
+ return;
+ }
+ verboselog(0, "ds1994 %s: Wrong region length for data, expected 0x%x, got 0x%x\n", tag(), ROM_SIZE+SPD_SIZE+DATA_SIZE+RTC_SIZE+REGS_SIZE, region->bytes());
+ }
+ else
+ {
+ verboselog(0, "ds1994 %s: Warning, no id provided, answer will be all zeroes.\n", tag());
+ memset(m_rom, 0, ROM_SIZE);
+ memset(m_ram, 0, SPD_SIZE);
+ memset(m_sram, 0, DATA_SIZE);
+ memset(m_rtc, 0, RTC_SIZE);
+ memset(m_regs, 0, REGS_SIZE);
+ }
+}
+
+/********************************************/
+/* */
+/* 1-wire protocol - Tx/Rx Bit Routines */
+/* */
+/********************************************/
+
+bool ds1994_device::one_wire_tx_bit(uint8_t value)
+{
+ if (!m_bit)
+ {
+ m_shift = value;
+ verboselog(1, "one_wire_tx_bit: Byte to send %02x\n", m_shift);
+ }
+ m_tx = m_shift & 1;
+ m_shift >>= 1;
+ verboselog(1, "one_wire_tx_bit: State %d\n", m_tx);
+ m_bit++;
+ if (m_bit == 8) return true;
+ else
+ return false;
+}
+
+bool ds1994_device::one_wire_rx_bit(void)
+{
+ m_shift >>= 1;
+ if (m_rx)
+ {
+ m_shift |= 0x80;
+ }
+ verboselog(1, "one_wire_rx_bit: State %d\n", m_rx);
+ m_bit++;
+ if (m_bit == 8)
+ {
+ verboselog(1, "one_wire_rx_bit: Byte Received %02x\n", m_shift);
+ return true;
+ }
+ else
+ return false;
+}
+
+/********************************************/
+/* */
+/* Internal states - Rom Commands */
+/* */
+/********************************************/
+
+void ds1994_device::ds1994_rom_cmd(void)
+{
+ verboselog(2, "timer_main state_rom_command\n");
+ if (one_wire_rx_bit())
+ {
+ switch (m_shift)
+ {
+ case ROMCMD_READROM:
+ verboselog(1, "timer_main rom_cmd readrom\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_state[0] = STATE_READROM;
+ m_state_ptr = 0;
+ break;
+ case ROMCMD_SKIPROM:
+ verboselog(1, "timer_main rom_cmd skiprom\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_state[0] = STATE_COMMAND;
+ m_state_ptr = 0;
+ break;
+ case ROMCMD_MATCHROM:
+ verboselog(1, "timer_main rom_cmd matchrom\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_state[0] = STATE_MATCHROM;
+ m_state_ptr = 0;
+ break;
+ case ROMCMD_SEARCHROM:
+ case ROMCMD_SEARCHINT:
+ verboselog(0, "timer_main rom_command not implemented %02x\n", m_shift);
+ m_state[m_state_ptr] = STATE_COMMAND;
+ default:
+ verboselog(0, "timer_main rom_command not found %02x\n", m_shift);
+ m_state[m_state_ptr] = STATE_IDLE;
+ break;
+ }
+ }
+}
+
+/********************************************/
+/* */
+/* Internal states - DS1994 Commands */
+/* */
+/********************************************/
+
+void ds1994_device::ds1994_cmd(void)
+{
+ verboselog(2, "timer_main state_command\n");
+ if (one_wire_rx_bit())
+ {
+ switch (m_shift)
+ {
+ case COMMAND_READ_MEMORY:
+ verboselog(1, "timer_main cmd read_memory\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_state[0] = STATE_ADDRESS1;
+ m_state[1] = STATE_ADDRESS2;
+ m_state[2] = STATE_INIT_COMMAND;
+ m_state[3] = STATE_READ_MEMORY;
+ m_state_ptr = 0;
+ break;
+ case COMMAND_WRITE_SCRATCHPAD:
+ verboselog(1, "timer_main cmd write_scratchpad\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_offs_ro = false;
+ m_state[0] = STATE_ADDRESS1;
+ m_state[1] = STATE_ADDRESS2;
+ m_state[2] = STATE_INIT_COMMAND;
+ m_state[3] = STATE_WRITE_SCRATCHPAD;
+ m_state_ptr = 0;
+ break;
+ case COMMAND_READ_SCRATCHPAD:
+ verboselog(1, "timer_main cmd read_scratchpad\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_state[0] = STATE_TXADDRESS1;
+ m_state[1] = STATE_TXADDRESS2;
+ m_state[2] = STATE_TXOFFSET;
+ m_state[3] = STATE_INIT_COMMAND;
+ m_state[4] = STATE_READ_SCRATCHPAD;
+ m_state_ptr = 0;
+ break;
+ case COMMAND_COPY_SCRATCHPAD:
+ verboselog(1, "timer_main cmd copy_scratchpad\n");
+ m_bit = 0;
+ m_byte = 0;
+ m_offs_ro = true;
+ m_auth = true;
+ m_state[0] = STATE_ADDRESS1;
+ m_state[1] = STATE_ADDRESS2;
+ m_state[2] = STATE_OFFSET;
+ m_state[3] = STATE_INIT_COMMAND;
+ m_state[4] = STATE_COPY_SCRATCHPAD;
+ m_state_ptr = 0;
+ break;
+ default:
+ verboselog(0, "timer_main command not handled %02x\n", m_shift);
+ m_state[m_state_ptr] = STATE_IDLE;
+ break;
+ }
+ }
+}
+
+/********************************************/
+/* */
+/* Internal Routines - Memory R/W */
+/* */
+/********************************************/
+
+uint8_t ds1994_device::ds1994_readmem()
+{
+ if (m_address < 0x200)
+ {
+ return m_sram[m_address];
+ }
+ else
+ if (m_address >= 0x202 && m_address <= 0x206)
+ {
+ return m_rtc[m_address - 0x202];
+ }
+ return 0;
+}
+
+void ds1994_device::ds1994_writemem(uint8_t value) {
+ if (m_address < 0x200)
+ {
+ m_sram[m_address] = value;
+ }
+ else
+ if (m_address >= 0x202 && m_address <= 0x206)
+ {
+ m_rtc[m_address - 0x202] = value;
+ }
+}
+
+/*************************************************/
+/* */
+/* Internal states - Timer controlled Events */
+/* */
+/*************************************************/
+
+void ds1994_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_CLOCK:
+ for (auto & elem : m_rtc)
+ {
+ elem++;
+ if (elem != 0)
+ {
+ break;
+ }
+ }
+ break;
+ case TIMER_RESET:
+ verboselog(1, "timer_reset\n");
+ m_state[m_state_ptr] = STATE_RESET;
+ m_timer_reset->adjust(attotime::never);
+ break;
+ case TIMER_MAIN:
+ switch (m_state[m_state_ptr])
+ {
+ case STATE_RESET1:
+ verboselog(2, "timer_main state_reset1 %d\n", m_rx);
+ m_tx = false;
+ m_state[m_state_ptr] = STATE_RESET2;
+ m_timer_main->adjust(t_pdl);
+ break;
+ case STATE_RESET2:
+ verboselog(2, "timer_main state_reset2 %d\n", m_rx);
+ m_tx = true;
+ m_bit = 0;
+ m_shift = 0;
+ m_state[m_state_ptr] = STATE_ROMCMD;
+ break;
+ case STATE_ROMCMD:
+ ds1994_rom_cmd();
+ break;
+ case STATE_COMMAND:
+ ds1994_cmd();
+ break;
+ case STATE_MATCHROM:
+ verboselog(2, "timer_main state_matchrom - Data to match: <- %d\n", m_rx);
+ if (one_wire_rx_bit())
+ {
+ if (m_rom[7- m_byte] == m_shift)
+ {
+ m_byte++;
+ m_bit = 0;
+ verboselog(2, "timer_main state_matchrom: datamatch %x - byte=%d\n", m_shift, m_byte);
+ }
+ else
+ {
+ m_state[m_state_ptr] = STATE_IDLE;
+ verboselog(1, "timer_main state_matchrom: no match rx=%x <> mem=%x - byte:%d\n", m_shift, m_rom[7 - m_byte], m_byte);
+ }
+ }
+ if (m_byte == ROM_SIZE)
+ {
+ verboselog(2, "timer_main matchrom finished\n");
+ m_state[m_state_ptr] = STATE_COMMAND;
+ }
+ break;
+ case STATE_ADDRESS1:
+ verboselog(2, "timer_main state_address1\n");
+ if (one_wire_rx_bit())
+ {
+ m_bit = 0;
+ if (m_offs_ro)
+ {
+ if (m_a1 != m_shift) m_auth = false;
+ verboselog(1, "timer_main state_address1 - TA1=%02x - Auth_Code 1=%02x\n", m_a1, m_shift);
+ }
+ else
+ {
+ m_a1 = m_shift & 0xff;
+ verboselog(2, "timer_main state_address1 - Address1=%02x\n", m_a1);
+ }
+ m_state_ptr++;
+ }
+ break;
+ case STATE_ADDRESS2:
+ verboselog(2, "timer_main state_address2\n");
+ if (one_wire_rx_bit())
+ {
+ m_bit = 0;
+ if (m_offs_ro)
+ {
+ if ( m_a2 != m_shift ) m_auth = false;
+ verboselog(1, "timer_main state_address1 - TA2=%02x - Auth_Code 2=%02x\n", m_a1, m_shift);
+ }
+ else
+ {
+ m_a2 = m_shift & 0xff;
+ verboselog(2, "timer_main state_address2 - Address2=%02x\n", m_a2);
+ }
+ m_state_ptr++;
+ }
+ break;
+ case STATE_OFFSET:
+ verboselog(2, "timer_main state_offset\n");
+ if (one_wire_rx_bit())
+ {
+ m_bit = 0;
+ if (m_offs_ro)
+ {
+ if (m_a2 != m_shift) m_auth = false;
+ verboselog(1, "timer_main state_address1 - OFS_ES=%02x - Auth_Code 3=%02x\n", m_offset, m_shift);
+ }
+ else
+ {
+ m_offset = m_shift & 0x1f;
+ verboselog(2, "timer_main state_address2 - Offset=%02x\n", m_offset);
+ }
+ m_state_ptr++;
+ }
+ break;
+ case STATE_WRITE_SCRATCHPAD:
+ verboselog(2, "timer_main state_write_scratchpad\n");
+ if (one_wire_rx_bit())
+ {
+ m_bit = 0;
+ m_ram[m_offset & 0x1f] = m_shift & 0xff;
+ m_offset++;
+ }
+ verboselog(2, "timer_main state_write_scratchpad %d Offs=%02x\n", m_rx, m_offset);
+ break;
+ case STATE_READROM:
+ m_tx = true;
+ if (m_byte == ROM_SIZE)
+ {
+ verboselog(1, "timer_main readrom finished\n");
+ m_state[m_state_ptr] = STATE_COMMAND;
+ }
+ else
+ verboselog(2, "timer_main readrom window closed\n");
+ break;
+ case STATE_TXADDRESS1:
+ m_tx = true;
+ if (m_byte == 1)
+ {
+ verboselog(1, "timer_main txaddress1 finished m_byte=%d\n", m_byte);
+ m_byte = 0;
+ m_state_ptr++;
+ }
+ else
+ verboselog(2, "timer_main txaddress1 window closed\n");
+ break;
+ case STATE_TXADDRESS2:
+ m_tx = true;
+ if (m_byte == 1)
+ {
+ verboselog(1, "timer_main txaddress2 finished m_byte=%d\n", m_byte);
+ m_byte = 0;
+ m_state_ptr++;
+ }
+ else
+ verboselog(2, "timer_main txaddress2 window closed\n");
+ break;
+ case STATE_TXOFFSET:
+ m_tx = true;
+ if (m_byte == 1)
+ {
+ verboselog(1, "timer_main txoffset finished - m_byte=%d\n", m_byte);
+ m_byte = 0;
+ m_state_ptr++;
+ }
+ else
+ verboselog(2, "timer_main txoffset window closed\n");
+ break;
+ case STATE_READ_MEMORY:
+ verboselog(2, "timer_main state_readmemory\n");
+ break;
+ case STATE_COPY_SCRATCHPAD:
+ verboselog(2, "timer_main state_copy_scratchpad\n");
+ break;
+ case STATE_READ_SCRATCHPAD:
+ verboselog(2, "timer_main state_read_scratchpad\n");
+ break;
+ default:
+ verboselog(0, "timer_main state not handled: %d\n", m_state[m_state_ptr]);
+ break;
+ }
+ if (m_state[m_state_ptr] == STATE_INIT_COMMAND)
+ {
+ switch (m_state[m_state_ptr + 1])
+ {
+ case STATE_IDLE:
+ case STATE_COMMAND:
+ case STATE_ADDRESS1:
+ case STATE_ADDRESS2:
+ case STATE_OFFSET:
+ break;
+ case STATE_READ_MEMORY:
+ verboselog(2, "timer_main (init_cmd) -> state_read_memory - set address\n");
+ m_address = (m_a2 << 8) | m_a1;
+ break;
+ case STATE_WRITE_SCRATCHPAD:
+ verboselog(2, "timer_main (init_cmd) -> state_write_scratchpad - set address\n");
+ m_offs_ro = false;
+ m_offset = 0;
+ break;
+ case STATE_READ_SCRATCHPAD:
+ verboselog(2, "timer_main (init_cmd) -> state_read_scratchpad - set address\n");
+ m_address = 0;
+ break;
+ case STATE_COPY_SCRATCHPAD:
+ verboselog(2, "timer_main (init_cmd) -> state_copy_scratchpad - do copy\n");
+ if (m_auth)
+ {
+ m_address = (m_a2 << 8) | m_a1;
+ for (int i = 0; i <= m_offset; i++)
+ {
+ ds1994_writemem(m_ram[i]);
+ m_address++;
+ }
+ }
+ else
+ verboselog(1, "timer_main (init_cmd) -> state_copy_scratchpad - Auth-Rejected\n");
+ break;
+ }
+ m_state_ptr++;
+ }
+ }
+}
+
+/*********************/
+/* */
+/* Write Handler */
+/* */
+/*********************/
+
+WRITE_LINE_MEMBER(ds1994_device::write)
+{
+ verboselog(1, "write(%d)\n", state);
+ if (!state && m_rx)
+ {
+ switch (m_state[m_state_ptr])
+ {
+ case STATE_IDLE:
+ case STATE_INIT_COMMAND:
+ break;
+ case STATE_ROMCMD:
+ verboselog(2, "state_romcommand\n");
+ m_timer_main->adjust(t_samp);
+ break;
+ case STATE_COMMAND:
+ verboselog(2, "state_command\n");
+ m_timer_main->adjust(t_samp);
+ break;
+ case STATE_ADDRESS1:
+ verboselog(2, "state_address1\n");
+ m_timer_main->adjust(t_samp);
+ break;
+ case STATE_ADDRESS2:
+ verboselog(2, "state_address2\n");
+ m_timer_main->adjust(t_samp);
+ break;
+ case STATE_OFFSET:
+ verboselog(2, "state_offset\n");
+ m_timer_main->adjust(t_samp);
+ break;
+ case STATE_TXADDRESS1:
+ verboselog(2, "state_txaddress1\n");
+ if (one_wire_tx_bit(m_a1))
+ {
+ m_bit = 0;
+ m_byte++;
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_TXADDRESS2:
+ verboselog(2, "state_txaddress2\n");
+ if (one_wire_tx_bit(m_a2))
+ {
+ m_bit = 0;
+ m_byte++;
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_TXOFFSET:
+ verboselog(2, "state_txoffset\n");
+ if (one_wire_tx_bit(m_offset))
+ {
+ m_bit = 0;
+ m_byte++;
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_READROM:
+ verboselog(2, "state_readrom\n");
+ if (one_wire_tx_bit(m_rom[7 - m_byte]))
+ {
+ m_bit = 0;
+ m_byte++;
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_READ_MEMORY:
+ verboselog(2, "state_read_memory\n");
+ if (one_wire_tx_bit(ds1994_readmem()))
+ {
+ m_bit = 0;
+ if ( m_address < DATA_SIZE+RTC_SIZE+REGS_SIZE ) m_address++;
+ else
+ m_tx = true;
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_MATCHROM:
+ verboselog(2, "state_matchrom\n");
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_COPY_SCRATCHPAD:
+ if ( m_auth )
+ {
+ verboselog(2, "state_copy_scratchpad Auth_Code Match: %d\n", m_tx);
+ m_tx = true;
+ m_auth = false;
+ }
+ else
+ {
+ m_tx = false;
+ verboselog(1, "state_copy_scratchpad Auth_Code No Match: %d\n", m_tx);
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ case STATE_WRITE_SCRATCHPAD:
+ verboselog(2, "state_write_scratchpad\n");
+ m_timer_main->adjust(t_samp);
+ break;
+ case STATE_READ_SCRATCHPAD:
+ verboselog(2, "state_read_scratchpad\n");
+ if (one_wire_tx_bit(m_ram[m_address]))
+ {
+ m_bit = 0;
+ if ( m_address <= m_offset ) m_address++;
+ else
+ m_tx = true;
+ }
+ m_timer_main->adjust(t_rdv);
+ break;
+ default:
+ verboselog(0, "state not handled: %d\n", m_state[m_state_ptr]);
+ break;
+ }
+ m_timer_reset->adjust(t_rstl);
+ }
+ else if (state && !m_rx)
+ {
+ switch (m_state[m_state_ptr])
+ {
+ case STATE_RESET:
+ m_state[m_state_ptr] = STATE_RESET1;
+ m_timer_main->adjust(t_pdh);
+ break;
+ }
+ m_timer_reset->adjust(attotime::never);
+ }
+ m_rx = state;
+}
+
+/*********************/
+/* */
+/* Read Handler */
+/* */
+/*********************/
+
+READ_LINE_MEMBER(ds1994_device::read)
+{
+ verboselog(2, "read %d\n", m_tx && m_rx);
+ return m_tx && m_rx;
+}
+
+//-------------------------------------------------
+// nvram_default - called to initialize NVRAM to
+// its default state
+//-------------------------------------------------
+
+void ds1994_device::nvram_default()
+{
+ memset(m_rom, 0, ROM_SIZE);
+ memset(m_ram, 0, SPD_SIZE);
+ memset(m_sram, 0, DATA_SIZE);
+ memset(m_rtc, 0, RTC_SIZE);
+ memset(m_regs, 0, REGS_SIZE);
+}
+
+//-------------------------------------------------
+// nvram_read - called to read NVRAM from the
+// .nv file
+//-------------------------------------------------
+
+void ds1994_device::nvram_read(emu_file &file)
+{
+ file.read(m_rom, ROM_SIZE);
+ file.read(m_ram, SPD_SIZE);
+ file.read(m_sram, DATA_SIZE);
+ file.read(m_rtc, RTC_SIZE);
+ file.read(m_regs, REGS_SIZE);
+}
+
+//-------------------------------------------------
+// nvram_write - called to write NVRAM to the
+// .nv file
+//-------------------------------------------------
+
+void ds1994_device::nvram_write(emu_file &file)
+{
+ file.write(m_rom, ROM_SIZE);
+ file.write(m_ram, SPD_SIZE);
+ file.write(m_sram, DATA_SIZE);
+ file.write(m_rtc, RTC_SIZE);
+ file.write(m_regs, REGS_SIZE);
+}
+
+/*
+
+app74.pdf
+
+Under normal circumstances an ibutton will sample the line 30us after the falling edge of the start condition.
+The internal time base of ibutton may deviate from its nominal value. The allowed tollerance band ranges from 15us to 60us.
+This means that the actual slave sampling may occur anywhere from 15 and 60us after the start condition, which is a ratio of 1 to 4.
+During this time frame the voltage on the data line must stay below Vilmax or above Vihmin.
+
+In the 1-Wire system, the logical values 1 and 0 are represented by certain voltages in special waveforms.
+The waveforms needed to write commands or data to ibuttons are called write-1 and write-0 time slots.
+The duration of a low pulse to write a 1 must be shorter than 15us.
+To write a 0, the duration of the low pulse must be at least 60us to cope with worst-case conditions.
+
+The duration of the active part of a time slot can be extended beyond 60us.
+The maximum extension is limited by the fact that a low pulse of a duration of at least eight active time slots ( 480us ) is defined as a Reset Pulse.
+Allowing the same worst-case tolerance ratio, a low pulse of 120us might be sufficient for a reset.
+This limits the extension of the active part of a time slot to a maximum of 120us to prevent misinterpretation with reset.
+
+Commands and data are sent to ibuttons by combining write-0 and write-1 time slots.
+To read data, the master has to generate read-data time slots to define the start condition of each bit.
+The read-data time slots looks essentially the same as a write-1 time slot from the masters point of view.
+Starting at the high-to-low transition, the ibuttons sends 1 bit of its addressed contents.
+If the data bit is a 1, the ibutton leaves the pulse unchanged.
+If the data bit is a 0, the ibutton will pull the data line low for 15us.
+In this time frame data is valid for reading by the master.
+The duration of the low pulse sent by the master should be a minimum of 1us with a maximum value as short as possible to maximize the master sampling window.
+
+The Reset Pulse provides a clear starting condition that supersedes any time slot synchronisation.
+It is defined as single low pulse of minimum duration of eight time slots or 480us followed by a Reset-high time tRSTH of another 480us.
+After a Reset Pulse has been sent, the ibutton will wait for the time tPDH and then generate a Pulse-Presence Pulse of duration tPDL.
+No other communication on the 1-Wire bus is allowed during tRSTH.
+
+There are 1,000 microseconds in a millisecond, and 1,000 milliseconds in a second.
+Thus, there are 1,000,000 microseconds in a second. Why is it "usec"?
+The "u" is supposed to look like the Greek letter Mu that we use for "micro". .
+*/
diff --git a/src/devices/machine/ds1994.h b/src/devices/machine/ds1994.h
new file mode 100644
index 00000000000..a91c1d4525b
--- /dev/null
+++ b/src/devices/machine/ds1994.h
@@ -0,0 +1,134 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, smf, Grull Osgo
+/*
+ * DS1994
+ *
+ * Dallas Semiconductor
+ * 1-Wire Protocol
+ * RTC + BACKUP RAM
+ *
+ */
+
+#ifndef MAME_MACHINE_DS1994_H
+#define MAME_MACHINE_DS1994_H
+
+#pragma once
+
+class ds1994_device : public device_t, public device_nvram_interface
+{
+ public:
+ // construction/destruction
+ ds1994_device(const machine_config &mconfig, const char *tag, device_t *owner)
+ : ds1994_device(mconfig, tag, owner, uint32_t(0))
+ {
+ }
+
+ ds1994_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // inline configuration helpers
+ void ref_year(uint32_t year) { m_ref_year = year; }
+ void ref_month(uint8_t month) { m_ref_month = month; }
+ void ref_day(uint8_t day) { m_ref_day = day; }
+
+ DECLARE_WRITE_LINE_MEMBER(write);
+ DECLARE_READ_LINE_MEMBER(read);
+
+ protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() 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;
+ virtual void nvram_read(emu_file &file) override;
+ virtual void nvram_write(emu_file &file) override;
+
+ private:
+ enum {
+ ROM_SIZE = 8,
+ DATA_SIZE = 0x202,
+ SPD_SIZE = 0x20,
+ RTC_SIZE = 0x05,
+ REGS_SIZE = 0x19,
+ // Rom Commands
+ ROMCMD_READROM = 0x33,
+ ROMCMD_MATCHROM = 0x55,
+ ROMCMD_SEARCHROM = 0xf0,
+ ROMCMD_SEARCHINT = 0xec,
+ ROMCMD_SKIPROM = 0xcc,
+ // Memory Commands
+ COMMAND_READ_MEMORY = 0xf0,
+ COMMAND_WRITE_SCRATCHPAD = 0x0f,
+ COMMAND_READ_SCRATCHPAD = 0xaa,
+ COMMAND_COPY_SCRATCHPAD = 0x55
+ };
+
+ enum {
+ TIMER_MAIN,
+ TIMER_RESET,
+ TIMER_CLOCK
+ };
+
+ enum {
+ STATE_IDLE,
+ STATE_RESET,
+ STATE_RESET1,
+ STATE_RESET2,
+ STATE_ROMCMD,
+ STATE_READROM,
+ STATE_SKIPROM,
+ STATE_MATCHROM,
+ STATE_COMMAND,
+ STATE_ADDRESS1,
+ STATE_ADDRESS2,
+ STATE_OFFSET,
+ STATE_TXADDRESS1,
+ STATE_TXADDRESS2,
+ STATE_TXOFFSET,
+ STATE_INIT_COMMAND,
+ STATE_READ_MEMORY,
+ STATE_WRITE_SCRATCHPAD,
+ STATE_READ_SCRATCHPAD,
+ STATE_COPY_SCRATCHPAD
+ };
+
+ void ds1994_rom_cmd(void);
+ void ds1994_cmd(void);
+ bool one_wire_tx_bit(uint8_t value);
+ bool one_wire_rx_bit(void);
+ uint8_t ds1994_readmem();
+ void ds1994_writemem(uint8_t value);
+
+ emu_timer *m_timer_main, *m_timer_reset, *m_timer_clock;
+
+ uint32_t m_ref_year;
+ uint8_t m_ref_month;
+ uint8_t m_ref_day;
+
+ uint16_t m_address;
+ uint16_t m_offset;
+ uint8_t m_a1;
+ uint8_t m_a2;
+ int m_bit, m_shift;
+ uint8_t m_byte;
+ bool m_rx, m_tx;
+ uint8_t m_rom[ROM_SIZE];
+ uint8_t m_sram[DATA_SIZE];
+ uint8_t m_ram[SPD_SIZE];
+ uint8_t m_rtc[RTC_SIZE];
+ uint8_t m_regs[REGS_SIZE];
+ int m_state[6];
+ int m_state_ptr;
+ bool m_auth;
+ bool m_offs_ro;
+
+ attotime t_samp, t_rdv, t_rstl, t_pdh, t_pdl;
+
+ inline void verboselog(int n_level, const char *s_fmt, ...) ATTR_PRINTF(3, 4);
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(DS1994, ds1994_device)
+
+#endif // MAME_MACHINE_DS1994_H
diff --git a/src/mame/drivers/amaticmg.cpp b/src/mame/drivers/amaticmg.cpp
index 65a18f9ed6f..5f251a75ae9 100644
--- a/src/mame/drivers/amaticmg.cpp
+++ b/src/mame/drivers/amaticmg.cpp
@@ -413,6 +413,7 @@
#include "emu.h"
#include "cpu/z80/z80.h"
#include "machine/i8255.h"
+#include "machine/ds1994.h"
#include "sound/3812intf.h"
#include "video/mc6845.h"
//#include "sound/dac.h"
@@ -439,6 +440,7 @@ public:
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
+ m_tch(*this, "touch_m"),
m_lamps(*this, "lamp%u", 0U)
{
}
@@ -464,10 +466,14 @@ private:
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
+ optional_device<ds1994_device> m_tch;
output_finder<7> m_lamps;
uint8_t m_nmi_mask;
+ DECLARE_READ8_MEMBER(epm_code_r);
+ DECLARE_READ8_MEMBER(touchm_r);
+ DECLARE_WRITE8_MEMBER(touchm_w);
DECLARE_WRITE8_MEMBER(rombank_w);
DECLARE_WRITE8_MEMBER(nmi_mask_w);
DECLARE_WRITE8_MEMBER(unk80_w);
@@ -592,6 +598,20 @@ void amaticmg_state::amaticmg2_palette(palette_device &palette) const
/************************************
* Read/Write Handlers *
************************************/
+READ8_MEMBER( amaticmg_state::epm_code_r )
+{
+ return 0x65;
+}
+
+READ8_MEMBER( amaticmg_state::touchm_r )
+{
+ return m_tch->read() & 1;
+}
+
+WRITE8_MEMBER( amaticmg_state::touchm_w )
+{
+ m_tch->write(data & 1);
+}
WRITE8_MEMBER( amaticmg_state::rombank_w )
{
@@ -687,9 +707,11 @@ void amaticmg_state::amaticmg2_portmap(address_map &map)
map(0x00, 0x03).rw("ppi8255_0", FUNC(i8255_device::read), FUNC(i8255_device::write));
map(0x20, 0x23).rw("ppi8255_1", FUNC(i8255_device::read), FUNC(i8255_device::write));
map(0x40, 0x41).w("ymsnd", FUNC(ym3812_device::write));
- map(0x60, 0x60).w("crtc", FUNC(mc6845_device::address_w)); // 0e for mg_iii_vger_3.64_v_8309
+ map(0x60, 0x60).w("crtc", FUNC(mc6845_device::address_w)); // 0e for mg_iii_vger_3.64_v_8309
map(0x61, 0x61).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); // 0f for mg_iii_vger_3.64_v_8309
map(0xc0, 0xc0).w(FUNC(amaticmg_state::rombank_w));
+ map(0xe0, 0xe0).rw(FUNC(amaticmg_state::touchm_r),FUNC(amaticmg_state::touchm_w)); // Touch Memory DS1994f
+ map(0xe4, 0xe4).r(FUNC(amaticmg_state::epm_code_r)); // Input(0x00E4) must give back 0x65 in case of EPM Code 8201
map(0xe6, 0xe6).w(FUNC(amaticmg_state::nmi_mask_w));
map(0xe8, 0xeb).rw("ppi8255_2", FUNC(i8255_device::read), FUNC(i8255_device::write));
}
@@ -912,8 +934,9 @@ void amaticmg_state::amaticmg2(machine_config &config)
m_gfxdecode->set_info(gfx_amaticmg2);
m_palette->set_init(FUNC(amaticmg_state::amaticmg2_palette));
m_palette->set_entries(0x10000);
-}
+ DS1994(config, "touch_m");
+}
void amaticmg_state::amaticmg4(machine_config &config)
{
@@ -967,9 +990,12 @@ ROM_START( am_mg24 )
ROM_LOAD( "multi_2.4_zg2.i18.bin", 0x080000, 0x80000, CRC(b504e1b8) SHA1(ffa17a2c212eb2fffb89b131868e69430cb41203) )
ROM_LOAD( "multi_2.4_zg3.i33.bin", 0x000000, 0x80000, CRC(9b66bb4d) SHA1(64035d2028a9b68164c87475a1ec9754453ad572) )
- ROM_REGION( 0x20000/*0x0400*/, "proms", 0 )
- ROM_LOAD( "n82s147a_1.bin", 0x0000, 0x0200, NO_DUMP )
- ROM_LOAD( "n82s147a_2.bin", 0x0200, 0x0200, NO_DUMP )
+ ROM_REGION( 0x4000, "proms", 0 )
+ ROM_LOAD( "m2061295.bin", 0x0000, 0x1c00, CRC(05f4a6af) SHA1(b14e9c80d3313fa5bf076d129a509a711d80f982) )
+ ROM_LOAD( "m2080196.bin", 0x2000, 0x1c00, CRC(8cf6c3a6) SHA1(6454077c2ab94093e878cbc1c0102bbb6c4bc367) )
+
+ ROM_REGION( 0x0248, "touch_m", 0 )
+ ROM_LOAD( "ds1994.bin", 0x0000, 0x0248, CRC(7f581301) SHA1(33b2652f053a5e09442ccaa078b5d245255bb415) )
ROM_END
/*