summaryrefslogtreecommitdiffstats
path: root/src/mame/old/neocrypt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/old/neocrypt.cpp')
-rw-r--r--src/mame/old/neocrypt.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/mame/old/neocrypt.cpp b/src/mame/old/neocrypt.cpp
new file mode 100644
index 00000000000..a6b4263a5d2
--- /dev/null
+++ b/src/mame/old/neocrypt.cpp
@@ -0,0 +1,181 @@
+// license:BSD-3-Clause
+// copyright-holders:Bryan McPhail,Ernesto Corvi,Andrew Prime,Zsolt Vasvari
+// thanks-to:Fuzz
+
+/***************************************************************************
+
+Special decryption used on svcpcb and kf2k3pcb.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "includes/neogeo.h"
+
+
+
+
+/* ms5pcb and svcpcb have an additional scramble on top of the standard CMC scrambling */
+void neogeo_noslot_state::svcpcb_gfx_decrypt()
+{
+ static const uint8_t xorval[ 4 ] = { 0x34, 0x21, 0xc4, 0xe9 };
+ int i;
+ int ofst;
+ int rom_size = memregion( "sprites" )->bytes();
+ uint8_t *rom = memregion( "sprites" )->base();
+ std::vector<uint8_t> buf( rom_size );
+
+ for( i = 0; i < rom_size; i++ )
+ {
+ rom[ i ] ^= xorval[ (i % 4) ];
+ }
+ for( i = 0; i < rom_size; i += 4 )
+ {
+ uint32_t rom32 = rom[i] | rom[i+1]<<8 | rom[i+2]<<16 | rom[i+3]<<24;
+ rom32 = BITSWAP32( rom32, 0x09, 0x0d, 0x13, 0x00, 0x17, 0x0f, 0x03, 0x05, 0x04, 0x0c, 0x11, 0x1e, 0x12, 0x15, 0x0b, 0x06, 0x1b, 0x0a, 0x1a, 0x1c, 0x14, 0x02, 0x0e, 0x1d, 0x18, 0x08, 0x01, 0x10, 0x19, 0x1f, 0x07, 0x16 );
+ buf[i] = rom32 & 0xff;
+ buf[i+1] = (rom32>>8) & 0xff;
+ buf[i+2] = (rom32>>16) & 0xff;
+ buf[i+3] = (rom32>>24) & 0xff;
+ }
+ for( i = 0; i < rom_size / 4; i++ )
+ {
+ ofst = BITSWAP24( (i & 0x1fffff), 0x17, 0x16, 0x15, 0x04, 0x0b, 0x0e, 0x08, 0x0c, 0x10, 0x00, 0x0a, 0x13, 0x03, 0x06, 0x02, 0x07, 0x0d, 0x01, 0x11, 0x09, 0x14, 0x0f, 0x12, 0x05 );
+ ofst ^= 0x0c8923;
+ ofst += (i & 0xffe00000);
+ memcpy( &rom[ i * 4 ], &buf[ ofst * 4 ], 0x04 );
+ }
+}
+
+
+/* and a further swap on the s1 data */
+void neogeo_noslot_state::svcpcb_s1data_decrypt()
+{
+ int i;
+ uint8_t *s1 = memregion( "fixed" )->base();
+ size_t s1_size = memregion( "fixed" )->bytes();
+
+ for( i = 0; i < s1_size; i++ ) // Decrypt S
+ {
+ s1[ i ] = BITSWAP8( s1[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
+ }
+}
+
+
+/* kf2k3pcb has an additional scramble on top of the standard CMC scrambling */
+/* Thanks to Razoola & Halrin for the info */
+void neogeo_noslot_state::kf2k3pcb_gfx_decrypt()
+{
+ static const uint8_t xorval[ 4 ] = { 0x34, 0x21, 0xc4, 0xe9 };
+ int i;
+ int ofst;
+ int rom_size = memregion( "sprites" )->bytes();
+ uint8_t *rom = memregion( "sprites" )->base();
+ std::vector<uint8_t> buf( rom_size );
+
+ for ( i = 0; i < rom_size; i++ )
+ {
+ rom[ i ] ^= xorval[ (i % 4) ];
+ }
+ for ( i = 0; i < rom_size; i +=4 )
+ {
+ uint32_t rom32 = rom[i] | rom[i+1]<<8 | rom[i+2]<<16 | rom[i+3]<<24;
+ rom32 = BITSWAP32( rom32, 0x09, 0x0d, 0x13, 0x00, 0x17, 0x0f, 0x03, 0x05, 0x04, 0x0c, 0x11, 0x1e, 0x12, 0x15, 0x0b, 0x06, 0x1b, 0x0a, 0x1a, 0x1c, 0x14, 0x02, 0x0e, 0x1d, 0x18, 0x08, 0x01, 0x10, 0x19, 0x1f, 0x07, 0x16 );
+ buf[i] = rom32 & 0xff;
+ buf[i+1] = (rom32>>8) & 0xff;
+ buf[i+2] = (rom32>>16) & 0xff;
+ buf[i+3] = (rom32>>24) & 0xff;
+ }
+ for ( i = 0; i < rom_size; i+=4 )
+ {
+ ofst = BITSWAP24( (i & 0x7fffff), 0x17, 0x15, 0x0a, 0x14, 0x13, 0x16, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 );
+ ofst ^= 0x000000;
+ ofst += (i & 0xff800000);
+ memcpy( &rom[ ofst ], &buf[ i ], 0x04 );
+ }
+}
+
+
+/* and a further swap on the s1 data */
+void neogeo_noslot_state::kf2k3pcb_decrypt_s1data()
+{
+ uint8_t *src;
+ uint8_t *dst;
+ int i;
+ int tx_size = memregion( "fixed" )->bytes();
+ int srom_size = memregion( "sprites" )->bytes();
+
+ src = memregion( "sprites" )->base() + srom_size - 0x1000000 - 0x80000; // Decrypt S
+ dst = memregion( "fixed" )->base();
+
+ for( i = 0; i < tx_size / 2; i++ )
+ {
+ dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
+ }
+
+ src = memregion( "sprites" )->base() + srom_size - 0x80000;
+ dst = memregion( "fixed" )->base() + 0x80000;
+
+ for( i = 0; i < tx_size / 2; i++ )
+ {
+ dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
+ }
+
+ dst = memregion( "fixed" )->base();
+
+ for( i = 0; i < tx_size; i++ )
+ {
+ dst[ i ] = BITSWAP8( dst[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
+ }
+}
+
+
+
+
+
+/***************************************************************************
+
+NeoGeo 'SP1' (BIOS) ROM encryption
+
+***************************************************************************/
+
+
+/* only found on kf2k3pcb */
+void neogeo_noslot_state::kf2k3pcb_sp1_decrypt()
+{
+ static const uint8_t address[0x40] = {
+ 0x04,0x0a,0x04,0x0a,0x04,0x0a,0x04,0x0a,
+ 0x0a,0x04,0x0a,0x04,0x0a,0x04,0x0a,0x04,
+ 0x09,0x07,0x09,0x07,0x09,0x07,0x09,0x07,
+ 0x09,0x09,0x04,0x04,0x09,0x09,0x04,0x04,
+ 0x0b,0x0d,0x0b,0x0d,0x03,0x05,0x03,0x05,
+ 0x0e,0x0e,0x03,0x03,0x0e,0x0e,0x03,0x03,
+ 0x03,0x05,0x0b,0x0d,0x03,0x05,0x0b,0x0d,
+ 0x04,0x00,0x04,0x00,0x0e,0x0a,0x0e,0x0a
+ };
+
+ uint16_t *rom = (uint16_t *)memregion("mainbios")->base();
+ std::vector<uint16_t> buf(0x80000/2);
+ int i, addr;
+
+ for (i = 0; i < 0x80000/2; i++)
+ {
+ // address xor
+ addr = i ^ 0x0020;
+ if ( i & 0x00020) addr ^= 0x0010;
+ if (~i & 0x00010) addr ^= 0x0040;
+ if (~i & 0x00004) addr ^= 0x0080;
+ if ( i & 0x00200) addr ^= 0x0100;
+ if (~i & 0x02000) addr ^= 0x0400;
+ if (~i & 0x10000) addr ^= 0x1000;
+ if ( i & 0x02000) addr ^= 0x8000;
+ addr ^= address[((i >> 1) & 0x38) | (i & 7)];
+ buf[i] = rom[addr];
+
+ // data xor
+ if (buf[i] & 0x0004) buf[i] ^= 0x0001;
+ if (buf[i] & 0x0010) buf[i] ^= 0x0002;
+ if (buf[i] & 0x0020) buf[i] ^= 0x0008;
+ }
+
+ memcpy(rom, &buf[0], 0x80000);
+}