summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cracyc <cracyc@users.noreply.github.com>2017-04-12 17:32:22 -0500
committer cracyc <cracyc@users.noreply.github.com>2017-04-12 17:32:22 -0500
commit490d00afb7024a53e16511f98bfff82e4185bd3e (patch)
treec6950a4675023e57832b7b2f03d66e256ba6657d
parent2f47ccd579ab4862c391c8de6732c3e767e610f0 (diff)
ds1205: Add Dallas DS1205 Multikey [Carl]
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--src/devices/machine/ds1205.cpp391
-rw-r--r--src/devices/machine/ds1205.h100
-rw-r--r--src/mame/drivers/mtouchxl.cpp23
5 files changed, 520 insertions, 7 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index 493575cc093..fd0f4c5c17a 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -780,6 +780,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/ds1205.h,MACHINES["DS1205"] = true
+---------------------------------------------------
+
+if (MACHINES["DS1205"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/ds1205.cpp",
+ MAME_DIR .. "src/devices/machine/ds1205.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/ds1302.h,MACHINES["DS1302"] = true
---------------------------------------------------
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index d856184cd2a..cbd77162be7 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -407,6 +407,7 @@ MACHINES["CXD1095"] = true
--MACHINES["DM9334"] = true
MACHINES["DP8390"] = true
MACHINES["DS1204"] = true
+MACHINES["DS1205"] = true
MACHINES["DS1302"] = true
--MACHINES["DS1315"] = true
--MACHINES["DS1386"] = true
diff --git a/src/devices/machine/ds1205.cpp b/src/devices/machine/ds1205.cpp
new file mode 100644
index 00000000000..959c8ee69be
--- /dev/null
+++ b/src/devices/machine/ds1205.cpp
@@ -0,0 +1,391 @@
+// license:BSD-3-Clause
+// copyright-holders:smf, Carl
+/*
+ * ds1205.c
+ *
+ * MultiKey
+ *
+ */
+
+#include <stdio.h>
+#include "emu.h"
+#include "ds1205.h"
+
+#define VERBOSE_LEVEL ( 2 )
+
+inline void ATTR_PRINTF( 3, 4 ) ds1205_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( "%s: ds1205(%s) %s", machine().describe_context(), tag(), buf );
+ }
+}
+
+// device type definition
+const device_type DS1205 = device_creator<ds1205_device>;
+
+ds1205_device::ds1205_device( const machine_config &mconfig, const char *tag, device_t *owner, u32 clock )
+ : device_t( mconfig, DS1205, "DS1205", tag, owner, clock, "ds1205", __FILE__ ),
+ device_nvram_interface(mconfig, *this),
+ m_region(*this, DEVICE_SELF),
+ m_rst( 0 ),
+ m_clk( 0 ),
+ m_dqw( 0 ), m_dqr(0), m_state(0), m_bit(0)
+{
+}
+
+void ds1205_device::device_start()
+{
+ new_state( STATE_STOP );
+ m_dqr = DQ_HIGH_IMPEDANCE;
+
+ memset( m_command, 0, sizeof( m_command ) );
+ memset( m_compare_register, 0, sizeof( m_compare_register ) );
+ memset( m_scratchpad, 0, sizeof( m_scratchpad ) );
+
+ save_item( NAME( m_rst ) );
+ save_item( NAME( m_clk ) );
+ save_item( NAME( m_dqw ) );
+ save_item( NAME( m_dqr ) );
+ save_item( NAME( m_state ) );
+ save_item( NAME( m_bit ) );
+ save_item( NAME( m_command ) );
+ save_item( NAME( m_scratchpad ) );
+ save_item( NAME( m_compare_register ) );
+ save_item( NAME( m_identification ) );
+ save_item( NAME( m_security_match ) );
+ save_item( NAME( m_secure_memory ) );
+}
+
+void ds1205_device::nvram_default()
+{
+ memset( m_identification, 0, sizeof( m_identification ) );
+ memset( m_security_match, 0, sizeof( m_security_match ) );
+ memset( m_secure_memory, 0, sizeof( m_secure_memory ) );
+
+ int expected_bytes = sizeof( m_identification ) + sizeof( m_security_match ) + sizeof( m_secure_memory );
+
+ if (!m_region.found())
+ {
+ logerror( "ds1205(%s) region not found\n", tag() );
+ }
+ else if( m_region->bytes() != expected_bytes )
+ {
+ logerror( "ds1205(%s) region length 0x%x expected 0x%x\n", tag(), m_region->bytes(), expected_bytes );
+ }
+ else
+ {
+ u8 *region = m_region->base();
+
+ for(int i = 0; i < 3; i++)
+ {
+ memcpy( m_identification[i], region, sizeof( m_identification[i] ) ); region += sizeof( m_identification[i] );
+ memcpy( m_security_match[i], region, sizeof( m_security_match[i] ) ); region += sizeof( m_security_match[i] );
+ memcpy( m_secure_memory[i], region, sizeof( m_secure_memory[i] ) ); region += sizeof( m_secure_memory[i] );
+ }
+ }
+}
+
+void ds1205_device::nvram_read( emu_file &file )
+{
+ for(int i = 0; i < 3; i++)
+ {
+ file.read( m_identification[i], sizeof( m_identification[i] ) );
+ file.read( m_security_match[i], sizeof( m_security_match[i] ) );
+ file.read( m_secure_memory[i], sizeof( m_secure_memory[i] ) );
+ }
+}
+
+void ds1205_device::nvram_write( emu_file &file )
+{
+ for(int i = 0; i < 3; i++)
+ {
+ file.write( m_identification[i], sizeof( m_identification[i] ) );
+ file.write( m_security_match[i], sizeof( m_security_match[i] ) );
+ file.write( m_secure_memory[i], sizeof( m_secure_memory[i] ) );
+ }
+}
+
+void ds1205_device::new_state( int state )
+{
+ m_state = state;
+ m_bit = 0;
+}
+
+void ds1205_device::writebit( u8 *buffer )
+{
+ if( m_clk )
+ {
+ int index = m_bit / 8;
+ int mask = 1 << ( m_bit % 8 );
+
+ if( m_dqw )
+ {
+ buffer[ index ] |= mask;
+ }
+ else
+ {
+ buffer[ index ] &= ~mask;
+ }
+
+ m_bit++;
+ }
+}
+
+void ds1205_device::readbit( u8 *buffer )
+{
+ if( !m_clk )
+ {
+ int index = m_bit / 8;
+ int mask = 1 << ( m_bit % 8 );
+
+ if( buffer[ index ] & mask )
+ {
+ m_dqr = 1;
+ }
+ else
+ {
+ m_dqr = 0;
+ }
+ }
+ else
+ {
+ m_bit++;
+ }
+}
+
+WRITE_LINE_MEMBER( ds1205_device::write_rst )
+{
+ if( m_rst != state )
+ {
+ m_rst = state;
+ verboselog( 2, "rst=%d\n", m_rst );
+
+ if( m_rst )
+ {
+ new_state( STATE_PROTOCOL );
+ }
+ else
+ {
+ switch( m_state )
+ {
+ case STATE_WRITE_IDENTIFICATION:
+ verboselog( 0, "reset during write identification (bit=%d)\n", m_bit );
+ break;
+ case STATE_WRITE_SECURITY_MATCH:
+ verboselog( 0, "reset during write security match (bit=%d)\n", m_bit );
+ break;
+ case STATE_WRITE_DATA:
+ verboselog( 0, "reset during write secure memory (bit=%d)\n", m_bit );
+ break;
+ }
+
+ new_state( STATE_STOP );
+ m_dqr = DQ_HIGH_IMPEDANCE;
+ }
+ }
+}
+
+WRITE_LINE_MEMBER( ds1205_device::write_clk )
+{
+ if( m_clk != state )
+ {
+ m_clk = state;
+ verboselog( 2, "clk=%d state=%d (bit=%d)\n", m_clk, m_state, m_bit );
+
+ if( m_clk )
+ {
+ m_dqr = DQ_HIGH_IMPEDANCE;
+ }
+
+ switch( m_state )
+ {
+ case STATE_PROTOCOL:
+ writebit( m_command );
+
+ if( m_bit == 24 )
+ {
+ verboselog( 1, "-> command %02x %02x %02x\n",
+ m_command[ 0 ], m_command[ 1 ], m_command[ 2 ] );
+
+ if( m_command[ 0 ] == COMMAND_GET_SCRATCHPAD && (m_command[ 1 ] & 0xc0) == 0xc0 && m_command[ 1 ] == ( ~m_command[ 2 ] & 0xff ) )
+ {
+ new_state( STATE_READ_SCRATCH );
+ }
+ else if( m_command[ 0 ] == COMMAND_GET_DATA && (m_command[ 1 ] & 0xc0) != 0xc0 && (m_command[ 1 ] & 0x3f) >= 0x10 && m_command[ 1 ] == ( ~m_command[ 2 ] & 0xff ) )
+ {
+ new_state( STATE_READ_IDENTIFICATION );
+ }
+ else if( m_command[ 0 ] == COMMAND_SET_SECURITY && (m_command[ 1 ] & 0xc0) != 0xc0 && !(m_command [ 1 ] & 0x3f) && m_command[ 1 ] == ( ~m_command[ 2 ] & 0xff ) )
+ {
+ new_state( STATE_READ_IDENTIFICATION );
+ }
+ else
+ {
+ new_state( STATE_STOP );
+ }
+ }
+ break;
+
+ case STATE_READ_IDENTIFICATION:
+ readbit( m_identification[ m_command[ 1 ] >> 6 ] );
+
+ if( m_bit == 64 )
+ {
+ int page = m_command [ 1 ] >> 6;
+ verboselog( 1, "<- identification %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ m_identification[ page ][ 0 ], m_identification[ page ][ 1 ], m_identification[ page ][ 2 ], m_identification[ page ][ 3 ],
+ m_identification[ page ][ 4 ], m_identification[ page ][ 5 ], m_identification[ page ][ 6 ], m_identification[ page ][ 7 ] );
+
+ new_state( STATE_WRITE_COMPARE_REGISTER );
+ }
+ break;
+
+ case STATE_WRITE_COMPARE_REGISTER:
+ writebit( m_compare_register );
+
+ if( m_bit == 64 )
+ {
+ int page = m_command[ 1 ] >> 6;
+ verboselog( 1, "-> compare register %02x %02x %02x %02x %02x %02x %02x %02x (%02x %02x %02x %02x %02x %02x %02x %02x)\n",
+ m_compare_register[ 0 ], m_compare_register[ 1 ], m_compare_register[ 2 ], m_compare_register[ 3 ],
+ m_compare_register[ 4 ], m_compare_register[ 5 ], m_compare_register[ 6 ], m_compare_register[ 7 ],
+ m_security_match[ page ][ 0 ], m_security_match[ page ][ 1 ], m_security_match[ page ][ 2 ], m_security_match[ page ][ 3 ],
+ m_security_match[ page ][ 4 ], m_security_match[ page ][ 5 ], m_security_match[ page ][ 6 ], m_security_match[ page ][ 7 ] );
+
+ if( memcmp( m_compare_register, m_security_match[ page ], sizeof( m_compare_register ) ) == 0 )
+ {
+ if( m_command[ 0 ] == COMMAND_GET_DATA )
+ {
+ new_state( STATE_READ_DATA );
+ }
+ else if( m_command[ 0 ] == COMMAND_GET_SCRATCHPAD)
+ {
+ new_state( STATE_READ_SCRATCH );
+ }
+ else if( m_command[ 0 ] == COMMAND_SET_SECURITY)
+ {
+ new_state( STATE_WRITE_IDENTIFICATION );
+ }
+ }
+ else
+ {
+ new_state( STATE_OUTPUT_GARBLED_DATA );
+ }
+ }
+ break;
+
+ case STATE_READ_DATA:
+ readbit( m_secure_memory[ m_command[ 1 ] >> 6 ] );
+
+ if( m_bit == 384 )
+ {
+ int page = m_command [ 1 ] >> 6;
+ verboselog( 1, "<- secure memory %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ m_secure_memory[ page ][ 0 ], m_secure_memory[ page ][ 1 ], m_secure_memory[ page ][ 2 ], m_secure_memory[ page ][ 3 ],
+ m_secure_memory[ page ][ 4 ], m_secure_memory[ page ][ 5 ], m_secure_memory[ page ][ 6 ], m_secure_memory[ page ][ 7 ],
+ m_secure_memory[ page ][ 8 ], m_secure_memory[ page ][ 9 ], m_secure_memory[ page ][ 10 ], m_secure_memory[ page ][ 11 ],
+ m_secure_memory[ page ][ 12 ], m_secure_memory[ page ][ 13 ], m_secure_memory[ page ][ 14 ], m_secure_memory[ page ][ 15 ] );
+
+ new_state( STATE_STOP );
+ }
+ break;
+
+ case STATE_READ_SCRATCH:
+ readbit( m_scratchpad );
+
+ if( m_bit == 512 )
+ {
+ verboselog( 1, "<- scratchpad %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ m_scratchpad[ 0 ], m_scratchpad[ 1 ], m_scratchpad[ 2 ], m_scratchpad[ 3 ],
+ m_scratchpad[ 4 ], m_scratchpad[ 5 ], m_scratchpad[ 6 ], m_scratchpad[ 7 ],
+ m_scratchpad[ 8 ], m_scratchpad[ 9 ], m_scratchpad[ 10 ], m_scratchpad[ 11 ],
+ m_scratchpad[ 12 ], m_scratchpad[ 13 ], m_scratchpad[ 14 ], m_scratchpad[ 15 ] );
+
+ new_state( STATE_STOP );
+ }
+ break;
+
+ case STATE_WRITE_IDENTIFICATION:
+ writebit( m_identification[ m_command[ 1 ] >> 6 ] );
+
+ if( m_bit == 64 )
+ {
+ int page = m_command[ 1 ] >> 6;
+ verboselog( 1, "-> identification %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ m_identification[ page ][ 0 ], m_identification[ page ][ 1 ], m_identification[ page ][ 2 ], m_identification[ page ][ 3 ],
+ m_identification[ page ][ 4 ], m_identification[ page ][ 5 ], m_identification[ page ][ 6 ], m_identification[ page ][ 7 ] );
+
+ new_state( STATE_WRITE_SECURITY_MATCH );
+ }
+ break;
+
+ case STATE_WRITE_SECURITY_MATCH:
+ writebit( m_security_match[ m_command[ 1 ] >> 6 ] );
+
+ if( m_bit == 64 )
+ {
+ int page = m_command[ 1 ] >> 6;
+ verboselog( 1, ">- security match %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ m_security_match[ page ][ 0 ], m_security_match[ page ][ 1 ], m_security_match[ page ][ 2 ], m_security_match[ page ][ 3 ],
+ m_security_match[ page ][ 4 ], m_security_match[ page ][ 5 ], m_security_match[ page ][ 6 ], m_security_match[ page ][ 7 ] );
+
+ new_state( STATE_STOP );
+ }
+ break;
+
+ case STATE_OUTPUT_GARBLED_DATA:
+ if( !m_clk && m_command[ 0 ] == COMMAND_GET_DATA )
+ {
+ m_dqr = machine().rand() & 1;
+ m_bit++;
+ }
+ else if( m_clk && m_command[ 0 ] == COMMAND_SET_DATA )
+ {
+ m_bit++;
+ }
+
+ if( m_bit == 64 )
+ {
+ if( m_command[ 0 ] == COMMAND_GET_DATA )
+ {
+ verboselog( 1, "<- random\n" );
+ }
+ else
+ {
+ verboselog( 1, "-> ignore\n" );
+ }
+
+ new_state( STATE_STOP );
+ }
+ break;
+ }
+ }
+}
+
+WRITE_LINE_MEMBER( ds1205_device::write_dq )
+{
+ if( m_dqw != state )
+ {
+ m_dqw = state;
+
+ verboselog( 2, "dqw=%d\n", m_dqw );
+ }
+}
+
+READ_LINE_MEMBER( ds1205_device::read_dq )
+{
+ if( m_dqr == DQ_HIGH_IMPEDANCE )
+ {
+ verboselog( 2, "dqr=high impedance\n" );
+ return 0;
+ }
+
+ verboselog( 2, "dqr=%d (bit=%d)\n", m_dqr, m_bit );
+ return m_dqr;
+}
diff --git a/src/devices/machine/ds1205.h b/src/devices/machine/ds1205.h
new file mode 100644
index 00000000000..8856d5d2567
--- /dev/null
+++ b/src/devices/machine/ds1205.h
@@ -0,0 +1,100 @@
+// license:BSD-3-Clause
+// copyright-holders:smf,Carl
+/*
+ * ds1205.h
+ *
+ * MultiKey
+ *
+ */
+
+#pragma once
+
+#ifndef __DS1205_H__
+#define __DS1205_H__
+
+
+#define MCFG_DS1205_ADD( _tag ) \
+ MCFG_DEVICE_ADD( _tag, DS1205, 0 )
+
+class ds1205_device : public device_t,
+ public device_nvram_interface
+{
+public:
+ // construction/destruction
+ ds1205_device( const machine_config &mconfig, const char *tag, device_t *owner, u32 clock );
+
+ DECLARE_WRITE_LINE_MEMBER( write_rst );
+ DECLARE_WRITE_LINE_MEMBER( write_clk );
+ DECLARE_WRITE_LINE_MEMBER( write_dq );
+ DECLARE_READ_LINE_MEMBER( read_dq );
+
+protected:
+ // device-level overrides
+ virtual void device_start() 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:
+ inline void ATTR_PRINTF( 3, 4 ) verboselog( int n_level, const char *s_fmt, ... );
+ void new_state(int state);
+ void writebit(u8 *buffer);
+ void readbit(u8 *buffer);
+
+ enum state_t
+ {
+ STATE_STOP,
+ STATE_PROTOCOL,
+ STATE_READ_IDENTIFICATION,
+ STATE_WRITE_IDENTIFICATION,
+ STATE_WRITE_COMPARE_REGISTER,
+ STATE_WRITE_SECURITY_MATCH,
+ STATE_READ_DATA,
+ STATE_WRITE_DATA,
+ STATE_READ_SCRATCH,
+ STATE_WRITE_SCRATCH,
+ STATE_OUTPUT_GARBLED_DATA
+ };
+
+ enum command_t
+ {
+ COMMAND_SET_SCRATCHPAD = 0x96,
+ COMMAND_GET_SCRATCHPAD = 0x69,
+ COMMAND_SET_DATA = 0x99,
+ COMMAND_GET_DATA = 0x66,
+ COMMAND_SET_SECURITY = 0x5a,
+ COMMAND_MOVE_BLOCK = 0x3c
+ };
+
+ enum cycle_t
+ {
+ CYCLE_NORMAL = 1,
+ CYCLE_PROGRAM = 2,
+ CYCLE_MASK = 3
+ };
+
+ static const int DQ_HIGH_IMPEDANCE = -1;
+
+ optional_memory_region m_region;
+
+ int m_rst;
+ int m_clk;
+ int m_dqw;
+ int m_dqr;
+ int m_state;
+ int m_bit;
+ u8 m_command[3];
+ u8 m_compare_register[8];
+ u8 m_scratchpad[64];
+ u8 m_identification[3][8];
+ u8 m_security_match[3][8];
+ u8 m_secure_memory[3][48];
+};
+
+
+// device type definition
+extern const device_type DS1205;
+
+#endif
diff --git a/src/mame/drivers/mtouchxl.cpp b/src/mame/drivers/mtouchxl.cpp
index 1bfe7016bcb..53f0449e1eb 100644
--- a/src/mame/drivers/mtouchxl.cpp
+++ b/src/mame/drivers/mtouchxl.cpp
@@ -12,7 +12,9 @@
Audio is a CS4231 combination CODEC/Mixer also found in Gravis Ultraound MAX
and some SPARCstations.
-
+
+ Some boards use the DS1205 chip for security, others use the DS1991 iButton
+
***************************************************************************/
#include "emu.h"
@@ -29,6 +31,7 @@
#include "machine/intelfsh.h"
#include "machine/ds128x.h"
#include "machine/ds2401.h"
+#include "machine/ds1205.h"
#include "speaker.h"
class mtxl_state : public driver_device
@@ -40,13 +43,15 @@ public:
m_mb(*this, "mb"),
m_ram(*this, RAM_TAG),
m_iocard(*this, "dbank"),
- m_ibutton(*this, "ibutton")
+ //m_ibutton(*this, "ibutton"),
+ m_multikey(*this, "multikey")
{ }
required_device<cpu_device> m_maincpu;
required_device<at_mb_device> m_mb;
required_device<ram_device> m_ram;
required_device<address_map_bank_device> m_iocard;
- required_device<ds2401_device> m_ibutton;
+ //optional_device<ds2401_device> m_ibutton;
+ optional_device<ds1205_device> m_multikey;
void machine_start() override;
void machine_reset() override;
DECLARE_WRITE8_MEMBER(bank_w);
@@ -61,12 +66,14 @@ WRITE8_MEMBER(mtxl_state::bank_w)
READ8_MEMBER(mtxl_state::key_r)
{
- return m_ibutton->read() ? 0x20 : 0;
+ return m_multikey->read_dq() ? 0x20 : 0;
}
WRITE8_MEMBER(mtxl_state::key_w)
{
- m_ibutton->write((data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
+ m_multikey->write_rst((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
+ m_multikey->write_clk((data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
+ m_multikey->write_dq((data & 0x20) ? ASSERT_LINE : CLEAR_LINE);
}
static ADDRESS_MAP_START( at32_map, AS_PROGRAM, 32, mtxl_state )
@@ -185,8 +192,8 @@ static MACHINE_CONFIG_START( at486, mtxl_state )
/* Flash ROM */
MCFG_AMD_29F040_ADD("flash")
- /* Security iButton */
- MCFG_DS2401_ADD("ibutton")
+ /* Security key */
+ MCFG_DS1205_ADD("multikey")
MACHINE_CONFIG_END
ROM_START( mtchxl6k )
@@ -197,6 +204,8 @@ ROM_START( mtchxl6k )
ROM_LOAD( "sa3014-04_u12-r00.u12", 0x000000, 0x100000, CRC(2a6fbca4) SHA1(186eb052cb9b77ffe6ee4cb50c1b580532fd8f47) )
ROM_REGION(0x8000, "dallas", ROMREGION_ERASE00)
+
+ ROM_REGION(192, "multikey", ROMREGION_ERASE00)
DISK_REGION("board1:ide:ide:0:cdrom")
DISK_IMAGE_READONLY("r02", 0, SHA1(eaaf26d2b700f16138090de7f372b40b93e8dba9))