on-the-fly decryption support for chocovdr & nflclsfb (nw)

This commit is contained in:
andreasnaive 2015-08-05 18:47:40 +02:00
parent b6e1d3d986
commit 977221d7a5
3 changed files with 137 additions and 30 deletions

View File

@ -406,6 +406,10 @@ ADDRESS_MAP_END
WRITE16_MEMBER(namcos10_state::crypto_switch_w)
{
printf("crypto_switch_w: %04x\n", data);
if (decrypter == 0)
return;
if (BIT(data, 15) != 0)
decrypter->activate(data & 0xf);
else
@ -462,6 +466,9 @@ READ16_MEMBER( namcos10_state::nand_data_r )
/* printf( "data<-%08x (%08x)\n", data, nand_address ); */
nand_address++;
if (decrypter == 0)
return data;
if (decrypter->is_active())
return decrypter->decrypt(data);
else
@ -490,6 +497,7 @@ READ16_MEMBER(namcos10_state::nand_block_r)
static ADDRESS_MAP_START( namcos10_memn_map, AS_PROGRAM, 32, namcos10_state )
AM_RANGE(0x1f300000, 0x1f300003) AM_WRITE16(crypto_switch_w, 0x0000ffff)
AM_RANGE(0x1f380000, 0x1f380003) AM_WRITE16(crypto_switch_w, 0x0000ffff)
AM_RANGE(0x1f400000, 0x1f400003) AM_READ16(nand_status_r, 0x0000ffff)
AM_RANGE(0x1f410000, 0x1f410003) AM_WRITE8(nand_address1_w, 0x000000ff)
AM_RANGE(0x1f420000, 0x1f420003) AM_WRITE8(nand_address2_w, 0x000000ff)
@ -580,7 +588,9 @@ DRIVER_INIT_MEMBER(namcos10_state,gunbalna)
DRIVER_INIT_MEMBER(namcos10_state,chocovdr)
{
int regSize = machine().root_device().memregion("user2")->bytes();
decrypt_bios(machine(), "user2", 0x8400, regSize, 0x5, 0x4, 0x6, 0x7, 0x1, 0x0, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x0008400, 0x0029400, 0x5, 0x4, 0x6, 0x7, 0x1, 0x0, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x01eae00, 0x105ae00, 0x5, 0x4, 0x6, 0x7, 0x1, 0x0, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x1080000, regSize , 0x5, 0x4, 0x6, 0x7, 0x1, 0x0, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x8, 0xb, 0xa, 0x9);
memn_driver_init();
}
@ -594,7 +604,9 @@ DRIVER_INIT_MEMBER(namcos10_state,panikuru)
DRIVER_INIT_MEMBER(namcos10_state,nflclsfb)
{
int regSize = machine().root_device().memregion("user2")->bytes();
decrypt_bios(machine(), "user2", 0x8400, regSize, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x0008400, 0x0029400, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x0214200, 0x105ae00, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x1080000, regSize , 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
memn_driver_init();
}
@ -646,14 +658,9 @@ static MACHINE_CONFIG_START( namcos10_memn, namcos10_state )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_konotako, namcos10_memn)
static MACHINE_CONFIG_DERIVED(ns10_chocovdr, namcos10_memn)
/* decrypter device (CPLD in hardware?) */
MCFG_DEVICE_ADD("decrypter", KONOTAKO_DECRYPTER, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_startrgn, namcos10_memn)
/* decrypter device (CPLD in hardware?) */
MCFG_DEVICE_ADD("decrypter", STARTRGN_DECRYPTER, 0)
MCFG_DEVICE_ADD("decrypter", CHOCOVDR_DECRYPTER, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_gamshara, namcos10_memn)
@ -661,6 +668,21 @@ static MACHINE_CONFIG_DERIVED(ns10_gamshara, namcos10_memn)
MCFG_DEVICE_ADD("decrypter", GAMSHARA_DECRYPTER, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_konotako, namcos10_memn)
/* decrypter device (CPLD in hardware?) */
MCFG_DEVICE_ADD("decrypter", KONOTAKO_DECRYPTER, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_nflclsfb, namcos10_memn)
/* decrypter device (CPLD in hardware?) */
MCFG_DEVICE_ADD("decrypter", NFLCLSFB_DECRYPTER, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_startrgn, namcos10_memn)
/* decrypter device (CPLD in hardware?) */
MCFG_DEVICE_ADD("decrypter", STARTRGN_DECRYPTER, 0)
MACHINE_CONFIG_END
static INPUT_PORTS_START( namcos10 )
/* IN 0 */
PORT_START("SYSTEM")
@ -862,9 +884,9 @@ GAME( 2001, gjspace, 0, namcos10_memn, namcos10, namcos10_state, gjspac
GAME( 2001, mrdrilrg, 0, namcos10_memn, namcos10, namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
GAME( 2001, mrdrilrga, mrdrilrg, namcos10_memn, namcos10, namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G ALT (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
GAME( 2001, knpuzzle, 0, namcos10_memn, namcos10, namcos10_state, knpuzzle, ROT0, "Namco", "Kotoba no Puzzle Mojipittan (Japan, KPM1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2002, chocovdr, 0, namcos10_memn, namcos10, namcos10_state, chocovdr, ROT0, "Namco", "Uchuu Daisakusen: Chocovader Contactee (Japan, CVC1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2002, chocovdr, 0, ns10_chocovdr, namcos10, namcos10_state, chocovdr, ROT0, "Namco", "Uchuu Daisakusen: Chocovader Contactee (Japan, CVC1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2002, startrgn, 0, ns10_startrgn, namcos10, namcos10_state, startrgn, ROT0, "Namco", "Star Trigon (Japan, STT1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
GAME( 2002, panikuru, 0, namcos10_memn, namcos10, namcos10_state, panikuru, ROT0, "Namco", "Panicuru Panekuru (Japan, PPA1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2003, nflclsfb, 0, namcos10_memn, namcos10, namcos10_state, nflclsfb, ROT0, "Namco", "NFL Classic Football (US, NCF3 Ver.A.)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2003, nflclsfb, 0, ns10_nflclsfb, namcos10, namcos10_state, nflclsfb, ROT0, "Namco", "NFL Classic Football (US, NCF3 Ver.A.)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2003, gamshara, 0, ns10_gamshara, namcos10, namcos10_state, gamshara, ROT0, "Mitchell", "Gamshara (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2003, konotako, 0, ns10_konotako, namcos10, namcos10_state, konotako, ROT0, "Mitchell", "Kono Tako (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)

View File

@ -84,8 +84,10 @@ really exist.
#include "emu.h"
#include "ns10crypt.h"
const device_type CHOCOVDR_DECRYPTER = &device_creator<chocovdr_decrypter_device>;
const device_type GAMSHARA_DECRYPTER = &device_creator<gamshara_decrypter_device>;
const device_type KONOTAKO_DECRYPTER = &device_creator<konotako_decrypter_device>;
const device_type NFLCLSFB_DECRYPTER = &device_creator<nflclsfb_decrypter_device>;
const device_type STARTRGN_DECRYPTER = &device_creator<startrgn_decrypter_device>;
// this could perfectly be part of the per-game logic; by now, only gamshara seems to use it, so we keep it global
@ -127,16 +129,30 @@ UINT16 ns10_decrypter_device::decrypt(UINT16 cipherword)
for (int j = 15; j >= 0; --j)
{
_mask <<= 1;
_mask ^= gf2_reduce(_logic.eMask[j] & _previous_cipherwords);
_mask ^= gf2_reduce(_logic.dMask[j] & _previous_plainwords);
_mask ^= _reducer.gf2_reduce(_logic.eMask[j] & _previous_cipherwords);
_mask ^= _reducer.gf2_reduce(_logic.dMask[j] & _previous_plainwords);
}
_mask ^= _logic.xMask;
_mask ^= _logic.nonlinear_calculation(_previous_cipherwords, _previous_plainwords);
_mask ^= _logic.nonlinear_calculation(_previous_cipherwords, _previous_plainwords, _reducer);
return plainword;
}
void ns10_decrypter_device::device_start()
{
_active = false;
}
void ns10_decrypter_device::init(int iv)
{
// by now, only gamshara requires non-trivial initialization code; data
// should be moved to the per-game logic in case any other game do it differently
_previous_cipherwords = BITSWAP16(initSbox[iv],3,16,16,2,1,16,16,0,16,16,16,16,16,16,16,16);
_previous_plainwords = 0;
_mask = 0;
}
gf2_reducer::gf2_reducer()
{
int reduction;
@ -151,16 +167,7 @@ void ns10_decrypter_device::device_start()
}
}
void ns10_decrypter_device::init(int iv)
{
// by now, only gamshara requires non-trivial initialization code; data
// should be moved to the per-game logic in case any other game do it differently
_previous_cipherwords = BITSWAP16(initSbox[iv],3,16,16,2,1,16,16,0,16,16,16,16,16,16,16,16);
_previous_plainwords = 0;
_mask = 0;
}
int ns10_decrypter_device::gf2_reduce(UINT64 num)
int gf2_reducer::gf2_reduce(UINT64 num)const
{
return
_gf2Reduction[num & 0xffff] ^
@ -172,7 +179,29 @@ int ns10_decrypter_device::gf2_reduce(UINT64 num)
// game-specific logic
static UINT16 gamshara_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
static UINT16 chocovdr_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
return ((previous_masks >> 9) & (reducer.gf2_reduce(0x0000000010065810ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000021005810ull & previous_plainwords)) & 1) << 10;
}
static const ns10_decrypter_device::ns10_crypto_logic chocovdr_crypto_logic = {
{
0x00005239351ec1daull, 0x0000000000008090ull, 0x0000000048264808ull, 0x0000000000004820ull,
0x0000000000000500ull, 0x0000000058ff5a54ull, 0x00000000d8220208ull, 0x00005239351e91d3ull,
0x000000009a1dfaffull, 0x0000000090040001ull, 0x0000000000000100ull, 0x0000000000001408ull,
0x0000000032efd3f1ull, 0x00000000000000d0ull, 0x0000000032efd2d7ull, 0x0000000000000840ull,
}, {
0x00002000410485daull, 0x0000000000008081ull, 0x0000000008044088ull, 0x0000000000004802ull,
0x0000000000000500ull, 0x00000000430cda54ull, 0x0000000010000028ull, 0x00002000410491dbull,
0x000000001100fafeull, 0x0000000018040001ull, 0x0000000000000010ull, 0x0000000000000508ull,
0x000000006800d3f5ull, 0x0000000000000058ull, 0x000000006800d2d5ull, 0x0000000000001840ull,
},
0x5b22,
chocovdr_nonlinear_calc
};
static UINT16 gamshara_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
return ((previous_masks >> 7) & (previous_masks >> 13) & 1) << 2;
@ -194,7 +223,7 @@ static const ns10_decrypter_device::ns10_crypto_logic gamshara_crypto_logic = {
gamshara_nonlinear_calc
};
static UINT16 konotako_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
static UINT16 konotako_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
return ((previous_masks >> 7) & (previous_masks >> 15) & 1) << 15;
@ -216,7 +245,29 @@ static const ns10_decrypter_device::ns10_crypto_logic konotako_crypto_logic = {
konotako_nonlinear_calc
};
static UINT16 startrgn_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
static UINT16 nflclsfb_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
return ((previous_masks >> 1) & (reducer.gf2_reduce(0x0000000040de8fb3ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000088008fb3ull & previous_plainwords)) & 1) << 2;
}
static const ns10_decrypter_device::ns10_crypto_logic nflclsfb_crypto_logic = {
{
0x000034886e281880ull, 0x0000000012c5e7baull, 0x0000000000000200ull, 0x000000002900002aull,
0x00000000000004c0ull, 0x0000000012c5e6baull, 0x00000000e0df8bbbull, 0x000000002011532aull,
0x0000000000009040ull, 0x0000000000006004ull, 0x000000000000a001ull, 0x000034886e2818e1ull,
0x0000000000004404ull, 0x0000000000004200ull, 0x0000000000009100ull, 0x0000000020115712ull,
}, {
0x00000e00060819c0ull, 0x000000000e08e7baull, 0x0000000000000800ull, 0x000000000100002aull,
0x00000000000010c0ull, 0x000000000e08cebaull, 0x0000000088018bbbull, 0x000000008c005302ull,
0x000000000000c040ull, 0x0000000000006010ull, 0x0000000000000001ull, 0x00000e00060818e3ull,
0x0000000000000404ull, 0x0000000000004201ull, 0x0000000000001100ull, 0x000000008c0057b2ull,
},
0xbe32,
nflclsfb_nonlinear_calc
};
static UINT16 startrgn_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
return ((previous_masks >> 12) & (previous_masks >> 14) & 1) << 4;
@ -241,6 +292,11 @@ static const ns10_decrypter_device::ns10_crypto_logic startrgn_crypto_logic = {
// game-specific devices
chocovdr_decrypter_device::chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ns10_decrypter_device(CHOCOVDR_DECRYPTER, chocovdr_crypto_logic, mconfig, tag, owner, clock)
{
}
gamshara_decrypter_device::gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ns10_decrypter_device(GAMSHARA_DECRYPTER, gamshara_crypto_logic, mconfig, tag, owner, clock)
{
@ -251,6 +307,11 @@ konotako_decrypter_device::konotako_decrypter_device(const machine_config &mconf
{
}
nflclsfb_decrypter_device::nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ns10_decrypter_device(NFLCLSFB_DECRYPTER, nflclsfb_crypto_logic, mconfig, tag, owner, clock)
{
}
startrgn_decrypter_device::startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ns10_decrypter_device(STARTRGN_DECRYPTER, startrgn_crypto_logic, mconfig, tag, owner, clock)
{

View File

@ -4,6 +4,15 @@
#ifndef _NS10CRYPT_H_
#define _NS10CRYPT_H_
class gf2_reducer // helper class
{
public:
gf2_reducer();
int gf2_reduce(UINT64 num)const;
private:
int _gf2Reduction[0x10000];
};
class ns10_decrypter_device : public device_t
{
public:
@ -14,7 +23,7 @@ public:
UINT64 eMask[16];
UINT64 dMask[16];
UINT16 xMask;
UINT16(*nonlinear_calculation)(UINT64, UINT64); // preliminary encoding; need research
UINT16(*nonlinear_calculation)(UINT64, UINT64, const gf2_reducer&); // preliminary encoding; need research
};
void activate(int iv);
@ -34,16 +43,23 @@ private:
UINT64 _previous_plainwords;
bool _active;
const ns10_crypto_logic& _logic;
int _gf2Reduction[0x10000];
static const int initSbox[16];
const gf2_reducer _reducer;
void device_start();
void init(int iv);
int gf2_reduce(UINT64 num);
};
// game-specific devices
class chocovdr_decrypter_device : public ns10_decrypter_device
{
public:
chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class gamshara_decrypter_device : public ns10_decrypter_device
{
public:
@ -56,6 +72,12 @@ public:
konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class nflclsfb_decrypter_device : public ns10_decrypter_device
{
public:
nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class startrgn_decrypter_device : public ns10_decrypter_device
{
public:
@ -63,8 +85,10 @@ public:
};
extern const device_type CHOCOVDR_DECRYPTER;
extern const device_type GAMSHARA_DECRYPTER;
extern const device_type KONOTAKO_DECRYPTER;
extern const device_type NFLCLSFB_DECRYPTER;
extern const device_type STARTRGN_DECRYPTER;
#endif