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:
987123879113 2023-05-23 21:47:57 +09:00 committed by GitHub
parent 6a5898d6d5
commit 1b54a32a92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 206 additions and 22 deletions

View File

@ -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 *)&reg[0x1c0]);
if (cur_reverb_preset==nullptr)

View File

@ -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

View File

@ -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 )

View File

@ -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;
}

View File

@ -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