diff options
author | 2019-05-14 17:07:02 -0300 | |
---|---|---|
committer | 2019-05-14 16:07:02 -0400 | |
commit | aff42a99693d24b5234e7cba6584678fddd85b6e (patch) | |
tree | a5de6cb1f0c84a81ec7f51b93d67f61606626fde /src | |
parent | bbb32eb832ba2cc75c7067dbea9c60971231703b (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.cpp | 798 | ||||
-rw-r--r-- | src/devices/machine/ds1994.h | 134 | ||||
-rw-r--r-- | src/mame/drivers/amaticmg.cpp | 36 |
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(¤t_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 /* |