Naomi: implemented live M2/M3 decryption and decompression & emoved trojaned data from more games. [Andreas Naive, Olivier Galibert, Deunan Knute, Cah4e3, R. Belmont]

This commit is contained in:
R. Belmont 2011-02-27 01:31:59 +00:00
parent ab218cefa3
commit 7457b6e373
2 changed files with 322 additions and 320 deletions

View File

@ -2651,25 +2651,6 @@ ROM_START( doa2 )
// on-cart X76F100 eeprom contents // on-cart X76F100 eeprom contents
ROM_REGION( 0x84, "naomibd_eeprom", 0 ) ROM_REGION( 0x84, "naomibd_eeprom", 0 )
ROM_LOAD( "841-0003.sf", 0x000000, 0x000084, CRC(3a119a17) SHA1(d37a092cca7c9cfc5f2637b355af90a65d04013e) ) ROM_LOAD( "841-0003.sf", 0x000000, 0x000084, CRC(3a119a17) SHA1(d37a092cca7c9cfc5f2637b355af90a65d04013e) )
// trojaned protection data (filename is word offset)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "00000500.bin", 0x000000, 0x020000, CRC(3751d50e) SHA1(08d56e7befd3e1bc2c29217c60dee0c862af65ed) )
ROM_LOAD( "00020504.bin", 0x020000, 0x020000, CRC(6b4ab9f6) SHA1(205c355a5a55659f35645d3e66dc1dcff703727c) )
ROM_LOAD( "00040508.bin", 0x040000, 0x020000, CRC(dae5d37d) SHA1(63d0cde73b86e77ea7b5e1d71643566c500f9933) )
ROM_LOAD( "0006050c.bin", 0x060000, 0x020000, CRC(c2b7ea51) SHA1(59f1cb01b140e7fdea7d945acad464e08e3adf44) )
ROM_LOAD( "00080510.bin", 0x080000, 0x020000, CRC(7b84acb4) SHA1(e48448795c058c0fc3a9e9108de18a3181db5417) )
ROM_LOAD( "000a0514.bin", 0x0a0000, 0x020000, CRC(f954ffcd) SHA1(3015dfc298de1e16db07406e9ecb5fc0e2aae0a8) )
ROM_LOAD( "000c0518.bin", 0x0c0000, 0x020000, CRC(28fce8ad) SHA1(180ae2dc9181bbe4215093e4e933c9e78d3af7a8) )
ROM_LOAD( "000e051c.bin", 0x0e0000, 0x020000, CRC(a7f7a5c1) SHA1(6b39aa8f8a762ffe61b07f77713cca5c95a8dfcf) )
ROM_LOAD( "00100520.bin", 0x100000, 0x020000, CRC(85417674) SHA1(0d35aa0f3d5f451bbf4daad343b9ad1ebd9d9551) )
ROM_LOAD( "00118a3a.bin", 0x120000, 0x020000, CRC(72e58444) SHA1(09ae85c131f7b4a0638efd1dff0807cc20b59637) )
ROM_LOAD( "0012c0d8.bin", 0x140000, 0x020000, CRC(84e8e517) SHA1(f1e81913181b9c6276a430988fefc00597e33e89) )
ROM_LOAD( "00147e22.bin", 0x160000, 0x020000, CRC(66efd53e) SHA1(40cfc20df93f9ec1f260fc3f56bb5ac0be775cc6) )
ROM_LOAD( "001645ce.bin", 0x180000, 0x020000, CRC(adc73d19) SHA1(4df4bd7db6bf2f9af06d9d3ec9466970bec7833c) )
ROM_LOAD( "0017c6b2.bin", 0x1a0000, 0x020000, CRC(717f2e91) SHA1(e03d778a1c39cf01827f79a1b10c03a4a6047962) )
ROM_LOAD( "0019902e.bin", 0x1c0000, 0x020000, CRC(f4882ea8) SHA1(a27e52062780e095675f749191e0ea22755152eb) )
ROM_LOAD( "001b562a.bin", 0x1e0000, 0x013e00, CRC(01ae0721) SHA1(b9f24e0bb8609b8cb1a45e7c1e1dc1f271bbdcaf) )
ROM_END ROM_END
/* /*
@ -2740,25 +2721,6 @@ ROM_START( doa2m )
// on-cart X76F100 eeprom contents // on-cart X76F100 eeprom contents
ROM_REGION( 0x84, "naomibd_eeprom", 0 ) ROM_REGION( 0x84, "naomibd_eeprom", 0 )
ROM_LOAD( "841-0003.sf", 0x000000, 0x000084, CRC(3a119a17) SHA1(d37a092cca7c9cfc5f2637b355af90a65d04013e) ) ROM_LOAD( "841-0003.sf", 0x000000, 0x000084, CRC(3a119a17) SHA1(d37a092cca7c9cfc5f2637b355af90a65d04013e) )
// trojaned protection data (filename is word offset)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "00000500.bin", 0x000000, 0x020000, CRC(a42f0337) SHA1(0aaeff753a4e2f9b5d287cd80952533f0ced430c) )
ROM_LOAD( "00020504.bin", 0x020000, 0x020000, CRC(3d3bfbe4) SHA1(4748ca4c14a31da623ebd3a1acff93635c039888) )
ROM_LOAD( "00040508.bin", 0x040000, 0x020000, CRC(d0c3699c) SHA1(11a4e8b47cb6ae827307cd44689477ebfe23d690) )
ROM_LOAD( "0006050c.bin", 0x060000, 0x020000, CRC(bc2e8e71) SHA1(253561a58caf15607d87d932d9b98d6ffa779669) )
ROM_LOAD( "00080510.bin", 0x080000, 0x020000, CRC(a26a6159) SHA1(8e4f0a2091b5b2eb825bb9220c5e4dfe9ab935fe) )
ROM_LOAD( "000a0514.bin", 0x0a0000, 0x020000, CRC(83138b3b) SHA1(6b69e43b6e6c4b75278045a883337cb7abcf9501) )
ROM_LOAD( "000c0518.bin", 0x0c0000, 0x020000, CRC(9f246058) SHA1(bc54f3bdc23a278b14867e096c3f644447b9c0a6) )
ROM_LOAD( "000e051c.bin", 0x0e0000, 0x020000, CRC(7cfd53d5) SHA1(d77ff8d3edbc2d41334d6416d17339ea2c764887) )
ROM_LOAD( "00100520.bin", 0x100000, 0x020000, CRC(8dd856d3) SHA1(9952fdf9017bdb8c50b413de5817a746c24901e9) )
ROM_LOAD( "0011a5b4.bin", 0x120000, 0x020000, CRC(484c511d) SHA1(02c8c1b46ce8a27b85652d3f032f4f42be5341ba) )
ROM_LOAD( "0012e7c4.bin", 0x140000, 0x020000, CRC(ceffdd4b) SHA1(36dfa9fd4857429cf9b505d04d7a82d3bc161b90) )
ROM_LOAD( "001471f6.bin", 0x160000, 0x020000, CRC(263d0706) SHA1(194e259b78d3006372ad007a7e3b9456f607b922) )
ROM_LOAD( "001640c4.bin", 0x180000, 0x020000, CRC(3addb31e) SHA1(97794166b0811ff9535b3a3f598e0cb3da9fc7b3) )
ROM_LOAD( "001806ca.bin", 0x1a0000, 0x020000, CRC(dbfddad2) SHA1(72696b5ed942fe3ef0bc271f6d66d5f089221192) )
ROM_LOAD( "00199df4.bin", 0x1c0000, 0x020000, CRC(2ab0d0c3) SHA1(10642e9d8c9c24f366359fbe7890a0f1347a7a1a) )
ROM_LOAD( "001b5d0a.bin", 0x1e0000, 0x017e00, CRC(c9c3bbd5) SHA1(6f3853e3e1614993b5d658ebec6bf5183577ab36) )
ROM_END ROM_END
/* /*
@ -3423,29 +3385,6 @@ ROM_START( ggx )
ROM_LOAD("mpr-23353.ic12", 0x6000000, 0x0800000, CRC(daa0ca24) SHA1(afce14e213e79add7fded838e71bb4447425906a) ) ROM_LOAD("mpr-23353.ic12", 0x6000000, 0x0800000, CRC(daa0ca24) SHA1(afce14e213e79add7fded838e71bb4447425906a) )
ROM_LOAD("mpr-23354.ic13", 0x6800000, 0x0800000, CRC(cea127f7) SHA1(11f12472ebfc93eb72b764c780e30afd4812dbe9) ) ROM_LOAD("mpr-23354.ic13", 0x6800000, 0x0800000, CRC(cea127f7) SHA1(11f12472ebfc93eb72b764c780e30afd4812dbe9) )
ROM_LOAD("mpr-23355.ic14", 0x7000000, 0x0800000, CRC(e809685f) SHA1(dc052b4eb4fdcfdc22c4807316ce34ee7a0d58a6) ) ROM_LOAD("mpr-23355.ic14", 0x7000000, 0x0800000, CRC(e809685f) SHA1(dc052b4eb4fdcfdc22c4807316ce34ee7a0d58a6) )
// trojaned protection data
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a0100000.bin", 0x000000, 0x010000, CRC(cbe5a37a) SHA1(63f40758ef94d02a53ad860b2bed9c41e20a8263) )
ROM_LOAD( "a010b268.bin", 0x010000, 0x010000, CRC(7f0ba37e) SHA1(2d33703c9ec08800c3fae23991859f713f8c944b) )
ROM_LOAD( "a0115558.bin", 0x020000, 0x010000, CRC(882c945f) SHA1(60bf8fe3dcf079464f660c7c210d2a379b2ef04f) )
ROM_LOAD( "a0120b28.bin", 0x030000, 0x010000, CRC(024952c0) SHA1(98e4ce87b5ac1169b5ab1ba9cc7553069e09cbbe) )
ROM_LOAD( "a012987a.bin", 0x040000, 0x010000, CRC(50ea6621) SHA1(ea4e5e0b9563c5e49794a634c08be8d2e81fb773) )
ROM_LOAD( "a012e320.bin", 0x050000, 0x010000, CRC(e445906e) SHA1(cd585100b78253bdd16f3895fdb37ff1e08690f6) )
ROM_LOAD( "a0133cf6.bin", 0x060000, 0x00f014, CRC(5763d154) SHA1(645b0a10fd196f53ff7f656b8db798c8e753c4ed) )
ROM_LOAD( "a0170000.bin", 0x070000, 0x010000, CRC(e153030a) SHA1(e1738ec558f0e3d5a796e34618c533cfcd6928ed) )
ROM_LOAD( "a017cf18.bin", 0x080000, 0x010000, CRC(def783cf) SHA1(911e6b99f8ce498ddd5048ea655b76cad33f47c0) )
ROM_LOAD( "a018a45a.bin", 0x090000, 0x010000, CRC(408cd99b) SHA1(110f9922cded7ffc5108ed964b82ac39beb6ce6b) )
ROM_LOAD( "a0197852.bin", 0x0a0000, 0x010000, CRC(09d10a60) SHA1(04bfdba2ea9a45cb10a60fe95d7d2e0997012b4f) )
ROM_LOAD( "a01a4916.bin", 0x0b0000, 0x010000, CRC(3895730e) SHA1(b2c0a839e330916e598c8f27f2a4873bbaaddbde) )
ROM_LOAD( "a01b1c3e.bin", 0x0c0000, 0x010000, CRC(eecb6a13) SHA1(0203c54b98aaf203e7d1b3646102efe63c550115) )
ROM_LOAD( "a01bef38.bin", 0x0d0000, 0x010000, CRC(7d9a497c) SHA1(680a49389e7774aa03ebe6fc844dea53b430796f) )
ROM_LOAD( "a01cbb10.bin", 0x0e0000, 0x010000, CRC(69b770bd) SHA1(aac5801d9a8a48ef77e932195cd7c30ae562bc38) )
ROM_LOAD( "a01d7500.bin", 0x0f0000, 0x010000, CRC(a1119fca) SHA1(1acda8f73a5b1fb180985245b8b0eb9453db0cea) )
ROM_LOAD( "a0200000.bin", 0x100000, 0x010000, CRC(21662b41) SHA1(4dab25dcc92d1a7418d308542499bdec6c3b3b2b) )
ROM_LOAD( "a0210004.bin", 0x110000, 0x010000, CRC(07166890) SHA1(529c28bf925243468fc00b0ad5ea57429d4de907) )
ROM_LOAD( "a0220008.bin", 0x120000, 0x008000, CRC(09cd1354) SHA1(83f6b36aec4e7c5aa1b8bc21dc6fabf8f283ed55) )
ROM_LOAD( "a0228000.bin", 0x130000, 0x008000, CRC(628a4917) SHA1(cf36bc2413cb63fb511936ab4b5f11b7c8cbb057) )
ROM_END ROM_END
/* /*
@ -3743,9 +3682,6 @@ ROM_START( 18wheelr )
ROM_LOAD( "mpr-22182.ic19s", 0x9800000, 0x800000, CRC(c5606c42) SHA1(5871104ff1c7acde0493e13b9a4d0abdf8a40728) ) ROM_LOAD( "mpr-22182.ic19s", 0x9800000, 0x800000, CRC(c5606c42) SHA1(5871104ff1c7acde0493e13b9a4d0abdf8a40728) )
ROM_LOAD( "mpr-22183.ic20s", 0xa000000, 0x800000, CRC(776af308) SHA1(7d29cb4dce75d34c622549fea7e102868d0da60a) ) ROM_LOAD( "mpr-22183.ic20s", 0xa000000, 0x800000, CRC(776af308) SHA1(7d29cb4dce75d34c622549fea7e102868d0da60a) )
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "00800000.bin", 0x000000, 0x002000, CRC(7fc42084) SHA1(7c7b9e7e0b8885e690f3edd25e6d26201c899f2f) )
// JVS I/O board 837-13844, code is for a Z80 of unknown type (it's inside the big Sega ASIC) // JVS I/O board 837-13844, code is for a Z80 of unknown type (it's inside the big Sega ASIC)
ROM_REGION( 0x20000, "jvsio", ROMREGION_ERASEFF) ROM_REGION( 0x20000, "jvsio", ROMREGION_ERASEFF)
ROM_LOAD( "epr-21868.ic7", 0x000000, 0x010000, CRC(c306a51f) SHA1(7833b73dc34c4c62401a30637968f46b949ceac0) ) ROM_LOAD( "epr-21868.ic7", 0x000000, 0x010000, CRC(c306a51f) SHA1(7833b73dc34c4c62401a30637968f46b949ceac0) )
@ -3802,10 +3738,6 @@ ROM_START( sgtetris )
ROM_LOAD( "mpr-22913.ic4", 0x2000000, 0x800000, CRC(1fbdc41a) SHA1(eb8b9577b7677b9e9aec05ae950dee516ae15bf5) ) ROM_LOAD( "mpr-22913.ic4", 0x2000000, 0x800000, CRC(1fbdc41a) SHA1(eb8b9577b7677b9e9aec05ae950dee516ae15bf5) )
ROM_LOAD( "mpr-22914.ic5", 0x2800000, 0x800000, CRC(77844b60) SHA1(65d71febb8a160d00778ac7b53e082253cad9834) ) ROM_LOAD( "mpr-22914.ic5", 0x2800000, 0x800000, CRC(77844b60) SHA1(65d71febb8a160d00778ac7b53e082253cad9834) )
ROM_LOAD( "mpr-22915.ic6", 0x3000000, 0x800000, CRC(e48148ac) SHA1(c1273353eeaf9bb6b185f133281d7d04271bc895) ) ROM_LOAD( "mpr-22915.ic6", 0x3000000, 0x800000, CRC(e48148ac) SHA1(c1273353eeaf9bb6b185f133281d7d04271bc895) )
// trojaned protection data (filename is address read from)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a0cad0c0.bin", 0x000000, 0x0101b2, CRC(0db80e6d) SHA1(74f8e817e3e69c64391b2eff2c8c504dcad9f84f) )
ROM_END ROM_END
/* /*
@ -4694,9 +4626,6 @@ ROM_START( vtenis2c )
ROM_LOAD32_WORD( "mpr-22322.32", 0x7800002, 0x800000, CRC(21bf1caf) SHA1(bc1828db2f5f71ef87153a81b49b2ba72ba176e1) ) ROM_LOAD32_WORD( "mpr-22322.32", 0x7800002, 0x800000, CRC(21bf1caf) SHA1(bc1828db2f5f71ef87153a81b49b2ba72ba176e1) )
ROM_LOAD32_WORD( "mpr-22323.33s", 0x8800000, 0x800000, CRC(0bd632ab) SHA1(21acab5336dd0ba317839176f2557df95917729e) ) ROM_LOAD32_WORD( "mpr-22323.33s", 0x8800000, 0x800000, CRC(0bd632ab) SHA1(21acab5336dd0ba317839176f2557df95917729e) )
ROM_LOAD32_WORD( "mpr-22324.34", 0x8800002, 0x800000, CRC(ff2571d4) SHA1(c2cbb2345163bbf1973e63cefb9a952e5a52a6cf) ) ROM_LOAD32_WORD( "mpr-22324.34", 0x8800002, 0x800000, CRC(ff2571d4) SHA1(c2cbb2345163bbf1973e63cefb9a952e5a52a6cf) )
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "01f169c0.bin", 0x000000, 0x000100, CRC(b0a330f4) SHA1(10c7a7f4d6c7f265a32887beaca73686c4cb1e03) )
ROM_END ROM_END
ROM_START( kick4csh ) ROM_START( kick4csh )

View File

@ -181,7 +181,7 @@ Atomiswave ROM board specs from Cah4e3 @ http://cah4e3.wordpress.com/2009/07/26/
#define NAOMIBD_FLAG_SPECIAL_MODE (4) // used to access protection registers #define NAOMIBD_FLAG_SPECIAL_MODE (4) // used to access protection registers
#define NAOMIBD_FLAG_ADDRESS_SHUFFLE (2) // 0 to let protection chip en/decrypt, 1 for normal #define NAOMIBD_FLAG_ADDRESS_SHUFFLE (2) // 0 to let protection chip en/decrypt, 1 for normal
#define NAOMIBD_PRINTF_PROTECTION (1) // 1 to printf protection access details #define NAOMIBD_PRINTF_PROTECTION (0) // 1 to printf protection access details
/************************************* /*************************************
* *
@ -191,13 +191,33 @@ Atomiswave ROM board specs from Cah4e3 @ http://cah4e3.wordpress.com/2009/07/26/
#define MAX_PROT_REGIONS (32) #define MAX_PROT_REGIONS (32)
#define PACK_BUF_SIZE (32768)
enum
{
CMD_READY = 0,
CMD_FETCH,
CMD_REPEAT
};
typedef struct _naomibd_config_table naomibd_config_table; typedef struct _naomibd_config_table naomibd_config_table;
struct _naomibd_config_table struct _naomibd_config_table
{ {
const char *name; const char *name;
int reverse_bytes; int m2m3_key;
int live_key; int m1_key;
UINT32 transtbl[MAX_PROT_REGIONS*3]; };
typedef struct _naomibd_prot naomibd_prot;
struct _naomibd_prot
{
UINT16 last_word, aux_word, pak_word, heading_word;
UINT16 *ptr;
int count, pak_bit, control_bits, pak_state, dec_count, pak_buf_size, pak_buf_pos;
int pak_fetch_ofs;
UINT8 pak_byte, cmd_byte;
int seed;
UINT8 pak_buf[PACK_BUF_SIZE];
}; };
typedef struct _naomibd_state naomibd_state; typedef struct _naomibd_state naomibd_state;
@ -208,7 +228,6 @@ struct _naomibd_state
device_t *device; /* pointer to our containing device */ device_t *device; /* pointer to our containing device */
UINT8 * memory; UINT8 * memory;
UINT8 * protdata;
chd_file * gdromchd; chd_file * gdromchd;
UINT8 * picdata; UINT8 * picdata;
UINT32 rom_offset, rom_offset_flags, dma_count; UINT32 rom_offset, rom_offset_flags, dma_count;
@ -216,19 +235,16 @@ struct _naomibd_state
UINT32 prot_offset, prot_key; UINT32 prot_offset, prot_key;
UINT32 aw_offset, aw_file_base, aw_file_offset; UINT32 aw_offset, aw_file_base, aw_file_offset;
INT32 prot_sum;
const UINT32 *prot_translate;
int prot_reverse_bytes;
// live decrypt vars // live decrypt vars
UINT32 dc_gamekey, dc_seqkey, dc_seed; UINT32 dc_gamekey, dc_seqkey, dc_dmakey;
UINT8 dc_cart_ram[128*1024]; // internal cartridge RAM UINT8 dc_cart_ram[128*1024]; // internal cartridge RAM
INT32 dc_m3_ptr, dc_m2_ptr, dc_readback; INT32 dc_m3_ptr;
#if NAOMIBD_PRINTF_PROTECTION #if NAOMIBD_PRINTF_PROTECTION
int prot_pio_count; int prot_pio_count;
#endif #endif
naomibd_prot prot;
}; };
// maps protection offsets to real addresses // maps protection offsets to real addresses
@ -237,70 +253,65 @@ struct _naomibd_state
static const naomibd_config_table naomibd_translate_tbl[] = static const naomibd_config_table naomibd_translate_tbl[] =
{ {
// games where on-the-fly decryption works (many of these are fully playable in MAME, just slow) // games where on-the-fly decryption works (many of these are fully playable in MAME, just slow)
{ "18wheelr", 0, 0x07cf54, { 0x1502, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "18wheelr", 0x07cf54, 0 },
{ "alpilota", 0, 0x070e41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "alpilota", 0x070e41, 0 },
{ "alpiltdx", 0, 0x070e41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "alpiltdx", 0x070e41, 0 },
{ "capsnk", 0, 0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "capsnk", 0, 0 },
{ "capsnka", 0, 0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "capsnka", 0, 0 },
{ "crackndj", 0, 0x1c2347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "crackndj", 0x1c2347, 0 },
{ "crzytaxi", 0, 0x0d2f45, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "crzytaxi", 0x0d2f45, 0 },
{ "csmash", 1, 0x103347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "csmash", 0x103347, 0 },
{ "csmasho", 1, 0x103347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "csmasho", 0x103347, 0 },
{ "cspike", 0, 0x0e2010, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "cspike", 0x0e2010, 0 },
{ "deathcox", 0, 0x0b64d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "deathcox", 0x0b64d0, 0 },
{ "derbyoc", 0, 0x0fee35, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "derbyoc", 0x0fee35, 0 },
{ "dybb99", 0, 0x048a01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "doa2", 0x8ad01, 0 },
{ "f355twin", 0, 0x06efd4, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "doa2m", 0x8ad01, 0 },
{ "f355twn2", 0, 0x1666c6, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "dybb99", 0x048a01, 0 },
{ "ggram2", 0, 0x074a61, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "f355twin", 0x06efd4, 0 },
{ "gundmct", 0, 0x0e8010, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "f355twn2", 0x1666c6, 0 },
{ "gwing2", 0, 0x0b25d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "ggram2", 0x074a61, 0 },
{ "hmgeo", 0, 0x038510, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "ggx", 0x076110, 0 },
{ "jambo", 0, 0x0fab95, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "gram2000", 0, 0x7f805c3f },
{ "otrigger", 0, 0x0fea94, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "gundmct", 0x0e8010, 0 },
{ "pjustic", 0, 0x0725d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "gwing2", 0x0b25d0, 0 },
{ "pstone", 0, 0x0e69c1, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "hmgeo", 0x038510, 0 },
{ "pstone2", 0, 0x0b8dc0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "jambo", 0x0fab95, 0 },
{ "puyoda", 0, 0x0acd40, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "kick4csh", 0, 0x820857c9 },
{ "ringout", 0, 0x0b1e40, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "mvsc2", 0, 0xc18b6e7c },
{ "samba", 0, 0x0a8b5d, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "otrigger", 0x0fea94, 0 },
{ "samba2k", 0, 0x1702cf, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "pjustic", 0x0725d0, 0 },
{ "slasho", 0, 0x1a66ca, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "pstone", 0x0e69c1, 0 },
{ "smlg99", 0, 0x048a01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "pstone2", 0x0b8dc0, 0 },
{ "spawn", 0, 0x078d01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "puyoda", 0x0acd40, 0 },
{ "sstrkfgt", 0, 0x132303, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "qmegamis", 0, 0xcd9b4896 },
{ "suchie3", 0, 0x0368e1, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "ringout", 0x0b1e40, 0 },
{ "toyfight", 0, 0x02ca85, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "samba", 0x0a8b5d, 0 },
{ "vf4cart", 0, 0x2ef2f96, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "samba2k", 0x1702cf, 0 },
{ "vtennis", 0, 0x03eb15, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "sgtetris", 0x8ae51, 0 },
{ "vonot", 0, 0x010715, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "shootopl", 0, 0xa0f37ca7 },
{ "wldkicks", 0, 0xae2901, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "shootpl", 0, 0x9d8de9cd },
{ "wwfroyal",0, 0x1627c3, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "shootplm", 0, 0x9d8de9cd },
{ "zerogu2", 0, 0x07c010, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "slasho", 0x1a66ca, 0 },
{ "zombrvn", 0, 0x012b41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "smlg99", 0x048a01, 0 },
{ "spawn", 0x078d01, 0 },
// games where the encryption is stacked with the ASIC's compression { "sstrkfgt", 0x132303, 0 },
{ "doa2", 0, -1, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000, // 0x8ad01, has compression { "suchie3", 0x0368e1, 0 },
-1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x118a3a, 0x120000, { "toyfight", 0x02ca85, 0 },
-1, 0x12c0d8, 0x140000, -1, 0x147e22, 0x160000, -1, 0x1645ce, 0x180000, -1, 0x17c6b2, 0x1a0000, { "vf4cart", 0x2ef2f96, 0 },
-1, 0x19902e, 0x1c0000, -1, 0x1b562a, 0x1e0000, -1, 0xffffffff, 0xffffffff } }, { "vf4evoct", 0, 0x1e5bb0cd },
{ "doa2m", 0, -1, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000, { "virnbao", 0x68b58, 0 }, // note: "virnba" set doesn't have protection
-1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x11a5b4, 0x120000, { "vs2_2k", 0x88b08, 0 },
-1, 0x12e7c4, 0x140000, -1, 0x1471f6, 0x160000, -1, 0x1640c4, 0x180000, -1, 0x1806ca, 0x1a0000, { "vtennis", 0x03eb15, 0 },
-1, 0x199df4, 0x1c0000, -1, 0x1b5d0a, 0x1e0000, 0xffffffff, 0xffffffff } }, { "vtenis2c", 0, 0x2d2d4743 },
{ "ggx", 0, -1, { -1, 0x200000, 0x100000, -1, 0x210004, 0x110000, -1, 0x220008, 0x120000, -1, 0x228000, 0x130000, // 0x76110, uses compression { "vonot", 0x010715, 0 },
0x3af9, 0, 0x000000, 0x2288, 0, 0x010000, 0xe5e6, 0, 0x020000, 0xebb0, 0, 0x030000, { "wldkicks", 0xae2901, 0 },
0x0228, 0, 0x040000, 0x872c, 0, 0x050000, 0xbba0, 0, 0x060000, 0x772f, 0, 0x070000, { "wwfroyal", 0x1627c3, 0 },
0x2924, 0, 0x080000, 0x3222, 0, 0x090000, 0x7954, 0, 0x0a0000, 0x5acd, 0, 0x0b0000, { "zerogu2", 0x07c010, 0 },
0xdd19, 0, 0x0c0000, 0x2428, 0, 0x0d0000, 0x3329, 0, 0x0e0000, 0x2142, 0, 0x0f0000, { "zombrvn", 0x012b41, 0 },
0xffffffff, 0xffffffff, 0xffffffff } },
{ "sgtetris", 0, -1, { 0x1234, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // 0x08ae51, uses compression
// { "virnbao", 0, 0x68b58, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // note: "virnba" set doesn't have protection
// { "vs2_2k", 0, 0x88b08, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
}; };
// forward declaration for decrypt function // forward declaration for decrypt function
static void stream_decrypt(UINT32 game_key, UINT32 sequence_key, UINT16 seed, UINT8* ciphertext, UINT8* plaintext, int length);
static UINT16 block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter, UINT16 data); static UINT16 block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter, UINT16 data);
/*************************************************************************** /***************************************************************************
@ -349,6 +360,219 @@ void *naomibd_get_memory(device_t *device)
return get_safe_token(device)->memory; return get_safe_token(device)->memory;
} }
// Streaming M2/M3 protection and decompression
INLINE UINT16 bswap16(UINT16 in)
{
return ((in>>8) | (in<<8));
}
UINT16 naomibd_get_decrypted_stream(naomibd_state *naomibd)
{
UINT16 wordn = bswap16(naomibd->prot.ptr[naomibd->prot.count++]);
naomibd->prot.aux_word = block_decrypt(naomibd->dc_gamekey, naomibd->dc_seqkey, naomibd->prot.seed++, wordn);
wordn = (naomibd->prot.last_word&~3) | (naomibd->prot.aux_word&3);
naomibd->prot.last_word = naomibd->prot.aux_word;
return wordn;
}
void naomibd_init_stream(naomibd_state *naomibd)
{
naomibd->prot.last_word = 0;
naomibd->prot.control_bits = naomibd_get_decrypted_stream(naomibd);
naomibd->prot.heading_word = naomibd_get_decrypted_stream(naomibd);
if (naomibd->prot.control_bits & 2)
{
naomibd->prot.pak_bit = 0;
naomibd->prot.pak_state = CMD_READY;
naomibd->prot.dec_count = 0;
naomibd->prot.pak_buf_size = 256 << (naomibd->prot.control_bits & 1);
naomibd->prot.pak_buf_pos = 0;
}
}
UINT16 naomibd_get_compressed_bit(naomibd_state *naomibd)
{
if(naomibd->prot.pak_bit == 0)
{
naomibd->prot.pak_bit = 15;
naomibd->prot.pak_word = naomibd_get_decrypted_stream(naomibd);
}
else
{
naomibd->prot.pak_bit--;
naomibd->prot.pak_word<<=1;
}
return naomibd->prot.pak_word >> 15;
}
UINT16 naomibd_get_decompressed_stream(naomibd_state *naomibd)
{
/* node format
0xxxxxxx - next node index
1a0bbccc - end node
a - 0 = repeat
1 = fetch
b - if a = 1
00 - fetch 0
01 - fetch 1
11 - fetch -1
if a = 0
000
c - repeat/fetch counter
count = ccc + 1
11111111 - empty node
*/
static UINT8 trees[9][2][32] = {
{
{0x01,0x10,0x0f,0x05,0xc4,0x13,0x87,0x0a,0xcc,0x81,0xce,0x0c,0x86,0x0e,0x84,0xc2,
0x11,0xc1,0xc3,0xcf,0x15,0xc8,0xcd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc7,0x02,0x03,0x04,0x80,0x06,0x07,0x08,0x09,0xc9,0x0b,0x0d,0x82,0x83,0x85,0xc0,
0x12,0xc6,0xc5,0x14,0x16,0xca,0xcb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x02,0x80,0x05,0x04,0x81,0x10,0x15,0x82,0x09,0x83,0x0b,0x0c,0x0d,0xdc,0x0f,0xde,
0x1c,0xcf,0xc5,0xdd,0x86,0x16,0x87,0x18,0x19,0x1a,0xda,0xca,0xc9,0x1e,0xce,0xff,},
{0x01,0x17,0x03,0x0a,0x08,0x06,0x07,0xc2,0xd9,0xc4,0xd8,0xc8,0x0e,0x84,0xcb,0x85,
0x11,0x12,0x13,0x14,0xcd,0x1b,0xdb,0xc7,0xc0,0xc1,0x1d,0xdf,0xc3,0xc6,0xcc,0xff,},
},
{
{0xc6,0x80,0x03,0x0b,0x05,0x07,0x82,0x08,0x15,0xdc,0xdd,0x0c,0xd9,0xc2,0x14,0x10,
0x85,0x86,0x18,0x16,0xc5,0xc4,0xc8,0xc9,0xc0,0xcc,0xff,0xff,0xff,0xff,0xff,0xff,},
{0x01,0x02,0x12,0x04,0x81,0x06,0x83,0xc3,0x09,0x0a,0x84,0x11,0x0d,0x0e,0x0f,0x19,
0xca,0xc1,0x13,0xd8,0xda,0xdb,0x17,0xde,0xcd,0xcb,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x01,0x80,0x0d,0x04,0x05,0x15,0x83,0x08,0xd9,0x10,0x0b,0x0c,0x84,0x0e,0xc0,0x14,
0x12,0xcb,0x13,0xca,0xc8,0xc2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc5,0x02,0x03,0x07,0x81,0x06,0x82,0xcc,0x09,0x0a,0xc9,0x11,0xc4,0x0f,0x85,0xd8,
0xda,0xdb,0xc3,0xdc,0xdd,0xc1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x01,0x80,0x06,0x0c,0x05,0x81,0xd8,0x84,0x09,0xdc,0x0b,0x0f,0x0d,0x0e,0x10,0xdb,
0x11,0xca,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc4,0x02,0x03,0x04,0xcb,0x0a,0x07,0x08,0xd9,0x82,0xc8,0x83,0xc0,0xc1,0xda,0xc2,
0xc9,0xc3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x01,0x02,0x06,0x0a,0x83,0x0b,0x07,0x08,0x09,0x82,0xd8,0x0c,0xd9,0xda,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc3,0x80,0x03,0x04,0x05,0x81,0xca,0xc8,0xdb,0xc9,0xc0,0xc1,0x0d,0xc2,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x01,0x02,0x03,0x04,0x81,0x07,0x08,0xd8,0xda,0xd9,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc2,0x80,0x05,0xc9,0xc8,0x06,0x82,0xc0,0x09,0xc1,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x01,0x80,0x04,0xc8,0xc0,0xd9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc1,0x02,0x03,0x81,0x05,0xd8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
{
{0x01,0xd8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
{0xc0,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,},
},
};
UINT32 word_complete = 2;
UINT16 wordn = 0;
while(word_complete)
{
switch(naomibd->prot.pak_state)
{
case CMD_READY:
{
UINT32 tmp = 0;
INT32 slot = (naomibd->prot.pak_buf_pos & (naomibd->prot.pak_buf_size-1));
if(slot > 0)
{
if(slot < (naomibd->prot.pak_buf_size-7))
slot = 1;
else
slot = (slot & 7) + 1;
}
while (!(tmp&0x80))
if(naomibd_get_compressed_bit(naomibd))
tmp = trees[slot][1][tmp];
else
tmp = trees[slot][0][tmp];
if(tmp != 0xff)
{
naomibd->prot.pak_byte = (tmp&7)+1;
if(tmp&0x40)
{
static INT32 cmds[4] = {0, 1, 0, -1};
naomibd->prot.pak_fetch_ofs = cmds[(tmp&0x18)>>3];
naomibd->prot.pak_state = CMD_FETCH;
}
else
{
UINT8 byten;
naomibd->prot.pak_state = CMD_REPEAT;
byten = naomibd_get_compressed_bit(naomibd) << 1;
byten = (byten | naomibd_get_compressed_bit(naomibd)) << 1;
byten = (byten | naomibd_get_compressed_bit(naomibd)) << 1;
byten = (byten | naomibd_get_compressed_bit(naomibd)) << 1;
byten = (byten | naomibd_get_compressed_bit(naomibd)) << 1;
byten = (byten | naomibd_get_compressed_bit(naomibd)) << 1;
byten = (byten | naomibd_get_compressed_bit(naomibd)) << 1;
byten = byten | naomibd_get_compressed_bit(naomibd);
naomibd->prot.cmd_byte = byten;
}
}
break;
}
case CMD_FETCH:
naomibd->prot.cmd_byte = naomibd->prot.pak_buf[(naomibd->prot.pak_buf_pos-naomibd->prot.pak_buf_size+naomibd->prot.pak_fetch_ofs)&(PACK_BUF_SIZE-1)];
case CMD_REPEAT:
naomibd->prot.pak_buf[naomibd->prot.pak_buf_pos&(PACK_BUF_SIZE-1)]=naomibd->prot.cmd_byte;
if(word_complete&2)
{
wordn = naomibd->prot.cmd_byte << 8;
}
else
{
wordn = wordn | naomibd->prot.cmd_byte;
}
word_complete--;
naomibd->prot.pak_byte--;
naomibd->prot.pak_buf_pos++;
if(naomibd->prot.pak_byte == 0) naomibd->prot.pak_state = CMD_READY;
break;
}
}
return wordn;
}
// stream read protected PIO hook
//-----------------------------------------------------------
UINT16 naomibd_get_data_stream(naomibd_state *naomibd)
{
UINT16 wordn;
if(naomibd->prot.control_bits&2)
{
wordn = naomibd_get_decompressed_stream(naomibd);
}
else
{
wordn = naomibd_get_decrypted_stream(naomibd);
}
return wordn;
}
offs_t naomibd_get_dmaoffset(device_t *device) offs_t naomibd_get_dmaoffset(device_t *device)
{ {
@ -438,8 +662,6 @@ static void init_save_state(device_t *device)
static void soft_reset(naomibd_state *v) static void soft_reset(naomibd_state *v)
{ {
v->prot_sum = 0;
v->dc_m3_ptr = 0; v->dc_m3_ptr = 0;
v->dc_seqkey = 0; v->dc_seqkey = 0;
} }
@ -474,50 +696,11 @@ READ64_DEVICE_HANDLER( naomibd_r )
// can we live-decrypt this game? // can we live-decrypt this game?
if (v->dc_gamekey != -1) if (v->dc_gamekey != -1)
{ {
ret = (UINT64)(v->dc_cart_ram[v->dc_readback+1] | (v->dc_cart_ram[v->dc_readback]<<8)); ret = (UINT64)naomibd_get_data_stream(v);
v->dc_readback += 2;
} }
else else
{ {
if (v->rom_offset == 0x1fffe) ret = U64(0);
{
UINT8 *prot = (UINT8 *)v->protdata;
UINT32 byte_offset = v->prot_offset*2;
// this is a good time to clear the prot_sum
v->prot_sum = 0;
if (v->prot_translate == NULL)
{
#if NAOMIBD_PRINTF_PROTECTION
v->prot_pio_count += 2;
printf("naomibd: reading protection data, but none was supplied (now %x bytes)\n", v->prot_pio_count);
#endif
return 0;
}
#if NAOMIBD_PRINTF_PROTECTION
v->prot_pio_count += 2;
printf("naomibd: PIO read count %x\n", v->prot_pio_count);
#endif
if (v->prot_reverse_bytes)
{
ret = (UINT64)(prot[byte_offset+1] | (prot[byte_offset]<<8));
}
else
{
ret = (UINT64)(prot[byte_offset] | (prot[byte_offset+1]<<8));
}
v->prot_offset++;
}
#if NAOMIBD_PRINTF_PROTECTION
else
{
printf("Bad protection offset read %x\n", v->rom_offset);
}
#endif
} }
} }
else else
@ -733,7 +916,7 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
v->prot_key = data; v->prot_key = data;
#if NAOMIBD_PRINTF_PROTECTION #if NAOMIBD_PRINTF_PROTECTION
printf("Protection: set up read @ %x, key %x sum %x (PIO %x DMA %x) [%s]\n", v->prot_offset*2, v->prot_key, v->prot_sum, v->rom_offset, v->dma_offset, device->machine->describe_context()); printf("Protection: set up read @ %x, key %x (PIO %x DMA %x) [%s]\n", v->prot_offset*2, v->prot_key, v->rom_offset, v->dma_offset, device->machine->describe_context());
v->prot_pio_count = 0; v->prot_pio_count = 0;
#endif #endif
@ -741,113 +924,44 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
// if dc_gamekey isn't -1, we can live-decrypt this one // if dc_gamekey isn't -1, we can live-decrypt this one
if (v->dc_gamekey != -1) if (v->dc_gamekey != -1)
{ {
UINT8 temp_ram[128*1024];
UINT8 *ROM = (UINT8 *)v->memory; UINT8 *ROM = (UINT8 *)v->memory;
v->dc_seed = 0;
v->dc_readback = 0;
v->dc_seqkey = v->prot_key; v->dc_seqkey = v->prot_key;
#if NAOMIBD_PRINTF_PROTECTION
printf("M2/M3 decrypt: gamekey %x seqkey %x seed %x length %x\n", v->dc_gamekey, v->dc_seqkey, v->dc_seed, v->dc_m3_ptr);
#endif
// M2: just decrypt up to the size limit since we don't know the size in advance
if (v->prot_offset != 0x2000000/2) if (v->prot_offset != 0x2000000/2)
{ {
// decrypt to temp buffer // M2: decrypt from ROM
stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->prot_offset&0xffff, &ROM[v->prot_offset*2], temp_ram, 128*1024); v->prot.ptr = (UINT16 *)&ROM[v->prot_offset*2];
v->prot.seed = v->prot_offset&0xffff;
#if NAOMIBD_PRINTF_PROTECTION
printf("M2 decrypt: gamekey %x seqkey %x length %x\n", v->dc_gamekey, v->dc_seqkey, v->dc_m3_ptr);
#endif
} }
else else
{ {
// decrypt cart ram to temp buffer // M3: decrypt from cart ram
stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed, v->dc_cart_ram, temp_ram, v->dc_m3_ptr); v->prot.ptr = (UINT16 *)v->dc_cart_ram;
v->prot.seed = 0;
#if NAOMIBD_PRINTF_PROTECTION
printf("M3 decrypt: gamekey %x seqkey %x length %x\n", v->dc_gamekey, v->dc_seqkey, v->dc_m3_ptr);
#endif
} }
#if NAOMIBD_PRINTF_PROTECTION v->prot.count = 0;
printf("result: %02x %02x %02x %02x %02x %02x %02x %02x\n", naomibd_init_stream(v);
temp_ram[0], temp_ram[1], temp_ram[2], temp_ram[3],
temp_ram[4], temp_ram[5], temp_ram[6], temp_ram[7]);
#endif
// copy results to cart ram for readback
memcpy(v->dc_cart_ram, temp_ram, 128*1024);
v->dc_m3_ptr = 0; v->dc_m3_ptr = 0;
v->prot_sum = 0;
}
else
{
// translate address if necessary
if (v->prot_translate != NULL)
{
int i = 0;
while (v->prot_translate[i+1] != 0xffffffff)
{
// should we match by key, address, or sum?
if (v->prot_translate[i] == -2) // match sum
{
if (v->prot_translate[i+1] == v->prot_sum)
{
#if NAOMIBD_PRINTF_PROTECTION
printf("Protection: got sum %x, translated to %x\n", v->prot_sum, v->prot_translate[i+2]);
#endif
v->prot_offset = v->prot_translate[i+2]/2;
break;
}
else
{
i+= 3;
}
}
else if (v->prot_translate[i] == -1) // match address
{
if (v->prot_translate[i+1] == (v->prot_offset*2))
{
#if NAOMIBD_PRINTF_PROTECTION
printf("Protection: got offset %x, translated to %x\n", v->prot_offset, v->prot_translate[i+2]);
#endif
v->prot_offset = v->prot_translate[i+2]/2;
break;
}
else
{
i += 3;
}
}
else // match key
{
if (v->prot_translate[i] == v->prot_key)
{
#if NAOMIBD_PRINTF_PROTECTION
printf("Protection: got key %x, translated to %x\n", v->prot_key, v->prot_translate[i+2]);
#endif
v->prot_offset = v->prot_translate[i+2]/2;
break;
}
else
{
i+= 3;
}
}
}
}
#if NAOMIBD_PRINTF_PROTECTION
else
{
printf("naomibd: protection not handled for this game\n");
}
#endif
} }
#if NAOMIBD_PRINTF_PROTECTION
else
{
printf("naomibd: protection not handled for this game\n");
}
#endif
break; break;
case 0x2000000: case 0x2000000:
case 0x2020000: case 0x2020000:
#if NAOMIBD_PRINTF_PROTECTION
printf("Protection write %04x to upload @ %x\n", (UINT32)(data&0xffff), v->dc_m3_ptr);
#endif
v->prot_sum += (INT16)(data&0xffff);
v->dc_cart_ram[v->dc_m3_ptr] = (data&0xff); v->dc_cart_ram[v->dc_m3_ptr] = (data&0xff);
v->dc_cart_ram[v->dc_m3_ptr+1] = (data>>8)&0xff; v->dc_cart_ram[v->dc_m3_ptr+1] = (data>>8)&0xff;
v->dc_m3_ptr += 2; v->dc_m3_ptr += 2;
@ -1703,43 +1817,6 @@ static UINT16 block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter
return aux; return aux;
} }
static void stream_decrypt(UINT32 game_key, UINT32 sequence_key, UINT16 seed, UINT8* ciphertext, UINT8* plaintext, int length)
{
UINT16 counter = seed;
UINT16 last_word;
UINT16 plain_word;
UINT16 aux_word;
int control_bits;
UINT16 heading_word;
last_word = block_decrypt(game_key, sequence_key, counter, *ciphertext<<8 | *(ciphertext+1));
control_bits = last_word&3;
++counter; ciphertext+=2;
aux_word = block_decrypt(game_key, sequence_key, counter, *ciphertext<<8 | *(ciphertext+1));
heading_word = (last_word&~3) | (aux_word&3);
last_word = aux_word;
++counter; ciphertext+=2;
if (BIT(control_bits,1)==0) // no decompression, just decryption
{
for (; length>0; length-=2, ++counter, ciphertext+=2)
{
aux_word = block_decrypt(game_key, sequence_key, counter, *ciphertext<<8 | *(ciphertext+1));
plain_word = (last_word&~3) | (aux_word&3);
last_word = aux_word;
*(plaintext++) = plain_word>>8;
*(plaintext++) = plain_word&0xff;
}
}
else // decryption plus decompression
{
fatalerror("NAOMI ASIC compression unsupported\n");
return; // not implemented, decompression has not been fully reverse engineered as of february/2010
}
}
/*************************************************************************** /***************************************************************************
DEVICE INTERFACE DEVICE INTERFACE
***************************************************************************/ ***************************************************************************/
@ -1766,8 +1843,6 @@ static DEVICE_START( naomibd )
/* store a pointer back to the device */ /* store a pointer back to the device */
v->device = device; v->device = device;
/* find the protection address translation for this game */
v->prot_translate = (UINT32 *)0;
#if NAOMIBD_PRINTF_PROTECTION #if NAOMIBD_PRINTF_PROTECTION
v->prot_pio_count = 0; v->prot_pio_count = 0;
#endif #endif
@ -1775,9 +1850,8 @@ static DEVICE_START( naomibd )
{ {
if (!strcmp(device->machine->gamedrv->name, naomibd_translate_tbl[i].name)) if (!strcmp(device->machine->gamedrv->name, naomibd_translate_tbl[i].name))
{ {
v->prot_translate = &naomibd_translate_tbl[i].transtbl[0]; v->dc_gamekey = naomibd_translate_tbl[i].m2m3_key;
v->prot_reverse_bytes = naomibd_translate_tbl[i].reverse_bytes; v->dc_dmakey = naomibd_translate_tbl[i].m1_key;
v->dc_gamekey = naomibd_translate_tbl[i].live_key;
break; break;
} }
} }
@ -1787,7 +1861,6 @@ static DEVICE_START( naomibd )
{ {
case ROM_BOARD: case ROM_BOARD:
v->memory = (UINT8 *)device->machine->region(config->regiontag)->base(); v->memory = (UINT8 *)device->machine->region(config->regiontag)->base();
v->protdata = (UINT8 *)device->machine->region("naomibd_prot")->base();
break; break;
case AW_ROM_BOARD: case AW_ROM_BOARD: