turned znsec into a device [smf]

This commit is contained in:
smf- 2012-11-01 15:43:21 +00:00
parent cd30abae7a
commit 453e916ae5
5 changed files with 156 additions and 94 deletions

View File

@ -100,7 +100,4 @@ private:
devcb2_write_line m_irq1_handler; devcb2_write_line m_irq1_handler;
}; };
DECLARE_WRITE32_HANDLER( psx_sio_w );
DECLARE_READ32_HANDLER( psx_sio_r );
#endif #endif

View File

@ -332,8 +332,15 @@ Type 3 (PCMCIA Compact Flash Adaptor + Compact Flash card, sealed together with
class taitogn_state : public psx_state class taitogn_state : public psx_state
{ {
public: public:
taitogn_state(const machine_config &mconfig, device_type type, const char *tag) taitogn_state(const machine_config &mconfig, device_type type, const char *tag) :
: psx_state(mconfig, type, tag) { } psx_state(mconfig, type, tag),
m_znsec0(*this,"znsec0"),
m_znsec1(*this,"znsec1")
{
}
required_device<znsec_device> m_znsec0;
required_device<znsec_device> m_znsec1;
intel_te28f160_device *m_biosflash; intel_te28f160_device *m_biosflash;
intel_e28f400_device *m_pgmflash; intel_e28f400_device *m_pgmflash;
@ -690,15 +697,16 @@ static void sio_znsec0_handler( running_machine &machine, int n_data )
taitogn_state *state = machine.driver_data<taitogn_state>(); taitogn_state *state = machine.driver_data<taitogn_state>();
if( ( n_data & PSX_SIO_OUT_CLOCK ) == 0 ) if( ( n_data & PSX_SIO_OUT_CLOCK ) == 0 )
{ {
if( state->m_b_lastclock ) if( state->m_b_lastclock )
psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( znsec_step( 0, ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA ); psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( state->m_znsec0->step( ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA );
state->m_b_lastclock = 0;
} state->m_b_lastclock = 0;
}
else else
{ {
state->m_b_lastclock = 1; state->m_b_lastclock = 1;
} }
} }
static void sio_znsec1_handler( running_machine &machine, int n_data ) static void sio_znsec1_handler( running_machine &machine, int n_data )
@ -706,15 +714,16 @@ static void sio_znsec1_handler( running_machine &machine, int n_data )
taitogn_state *state = machine.driver_data<taitogn_state>(); taitogn_state *state = machine.driver_data<taitogn_state>();
if( ( n_data & PSX_SIO_OUT_CLOCK ) == 0 ) if( ( n_data & PSX_SIO_OUT_CLOCK ) == 0 )
{ {
if( state->m_b_lastclock ) if( state->m_b_lastclock )
psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( znsec_step( 1, ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA ); psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( state->m_znsec1->step( ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA );
state->m_b_lastclock = 0;
} state->m_b_lastclock = 0;
}
else else
{ {
state->m_b_lastclock = 1; state->m_b_lastclock = 1;
} }
} }
static void sio_pad_handler( running_machine &machine, int n_data ) static void sio_pad_handler( running_machine &machine, int n_data )
@ -722,13 +731,13 @@ static void sio_pad_handler( running_machine &machine, int n_data )
taitogn_state *state = machine.driver_data<taitogn_state>(); taitogn_state *state = machine.driver_data<taitogn_state>();
if( ( n_data & PSX_SIO_OUT_DTR ) != 0 ) if( ( n_data & PSX_SIO_OUT_DTR ) != 0 )
{ {
state->m_b_znsecport = 1; state->m_b_znsecport = 1;
} }
else else
{ {
state->m_b_znsecport = 0; state->m_b_znsecport = 0;
} }
psx_sio_input( machine, 0, PSX_SIO_IN_DATA | PSX_SIO_IN_DSR, PSX_SIO_IN_DATA | PSX_SIO_IN_DSR ); psx_sio_input( machine, 0, PSX_SIO_IN_DATA | PSX_SIO_IN_DSR, PSX_SIO_IN_DATA | PSX_SIO_IN_DSR );
} }
@ -758,33 +767,34 @@ WRITE32_MEMBER(taitogn_state::znsecsel_w)
{ {
COMBINE_DATA( &m_n_znsecsel ); COMBINE_DATA( &m_n_znsecsel );
m_znsec0->select( ( m_n_znsecsel >> 2 ) & 1 );
m_znsec1->select( ( m_n_znsecsel >> 3 ) & 1 );
if( ( m_n_znsecsel & 0x80 ) == 0 ) if( ( m_n_znsecsel & 0x80 ) == 0 )
{ {
psx_sio_install_handler( machine(), 0, sio_pad_handler ); psx_sio_install_handler( machine(), 0, sio_pad_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 ); psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
} }
else if( ( m_n_znsecsel & 0x08 ) == 0 ) else if( ( m_n_znsecsel & 0x08 ) == 0 )
{ {
znsec_start( 1 ); psx_sio_install_handler( machine(), 0, sio_znsec1_handler );
psx_sio_install_handler( machine(), 0, sio_znsec1_handler ); psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 ); }
}
else if( ( m_n_znsecsel & 0x04 ) == 0 ) else if( ( m_n_znsecsel & 0x04 ) == 0 )
{ {
znsec_start( 0 ); psx_sio_install_handler( machine(), 0, sio_znsec0_handler );
psx_sio_install_handler( machine(), 0, sio_znsec0_handler ); psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 ); }
}
else else
{ {
m_n_dip_bit = 0; m_n_dip_bit = 0;
m_b_lastclock = 1; m_b_lastclock = 1;
psx_sio_install_handler( machine(), 0, sio_dip_handler ); psx_sio_install_handler( machine(), 0, sio_dip_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 ); psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
m_dip_timer->adjust( downcast<cpu_device *>(&space.device())->cycles_to_attotime( 100 ), 1 ); m_dip_timer->adjust( downcast<cpu_device *>(&space.device())->cycles_to_attotime( 100 ), 1 );
} }
} }
TIMER_CALLBACK_MEMBER(taitogn_state::dip_timer_fired) TIMER_CALLBACK_MEMBER(taitogn_state::dip_timer_fired)
@ -869,8 +879,8 @@ DRIVER_INIT_MEMBER(taitogn_state,coh3002t)
m_sndflash[2] = machine().device<intel_te28f160_device>("sndflash2"); m_sndflash[2] = machine().device<intel_te28f160_device>("sndflash2");
psx_driver_init(machine()); psx_driver_init(machine());
znsec_init(0, tt10); m_znsec0->init(tt10);
znsec_init(1, tt16); m_znsec1->init(tt16);
psx_sio_install_handler(machine(), 0, sio_pad_handler); psx_sio_install_handler(machine(), 0, sio_pad_handler);
m_dip_timer = machine().scheduler().timer_alloc( timer_expired_delegate(FUNC(taitogn_state::dip_timer_fired),this), NULL ); m_dip_timer = machine().scheduler().timer_alloc( timer_expired_delegate(FUNC(taitogn_state::dip_timer_fired),this), NULL );
@ -941,6 +951,9 @@ static MACHINE_CONFIG_START( coh3002t, taitogn_state )
MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz ) MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz )
MCFG_CPU_PROGRAM_MAP(taitogn_map) MCFG_CPU_PROGRAM_MAP(taitogn_map)
MCFG_DEVICE_ADD("znsec0", ZNSEC, 0)
MCFG_DEVICE_ADD("znsec1", ZNSEC, 0)
/* video hardware */ /* video hardware */
MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz ) MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz )

View File

@ -34,11 +34,15 @@ class zn_state : public psx_state
public: public:
zn_state(const machine_config &mconfig, device_type type, const char *tag) : zn_state(const machine_config &mconfig, device_type type, const char *tag) :
psx_state(mconfig, type, tag), psx_state(mconfig, type, tag),
m_gpu(*this, "gpu") m_gpu(*this, "gpu"),
m_znsec0(*this,"znsec0"),
m_znsec1(*this,"znsec1")
{ {
} }
required_device<psxgpu_device> m_gpu; required_device<psxgpu_device> m_gpu;
required_device<znsec_device> m_znsec0;
required_device<znsec_device> m_znsec1;
UINT32 m_n_znsecsel; UINT32 m_n_znsecsel;
UINT32 m_b_znsecport; UINT32 m_b_znsecport;
int m_n_dip_bit; int m_n_dip_bit;
@ -323,8 +327,9 @@ static void sio_znsec0_handler( running_machine &machine, int n_data )
{ {
if( state->m_b_lastclock ) if( state->m_b_lastclock )
{ {
psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( znsec_step( 0, ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA ); psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( state->m_znsec0->step( ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA );
} }
state->m_b_lastclock = 0; state->m_b_lastclock = 0;
} }
else else
@ -341,8 +346,9 @@ static void sio_znsec1_handler( running_machine &machine, int n_data )
{ {
if( state->m_b_lastclock ) if( state->m_b_lastclock )
{ {
psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( znsec_step( 1, ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA ); psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( state->m_znsec1->step( ( n_data & PSX_SIO_OUT_DATA ) != 0 ) != 0 ) * PSX_SIO_IN_DATA );
} }
state->m_b_lastclock = 0; state->m_b_lastclock = 0;
} }
else else
@ -394,6 +400,9 @@ WRITE32_MEMBER(zn_state::znsecsel_w)
{ {
COMBINE_DATA( &m_n_znsecsel ); COMBINE_DATA( &m_n_znsecsel );
m_znsec0->select( ( m_n_znsecsel >> 2 ) & 1 );
m_znsec1->select( ( m_n_znsecsel >> 3 ) & 1 );
if( ( m_n_znsecsel & 0x80 ) == 0 ) if( ( m_n_znsecsel & 0x80 ) == 0 )
{ {
psx_sio_install_handler( machine(), 0, sio_pad_handler ); psx_sio_install_handler( machine(), 0, sio_pad_handler );
@ -401,13 +410,11 @@ WRITE32_MEMBER(zn_state::znsecsel_w)
} }
else if( ( m_n_znsecsel & 0x08 ) == 0 ) else if( ( m_n_znsecsel & 0x08 ) == 0 )
{ {
znsec_start( 1 );
psx_sio_install_handler( machine(), 0, sio_znsec1_handler ); psx_sio_install_handler( machine(), 0, sio_znsec1_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 ); psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
} }
else if( ( m_n_znsecsel & 0x04 ) == 0 ) else if( ( m_n_znsecsel & 0x04 ) == 0 )
{ {
znsec_start( 0 );
psx_sio_install_handler( machine(), 0, sio_znsec0_handler ); psx_sio_install_handler( machine(), 0, sio_znsec0_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 ); psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
} }
@ -527,8 +534,8 @@ static void zn_driver_init( running_machine &machine )
{ {
if( strcmp( machine.system().name, zn_config_table[ n_game ].s_name ) == 0 ) if( strcmp( machine.system().name, zn_config_table[ n_game ].s_name ) == 0 )
{ {
znsec_init( 0, zn_config_table[ n_game ].p_n_mainsec ); state->m_znsec0->init( zn_config_table[ n_game ].p_n_mainsec );
znsec_init( 1, zn_config_table[ n_game ].p_n_gamesec ); state->m_znsec1->init( zn_config_table[ n_game ].p_n_gamesec );
psx_sio_install_handler( machine, 0, sio_pad_handler ); psx_sio_install_handler( machine, 0, sio_pad_handler );
break; break;
} }
@ -551,6 +558,9 @@ static MACHINE_CONFIG_START( zn1_1mb_vram, zn_state )
MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz ) MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz )
MCFG_CPU_PROGRAM_MAP( zn_map) MCFG_CPU_PROGRAM_MAP( zn_map)
MCFG_DEVICE_ADD("znsec0", ZNSEC, 0)
MCFG_DEVICE_ADD("znsec1", ZNSEC, 0)
/* video hardware */ /* video hardware */
MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8561Q, 0x100000, XTAL_53_693175MHz ) MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8561Q, 0x100000, XTAL_53_693175MHz )
@ -573,6 +583,9 @@ static MACHINE_CONFIG_START( zn2, zn_state )
MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz ) MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz )
MCFG_CPU_PROGRAM_MAP( zn_map) MCFG_CPU_PROGRAM_MAP( zn_map)
MCFG_DEVICE_ADD("znsec0", ZNSEC, 0)
MCFG_DEVICE_ADD("znsec1", ZNSEC, 0)
/* video hardware */ /* video hardware */
MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz ) MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz )

View File

@ -82,17 +82,21 @@
= Shift(c[n-1, 6])^Shift(c[n-1, 7]) = Shift(c[n-1, 6])^Shift(c[n-1, 7])
*/ */
#include "emu.h"
#include "znsec.h" #include "znsec.h"
struct znsec_state { const device_type ZNSEC = &device_creator<znsec_device>;
const UINT8 *transform;
UINT8 state;
UINT8 bit;
};
static znsec_state zns[2]; znsec_device::znsec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, ZNSEC, "ZNSEC", tag, owner, clock)
{
}
void znsec_device::device_start()
{
save_item(NAME(m_select));
save_item(NAME(m_state));
save_item(NAME(m_bit));
}
// Given the value for x7..x0 and linear transform coefficients a7..a0 // Given the value for x7..x0 and linear transform coefficients a7..a0
// compute the value of the transform // compute the value of the transform
@ -111,71 +115,76 @@ static int c_linear(UINT8 x, UINT8 a)
#endif #endif
// Derive the sbox xor mask for a given input and select bit // Derive the sbox xor mask for a given input and select bit
static UINT8 compute_sbox_coef(int chip, int sel, int bit) UINT8 znsec_device::compute_sbox_coef(int sel, int bit)
{ {
UINT8 r;
if(!sel) if(!sel)
return zns[chip].transform[bit]; return m_transform[bit];
r = compute_sbox_coef(chip, (sel-1) & 7, (bit-1) & 7);
UINT8 r = compute_sbox_coef((sel-1) & 7, (bit-1) & 7);
r = (r << 1)|(((r >> 7)^(r >> 6)) & 1); r = (r << 1)|(((r >> 7)^(r >> 6)) & 1);
if(bit != 7) if(bit != 7)
return r; return r;
return r ^ compute_sbox_coef(chip, sel, 0); return r ^ compute_sbox_coef(sel, 0);
} }
// Apply the sbox for a input 0 bit // Apply the sbox for a input 0 bit
static UINT8 apply_bit_sbox(int chip, UINT8 state, int sel) void znsec_device::apply_bit_sbox(int sel)
{ {
int i; int i;
UINT8 r = 0; UINT8 r = 0;
for(i=0; i<8; i++) for(i=0; i<8; i++)
if(state & (1<<i)) if(m_state & (1<<i))
r ^= compute_sbox_coef(chip, sel, i); r ^= compute_sbox_coef(sel, i);
return r;
m_state = r;
} }
// Apply a sbox // Apply a sbox
static UINT8 apply_sbox(UINT8 state, const UINT8 *sbox) void znsec_device::apply_sbox(const UINT8 *sbox)
{ {
int i; int i;
UINT8 r = 0; UINT8 r = 0;
for(i=0; i<8; i++) for(i=0; i<8; i++)
if(state & (1<<i)) if(m_state & (1<<i))
r ^= sbox[i]; r ^= sbox[i];
return r;
m_state = r;
} }
void znsec_init(int chip, const UINT8 *transform) void znsec_device::init(const UINT8 *transform)
{ {
zns[chip].transform = transform; m_transform = transform;
zns[chip].state = 0xfc;
zns[chip].bit = 0;
} }
void znsec_start(int chip) void znsec_device::select(int select)
{ {
zns[chip].state = 0xfc; if (m_select && !select)
zns[chip].bit = 0; {
m_state = 0xfc;
m_bit = 0;
}
m_select = select;
} }
UINT8 znsec_step(int chip, UINT8 input) UINT8 znsec_device::step(UINT8 input)
{ {
UINT8 res; UINT8 res;
static const UINT8 initial_sbox[8] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x7f }; static const UINT8 initial_sbox[8] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x7f };
if (zns[chip].bit==0) if (m_bit==0)
{ {
// Apply the initial xbox // Apply the initial sbox
zns[chip].state = apply_sbox(zns[chip].state, initial_sbox); apply_sbox(initial_sbox);
} }
// Compute the output and change the state // Compute the output and change the state
res = (zns[chip].state>>zns[chip].bit) & 1; res = (m_state >> m_bit) & 1;
if((input & 1)==0) if((input & 1)==0)
zns[chip].state = apply_bit_sbox(chip, zns[chip].state, zns[chip].bit); apply_bit_sbox(m_bit);
zns[chip].bit++; m_bit++;
zns[chip].bit&=7; m_bit&=7;
return res; return res;
} }

View File

@ -1,5 +1,35 @@
/* CAT702 ZN security chip */ /* CAT702 ZN security chip */
void znsec_init(int chip, const UINT8 *transform); #pragma once
void znsec_start(int chip);
UINT8 znsec_step(int chip, UINT8 input); #ifndef __ZNSEC_H__
#define __ZNSEC_H__
#include "emu.h"
extern const device_type ZNSEC;
class znsec_device : public device_t
{
public:
znsec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
void init(const UINT8 *transform);
void select(int select);
UINT8 step(UINT8 input);
protected:
void device_start();
private:
UINT8 compute_sbox_coef(int sel, int bit);
void apply_bit_sbox(int sel);
void apply_sbox(const UINT8 *sbox);
const UINT8 *m_transform;
int m_select;
UINT8 m_state;
UINT8 m_bit;
};
#endif