mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
namco/namcos10.cpp, namco/ns10crypt.cpp: Added partial decrypter for Point Blank 3. (#11244) [Peter Wilhelmsen, Samuel Neves]
sound/spu.cpp: Don't explode when the reverb parameters couldn't be found after a save state. [Windy Fairy]
This commit is contained in:
parent
6a5898d6d5
commit
1b54a32a92
@ -2536,6 +2536,13 @@ void spu_device::update_reverb()
|
||||
{
|
||||
if (dirty_flags&dirtyflag_reverb)
|
||||
{
|
||||
// TODO: Handle cases where reverb present can't be found better
|
||||
// If a save state is loaded and has reverb values that don't match a preset
|
||||
// then spu_reverb_cfg is never set so the reverb settings won't be the same as
|
||||
// when the save state was created.
|
||||
// This only becomes an issue when loading save states from the command line
|
||||
// because if you load a save state from within MAME it will hold the last used
|
||||
// spu_reverb_cfg and reuse that value.
|
||||
cur_reverb_preset=find_reverb_preset((unsigned short *)®[0x1c0]);
|
||||
|
||||
if (cur_reverb_preset==nullptr)
|
||||
|
@ -308,7 +308,7 @@ void spu_device::reverb::process(signed short *output,
|
||||
signed short *sp=(signed short *)reverb_input,
|
||||
*dp=(signed short *)output;
|
||||
|
||||
if (rp->band_gain>0.0f)
|
||||
if (rp && rp->band_gain>0.0f)
|
||||
{
|
||||
// Do reverb processing
|
||||
|
||||
|
@ -2289,7 +2289,24 @@ void namcos10_memn_state::ns10_ptblank3(machine_config &config)
|
||||
|
||||
m_unscrambler = [] (uint16_t data) { return bitswap<16>(data, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa, 0x5, 0x7, 0x4, 0x6, 0x1, 0x0, 0x2, 0x3); };
|
||||
|
||||
// NS10_TYPE2_DECRYPTER(config, m_decrypter, 0, logic);
|
||||
NS10_TYPE2_DECRYPTER_NONLINEAR(config, m_decrypter, 0, ns10_type2_decrypter_nonlinear_device::ns10_crypto_logic{
|
||||
{
|
||||
0x0000000057001200ULL,0x00000000000000a4ULL,0x0000000000000150ULL,0x0000000000008004ULL,
|
||||
0x0000000057002204ULL,0x0000000009001000ULL,0x0000000000102000ULL,0x0000000064004888ULL,
|
||||
0x0000000000100008ULL,0x000000a0c0980600ULL,0x000000001801c020ULL,0x00005810881a09c0ULL,
|
||||
// 0x00000c10084a29dcULL if non_linear[0] is 0x44 instead of of 0x04 then we need this instead (final plaintext is the same)
|
||||
0x0000000400980600ULL,0x0000000000000300ULL,0x0000000000000080ULL,0x0000000000a00c0aULL
|
||||
}, {
|
||||
0x0000000041051000ULL,0x0000000000000024ULL,0x0000000000000050ULL,0x0000000000008004ULL,
|
||||
0x0000000041052200ULL,0x0000000009401100ULL,0x0000000000122000ULL,0x0000000004100898ULL,
|
||||
0x0000000000120088ULL,0x0000000040a80400ULL,0x0000000019004000ULL,0x000001859830281dULL,
|
||||
0x0000002400880201ULL,0x0000000000000300ULL,0x00000000000000c0ULL,0x0000000000000408ULL
|
||||
},
|
||||
0xe1b8,
|
||||
[] (uint16_t nonlinear_bit) -> uint16_t {
|
||||
return nonlinear_bit << 11;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void namcos10_memn_state::ns10_puzzball(machine_config &config)
|
||||
@ -3460,12 +3477,12 @@ ROM_START( gunbalina )
|
||||
|
||||
ROM_REGION32_LE( 0x1080000, "nand0", 0 )
|
||||
ROM_LOAD( "gnn1a.8e", 0x0000000, 0x1080000, CRC(981b03d4) SHA1(1c55458f1b2964afe2cf4e9d84548c0699808e9f) )
|
||||
ROM_LOAD( "ptblank3_prog.bin", 0x00029400, 0x002de3f0, CRC(1612383d) SHA1(e2f339444fe01a4f51ee784692c6d7f989080dc7) ) // Program code is unencrypted but scrambled
|
||||
ROM_CONTINUE( 0x1056c00, 0x25200 )
|
||||
ROM_COPY( "nand0", 0x84000, 0x1052a00, 0x4200 ) // relocate block 0x20
|
||||
|
||||
ROM_REGION32_LE( 0x1080000, "nand1", 0 )
|
||||
ROM_LOAD( "gnn1a.8d", 0x0000000, 0x1080000, CRC(6cd343e0) SHA1(dcec44abae1504025895f42fe574549e5010f7d5) )
|
||||
|
||||
ROM_REGION( 0x2ec00, "decrypter:nonlinear_table", 0 )
|
||||
ROM_LOAD( "ptblank3_nonlinear", 0x00000, 0x2ec00, CRC(5997d7dd) SHA1(ab3f32fd92ee20ca3c7642686d9d8039d0b6cbc5) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( kd2001 )
|
||||
@ -3602,11 +3619,12 @@ ROM_START( ptblank3 )
|
||||
|
||||
ROM_REGION32_LE( 0x1080000, "nand0", 0 )
|
||||
ROM_LOAD( "gnn2vera_0.8e", 0x0000000, 0x1080000, CRC(3777ef6b) SHA1(44dce83f75d10f843db0feef4c2a738442434246) )
|
||||
ROM_LOAD( "ptblank3_prog.bin", 0x00029400, 0x002de3f0, CRC(1612383d) SHA1(e2f339444fe01a4f51ee784692c6d7f989080dc7) ) // Program code is unencrypted but scrambled
|
||||
ROM_CONTINUE(0x1056c00, 0x25200)
|
||||
|
||||
ROM_REGION32_LE( 0x1080000, "nand1", 0 )
|
||||
ROM_LOAD( "gnn2vera_1.8d", 0x0000000, 0x1080000, CRC(82d2cfb5) SHA1(4b5e713a55e74a7b32b1b9b5811892df2df86256) )
|
||||
|
||||
ROM_REGION( 0x2ec00, "decrypter:nonlinear_table", 0 )
|
||||
ROM_LOAD( "ptblank3_nonlinear", 0x00000, 0x2ec00, CRC(5997d7dd) SHA1(ab3f32fd92ee20ca3c7642686d9d8039d0b6cbc5) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( puzzball )
|
||||
|
@ -124,15 +124,25 @@ really exist.
|
||||
DEFINE_DEVICE_TYPE(MRDRILR2_DECRYPTER, mrdrilr2_decrypter_device, "mrdrilr2_decrypter", "Mr Driller 2 decrypter")
|
||||
|
||||
DEFINE_DEVICE_TYPE(NS10_TYPE2_DECRYPTER, ns10_type2_decrypter_device, "ns10_type2_decrypter", "Namco System 10 Type 2 decrypter")
|
||||
DEFINE_DEVICE_TYPE(NS10_TYPE2_DECRYPTER_NONLINEAR, ns10_type2_decrypter_nonlinear_device, "ns10_type2_decrypter_nonlinear", "Namco System 10 Type 2 decrypter (non-linear bit lookup table)")
|
||||
|
||||
// base class
|
||||
|
||||
ns10_decrypter_device::ns10_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, m_active(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ns10_decrypter_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_active));
|
||||
}
|
||||
|
||||
void ns10_decrypter_device::device_reset()
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
void ns10_decrypter_device::activate(int iv)
|
||||
{
|
||||
init(iv);
|
||||
@ -157,11 +167,25 @@ const int ns10_type1_decrypter_device::INIT_SBOX[16]{U, U, U, 0, 4, 9, U, U, U,
|
||||
|
||||
ns10_type1_decrypter_device::ns10_type1_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(mconfig, type, tag, owner, clock)
|
||||
, m_mask(0)
|
||||
, m_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
void ns10_type1_decrypter_device::device_start()
|
||||
{
|
||||
ns10_decrypter_device::device_start();
|
||||
|
||||
save_item(NAME(m_mask));
|
||||
save_item(NAME(m_counter));
|
||||
}
|
||||
|
||||
void ns10_type1_decrypter_device::device_reset()
|
||||
{
|
||||
ns10_decrypter_device::device_reset();
|
||||
|
||||
m_mask = 0;
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
uint16_t ns10_type1_decrypter_device::decrypt(uint16_t cipherword)
|
||||
{
|
||||
uint16_t plainword = m_mask ^ bitswap<16>(cipherword, 9, 13, 15, 7, 14, 8, 6, 10, 11, 12, 3, 5, 0, 1, 4, 2);
|
||||
@ -193,11 +217,6 @@ void ns10_type1_decrypter_device::init(int iv)
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
void ns10_type1_decrypter_device::device_start()
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
mrdrilr2_decrypter_device::mrdrilr2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type1_decrypter_device(mconfig, MRDRILR2_DECRYPTER, tag, owner, clock)
|
||||
{
|
||||
@ -210,9 +229,6 @@ const int ns10_type2_decrypter_device::INIT_SBOX[16]{0, 12, 13, 6, 2, 4, 9, 8, 1
|
||||
|
||||
ns10_type2_decrypter_device::ns10_type2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(mconfig, NS10_TYPE2_DECRYPTER, tag, owner, clock)
|
||||
, m_mask(0)
|
||||
, m_previous_cipherwords(0)
|
||||
, m_previous_plainwords(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -257,8 +273,100 @@ void ns10_type2_decrypter_device::init(int iv)
|
||||
|
||||
void ns10_type2_decrypter_device::device_start()
|
||||
{
|
||||
// If the logic isn't initialized then this will just fail
|
||||
assert(m_logic_initialized == true);
|
||||
ns10_decrypter_device::device_start();
|
||||
|
||||
m_active = false;
|
||||
// If the logic isn't initialized then this will just fail, this is a programmer error
|
||||
if (!m_logic_initialized)
|
||||
fatalerror("ns10_type2_decrypter_device: Required logic data for decrypter device not initialized");
|
||||
|
||||
save_item(NAME(m_mask));
|
||||
save_item(NAME(m_previous_cipherwords));
|
||||
save_item(NAME(m_previous_plainwords));
|
||||
}
|
||||
|
||||
void ns10_type2_decrypter_device::device_reset()
|
||||
{
|
||||
ns10_decrypter_device::device_reset();
|
||||
|
||||
m_mask = 0;
|
||||
m_previous_cipherwords = 0;
|
||||
m_previous_plainwords = 0;
|
||||
}
|
||||
|
||||
// type-2 decrypter with a table for the non-linear bits
|
||||
const int ns10_type2_decrypter_nonlinear_device::INIT_SBOX[16]{0, 12, 13, 6, 2, 4, 9, 8, 11, 1, 7, 15, 10, 5, 14, 3};
|
||||
|
||||
ns10_type2_decrypter_nonlinear_device::ns10_type2_decrypter_nonlinear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(mconfig, NS10_TYPE2_DECRYPTER_NONLINEAR, tag, owner, clock)
|
||||
, m_nonlinear_region(*this, "nonlinear_table")
|
||||
{
|
||||
}
|
||||
|
||||
ns10_type2_decrypter_nonlinear_device::ns10_type2_decrypter_nonlinear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, ns10_crypto_logic &&logic)
|
||||
: ns10_decrypter_device(mconfig, NS10_TYPE2_DECRYPTER_NONLINEAR, tag, owner, clock)
|
||||
, m_nonlinear_region(*this, "nonlinear_table")
|
||||
, m_logic(std::move(logic))
|
||||
{
|
||||
m_logic_initialized = true;
|
||||
}
|
||||
|
||||
uint16_t ns10_type2_decrypter_nonlinear_device::decrypt(uint16_t cipherword)
|
||||
{
|
||||
uint16_t const plainword = cipherword ^ m_mask;
|
||||
|
||||
m_previous_cipherwords <<= 16;
|
||||
m_previous_cipherwords ^= cipherword;
|
||||
m_previous_plainwords <<= 16;
|
||||
m_previous_plainwords ^= plainword;
|
||||
|
||||
m_mask = 0;
|
||||
for (int j = 15; j >= 0; --j)
|
||||
{
|
||||
m_mask <<= 1;
|
||||
m_mask ^= gf2_reduce(m_logic.eMask[j] & m_previous_cipherwords);
|
||||
m_mask ^= gf2_reduce(m_logic.dMask[j] & m_previous_plainwords);
|
||||
}
|
||||
m_mask ^= m_logic.xMask;
|
||||
|
||||
uint8_t nonlinear_bit = BIT(m_nonlinear_region->base()[m_nonlinear_count / 8], 7 - (m_nonlinear_count % 8));
|
||||
m_nonlinear_count++;
|
||||
if (m_nonlinear_count >= m_nonlinear_region->bytes() * 8)
|
||||
m_nonlinear_count = 0;
|
||||
m_mask ^= m_logic.nonlinear_calculation(nonlinear_bit);
|
||||
|
||||
return plainword;
|
||||
}
|
||||
|
||||
void ns10_type2_decrypter_nonlinear_device::init(int iv)
|
||||
{
|
||||
if (m_logic.iv_calculation)
|
||||
m_previous_cipherwords = m_logic.iv_calculation(iv);
|
||||
else
|
||||
m_previous_cipherwords = bitswap(INIT_SBOX[iv], 3, 16, 16, 2, 1, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16);
|
||||
m_previous_plainwords = 0;
|
||||
m_mask = 0;
|
||||
}
|
||||
|
||||
void ns10_type2_decrypter_nonlinear_device::device_start()
|
||||
{
|
||||
ns10_decrypter_device::device_start();
|
||||
|
||||
// If the logic isn't initialized then this will just fail, this is a programmer error
|
||||
if (!m_logic_initialized)
|
||||
fatalerror("ns10_type2_decrypter_nonlinear_device: Required logic data for decrypter device not initialized");
|
||||
|
||||
save_item(NAME(m_mask));
|
||||
save_item(NAME(m_previous_cipherwords));
|
||||
save_item(NAME(m_previous_plainwords));
|
||||
save_item(NAME(m_nonlinear_count));
|
||||
}
|
||||
|
||||
void ns10_type2_decrypter_nonlinear_device::device_reset()
|
||||
{
|
||||
ns10_decrypter_device::device_reset();
|
||||
|
||||
m_mask = 0;
|
||||
m_previous_cipherwords = 0;
|
||||
m_previous_plainwords = 0;
|
||||
m_nonlinear_count = 0;
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ public:
|
||||
protected:
|
||||
ns10_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual void device_start() override = 0;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual void init(int iv) = 0;
|
||||
|
||||
@ -42,6 +43,7 @@ protected:
|
||||
ns10_type1_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
static const int INIT_SBOX[16];
|
||||
@ -79,6 +81,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
static const int INIT_SBOX[16];
|
||||
@ -88,6 +91,53 @@ private:
|
||||
uint16_t m_mask;
|
||||
uint64_t m_previous_cipherwords;
|
||||
uint64_t m_previous_plainwords;
|
||||
|
||||
const ns10_crypto_logic m_logic;
|
||||
|
||||
bool m_logic_initialized;
|
||||
};
|
||||
|
||||
class ns10_type2_decrypter_nonlinear_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
|
||||
{
|
||||
using nonlinear_calculation_function = uint16_t (*)(uint16_t);
|
||||
using iv_calculation_function = uint64_t (*)(int);
|
||||
uint64_t eMask[16]{};
|
||||
uint64_t dMask[16]{};
|
||||
uint16_t xMask = 0;
|
||||
nonlinear_calculation_function nonlinear_calculation = nullptr; // preliminary encoding; need research
|
||||
iv_calculation_function iv_calculation = nullptr;
|
||||
};
|
||||
|
||||
ns10_type2_decrypter_nonlinear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
ns10_type2_decrypter_nonlinear_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, ns10_crypto_logic &&logic);
|
||||
|
||||
virtual uint16_t decrypt(uint16_t cipherword) override;
|
||||
|
||||
static int gf2_reduce(uint64_t num)
|
||||
{
|
||||
return population_count_64(num) & 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
static const int INIT_SBOX[16];
|
||||
|
||||
virtual void init(int iv) override;
|
||||
|
||||
uint16_t m_mask;
|
||||
uint64_t m_previous_cipherwords;
|
||||
uint64_t m_previous_plainwords;
|
||||
uint32_t m_nonlinear_count;
|
||||
|
||||
required_memory_region m_nonlinear_region;
|
||||
|
||||
const ns10_crypto_logic m_logic;
|
||||
|
||||
bool m_logic_initialized;
|
||||
@ -101,5 +151,6 @@ public:
|
||||
|
||||
DECLARE_DEVICE_TYPE(MRDRILR2_DECRYPTER, mrdrilr2_decrypter_device) // Type 1
|
||||
DECLARE_DEVICE_TYPE(NS10_TYPE2_DECRYPTER, ns10_type2_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(NS10_TYPE2_DECRYPTER_NONLINEAR, ns10_type2_decrypter_nonlinear_device)
|
||||
|
||||
#endif // MAME_NAMCO_NS10CRYPT_H
|
||||
|
Loading…
Reference in New Issue
Block a user