From 490d00afb7024a53e16511f98bfff82e4185bd3e Mon Sep 17 00:00:00 2001 From: cracyc Date: Wed, 12 Apr 2017 17:32:22 -0500 Subject: ds1205: Add Dallas DS1205 Multikey [Carl] --- scripts/src/machine.lua | 12 ++ scripts/target/mame/arcade.lua | 1 + src/devices/machine/ds1205.cpp | 391 +++++++++++++++++++++++++++++++++++++++++ src/devices/machine/ds1205.h | 100 +++++++++++ src/mame/drivers/mtouchxl.cpp | 23 ++- 5 files changed, 520 insertions(+), 7 deletions(-) create mode 100644 src/devices/machine/ds1205.cpp create mode 100644 src/devices/machine/ds1205.h 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 @@ -778,6 +778,18 @@ if (MACHINES["DS1204"]~=null) then } 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 +#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( 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 m_maincpu; required_device m_mb; required_device m_ram; required_device m_iocard; - required_device m_ibutton; + //optional_device m_ibutton; + optional_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)) -- cgit v1.2.3