mirror of
https://github.com/holub/mame
synced 2025-04-26 10:13:37 +03:00
on-the-fly decryption support for mrdrilr2
This commit is contained in:
parent
8ab7875e89
commit
d501f35e96
@ -279,12 +279,11 @@ public:
|
||||
m_maincpu(*this, "maincpu") { }
|
||||
|
||||
// memm variant interface
|
||||
DECLARE_WRITE16_MEMBER(key_w);
|
||||
DECLARE_WRITE16_MEMBER(crypto_switch_w);
|
||||
DECLARE_READ16_MEMBER(range_r);
|
||||
DECLARE_WRITE16_MEMBER(bank_w);
|
||||
|
||||
// memn variant interface
|
||||
DECLARE_WRITE16_MEMBER(crypto_switch_w);
|
||||
DECLARE_READ16_MEMBER(nand_status_r);
|
||||
DECLARE_WRITE8_MEMBER(nand_address1_w);
|
||||
DECLARE_WRITE8_MEMBER(nand_address2_w);
|
||||
@ -316,7 +315,6 @@ private:
|
||||
I2CP_RECIEVE_ACK_0
|
||||
};
|
||||
UINT16 key;
|
||||
UINT8 cnt;
|
||||
UINT32 bank_base;
|
||||
UINT32 nand_address;
|
||||
UINT16 block[0x1ff];
|
||||
@ -369,55 +367,36 @@ ADDRESS_MAP_END
|
||||
// know until the decryption is done.
|
||||
//
|
||||
// bios copies 62000-37ffff from the flash to 80012000 in ram through the
|
||||
// decryption in range_r then jumps there (and dies horribly, of course)
|
||||
// decryption in range_r then jumps there
|
||||
|
||||
WRITE16_MEMBER(namcos10_state::key_w )
|
||||
WRITE16_MEMBER(namcos10_state::crypto_switch_w)
|
||||
{
|
||||
key = (data >> 15) | (data << 1);
|
||||
logerror("key_w %04x\n", key);
|
||||
cnt = 0;
|
||||
printf("crypto_switch_w: %04x\n", data);
|
||||
if (decrypter == nullptr)
|
||||
return;
|
||||
|
||||
if (BIT(data, 15) != 0)
|
||||
decrypter->activate(data & 0xf);
|
||||
else
|
||||
decrypter->deactivate();
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(namcos10_state::bank_w)
|
||||
{
|
||||
bank_base = 0x80000 * offset;
|
||||
bank_base = 0x100000 * offset;
|
||||
}
|
||||
|
||||
READ16_MEMBER(namcos10_state::range_r)
|
||||
{
|
||||
UINT32 d16 = ((const UINT16 *)(memregion("maincpu:rom")->base()))[offset+bank_base];
|
||||
UINT16 data = ((const UINT16 *)(memregion("maincpu:rom")->base()))[bank_base+offset];
|
||||
|
||||
/* This is not entirely correct, but not entirely incorrect either...
|
||||
It's also specific to mrdriller2, it seems.
|
||||
*/
|
||||
if (decrypter == nullptr)
|
||||
return data;
|
||||
|
||||
UINT16 dd16 = d16 ^ key;
|
||||
|
||||
key = d16;
|
||||
|
||||
key =
|
||||
//(( BIT(d16, 3) ^ (BIT(cnt, 0) & !BIT(cnt, 2))) << 15) |
|
||||
((1 ^ BIT(key, 3) ^ BIT(d16, 0)) << 15) |
|
||||
((1 ^ BIT(key, 13) ^ BIT(cnt, 0)) << 14) |
|
||||
((1 ^ BIT(key, 11) ^ BIT(d16, 5) ^ BIT(d16, 2)) << 13) |
|
||||
(( BIT(key, 9) ^ BIT(cnt, 3)) << 12) |
|
||||
((1 ^ BIT(key, 2)) << 11) |
|
||||
(( BIT(key, 10) ^ (BIT(d16, 4) & BIT(cnt, 1))) << 10) |
|
||||
((1 ^ BIT(key, 6) ^ BIT(cnt, 4)) << 9) |
|
||||
((1 ^ BIT(d16, 6) ^ BIT(key, 5)) << 8) |
|
||||
(( BIT(key, 1) ^ (BIT(d16, 5) | BIT(d16, 4))) << 7) |
|
||||
(( BIT(key, 15)) << 6) |
|
||||
((1 ^ BIT(key, 4) ^ BIT(cnt, 3) ^ BIT(d16, 2)) << 5) |
|
||||
((1 ^ BIT(key, 7) ^ BIT(cnt, 5)) << 4) |
|
||||
((1 ^ BIT(key, 8) ^ (BIT(cnt, 7) | BIT(d16, 3))) << 3) |
|
||||
(( BIT(key, 14) ^ (BIT(cnt, 1) | BIT(d16, 7))) << 2) |
|
||||
((1 ^ BIT(key, 12) ^ (BIT(cnt, 7) & BIT(d16, 7))) << 1) |
|
||||
//(( (BIT(cnt, 0) | BIT(cnt, 2))) << 0);
|
||||
((1 ^ BIT(key, 0) ^ BIT(cnt, 2)) << 0);
|
||||
|
||||
cnt++;
|
||||
|
||||
return dd16;
|
||||
if (decrypter->is_active())
|
||||
return decrypter->decrypt(data);
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
READ16_MEMBER(namcos10_state::control_r)
|
||||
@ -556,7 +535,7 @@ void namcos10_state::i2c_update()
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( namcos10_memm_map, AS_PROGRAM, 32, namcos10_state )
|
||||
AM_RANGE(0x1f300000, 0x1f300003) AM_WRITE16(key_w, 0x0000ffff)
|
||||
AM_RANGE(0x1f300000, 0x1f300003) AM_WRITE16(crypto_switch_w, 0x0000ffff)
|
||||
AM_RANGE(0x1f400000, 0x1f5fffff) AM_READ16(range_r, 0xffffffff)
|
||||
AM_RANGE(0x1fb40000, 0x1fb4000f) AM_WRITE16(bank_w, 0xffffffff)
|
||||
|
||||
@ -569,18 +548,6 @@ ADDRESS_MAP_END
|
||||
// Block access to the nand. Something strange is going on with the
|
||||
// status port. Interaction with the decryption is unclear at best.
|
||||
|
||||
WRITE16_MEMBER(namcos10_state::crypto_switch_w)
|
||||
{
|
||||
printf("crypto_switch_w: %04x\n", data);
|
||||
if (decrypter == nullptr)
|
||||
return;
|
||||
|
||||
if (BIT(data, 15) != 0)
|
||||
decrypter->activate(data & 0xf);
|
||||
else
|
||||
decrypter->deactivate();
|
||||
}
|
||||
|
||||
READ16_MEMBER(namcos10_state::nand_status_r )
|
||||
{
|
||||
return 0;
|
||||
@ -703,7 +670,10 @@ static void decrypt_bios( running_machine &machine, const char *regionName, int
|
||||
DRIVER_INIT_MEMBER(namcos10_state,mrdrilr2)
|
||||
{
|
||||
int regSize = machine().root_device().memregion("maincpu:rom")->bytes();
|
||||
decrypt_bios(machine(), "maincpu:rom", 0, regSize, 0xc, 0xd, 0xf, 0xe, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x4, 0x1, 0x2, 0x5, 0x0, 0x3);
|
||||
|
||||
decrypt_bios(machine(), "maincpu:rom", 0, 0x62000, 0xc, 0xd, 0xf, 0xe, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x4, 0x1, 0x2, 0x5, 0x0, 0x3);
|
||||
decrypt_bios(machine(), "maincpu:rom", 0x380000, regSize, 0xc, 0xd, 0xf, 0xe, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x4, 0x1, 0x2, 0x5, 0x0, 0x3);
|
||||
decrypter = static_cast<ns10_decrypter_device*>(machine().root_device().subdevice("decrypter"));
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(namcos10_state,gjspace)
|
||||
@ -849,6 +819,11 @@ static MACHINE_CONFIG_START( namcos10_memn, namcos10_state )
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED(ns10_mrdrilr2, namcos10_memm)
|
||||
/* decrypter device (CPLD in hardware?) */
|
||||
MCFG_DEVICE_ADD("decrypter", MRDRILR2_DECRYPTER, 0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED(ns10_chocovdr, namcos10_memn)
|
||||
/* decrypter device (CPLD in hardware?) */
|
||||
MCFG_DEVICE_ADD("decrypter", CHOCOVDR_DECRYPTER, 0)
|
||||
@ -1077,8 +1052,8 @@ 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, mrdrilr2, 0, ns10_mrdrilr2, 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, ns10_mrdrilr2, 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, ns10_gjspace , namcos10, namcos10_state, gjspace, ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
|
||||
|
@ -3,15 +3,17 @@
|
||||
/****************************************************************************
|
||||
Namco System 10 decryption emulation
|
||||
|
||||
(As of 2015-08, this file is still pretty much a WIP; changes are expected as
|
||||
out knowledge progress.)
|
||||
|
||||
The decryption used by type-2 System10 PCBs (MEM-N) acts on 16-bit words and is
|
||||
The decryption used by both System10 PCB types act on 16-bit words and is
|
||||
designed to operate in a serial way: once the decryption is triggered, every
|
||||
word is XORed with a mask calculated over data taken from the previous words
|
||||
(both encrypted and decrypted). Type-1 PCBs seem to use a similar
|
||||
scheme, probably involving the word address too and a bitswap, but his relation
|
||||
to what is described here needs further investigation.
|
||||
(both encrypted and decrypted). Type-1 (MEM-M) calculate the mask using the previous
|
||||
cipherword and plainword, plus the 8 lowest bits of the word address. Type-2 (MEM-N)
|
||||
boards dropped the use of the word address (maybe due to the serial protocol
|
||||
used by the K9F2808U0B?), but expanded the number of previous cipherwords and
|
||||
plainwords used up to three.
|
||||
|
||||
The only known type-1 game (mrdrilr2) has the encrypted data contained in them
|
||||
[0x62000,0x380000] region of the first ROM of the game (1A).
|
||||
|
||||
In type-2 PCBs, the encrypted data is always contained in the first ROM of the
|
||||
game (8E), and it's always stored spanning an integer number of NAND blocks
|
||||
@ -48,22 +50,26 @@ the end-of-ROM region, in what maybe is an attempt to hinder the
|
||||
recognition/reconstruction of the encrypted data.
|
||||
|
||||
Most games do a single decryption run, so the process is only initialized once;
|
||||
however, at least three of them (gamshara, mrdrilrg & panikuru) do reinitialize the
|
||||
internal state of the decrypted several times. As of 2015-08-19, only gamshara shows signs
|
||||
however, at least four of them (mrdrilr2, gamshara, mrdrilrg & panikuru) do
|
||||
reinitialize the internal state of the decryption several times. As of 2016-09-16,
|
||||
only mrdrilr2 (type-1) and gamshara (type-2) show signs
|
||||
of doing it by writing to the triggering register; how the others two are triggering the
|
||||
reinitializations is still unclear. gamshara does a reinitialization every 5 NAND blocks
|
||||
reinitializations is still unclear. mrdrilr2 does a reinitialization every time the address
|
||||
hits a 0x80000-bytes multiple); gamshara does a reinitialization every 5 NAND blocks
|
||||
(16 times in total); mrdrilrg does the second one after 0x38000 bytes and then subsequent
|
||||
ones every 32 blocks (8 times in total); panikuru does one every 2 blocks up to a total
|
||||
of 16 times.
|
||||
|
||||
The calculation of the XOR masks seem to operate this way: most bits are
|
||||
The calculation of the XOR masks operate in this way: most bits are
|
||||
calculated by using linear equations over GF(2) taking as input data the bits from
|
||||
previously processed words; however, one nonlinear calculation is performed
|
||||
per word processed, and that calculation typically affect just one bit (the only
|
||||
known exception is mrdrilrg, where the same nonlinear terms are
|
||||
affecting two of them). Till now, all the formulae seem to depend only on the
|
||||
per word processed, and that calculation typically affect just one bit. The only
|
||||
known exceptions are mrdrilr2 (type-1), where the counter is used in nonlinear terms
|
||||
(but, like in type-2 ones, just one nonlinear term involving previous words is present),
|
||||
and mrdrilrg (type-2), where the same nonlinear terms are
|
||||
affecting two of them). Till now, all the formulae for type-2 games seem to depend only on the
|
||||
previous 3 words, and the first mask after a (re-)initialization is always zero, so
|
||||
chances are the mask bits are calculated one word in advance, having access to the
|
||||
chances are that the mask bits are calculated one word in advance, having access to the
|
||||
current encrypted and decrypted words plus two further words in each sequence, maybe stored
|
||||
in 32 bits registers. All the nonlinear terms reverse-engineered till now are of the form
|
||||
A x B, where A and B are linear formulae; thus, as everything else in the schema involves
|
||||
@ -71,7 +77,7 @@ only linear relations, those nonlinear terms are probably caused by an Y-combina
|
||||
the resuls of two such linear relations as input, and deciding between both branches based
|
||||
on another linear formula.
|
||||
|
||||
The bits affected by the nonlinear calculations are given below:
|
||||
The bits affected by the nonlinear calculations in type-2 games are given below:
|
||||
chocovdr -> #10
|
||||
gamshara -> #2
|
||||
gjspace -> none
|
||||
@ -93,11 +99,10 @@ equivalent datasets, nothing else.
|
||||
|
||||
|
||||
TO-DO:
|
||||
* If further dumps support the theory of the calculations just depending on 3 previous words,
|
||||
change the implementation accordingly to reflect that.
|
||||
* Research how type-1 encryption is related to this.
|
||||
* If further dumps support the theory of the calculations of type-2 games just depending
|
||||
on 3 previous words, change the implementation accordingly to reflect that.
|
||||
|
||||
Observing the linear equations, there is a keen difference between bits using
|
||||
Observing the linear equations of type-2 games, there is a keen difference between bits using
|
||||
just a bunch of previous bits, and others using much more bits from more words;
|
||||
simplifying the latter ones could be handy, and probably closer to what the
|
||||
hardware is doing. Two possible simplifications could be:
|
||||
@ -113,22 +118,21 @@ 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 GJSPACE_DECRYPTER = &device_creator<gjspace_decrypter_device>;
|
||||
const device_type KNPUZZLE_DECRYPTER = &device_creator<knpuzzle_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>;
|
||||
constexpr device_type CHOCOVDR_DECRYPTER = &device_creator<chocovdr_decrypter_device>;
|
||||
constexpr device_type GAMSHARA_DECRYPTER = &device_creator<gamshara_decrypter_device>;
|
||||
constexpr device_type GJSPACE_DECRYPTER = &device_creator<gjspace_decrypter_device>;
|
||||
constexpr device_type KNPUZZLE_DECRYPTER = &device_creator<knpuzzle_decrypter_device>;
|
||||
constexpr device_type KONOTAKO_DECRYPTER = &device_creator<konotako_decrypter_device>;
|
||||
constexpr device_type MRDRILR2_DECRYPTER = &device_creator<mrdrilr2_decrypter_device>;
|
||||
constexpr device_type NFLCLSFB_DECRYPTER = &device_creator<nflclsfb_decrypter_device>;
|
||||
constexpr 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};
|
||||
// base class
|
||||
|
||||
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)
|
||||
ns10_decrypter_device::ns10_decrypter_device(device_type type, const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, "Namco System 10 Decrypter", tag, owner, clock, "ns10_crypto", __FILE__)
|
||||
, _active(false)
|
||||
, _logic(logic)
|
||||
{
|
||||
_active = false;
|
||||
}
|
||||
|
||||
void ns10_decrypter_device::activate(int iv)
|
||||
@ -147,9 +151,77 @@ bool ns10_decrypter_device::is_active()const
|
||||
return _active;
|
||||
}
|
||||
|
||||
UINT16 ns10_decrypter_device::decrypt(UINT16 cipherword)
|
||||
ns10_decrypter_device::~ns10_decrypter_device()
|
||||
{
|
||||
UINT16 plainword = cipherword ^ _mask;
|
||||
}
|
||||
|
||||
|
||||
// type-1 decrypter
|
||||
|
||||
constexpr int UNKNOWN {16};
|
||||
constexpr int U {UNKNOWN};
|
||||
// this could perfectly be part of the per-game logic but, with only one known type-1 game, we cannot say anything definitive
|
||||
constexpr int ns10_type1_decrypter_device::initSbox[16] {U,U,U,0,4,9,U,U,U,8,U,1,U,9,U,5};
|
||||
|
||||
ns10_type1_decrypter_device::ns10_type1_decrypter_device(device_type type, const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(type, mconfig, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t ns10_type1_decrypter_device::decrypt(uint16_t cipherword)
|
||||
{
|
||||
uint16_t plainword = _mask ^ bitswap(cipherword,9,13,15,7,14,8,6,10,11,12,3,5,0,1,4,2);
|
||||
|
||||
uint16_t nbs =
|
||||
((BIT(_counter, 4) ) << 15) ^
|
||||
((BIT(cipherword, 2) ^ BIT(cipherword, 5) ) << 14) ^
|
||||
((BIT(cipherword, 0) ) << 13) ^
|
||||
(((BIT(cipherword, 4) | BIT(cipherword, 5))) << 12) ^ // this is the only nonlinear term not involving the counter
|
||||
((BIT(_counter, 0) ) << 11) ^
|
||||
((BIT(cipherword, 6) ) << 10) ^
|
||||
(((BIT(cipherword, 4) & BIT(_counter, 1)) ) << 8) ^
|
||||
((BIT(_counter, 3) ) << 6) ^
|
||||
(((BIT(cipherword, 3) | BIT(_counter, 7)) ) << 5) ^
|
||||
((BIT(cipherword, 2) ^ BIT(_counter, 3) ) << 4) ^
|
||||
((BIT(_counter, 2) ) << 3) ^
|
||||
(((BIT(cipherword, 7) & BIT(_counter, 7)) ) << 2) ^
|
||||
((BIT(_counter, 5) ) << 1) ^
|
||||
(((BIT(cipherword, 7) | BIT(_counter, 1)) ) << 0);
|
||||
_mask = nbs
|
||||
^ bitswap(cipherword, 6,11, 3, 1,13, 5,15,10, 2, 9, 8, 4, 0,12, 7,14)
|
||||
^ bitswap(plainword , 9, 7, 5, 2,14, 4,13, 8, 0,15,10, 1, 3, 6,12,11)
|
||||
^ 0xecbe;
|
||||
++_counter;
|
||||
|
||||
return plainword;
|
||||
}
|
||||
|
||||
void ns10_type1_decrypter_device::init(int iv)
|
||||
{
|
||||
_mask = initSbox[iv];
|
||||
_counter = 0;
|
||||
}
|
||||
|
||||
void ns10_type1_decrypter_device::device_start()
|
||||
{
|
||||
_active = false;
|
||||
}
|
||||
|
||||
|
||||
// type-2 decrypter
|
||||
|
||||
// this could perfectly be part of the per-game logic; by now, only gamshara seems to use it, so we keep it global
|
||||
constexpr int ns10_type2_decrypter_device::initSbox[16] {0,12,13,6,2,4,9,8,11,1,7,15,10,5,14,3};
|
||||
|
||||
ns10_type2_decrypter_device::ns10_type2_decrypter_device(device_type type, const ns10_crypto_logic &logic, const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(type, mconfig, tag, owner, clock)
|
||||
, _logic(logic)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t ns10_type2_decrypter_device::decrypt(UINT16 cipherword)
|
||||
{
|
||||
uint16_t plainword = cipherword ^ _mask;
|
||||
|
||||
_previous_cipherwords <<= 16;
|
||||
_previous_cipherwords ^= cipherword;
|
||||
@ -169,20 +241,21 @@ UINT16 ns10_decrypter_device::decrypt(UINT16 cipherword)
|
||||
return plainword;
|
||||
}
|
||||
|
||||
void ns10_decrypter_device::device_start()
|
||||
void ns10_type2_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 = bitswap(initSbox[iv],3,16,16,2,1,16,16,0,16,16,16,16,16,16,16,16);
|
||||
_previous_plainwords = 0;
|
||||
_mask = 0;
|
||||
}
|
||||
|
||||
void ns10_type2_decrypter_device::device_start()
|
||||
{
|
||||
_active = false;
|
||||
_reducer = std::make_unique<gf2_reducer>();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@ -191,11 +264,13 @@ gf2_reducer::gf2_reducer()
|
||||
// create a look-up table of GF2 reductions of 16-bits words
|
||||
for (int i = 0; i < 0x10000; ++i)
|
||||
{
|
||||
reduction = 0;
|
||||
for (int j = 0; j < 16; ++j)
|
||||
reduction ^= BIT(i, j);
|
||||
reduction = i;
|
||||
reduction ^= reduction >> 8;
|
||||
reduction ^= reduction >> 4;
|
||||
reduction ^= reduction >> 2;
|
||||
reduction ^= reduction >> 1;
|
||||
|
||||
_gf2Reduction[i] = reduction;
|
||||
_gf2Reduction[i] = reduction & 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,25 +286,25 @@ int gf2_reducer::gf2_reduce(UINT64 num)const
|
||||
|
||||
// game-specific logic
|
||||
|
||||
// static UINT16 mrdrilrg_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
|
||||
// static uint16_t mrdrilrg_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
// {
|
||||
// UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
// uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
// return (reducer.gf2_reduce(0x00000a00a305c826ull & previous_masks) & reducer.gf2_reduce(0x0000011800020000ull & previous_masks)) * 0x0011;
|
||||
// }
|
||||
|
||||
// static UINT16 panikuru_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
|
||||
// static uint16_t panikuru_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
// {
|
||||
// return ((reducer.gf2_reduce(0x0000000088300281ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000004600281ull & previous_plainwords))
|
||||
// & (reducer.gf2_reduce(0x0000a13140090000ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000806240090000ull & previous_plainwords))) << 2;
|
||||
// }
|
||||
|
||||
static UINT16 chocovdr_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
|
||||
static uint16_t chocovdr_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
{
|
||||
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
uint64_t 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 = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic chocovdr_crypto_logic = {
|
||||
{
|
||||
0x00005239351ec1daull, 0x0000000000008090ull, 0x0000000048264808ull, 0x0000000000004820ull,
|
||||
0x0000000000000500ull, 0x0000000058ff5a54ull, 0x00000000d8220208ull, 0x00005239351e91d3ull,
|
||||
@ -245,13 +320,13 @@ static const ns10_decrypter_device::ns10_crypto_logic chocovdr_crypto_logic = {
|
||||
chocovdr_nonlinear_calc
|
||||
};
|
||||
|
||||
static UINT16 gamshara_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
|
||||
static uint16_t gamshara_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
uint64_t 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 = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic gamshara_crypto_logic = {
|
||||
{
|
||||
0x0000000000000028ull, 0x0000cae83f389fd9ull, 0x0000000000001000ull, 0x0000000042823402ull,
|
||||
0x0000cae8736a0592ull, 0x0000cae8736a8596ull, 0x000000008b4095b9ull, 0x0000000000002100ull,
|
||||
@ -267,12 +342,12 @@ static const ns10_decrypter_device::ns10_crypto_logic gamshara_crypto_logic = {
|
||||
gamshara_nonlinear_calc
|
||||
};
|
||||
|
||||
static UINT16 gjspace_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
|
||||
static uint16_t gjspace_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const ns10_decrypter_device::ns10_crypto_logic gjspace_crypto_logic = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic gjspace_crypto_logic = {
|
||||
{
|
||||
0x0000000000000240ull, 0x0000d617eb0f1ab1ull, 0x00000000451111c0ull, 0x00000000013b1f44ull,
|
||||
0x0000aab0b356abceull, 0x00007ca76b89602aull, 0x0000000000001800ull, 0x00000000031d1303ull,
|
||||
@ -288,13 +363,13 @@ static const ns10_decrypter_device::ns10_crypto_logic gjspace_crypto_logic = {
|
||||
gjspace_nonlinear_calc
|
||||
};
|
||||
|
||||
static UINT16 knpuzzle_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
|
||||
static uint16_t knpuzzle_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
{
|
||||
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 0x13) & (reducer.gf2_reduce(0x0000000014001290ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000000021290ull & previous_plainwords)) & 1) << 1;
|
||||
}
|
||||
|
||||
static const ns10_decrypter_device::ns10_crypto_logic knpuzzle_crypto_logic = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic knpuzzle_crypto_logic = {
|
||||
{
|
||||
0x00000000c0a4208cull, 0x00000000204100a8ull, 0x000000000c0306a0ull, 0x000000000819e944ull,
|
||||
0x0000000000001400ull, 0x0000000000000061ull, 0x000000000141401cull, 0x0000000000000020ull,
|
||||
@ -310,13 +385,13 @@ static const ns10_decrypter_device::ns10_crypto_logic knpuzzle_crypto_logic = {
|
||||
knpuzzle_nonlinear_calc
|
||||
};
|
||||
|
||||
static UINT16 konotako_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
|
||||
static uint16_t konotako_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 7) & (previous_masks >> 15) & 1) << 15;
|
||||
}
|
||||
|
||||
static const ns10_decrypter_device::ns10_crypto_logic konotako_crypto_logic = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic konotako_crypto_logic = {
|
||||
{
|
||||
0x000000000000004cull, 0x00000000d39e3d3dull, 0x0000000000001110ull, 0x0000000000002200ull,
|
||||
0x000000003680c008ull, 0x0000000000000281ull, 0x0000000000005002ull, 0x00002a7371895a47ull,
|
||||
@ -332,13 +407,13 @@ static const ns10_decrypter_device::ns10_crypto_logic konotako_crypto_logic = {
|
||||
konotako_nonlinear_calc
|
||||
};
|
||||
|
||||
static UINT16 nflclsfb_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer& reducer)
|
||||
static uint16_t nflclsfb_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
{
|
||||
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
uint64_t 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 = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic nflclsfb_crypto_logic = {
|
||||
{
|
||||
0x000034886e281880ull, 0x0000000012c5e7baull, 0x0000000000000200ull, 0x000000002900002aull,
|
||||
0x00000000000004c0ull, 0x0000000012c5e6baull, 0x00000000e0df8bbbull, 0x000000002011532aull,
|
||||
@ -354,13 +429,13 @@ static const ns10_decrypter_device::ns10_crypto_logic nflclsfb_crypto_logic = {
|
||||
nflclsfb_nonlinear_calc
|
||||
};
|
||||
|
||||
static UINT16 startrgn_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords, const gf2_reducer&)
|
||||
static uint16_t startrgn_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 12) & (previous_masks >> 14) & 1) << 4;
|
||||
}
|
||||
|
||||
static const ns10_decrypter_device::ns10_crypto_logic startrgn_crypto_logic = {
|
||||
static constexpr ns10_type2_decrypter_device::ns10_crypto_logic startrgn_crypto_logic = {
|
||||
{
|
||||
0x00003e4bfe92c6a9ull, 0x000000000000010cull, 0x00003e4b7bd6c4aaull, 0x0000b1a904b8fab8ull,
|
||||
0x0000000000000080ull, 0x0000000000008c00ull, 0x0000b1a9b2f0b4cdull, 0x000000006c100828ull,
|
||||
@ -379,37 +454,42 @@ 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)
|
||||
mrdrilr2_decrypter_device::mrdrilr2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type1_decrypter_device(MRDRILR2_DECRYPTER,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)
|
||||
chocovdr_decrypter_device::chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(CHOCOVDR_DECRYPTER, chocovdr_crypto_logic, mconfig, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
gjspace_decrypter_device::gjspace_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: ns10_decrypter_device(GJSPACE_DECRYPTER, gjspace_crypto_logic, mconfig, tag, owner, clock)
|
||||
gamshara_decrypter_device::gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(GAMSHARA_DECRYPTER, gamshara_crypto_logic, mconfig, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
knpuzzle_decrypter_device::knpuzzle_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: ns10_decrypter_device(KNPUZZLE_DECRYPTER, knpuzzle_crypto_logic, mconfig, tag, owner, clock)
|
||||
gjspace_decrypter_device::gjspace_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(GJSPACE_DECRYPTER, gjspace_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)
|
||||
knpuzzle_decrypter_device::knpuzzle_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(KNPUZZLE_DECRYPTER, knpuzzle_crypto_logic, mconfig, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
konotako_decrypter_device::konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(KONOTAKO_DECRYPTER, konotako_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)
|
||||
nflclsfb_decrypter_device::nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_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_t clock)
|
||||
: ns10_type2_decrypter_device(STARTRGN_DECRYPTER, startrgn_crypto_logic, mconfig, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
@ -4,99 +4,143 @@
|
||||
#ifndef _NS10CRYPT_H_
|
||||
#define _NS10CRYPT_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class gf2_reducer // helper class
|
||||
{
|
||||
public:
|
||||
gf2_reducer();
|
||||
int gf2_reduce(UINT64 num)const;
|
||||
int gf2_reduce(uint64_t num)const;
|
||||
private:
|
||||
int _gf2Reduction[0x10000];
|
||||
};
|
||||
|
||||
|
||||
class ns10_decrypter_device : public device_t
|
||||
{
|
||||
public:
|
||||
void activate(int iv);
|
||||
void deactivate();
|
||||
bool is_active()const;
|
||||
|
||||
virtual uint16_t decrypt(uint16_t cipherword)=0;
|
||||
virtual ~ns10_decrypter_device();
|
||||
|
||||
protected:
|
||||
ns10_decrypter_device(device_type type, const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
virtual void init(int iv)=0;
|
||||
virtual void device_start()=0;
|
||||
|
||||
bool _active;
|
||||
};
|
||||
|
||||
class ns10_type1_decrypter_device : public ns10_decrypter_device
|
||||
{
|
||||
public:
|
||||
// with just only type-1 game known, we cannot say which parts of the crypto_logic is common, if any,
|
||||
// and which is game-specific. In practice, this class is just an alias for the decrypter device of mrdrilr2
|
||||
uint16_t decrypt(uint16_t cipherword);
|
||||
|
||||
protected:
|
||||
ns10_type1_decrypter_device(device_type type, const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
private:
|
||||
uint16_t _mask;
|
||||
uint8_t _counter;
|
||||
static const int initSbox[16];
|
||||
|
||||
void init(int iv);
|
||||
void device_start()override;
|
||||
};
|
||||
|
||||
|
||||
class ns10_type2_decrypter_device : public ns10_decrypter_device
|
||||
{
|
||||
public:
|
||||
// this encodes the decryption logic, which varies per game
|
||||
// and is probably hard-coded into the CPLD
|
||||
struct ns10_crypto_logic
|
||||
{
|
||||
UINT64 eMask[16];
|
||||
UINT64 dMask[16];
|
||||
UINT16 xMask;
|
||||
UINT16(*nonlinear_calculation)(UINT64, UINT64, const gf2_reducer&); // preliminary encoding; need research
|
||||
uint64_t eMask[16];
|
||||
uint64_t dMask[16];
|
||||
uint16_t xMask;
|
||||
uint16_t(*nonlinear_calculation)(uint64_t, uint64_t, const gf2_reducer&); // preliminary encoding; need research
|
||||
};
|
||||
|
||||
void activate(int iv);
|
||||
void deactivate();
|
||||
bool is_active()const;
|
||||
|
||||
UINT16 decrypt(UINT16 cipherword);
|
||||
uint16_t decrypt(uint16_t cipherword);
|
||||
|
||||
protected:
|
||||
ns10_decrypter_device(
|
||||
device_type type, const ns10_decrypter_device::ns10_crypto_logic &logic,
|
||||
ns10_type2_decrypter_device(
|
||||
device_type type, const ns10_type2_decrypter_device::ns10_crypto_logic &logic,
|
||||
const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
private:
|
||||
UINT16 _mask;
|
||||
UINT64 _previous_cipherwords;
|
||||
UINT64 _previous_plainwords;
|
||||
bool _active;
|
||||
uint16_t _mask;
|
||||
uint64_t _previous_cipherwords;
|
||||
uint64_t _previous_plainwords;
|
||||
const ns10_crypto_logic& _logic;
|
||||
static const int initSbox[16];
|
||||
std::unique_ptr<const gf2_reducer>_reducer;
|
||||
static const int initSbox[16];
|
||||
|
||||
void device_start() override;
|
||||
void init(int iv);
|
||||
void device_start()override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// game-specific devices
|
||||
|
||||
class chocovdr_decrypter_device : public ns10_decrypter_device
|
||||
class mrdrilr2_decrypter_device : public ns10_type1_decrypter_device
|
||||
{
|
||||
public:
|
||||
chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
mrdrilr2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class gamshara_decrypter_device : public ns10_decrypter_device
|
||||
class chocovdr_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class gjspace_decrypter_device : public ns10_decrypter_device
|
||||
class gamshara_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
gjspace_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class knpuzzle_decrypter_device : public ns10_decrypter_device
|
||||
class gjspace_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
knpuzzle_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
gjspace_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class konotako_decrypter_device : public ns10_decrypter_device
|
||||
class knpuzzle_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
knpuzzle_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class nflclsfb_decrypter_device : public ns10_decrypter_device
|
||||
class konotako_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class startrgn_decrypter_device : public ns10_decrypter_device
|
||||
class nflclsfb_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class startrgn_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
|
||||
extern const device_type MRDRILR2_DECRYPTER;
|
||||
extern const device_type CHOCOVDR_DECRYPTER;
|
||||
extern const device_type GAMSHARA_DECRYPTER;
|
||||
extern const device_type GJSPACE_DECRYPTER;
|
||||
|
Loading…
Reference in New Issue
Block a user