mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
gamshara, konotako & startrgn now decrypt themselves on-the-fly (nw)
This commit is contained in:
parent
fb0b95c7b4
commit
1241e1de6f
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user