mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
turned znsec into a device [smf]
This commit is contained in:
parent
cd30abae7a
commit
453e916ae5
@ -100,7 +100,4 @@ private:
|
||||
devcb2_write_line m_irq1_handler;
|
||||
};
|
||||
|
||||
DECLARE_WRITE32_HANDLER( psx_sio_w );
|
||||
DECLARE_READ32_HANDLER( psx_sio_r );
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
@ -690,15 +697,16 @@ static void sio_znsec0_handler( running_machine &machine, int n_data )
|
||||
taitogn_state *state = machine.driver_data<taitogn_state>();
|
||||
|
||||
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 );
|
||||
state->m_b_lastclock = 0;
|
||||
}
|
||||
{
|
||||
if( state->m_b_lastclock )
|
||||
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
|
||||
{
|
||||
state->m_b_lastclock = 1;
|
||||
}
|
||||
{
|
||||
state->m_b_lastclock = 1;
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
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 );
|
||||
state->m_b_lastclock = 0;
|
||||
}
|
||||
{
|
||||
if( state->m_b_lastclock )
|
||||
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
|
||||
{
|
||||
state->m_b_lastclock = 1;
|
||||
}
|
||||
{
|
||||
state->m_b_lastclock = 1;
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
if( ( n_data & PSX_SIO_OUT_DTR ) != 0 )
|
||||
{
|
||||
state->m_b_znsecport = 1;
|
||||
}
|
||||
{
|
||||
state->m_b_znsecport = 1;
|
||||
}
|
||||
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 );
|
||||
}
|
||||
@ -758,33 +767,34 @@ 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 );
|
||||
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
|
||||
}
|
||||
{
|
||||
psx_sio_install_handler( machine(), 0, sio_pad_handler );
|
||||
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
{
|
||||
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 );
|
||||
}
|
||||
{
|
||||
psx_sio_install_handler( machine(), 0, sio_znsec0_handler );
|
||||
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_n_dip_bit = 0;
|
||||
m_b_lastclock = 1;
|
||||
{
|
||||
m_n_dip_bit = 0;
|
||||
m_b_lastclock = 1;
|
||||
|
||||
psx_sio_install_handler( machine(), 0, sio_dip_handler );
|
||||
psx_sio_input( machine(), 0, PSX_SIO_IN_DSR, 0 );
|
||||
psx_sio_install_handler( machine(), 0, sio_dip_handler );
|
||||
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)
|
||||
@ -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 )
|
||||
|
||||
|
@ -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 )
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
m_select = select;
|
||||
}
|
||||
|
||||
UINT8 znsec_step(int chip, UINT8 input)
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user