Naomi updates: [R. Belmont, David Haywood, Andreas Naive, Deunan Knute, Guru, ANY]

- Fix ROM mirroring in gram2000 and friends
- Preliminary hookup of live decryption.  Decryption + decompression is not yet supported so some games still load trojaned data instead.
This commit is contained in:
R. Belmont 2010-02-27 20:17:01 +00:00
parent 000351226a
commit 49d8c9c212
2 changed files with 824 additions and 282 deletions

View File

@ -2227,33 +2227,6 @@ ROM_START( capsnk )
ROM_LOAD( "mpr-23508.ic5", 0x4800000, 0x1000000, CRC(0a3590aa) SHA1(84c0e1853f069b003d09b268caee97e58c4dacb6) ) ROM_LOAD( "mpr-23508.ic5", 0x4800000, 0x1000000, CRC(0a3590aa) SHA1(84c0e1853f069b003d09b268caee97e58c4dacb6) )
ROM_LOAD( "mpr-23509.ic6", 0x5800000, 0x1000000, CRC(281d633d) SHA1(d773be8e95f7bf9212ee1061f3076220d4fce9e0) ) ROM_LOAD( "mpr-23509.ic6", 0x5800000, 0x1000000, CRC(281d633d) SHA1(d773be8e95f7bf9212ee1061f3076220d4fce9e0) )
ROM_LOAD( "mpr-23510.ic7", 0x6800000, 0x1000000, CRC(b856fef5) SHA1(0634f86740c438b40286256a0269570d24cb845a) ) ROM_LOAD( "mpr-23510.ic7", 0x6800000, 0x1000000, CRC(b856fef5) SHA1(0634f86740c438b40286256a0269570d24cb845a) )
// trojaned protection data (filename is address read from)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a63a9260.bin", 0x000000, 0x008760, CRC(54efa963) SHA1(41874253567da56441d83de041f6e82111977fa4) )
ROM_LOAD( "a63b19c0.bin", 0x010000, 0x008260, CRC(f0ca72ef) SHA1(87fc4654afaf763cdb3ea5b4501948bfe7b9e9dc) )
ROM_LOAD( "a63b9c20.bin", 0x020000, 0x00a0c0, CRC(92eec22c) SHA1(c7267503a828e852edeb26f68f3f4b685b9b163e) )
ROM_LOAD( "a63c3ce0.bin", 0x030000, 0x00d7e0, CRC(93201f32) SHA1(5aca43776306a5a5ecd68a7e8699a724703f329a) )
ROM_LOAD( "a63d14c0.bin", 0x040000, 0x00a8e0, CRC(fb2e9f7b) SHA1(ae4fc9a82eafb5b511485eef1d65ee9d3adc27b6) )
ROM_LOAD( "a63dbda0.bin", 0x050000, 0x008460, CRC(b4b74624) SHA1(6ae2f5d69e45d295a3d0dcf295b1fb76be201e8e) )
ROM_LOAD( "a63e4200.bin", 0x060000, 0x00b500, CRC(69ee516d) SHA1(f358aff12b826d1685199a9d5950abd121b54192) )
ROM_LOAD( "a63ef700.bin", 0x070000, 0x00cec0, CRC(b2f4df7e) SHA1(4aafcf65e3fc193ee191f06ffcce37e52fc12364) )
ROM_LOAD( "a63fc5c0.bin", 0x080000, 0x004cfc, CRC(1d534f98) SHA1(32afbb1d1fd1abba9e49b7b4bcf310860e4e47dc) )
ROM_LOAD( "a643a120.bin", 0x090000, 0x00d6e0, CRC(27a0deb7) SHA1(c8da2e212ca8f5985d9336e8200c3382d6d373a5) )
ROM_LOAD( "a6447800.bin", 0x0a0000, 0x00c920, CRC(42c9e4b1) SHA1(d7ef0d23956b795fad888f49a4dc42d74899de71) )
ROM_LOAD( "a6454120.bin", 0x0b0000, 0x00a540, CRC(69321860) SHA1(675767e9fd18a0d72de2decb68acd7d500b11de2) )
ROM_LOAD( "a645e660.bin", 0x0c0000, 0x00ccc0, CRC(4919083d) SHA1(89dfc2837e5298dc691350ac470bc76557657736) )
ROM_LOAD( "a646b320.bin", 0x0d0000, 0x00c120, CRC(a66da245) SHA1(48d543244cdc52887131e734e0643c69f9368681) )
ROM_LOAD( "a6477440.bin", 0x0e0000, 0x0097a8, CRC(6289f812) SHA1(574459f7c79dd757ae94f8e06dbcefa5b203e510) )
ROM_LOAD( "a6480c00.bin", 0x0f0000, 0x00eca0, CRC(a4128a65) SHA1(35625df0109a72cb508bb4a89641bcb86aa697fb) )
ROM_LOAD( "a648f8a0.bin", 0x100000, 0x009520, CRC(45a06ed6) SHA1(e9ee99e329cf35a95440312b9d0bed40254481c2) )
ROM_LOAD( "a6498dc0.bin", 0x110000, 0x009f40, CRC(2cea7b46) SHA1(5398b8f1ba01e21d5fee0b1c6a796ce396c9697f) )
ROM_LOAD( "a64a2d00.bin", 0x120000, 0x00dbe0, CRC(9c75fc98) SHA1(aa1a630c77b29202a4045b1eade455f02f29b81a) )
ROM_LOAD( "a64b08e0.bin", 0x130000, 0x00cb40, CRC(72ae0dd2) SHA1(f4e8face14dac9a5cc75c6ccdfb9911929e2d76e) )
ROM_LOAD( "a64bd420.bin", 0x140000, 0x00e920, CRC(198e4aa9) SHA1(294b9c3f89b138898c3ef6db60ac5473516d74dc) )
ROM_LOAD( "a64cbd40.bin", 0x150000, 0x005e94, CRC(cc4a4e58) SHA1(dce67374a8dc6d2c9b66c0cd7e68b4f9fdab3e27) )
ROM_LOAD( "a6617be0.bin", 0x160000, 0x00e480, CRC(b7d6ce86) SHA1(c3d9a8cf6125c50a0129591d807bbb13a836a651) )
ROM_LOAD( "a6626060.bin", 0x170000, 0x0078a8, CRC(8c258ad2) SHA1(51d4d227e037992905a7a7f2b5bb13646920670d) )
ROM_END ROM_END
// ver 000804 // ver 000804
@ -2271,33 +2244,6 @@ ROM_START( capsnka )
ROM_LOAD( "mpr-23508.ic5", 0x4800000, 0x1000000, CRC(0a3590aa) SHA1(84c0e1853f069b003d09b268caee97e58c4dacb6) ) ROM_LOAD( "mpr-23508.ic5", 0x4800000, 0x1000000, CRC(0a3590aa) SHA1(84c0e1853f069b003d09b268caee97e58c4dacb6) )
ROM_LOAD( "mpr-23509.ic6", 0x5800000, 0x1000000, CRC(281d633d) SHA1(d773be8e95f7bf9212ee1061f3076220d4fce9e0) ) ROM_LOAD( "mpr-23509.ic6", 0x5800000, 0x1000000, CRC(281d633d) SHA1(d773be8e95f7bf9212ee1061f3076220d4fce9e0) )
ROM_LOAD( "mpr-23510.ic7", 0x6800000, 0x1000000, CRC(b856fef5) SHA1(0634f86740c438b40286256a0269570d24cb845a) ) ROM_LOAD( "mpr-23510.ic7", 0x6800000, 0x1000000, CRC(b856fef5) SHA1(0634f86740c438b40286256a0269570d24cb845a) )
// trojaned protection data (filename is address read from)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a63a9260.bin", 0x000000, 0x008760, CRC(54efa963) SHA1(41874253567da56441d83de041f6e82111977fa4) )
ROM_LOAD( "a63b19c0.bin", 0x010000, 0x008260, CRC(f0ca72ef) SHA1(87fc4654afaf763cdb3ea5b4501948bfe7b9e9dc) )
ROM_LOAD( "a63b9c20.bin", 0x020000, 0x00a0c0, CRC(92eec22c) SHA1(c7267503a828e852edeb26f68f3f4b685b9b163e) )
ROM_LOAD( "a63c3ce0.bin", 0x030000, 0x00d7e0, CRC(93201f32) SHA1(5aca43776306a5a5ecd68a7e8699a724703f329a) )
ROM_LOAD( "a63d14c0.bin", 0x040000, 0x00a8e0, CRC(fb2e9f7b) SHA1(ae4fc9a82eafb5b511485eef1d65ee9d3adc27b6) )
ROM_LOAD( "a63dbda0.bin", 0x050000, 0x008460, CRC(b4b74624) SHA1(6ae2f5d69e45d295a3d0dcf295b1fb76be201e8e) )
ROM_LOAD( "a63e4200.bin", 0x060000, 0x00b500, CRC(69ee516d) SHA1(f358aff12b826d1685199a9d5950abd121b54192) )
ROM_LOAD( "a63ef700.bin", 0x070000, 0x00cec0, CRC(b2f4df7e) SHA1(4aafcf65e3fc193ee191f06ffcce37e52fc12364) )
ROM_LOAD( "a63fc5c0.bin", 0x080000, 0x004cfc, CRC(1d534f98) SHA1(32afbb1d1fd1abba9e49b7b4bcf310860e4e47dc) )
ROM_LOAD( "a643a120.bin", 0x090000, 0x00d6e0, CRC(27a0deb7) SHA1(c8da2e212ca8f5985d9336e8200c3382d6d373a5) )
ROM_LOAD( "a6447800.bin", 0x0a0000, 0x00c920, CRC(42c9e4b1) SHA1(d7ef0d23956b795fad888f49a4dc42d74899de71) )
ROM_LOAD( "a6454120.bin", 0x0b0000, 0x00a540, CRC(69321860) SHA1(675767e9fd18a0d72de2decb68acd7d500b11de2) )
ROM_LOAD( "a645e660.bin", 0x0c0000, 0x00ccc0, CRC(4919083d) SHA1(89dfc2837e5298dc691350ac470bc76557657736) )
ROM_LOAD( "a646b320.bin", 0x0d0000, 0x00c120, CRC(a66da245) SHA1(48d543244cdc52887131e734e0643c69f9368681) )
ROM_LOAD( "a6477440.bin", 0x0e0000, 0x0097a8, CRC(6289f812) SHA1(574459f7c79dd757ae94f8e06dbcefa5b203e510) )
ROM_LOAD( "a6480c00.bin", 0x0f0000, 0x00eca0, CRC(a4128a65) SHA1(35625df0109a72cb508bb4a89641bcb86aa697fb) )
ROM_LOAD( "a648f8a0.bin", 0x100000, 0x009520, CRC(45a06ed6) SHA1(e9ee99e329cf35a95440312b9d0bed40254481c2) )
ROM_LOAD( "a6498dc0.bin", 0x110000, 0x009f40, CRC(2cea7b46) SHA1(5398b8f1ba01e21d5fee0b1c6a796ce396c9697f) )
ROM_LOAD( "a64a2d00.bin", 0x120000, 0x00dbe0, CRC(9c75fc98) SHA1(aa1a630c77b29202a4045b1eade455f02f29b81a) )
ROM_LOAD( "a64b08e0.bin", 0x130000, 0x00cb40, CRC(72ae0dd2) SHA1(f4e8face14dac9a5cc75c6ccdfb9911929e2d76e) )
ROM_LOAD( "a64bd420.bin", 0x140000, 0x00e920, CRC(198e4aa9) SHA1(294b9c3f89b138898c3ef6db60ac5473516d74dc) )
ROM_LOAD( "a64cbd40.bin", 0x150000, 0x005e94, CRC(cc4a4e58) SHA1(dce67374a8dc6d2c9b66c0cd7e68b4f9fdab3e27) )
ROM_LOAD( "a6617be0.bin", 0x160000, 0x00e480, CRC(b7d6ce86) SHA1(c3d9a8cf6125c50a0129591d807bbb13a836a651) )
ROM_LOAD( "a6626060.bin", 0x170000, 0x0078a8, CRC(8c258ad2) SHA1(51d4d227e037992905a7a7f2b5bb13646920670d) )
ROM_END ROM_END
/* /*
@ -2338,9 +2284,6 @@ ROM_START( csmash )
ROM_LOAD("mpr-23425.ic6", 0x3000000, 0x0800000, CRC(47f51da2) SHA1(af5ecd460114caed3a00157ffd3a2df0fbf348c0) ) ROM_LOAD("mpr-23425.ic6", 0x3000000, 0x0800000, CRC(47f51da2) SHA1(af5ecd460114caed3a00157ffd3a2df0fbf348c0) )
ROM_LOAD("mpr-23426.ic7", 0x3800000, 0x0800000, CRC(7f91b13f) SHA1(2d534f77291ebfedc011bf0e803a1b9243fb477f) ) ROM_LOAD("mpr-23426.ic7", 0x3800000, 0x0800000, CRC(7f91b13f) SHA1(2d534f77291ebfedc011bf0e803a1b9243fb477f) )
ROM_LOAD("mpr-23427.ic8", 0x4000000, 0x0800000, CRC(5851d525) SHA1(1cb1073542d75a3bcc0d363ed31d49bcaf1fd494) ) ROM_LOAD("mpr-23427.ic8", 0x4000000, 0x0800000, CRC(5851d525) SHA1(1cb1073542d75a3bcc0d363ed31d49bcaf1fd494) )
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_COPY("user1", 0, 0, 0x200000)
ROM_END ROM_END
ROM_START( csmasho ) ROM_START( csmasho )
@ -2359,9 +2302,6 @@ ROM_START( csmasho )
ROM_LOAD("mpr-23425.ic6", 0x3000000, 0x0800000, CRC(47f51da2) SHA1(af5ecd460114caed3a00157ffd3a2df0fbf348c0) ) ROM_LOAD("mpr-23425.ic6", 0x3000000, 0x0800000, CRC(47f51da2) SHA1(af5ecd460114caed3a00157ffd3a2df0fbf348c0) )
ROM_LOAD("mpr-23426.ic7", 0x3800000, 0x0800000, CRC(7f91b13f) SHA1(2d534f77291ebfedc011bf0e803a1b9243fb477f) ) ROM_LOAD("mpr-23426.ic7", 0x3800000, 0x0800000, CRC(7f91b13f) SHA1(2d534f77291ebfedc011bf0e803a1b9243fb477f) )
ROM_LOAD("mpr-23427.ic8", 0x4000000, 0x0800000, CRC(5851d525) SHA1(1cb1073542d75a3bcc0d363ed31d49bcaf1fd494) ) ROM_LOAD("mpr-23427.ic8", 0x4000000, 0x0800000, CRC(5851d525) SHA1(1cb1073542d75a3bcc0d363ed31d49bcaf1fd494) )
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_COPY("user1", 0, 0, 0x200000)
ROM_END ROM_END
/* /*
@ -3066,9 +3006,7 @@ ROM_START( gram2000 )
ROM_REGION( 0xb000000, "user1", ROMREGION_ERASEFF) ROM_REGION( 0xb000000, "user1", ROMREGION_ERASEFF)
ROM_LOAD("epr-23377.ic11", 0x0000000, 0x0400000, CRC(4ca3149c) SHA1(9d25fc659658b416202b033754669be2f3abcdbe) ) ROM_LOAD("epr-23377.ic11", 0x0000000, 0x0400000, CRC(4ca3149c) SHA1(9d25fc659658b416202b033754669be2f3abcdbe) )
/* Test mode returns IC1 as bad dump, it looks like that is data provided by the Actel A54SX32 FPGA present on board // the 0x0800000 - 0x0ffffff space mirrors part of roms 17/18, see ROM_COPY below, gets tested as 'IC1' if actel_id is 0xffff
and mirrored there. Provided as documentation until we know more about it. */
ROM_LOAD("gram2000.ic1", 0x0800000, 0x0800000, CRC(4a86556a) SHA1(61100dc84c95dd47d9f61c7cc52ea25579b90632) )
ROM_LOAD32_WORD("mpr-23357.ic17", 0x1000000, 0x0800000, CRC(eaf77487) SHA1(bdfc4666a6724441c11b31d89fa30c4bd11cbdd1) ) //ic 2 ROM_LOAD32_WORD("mpr-23357.ic17", 0x1000000, 0x0800000, CRC(eaf77487) SHA1(bdfc4666a6724441c11b31d89fa30c4bd11cbdd1) ) //ic 2
ROM_LOAD32_WORD("mpr-23358.ic18", 0x1000002, 0x0800000, CRC(96819a5b) SHA1(e28c9d7b0579ab5d6116401b49f30dc8e4961618) ) //ic 3 ROM_LOAD32_WORD("mpr-23358.ic18", 0x1000002, 0x0800000, CRC(96819a5b) SHA1(e28c9d7b0579ab5d6116401b49f30dc8e4961618) ) //ic 3
ROM_LOAD32_WORD("mpr-23359.ic19", 0x2000000, 0x0800000, CRC(757b9e89) SHA1(b131af1cbcb4fcebb7081b208acc86841192ff14) ) //ic 4 ROM_LOAD32_WORD("mpr-23359.ic19", 0x2000000, 0x0800000, CRC(757b9e89) SHA1(b131af1cbcb4fcebb7081b208acc86841192ff14) ) //ic 4
@ -3089,6 +3027,9 @@ ROM_START( gram2000 )
ROM_LOAD32_WORD("mpr-23374.ic34", 0x9000002, 0x0800000, CRC(1f8a2e08) SHA1(ff9b9bfada831baeb4830a3d1a4bfb38570b9972) ) //ic 19 ROM_LOAD32_WORD("mpr-23374.ic34", 0x9000002, 0x0800000, CRC(1f8a2e08) SHA1(ff9b9bfada831baeb4830a3d1a4bfb38570b9972) ) //ic 19
ROM_LOAD32_WORD("mpr-23375.ic35", 0xa000000, 0x0800000, CRC(7d4043db) SHA1(cadf22419e5b63c33a179bb6b0742035fc9d8028) ) //ic 20 ROM_LOAD32_WORD("mpr-23375.ic35", 0xa000000, 0x0800000, CRC(7d4043db) SHA1(cadf22419e5b63c33a179bb6b0742035fc9d8028) ) //ic 20
ROM_LOAD32_WORD("mpr-23376.ic36", 0xa000002, 0x0800000, CRC(e09cb473) SHA1(c3ec980f1a56142a0e06bae9594d6038acf0690d) ) //ic 21 ROM_LOAD32_WORD("mpr-23376.ic36", 0xa000002, 0x0800000, CRC(e09cb473) SHA1(c3ec980f1a56142a0e06bae9594d6038acf0690d) ) //ic 21
ROM_COPY( "user1", 0x1400000, 0x0800000, 0x0800000 ) // mirror data so IC1 check can pass
//ROM_COPY( "user1", 0x1000000, 0x0400000, 0x0c00000 ) // or does it mirror the start of 17/18 from 0x0400000 upwards like this, check on real hw
ROM_END ROM_END
ROM_START( crackndj ) ROM_START( crackndj )
@ -3206,31 +3147,6 @@ ROM_START( hmgeo )
ROM_LOAD("mpr-23713.ic9", 0x4800000, 0x0800000, CRC(2969bac7) SHA1(5f1cf6ac726c2fe183d66e4022962e44592f9ccd) ) ROM_LOAD("mpr-23713.ic9", 0x4800000, 0x0800000, CRC(2969bac7) SHA1(5f1cf6ac726c2fe183d66e4022962e44592f9ccd) )
ROM_LOAD("mpr-23714.ic10",0x5000000, 0x0800000, CRC(da462c44) SHA1(ca450b6c07f939f96eba7b44c45b4e38abd598aa) ) ROM_LOAD("mpr-23714.ic10",0x5000000, 0x0800000, CRC(da462c44) SHA1(ca450b6c07f939f96eba7b44c45b4e38abd598aa) )
ROM_LOAD("mpr-23715.ic11",0x5800000, 0x0800000, CRC(c750abbd) SHA1(2a5bedc2b21cd3f991c7145ccfd8c7a9e7f647ae) ) ROM_LOAD("mpr-23715.ic11",0x5800000, 0x0800000, CRC(c750abbd) SHA1(2a5bedc2b21cd3f991c7145ccfd8c7a9e7f647ae) )
// trojaned protection data
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a3075ac0.bin", 0x000000, 0x00ff04, CRC(440dca2a) SHA1(4e261ff309e7e774fa2061de30174b0e4e967c00) )
ROM_LOAD( "a30859c4.bin", 0x010000, 0x00ff04, CRC(c22c76a7) SHA1(76d9e47730e4551e6e1a96eeee937296f1153b8b) )
ROM_LOAD( "a30958c8.bin", 0x020000, 0x00ff04, CRC(8f29ee4d) SHA1(e1ac1ccf85dc338e9d5381dfa8ededc8af8f3e92) )
ROM_LOAD( "a30a57cc.bin", 0x030000, 0x00ff04, CRC(479846c1) SHA1(b063e2f7d521cd8a60b770477c13946679e06dd7) )
ROM_LOAD( "a30b56d0.bin", 0x040000, 0x00ff04, CRC(107f777e) SHA1(002f062a2073dff5f0d4722803aef0a8ffc7a61a) )
ROM_LOAD( "a30c55d4.bin", 0x050000, 0x00ff04, CRC(d73b35c1) SHA1(951cceaf6a53d4fc4b967c3675d3fa98a6874b2a) )
ROM_LOAD( "a30d54d8.bin", 0x060000, 0x00ff04, CRC(969a6957) SHA1(ee6909f832b96ec3e6ae0cec3f18a7983cae89d9) )
ROM_LOAD( "a30e53dc.bin", 0x070000, 0x00ff04, CRC(002f7b41) SHA1(12bb33f1229d74b32ab481f5a2e57332f0def6e7) )
ROM_LOAD( "a30f52e0.bin", 0x080000, 0x00a904, CRC(97e32fdd) SHA1(a40f412e40544a45784b2f8d9d5494b6491efc4a) )
ROM_LOAD( "a30ffbe4.bin", 0x090000, 0x000084, CRC(c4311af6) SHA1(7a53061a1a1a024d72880a9a9c2e6a61d2607a46) )
ROM_LOAD( "a30ffc80.bin", 0x0a0000, 0x00ff04, CRC(b1b5e559) SHA1(2f5963d8aa46d7aeb869769a7052d3006d56d5a4) )
ROM_LOAD( "a310fb84.bin", 0x0b0000, 0x00ff04, CRC(91bdc0b2) SHA1(3f77fe6b67dba605296c3c038265b4e0e7eabd97) )
ROM_LOAD( "a311fa88.bin", 0x0c0000, 0x00ff04, CRC(dc5d1334) SHA1(52287bd3ade05be4511e43a7707de8cc38117316) )
ROM_LOAD( "a312f98c.bin", 0x0d0000, 0x00ff04, CRC(e3d9ea36) SHA1(0860f5ac3086d16132f3d0d27266c644470b4f1e) )
ROM_LOAD( "a313f890.bin", 0x0e0000, 0x00ff04, CRC(8b23c562) SHA1(fcc9d04c150f007dcd4a9a2bbee1e438a81b7c49) )
ROM_LOAD( "a314f794.bin", 0x0f0000, 0x009104, CRC(0c0a9aa2) SHA1(1b9063a18703ce4a03ffe20e3f13e9bae06bdb57) )
ROM_LOAD( "a3158898.bin", 0x100000, 0x0000ac, CRC(e23f61d5) SHA1(80ff570a6846f1af2b87e5888675257728e8e253) )
ROM_LOAD( "a0800f40.bin", 0x110000, 0x000204, CRC(f4935846) SHA1(d7eaa710274080f378afa4fb2e14f3bd406c45fe) )
ROM_LOAD( "a0801144.bin", 0x120000, 0x000034, CRC(28a62ac0) SHA1(d9bb6baf5feaca655f333e2f0b9b200f44ef1726) )
ROM_LOAD( "a0801180.bin", 0x130000, 0x00ff04, CRC(4b9e08b7) SHA1(dab208f7af4475210135aeb648e6bed7db7399b9) )
ROM_LOAD( "a0811084.bin", 0x140000, 0x00ff04, CRC(4003bab7) SHA1(0b1df4b9b1d1a1072719b559a71f5ae5811be63c) )
ROM_LOAD( "a0820f88.bin", 0x150000, 0x007e04, CRC(67fb4342) SHA1(8b8c384a1628756a08aa8131095e49756967b5e2) )
ROM_LOAD( "a0828d8c.bin", 0x160000, 0x0000f4, CRC(71c85e2b) SHA1(680b6ee02ea24a502bc42bade23e11e6a7ddc7ad) )
ROM_END ROM_END
/* /*
@ -3253,9 +3169,6 @@ IC8 64M EACA 12CD
IC9 64M 717F 40ED IC9 64M 717F 40ED
IC10 64M 1E43 0F1A IC10 64M 1E43 0F1A
byteswaped @ e0158 key b957 read count 400, write 404
e055c key 37ca read count 400, write 404
*/ */
ROM_START( gwing2 ) ROM_START( gwing2 )
@ -3404,6 +3317,8 @@ ROM_START( mvsc2 )
ROM_LOAD("mpr-23083.ic31", 0x7800000, 0x0400000, CRC(c61d2dfe) SHA1(a05fb979ed7c8040de91716fc8814e6bd995efa2) ) ROM_LOAD("mpr-23083.ic31", 0x7800000, 0x0400000, CRC(c61d2dfe) SHA1(a05fb979ed7c8040de91716fc8814e6bd995efa2) )
ROM_LOAD("mpr-23084.ic32", 0x8000000, 0x0400000, CRC(e228cdfd) SHA1(d02a2e3557bd24cf34c5ddb42d41ca15e78ae885) ) ROM_LOAD("mpr-23084.ic32", 0x8000000, 0x0400000, CRC(e228cdfd) SHA1(d02a2e3557bd24cf34c5ddb42d41ca15e78ae885) )
// DMA protection data // DMA protection data
ROM_LOAD("88000000.bin", 0x8800000, 0x025f00, CRC(77d79823) SHA1(2545d28eee47114e8ffb9bc6d7a910e90fc48420) ) ROM_LOAD("88000000.bin", 0x8800000, 0x025f00, CRC(77d79823) SHA1(2545d28eee47114e8ffb9bc6d7a910e90fc48420) )
ROM_LOAD("88026440.bin", 0x8830000, 0x016520, CRC(dad9ebbd) SHA1(39c0697caa2b5ee11d99e75726e92ed86a23f10b) ) ROM_LOAD("88026440.bin", 0x8830000, 0x016520, CRC(dad9ebbd) SHA1(39c0697caa2b5ee11d99e75726e92ed86a23f10b) )
@ -3433,14 +3348,9 @@ ROM_START( toyfight )
ROM_LOAD("mpr-22032.ic8", 0x4000000, 0x0800000, CRC(3c48c9ba) SHA1(00be199b23040f8e81db2ec489ba98cbf615652c) ) ROM_LOAD("mpr-22032.ic8", 0x4000000, 0x0800000, CRC(3c48c9ba) SHA1(00be199b23040f8e81db2ec489ba98cbf615652c) )
ROM_LOAD("mpr-22033.ic9", 0x4800000, 0x0800000, CRC(5fe5586e) SHA1(3ff41ae1f81469597684faadd88e62b5e0634352) ) ROM_LOAD("mpr-22033.ic9", 0x4800000, 0x0800000, CRC(5fe5586e) SHA1(3ff41ae1f81469597684faadd88e62b5e0634352) )
ROM_LOAD("mpr-22034.ic10",0x5000000, 0x0800000, CRC(3aa5ce5e) SHA1(f00a906235e4522d6fc2ac771324114346875314) ) ROM_LOAD("mpr-22034.ic10",0x5000000, 0x0800000, CRC(3aa5ce5e) SHA1(f00a906235e4522d6fc2ac771324114346875314) )
// protection data (also found in cleartext in the program ROM!)
ROM_REGION( 0x400000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_COPY("user1", 0, 0, 0x400000)
ROM_END ROM_END
/* Crazy Taxi */ /* Crazy Taxi */
/* protection: crypt data at 0x3ff000, key 0x0219, feed 0x504, read 0x500 */
ROM_START( crzytaxi ) ROM_START( crzytaxi )
ROM_REGION( 0x200000, "maincpu", 0) ROM_REGION( 0x200000, "maincpu", 0)
NAOMI_BIOS NAOMI_BIOS
@ -3461,9 +3371,6 @@ ROM_START( crzytaxi )
ROM_LOAD( "mpr21681.ic13s", 0x6800000, 0x800000, CRC(e5dcde7d) SHA1(8a90d9fb4ce0d2ceb609fcf4c54cf5b55c266c50) ) ROM_LOAD( "mpr21681.ic13s", 0x6800000, 0x800000, CRC(e5dcde7d) SHA1(8a90d9fb4ce0d2ceb609fcf4c54cf5b55c266c50) )
ROM_LOAD( "mpr21682.ic14s", 0x7000000, 0x800000, CRC(54c0290e) SHA1(6e07ab6e95c29a2aabed0ba1a7af0d7d605e0309) ) ROM_LOAD( "mpr21682.ic14s", 0x7000000, 0x800000, CRC(54c0290e) SHA1(6e07ab6e95c29a2aabed0ba1a7af0d7d605e0309) )
ROM_LOAD( "mpr21683.ic15s", 0x7800000, 0x800000, CRC(ac8a27e0) SHA1(8e71d853a102dd6c164d5326e6d157ccfb8c7b36) ) ROM_LOAD( "mpr21683.ic15s", 0x7800000, 0x800000, CRC(ac8a27e0) SHA1(8e71d853a102dd6c164d5326e6d157ccfb8c7b36) )
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a03ff000.bin", 0x000000, 0x000500, CRC(be5e415d) SHA1(baf87191236f332c8df7674a080c2be4824a4bcb) )
ROM_END ROM_END
/* Jambo! Safari */ /* Jambo! Safari */
@ -3482,9 +3389,6 @@ ROM_START( jambo )
ROM_LOAD( "mpr22823.ic6", 0x3000000, 0x800000, CRC(00c33e51) SHA1(c55646a146ed259e6c61fd912c93fa784b5e6910) ) ROM_LOAD( "mpr22823.ic6", 0x3000000, 0x800000, CRC(00c33e51) SHA1(c55646a146ed259e6c61fd912c93fa784b5e6910) )
ROM_LOAD( "mpr22824.ic7", 0x3800000, 0x800000, CRC(cc55304a) SHA1(e548d8de83469e5816c55dbbb00afbb894282fd6) ) ROM_LOAD( "mpr22824.ic7", 0x3800000, 0x800000, CRC(cc55304a) SHA1(e548d8de83469e5816c55dbbb00afbb894282fd6) )
ROM_LOAD( "mpr22825.ic8", 0x4000000, 0x800000, CRC(85bada10) SHA1(b6e15d8f1d6bca12ffa4816ed0393c04ca500fba) ) ROM_LOAD( "mpr22825.ic8", 0x4000000, 0x800000, CRC(85bada10) SHA1(b6e15d8f1d6bca12ffa4816ed0393c04ca500fba) )
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a03ff000.bin", 0x000000, 0x000500, CRC(74ffc580) SHA1(8de297303b14a6773c0d944de1bc1dcc3b1d042e) )
ROM_END ROM_END
/* 18 Wheeler */ /* 18 Wheeler */
@ -3660,14 +3564,6 @@ ROM_START( pjustic )
ROM_LOAD( "mpr-23545.ic9", 0x8800000, 0x1000000, CRC(60bd692f) SHA1(37b508f4a821d832eafff81574e7df3fe1c729f8) ) ROM_LOAD( "mpr-23545.ic9", 0x8800000, 0x1000000, CRC(60bd692f) SHA1(37b508f4a821d832eafff81574e7df3fe1c729f8) )
ROM_LOAD( "mpr-23546.ic10", 0x9800000, 0x1000000, CRC(85db2248) SHA1(37845c269a2e65ee6181a8e7500c2e7dd9b2e343) ) ROM_LOAD( "mpr-23546.ic10", 0x9800000, 0x1000000, CRC(85db2248) SHA1(37845c269a2e65ee6181a8e7500c2e7dd9b2e343) )
ROM_LOAD( "mpr-23547.ic11", 0xa800000, 0x1000000, CRC(18b369c7) SHA1(b61cb3fda8cc685865684f7afc7dad0b29d93ca5) ) ROM_LOAD( "mpr-23547.ic11", 0xa800000, 0x1000000, CRC(18b369c7) SHA1(b61cb3fda8cc685865684f7afc7dad0b29d93ca5) )
// trojaned protection data (filename is address read from)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a0820000.bin", 0x000000, 0x00267e, CRC(15db53ed) SHA1(a28ba1abc77ca559cff2fd34f3499c556ad8674e) )
ROM_LOAD( "a0920000.bin", 0x010000, 0x00c91c, CRC(431436f8) SHA1(0136d6b210689b2023f982300bc8842b5c0914b4) )
ROM_LOAD( "a092c920.bin", 0x020000, 0x00a53c, CRC(43e1a419) SHA1(34020cc7b10a1c5b2860db84d133489bce53d3d4) )
ROM_LOAD( "a0936e60.bin", 0x030000, 0x001a32, CRC(2a998df6) SHA1(c7bed2777b2358bc0f1d7a3c23f3029591eb674d) )
ROM_LOAD( "a3480000.bin", 0x040000, 0x008e9c, CRC(c8939e48) SHA1(a8d26c2b32211a50b8cc49b51c0d2e34416cc715) )
ROM_END ROM_END
/* /*
@ -3749,35 +3645,6 @@ ROM_START( pstone2 )
ROM_LOAD("mpr-23124.ic7", 0x3800000, 0x0800000, CRC(508c0207) SHA1(e50d97a17cdd6771fbc63a254a4d638e7daa8f57) ) ROM_LOAD("mpr-23124.ic7", 0x3800000, 0x0800000, CRC(508c0207) SHA1(e50d97a17cdd6771fbc63a254a4d638e7daa8f57) )
ROM_LOAD("mpr-23125.ic8", 0x4000000, 0x0800000, CRC(b9938bbc) SHA1(d55d7adecb5a5a4a276a5a17c12808085d980fd9) ) ROM_LOAD("mpr-23125.ic8", 0x4000000, 0x0800000, CRC(b9938bbc) SHA1(d55d7adecb5a5a4a276a5a17c12808085d980fd9) )
ROM_LOAD("mpr-23126.ic9", 0x4800000, 0x0800000, CRC(fbb0325b) SHA1(21b965519d7508d84344641d43e8af2c3ca29ba4) ) ROM_LOAD("mpr-23126.ic9", 0x4800000, 0x0800000, CRC(fbb0325b) SHA1(21b965519d7508d84344641d43e8af2c3ca29ba4) )
// trojaned protection data (filename is address read from)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a2785e20.bin", 0x000000, 0x0072f0, CRC(52912418) SHA1(ec0992eda50953001801d152e09195a17132cb0f) )
ROM_LOAD( "a2765e00.bin", 0x010000, 0x00e47c, CRC(d9acaa94) SHA1(6ab7ebc2dd78c0bc007f3656a67f3c24d23d48ae) )
ROM_LOAD( "a2774280.bin", 0x020000, 0x00c61c, CRC(8dd9581f) SHA1(f852c44e423effa894769d3e156325a132b2df8e) )
ROM_LOAD( "a27808a0.bin", 0x030000, 0x005568, CRC(4f4aee03) SHA1(453c0ec08ca69ad844f24be290e92bf16231a713) )
ROM_LOAD( "a154bdc0.bin", 0x040000, 0x00ec9c, CRC(755a7343) SHA1(a4355850e1cb6f81d53d461e70884a5c51083454) )
ROM_LOAD( "a155aa60.bin", 0x050000, 0x00951c, CRC(fc7a23d8) SHA1(a428114d89471f4b4c8af6d932376e7b0887c4cc) )
ROM_LOAD( "a1563f80.bin", 0x060000, 0x009f3c, CRC(90903b9c) SHA1(da6fcda74710497bab97c4c8342d93b5dfb14184) )
ROM_LOAD( "a156dec0.bin", 0x070000, 0x00dbdc, CRC(fb7b0b77) SHA1(ace73e925e5ffa3f805ff0ef68b564119cf4ce41) )
ROM_LOAD( "a157baa0.bin", 0x080000, 0x00cb3c, CRC(60e5dad6) SHA1(db8880ebbc3ebb02d861aa3bcf2cc34071d613e8) )
ROM_LOAD( "a15885e0.bin", 0x090000, 0x00e91c, CRC(6b2e1400) SHA1(8965e97e3d85a568c2bef2d1d0faf5b8aee289d0) )
ROM_LOAD( "a1596f00.bin", 0x0a0000, 0x00a3bc, CRC(cf538afa) SHA1(b7f94195760a0b14c18654823ead2e28fe526b07) )
ROM_LOAD( "a15a12c0.bin", 0x0b0000, 0x007f04, CRC(e07d589b) SHA1(60bc7f3e91d1f22b4854777644add346e5df58bb) )
ROM_LOAD( "a15a91e0.bin", 0x0c0000, 0x00c91c, CRC(124fce0b) SHA1(8949df4586c736e22c88b7594221ae114848284a) )
ROM_LOAD( "a15b5b00.bin", 0x0d0000, 0x00a53c, CRC(453bb126) SHA1(d5251f54e80504f3c427f6cc3443fe56edcd62c0) )
ROM_LOAD( "a15c0040.bin", 0x0e0000, 0x0088e0, CRC(7d601fb3) SHA1(ff2aca546e0db05b79f48fdb086f0e8e7e0853e4) )
ROM_LOAD( "a16203e0.bin", 0x0f0000, 0x00c61c, CRC(300c8e1e) SHA1(25f9c4af3bed0da5fc9e440096fb5cf4c29a89b3) )
ROM_LOAD( "a162ca00.bin", 0x100000, 0x009e9c, CRC(8f0ccd81) SHA1(0ae2209912e31195bb8110e28d0791fc398b49cd) )
ROM_LOAD( "a16368a0.bin", 0x110000, 0x00b2dc, CRC(e497f060) SHA1(05d8ffc0ead6c31ddc3197c877466fec354a71d9) )
ROM_LOAD( "a1641b80.bin", 0x120000, 0x00ac5c, CRC(e6d81d57) SHA1(97cfe0b14e1e23c7428dad426848de3fe2496ddb) )
ROM_LOAD( "a164c7e0.bin", 0x130000, 0x008b7c, CRC(ab6ca421) SHA1(84979f01f82f34a9d708b645e9f2cc45abed03a9) )
ROM_LOAD( "a1655360.bin", 0x140000, 0x00c8bc, CRC(c5554803) SHA1(06b712aed14a489d167876217cec48ad0aee495f) )
ROM_LOAD( "a1661c20.bin", 0x150000, 0x0083dc, CRC(4f5abf07) SHA1(3d03f8728ce445b6070f182d84f843f08420ad05) )
ROM_LOAD( "a166a000.bin", 0x160000, 0x00f73c, CRC(bfddc3bf) SHA1(a89bdebefaffc235e163a022d85b7c3bdbffcaf6) )
ROM_LOAD( "a1679740.bin", 0x170000, 0x00fb5c, CRC(ec9889a5) SHA1(d7f04b62a8a78b3bfc9a25f1b21be08dcb986546) )
ROM_LOAD( "a1688d00.bin", 0x180000, 0x00e080, CRC(ad7adaf6) SHA1(516858081ebab25ef0561e4b0f8842026504c5dd) )
ROM_LOAD( "a1696d80.bin", 0x190000, 0x007c10, CRC(4e0c7365) SHA1(0d564956c8330aa57c504a247aef6a230b1e8884) )
ROM_END ROM_END
@ -3879,6 +3746,8 @@ ROM_START( qmegamis )
ROM_LOAD32_WORD("mpr-23225.ic31", 0x8000000, 0x0800000, CRC(ea558614) SHA1(b7dfe5598639a8e59e3cbbee38b1d9a1d8e022ea) ) //ic 16 ROM_LOAD32_WORD("mpr-23225.ic31", 0x8000000, 0x0800000, CRC(ea558614) SHA1(b7dfe5598639a8e59e3cbbee38b1d9a1d8e022ea) ) //ic 16
ROM_LOAD32_WORD("mpr-23226.ic32", 0x8000002, 0x0800000, CRC(cd5da506) SHA1(2e76c8892c1d389b0f12a0046213f43d2ab07d78) ) //ic 17 ROM_LOAD32_WORD("mpr-23226.ic32", 0x8000002, 0x0800000, CRC(cd5da506) SHA1(2e76c8892c1d389b0f12a0046213f43d2ab07d78) ) //ic 17
ROM_COPY( "user1", 0x1400000, 0x0800000, 0x0800000 ) // mirror data for IC1 (no test on this game, but layout is the same as gram2000)
// trojaned protection data (must be in the "user1" region because it's accessed via DMA) // trojaned protection data (must be in the "user1" region because it's accessed via DMA)
ROM_LOAD( "81452000_dma.bin", 0x9000000, 0x000120, CRC(96049488) SHA1(e2b98e8986f8cbf026db50a652300081a8e470b0) ) ROM_LOAD( "81452000_dma.bin", 0x9000000, 0x000120, CRC(96049488) SHA1(e2b98e8986f8cbf026db50a652300081a8e470b0) )
ROM_END ROM_END
@ -4297,10 +4166,6 @@ ROM_START( wwfroyal )
ROM_LOAD( "mpr-22267.ic6", 0x5800000, 0x1000000, CRC(67ec1027) SHA1(2432b33983bbc9b07477459adb5ee1a62b6c0ea3) ) ROM_LOAD( "mpr-22267.ic6", 0x5800000, 0x1000000, CRC(67ec1027) SHA1(2432b33983bbc9b07477459adb5ee1a62b6c0ea3) )
ROM_LOAD( "mpr-22268.ic7", 0x6800000, 0x1000000, CRC(536f5eea) SHA1(f1de8624f82595adf75693b604fb026bf3f778ee) ) ROM_LOAD( "mpr-22268.ic7", 0x6800000, 0x1000000, CRC(536f5eea) SHA1(f1de8624f82595adf75693b604fb026bf3f778ee) )
ROM_LOAD( "mpr-22269.ic8", 0x7800000, 0x1000000, CRC(6c0cf740) SHA1(da10b33a6e54afbe1d7e52801216e7119b0b33b1) ) ROM_LOAD( "mpr-22269.ic8", 0x7800000, 0x1000000, CRC(6c0cf740) SHA1(da10b33a6e54afbe1d7e52801216e7119b0b33b1) )
// trojaned protection data (filename is address read from)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "a24db210.bin", 0x000000, 0x00005e, CRC(79fc852b) SHA1(58229b71d1a7067dd6ce3a617edc7d8bdd132036) )
ROM_END ROM_END
/* /*
@ -5699,15 +5564,7 @@ ROM_START( vf4cart )
ROM_END ROM_END
/* /*
This is the same nonsense layout rom board as gram2000, and just like Tests IC1 like gram2000 if actel_id is 0xffff, see ROM_COPY
that it tests IC1 which doesn't exist - is it a mirror, or protection
related? There is no physical rom for it, also note, the roms are
interleaved, so each test is testing 2 roms and the labeling / ic
positions on the cart don't relate to the display in test mode.
Desired IC1 @ 0x800000 sums from the header = 9f39 fdc4
We need a USB dump of this from 0x800000 to 0x1000000.
*/ */
ROM_START( vf4evoct ) ROM_START( vf4evoct )
NAOMI2_BIOS NAOMI2_BIOS
@ -5735,6 +5592,8 @@ ROM_START( vf4evoct )
ROM_LOAD32_WORD( "mpr-23929.ic34s", 0x9000002, 0x800000, CRC(d768f242) SHA1(3ade29b094308d870ecac53cfe77b843d50af85a) ) ROM_LOAD32_WORD( "mpr-23929.ic34s", 0x9000002, 0x800000, CRC(d768f242) SHA1(3ade29b094308d870ecac53cfe77b843d50af85a) )
ROM_LOAD32_WORD( "mpr-23930.ic35", 0xa000000, 0x800000, CRC(0e45e4c4) SHA1(974b83d4cc35e8ac9f83d04ebd395f1e2196e829) ) ROM_LOAD32_WORD( "mpr-23930.ic35", 0xa000000, 0x800000, CRC(0e45e4c4) SHA1(974b83d4cc35e8ac9f83d04ebd395f1e2196e829) )
ROM_LOAD32_WORD( "mpr-23931.ic36s", 0xa000002, 0x800000, CRC(12ecd2f0) SHA1(3222d4d9d3e30c297a072a8888c28503306db40c) ) ROM_LOAD32_WORD( "mpr-23931.ic36s", 0xa000002, 0x800000, CRC(12ecd2f0) SHA1(3222d4d9d3e30c297a072a8888c28503306db40c) )
ROM_COPY( "user1", 0x1400000, 0x0800000, 0x0800000 ) // mirror data so IC1 check can pass
ROM_END ROM_END
ROM_START( clubkrte ) ROM_START( clubkrte )

View File

@ -196,6 +196,7 @@ struct _naomibd_config_table
{ {
const char *name; const char *name;
int reverse_bytes; int reverse_bytes;
int live_key;
UINT32 transtbl[MAX_PROT_REGIONS*3]; UINT32 transtbl[MAX_PROT_REGIONS*3];
}; };
@ -219,6 +220,12 @@ struct _naomibd_state
const UINT32 *prot_translate; const UINT32 *prot_translate;
int prot_reverse_bytes; int prot_reverse_bytes;
// live decrypt vars
UINT32 dc_gamekey, dc_seqkey, dc_seed;
UINT8 dc_cart_ram[128*1024]; // internal cartridge RAM
INT32 dc_m3_ptr, dc_is_m3, dc_m2_ptr, dc_readback;
#if NAOMIBD_PRINTF_PROTECTION #if NAOMIBD_PRINTF_PROTECTION
int prot_pio_count; int prot_pio_count;
#endif #endif
@ -229,67 +236,52 @@ struct _naomibd_state
// if key is not -1, it's used for the match instead of the address written. // if key is not -1, it's used for the match instead of the address written.
static const naomibd_config_table naomibd_translate_tbl[] = static const naomibd_config_table naomibd_translate_tbl[] =
{ {
{ "doa2", 0, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000, // capsnk/capsnka use a game key of 0. Seriously.
{ "capsnk", 0, 0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "capsnka", 0, 0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "wwfroyal",0, 0x627c3, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "crzytaxi", 0, 0xd2f45, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "jambo", 0, 0xfab95, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "csmash", 1, 0x03347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "csmasho", 1, 0x03347, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "toyfight", 0, 0x2ca85, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "suchie3", 0, 0x368e1, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "vtennis", 0, 0x3eb15, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
// { "vs2_2k", 0, 0x88b08, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // uses compression
{ "dybb99", 0, 0x48a01, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "zombrvn", 0, 0x12b41, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "doa2", 0, -1, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000, // 0x8ad01, has compression
-1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x118a3a, 0x120000, -1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x118a3a, 0x120000,
-1, 0x12c0d8, 0x140000, -1, 0x147e22, 0x160000, -1, 0x1645ce, 0x180000, -1, 0x17c6b2, 0x1a0000, -1, 0x12c0d8, 0x140000, -1, 0x147e22, 0x160000, -1, 0x1645ce, 0x180000, -1, 0x17c6b2, 0x1a0000,
-1, 0x19902e, 0x1c0000, -1, 0x1b562a, 0x1e0000, -1, 0xffffffff, 0xffffffff } }, -1, 0x19902e, 0x1c0000, -1, 0x1b562a, 0x1e0000, -1, 0xffffffff, 0xffffffff } },
{ "doa2m", 0, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000, { "doa2m", 0, -1, { -1, 0x500, 0, -1, 0x20504, 0x20000, -1, 0x40508, 0x40000, -1, 0x6050c, 0x60000, -1, 0x80510, 0x80000,
-1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x11a5b4, 0x120000, -1, 0xa0514, 0xa0000, -1, 0xc0518, 0xc0000, -1, 0xe051c, 0xe0000, -1, 0x100520,0x100000, -1, 0x11a5b4, 0x120000,
-1, 0x12e7c4, 0x140000, -1, 0x1471f6, 0x160000, -1, 0x1640c4, 0x180000, -1, 0x1806ca, 0x1a0000, -1, 0x12e7c4, 0x140000, -1, 0x1471f6, 0x160000, -1, 0x1640c4, 0x180000, -1, 0x1806ca, 0x1a0000,
-1, 0x199df4, 0x1c0000, -1, 0x1b5d0a, 0x1e0000, 0xffffffff, 0xffffffff } }, -1, 0x199df4, 0x1c0000, -1, 0x1b5d0a, 0x1e0000, 0xffffffff, 0xffffffff } },
{ "csmash", 1, { -1, 0x2000000, 0xbb614, 0xffffffff, 0xffffffff, 0xffffffff } }, { "hmgeo", 0, 0x38510, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "csmasho", 1, { -1, 0x2000000, 0xbb5b4, 0xffffffff, 0xffffffff, 0xffffffff } }, { "gwing2", 0, -1, { -1, 0x85ddc0, 0, 0xd567, 0, 0x10000, 0xe329, 0, 0x30000, 0xc112, 0, 0x50000, // 0xb25d0, uses compression
{ "capsnk", 0, { 0x8c2a, 0, 0, 0x3d3e, 0, 0x10000, 0x65b7, 0, 0x20000, 0x5896, 0, 0x30000, 0x16d2, 0, 0x40000,
0x9147, 0, 0x50000, 0x7ac, 0, 0x60000, 0xee67, 0, 0x70000, 0xeb63, 0, 0x80000, 0x2a04, 0, 0x90000,
0x3e41, 0, 0xa0000, 0xb7af, 0, 0xb0000, 0x9651, 0, 0xc0000, 0xd208, 0, 0xd0000, 0x4769, 0, 0xe0000,
0xad8c, 0, 0xf0000, 0x923d, 0, 0x100000, 0x4a65, 0, 0x110000, 0x9958, 0, 0x120000, 0x8216, 0, 0x130000,
0xaa91, 0, 0x140000, 0xd007, 0, 0x150000, 0xead, 0, 0x160000, 0x492, 0, 0x170000,
0xffffffff, 0xffffffff, 0xffffffff } },
{ "capsnka", 0, { 0x8c2a, 0, 0, 0x3d3e, 0, 0x10000, 0x65b7, 0, 0x20000, 0x5896, 0, 0x30000, 0x16d2, 0, 0x40000,
0x9147, 0, 0x50000, 0x7ac, 0, 0x60000, 0xee67, 0, 0x70000, 0xeb63, 0, 0x80000, 0x2a04, 0, 0x90000,
0x3e41, 0, 0xa0000, 0xb7af, 0, 0xb0000, 0x9651, 0, 0xc0000, 0xd208, 0, 0xd0000, 0x4769, 0, 0xe0000,
0xad8c, 0, 0xf0000, 0x923d, 0, 0x100000, 0x4a65, 0, 0x110000, 0x9958, 0, 0x120000, 0x8216, 0, 0x130000,
0xaa91, 0, 0x140000, 0xd007, 0, 0x150000, 0xead, 0, 0x160000, 0x492, 0, 0x170000,
0xffffffff, 0xffffffff, 0xffffffff } },
{ "pjustic", 0, { 0x923d, 0, 0, 0x3e41, 0, 0x10000, 0xb7af, 0, 0x20000,
0x9651, 0, 0x30000, 0xad8c, 0, 0x40000, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "hmgeo", 0, { 0x6cc8, 0, 0x000000, 0x7b92, 0, 0x010000, 0x69bc, 0, 0x020000,
0x6d16, 0, 0x030000, 0x6134, 0, 0x040000, 0x1340, 0, 0x050000,
0x7716, 0, 0x060000, 0x2e1a, 0, 0x070000, 0x3030, 0, 0x080000,
0x0870, 0, 0x090000, 0x2856, 0, 0x0a0000, 0x4224, 0, 0x0b0000,
0x6df0, 0, 0x0c0000, 0x0dd8, 0, 0x0d0000, 0x576c, 0, 0x0e0000,
0x0534, 0, 0x0f0000, 0x0904, 0, 0x100000, 0x2f14, 0, 0x110000,
0x1792, 0, 0x120000, 0x6866, 0, 0x130000, 0x06fa, 0, 0x140000,
0x2842, 0, 0x150000, 0x7cc8, 0, 0x160000, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "wwfroyal",0, { 0xaaaa, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "gwing2", 0, { -1, 0x85ddc0, 0, 0xd567, 0, 0x10000, 0xe329, 0, 0x30000, 0xc112, 0, 0x50000,
0xabcd, 0, 0x70000, 0xef01, 0, 0x90000, 0x1234, 0, 0xb0000, 0x5678, 0, 0xd0000, 0xabcd, 0, 0x70000, 0xef01, 0, 0x90000, 0x1234, 0, 0xb0000, 0x5678, 0, 0xd0000,
0x5555, 0, 0xf0000, 0x6666, 0, 0x110000, 0xa901, 0, 0x130000, 0xa802, 0, 0x150000, 0x5555, 0, 0xf0000, 0x6666, 0, 0x110000, 0xa901, 0, 0x130000, 0xa802, 0, 0x150000,
0x3232, 0, 0x170000, 0x8989, 0, 0x190000, 0x6655, 0, 0x1a0000, 0x3232, 0, 0x170000, 0x8989, 0, 0x190000, 0x6655, 0, 0x1a0000,
0x3944, 0, 0x1c0000, 0x655a, 0, 0x1d0000, 0xf513, 0, 0x1e0000, 0x3944, 0, 0x1c0000, 0x655a, 0, 0x1d0000, 0xf513, 0, 0x1e0000,
0xb957, 0, 0, 0x37ca, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, 0xb957, 0, 0, 0x37ca, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "pstone2", 0, { -2, 0x14db3f4, 0x000000, -2, 0xfbd0179d, 0x010000, -2, 0x9827117, 0x020000, -2, 0x69358f, 0x030000, { "pjustic", 0, 0x725d0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
-2, 0x193954e, 0x040000, -2, 0xba50eb, 0x050000, -2, 0x9f1523, 0x060000, -2, 0xcb7b03, 0x070000, { "pstone2", 0, 0xb8dc0, { 0, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
-2, 0x8f712b, 0x080000, -2, 0x120f246, 0x090000, -2, 0xacc9fc, 0x0a0000, -2, 0x4eb319, 0x0b0000, { "ggx", 0, -1, { -1, 0x200000, 0x100000, -1, 0x210004, 0x110000, -1, 0x220008, 0x120000, -1, 0x228000, 0x130000, // 0x76110, uses compression
-2, 0x19d0c41, 0x0c0000, -2, 0x1077853, 0x0d0000, -2, 0x100019d, 0x0e0000, -2, 0xfd91596b, 0x0f0000,
-2, 0x63bae7, 0x100000, -2, 0x3e3685, 0x110000, -2, 0x6d08a9, 0x120000, -2, 0xfff85c5d, 0x130000,
-2, 0x5263bf, 0x140000, -2, 0x396180, 0x150000, -2, 0x73af6c, 0x160000, -2, 0xfffa8a76, 0x170000,
-2, 0xc2d9e0, 0x180000, -2, 0x33be72, 0x190000,
0xffffffff, 0xffffffff, 0xffffffff } },
{ "toyfight", 0,{ 0x0615, 0, 0x8f058, 0x1999, 0, 0x8ec58, 0x7510, 0, 0x8f458, 0x5736, 0, 0x8e858,
0xffffffff, 0xffffffff, 0xffffffff } },
{ "ggx", 0,{ -1, 0x200000, 0x100000, -1, 0x210004, 0x110000, -1, 0x220008, 0x120000, -1, 0x228000, 0x130000,
0x3af9, 0, 0x000000, 0x2288, 0, 0x010000, 0xe5e6, 0, 0x020000, 0xebb0, 0, 0x030000, 0x3af9, 0, 0x000000, 0x2288, 0, 0x010000, 0xe5e6, 0, 0x020000, 0xebb0, 0, 0x030000,
0x0228, 0, 0x040000, 0x872c, 0, 0x050000, 0xbba0, 0, 0x060000, 0x772f, 0, 0x070000, 0x0228, 0, 0x040000, 0x872c, 0, 0x050000, 0xbba0, 0, 0x060000, 0x772f, 0, 0x070000,
0x2924, 0, 0x080000, 0x3222, 0, 0x090000, 0x7954, 0, 0x0a0000, 0x5acd, 0, 0x0b0000, 0x2924, 0, 0x080000, 0x3222, 0, 0x090000, 0x7954, 0, 0x0a0000, 0x5acd, 0, 0x0b0000,
0xdd19, 0, 0x0c0000, 0x2428, 0, 0x0d0000, 0x3329, 0, 0x0e0000, 0x2142, 0, 0x0f0000, 0xdd19, 0, 0x0c0000, 0x2428, 0, 0x0d0000, 0x3329, 0, 0x0e0000, 0x2142, 0, 0x0f0000,
0xffffffff, 0xffffffff, 0xffffffff } }, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "crzytaxi", 0,{ 0x0219, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "18wheelr", 0, -1, { 0x1502, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // 0x7cf54, uses compression
{ "jambo", 0,{ 0x0223, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, { "sgtetris", 0, -1, { 0x1234, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } }, // 0x8ae51, uses compression
{ "18wheelr", 0,{ 0x1502, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
{ "sgtetris", 0,{ 0x1234, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff } },
}; };
// forward declaration for decrypt function
static void stream_decrypt(UINT32 game_key, UINT32 sequence_key, UINT16 seed, UINT8* ciphertext, UINT8* plaintext, int length);
/*************************************************************************** /***************************************************************************
INLINE FUNCTIONS INLINE FUNCTIONS
***************************************************************************/ ***************************************************************************/
@ -377,6 +369,9 @@ static void init_save_state(running_device *device)
static void soft_reset(naomibd_state *v) static void soft_reset(naomibd_state *v)
{ {
v->prot_sum = 0; v->prot_sum = 0;
v->dc_m3_ptr = 0;
v->dc_seqkey = 0;
} }
@ -405,6 +400,37 @@ READ64_DEVICE_HANDLER( naomibd_r )
UINT64 ret = 0; UINT64 ret = 0;
if (v->rom_offset_flags & NAOMIBD_FLAG_SPECIAL_MODE) if (v->rom_offset_flags & NAOMIBD_FLAG_SPECIAL_MODE)
{
// can we live-decrypt this game?
if (v->dc_gamekey != -1)
{
if (v->dc_is_m3)
{
ret = (UINT64)(v->dc_cart_ram[v->dc_readback+1] | (v->dc_cart_ram[v->dc_readback]<<8));
v->dc_readback += 2;
}
else
{
UINT8 plain[2], crypt[2];
crypt[0] = ROM[(v->prot_offset*2)+v->dc_seed+1];
crypt[1] = ROM[(v->prot_offset*2)+v->dc_seed];
// decrypt
// stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed>>1, &ROM[(v->prot_offset*2)+v->dc_seed], plain, 2);
stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed>>1, crypt, plain, 2);
ret = (UINT64)(plain[0] | (plain[1]<<8));
#if NAOMIBD_PRINTF_PROTECTION
printf("M2 decrypt: gamekey %x seqkey %x offset %x seed %x src %02x %02x = %02x %02x\n", v->dc_gamekey, v->dc_seqkey, v->prot_offset*2, v->dc_seed>>1, ROM[(v->prot_offset*2)+v->dc_seed], ROM[(v->prot_offset*2)+v->dc_seed+1], plain[0], plain[1]);
#endif
// bump readback pointer
v->dc_seed += 2;
}
}
else
{ {
if (v->rom_offset == 0x1fffe) if (v->rom_offset == 0x1fffe)
{ {
@ -446,6 +472,7 @@ READ64_DEVICE_HANDLER( naomibd_r )
} }
#endif #endif
} }
}
else else
{ {
ret = (UINT64)(ROM[v->rom_offset] | (ROM[v->rom_offset+1]<<8)); ret = (UINT64)(ROM[v->rom_offset] | (ROM[v->rom_offset+1]<<8));
@ -461,7 +488,15 @@ READ64_DEVICE_HANDLER( naomibd_r )
else if ((offset == 2) && ACCESSING_BITS_32_63) else if ((offset == 2) && ACCESSING_BITS_32_63)
{ {
// Actel FPGA ID, used on some games for a "special" ROM test. // Actel FPGA ID, used on some games for a "special" ROM test.
//
// without this (by returning 0xffff) some games will do a rom test where
// the IC numbers tested do not relate to the actual ROMs on the cart,
// and a fake 'IC1' will be tested, which returns mirrored data from the
// other roms in order to pass if enabled on the real hardware.
// (certain bios / board combinations will also cause this, so it is
// important that we mirror the data in the rom loading using ROM_COPY)
//return (UINT64)0xffff << 32;
return (UINT64)actel_id << 32; return (UINT64)actel_id << 32;
} }
else if ((offset == 7) && ACCESSING_BITS_32_47) else if ((offset == 7) && ACCESSING_BITS_32_47)
@ -513,7 +548,6 @@ READ64_DEVICE_HANDLER( naomibd_r )
WRITE64_DEVICE_HANDLER( naomibd_w ) WRITE64_DEVICE_HANDLER( naomibd_w )
{ {
naomibd_state *v = get_safe_token(device); naomibd_state *v = get_safe_token(device);
INT32 i;
// AW board // AW board
if (v->type == AW_ROM_BOARD) if (v->type == AW_ROM_BOARD)
@ -657,10 +691,46 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
v->prot_pio_count = 0; v->prot_pio_count = 0;
#endif #endif
// if dc_gamekey isn't -1, we can live-decrypt this one
if (v->dc_gamekey != -1)
{
v->dc_seed = 0;
v->dc_is_m3 = 0;
v->dc_readback = 0;
v->dc_seqkey = v->prot_key;
if (v->prot_offset == 0x2000000/2) // M3 readback, must decrypt now
{
UINT8 temp_ram[128*1024];
#if NAOMIBD_PRINTF_PROTECTION
printf("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
// decrypt cart ram to temp buffer
stream_decrypt(v->dc_gamekey, v->dc_seqkey, v->dc_seed, v->dc_cart_ram, temp_ram, v->dc_m3_ptr);
#if NAOMIBD_PRINTF_PROTECTION
printf("result: %02x %02x %02x %02x %02x %02x %02x %02x\n",
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_is_m3 = 1;
}
v->dc_m3_ptr = 0;
v->prot_sum = 0;
}
else
{
// translate address if necessary // translate address if necessary
if (v->prot_translate != NULL) if (v->prot_translate != NULL)
{ {
i = 0; int i = 0;
while (v->prot_translate[i+1] != 0xffffffff) while (v->prot_translate[i+1] != 0xffffffff)
{ {
// should we match by key, address, or sum? // should we match by key, address, or sum?
@ -717,14 +787,19 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
printf("naomibd: protection not handled for this game\n"); printf("naomibd: protection not handled for this game\n");
} }
#endif #endif
}
break; break;
case 0x2000000: case 0x2000000:
case 0x2020000: case 0x2020000:
#if NAOMIBD_PRINTF_PROTECTION #if NAOMIBD_PRINTF_PROTECTION
printf("Protection write %04x to upload\n", (UINT32)(data&0xffff)); printf("Protection write %04x to upload @ %x\n", (UINT32)(data&0xffff), v->dc_m3_ptr);
#endif #endif
v->prot_sum += (INT16)(data&0xffff); v->prot_sum += (INT16)(data&0xffff);
v->dc_cart_ram[v->dc_m3_ptr] = (data&0xff);
v->dc_cart_ram[v->dc_m3_ptr+1] = (data>>8)&0xff;
v->dc_m3_ptr += 2;
break; break;
default: default:
@ -971,7 +1046,614 @@ static void load_rom_gdrom(running_machine* machine, naomibd_state *v)
cdrom_close(gdromfile); cdrom_close(gdromfile);
} }
/***************************************************************************
DECRYPTION EMULATION
By convention, we label the tree known cart protection methods this way (using Deunan Knute's wording):
M1: DMA read of protected ROM area
M2: special read of ROM area which supplies decryption key first
M3: normal read followed by write to cart's decryption buffer (up to 64kB), followed by M2 but from buffer area
M1's working is still unclear (more on this later), so we will be speaking of M2 & M3 most of the time.
The encryption is done by a stream cipher operating in counter mode, which use a 16-bits internal block cipher.
There are 2 "control bits" at the start of the decrypted stream which control the mode of operation: bit #1 set to 1 means
that the decrypted stream needs to be decompressed after being decrypted. More on this later.
The next 16-bits are part of the header (they don't belong to the plaintext), but his meaning is unclear. It has been
conjectured that it could stablish when to "reset" the process and start processing a new stream (based on some tests
on WWFROYAL, in which the decryption's output doesn't seem to be valid for more than some dozens of words), but some
more testing would be needed for clarifying that.
After those 18 heading bits, we find the proper plaintext. It must be noted that, due to the initial 2 special bits,
the 16-bits words of the plaintext are shifted 2 bits respect to the word-boundaries of the output stream of the
internal block-cipher. So, at a given step, the internal block cipher will output 16-bits, 14 of which will go to a
given plaintext word, and the remaining 2 to the next plaintext word.
The underlying block cipher consists of two 4-round Feistel Networks (FN): the first one takes the counter (16 bits),
the game-key (20 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key
for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key and the result
from the first FN and will output the decrypted word (16 bits).
Each round of the Feistel Networks use four substitution sboxes, each having 6 inputs and 2 outputs. The input can be the
XOR of at most two "sources bits", being source bits the bits from the previous round and the bits from the different keys.
The underlying block cipher has the same structure than the one used by the CPS-2 (Capcom Play System 2) and,
indeed, some of the used sboxes are exactly the same and appear in the same FN/round in both systems (this is not evident,
as you need to apply a bitswapping and some XORs to the input & output of the sboxes to get the same values due). However,
the key scheduling used by this implementation is much weaker than the CPS-2's one. Many s-boxes inputs are XORed with any
key bit and, indeed, the cart-specific key is just 20-bits long.
Due to the small key-length, no sophisticated attacks are needed to recover the keys; a brute-force attack knowing just
one or two (encrypted word-decrypted word) pairs suffice.
The only difference in the decryption process between M2 and M3 is the initialization of the counter. In M3, the counter is
always set to 0 at the beginning of the decryption while, in M2, the bits #1-#16 of the ciphertext's address are used
to initialize the counter.
Due to the nature of the cipher, there are some degrees of freedom when choosing the s-boxes and keys values; by example,
you could apply a fixed bitswapping and XOR to the keys and the decryption would remain the same as long as you change
accordingly the s-boxes' definitions. So the order of the bits in the keys is arbitrary, and the s-boxes values have been
chosen so as to make the key for CAPSNK equal to 0.
It can be observed that some sboxes have incomplete tables (a 255 value indicate an unknown value). In most of the cases,
they are apparently unused by the cipher (due to the weak key scheduling mentioned above). As of february/2010, the only
s-box which have a incomplete table which could be begin used is the 4th s-box of the 1st round of the 2nd FN. It's
incomplete because we haven't located any game using that part of the s-box till now, but definitively it could be being
used by some still-not-analyzed carts.
When bit #1 of the heading control bits is set to 1, an additional decompression step seems to be carried out. As of
february/2010, Deunan Knute has put some work on analyzing the decompression algorithm, but probably much more work will
be needed to completely reverse engineer it. Interested devs with quick access to hardware tests are welcomed to join
the task.
Guilty Gear X & Sega Tetris are examples of games using the decompression ingame.
Due to technical details, it's more difficult to get custom decryption data from M1 carts, which hinders some types of
analysis. The only M1 cart which have received attention until now have been AH! MY GODDESS. The available data clearly
doesn't have the same structure than M2&M3 carts using only the decryption step. However, due to that some hardware tests
show cycled structures similar to the ones returned by M2&M3 carts using the decompression algo, it's conjectured that M1
carts will be using the same decompression algorithm seen in M2&M3 ones.
****************************************************************************************/
struct sbox
{
UINT8 table[64];
int inputs[6]; // positions of the inputs bits, -1 means no input except from key
int outputs[2]; // positions of the output bits
};
static const struct sbox fn1_sboxes[4][4] =
{
{ // 1st round
{
{
0,3,2,2,1,3,1,2,3,2,1,2,1,2,3,1,3,2,2,0,2,1,3,0,0,3,2,3,2,1,2,0,
// unused
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
},
{3,4,5,7,-1,-1},
{0,4}
},
{
{
2,2,2,0,3,3,0,1,2,2,3,2,3,0,2,2,1,1,0,3,3,2,0,2,0,1,0,1,2,3,1,1,
0,1,3,3,1,3,3,1,2,3,2,0,0,0,2,2,0,3,1,3,0,3,2,2,0,3,0,3,1,1,0,2,
},
{0,1,2,5,6,7},
{1,6}
},
{
{
0,1,3,0,3,1,1,1,1,2,3,1,3,0,2,3,3,2,0,2,1,1,2,1,1,3,1,0,0,2,0,1,
1,3,1,0,0,3,2,3,2,0,3,3,0,0,0,0,1,2,3,3,2,0,3,2,1,0,0,0,2,2,3,3,
},
{0,2,5,6,7,-1},
{2,3}
},
{
{
3,2,1,2,1,2,3,2,0,3,2,2,3,1,3,3,0,2,3,0,3,3,2,1,1,1,2,0,2,2,0,1,
1,3,3,0,0,3,0,3,0,2,1,3,2,1,0,0,0,1,1,2,0,1,0,0,0,1,3,3,2,0,3,3,
},
{1,2,3,4,6,7},
{5,7}
},
},
{ // 2nd round
{
{
3,3,1,2,0,0,2,2,2,1,2,1,3,1,1,3,3,0,0,3,0,3,3,2,1,1,3,2,3,2,1,3,
2,3,0,1,3,2,0,1,2,1,3,1,2,2,3,3,3,1,2,2,0,3,1,2,2,1,3,0,3,0,1,3,
},
{0,1,3,4,5,7},
{0,4}
},
{
{
2,0,1,0,0,3,2,0,3,3,1,2,1,3,0,2,0,2,0,0,0,2,3,1,3,1,1,2,3,0,3,0,
// unused
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
},
{0,1,3,4,6,-1},
{1,5}
},
{
{
2,2,2,3,1,1,0,1,0,1,2,2,3,3,0,2,0,3,2,3,3,0,2,1,0,3,1,0,0,2,3,2,
3,2,0,3,2,0,1,0,3,3,1,1,2,2,2,0,2,1,3,1,1,1,1,2,2,2,3,0,1,3,0,0,
},
{1,2,5,6,7,-1},
{2,7}
},
{
{
0,1,3,3,3,1,3,3,1,0,2,0,2,0,0,3,1,2,1,3,1,2,3,2,2,0,1,3,0,3,3,3,
0,0,0,2,1,1,2,3,2,2,3,1,1,2,0,2,0,2,1,3,1,1,3,3,1,1,3,0,2,3,0,0,
},
{2,3,4,5,6,7},
{3,6}
},
},
{ // 3rd round
{
{
0,0,1,0,1,0,0,3,2,0,0,3,0,1,0,2,0,3,0,0,2,0,3,2,2,1,3,2,2,1,1,2,
0,0,0,3,0,1,1,0,0,2,1,0,3,1,2,2,2,0,3,1,3,0,1,2,2,1,1,1,0,2,3,1,
},
{1,2,3,4,5,7},
{0,5}
},
{
{
1,2,1,0,3,1,1,2,0,0,2,3,2,3,1,3,2,0,3,2,2,3,1,1,1,1,0,3,2,0,0,1,
1,0,0,1,3,1,2,3,0,0,2,3,3,0,1,0,0,2,3,0,1,2,0,1,3,3,3,1,2,0,2,1,
},
{0,2,4,5,6,7},
{1,6}
},
{
{
0,3,0,2,1,2,0,0,1,1,0,0,3,1,1,0,0,3,0,0,2,3,3,2,3,1,2,0,0,2,3,0,
// unused
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
},
{0,2,4,6,7,-1},
{2,3}
},
{
{
0,0,1,0,0,1,0,2,3,3,0,3,3,2,3,0,2,2,2,0,3,2,0,3,1,0,0,3,3,0,0,0,
2,2,1,0,2,0,3,2,0,0,3,1,3,3,0,0,2,1,1,2,1,0,1,1,0,3,1,2,0,2,0,3,
},
{0,1,2,3,6,-1},
{4,7}
},
},
{ // 4th round
{
{
0,3,3,3,3,3,2,0,0,1,2,0,2,2,2,2,1,1,0,2,2,1,3,2,3,2,0,1,2,3,2,1,
3,2,2,3,1,0,1,0,0,2,0,1,2,1,2,3,1,2,1,1,2,2,1,0,1,3,2,3,2,0,3,1,
},
{0,1,3,4,5,6},
{0,5}
},
{
{
0,3,0,0,2,0,3,1,1,1,2,2,2,1,3,1,2,2,1,3,2,2,3,3,0,3,1,0,3,2,0,1,
3,0,2,0,1,0,2,1,3,3,1,2,2,0,2,3,3,2,3,0,1,1,3,3,0,2,1,3,0,2,2,3,
},
{0,1,2,3,5,7},
{1,7}
},
{
{
0,1,2,3,3,3,3,1,2,0,2,3,2,1,0,1,2,2,1,2,0,3,2,0,1,1,0,1,3,1,3,1,
3,1,0,0,1,0,0,0,0,1,2,2,1,1,3,3,1,2,3,3,3,2,3,0,2,2,1,3,3,0,2,0,
},
{2,3,4,5,6,7},
{2,3}
},
{
{
0,2,1,1,3,2,0,3,1,0,1,0,3,2,1,1,2,2,0,3,1,0,1,2,2,2,3,3,0,0,0,0,
1,2,1,0,2,1,2,2,2,3,2,3,0,1,3,0,0,1,3,0,0,1,1,0,1,0,0,0,0,2,0,1,
},
{0,1,2,4,6,7},
{4,6}
},
},
};
static const struct sbox fn2_sboxes[4][4] =
{
{ // 1st round
{
{
3,3,0,1,0,1,0,0,0,3,0,0,1,3,1,2,0,3,3,3,2,1,0,1,1,1,2,2,2,3,2,2,
2,1,3,3,1,3,1,1,0,0,1,2,0,2,2,1,1,2,3,1,2,1,3,1,2,2,0,1,3,0,2,2,
},
{1,3,4,5,6,7},
{0,7}
},
{
{
0,2,3,2,1,1,0,0,2,1,0,3,3,0,0,0,3,2,0,2,1,1,2,1,0,0,3,1,2,2,3,1,
3,1,3,0,0,0,1,3,1,0,0,3,2,2,3,1,1,3,0,0,2,1,3,3,1,3,1,2,3,1,2,1,
},
{0,3,5,6,-1,-1},
{1,2}
},
{
{
0,2,2,1,0,1,2,1,2,0,1,2,3,3,0,1,3,1,1,2,1,2,1,3,3,2,3,3,2,1,0,1,
// unused
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
},
{0,2,3,4,7,-1},
{3,4}
},
{
{
2,3,1,3,2,0,1,2,0,0,3,3,3,3,3,1,2,0,2,1,2,3,0,2,0,1,0,3,0,2,1,0,
2,3,0,1,3,0,3,2,3,1,2,0,3,1,1,2,
// potentially used, but we haven't located any game using it
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
},
{1,2,5,6,-1,-1},
{5,6}
},
},
{ // 2nd round
{
{
2,3,1,3,1,0,3,3,3,2,3,3,2,0,0,3,2,3,0,3,1,1,2,3,1,1,2,2,0,1,0,0,
2,1,0,1,2,0,1,2,0,3,1,1,2,3,1,2,0,2,0,1,3,0,1,0,2,2,3,0,3,2,3,0,
},
{0,1,4,5,6,7},
{0,7}
},
{
{
0,2,2,0,2,2,0,3,2,3,2,1,3,2,3,3,1,1,0,0,3,0,2,1,1,3,3,2,3,2,0,1,
1,2,3,0,1,0,3,0,3,1,0,2,1,2,0,3,2,3,1,2,2,0,3,2,3,0,0,1,2,3,3,3,
},
{0,2,3,6,7,-1},
{1,5}
},
{
{
1,2,3,2,0,3,2,3,0,1,1,0,0,2,2,3,2,0,0,3,0,2,3,3,2,2,1,0,2,1,0,3,
1,0,2,0,1,1,0,1,0,0,1,0,3,0,3,3,2,2,0,2,1,1,1,0,3,0,1,3,2,3,2,1,
},
{2,3,4,6,7,-1},
{2,3}
},
{
{
2,3,1,3,1,1,2,3,3,1,1,0,1,0,2,3,2,1,0,0,2,2,0,1,0,2,2,2,0,2,1,0,
3,1,2,3,1,3,0,2,1,0,1,0,0,1,2,2,3,2,3,1,3,2,1,1,2,0,2,1,3,3,1,0,
},
{1,2,3,4,5,6},
{4,6}
},
},
{ // 3rd round
{
{
0,3,0,1,0,2,3,3,1,0,1,3,2,2,1,1,3,3,3,0,2,0,2,0,0,0,2,3,1,1,0,0,
3,3,0,3,3,0,0,2,1,1,1,0,2,2,2,0,3,0,3,1,2,2,0,3,0,0,3,2,0,3,2,1,
},
{1,4,5,6,7,-1},
{0,5}
},
{
{
0,3,0,1,3,0,3,1,3,2,2,2,3,0,3,2,2,1,2,2,0,3,2,2,0,0,2,1,1,3,2,3,
2,3,3,1,2,0,1,2,2,1,0,0,0,0,2,3,1,2,0,3,1,3,1,2,3,2,1,0,3,0,0,2,
},
{0,2,3,4,6,7},
{1,7}
},
{
{
2,2,3,2,0,3,2,3,1,1,2,0,2,3,1,3,0,0,0,3,2,0,1,0,1,3,2,3,3,3,1,0,
// unused
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
},
{1,2,4,7,-1,-1},
{2,4}
},
{
{
0,2,3,1,3,1,1,0,0,1,3,0,2,1,3,3,2,0,2,1,1,2,3,3,0,0,0,2,0,2,3,0,
3,3,3,3,2,3,3,2,3,0,1,0,2,3,3,2,0,1,3,1,0,1,2,3,3,0,2,0,3,0,3,3,
},
{0,1,2,3,5,7},
{3,6}
},
},
{ // 4th round
{
{
0,1,1,0,0,1,0,2,3,3,0,1,2,3,0,2,1,0,3,3,2,0,3,0,0,2,1,0,1,0,1,3,
0,3,3,1,2,0,3,0,1,3,2,0,3,3,1,3,0,2,3,3,2,1,1,2,2,1,2,1,2,0,1,1,
},
{0,1,2,4,7,-1},
{0,5}
},
{
{
2,0,0,2,3,0,2,3,3,1,1,1,2,1,1,0,0,2,1,0,0,3,1,0,0,3,3,0,1,0,1,2,
0,2,0,2,0,1,2,3,2,1,1,0,3,3,3,3,3,3,1,0,3,0,0,2,0,3,2,0,2,2,0,1,
},
{0,1,3,5,6,-1},
{1,3}
},
{
{
0,1,1,2,1,3,1,1,0,0,3,1,1,1,2,0,3,2,0,1,1,2,3,3,3,0,3,0,0,2,0,3,
3,2,0,0,3,2,3,1,2,3,0,3,2,0,1,2,2,2,0,2,0,1,2,2,3,1,2,2,1,1,1,1,
},
{0,2,3,4,5,7},
{2,7}
},
{
{
0,1,2,0,3,3,0,3,2,1,3,3,0,3,1,1,3,2,3,2,3,0,0,0,3,0,2,2,3,2,2,3,
2,2,3,1,2,3,1,2,0,3,0,2,3,1,0,0,3,2,1,2,1,2,1,3,1,0,2,3,3,1,3,2,
},
{2,3,4,5,6,7},
{4,6}
},
},
};
static const int fn1_game_key_scheduling[30][2] =
{
{1,29}, {1,71}, {1,81}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73},
{5,11}, {6,51}, {7,92}, {8,89}, {9,9}, {9,10}, {9,39}, {9,41},
{9,58}, {9,59}, {9,86}, {10,90}, {11,6}, {12,64}, {13,49}, {14,44},
{15,40}, {16,69}, {17,15}, {18,23}, {18,43}, {19,82},
};
static const int fn2_game_key_scheduling[27][2] =
{
{0,0}, {1,3}, {1,35}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29},
{7,38}, {8,39}, {9,47}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50},
{10,53}, {11,57}, {12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72},
{17,83}, {18,88}, {19,94},
};
static const int fn1_sequence_key_scheduling[20][2] =
{
{0,52}, {1,34}, {2,17}, {3,36}, {4,84}, {4,88}, {5,57}, {6,48},
{6,68}, {7,76}, {8,83}, {9,30}, {10,22}, {10,41}, {11,38}, {12,55},
{13,74}, {14,19}, {14,80}, {15,26}
};
static const int fn2_sequence_key_scheduling[16] = {77,34,8,42,36,27,69,66,13,9,79,31,49,7,24,64};
static const int fn2_middle_result_scheduling[16] = {1,10,44,68,74,78,81,95,2,4,30,40,41,51,53,58};
static int feistel_function(int input, const struct sbox* sboxes, UINT32 subkeys)
{
int k,m;
int aux;
int result=0;
for (m=0; m<4; ++m) // 4 sboxes
{
for (k=0, aux=0; k<6; ++k)
{
if (sboxes[m].inputs[k]!=-1)
{
aux |= (BIT(input, sboxes[m].inputs[k])<<k);
}
}
aux = sboxes[m].table[(aux^subkeys)&0x3f];
for (k=0; k<2; ++k)
{
result |= (BIT(aux,k)<<sboxes[m].outputs[k]);
}
subkeys >>=6;
}
return result;
}
/**************************
This implementation is an "educational" version. It must be noted that it can be speed-optimized in a number of ways.
The most evident one is to factor out the parts of the key-scheduling that must only be done once (like the game-key &
sequence-key parts) as noted in the comments inlined in the function. More sophisticated speed-ups can be gained by
noticing that the weak key-scheduling would allow to create some pregenerated look-up tables for doing most of the work
of the function. Even so, it would still be pretty slow, so caching techniques could be a wiser option here.
**************************/
static UINT16 block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter, UINT16 data)
{
int j;
int aux,aux2;
int A,B;
int middle_result;
UINT32 fn1_subkeys[4];
UINT32 fn2_subkeys[4];
/* Game-key scheduling; this could be done just once per game at initialization time */
memset(fn1_subkeys,0,sizeof(UINT32)*4);
memset(fn2_subkeys,0,sizeof(UINT32)*4);
for (j=0; j<30; ++j)
{
if (BIT(game_key, fn1_game_key_scheduling[j][0])!=0)
{
aux = fn1_game_key_scheduling[j][1]%24;
aux2 = fn1_game_key_scheduling[j][1]/24;
fn1_subkeys[aux2] ^= (1<<aux);
}
}
for (j=0; j<27; ++j)
{
if (BIT(game_key, fn2_game_key_scheduling[j][0])!=0)
{
aux = fn2_game_key_scheduling[j][1]%24;
aux2 = fn2_game_key_scheduling[j][1]/24;
fn2_subkeys[aux2] ^= (1<<aux);
}
}
/********************************************************/
/* Sequence-key scheduling; this could be done just once per decryption run */
for (j=0; j<20; ++j)
{
if (BIT(sequence_key,fn1_sequence_key_scheduling[j][0])!=0)
{
aux = fn1_sequence_key_scheduling[j][1]%24;
aux2 = fn1_sequence_key_scheduling[j][1]/24;
fn1_subkeys[aux2] ^= (1<<aux);
}
}
for (j=0; j<16; ++j)
{
if (BIT(sequence_key,j)!=0)
{
aux = fn2_sequence_key_scheduling[j]%24;
aux2 = fn2_sequence_key_scheduling[j]/24;
fn2_subkeys[aux2] ^= (1<<aux);
}
}
// subkeys bits 10 & 41
fn2_subkeys[0] ^= (BIT(sequence_key,2)<<10);
fn2_subkeys[1] ^= (BIT(sequence_key,4)<<17);
/**************************************************************/
// First Feistel Network
aux = BITSWAP16(counter,5,12,14,13,9,3,6,4, 8,1,15,11,0,7,10,2);
// 1st round
B = aux >> 8;
A = (aux & 0xff) ^ feistel_function(B,fn1_sboxes[0],fn1_subkeys[0]);
// 2nd round
B = B ^ feistel_function(A,fn1_sboxes[1],fn1_subkeys[1]);
// 3rd round
A = A ^ feistel_function(B,fn1_sboxes[2],fn1_subkeys[2]);
// 4th round
B = B ^ feistel_function(A,fn1_sboxes[3],fn1_subkeys[3]);
middle_result = (B<<8)|A;
/* Middle-result-key sheduling */
for (j=0; j<16; ++j)
{
if (BIT(middle_result,j)!=0)
{
aux = fn2_middle_result_scheduling[j]%24;
aux2 = fn2_middle_result_scheduling[j]/24;
fn2_subkeys[aux2] ^= (1<<aux);
}
}
/*********************/
// Second Feistel Network
aux = BITSWAP16(data,14,3,8,12,13,7,15,4, 6,2,9,5,11,0,1,10);
// 1st round
B = aux >> 8;
A = (aux & 0xff) ^ feistel_function(B,fn2_sboxes[0],fn2_subkeys[0]);
// 2nd round
B = B ^ feistel_function(A,fn2_sboxes[1],fn2_subkeys[1]);
// 3rd round
A = A ^ feistel_function(B,fn2_sboxes[2],fn2_subkeys[2]);
// 4th round
B = B ^ feistel_function(A,fn2_sboxes[3],fn2_subkeys[3]);
aux = (B<<8)|A;
aux = BITSWAP16(aux,15,7,6,14,13,12,5,4, 3,2,11,10,9,1,0,8);
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
@ -1010,6 +1692,7 @@ static DEVICE_START( naomibd )
{ {
v->prot_translate = &naomibd_translate_tbl[i].transtbl[0]; v->prot_translate = &naomibd_translate_tbl[i].transtbl[0];
v->prot_reverse_bytes = naomibd_translate_tbl[i].reverse_bytes; v->prot_reverse_bytes = naomibd_translate_tbl[i].reverse_bytes;
v->dc_gamekey = naomibd_translate_tbl[i].live_key;
break; break;
} }
} }