Previous 199869 Revisions Next

r26480 Monday 2nd December, 2013 at 15:06:03 UTC by smf
remodernised x76f041/x76f100 & zs01 so that logging becomes easy again & uses READ_LINE_MEMBER/WRITE_LINE_MEMBER so the pins can be bound to directly. Hooked up x76f041 to the early beatmania IIDX games. They all pass the security check eventually but it takes a long time as it repeatedly reads the first byte, it's possible that the contents aren't correct as the game says the security is OK even when the data returned is not what it's checking for. [smf]
[src/emu/machine]i2cmem.h machine.mak secflash.c secflash.h x76f041.c x76f041.h x76f100.c x76f100.h
[src/mame/drivers]twinkle.c
[src/mame/machine]k573cass.c naomibd.c zs01.c zs01.h

trunk/src/emu/machine/secflash.c
r26479r26480
1#include "emu.h"
2#include "machine/secflash.h"
3
4device_secure_serial_flash::device_secure_serial_flash(const machine_config &mconfig,
5                                                      device_type type,
6                                                      const char *name, const char *tag,
7                                                      device_t *owner, UINT32 clock, const char *shortname, const char *source) :
8   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
9   device_nvram_interface(mconfig, *this)
10{
11}
12
13void device_secure_serial_flash::device_start()
14{
15   save_item(NAME(cs));
16   save_item(NAME(rst));
17   save_item(NAME(scl));
18   save_item(NAME(sdaw));
19   save_item(NAME(sdar));
20}
21
22void device_secure_serial_flash::device_reset()
23{
24   cs = rst = scl = sdaw = sdar = false;
25}
26
27void device_secure_serial_flash::cs_w(bool _cs)
28{
29   if(cs == _cs)
30      return;
31   cs = _cs;
32   if(cs)
33      cs_1();
34   else
35      cs_0();
36}
37
38void device_secure_serial_flash::rst_w(bool _rst)
39{
40   if(rst == _rst)
41      return;
42   rst = _rst;
43   if(rst)
44      rst_1();
45   else
46      rst_0();
47}
48
49void device_secure_serial_flash::scl_w(bool _scl)
50{
51   if(scl == _scl)
52      return;
53   scl = _scl;
54   if(scl)
55      scl_1();
56   else
57      scl_0();
58}
59
60void device_secure_serial_flash::sda_w(bool _sda)
61{
62   if(sdaw == _sda)
63      return;
64   sdaw = _sda;
65   if(sdaw)
66      sda_1();
67   else
68      sda_0();
69}
70
71bool device_secure_serial_flash::sda_r()
72{
73   return cs ? true : sdar;
74}
trunk/src/emu/machine/secflash.h
r26479r26480
1// Common interface for all secure serial flashes
2
3#ifndef __SECFLASH_H__
4#define __SECFLASH_H__
5
6#include "emu.h"
7
8class device_secure_serial_flash : public device_t,
9                           public device_nvram_interface
10{
11public:
12   void cs_w(bool cs);
13   void rst_w(bool rst);
14   void scl_w(bool scl);
15   void sda_w(bool sda);
16   bool sda_r();
17
18protected:
19   bool cs, rst, scl, sdaw, sdar;
20
21   virtual void cs_0() = 0;
22   virtual void cs_1() = 0;
23   virtual void rst_0() = 0;
24   virtual void rst_1() = 0;
25   virtual void scl_0() = 0;
26   virtual void scl_1() = 0;
27   virtual void sda_0() = 0;
28   virtual void sda_1() = 0;
29
30   device_secure_serial_flash(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
31   virtual void device_start();
32   virtual void device_reset();
33};
34
35#endif
trunk/src/emu/machine/x76f041.h
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/*
24 * x76f041.h
35 *
r26479r26480
57 *
68 */
79
10#pragma once
11
812#ifndef __X76F041_H__
913#define __X76F041_H__
1014
11#define MCFG_X76F041_ADD(_tag) \
12   MCFG_DEVICE_ADD(_tag, X76F041, 0)
15#include "emu.h"
1316
14#include "machine/secflash.h"
17#define MCFG_X76F041_ADD( _tag ) \
18   MCFG_DEVICE_ADD( _tag, X76F041, 0 )
1519
16class x76f041_device : public device_secure_serial_flash
20class x76f041_device : public device_t,
21   public device_nvram_interface
1722{
1823public:
1924   // construction/destruction
20   x76f041_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
25   x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock );
2126
27   DECLARE_WRITE_LINE_MEMBER( write_cs );
28   DECLARE_WRITE_LINE_MEMBER( write_rst );
29   DECLARE_WRITE_LINE_MEMBER( write_scl );
30   DECLARE_WRITE_LINE_MEMBER( write_sda );
31   DECLARE_READ_LINE_MEMBER( read_sda );
32
2233protected:
2334   // device-level overrides
2435   virtual void device_start();
25   virtual void device_reset();
2636
2737   // device_nvram_interface overrides
2838   virtual void nvram_default();
29   virtual void nvram_read(emu_file &file);
30   virtual void nvram_write(emu_file &file);
39   virtual void nvram_read( emu_file &file );
40   virtual void nvram_write( emu_file &file );
3141
32   // device_secure_serial_flash implementations
33   virtual void cs_0();
34   virtual void cs_1();
35   virtual void rst_0();
36   virtual void rst_1();
37   virtual void scl_0();
38   virtual void scl_1();
39   virtual void sda_0();
40   virtual void sda_1();
42private:
43   inline void ATTR_PRINTF( 3, 4 ) verboselog( int n_level, const char *s_fmt, ... );
44   UINT8 *password();
45   void password_ok();
46   void load_address();
47   int data_offset();
4148
42   // internal state
43   enum {
44      SIZE_WRITE_BUFFER = 8,
45      SIZE_RESPONSE_TO_RESET = 4,
46      SIZE_WRITE_PASSWORD = 8,
47      SIZE_READ_PASSWORD = 8,
48      SIZE_CONFIGURATION_PASSWORD = 8,
49      SIZE_CONFIGURATION_REGISTERS = 8,
50      SIZE_DATA = 512,
51
49   enum configuration_register_t
50   {
5251      CONFIG_BCR1 = 0,
5352      CONFIG_BCR2 = 1,
5453      CONFIG_CR = 2,
5554      CONFIG_RR = 3,
5655      CONFIG_RC = 4,
56   };
5757
58   enum bcr_t
59   {
5860      BCR_X = 8,
5961      BCR_Y = 4,
6062      BCR_Z = 2,
61      BCR_T = 1,
63      BCR_T = 1
64   };
6265
66   enum command_t
67   {
6368      COMMAND_WRITE = 0x00,
6469      COMMAND_READ = 0x20,
6570      COMMAND_WRITE_USE_CONFIGURATION_PASSWORD = 0x40,
6671      COMMAND_READ_USE_CONFIGURATION_PASSWORD = 0x60,
67      COMMAND_CONFIGURATION = 0x80,
72      COMMAND_CONFIGURATION = 0x80
73   };
6874
75   enum configuration_t
76   {
6977      CONFIGURATION_PROGRAM_WRITE_PASSWORD = 0x00,
7078      CONFIGURATION_PROGRAM_READ_PASSWORD = 0x10,
7179      CONFIGURATION_PROGRAM_CONFIGURATION_PASSWORD = 0x20,
r26479r26480
7785      CONFIGURATION_MASS_ERASE = 0x80
7886   };
7987
80   enum {
88   enum state_t
89   {
8190      STATE_STOP,
8291      STATE_RESPONSE_TO_RESET,
8392      STATE_LOAD_COMMAND,
r26479r26480
9099      STATE_WRITE_CONFIGURATION_REGISTERS
91100   };
92101
93   int state, bit, byte, address;
94   UINT8 command, shift;
95   UINT8 write_buffer[SIZE_WRITE_BUFFER];
96   UINT8 response_to_reset[SIZE_RESPONSE_TO_RESET];
97   UINT8 write_password[SIZE_WRITE_PASSWORD];
98   UINT8 read_password[SIZE_READ_PASSWORD];
99   UINT8 configuration_password[SIZE_CONFIGURATION_PASSWORD];
100   UINT8 configuration_registers[SIZE_CONFIGURATION_REGISTERS];
101   UINT8 data[SIZE_DATA];
102
103   UINT8 *password();
104   void password_ok();
105   void load_address();
106   int data_offset();
107
108private:
109   inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ...);
102   // internal state
103   int m_cs;
104   int m_rst;
105   int m_scl;
106   int m_sdaw;
107   int m_sdar;
108   int m_state;
109   int m_shift;
110   int m_bit;
111   int m_byte;
112   int m_command;
113   int m_address;
114   UINT8 m_write_buffer[ 8 ];
115   UINT8 m_response_to_reset[ 4 ];
116   UINT8 m_write_password[ 8 ];
117   UINT8 m_read_password[ 8 ];
118   UINT8 m_configuration_password[ 8 ];
119   UINT8 m_configuration_registers[ 8 ];
120   UINT8 m_data[ 512 ];
110121};
111122
112123
trunk/src/emu/machine/machine.mak
r26479r26480
14721472#-------------------------------------------------
14731473
14741474ifneq ($(filter X76F041,$(MACHINES)),)
1475MACHINES += SECFLASH
14761475MACHINEOBJS += $(MACHINEOBJ)/x76f041.o
14771476endif
14781477
r26479r26480
14821481#-------------------------------------------------
14831482
14841483ifneq ($(filter X76F100,$(MACHINES)),)
1485MACHINES += SECFLASH
14861484MACHINEOBJS += $(MACHINEOBJ)/x76f100.o
14871485endif
14881486
r26479r26480
15511549
15521550#-------------------------------------------------
15531551#
1554#@src/emu/machine/secflash.h,MACHINES += SECFLASH
1555#-------------------------------------------------
1556
1557ifneq ($(filter SECFLASH,$(MACHINES)),)
1558MACHINEOBJS += $(MACHINEOBJ)/secflash.o
1559endif
1560
1561#-------------------------------------------------
1562#
15631552#@src/emu/machine/pccard.h,MACHINES += PCCARD
15641553#-------------------------------------------------
15651554
trunk/src/emu/machine/x76f100.c
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/*
24 * x76f100.c
35 *
r26479r26480
1214#include "emu.h"
1315#include "machine/x76f100.h"
1416
15#define VERBOSE_LEVEL 0
17#define VERBOSE_LEVEL ( 0 )
1618
17inline void ATTR_PRINTF(3,4) x76f100_device::verboselog(int n_level, const char *s_fmt, ...)
19inline void ATTR_PRINTF( 3, 4 ) x76f100_device::verboselog( int n_level, const char *s_fmt, ... )
1820{
19   if(VERBOSE_LEVEL >= n_level)
21   if( VERBOSE_LEVEL >= n_level )
2022   {
2123      va_list v;
22      char buf[32768];
23      va_start(v, s_fmt);
24      vsprintf(buf, s_fmt, v);
25      va_end(v);
26      logerror("x76f100 %s %s: %s", tag(), machine().describe_context(), buf);
24      char buf[ 32768 ];
25      va_start( v, s_fmt );
26      vsprintf( buf, s_fmt, v );
27      va_end( v );
28      logerror( "%s: x76f100(%s) %s", machine().describe_context(), tag(), buf );
2729   }
2830}
2931
3032// device type definition
3133const device_type X76F100 = &device_creator<x76f100_device>;
3234
33x76f100_device::x76f100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
34   : device_secure_serial_flash(mconfig, X76F100, "X76F100", tag, owner, clock, "x76f100", __FILE__)
35x76f100_device::x76f100_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock )
36   : device_t( mconfig, X76F100, "X76F100", tag, owner, clock, "x76f100", __FILE__ ),
37   device_nvram_interface(mconfig, *this),
38   m_cs( 0 ),
39   m_rst( 0 ),
40   m_scl( 0 ),
41   m_sdaw( 0 ),
42   m_sdar( 0 ),
43   m_state( STATE_STOP ),
44   m_shift( 0 ),
45   m_bit( 0 ),
46   m_byte( 0 ),
47   m_command( 0 )
3548{
3649}
3750
3851void x76f100_device::device_start()
3952{
40   device_secure_serial_flash::device_start();
41   save_item(NAME(state));
42   save_item(NAME(shift));
43   save_item(NAME(bit));
44   save_item(NAME(byte));
45   save_item(NAME(command));
46   save_item(NAME(write_buffer));
47   save_item(NAME(response_to_reset));
48   save_item(NAME(write_password));
49   save_item(NAME(read_password));
50   save_item(NAME(data));
51}
53   memset( m_write_buffer, 0, sizeof( m_write_buffer ) );
5254
53void x76f100_device::device_reset()
54{
55   device_secure_serial_flash::device_reset();
56   state = STATE_STOP;
57   shift = 0;
58   bit = 0;
59   byte = 0;
60   command = 0;
61   memset(write_buffer, 0, SIZE_WRITE_BUFFER);
55   save_item( NAME( m_cs ) );
56   save_item( NAME( m_rst ) );
57   save_item( NAME( m_scl ) );
58   save_item( NAME( m_sdaw ) );
59   save_item( NAME( m_sdar ) );
60   save_item( NAME( m_state ) );
61   save_item( NAME( m_shift ) );
62   save_item( NAME( m_bit ) );
63   save_item( NAME( m_byte ) );
64   save_item( NAME( m_command ) );
65   save_item( NAME( m_write_buffer ) );
66   save_item( NAME( m_response_to_reset ) );
67   save_item( NAME( m_write_password ) );
68   save_item( NAME( m_read_password ) );
69   save_item( NAME( m_data ) );
6270}
6371
64void x76f100_device::nvram_default()
72WRITE_LINE_MEMBER( x76f100_device::write_cs )
6573{
66   // region always wins
67   if(m_region)
74   if( m_cs != state )
6875   {
69      // Ensure the size is correct though
70      if(m_region->bytes() != SIZE_RESPONSE_TO_RESET+SIZE_WRITE_PASSWORD+SIZE_READ_PASSWORD+SIZE_DATA)
71         logerror("x76f100 %s: Wrong region length for initialization data, expected 0x%x, got 0x%x\n",
72                  tag(),
73                  SIZE_RESPONSE_TO_RESET+SIZE_WRITE_PASSWORD+SIZE_READ_PASSWORD+SIZE_DATA,
74                  m_region->bytes());
75      else {
76         UINT8 *rb = m_region->base();
77         int offset = 0;
78         memcpy(response_to_reset, rb + offset, SIZE_RESPONSE_TO_RESET); offset += SIZE_RESPONSE_TO_RESET;
79         memcpy(write_password,    rb + offset, SIZE_WRITE_PASSWORD); offset += SIZE_WRITE_PASSWORD;
80         memcpy(read_password,     rb + offset, SIZE_READ_PASSWORD); offset += SIZE_READ_PASSWORD;
81         memcpy(data,              rb + offset, SIZE_DATA); offset += SIZE_DATA;
82         return;
83      }
76      verboselog( 2, "cs=%d\n", state );
8477   }
8578
86   // That chip isn't really usable without the passwords, so bitch
87   // if there's no region
88   logerror("x76f100 %s: Warning, no default data provided, chip is unusable.\n", tag());
89   memset(response_to_reset, 0, SIZE_RESPONSE_TO_RESET);
90   memset(write_password,    0, SIZE_WRITE_PASSWORD);
91   memset(read_password,     0, SIZE_READ_PASSWORD);
92   memset(data,              0, SIZE_DATA);
93}
79   if( m_cs != 0 && state == 0 )
80   {
81      /* enable chip */
82      m_state = STATE_STOP;
83   }
9484
95void x76f100_device::cs_0()
96{
97   /* enable chip */
98   state = STATE_STOP;
99}
85   if( m_cs == 0 && state != 0 )
86   {
87      /* disable chip */
88      m_state = STATE_STOP;
89      /* high impendence? */
90      m_sdar = 0;
91   }
10092
101void x76f100_device::cs_1()
102{
103   /* disable chip */
104   state = STATE_STOP;
105   /* high impendence? */
106   sdar = 0;
93   m_cs = state;
10794}
10895
109void x76f100_device::rst_0()
96WRITE_LINE_MEMBER( x76f100_device::write_rst )
11097{
111}
98   if( m_rst != state )
99   {
100      verboselog( 2, "rst=%d\n", state );
101   }
112102
113void x76f100_device::rst_1()
114{
115   if(!cs) {
116      verboselog(1, "goto response to reset\n");
117      state = STATE_RESPONSE_TO_RESET;
118      bit = 0;
119      byte = 0;
103   if( m_rst == 0 && state != 0 && m_cs == 0 )
104   {
105      verboselog( 1, "goto response to reset\n" );
106      m_state = STATE_RESPONSE_TO_RESET;
107      m_bit = 0;
108      m_byte = 0;
120109   }
110
111   m_rst = state;
121112}
122113
123114UINT8 *x76f100_device::password()
124115{
125   if((command & 0xe1) == COMMAND_READ)
116   if( ( m_command & 0xe1 ) == COMMAND_READ )
126117   {
127      return read_password;
118      return m_read_password;
128119   }
129120
130   return write_password;
121   return m_write_password;
131122}
132123
133124void x76f100_device::password_ok()
134125{
135   if((command & 0xe1) == COMMAND_READ)
126   if( ( m_command & 0xe1 ) == COMMAND_READ )
136127   {
137      state = STATE_READ_DATA;
128      m_state = STATE_READ_DATA;
138129   }
139   else if((command & 0xe1) == COMMAND_WRITE)
130   else if( ( m_command & 0xe1 ) == COMMAND_WRITE )
140131   {
141      state = STATE_WRITE_DATA;
132      m_state = STATE_WRITE_DATA;
142133   }
143134   else
144135   {
r26479r26480
148139
149140int x76f100_device::data_offset()
150141{
151   int block_offset = (command >> 1) & 0x0f;
142   int block_offset = ( m_command >> 1 ) & 0x0f;
152143
153   return block_offset * SIZE_WRITE_BUFFER + byte;
144   return ( block_offset * sizeof( m_write_buffer ) ) + m_byte;
154145}
155146
156void x76f100_device::scl_0()
147WRITE_LINE_MEMBER( x76f100_device::write_scl )
157148{
158   if(cs)
159      return;
149   if( m_scl != state )
150   {
151      verboselog( 2, "scl=%d\n", state );
152   }
160153
161   switch(state) {
162   case STATE_RESPONSE_TO_RESET:
163      if(bit == 0) {
164         shift = response_to_reset[byte];
165         verboselog(1, "<- response_to_reset[%d]: %02x\n", byte, shift);
166      }
154   if( m_cs == 0 )
155   {
156      switch( m_state )
157      {
158      case STATE_STOP:
159         break;
167160
168      sdar = shift & 1;
169      shift >>= 1;
170      bit++;
161      case STATE_RESPONSE_TO_RESET:
162         if( m_scl != 0 && state == 0 )
163         {
164            if( m_bit == 0 )
165            {
166               m_shift = m_response_to_reset[ m_byte ];
167               verboselog( 1, "<- response_to_reset[%d]: %02x\n", m_byte, m_shift );
168            }
171169
172      if(bit == 8) {
173         bit = 0;
174         byte++;
175         if(byte == 4)
176            byte = 0;
170            m_sdar = m_shift & 1;
171            m_shift >>= 1;
172            m_bit++;
173
174            if( m_bit == 8 )
175            {
176               m_bit = 0;
177               m_byte++;
178
179               if( m_byte == sizeof( m_response_to_reset ) )
180               {
181                  m_byte = 0;
182               }
183            }
184         }
185         break;
186
187      case STATE_LOAD_COMMAND:
188      case STATE_LOAD_PASSWORD:
189      case STATE_VERIFY_PASSWORD:
190      case STATE_WRITE_DATA:
191         if( m_scl == 0 && state != 0 )
192         {
193            if( m_bit < 8 )
194            {
195               verboselog( 2, "clock\n" );
196               m_shift <<= 1;
197
198               if( m_sdaw != 0 )
199               {
200                  m_shift |= 1;
201               }
202
203               m_bit++;
204            }
205            else
206            {
207               m_sdar = 0;
208
209               switch( m_state )
210               {
211               case STATE_LOAD_COMMAND:
212                  m_command = m_shift;
213                  verboselog( 1, "-> command: %02x\n", m_command );
214                  /* todo: verify command is valid? */
215                  m_state = STATE_LOAD_PASSWORD;
216                  break;
217
218               case STATE_LOAD_PASSWORD:
219                  verboselog( 1, "-> password: %02x\n", m_shift );
220                  m_write_buffer[ m_byte++ ] = m_shift;
221
222                  if( m_byte == sizeof( m_write_buffer ) )
223                  {
224                     m_state = STATE_VERIFY_PASSWORD;
225                  }
226                  break;
227
228               case STATE_VERIFY_PASSWORD:
229                  verboselog( 1, "-> verify password: %02x\n", m_shift );
230
231                  /* todo: this should probably be handled as a command */
232                  if( m_shift == COMMAND_ACK_PASSWORD )
233                  {
234                     /* todo: this should take 10ms before it returns ok. */
235                     if( memcmp( password(), m_write_buffer, sizeof( m_write_buffer ) ) == 0 )
236                     {
237                        password_ok();
238                     }
239                     else
240                     {
241                        m_sdar = 1;
242                     }
243                  }
244                  break;
245
246               case STATE_WRITE_DATA:
247                  verboselog( 2, "-> data: %02x\n", m_shift );
248                  m_write_buffer[ m_byte++ ] = m_shift;
249
250                  if( m_byte == sizeof( m_write_buffer ) )
251                  {
252                     for( m_byte = 0; m_byte < sizeof( m_write_buffer ); m_byte++ )
253                     {
254                        int offset = data_offset();
255                        verboselog( 1, "-> data[ %03x ]: %02x\n", offset, m_write_buffer[ m_byte ] );
256                        m_data[ offset ] = m_write_buffer[ m_byte ];
257                     }
258
259                     m_byte = 0;
260
261                     verboselog( 1, "data flushed\n" );
262                  }
263                  break;
264               }
265
266               m_bit = 0;
267               m_shift = 0;
268            }
269         }
270         break;
271
272      case STATE_READ_DATA:
273         if( m_scl == 0 && state != 0 )
274         {
275            if( m_bit < 8 )
276            {
277               if( m_bit == 0 )
278               {
279                  int offset;
280
281                  switch( m_state )
282                  {
283                  case STATE_READ_DATA:
284                     offset = data_offset();
285                     m_shift = m_data[ offset ];
286                     verboselog( 1, "<- data[ %02x ]: %02x\n", offset, m_shift );
287                     break;
288                  }
289               }
290
291               m_sdar = ( m_shift >> 7 ) & 1;
292               m_shift <<= 1;
293               m_bit++;
294            }
295            else
296            {
297               m_bit = 0;
298               m_sdar = 0;
299
300               if( m_sdaw == 0 )
301               {
302                  verboselog( 2, "ack <-\n" );
303                  m_byte++;
304               }
305               else
306               {
307                  verboselog( 2, "nak <-\n" );
308               }
309            }
310         }
311         break;
177312      }
178      break;
179313   }
314
315   m_scl = state;
180316}
181317
182void x76f100_device::scl_1()
318WRITE_LINE_MEMBER( x76f100_device::write_sda )
183319{
184   if(cs)
185      return;
320   if( m_sdaw != state )
321   {
322      verboselog( 2, "sdaw=%d\n", state );
323   }
186324
187   switch(state) {
188   case STATE_RESPONSE_TO_RESET:
189      break;
325   if( m_cs == 0 && m_scl != 0 )
326   {
327      if( m_sdaw == 0 && state != 0 )
328      {
329         verboselog( 1, "goto stop\n" );
330         m_state = STATE_STOP;
331         m_sdar = 0;
332      }
190333
191   case STATE_LOAD_COMMAND:
192   case STATE_LOAD_PASSWORD:
193   case STATE_VERIFY_PASSWORD:
194   case STATE_WRITE_DATA:
195      if(bit < 8) {
196         verboselog(2, "clock\n");
197         shift <<= 1;
198         if(sdaw)
199            shift |= 1;
200         bit++;
201      } else {
202         switch(state) {
203         case STATE_LOAD_COMMAND:
204            verboselog(1, "-> command: %02x\n", command);
205            sdar = false;
206            command = shift;
207            /* todo: verify command is valid? */
208            state = STATE_LOAD_PASSWORD;
209            bit = 0;
210            shift = 0;
334      if( m_sdaw != 0 && state == 0 )
335      {
336         switch( m_state )
337         {
338         case STATE_STOP:
339            verboselog( 1, "goto start\n" );
340            m_state = STATE_LOAD_COMMAND;
211341            break;
212342
213343         case STATE_LOAD_PASSWORD:
214            verboselog(1, "-> password: %02x\n", shift);
215            sdar = false;
216            write_buffer[byte++] = shift;
217            if(byte == SIZE_WRITE_BUFFER)
218               state = STATE_VERIFY_PASSWORD;
219            bit = 0;
220            shift = 0;
344            /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */
345            verboselog( 1, "goto start\n" );
221346            break;
222347
223         case STATE_VERIFY_PASSWORD:
224            verboselog(1, "-> verify password: %02x\n", shift);
225            sdar = false;
226            /* todo: this should probably be handled as a command */
227            if(shift == COMMAND_ACK_PASSWORD) {
228               /* todo: this should take 10ms before it returns ok. */
229               if(!memcmp(password(), write_buffer, SIZE_WRITE_BUFFER))
230                  password_ok();
231               else
232                  sdar = true;
233            }
234            bit = 0;
235            shift = 0;
348         case STATE_READ_DATA:
349            verboselog( 1, "continue reading??\n" );
350//              verboselog( 1, "goto load address\n" );
351//              m_state = STATE_LOAD_ADDRESS;
236352            break;
237353
238         case STATE_WRITE_DATA:
239            verboselog(1, "-> data: %02x\n", shift );
240            sdar = false;
241            write_buffer[byte++] = shift;
242            if(byte == SIZE_WRITE_BUFFER) {
243               for(byte = 0; byte < SIZE_WRITE_BUFFER; byte++)
244                  data[data_offset()] = write_buffer[byte];
245               byte = 0;
246            }
247            bit = 0;
248            shift = 0;
354         default:
355            verboselog( 1, "skipped start (default)\n" );
249356            break;
250357         }
251      }
252      break;
253358
254   case STATE_READ_DATA:
255      if(bit < 8) {
256         if(bit == 0) {
257            shift = data[data_offset()];
258            verboselog(1, "<- data: %02x\n", shift );
259         }
260         sdar = (shift >> 7) & 1;
261         shift <<= 1;
262         bit++;
263      } else {
264         bit = 0;
265         sdar = false;
266         if(!sdaw) {
267            verboselog(2, "ack <-\n");
268            byte++;
269         } else {
270            verboselog(2, "nak <-\n");
271         }
359         m_bit = 0;
360         m_byte = 0;
361         m_shift = 0;
362         m_sdar = 0;
272363      }
273      break;
274364   }
365
366   m_sdaw = state;
275367}
276368
277void x76f100_device::sda_0()
369READ_LINE_MEMBER( x76f100_device::read_sda )
278370{
279   if(cs || !scl)
280      return;
371   if( m_cs != 0 )
372   {
373      verboselog( 2, "not selected\n" );
374      return 1;
375   }
281376
282   switch(state) {
283   case STATE_STOP:
284      state = STATE_LOAD_COMMAND;
285      break;
377   verboselog( 2, "sdar=%d\n", m_sdar );
378   return m_sdar;
379}
286380
287   case STATE_LOAD_PASSWORD:
288      /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */
289      break;
381void x76f100_device::nvram_default()
382{
383   m_response_to_reset[ 0 ] = 0x19;
384   m_response_to_reset[ 1 ] = 0x00;
385   m_response_to_reset[ 2 ] = 0xaa;
386   m_response_to_reset[ 3 ] = 0x55,
290387
291   case STATE_READ_DATA:
292      //              c->state = STATE_LOAD_ADDRESS;
293      break;
388   memset( m_write_password, 0, sizeof( m_write_password ) );
389   memset( m_read_password, 0, sizeof( m_read_password ) );
390   memset( m_data, 0, sizeof( m_data ) );
294391
295   default:
296      break;
392   int expected_size = sizeof( m_response_to_reset ) + sizeof( m_write_password ) + sizeof( m_read_password ) + sizeof( m_data );
393
394   if( !m_region )
395   {
396      logerror( "x76f100(%s) region not found\n", tag() );
297397   }
398   else if( m_region->bytes() != expected_size )
399   {
400      logerror("x76f100(%s) region length 0x%x expected 0x%x\n", tag(), m_region->bytes(), expected_size );
401   }
402   else
403   {
404      UINT8 *region = m_region->base();
298405
299   bit = 0;
300   byte = 0;
301   shift = 0;
302   sdar = false;
406      memcpy( m_response_to_reset, region, sizeof( m_response_to_reset )); region += sizeof( m_response_to_reset );
407      memcpy( m_write_password, region, sizeof( m_write_password )); region += sizeof( m_write_password );
408      memcpy( m_read_password, region, sizeof( m_read_password )); region += sizeof( m_read_password );
409      memcpy( m_data, region, sizeof( m_data )); region += sizeof( m_data );
410   }
303411}
304412
305void x76f100_device::sda_1()
413void x76f100_device::nvram_read( emu_file &file )
306414{
307   if(cs || !scl)
308      return;
309
310   state = STATE_STOP;
311   sdar = false;
415   file.read( m_response_to_reset, sizeof( m_response_to_reset ) );
416   file.read( m_write_password, sizeof( m_write_password ) );
417   file.read( m_read_password, sizeof( m_read_password ) );
418   file.read( m_data, sizeof( m_data ) );
312419}
313420
314void x76f100_device::nvram_read(emu_file &file)
421void x76f100_device::nvram_write( emu_file &file )
315422{
316   file.read(response_to_reset, SIZE_RESPONSE_TO_RESET);
317   file.read(write_password,    SIZE_WRITE_PASSWORD);
318   file.read(read_password,     SIZE_READ_PASSWORD);
319   file.read(data,              SIZE_DATA);
423   file.write( m_response_to_reset, sizeof( m_response_to_reset ) );
424   file.write( m_write_password, sizeof( m_write_password ) );
425   file.write( m_read_password, sizeof( m_read_password ) );
426   file.write( m_data, sizeof( m_data ) );
320427}
321
322void x76f100_device::nvram_write(emu_file &file)
323{
324   file.write(response_to_reset, SIZE_RESPONSE_TO_RESET);
325   file.write(write_password,    SIZE_WRITE_PASSWORD);
326   file.write(read_password,     SIZE_READ_PASSWORD);
327   file.write(data,              SIZE_DATA);
328}
trunk/src/emu/machine/x76f100.h
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/*
24 * x76f100.h
35 *
r26479r26480
57 *
68 */
79
10#pragma once
11
812#ifndef __X76F100_H__
913#define __X76F100_H__
1014
11#define MCFG_X76F100_ADD(_tag) \
12   MCFG_DEVICE_ADD(_tag, X76F100, 0)
15#include "emu.h"
1316
14#include "machine/secflash.h"
17#define MCFG_X76F100_ADD( _tag ) \
18   MCFG_DEVICE_ADD( _tag, X76F100, 0 )
1519
16class x76f100_device : public device_secure_serial_flash
20class x76f100_device : public device_t,
21   public device_nvram_interface
1722{
1823public:
1924   // construction/destruction
20   x76f100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
25   x76f100_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock );
2126
27   DECLARE_WRITE_LINE_MEMBER( write_cs );
28   DECLARE_WRITE_LINE_MEMBER( write_rst );
29   DECLARE_WRITE_LINE_MEMBER( write_scl );
30   DECLARE_WRITE_LINE_MEMBER( write_sda );
31   DECLARE_READ_LINE_MEMBER( read_sda );
32
2233protected:
2334   // device-level overrides
2435   virtual void device_start();
25   virtual void device_reset();
2636
2737   // device_nvram_interface overrides
2838   virtual void nvram_default();
29   virtual void nvram_read(emu_file &file);
30   virtual void nvram_write(emu_file &file);
39   virtual void nvram_read( emu_file &file );
40   virtual void nvram_write( emu_file &file );
3141
32   // device_secure_serial_flash implementations
33   virtual void cs_0();
34   virtual void cs_1();
35   virtual void rst_0();
36   virtual void rst_1();
37   virtual void scl_0();
38   virtual void scl_1();
39   virtual void sda_0();
40   virtual void sda_1();
42private:
43   inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ...);
4144
42   // internal state
43   enum {
44      SIZE_WRITE_BUFFER = 8,
45      SIZE_RESPONSE_TO_RESET = 4,
46      SIZE_WRITE_PASSWORD = 8,
47      SIZE_READ_PASSWORD = 8,
48      SIZE_DATA = 112,
45   UINT8 *password();
46   void password_ok();
47   int data_offset();
4948
49   enum command_t
50   {
5051      COMMAND_WRITE = 0x80,
5152      COMMAND_READ = 0x81,
5253      COMMAND_CHANGE_WRITE_PASSWORD = 0xfc,
r26479r26480
5455      COMMAND_ACK_PASSWORD = 0x55
5556   };
5657
57   enum {
58   enum state_t
59   {
5860      STATE_STOP,
5961      STATE_RESPONSE_TO_RESET,
6062      STATE_LOAD_COMMAND,
r26479r26480
6466      STATE_WRITE_DATA
6567   };
6668
67   int state, bit, byte;
68   UINT8 command, shift;
69   UINT8 write_buffer[SIZE_WRITE_BUFFER];
70   UINT8 response_to_reset[SIZE_RESPONSE_TO_RESET];
71   UINT8 write_password[SIZE_WRITE_PASSWORD];
72   UINT8 read_password[SIZE_READ_PASSWORD];
73   UINT8 data[SIZE_DATA];
74
75   UINT8 *password();
76   void password_ok();
77   int data_offset();
78
79private:
80   inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ...);
69   // internal state
70   int m_cs;
71   int m_rst;
72   int m_scl;
73   int m_sdaw;
74   int m_sdar;
75   int m_state;
76   int m_shift;
77   int m_bit;
78   int m_byte;
79   int m_command;
80   UINT8 m_write_buffer[ 8 ];
81   UINT8 m_response_to_reset[ 4 ];
82   UINT8 m_write_password[ 8 ];
83   UINT8 m_read_password[ 8 ];
84   UINT8 m_data[ 112 ];
8185};
8286
83
8487// device type definition
8588extern const device_type X76F100;
8689
trunk/src/emu/machine/i2cmem.h
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/***************************************************************************
24
35    i2cmem.h
trunk/src/emu/machine/x76f041.c
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/*
24 * x76f041.c
35 *
r26479r26480
1416#include "emu.h"
1517#include "machine/x76f041.h"
1618
17#define VERBOSE_LEVEL 0
19#define VERBOSE_LEVEL ( 0 )
1820
19inline void ATTR_PRINTF(3,4) x76f041_device::verboselog(int n_level, const char *s_fmt, ...)
21inline void ATTR_PRINTF( 3, 4 ) x76f041_device::verboselog( int n_level, const char *s_fmt, ... )
2022{
21   if(VERBOSE_LEVEL >= n_level)
23   if( VERBOSE_LEVEL >= n_level )
2224   {
2325      va_list v;
24      char buf[32768];
25      va_start(v, s_fmt);
26      vsprintf(buf, s_fmt, v);
27      va_end(v);
28      logerror("x76f041 %s %s: %s", tag(), machine().describe_context(), buf);
26      char buf[ 32768 ];
27      va_start( v, s_fmt );
28      vsprintf( buf, s_fmt, v );
29      va_end( v );
30      logerror( "%s: x76f041(%s) %s", machine().describe_context(), tag(), buf );
2931   }
3032}
3133
3234// device type definition
3335const device_type X76F041 = &device_creator<x76f041_device>;
3436
35x76f041_device::x76f041_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
36   : device_secure_serial_flash(mconfig, X76F041, "X76F041", tag, owner, clock, "x76f041", __FILE__)
37x76f041_device::x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock )
38   : device_t( mconfig, X76F041, "X76F041", tag, owner, clock, "x76f041", __FILE__ ),
39   device_nvram_interface(mconfig, *this),
40   m_cs( 0 ),
41   m_rst( 0 ),
42   m_scl( 0 ),
43   m_sdaw( 0 ),
44   m_sdar( 0 ),
45   m_state( STATE_STOP ),
46   m_shift( 0 ),
47   m_bit( 0 ),
48   m_byte( 0 ),
49   m_command( 0 ),
50   m_address( 0 )
3751{
3852}
3953
4054void x76f041_device::device_start()
4155{
42   device_secure_serial_flash::device_start();
43   save_item(NAME(state));
44   save_item(NAME(shift));
45   save_item(NAME(bit));
46   save_item(NAME(byte));
47   save_item(NAME(command));
48   save_item(NAME(address));
49   save_item(NAME(write_buffer));
50   save_item(NAME(response_to_reset));
51   save_item(NAME(write_password));
52   save_item(NAME(read_password));
53   save_item(NAME(configuration_password));
54   save_item(NAME(configuration_registers));
55   save_item(NAME(data));
56}
56   memset( m_write_buffer, 0, sizeof( m_write_buffer ) );
5757
58void x76f041_device::device_reset()
59{
60   device_secure_serial_flash::device_reset();
61   state = STATE_STOP;
62   shift = 0;
63   bit = 0;
64   byte = 0;
65   command = 0;
66   address = 0;
67   memset(write_buffer, 0, SIZE_WRITE_BUFFER);
58   save_item( NAME( m_cs ) );
59   save_item( NAME( m_rst ) );
60   save_item( NAME( m_scl ) );
61   save_item( NAME( m_sdaw ) );
62   save_item( NAME( m_sdar ) );
63   save_item( NAME( m_state ) );
64   save_item( NAME( m_shift ) );
65   save_item( NAME( m_bit ) );
66   save_item( NAME( m_byte ) );
67   save_item( NAME( m_command ) );
68   save_item( NAME( m_address ) );
69   save_item( NAME( m_write_buffer ) );
70   save_item( NAME( m_response_to_reset ) );
71   save_item( NAME( m_write_password ) );
72   save_item( NAME( m_read_password ) );
73   save_item( NAME( m_configuration_password ) );
74   save_item( NAME( m_configuration_registers ) );
75   save_item( NAME( m_data ) );
6876}
6977
70void x76f041_device::nvram_default()
78WRITE_LINE_MEMBER( x76f041_device::write_cs )
7179{
72   // region always wins
73   if(m_region)
80   if( m_cs != state )
7481   {
75      // Ensure the size is correct though
76      if(m_region->bytes() != SIZE_RESPONSE_TO_RESET+SIZE_WRITE_PASSWORD+
77         SIZE_READ_PASSWORD+SIZE_CONFIGURATION_PASSWORD+SIZE_CONFIGURATION_REGISTERS+SIZE_DATA)
78         logerror("X76F041: Wrong region length for initialization data, expected 0x%x, got 0x%x\n",
79                  SIZE_RESPONSE_TO_RESET+SIZE_WRITE_PASSWORD+
80                  SIZE_READ_PASSWORD+SIZE_CONFIGURATION_PASSWORD+SIZE_CONFIGURATION_REGISTERS+SIZE_DATA,
81                  m_region->bytes());
82      else {
83         UINT8 *rb = m_region->base();
84         int offset = 0;
85         memcpy(response_to_reset,       rb + offset, SIZE_RESPONSE_TO_RESET); offset += SIZE_RESPONSE_TO_RESET;
86         memcpy(write_password,          rb + offset, SIZE_WRITE_PASSWORD); offset += SIZE_WRITE_PASSWORD;
87         memcpy(read_password,           rb + offset, SIZE_READ_PASSWORD); offset += SIZE_READ_PASSWORD;
88         memcpy(configuration_password,  rb + offset, SIZE_CONFIGURATION_PASSWORD); offset += SIZE_CONFIGURATION_PASSWORD;
89         memcpy(configuration_registers, rb + offset, SIZE_CONFIGURATION_REGISTERS); offset += SIZE_CONFIGURATION_REGISTERS;
90         memcpy(data,                    rb + offset, SIZE_DATA); offset += SIZE_DATA;
91         return;
92      }
82      verboselog( 2, "cs=%d\n", state );
9383   }
9484
95   // That chip isn't really usable without the passwords, so bitch
96   // if there's no region
97   logerror("X76F041: Warning, no default data provided, chip is unusable.\n");
98   memset(response_to_reset,       0, SIZE_RESPONSE_TO_RESET);
99   memset(write_password,          0, SIZE_WRITE_PASSWORD);
100   memset(read_password,           0, SIZE_READ_PASSWORD);
101   memset(configuration_password,  0, SIZE_CONFIGURATION_PASSWORD);
102   memset(configuration_registers, 0, SIZE_CONFIGURATION_REGISTERS);
103   memset(data,                    0, SIZE_DATA);
104}
85   if( m_cs != 0 && state == 0 )
86   {
87      /* enable chip */
88      m_state = STATE_STOP;
89   }
10590
106void x76f041_device::cs_0()
107{
108   /* enable chip */
109   state = STATE_STOP;
110}
91   if( m_cs == 0 && state != 0 )
92   {
93      /* disable chip */
94      m_state = STATE_STOP;
95      /* high impendence? */
96      m_sdar = 0;
97   }
11198
112void x76f041_device::cs_1()
113{
114   /* disable chip */
115   state = STATE_STOP;
116   /* high impendence? */
117   sdar = false;
99   m_cs = state;
118100}
119101
120void x76f041_device::rst_0()
102WRITE_LINE_MEMBER( x76f041_device::write_rst )
121103{
122}
104   if( m_rst != state )
105   {
106      verboselog( 2, "rst=%d\n", state );
107   }
123108
124void x76f041_device::rst_1()
125{
126   if(!cs) {
127      verboselog(1, "goto response to reset\n");
128      state = STATE_RESPONSE_TO_RESET;
129      bit = 0;
130      byte = 0;
109   if( m_rst == 0 && state != 0 && m_cs == 0 )
110   {
111      verboselog( 1, "goto response to reset\n" );
112      m_state = STATE_RESPONSE_TO_RESET;
113      m_bit = 0;
114      m_byte = 0;
131115   }
116
117   m_rst = state;
132118}
133119
134120UINT8 *x76f041_device::password()
135121{
136   switch(command & 0xe0) {
122   switch( m_command & 0xe0 )
123   {
137124   case COMMAND_WRITE:
138      return write_password;
125      return m_write_password;
126
139127   case COMMAND_READ:
140      return read_password;
128      return m_read_password;
129
141130   default:
142      return configuration_password;
131      return m_configuration_password;
143132   }
144133}
145134
146135void x76f041_device::password_ok()
147136{
148   switch(command & 0xe0) {
137   switch( m_command & 0xe0 )
138   {
149139   case COMMAND_WRITE:
150      state = STATE_WRITE_DATA;
140      m_state = STATE_WRITE_DATA;
151141      break;
152142   case COMMAND_READ:
153      state = STATE_READ_DATA;
143      m_state = STATE_READ_DATA;
154144      break;
155145   case COMMAND_WRITE_USE_CONFIGURATION_PASSWORD:
156      state = STATE_WRITE_DATA;
146      m_state = STATE_WRITE_DATA;
157147      break;
158148   case COMMAND_READ_USE_CONFIGURATION_PASSWORD:
159      state = STATE_READ_DATA;
149      m_state = STATE_READ_DATA;
160150      break;
161151   case COMMAND_CONFIGURATION:
162      switch( address ) {
152      switch( m_address )
153      {
163154      case CONFIGURATION_PROGRAM_WRITE_PASSWORD:
164155         break;
165156      case CONFIGURATION_PROGRAM_READ_PASSWORD:
r26479r26480
171162      case CONFIGURATION_RESET_READ_PASSWORD:
172163         break;
173164      case CONFIGURATION_PROGRAM_CONFIGURATION_REGISTERS:
174         state = STATE_WRITE_CONFIGURATION_REGISTERS;
175         byte = 0;
165         m_state = STATE_WRITE_CONFIGURATION_REGISTERS;
166         m_byte = 0;
176167         break;
177168      case CONFIGURATION_READ_CONFIGURATION_REGISTERS:
178         state = STATE_READ_CONFIGURATION_REGISTERS;
179         byte = 0;
169         m_state = STATE_READ_CONFIGURATION_REGISTERS;
170         m_byte = 0;
180171         break;
181172      case CONFIGURATION_MASS_PROGRAM:
182173         break;
r26479r26480
193184   /* todo: handle other bcr bits */
194185   int bcr;
195186
196   address = shift;
187   m_address = m_shift;
197188
198   verboselog(1, "-> address: %02x\n", address);
189   verboselog( 1, "-> address: %02x\n", m_address );
199190
200   if(!(command & 1 ))
201      bcr = configuration_registers[CONFIG_BCR1];
191   if( ( m_command & 1 ) == 0 )
192   {
193      bcr = m_configuration_registers[ CONFIG_BCR1 ];
194   }
202195   else
203      bcr = configuration_registers[CONFIG_BCR2];
204
205   if(address & 0x80)
196   {
197      bcr = m_configuration_registers[ CONFIG_BCR2 ];
198   }
199   if( ( m_address & 0x80 ) != 0 )
200   {
206201      bcr >>= 4;
202   }
207203
208   if(((command & 0xe0) == COMMAND_READ && (bcr & BCR_Z) && (bcr & BCR_T)) ||
209      ((command & 0xe0) == COMMAND_WRITE && (bcr & BCR_Z))) {
204   if( ( ( m_command & 0xe0 ) == COMMAND_READ && ( bcr & BCR_Z ) != 0 && ( bcr & BCR_T ) != 0 ) ||
205      ( ( m_command & 0xe0 ) == COMMAND_WRITE && ( bcr & BCR_Z ) != 0 ) )
206   {
210207      /* todo: find out when this is really checked. */
211      verboselog(1, "command not allowed\n");
212      state = STATE_STOP;
213      sdar = false;
214
215   } else if(((command & 0xe0) == COMMAND_WRITE && !(bcr & BCR_X)) ||
216            ((command & 0xe0) == COMMAND_READ && !(bcr & BCR_Y))) {
217      verboselog(1, "password not required\n");
208      verboselog( 1, "command not allowed\n" );
209      m_state = STATE_STOP;
210      m_sdar = 0;
211   }
212   else if( ( ( m_command & 0xe0 ) == COMMAND_WRITE && ( bcr & BCR_X ) == 0 ) ||
213      ( ( m_command & 0xe0 ) == COMMAND_READ && ( bcr & BCR_Y ) == 0 ) )
214   {
215      verboselog( 1, "password not required\n" );
218216      password_ok();
219
220   } else {
221      verboselog(1, "send password\n");
222      state = STATE_LOAD_PASSWORD;
223      byte = 0;
224217   }
218   else
219   {
220      verboselog( 1, "send password\n" );
221      m_state = STATE_LOAD_PASSWORD;
222      m_byte = 0;
223   }
225224}
226225
227226int x76f041_device::data_offset()
228227{
229   int block_offset = ((command & 1) << 8) + address;
228   int block_offset = ( ( m_command & 1 ) << 8 ) + m_address;
230229
231230   // TODO: confirm block_start doesn't wrap.
232231
233   return (block_offset & 0x180) | ((block_offset + byte) & 0x7f);
232   return ( block_offset & 0x180 ) | ( ( block_offset + m_byte ) & 0x7f );
234233}
235234
236void x76f041_device::scl_0()
235WRITE_LINE_MEMBER( x76f041_device::write_scl )
237236{
238   if(!cs) {
239      switch(state) {
240      case STATE_RESPONSE_TO_RESET:
241         sdar = (response_to_reset[byte] >> bit) & 1;
242         verboselog(2, "in response to reset %d (%d/%d)\n", sdar, byte, bit);
243         bit++;
244         if(bit == 8) {
245            bit = 0;
246            byte++;
247            if( byte == 4 )
248               byte = 0;
249         }
250         break;
251      }
237   if( m_scl != state )
238   {
239      verboselog( 2, "scl=%d\n", state );
252240   }
253}
254241
255void x76f041_device::scl_1()
256{
257   if(!cs) {
258      switch(state) {
242   if( m_cs == 0 )
243   {
244      switch( m_state )
245      {
259246      case STATE_STOP:
260247         break;
248
261249      case STATE_RESPONSE_TO_RESET:
250         if( m_scl != 0 && state == 0 )
251         {
252            m_sdar = ( m_response_to_reset[ m_byte ] >> m_bit ) & 1;
253            verboselog( 2, "in response to reset %d (%d/%d)\n", m_sdar, m_byte, m_bit );
254            m_bit++;
255
256            if( m_bit == 8 )
257            {
258               m_bit = 0;
259               m_byte++;
260
261               if( m_byte == sizeof( m_response_to_reset ) )
262               {
263                  m_byte = 0;
264               }
265            }
266         }
262267         break;
268
263269      case STATE_LOAD_COMMAND:
264270      case STATE_LOAD_ADDRESS:
265271      case STATE_LOAD_PASSWORD:
266272      case STATE_VERIFY_PASSWORD:
267273      case STATE_WRITE_DATA:
268274      case STATE_WRITE_CONFIGURATION_REGISTERS:
269         if(bit < 8) {
270            verboselog(2, "clock\n");
271            shift <<= 1;
272            if(sdaw)
273               shift |= 1;
274            bit++;
275         } else {
276            sdar = false;
275         if( m_scl == 0 && state != 0 )
276         {
277            if( m_bit < 8 )
278            {
279               verboselog( 2, "clock\n" );
280               m_shift <<= 1;
277281
278            switch(state) {
279            case STATE_LOAD_COMMAND:
280               command = shift;
281               verboselog(1, "-> command: %02x\n", command);
282               /* todo: verify command is valid? */
283               state = STATE_LOAD_ADDRESS;
284               break;
285            case STATE_LOAD_ADDRESS:
286               load_address();
287               break;
288            case STATE_LOAD_PASSWORD:
289               verboselog(1, "-> password: %02x\n", shift );
290               write_buffer[byte++] = shift;
291               if(byte == SIZE_WRITE_BUFFER)
292                  state = STATE_VERIFY_PASSWORD;
293               break;
294            case STATE_VERIFY_PASSWORD:
295               verboselog(1, "-> verify password: %02x\n", shift);
296               /* todo: this should probably be handled as a command */
297               if(shift == 0xc0) {
298                  /* todo: this should take 10ms before it returns ok. */
299                  if(!memcmp(password(), write_buffer, SIZE_WRITE_BUFFER))
300                     password_ok();
301                  else
302                     sdar = true;
282               if( m_sdaw != 0 )
283               {
284                  m_shift |= 1;
303285               }
304               break;
305            case STATE_WRITE_DATA:
306               verboselog(1, "-> data: %02x\n", shift);
307               write_buffer[byte++] = shift;
308               if(byte == SIZE_WRITE_BUFFER) {
309                  for(byte = 0; byte < SIZE_WRITE_BUFFER; byte++)
310                     data[data_offset()] = write_buffer[byte];
311                  byte = 0;
312                  verboselog(1, "data flushed\n");
286
287               m_bit++;
288            }
289            else
290            {
291               m_sdar = 0;
292
293               switch( m_state )
294               {
295               case STATE_LOAD_COMMAND:
296                  m_command = m_shift;
297                  verboselog( 1, "-> command: %02x\n", m_command );
298                  /* todo: verify command is valid? */
299                  m_state = STATE_LOAD_ADDRESS;
300                  break;
301
302               case STATE_LOAD_ADDRESS:
303                  load_address();
304                  break;
305
306               case STATE_LOAD_PASSWORD:
307                  verboselog( 1, "-> password: %02x\n", m_shift );
308                  m_write_buffer[ m_byte++ ] = m_shift;
309
310                  if( m_byte == sizeof( m_write_buffer ) )
311                  {
312                     m_state = STATE_VERIFY_PASSWORD;
313                  }
314                  break;
315
316               case STATE_VERIFY_PASSWORD:
317                  verboselog( 1, "-> verify password: %02x\n", m_shift );
318
319                  /* todo: this should probably be handled as a command */
320                  if( m_shift == 0xc0 )
321                  {
322                     /* todo: this should take 10ms before it returns ok. */
323                     if( memcmp( password(), m_write_buffer, sizeof( m_write_buffer ) ) == 0 )
324                     {
325                        password_ok();
326                     }
327                     else
328                     {
329                        m_sdar = 1;
330                     }
331                  }
332                  break;
333
334               case STATE_WRITE_DATA:
335                  verboselog( 2, "-> data: %02x\n", m_shift );
336                  m_write_buffer[ m_byte++ ] = m_shift;
337
338                  if( m_byte == sizeof( m_write_buffer ) )
339                  {
340                     for( m_byte = 0; m_byte < sizeof( m_write_buffer ); m_byte++ )
341                     {
342                        int offset = data_offset();
343                        verboselog( 1, "-> data[ %03x ]: %02x\n", offset, m_write_buffer[ m_byte ] );
344                        m_data[ offset ] = m_write_buffer[ m_byte ];
345                     }
346                     m_byte = 0;
347
348                     verboselog( 1, "data flushed\n" );
349                  }
350                  break;
351
352               case STATE_WRITE_CONFIGURATION_REGISTERS:
353                  verboselog( 1, "-> configuration register[ %d ]: %02x\n", m_byte, m_shift );
354                  /* todo: write after all bytes received? */
355                  m_configuration_registers[ m_byte++ ] = m_shift;
356
357                  if( m_byte == sizeof( m_configuration_registers ) )
358                  {
359                     m_byte = 0;
360                  }
361                  break;
313362               }
314               break;
315            case STATE_WRITE_CONFIGURATION_REGISTERS:
316               verboselog(1, "-> configuration register: %02x\n", shift);
317               /* todo: write after all bytes received? */
318               configuration_registers[byte++] = shift;
319               if(byte == SIZE_CONFIGURATION_REGISTERS)
320                  byte = 0;
321               break;
363
364               m_bit = 0;
365               m_shift = 0;
322366            }
323
324            bit = 0;
325            shift = 0;
326367         }
327368         break;
369
328370      case STATE_READ_DATA:
329371      case STATE_READ_CONFIGURATION_REGISTERS:
330         if(bit < 8) {
331            if(bit == 0) {
332               switch(state) {
333               case STATE_READ_DATA:
334                  shift = data[data_offset()];
335                  verboselog(1, "<- data: %02x\n", shift);
336                  break;
337               case STATE_READ_CONFIGURATION_REGISTERS:
338                  shift = configuration_registers[byte & 7];
339                  verboselog(1, "<- configuration register: %02x\n", shift );
340                  break;
372         if( m_scl == 0 && state != 0 )
373         {
374            if( m_bit < 8 )
375            {
376               if( m_bit == 0 )
377               {
378                  int offset;
379
380                  switch( m_state )
381                  {
382                  case STATE_READ_DATA:
383                     offset = data_offset();
384                     m_shift = m_data[ offset ];
385                     verboselog( 1, "<- data[ %03x ]: %02x\n", offset, m_shift );
386                     break;
387
388                  case STATE_READ_CONFIGURATION_REGISTERS:
389                     offset = m_byte & 7;
390                     m_shift = m_configuration_registers[ offset ];
391                     verboselog( 1, "<- configuration register[ %d ]: %02x\n", offset, m_shift );
392                     break;
393                  }
341394               }
395
396               m_sdar = ( m_shift >> 7 ) & 1;
397               m_shift <<= 1;
398               m_bit++;
342399            }
343            sdar = ( shift >> 7 ) & 1;
344            shift <<= 1;
345            bit++;
346         } else {
347            bit = 0;
348            sdar = false;
349            if(!sdaw) {
350               verboselog(2, "ack <-\n");
351               byte++;
352            } else {
353               verboselog(2, "nak <-\n");
400            else
401            {
402               m_bit = 0;
403               m_sdar = 0;
404
405               if( m_sdaw == 0 )
406               {
407                  verboselog( 2, "ack <-\n" );
408                  m_byte++;
409               }
410               else
411               {
412                  verboselog( 2, "nak <-\n" );
413               }
354414            }
355415         }
356416         break;
357417      }
358418   }
419
420   m_scl = state;
359421}
360422
361void x76f041_device::sda_0()
423WRITE_LINE_MEMBER( x76f041_device::write_sda )
362424{
363   if(!cs && scl) {
364      switch(state) {
365      case STATE_STOP:
366         verboselog(1, "goto start (1)\n");
367         state = STATE_LOAD_COMMAND;
368         break;
369      case STATE_LOAD_PASSWORD:
370         /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */
371         verboselog(1, "goto start (2)\n");
372         break;
373      case STATE_READ_DATA:
374         verboselog(1, "goto load address\n");
375         state = STATE_LOAD_ADDRESS;
376         break;
377      default:
378         verboselog(1, "skipped start (default)\n");
379         break;
425   if( m_sdaw != state )
426   {
427      verboselog( 2, "sdaw=%d\n", state );
428   }
429
430   if( m_cs == 0 && m_scl != 0 )
431   {
432      if( m_sdaw == 0 && state != 0 )
433      {
434         verboselog( 1, "goto stop\n" );
435         m_state = STATE_STOP;
436         m_sdar = 0;
380437      }
381438
382      bit = 0;
383      byte = 0;
384      shift = 0;
385      sdar = false;
439      if( m_sdaw != 0 && state == 0 )
440      {
441         switch( m_state )
442         {
443         case STATE_STOP:
444            verboselog( 1, "goto start\n" );
445            m_state = STATE_LOAD_COMMAND;
446            break;
447
448         case STATE_LOAD_PASSWORD:
449            /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */
450            verboselog( 1, "goto start\n" );
451            break;
452
453         case STATE_READ_DATA:
454            verboselog( 1, "goto load address\n" );
455            m_state = STATE_LOAD_ADDRESS;
456            break;
457
458         default:
459            verboselog( 1, "skipped start (default)\n" );
460            break;
461         }
462
463         m_bit = 0;
464         m_byte = 0;
465         m_shift = 0;
466         m_sdar = 0;
467      }
386468   }
469
470   m_sdaw = state;
387471}
388472
389void x76f041_device::sda_1()
473READ_LINE_MEMBER( x76f041_device::read_sda )
390474{
391   if(!cs && scl) {
392      verboselog(1, "goto stop\n");
393      state = STATE_STOP;
394      sdar = false;
475   if( m_cs != 0 )
476   {
477      verboselog( 2, "not selected\n" );
478      return 1;
395479   }
480
481   verboselog( 2, "sdar=%d\n", m_sdar );
482   return m_sdar;
396483}
397484
398void x76f041_device::nvram_read(emu_file &file)
485void x76f041_device::nvram_default()
399486{
400   file.read(response_to_reset, SIZE_RESPONSE_TO_RESET);
401   file.read(write_password, SIZE_WRITE_PASSWORD);
402   file.read(read_password, SIZE_READ_PASSWORD);
403   file.read(configuration_password, SIZE_CONFIGURATION_PASSWORD);
404   file.read(configuration_registers, SIZE_CONFIGURATION_REGISTERS);
405   file.read(data, SIZE_DATA);
487   m_response_to_reset[0] = 0x19;
488   m_response_to_reset[1] = 0x55;
489   m_response_to_reset[2] = 0xaa;
490   m_response_to_reset[3] = 0x55,
491
492   memset( m_write_password, 0, sizeof( m_write_password ) );
493   memset( m_read_password, 0, sizeof( m_read_password ) );
494   memset( m_configuration_password, 0, sizeof( m_configuration_password ) );
495   memset( m_configuration_registers, 0, sizeof( m_configuration_registers ) );
496   memset( m_data, 0, sizeof( m_data ) );
497
498   int expected_bytes = sizeof( m_response_to_reset ) + sizeof( m_write_password ) + sizeof( m_read_password ) +
499      sizeof( m_configuration_password ) + sizeof( m_configuration_registers ) + sizeof( m_data );
500
501   if( !m_region )
502   {
503      logerror( "x76f041(%s) region not found\n", tag() );
504   }
505   else if( m_region->bytes() != expected_bytes )
506   {
507      logerror( "x76f041(%s) region length 0x%x expected 0x%x\n", tag(), m_region->bytes(), expected_bytes );
508   }
509   else
510   {
511      UINT8 *region = m_region->base();
512
513      memcpy( m_response_to_reset, region, sizeof( m_response_to_reset ) ); region += sizeof( m_response_to_reset );
514      memcpy( m_write_password, region, sizeof( m_write_password ) ); region += sizeof( m_write_password );
515      memcpy( m_read_password, region, sizeof( m_read_password ) ); region += sizeof( m_read_password );
516      memcpy( m_configuration_password, region, sizeof( m_configuration_password ) ); region += sizeof( m_configuration_password );
517      memcpy( m_configuration_registers, region, sizeof( m_configuration_registers ) ); region += sizeof( m_configuration_registers );
518      memcpy( m_data, region, sizeof( m_data ) ); region += sizeof( m_data );
519   }
406520}
407521
408void x76f041_device::nvram_write(emu_file &file)
522void x76f041_device::nvram_read( emu_file &file )
409523{
410   file.write(response_to_reset, SIZE_RESPONSE_TO_RESET);
411   file.write(write_password, SIZE_WRITE_PASSWORD);
412   file.write(read_password, SIZE_READ_PASSWORD);
413   file.write(configuration_password, SIZE_CONFIGURATION_PASSWORD);
414   file.write(configuration_registers, SIZE_CONFIGURATION_REGISTERS);
415   file.write(data, SIZE_DATA);
524   file.read( m_response_to_reset, sizeof( m_response_to_reset ) );
525   file.read( m_write_password, sizeof( m_write_password ) );
526   file.read( m_read_password, sizeof( m_read_password ) );
527   file.read( m_configuration_password, sizeof( m_configuration_password ) );
528   file.read( m_configuration_registers, sizeof( m_configuration_registers ) );
529   file.read( m_data, sizeof( m_data ) );
416530}
531
532void x76f041_device::nvram_write( emu_file &file )
533{
534   file.write( m_response_to_reset, sizeof( m_response_to_reset ) );
535   file.write( m_write_password, sizeof( m_write_password ) );
536   file.write( m_read_password, sizeof( m_read_password ) );
537   file.write( m_configuration_password, sizeof( m_configuration_password ) );
538   file.write( m_configuration_registers, sizeof( m_configuration_registers ) );
539   file.write( m_data, sizeof( m_data ) );
540}
trunk/src/mame/drivers/twinkle.c
r26479r26480
235235#include "machine/am53cf96.h"
236236#include "machine/rtc65271.h"
237237#include "machine/i2cmem.h"
238#include "machine/x76f041.h"
238239#include "machine/ataintf.h"
239240#include "sound/spu.h"
240241#include "sound/cdda.h"
r26479r26480
903904   MCFG_SOUND_ROUTE( 1, "^^^speakerright", 1.0 )
904905MACHINE_CONFIG_END
905906
907static MACHINE_CONFIG_DERIVED( twinklex, twinkle )
908   MCFG_X76F041_ADD( "security" )
909MACHINE_CONFIG_END
910
906911static MACHINE_CONFIG_DERIVED( twinklei, twinkle )
907   MCFG_I2CMEM_ADD("security")
908   MCFG_I2CMEM_DATA_SIZE(0x100)
912   MCFG_I2CMEM_ADD( "security" )
913   MCFG_I2CMEM_DATA_SIZE( 0x100 )
909914MACHINE_CONFIG_END
910915
911916static INPUT_PORTS_START( twinkle )
r26479r26480
958963   PORT_START("INSEC")
959964INPUT_PORTS_END
960965
966static INPUT_PORTS_START( twinklex )
967   PORT_INCLUDE( twinkle )
968
969   PORT_MODIFY("OUTSEC")
970   PORT_BIT( 0x00000010, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("security", x76f041_device, write_scl)
971   PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("security", x76f041_device, write_sda)
972   PORT_BIT( 0x00000004, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("security", x76f041_device, write_cs)
973
974   PORT_MODIFY("INSEC")
975   PORT_BIT( 0x00001000, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_READ_LINE_DEVICE_MEMBER("security", x76f041_device, read_sda)
976INPUT_PORTS_END
977
961978static INPUT_PORTS_START( twinklei )
962979   PORT_INCLUDE( twinkle )
963980
r26479r26480
9851002ROM_START( bmiidx )
9861003   TWINKLE_BIOS
9871004
988   ROM_REGION( 0x100, "security", 0 )
989   ROM_LOAD( "863a02", 0x000000, 0x000100, NO_DUMP )
1005   ROM_REGION( 0x224, "security", 0 )
1006   ROM_LOAD( "863a02", 0x000000, 0x000224, BAD_DUMP CRC(7b2a429b) SHA1(f710d19c7b900a58584c07ab8fd3ab7b9f0121d7) )
9901007
9911008   DISK_REGION( "scsi:cdrom" ) // program
9921009   DISK_IMAGE_READONLY( "gq863-jab01", 0, SHA1(331f80b40ed560c7e017621b7daeeb8275d92b9a) )
r26479r26480
10011018ROM_START( bmiidxa )
10021019   TWINKLE_BIOS
10031020
1004   ROM_REGION( 0x100, "security", 0 )
1005   ROM_LOAD( "863a02", 0x000000, 0x000100, NO_DUMP )
1021   ROM_REGION( 0x224, "security", 0 )
1022   ROM_LOAD( "863a02", 0x000000, 0x000224, BAD_DUMP CRC(7b2a429b) SHA1(f710d19c7b900a58584c07ab8fd3ab7b9f0121d7) )
10061023
10071024   DISK_REGION( "scsi:cdrom" ) // program
10081025   DISK_IMAGE_READONLY( "gq863a01", 0, SHA1(07fc467f6500504729becbaf77dabc093a134e65) )
r26479r26480
11611178ROM_START( bmiidxc )
11621179   TWINKLE_BIOS
11631180
1164   ROM_REGION( 0x100, "security", 0 )
1165   ROM_LOAD( "896a02", 0x000000, 0x000100, NO_DUMP )
1181   ROM_REGION( 0x224, "security", 0 )
1182   ROM_LOAD( "896a02", 0x000000, 0x000224, BAD_DUMP CRC(7b2a429b) SHA1(f710d19c7b900a58584c07ab8fd3ab7b9f0121d7) )
11661183
11671184   DISK_REGION( "scsi:cdrom" )
11681185   DISK_IMAGE_READONLY( "896jabbm", 0, BAD_DUMP SHA1(117ae4c876207bbaf9e8fe0fdf5bb161155c1bdb) )
r26479r26480
11771194ROM_START( bmiidxca )
11781195   TWINKLE_BIOS
11791196
1180   ROM_REGION( 0x100, "security", 0 )
1181   ROM_LOAD( "896a02", 0x000000, 0x000100, NO_DUMP )
1197   ROM_REGION( 0x224, "security", 0 )
1198   ROM_LOAD( "896a02", 0x000000, 0x000224, BAD_DUMP CRC(7b2a429b) SHA1(f710d19c7b900a58584c07ab8fd3ab7b9f0121d7) )
11821199
11831200   DISK_REGION( "scsi:cdrom" )
11841201   DISK_IMAGE_READONLY( "896jaabm", 0, SHA1(ea7205f86543d9273efcc226666ab530c32b23c1) )
r26479r26480
11931210ROM_START( bmiidxs )
11941211   TWINKLE_BIOS
11951212
1196   ROM_REGION( 0x100, "security", 0 )
1197   ROM_LOAD( "983a02", 0x000000, 0x000100, NO_DUMP )
1213   ROM_REGION( 0x224, "security", 0 )
1214   ROM_LOAD( "983a02", 0x000000, 0x000224, NO_DUMP )
11981215
11991216   DISK_REGION( "scsi:cdrom" )
12001217   DISK_IMAGE_READONLY( "gc983a01", 0, NO_DUMP )
r26479r26480
12091226ROM_START( bmiidxc2 )
12101227   TWINKLE_BIOS
12111228
1212   ROM_REGION( 0x100, "security", 0 )
1213   ROM_LOAD( "984a02", 0x000000, 0x000100, NO_DUMP )
1229   ROM_REGION( 0x224, "security", 0 )
1230   ROM_LOAD( "984a02", 0x000000, 0x000224, BAD_DUMP CRC(5b08e1ef) SHA1(d43ad5d958313ccb2420246621d9180230b4782d) )
12141231
12151232   DISK_REGION( "scsi:cdrom" )
12161233   DISK_IMAGE_READONLY( "ge984a01(bm)", 0, SHA1(03b083ba09652dfab6f328000c3c9de2a7a4e618) )
r26479r26480
12241241
12251242GAME( 1999, gq863,    0,       twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "Twinkle System", GAME_IS_BIOS_ROOT )
12261243
1227GAME( 1999, bmiidx,   gq863,   twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "beatmania IIDX (863 JAB)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )
1228GAME( 1999, bmiidxa,  bmiidx,  twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "beatmania IIDX (863 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )
1229GAME( 1999, bmiidxc,  gq863,   twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAB)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1230GAME( 1999, bmiidxca, bmiidxc, twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1231GAME( 1999, bmiidxs,  gq863,   twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "beatmania IIDX Substream (983 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1232GAME( 1999, bmiidxc2, gq863,   twinkle,  twinkle,  driver_device, 0,        ROT0, "Konami", "Beatmania IIDX Substream with DDR 2nd Club Version 2 (984 A01 BM)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1244GAME( 1999, bmiidx,   gq863,   twinklex, twinklex, driver_device, 0,        ROT0, "Konami", "beatmania IIDX (863 JAB)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )
1245GAME( 1999, bmiidxa,  bmiidx,  twinklex, twinklex, driver_device, 0,        ROT0, "Konami", "beatmania IIDX (863 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )
1246GAME( 1999, bmiidxc,  gq863,   twinklex, twinklex, driver_device, 0,        ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAB)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1247GAME( 1999, bmiidxca, bmiidxc, twinklex, twinklex, driver_device, 0,        ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1248GAME( 1999, bmiidxs,  gq863,   twinklex, twinklex, driver_device, 0,        ROT0, "Konami", "beatmania IIDX Substream (983 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
1249GAME( 1999, bmiidxc2, gq863,   twinklex, twinklex, driver_device, 0,        ROT0, "Konami", "Beatmania IIDX Substream with DDR 2nd Club Version 2 (984 A01 BM)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
12331250GAME( 1999, bmiidx2,  gq863,   twinklei, twinklei, driver_device, 0,        ROT0, "Konami", "beatmania IIDX 2nd style (GC985 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
12341251GAME( 2000, bmiidx3,  gq863,   twinklei, twinklei, driver_device, 0,        ROT0, "Konami", "beatmania IIDX 3rd style (GC992 JAC)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
12351252GAME( 2000, bmiidx3a, bmiidx3, twinklei, twinklei, driver_device, 0,        ROT0, "Konami", "beatmania IIDX 3rd style (GC992 JAA)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING  )
trunk/src/mame/machine/naomibd.c
r26479r26480
188188
189189WRITE16_MEMBER(naomi_board::boardid_w)
190190{
191   eeprom->cs_w((data >> 2) & 1);
192   eeprom->rst_w((data >> 3) & 1);
193   eeprom->scl_w((data >> 1) & 1);
194   eeprom->sda_w((data >> 0) & 1);
191   eeprom->write_cs((data >> 2) & 1);
192   eeprom->write_rst((data >> 3) & 1);
193   eeprom->write_scl((data >> 1) & 1);
194   eeprom->write_sda((data >> 0) & 1);
195195}
196196
197197READ16_MEMBER(naomi_board::boardid_r)
198198{
199   return eeprom->sda_r() << 15;
199   return eeprom->read_sda() << 15;
200200}
201201
202202READ16_MEMBER(naomi_board::default_r)
trunk/src/mame/machine/k573cass.c
r26479r26480
8383
8484WRITE_LINE_MEMBER(konami573_cassette_x_device::write_line_d0)
8585{
86   m_x76f041->sda_w( state );
86   m_x76f041->write_sda( state );
8787}
8888
8989WRITE_LINE_MEMBER(konami573_cassette_x_device::write_line_d1)
9090{
91   m_x76f041->scl_w( state );
91   m_x76f041->write_scl( state );
9292}
9393
9494WRITE_LINE_MEMBER(konami573_cassette_x_device::write_line_d2)
9595{
96   m_x76f041->cs_w( state );
96   m_x76f041->write_cs( state );
9797}
9898
9999WRITE_LINE_MEMBER(konami573_cassette_x_device::write_line_d3)
100100{
101   m_x76f041->rst_w( state );
101   m_x76f041->write_rst( state );
102102}
103103
104104READ_LINE_MEMBER(konami573_cassette_x_device::read_line_secflash_sda)
105105{
106   return m_x76f041->sda_r();
106   return m_x76f041->read_sda();
107107}
108108
109109
r26479r26480
222222
223223READ_LINE_MEMBER(konami573_cassette_y_device::read_line_secflash_sda)
224224{
225   return m_x76f100->sda_r();
225   return m_x76f100->read_sda();
226226}
227227
228228WRITE_LINE_MEMBER(konami573_cassette_y_device::write_line_d0)
229229{
230230   m_d0_handler( state );
231   m_x76f100->sda_w( state );
231   m_x76f100->write_sda( state );
232232}
233233
234234WRITE_LINE_MEMBER(konami573_cassette_y_device::write_line_d1)
235235{
236236   m_d1_handler( state );
237   m_x76f100->scl_w( state );
237   m_x76f100->write_scl( state );
238238}
239239
240240WRITE_LINE_MEMBER(konami573_cassette_y_device::write_line_d2)
241241{
242242   m_d2_handler( state );
243   m_x76f100->cs_w( state );
243   m_x76f100->write_cs( state );
244244}
245245
246246WRITE_LINE_MEMBER(konami573_cassette_y_device::write_line_d3)
247247{
248248   m_d3_handler( state );
249   m_x76f100->rst_w( state );
249   m_x76f100->write_rst( state );
250250}
251251
252252WRITE_LINE_MEMBER(konami573_cassette_y_device::write_line_d4)
r26479r26480
312312}
313313
314314static MACHINE_CONFIG_FRAGMENT( casszi )
315   MCFG_ZS01_ADD( "eeprom", "id" )
316315   MCFG_DS2401_ADD( "id" )
316   MCFG_ZS01_ADD( "eeprom" )
317   MCFG_ZS01_DS2401( "id" )
317318MACHINE_CONFIG_END
318319
319320machine_config_constructor konami573_cassette_zi_device::device_mconfig_additions() const
r26479r26480
327328
328329WRITE_LINE_MEMBER(konami573_cassette_zi_device::write_line_d1)
329330{
330   m_zs01->scl_w( state );
331   m_zs01->write_scl( state );
331332}
332333
333334WRITE_LINE_MEMBER(konami573_cassette_zi_device::write_line_d2)
334335{
335   m_zs01->cs_w( state );
336   m_zs01->write_cs( state );
336337}
337338
338339WRITE_LINE_MEMBER(konami573_cassette_zi_device::write_line_d3)
339340{
340   m_zs01->rst_w( state );
341   m_zs01->write_rst( state );
341342}
342343
343344WRITE_LINE_MEMBER(konami573_cassette_zi_device::write_line_d4)
r26479r26480
347348
348349WRITE_LINE_MEMBER(konami573_cassette_zi_device::write_line_zs01_sda)
349350{
350   m_zs01->sda_w( state );
351   m_zs01->write_sda( state );
351352}
352353
353354READ_LINE_MEMBER(konami573_cassette_zi_device::read_line_ds2401)
r26479r26480
357358
358359READ_LINE_MEMBER(konami573_cassette_zi_device::read_line_secflash_sda)
359360{
360   return m_zs01->sda_r();
361   return m_zs01->read_sda();
361362}
362363
363364
trunk/src/mame/machine/zs01.c
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/*
24 * zs01.c
35 *
r26479r26480
79 *
810 */
911
10#include "emu.h"
1112#include "machine/zs01.h"
1213
13#define VERBOSE_LEVEL 0
14#define VERBOSE_LEVEL ( 0 )
1415
15inline void ATTR_PRINTF(3,4) zs01_device::verboselog(int n_level, const char *s_fmt, ...)
16inline void ATTR_PRINTF( 3, 4 ) zs01_device::verboselog( int n_level, const char *s_fmt, ... )
1617{
17   if(VERBOSE_LEVEL >= n_level)
18   if( VERBOSE_LEVEL >= n_level )
1819   {
1920      va_list v;
20      char buf[32768];
21      va_start(v, s_fmt);
22      vsprintf(buf, s_fmt, v);
23      va_end(v);
24      logerror("zs01 %s %s: %s", tag(), machine().describe_context(), buf);
21      char buf[ 32768 ];
22      va_start( v, s_fmt );
23      vsprintf( buf, s_fmt, v );
24      va_end( v );
25      logerror( "%s: zs01(%s) %s", machine().describe_context(), tag(), buf );
2526   }
2627}
2728
2829// device type definition
2930const device_type ZS01 = &device_creator<zs01_device>;
3031
31void zs01_device::static_set_ds2401_tag(device_t &device, const char *ds2401_tag)
32zs01_device::zs01_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock )
33   : device_t( mconfig, ZS01, "ZS01", tag, owner, clock, "zs01", __FILE__ ),
34   device_nvram_interface(mconfig, *this),
35   m_cs( 0 ),
36   m_rst( 0 ),
37   m_scl( 0 ),
38   m_sdaw( 0 ),
39   m_sdar( 0 ),
40   m_state( STATE_STOP ),
41   m_shift( 0 ),
42   m_bit( 0 ),
43   m_byte( 0 )
3244{
33   zs01_device &zs01 = downcast<zs01_device &>(device);
34   zs01.ds2401_tag = ds2401_tag;
3545}
3646
37zs01_device::zs01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
38   : device_secure_serial_flash(mconfig, ZS01, "ZS01", tag, owner, clock, "zs01", __FILE__)
39{
40}
41
4247void zs01_device::device_start()
4348{
44   device_secure_serial_flash::device_start();
45   save_item(NAME(state));
46   save_item(NAME(shift));
47   save_item(NAME(bit));
48   save_item(NAME(byte));
49   save_item(NAME(write_buffer));
50   save_item(NAME(read_buffer));
51   save_item(NAME(response_key));
52   save_item(NAME(response_to_reset));
53   save_item(NAME(command_key));
54   save_item(NAME(data_key));
55
56   m_ds2401 = siblingdevice<ds2401_device>(ds2401_tag);
49   m_ds2401 = siblingdevice<ds2401_device>(m_ds2401_tag);
5750   if( m_ds2401 == NULL )
5851   {
59      logerror( "ds2401 '%s' not found\n", ds2401_tag );
52      logerror( "ds2401 '%s' not found\n", m_ds2401_tag );
6053   }
61}
6254
63void zs01_device::device_reset()
64{
65   device_secure_serial_flash::device_reset();
66   state = STATE_STOP;
67   shift = 0;
68   bit = 0;
69   byte = 0;
70   memset(write_buffer, 0, SIZE_WRITE_BUFFER);
71   memset(read_buffer, 0, SIZE_READ_BUFFER);
72   memset(response_key, 0, SIZE_KEY);
55   memset( m_write_buffer, 0, sizeof( m_write_buffer ) );
56   memset( m_read_buffer, 0, sizeof( m_read_buffer ) );
57   memset( m_response_key, 0, sizeof( m_response_key ) );
58
59   save_item( NAME( m_cs ) );
60   save_item( NAME( m_rst ) );
61   save_item( NAME( m_scl ) );
62   save_item( NAME( m_sdaw ) );
63   save_item( NAME( m_sdar ) );
64   save_item( NAME( m_state ) );
65   save_item( NAME( m_shift ) );
66   save_item( NAME( m_bit ) );
67   save_item( NAME( m_byte ) );
68   save_item( NAME( m_write_buffer ) );
69   save_item( NAME( m_read_buffer ) );
70   save_item( NAME( m_response_key ) );
71   save_item( NAME( m_response_to_reset ) );
72   save_item( NAME( m_command_key ) );
73   save_item( NAME( m_data_key ) );
74   save_item( NAME( m_data ) );
7375}
7476
75void zs01_device::nvram_default()
77WRITE_LINE_MEMBER( zs01_device::write_rst )
7678{
77   // region always wins
78   if(m_region)
79   if( m_rst != state )
7980   {
80      // Ensure the size is correct though
81      if(m_region->bytes() != SIZE_RESPONSE_TO_RESET+SIZE_KEY+SIZE_KEY+SIZE_DATA)
82         logerror("zs01 %s: Wrong region length for initialization data, expected 0x%x, got 0x%x\n",
83                  tag(),
84                  SIZE_RESPONSE_TO_RESET+SIZE_KEY+SIZE_KEY+SIZE_DATA,
85                  m_region->bytes());
86      else {
87         UINT8 *rb = m_region->base();
88         int offset = 0;
89         memcpy(response_to_reset, rb + offset, SIZE_RESPONSE_TO_RESET); offset += SIZE_RESPONSE_TO_RESET;
90         memcpy(command_key,       rb + offset, SIZE_KEY); offset += SIZE_KEY;
91         memcpy(data_key,          rb + offset, SIZE_KEY); offset += SIZE_KEY;
92         memcpy(data,              rb + offset, SIZE_DATA); offset += SIZE_DATA;
93         return;
94      }
81      verboselog( 2, "rst=%d\n", state );
9582   }
9683
97   // That chip isn't really usable without the passwords, so bitch
98   // if there's no region
99   logerror("zs01 %s: Warning, no default data provided, chip is unusable.\n", tag());
100   memset(response_to_reset, 0, SIZE_RESPONSE_TO_RESET);
101   memset(command_key,       0, SIZE_KEY);
102   memset(data_key,          0, SIZE_KEY);
103   memset(data,              0, SIZE_DATA);
104}
84   if( m_rst == 0 && state != 0 && m_cs == 0 )
85   {
86      verboselog( 1, "goto response to reset\n" );
87      m_state = STATE_RESPONSE_TO_RESET;
88      m_bit = 0;
89      m_byte = 0;
90   }
10591
106void zs01_device::cs_0()
107{
92   m_rst = state;
10893}
10994
110void zs01_device::cs_1()
95WRITE_LINE_MEMBER( zs01_device::write_cs )
11196{
112}
97   if( m_cs != state )
98   {
99      verboselog( 2, "cs=%d\n", state );
100   }
113101
114void zs01_device::rst_0()
115{
116}
102//  if( m_cs != 0 && state == 0 )
103//  {
104//      /* enable chip */
105//      m_state = STATE_STOP;
106//  }
117107
118void zs01_device::rst_1()
119{
120   if(!cs) {
121      verboselog(1, "goto response to reset\n");
122      state = STATE_RESPONSE_TO_RESET;
123      bit = 0;
124      byte = 0;
125   }
108//  if( m_cs == 0 && state != 0 )
109//  {
110//      /* disable chip */
111//      m_state = STATE_STOP;
112//      /* high impendence? */
113//      m_sdar = 0;
114//  }
115
116   m_cs = state;
126117}
127118
128void zs01_device::decrypt(UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte)
119void zs01_device::decrypt( UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte )
129120{
130121   UINT32 a0;
131122   UINT32 v1;
r26479r26480
172163   }
173164}
174165
175void zs01_device::decrypt2(UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte)
166void zs01_device::decrypt2( UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte )
176167{
177168   UINT32 a0;
178169   UINT32 v1;
r26479r26480
220211   }
221212}
222213
223void zs01_device::encrypt(UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT32 previous_byte)
214void zs01_device::encrypt( UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT32 previous_byte )
224215{
225216   UINT32 t0;
226217   UINT32 v0;
r26479r26480
268259   }
269260}
270261
271UINT16 zs01_device::do_crc(UINT8 *buffer, UINT32 length)
262UINT16 zs01_device::calc_crc( UINT8 *buffer, UINT32 length )
272263{
273264   UINT32 v1;
274265   UINT32 a3;
r26479r26480
318309
319310int zs01_device::data_offset()
320311{
321   int block = ( (write_buffer[0] & 2 ) << 7 ) | write_buffer[1];
312   int block = ( ( m_write_buffer[ 0 ] & 2 ) << 7 ) | m_write_buffer[ 1 ];
322313
323314   return block * SIZE_DATA_BUFFER;
324315}
325316
326void zs01_device::scl_0()
317WRITE_LINE_MEMBER( zs01_device::write_scl )
327318{
328   if(!cs) {
329      switch(state) {
319   if( m_scl != state )
320   {
321      verboselog( 2, "scl=%d\n", state );
322   }
323
324   if( m_cs == 0 )
325   {
326      switch( m_state )
327      {
330328      case STATE_STOP:
331329         break;
332330
333331      case STATE_RESPONSE_TO_RESET:
334         if(!bit) {
335            shift = response_to_reset[byte];
336            verboselog(1, "<- response_to_reset[%d]: %02x\n", byte, shift);
337         }
332         if( m_scl != 0 && state == 0 )
333         {
334            if( m_bit == 0 )
335            {
336               m_shift = m_response_to_reset[ m_byte ];
337               verboselog( 1, "<- response_to_reset[ %d ]: %02x\n", m_byte, m_shift );
338            }
338339
339         sdar = (shift >> 7) & 1;
340         shift <<= 1;
341         bit++;
340            m_sdar = ( m_shift >> 7 ) & 1;
341            m_shift <<= 1;
342            m_bit++;
342343
343         if( bit == 8 ) {
344            bit = 0;
345            byte++;
346            if( byte == 4 ) {
347               sdar = true;
348               verboselog(1, "goto stop\n");
349               state = STATE_STOP;
344            if( m_bit == 8 )
345            {
346               m_bit = 0;
347               m_byte++;
348
349               if( m_byte == sizeof( m_response_to_reset ) )
350               {
351                  m_sdar = 1;
352                  verboselog( 1, "goto stop\n" );
353                  m_state = STATE_STOP;
354               }
350355            }
351356         }
352357         break;
353358
354359      case STATE_LOAD_COMMAND:
355         break;
360         if( m_scl == 0 && state != 0 )
361         {
362            if( m_bit < 8 )
363            {
364               verboselog( 2, "clock\n" );
365               m_shift <<= 1;
356366
357      case STATE_READ_DATA:
358         break;
359      }
360   }
361}
367               if( m_sdaw != 0 )
368               {
369                  m_shift |= 1;
370               }
362371
363void zs01_device::scl_1()
364{
365   if(!cs) {
366      switch(state) {
367      case STATE_STOP:
368         break;
372               m_bit++;
373            }
374            else
375            {
376               m_sdar = 0;
369377
370      case STATE_RESPONSE_TO_RESET:
371         break;
378               switch( m_state )
379               {
380               case STATE_LOAD_COMMAND:
381                  m_write_buffer[ m_byte ] = m_shift;
382                  verboselog( 2, "-> write_buffer[ %d ]: %02x\n", m_byte, m_write_buffer[ m_byte ] );
372383
373      case STATE_LOAD_COMMAND:
374         if(bit < 8) {
375            shift <<= 1;
376            if(sdaw)
377               shift |= 1;
378            bit++;
379            verboselog(2, "clock %d %02x\n", bit, shift);
380         } else {
381            sdar = false;
384                  m_byte++;
385                  if( m_byte == sizeof( m_write_buffer ) )
386                  {
387                     decrypt( m_write_buffer, m_write_buffer, sizeof( m_write_buffer ), m_command_key, 0xff );
382388
383            switch(state) {
384            case STATE_LOAD_COMMAND:
385               write_buffer[byte] = shift;
386               verboselog(2, "-> write_buffer[%d]: %02x\n", byte, write_buffer[byte]);
387               byte++;
388               if(byte == SIZE_WRITE_BUFFER) {
389                  UINT16 crc;
389                     if( ( m_write_buffer[ 0 ] & 4 ) != 0 )
390                     {
391                        decrypt2( &m_write_buffer[ 2 ], &m_write_buffer[ 2 ], SIZE_DATA_BUFFER, m_data_key, 0x00 );
392                     }
390393
391                  decrypt(write_buffer, write_buffer, SIZE_WRITE_BUFFER, command_key, 0xff);
394                     UINT16 crc = calc_crc( m_write_buffer, 10 );
392395
393                  if(write_buffer[0] & 4)
394                     decrypt2(&write_buffer[2], &write_buffer[2], SIZE_DATA_BUFFER, data_key, 0x00);
396                     if( crc == ( ( m_write_buffer[ 10 ] << 8 ) | m_write_buffer[ 11 ] ) )
397                     {
398                        verboselog( 1, "-> command: %02x\n", m_write_buffer[ 0 ] );
399                        verboselog( 1, "-> address: %02x\n", m_write_buffer[ 1 ] );
400                        verboselog( 1, "-> data: %02x%02x%02x%02x%02x%02x%02x%02x\n",
401                           m_write_buffer[ 2 ], m_write_buffer[ 3 ], m_write_buffer[ 4 ], m_write_buffer[ 5 ],
402                           m_write_buffer[ 6 ], m_write_buffer[ 7 ], m_write_buffer[ 8 ], m_write_buffer[ 9 ] );
403                        verboselog( 1, "-> crc: %02x%02x\n", m_write_buffer[ 10 ], m_write_buffer[ 11 ] );
395404
396                  crc = do_crc(write_buffer, 10);
405                        switch( m_write_buffer[ 0 ] & 1 )
406                        {
407                        case COMMAND_WRITE:
408                           memcpy( &m_data[ data_offset() ], &m_write_buffer[ 2 ], SIZE_DATA_BUFFER );
397409
398                  if(crc == ((write_buffer[10] << 8) | write_buffer[11])) {
399                     verboselog(1, "-> command: %02x\n", write_buffer[0]);
400                     verboselog(1, "-> address: %02x\n", write_buffer[1]);
401                     verboselog(1, "-> data: %02x%02x%02x%02x%02x%02x%02x%02x\n",
402                              write_buffer[2], write_buffer[3], write_buffer[4], write_buffer[5],
403                              write_buffer[6], write_buffer[7], write_buffer[8], write_buffer[9]);
404                     verboselog(1, "-> crc: %02x%02x\n", write_buffer[10], write_buffer[11]);
405                     switch(write_buffer[0] & 1) {
406                     case COMMAND_WRITE:
407                        memcpy(&data[data_offset()], &write_buffer[2], SIZE_DATA_BUFFER);
410                           /* todo: find out what should be returned. */
411                           memset( &m_read_buffer[ 0 ], 0, sizeof( m_write_buffer ) );
412                           break;
408413
409                        /* todo: find out what should be returned. */
410                        memset(&read_buffer[0] , 0, SIZE_WRITE_BUFFER);
411                        break;
414                        case COMMAND_READ:
415                           /* todo: find out what should be returned. */
416                           memset( &m_read_buffer[ 0 ], 0, 2 );
412417
413                     case COMMAND_READ:
414                        /* todo: find out what should be returned. */
415                        memset(&read_buffer[0], 0, 2);
418                           switch( m_write_buffer[ 1 ] )
419                           {
420                           case 0xfd:
421                              {
422                                 /* TODO: use read/write to talk to the ds2401, which will require a timer. */
423                                 for( int i = 0; i < SIZE_DATA_BUFFER; i++ )
424                                 {
425                                    m_read_buffer[ 2 + i ] = m_ds2401->direct_read( SIZE_DATA_BUFFER - i - 1 );
426                                 }
427                              }
428                              break;
416429
417                        switch(write_buffer[1]) {
418                        case 0xfd: {
419                           /* TODO: use read/write to talk to the ds2401, which will require a timer. */
420                           if( m_ds2401 != NULL )
421                              for(int i = 0; i < SIZE_DATA_BUFFER; i++)
422                                 read_buffer[2+i] = m_ds2401->direct_read(SIZE_DATA_BUFFER-i-1);
430                           default:
431                              memcpy( &m_read_buffer[ 2 ], &m_data[ data_offset() ], SIZE_DATA_BUFFER );
432                              break;
433                           }
434
435                           memcpy( m_response_key, &m_write_buffer[ 2 ], sizeof( m_response_key ) );
423436                           break;
424437                        }
425                        default:
426                           memcpy(&read_buffer[2], &data[data_offset()], SIZE_DATA_BUFFER);
427                           break;
428                        }
438                     }
439                     else
440                     {
441                        verboselog( 0, "bad crc\n" );
429442
430                        memcpy(response_key, &write_buffer[2], SIZE_KEY);
431                        break;
443                        /* todo: find out what should be returned. */
444                        memset( &m_read_buffer[ 0 ], 0xff, 2 );
432445                     }
433                  } else {
434                     verboselog(0, "bad crc\n");
435                     /* todo: find out what should be returned. */
436                     memset(&read_buffer[0], 0xff, 2 );
437                  }
438446
439                  verboselog(1, "<- status: %02x%02x\n",
440                           read_buffer[0], read_buffer[1]);
447                     verboselog( 1, "<- status: %02x%02x\n",
448                        m_read_buffer[ 0 ], m_read_buffer[ 1 ] );
441449
442                  verboselog(1, "<- data: %02x%02x%02x%02x%02x%02x%02x%02x\n",
443                           read_buffer[2], read_buffer[3], read_buffer[4], read_buffer[5],
444                           read_buffer[6], read_buffer[7], read_buffer[8], read_buffer[9]);
450                     verboselog( 1, "<- data: %02x%02x%02x%02x%02x%02x%02x%02x\n",
451                        m_read_buffer[ 2 ], m_read_buffer[ 3 ], m_read_buffer[ 4 ], m_read_buffer[ 5 ],
452                        m_read_buffer[ 6 ], m_read_buffer[ 7 ], m_read_buffer[ 8 ], m_read_buffer[ 9 ] );
445453
446                  crc = do_crc(read_buffer, 10);
447                  read_buffer[10] = crc >> 8;
448                  read_buffer[11] = crc & 255;
454                     crc = calc_crc( m_read_buffer, 10 );
455                     m_read_buffer[ 10 ] = crc >> 8;
456                     m_read_buffer[ 11 ] = crc & 255;
449457
450                  encrypt(read_buffer, read_buffer, SIZE_READ_BUFFER, response_key, 0xff);
458                     encrypt( m_read_buffer, m_read_buffer, sizeof( m_read_buffer ), m_response_key, 0xff );
451459
452                  byte = 0;
453                  state = STATE_READ_DATA;
460                     m_byte = 0;
461                     m_state = STATE_READ_DATA;
462                  }
463                  break;
454464               }
455               break;
465
466               m_bit = 0;
467               m_shift = 0;
456468            }
457
458            bit = 0;
459            shift = 0;
460469         }
461470         break;
462471
463472      case STATE_READ_DATA:
464         if(bit < 8) {
465            if(bit == 0) {
466               switch(state) {
467               case STATE_READ_DATA:
468                  shift = read_buffer[byte];
469                  verboselog(2, "<- read_buffer[%d]: %02x\n", byte, shift);
470                  break;
473         if( m_scl == 0 && state != 0 )
474         {
475            if( m_bit < 8 )
476            {
477               if( m_bit == 0 )
478               {
479                  switch( m_state )
480                  {
481                  case STATE_READ_DATA:
482                     m_shift = m_read_buffer[ m_byte ];
483                     verboselog( 2, "<- read_buffer[ %d ]: %02x\n", m_byte, m_shift );
484                     break;
485                  }
471486               }
487
488               m_sdar = ( m_shift >> 7 ) & 1;
489               m_shift <<= 1;
490               m_bit++;
472491            }
473            sdar = (shift >> 7) & 1;
474            shift <<= 1;
475            bit++;
476         } else {
477            bit = 0;
478            sdar = false;
479            if(!sdaw) {
480               verboselog(2, "ack <-\n");
481               byte++;
482               if(byte == SIZE_READ_BUFFER) {
483                  byte = 0;
484                  sdar = true;
485                  state = STATE_LOAD_COMMAND;
492            else
493            {
494               m_bit = 0;
495               m_sdar = 0;
496
497               if( m_sdaw == 0 )
498               {
499                  verboselog( 2, "ack <-\n" );
500                  m_byte++;
501
502                  if( m_byte == sizeof( m_read_buffer ) )
503                  {
504                     m_byte = 0;
505                     m_sdar = 1;
506                     m_state = STATE_LOAD_COMMAND;
507                  }
486508               }
487            } else {
488               verboselog(2, "nak <-\n");
509               else
510               {
511                  verboselog( 2, "nak <-\n" );
512               }
489513            }
490514         }
491515         break;
492516      }
493517   }
518
519   m_scl = state;
494520}
495521
496void zs01_device::sda_1()
522WRITE_LINE_MEMBER( zs01_device::write_sda )
497523{
498   if(!cs && scl){
499//      state = STATE_STOP;
500//      sdar = false;
524   if( m_sdaw != state )
525   {
526      verboselog( 2, "sdaw=%d\n", state );
501527   }
528
529   if( m_cs == 0 && m_scl != 0 )
530   {
531//      if( m_sdaw == 0 && state != 0 )
532//      {
533//          verboselog( 1, "goto stop\n" );
534//          m_state = STATE_STOP;
535//          m_sdar = 0;
536//      }
537
538      if( m_sdaw != 0 && state == 0 )
539      {
540         switch( m_state )
541         {
542         case STATE_STOP:
543            verboselog( 1, "goto start\n" );
544            m_state = STATE_LOAD_COMMAND;
545            break;
546
547//          default:
548//              verboselog( 1, "skipped start (default)\n" );
549//              break;
550         }
551
552         m_bit = 0;
553         m_byte = 0;
554         m_shift = 0;
555         m_sdar = 0;
556      }
557   }
558
559   m_sdaw = state;
502560}
503561
504void zs01_device::sda_0()
562READ_LINE_MEMBER( zs01_device::read_sda )
505563{
506   if(!cs && scl) {
507      switch(state) {
508      case STATE_STOP:
509         verboselog(1, "goto start\n");
510         state = STATE_LOAD_COMMAND;
511         break;
512         //  default:
513         //      verboselog(1, "skipped start (default)\n");
514         //      break;
515      }
564   if( m_cs != 0 )
565   {
566      verboselog( 2, "not selected\n" );
567      return 1;
568   }
516569
517      bit = 0;
518      byte = 0;
519      shift = 0;
520      sdar = false;
570   verboselog( 2, "sdar=%d\n", m_sdar );
571
572   return m_sdar;
573}
574
575void zs01_device::nvram_default()
576{
577   memset( m_response_to_reset, 0, sizeof( m_response_to_reset ) );
578   memset( m_command_key, 0, sizeof( m_command_key ) );
579   memset( m_data_key, 0, sizeof( m_data_key ) );
580   memset( m_data, 0, sizeof( m_data ) );
581
582   int expected_bytes = sizeof( m_response_to_reset ) + sizeof( m_command_key ) + sizeof( m_data_key ) + sizeof( m_data );
583
584   if( !m_region )
585   {
586      logerror( "zs01(%s) region not found\n", tag() );
521587   }
588   else if( m_region->bytes() != expected_bytes )
589   {
590      logerror( "zs01(%s) region length 0x%x expected 0x%x\n", tag(), m_region->bytes(), expected_bytes );
591   }
592   else
593   {
594      UINT8 *region = m_region->base();
595
596      memcpy( m_response_to_reset, region, sizeof( m_response_to_reset ) ); region += sizeof( m_response_to_reset );
597      memcpy( m_command_key, region, sizeof( m_command_key ) ); region += sizeof( m_command_key );
598      memcpy( m_data_key, region, sizeof( m_data_key ) ); region += sizeof( m_data_key );
599      memcpy( m_data, region, sizeof( m_data ) ); region += sizeof( m_data );
600   }
522601}
523602
524void zs01_device::nvram_read(emu_file &file)
603void zs01_device::nvram_read( emu_file &file )
525604{
526   file.read(response_to_reset, SIZE_RESPONSE_TO_RESET);
527   file.read(command_key,       SIZE_KEY);
528   file.read(data_key,          SIZE_KEY);
529   file.read(data,              SIZE_DATA);
605   file.read( m_response_to_reset, sizeof( m_response_to_reset ) );
606   file.read( m_command_key, sizeof( m_command_key ) );
607   file.read( m_data_key, sizeof( m_data_key ) );
608   file.read( m_data, sizeof( m_data ) );
530609}
531610
532void zs01_device::nvram_write(emu_file &file)
611void zs01_device::nvram_write( emu_file &file )
533612{
534   file.write(response_to_reset, SIZE_RESPONSE_TO_RESET);
535   file.write(command_key,       SIZE_KEY);
536   file.write(data_key,          SIZE_KEY);
537   file.write(data,              SIZE_DATA);
613   file.write( m_response_to_reset, sizeof( m_response_to_reset ) );
614   file.write( m_command_key, sizeof( m_command_key ) );
615   file.write( m_data_key, sizeof( m_data_key ) );
616   file.write( m_data, sizeof( m_data ) );
538617}
trunk/src/mame/machine/zs01.h
r26479r26480
1// license:MAME
2// copyright-holders:smf
13/*
24 * zs01.h
35 *
r26479r26480
57 *
68 */
79
10#pragma once
11
812#ifndef __ZS01_H__
913#define __ZS01_H__
1014
1115#include "machine/ds2401.h"
12#include "machine/secflash.h"
1316
14#define MCFG_ZS01_ADD(_tag, ds2401_tag) \
15   MCFG_DEVICE_ADD(_tag, ZS01, 0) \
16   zs01_device::static_set_ds2401_tag(*device, ds2401_tag);
17#define MCFG_ZS01_ADD( _tag ) \
18   MCFG_DEVICE_ADD( _tag, ZS01, 0 ) \
1719
18class zs01_device : public device_secure_serial_flash
20#define MCFG_ZS01_DS2401( ds2401_tag ) \
21   zs01_device::static_set_ds2401_tag( *device, ds2401_tag );
22
23class zs01_device : public device_t,
24   public device_nvram_interface
1925{
2026public:
2127   // construction/destruction
22   zs01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
28   zs01_device( const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock );
2329
2430   // inline configuration helpers
25   static void static_set_ds2401_tag(device_t &device, const char *ds2401_tag);
31   static void static_set_ds2401_tag( device_t &device, const char *ds2401_tag ) { downcast<zs01_device &>( device ).m_ds2401_tag = ds2401_tag; }
2632
33   DECLARE_WRITE_LINE_MEMBER( write_cs );
34   DECLARE_WRITE_LINE_MEMBER( write_rst );
35   DECLARE_WRITE_LINE_MEMBER( write_scl );
36   DECLARE_WRITE_LINE_MEMBER( write_sda );
37   DECLARE_READ_LINE_MEMBER( read_sda );
38
2739protected:
2840   // device-level overrides
2941   virtual void device_start();
30   virtual void device_reset();
3142
3243   // device_nvram_interface overrides
3344   virtual void nvram_default();
34   virtual void nvram_read(emu_file &file);
35   virtual void nvram_write(emu_file &file);
45   virtual void nvram_read( emu_file &file );
46   virtual void nvram_write( emu_file &file );
3647
37   // device_secure_serial_flash implementations
38   virtual void cs_0();
39   virtual void cs_1();
40   virtual void rst_0();
41   virtual void rst_1();
42   virtual void scl_0();
43   virtual void scl_1();
44   virtual void sda_0();
45   virtual void sda_1();
48private:
49   inline void ATTR_PRINTF( 3, 4 ) verboselog( int n_level, const char *s_fmt, ... );
4650
47   // internal state
48   const char *ds2401_tag;
51   void decrypt( UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte );
52   void decrypt2( UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte );
53   void encrypt( UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT32 previous_byte );
54   UINT16 calc_crc( UINT8 *buffer, UINT32 length );
55   int data_offset();
4956
50   enum {
51      SIZE_WRITE_BUFFER = 12,
52      SIZE_READ_BUFFER = 12,
53      SIZE_DATA_BUFFER = 8,
54      SIZE_RESPONSE_TO_RESET = 4,
55      SIZE_KEY = 8,
56      SIZE_DATA = 4096,
57   enum size_t
58   {
59      SIZE_DATA_BUFFER = 8
60   };
5761
62   enum command_t
63   {
5864      COMMAND_WRITE = 0x00,
5965      COMMAND_READ = 0x01
6066   };
6167
62   enum {
68   enum state_t
69   {
6370      STATE_STOP,
6471      STATE_RESPONSE_TO_RESET,
6572      STATE_LOAD_COMMAND,
6673      STATE_READ_DATA
6774   };
6875
69   int state, bit, byte;
70   UINT8 shift;
71   UINT8 write_buffer[SIZE_WRITE_BUFFER];
72   UINT8 read_buffer[SIZE_READ_BUFFER];
73   UINT8 response_key[SIZE_KEY];
74   UINT8 response_to_reset[SIZE_RESPONSE_TO_RESET];
75   UINT8 command_key[SIZE_KEY];
76   UINT8 data_key[SIZE_KEY];
77   UINT8 data[SIZE_DATA];
76   // internal state
77   const char *m_ds2401_tag;
7878
79   void decrypt(UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte);
80   void decrypt2(UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT8 previous_byte);
81   void encrypt(UINT8 *destination, UINT8 *source, int length, UINT8 *key, UINT32 previous_byte);
82   UINT16 do_crc(UINT8 *buffer, UINT32 length);
83   int data_offset();
84
85private:
86   inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ...);
87
79   int m_cs;
80   int m_rst;
81   int m_scl;
82   int m_sdaw;
83   int m_sdar;
84   int m_state;
85   int m_shift;
86   int m_bit;
87   int m_byte;
88   UINT8 m_write_buffer[ 12 ];
89   UINT8 m_read_buffer[ 12 ];
90   UINT8 m_response_key[ 8 ];
91   UINT8 m_response_to_reset[ 4 ];
92   UINT8 m_command_key[ 8 ];
93   UINT8 m_data_key[ 8 ];
94   UINT8 m_data[ 4096 ];
8895   ds2401_device *m_ds2401;
8996};
9097

Previous 199869 Revisions Next


© 1997-2024 The MAME Team