gamshara, konotako & startrgn now decrypt themselves on-the-fly (nw)

This commit is contained in:
andreasnaive 2015-08-04 22:07:55 +02:00
parent fb0b95c7b4
commit 1241e1de6f
3 changed files with 89 additions and 31 deletions

View File

@ -407,7 +407,7 @@ ADDRESS_MAP_END
WRITE16_MEMBER(namcos10_state::crypto_switch_w)
{
if (BIT(data, 15) != 0)
decrypter->activate();
decrypter->activate(data & 0xf);
else
decrypter->deactivate();
}
@ -555,16 +555,18 @@ DRIVER_INIT_MEMBER(namcos10_state,knpuzzle)
DRIVER_INIT_MEMBER(namcos10_state,startrgn)
{
int regSize = machine().root_device().memregion("user2")->bytes();
decrypt_bios(machine(), "user2", 0x008400, 0x028000, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x0b4000, 0xfdc000, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x1000000, regSize, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
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", 0x00b9a00, 0x105ae00, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
decrypt_bios(machine(), "user2", 0x1080000, regSize , 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
memn_driver_init();
}
DRIVER_INIT_MEMBER(namcos10_state,gamshara)
{
int regSize = machine().root_device().memregion("user2")->bytes();
decrypt_bios(machine(), "user2", 0x8400, regSize, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x8, 0x9, 0xa, 0xb);
decrypt_bios(machine(), "user2", 0x0008400, 0x0029400, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x8, 0x9, 0xa, 0xb);
decrypt_bios(machine(), "user2", 0x014e200, 0x105ae00, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x8, 0x9, 0xa, 0xb);
decrypt_bios(machine(), "user2", 0x1080000, regSize , 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x8, 0x9, 0xa, 0xb);
memn_driver_init();
}
@ -599,9 +601,9 @@ DRIVER_INIT_MEMBER(namcos10_state,nflclsfb)
DRIVER_INIT_MEMBER(namcos10_state,konotako)
{
int regSize = machine().root_device().memregion("user2")->bytes();
decrypt_bios(machine(), "user2", 0x008400, 0x028000, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
decrypt_bios(machine(), "user2", 0x0b4000, 0xfdc000, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
decrypt_bios(machine(), "user2", 0x1000000, regSize, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
decrypt_bios(machine(), "user2", 0x0008400, 0x0029400, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
decrypt_bios(machine(), "user2", 0x00b9a00, 0x105ae00, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
decrypt_bios(machine(), "user2", 0x1080000, regSize , 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
memn_driver_init();
}
@ -654,6 +656,11 @@ static MACHINE_CONFIG_DERIVED(ns10_startrgn, namcos10_memn)
MCFG_DEVICE_ADD("decrypter", STARTRGN_DECRYPTER, 0)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(ns10_gamshara, namcos10_memn)
/* decrypter device (CPLD in hardware?) */
MCFG_DEVICE_ADD("decrypter", GAMSHARA_DECRYPTER, 0)
MACHINE_CONFIG_END
static INPUT_PORTS_START( namcos10 )
/* IN 0 */
PORT_START("SYSTEM")
@ -847,17 +854,17 @@ ROM_START( konotako )
ROM_END
GAME( 2000, mrdrilr2, 0, namcos10_memm, namcos10, namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Japan, DR21 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
GAME( 2000, mrdrlr2a, mrdrilr2, namcos10_memm, namcos10, namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Asia, DR22 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
GAME( 2000, ptblank3, 0, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2001, gjspace, 0, namcos10_memn, namcos10, namcos10_state, gjspace, ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
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, 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, gamshara, 0, namcos10_memn, 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)
GAME( 2000, mrdrilr2, 0, namcos10_memm, namcos10, namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Japan, DR21 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
GAME( 2000, mrdrlr2a, mrdrilr2, namcos10_memm, namcos10, namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Asia, DR22 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
GAME( 2000, ptblank3, 0, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
GAME( 2001, gjspace, 0, namcos10_memn, namcos10, namcos10_state, gjspace, ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
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, 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, 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

@ -25,9 +25,11 @@ some bootup code has been executed, will copy the encrypted content from
the ROM to RAM, moment at which the decryption is triggered.
Most games do a single decryption run, so the process is only initialized once;
however, at least one game (gamshara) does write to the triggering registers
however, at least one game (gamshara) does write to the triggering register
more than once, effectively resetting the internal state of the decrypter
several times. (gamshara do it every 5 NAND blocks).
several times. (gamshara do it every 5 NAND blocks; the lowest nibble written to
the register seem to control the initial value of the state; see details in the
implementation).
The calculation of the XOR masks seem to operate this way: most bits are
calculated by using linear equations over GF(2) taking as input data the bits from
@ -53,6 +55,13 @@ panikuru -> #2
ptblank3 -> #11
startrgn -> #4
Overall, the values used as linear masks, those from the initSbox and
the values and bit order used at initialization time are not expected to
be exactly the ones used by the hardware; given the many degrees of freedom
caused by the nature of the scheme, the whole set of values should
be considered as a representative of a class of equivalence of functionally
equivalent datasets, nothing else.
TO-DO:
* Research the nonlinear calculations in most of the games.
@ -75,9 +84,13 @@ really exist.
#include "emu.h"
#include "ns10crypt.h"
const device_type GAMSHARA_DECRYPTER = &device_creator<gamshara_decrypter_device>;
const device_type KONOTAKO_DECRYPTER = &device_creator<konotako_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
const int ns10_decrypter_device::initSbox[16] = {0,12,13,6,2,4,9,8,11,1,7,15,10,5,14,3};
ns10_decrypter_device::ns10_decrypter_device(device_type type, const ns10_crypto_logic &logic, const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, type, "Namco System 10 Decrypter", tag, owner, clock, "ns10_crypto", __FILE__)
, _active(false)
@ -85,9 +98,9 @@ ns10_decrypter_device::ns10_decrypter_device(device_type type, const ns10_crypto
{
}
void ns10_decrypter_device::activate()
void ns10_decrypter_device::activate(int iv)
{
init();
init(iv);
_active = true;
}
@ -109,7 +122,7 @@ UINT16 ns10_decrypter_device::decrypt(UINT16 cipherword)
_previous_cipherwords ^= cipherword;
_previous_plainwords <<= 16;
_previous_plainwords ^= plainword;
_mask = 0;
for (int j = 15; j >= 0; --j)
{
@ -138,9 +151,11 @@ void ns10_decrypter_device::device_start()
}
}
void ns10_decrypter_device::init()
void ns10_decrypter_device::init(int iv)
{
_previous_cipherwords = 0;
// 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;
}
@ -157,6 +172,28 @@ int ns10_decrypter_device::gf2_reduce(UINT64 num)
// game-specific logic
static UINT16 gamshara_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
return ((previous_masks >> 7) & (previous_masks >> 13) & 1) << 2;
}
static const ns10_decrypter_device::ns10_crypto_logic gamshara_crypto_logic = {
{
0x0000000000000028ull, 0x0000cae83f389fd9ull, 0x0000000000001000ull, 0x0000000042823402ull,
0x0000cae8736a0592ull, 0x0000cae8736a8596ull, 0x000000008b4095b9ull, 0x0000000000002100ull,
0x0000000004018228ull, 0x0000000000000042ull, 0x0000000000000818ull, 0x0000000000004010ull,
0x000000008b4099f1ull, 0x00000000044bce08ull, 0x00000000000000c1ull, 0x0000000042823002ull,
}, {
0x0000000000000028ull, 0x00000904c2048dd9ull, 0x0000000000008000ull, 0x0000000054021002ull,
0x00000904e0078592ull, 0x00000904e00785b2ull, 0x00000000440097f9ull, 0x0000000000002104ull,
0x0000000029018308ull, 0x0000000000000042ull, 0x0000000000000850ull, 0x0000000000004012ull,
0x000000004400d1f1ull, 0x000000006001ce08ull, 0x00000000000000c8ull, 0x0000000054023002ull,
},
0x25ab,
gamshara_nonlinear_calc
};
static UINT16 konotako_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
{
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
@ -201,8 +238,14 @@ static const ns10_decrypter_device::ns10_crypto_logic startrgn_crypto_logic = {
startrgn_nonlinear_calc
};
// game-specific devices
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)
{
}
konotako_decrypter_device::konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ns10_decrypter_device(KONOTAKO_DECRYPTER, konotako_crypto_logic, mconfig, tag, owner, clock)
{

View File

@ -17,7 +17,7 @@ public:
UINT16(*nonlinear_calculation)(UINT64, UINT64); // preliminary encoding; need research
};
void activate();
void activate(int iv);
void deactivate();
bool is_active()const;
@ -35,14 +35,21 @@ private:
bool _active;
const ns10_crypto_logic& _logic;
int _gf2Reduction[0x10000];
static const int initSbox[16];
void device_start();
void init();
void init(int iv);
int gf2_reduce(UINT64 num);
};
// game-specific devices
class gamshara_decrypter_device : public ns10_decrypter_device
{
public:
gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class konotako_decrypter_device : public ns10_decrypter_device
{
public:
@ -56,6 +63,7 @@ public:
};
extern const device_type GAMSHARA_DECRYPTER;
extern const device_type KONOTAKO_DECRYPTER;
extern const device_type STARTRGN_DECRYPTER;