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;
};
DECLARE_WRITE32_HANDLER( psx_sio_w );
DECLARE_READ32_HANDLER( psx_sio_r );
#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
{
public:
taitogn_state(const machine_config &mconfig, device_type type, const char *tag)
: psx_state(mconfig, type, tag) { }
taitogn_state(const machine_config &mconfig, device_type type, const char *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_e28f400_device *m_pgmflash;
@ -692,7 +699,8 @@ static void sio_znsec0_handler( running_machine &machine, int n_data )
if( ( n_data & PSX_SIO_OUT_CLOCK ) == 0 )
{
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;
}
else
@ -708,7 +716,8 @@ static void sio_znsec1_handler( running_machine &machine, int n_data )
if( ( n_data & PSX_SIO_OUT_CLOCK ) == 0 )
{
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;
}
else
@ -758,6 +767,9 @@ WRITE32_MEMBER(taitogn_state::znsecsel_w)
{
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 )
{
psx_sio_install_handler( machine(), 0, sio_pad_handler );
@ -765,13 +777,11 @@ WRITE32_MEMBER(taitogn_state::znsecsel_w)
}
else if( ( m_n_znsecsel & 0x08 ) == 0 )
{
znsec_start( 1 );
psx_sio_install_handler( machine(), 0, sio_znsec1_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
}
else if( ( m_n_znsecsel & 0x04 ) == 0 )
{
znsec_start( 0 );
psx_sio_install_handler( machine(), 0, sio_znsec0_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
}
@ -869,8 +879,8 @@ DRIVER_INIT_MEMBER(taitogn_state,coh3002t)
m_sndflash[2] = machine().device<intel_te28f160_device>("sndflash2");
psx_driver_init(machine());
znsec_init(0, tt10);
znsec_init(1, tt16);
m_znsec0->init(tt10);
m_znsec1->init(tt16);
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 );
@ -941,6 +951,9 @@ static MACHINE_CONFIG_START( coh3002t, taitogn_state )
MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz )
MCFG_CPU_PROGRAM_MAP(taitogn_map)
MCFG_DEVICE_ADD("znsec0", ZNSEC, 0)
MCFG_DEVICE_ADD("znsec1", ZNSEC, 0)
/* video hardware */
MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8654Q, 0x200000, XTAL_53_693175MHz )

View File

@ -34,11 +34,15 @@ class zn_state : public psx_state
public:
zn_state(const machine_config &mconfig, device_type type, const char *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<znsec_device> m_znsec0;
required_device<znsec_device> m_znsec1;
UINT32 m_n_znsecsel;
UINT32 m_b_znsecport;
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 )
{
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;
}
else
@ -341,8 +346,9 @@ static void sio_znsec1_handler( running_machine &machine, int n_data )
{
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;
}
else
@ -394,6 +400,9 @@ WRITE32_MEMBER(zn_state::znsecsel_w)
{
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 )
{
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 )
{
znsec_start( 1 );
psx_sio_install_handler( machine(), 0, sio_znsec1_handler );
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
}
else if( ( m_n_znsecsel & 0x04 ) == 0 )
{
znsec_start( 0 );
psx_sio_install_handler( machine(), 0, sio_znsec0_handler );
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 )
{
znsec_init( 0, zn_config_table[ n_game ].p_n_mainsec );
znsec_init( 1, zn_config_table[ n_game ].p_n_gamesec );
state->m_znsec0->init( zn_config_table[ n_game ].p_n_mainsec );
state->m_znsec1->init( zn_config_table[ n_game ].p_n_gamesec );
psx_sio_install_handler( machine, 0, sio_pad_handler );
break;
}
@ -551,6 +558,9 @@ static MACHINE_CONFIG_START( zn1_1mb_vram, zn_state )
MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz )
MCFG_CPU_PROGRAM_MAP( zn_map)
MCFG_DEVICE_ADD("znsec0", ZNSEC, 0)
MCFG_DEVICE_ADD("znsec1", ZNSEC, 0)
/* video hardware */
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_PROGRAM_MAP( zn_map)
MCFG_DEVICE_ADD("znsec0", ZNSEC, 0)
MCFG_DEVICE_ADD("znsec1", ZNSEC, 0)
/* video hardware */
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])
*/
#include "emu.h"
#include "znsec.h"
struct znsec_state {
const UINT8 *transform;
UINT8 state;
UINT8 bit;
};
const device_type ZNSEC = &device_creator<znsec_device>;
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
// compute the value of the transform
@ -111,71 +115,76 @@ static int c_linear(UINT8 x, UINT8 a)
#endif
// 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)
return zns[chip].transform[bit];
r = compute_sbox_coef(chip, (sel-1) & 7, (bit-1) & 7);
return m_transform[bit];
UINT8 r = compute_sbox_coef((sel-1) & 7, (bit-1) & 7);
r = (r << 1)|(((r >> 7)^(r >> 6)) & 1);
if(bit != 7)
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
static UINT8 apply_bit_sbox(int chip, UINT8 state, int sel)
void znsec_device::apply_bit_sbox(int sel)
{
int i;
UINT8 r = 0;
for(i=0; i<8; i++)
if(state & (1<<i))
r ^= compute_sbox_coef(chip, sel, i);
return r;
if(m_state & (1<<i))
r ^= compute_sbox_coef(sel, i);
m_state = r;
}
// Apply a sbox
static UINT8 apply_sbox(UINT8 state, const UINT8 *sbox)
void znsec_device::apply_sbox(const UINT8 *sbox)
{
int i;
UINT8 r = 0;
for(i=0; i<8; i++)
if(state & (1<<i))
if(m_state & (1<<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;
zns[chip].state = 0xfc;
zns[chip].bit = 0;
m_transform = transform;
}
void znsec_start(int chip)
void znsec_device::select(int select)
{
zns[chip].state = 0xfc;
zns[chip].bit = 0;
if (m_select && !select)
{
m_state = 0xfc;
m_bit = 0;
}
UINT8 znsec_step(int chip, UINT8 input)
m_select = select;
}
UINT8 znsec_device::step(UINT8 input)
{
UINT8 res;
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
zns[chip].state = apply_sbox(zns[chip].state, initial_sbox);
// Apply the initial sbox
apply_sbox(initial_sbox);
}
// 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)
zns[chip].state = apply_bit_sbox(chip, zns[chip].state, zns[chip].bit);
apply_bit_sbox(m_bit);
zns[chip].bit++;
zns[chip].bit&=7;
m_bit++;
m_bit&=7;
return res;
}

View File

@ -1,5 +1,35 @@
/* CAT702 ZN security chip */
void znsec_init(int chip, const UINT8 *transform);
void znsec_start(int chip);
UINT8 znsec_step(int chip, UINT8 input);
#pragma once
#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