Previous 199869 Revisions Next

r40109 Saturday 1st August, 2015 at 15:28:22 UTC by Andreas Naive
Preliminary decryption support for Namco System 10 [Andreas Naive]
[scripts/target/mame]arcade.lua
[src/mame/drivers]namcos10.c
[src/mame/machine]ns10crypt.c* ns10crypt.h*

trunk/scripts/target/mame/arcade.lua
r248620r248621
20852085   MAME_DIR .. "src/mame/machine/namcos1.c",
20862086   MAME_DIR .. "src/mame/video/namcos1.c",
20872087   MAME_DIR .. "src/mame/drivers/namcos10.c",
2088   MAME_DIR .. "src/mame/machine/ns10crypt.c",
20882089   MAME_DIR .. "src/mame/drivers/namcos11.c",
20892090   MAME_DIR .. "src/mame/machine/ns11prot.c",
20902091   MAME_DIR .. "src/mame/drivers/namcos12.c",
trunk/src/mame/drivers/namcos10.c
r248620r248621
269269#include "emu.h"
270270#include "cpu/psx/psx.h"
271271#include "video/psx.h"
272#include "machine/ns10crypt.h"
272273
273274class namcos10_state : public driver_device
274275{
r248620r248621
283284   DECLARE_WRITE16_MEMBER(bank_w);
284285
285286   // memn variant interface
286   DECLARE_READ16_MEMBER (nand_status_r);
287   DECLARE_WRITE16_MEMBER(crypto_switch_w);
288   DECLARE_READ16_MEMBER(nand_status_r);
287289   DECLARE_WRITE8_MEMBER(nand_address1_w);
288290   DECLARE_WRITE8_MEMBER(nand_address2_w);
289291   DECLARE_WRITE8_MEMBER(nand_address3_w);
r248620r248621
301303   UINT32 bank_base;
302304   UINT32 nand_address;
303305   UINT16 block[0x1ff];
306   ns10_decrypter_device* decrypter;
304307
305308   UINT16 nand_read( UINT32 address );
306309   UINT16 nand_read2( UINT32 address );
r248620r248621
401404// Block access to the nand.  Something strange is going on with the
402405// status port.  Interaction with the decryption is unclear at best.
403406
407WRITE16_MEMBER(namcos10_state::crypto_switch_w)
408{
409   if (BIT(data, 15) != 0)
410      decrypter->activate();
411   else
412      decrypter->deactivate();
413}
414
404415READ16_MEMBER(namcos10_state::nand_status_r )
405416{
406417   return 0;
r248620r248621
451462/*  printf( "data<-%08x (%08x)\n", data, nand_address ); */
452463   nand_address++;
453464
454   return data;
465   if (decrypter->is_active())
466      return decrypter->decrypt(data);
467   else
468      return data;
455469}
456470
457471void namcos10_state::nand_copy( UINT32 *dst, UINT32 address, int len )
r248620r248621
475489}
476490
477491static ADDRESS_MAP_START( namcos10_memn_map, AS_PROGRAM, 32, namcos10_state )
478   AM_RANGE(0x1f300000, 0x1f300003) AM_WRITE16(key_w, 0x0000ffff)
479
492   AM_RANGE(0x1f300000, 0x1f300003) AM_WRITE16(crypto_switch_w, 0x0000ffff)
480493   AM_RANGE(0x1f400000, 0x1f400003) AM_READ16(nand_status_r, 0x0000ffff)
481494   AM_RANGE(0x1f410000, 0x1f410003) AM_WRITE8(nand_address1_w, 0x000000ff)
482495   AM_RANGE(0x1f420000, 0x1f420003) AM_WRITE8(nand_address2_w, 0x000000ff)
r248620r248621
492505{
493506   UINT8 *BIOS = (UINT8 *)memregion( "maincpu:rom" )->base();
494507   nand_base = (UINT8 *)memregion( "user2" )->base();
508   decrypter = static_cast<ns10_decrypter_device*>(machine().root_device().subdevice("decrypter"));
495509
496510   nand_copy( (UINT32 *)( BIOS + 0x0000000 ), 0x08000, 0x001c000 );
497511   nand_copy( (UINT32 *)( BIOS + 0x0020000 ), 0x24000, 0x03e0000 );
498512}
499513
500static void decrypt_bios( running_machine &machine, const char *regionName, int start, int b15, int b14, int b13, int b12, int b11, int b10, int b9, int b8,
514static void decrypt_bios( running_machine &machine, const char *regionName, int start, int end, int b15, int b14, int b13, int b12, int b11, int b10, int b9, int b8,
501515   int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0 )
502516{
503517   memory_region *region = machine.root_device().memregion( regionName );
504518   UINT16 *BIOS = (UINT16 *)( region->base() + start );
505   int len = (region->bytes()-start)/2;
519   int len = (end - start) / 2;
506520
507521   for( int i = 0; i < len; i++ )
508522   {
r248620r248621
513527
514528DRIVER_INIT_MEMBER(namcos10_state,mrdrilr2)
515529{
516   decrypt_bios( machine(), "maincpu:rom", 0, 0xc, 0xd, 0xf, 0xe, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x4, 0x1, 0x2, 0x5, 0x0, 0x3 );
530   int regSize = machine().root_device().memregion("user2")->bytes();
531   decrypt_bios(machine(), "maincpu:rom", 0, regSize, 0xc, 0xd, 0xf, 0xe, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x4, 0x1, 0x2, 0x5, 0x0, 0x3);
517532}
518533
519534DRIVER_INIT_MEMBER(namcos10_state,gjspace)
520535{
521   decrypt_bios( machine(), "user2", 0x8400, 0x0, 0x2, 0xe, 0xd, 0xf, 0x6, 0xc, 0x7, 0x5, 0x1, 0x9, 0x8, 0xa, 0x3, 0x4, 0xb );
536   int regSize = machine().root_device().memregion("user2")->bytes();
537   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x0, 0x2, 0xe, 0xd, 0xf, 0x6, 0xc, 0x7, 0x5, 0x1, 0x9, 0x8, 0xa, 0x3, 0x4, 0xb);
522538   memn_driver_init();
523539}
524540
525541DRIVER_INIT_MEMBER(namcos10_state,mrdrilrg)
526542{
527   decrypt_bios( machine(), "user2", 0x8400, 0x6, 0x4, 0x7, 0x5, 0x2, 0x1, 0x0, 0x3, 0xc, 0xd, 0xe, 0xf, 0x8, 0x9, 0xb, 0xa );
543   int regSize = machine().root_device().memregion("user2")->bytes();
544   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x6, 0x4, 0x7, 0x5, 0x2, 0x1, 0x0, 0x3, 0xc, 0xd, 0xe, 0xf, 0x8, 0x9, 0xb, 0xa);
528545   memn_driver_init();
529546}
530547
531548DRIVER_INIT_MEMBER(namcos10_state,knpuzzle)
532549{
533   decrypt_bios( machine(), "user2", 0x8400, 0x6, 0x7, 0x4, 0x5, 0x2, 0x0, 0x3, 0x1, 0xc, 0xd, 0xe, 0xf, 0x9, 0xb, 0x8, 0xa );
550   int regSize = machine().root_device().memregion("user2")->bytes();
551   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x6, 0x7, 0x4, 0x5, 0x2, 0x0, 0x3, 0x1, 0xc, 0xd, 0xe, 0xf, 0x9, 0xb, 0x8, 0xa);
534552   memn_driver_init();
535553}
536554
537555DRIVER_INIT_MEMBER(namcos10_state,startrgn)
538556{
539   decrypt_bios( machine(), "user2", 0x8400, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9 );
557   decrypt_bios(machine(), "user2", 0x008400, 0x028000, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
558   decrypt_bios(machine(), "user2", 0x0b4000, 0xfdc000, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
540559   memn_driver_init();
541560}
542561
543562DRIVER_INIT_MEMBER(namcos10_state,gamshara)
544563{
545   decrypt_bios( machine(), "user2", 0x8400, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x8, 0x9, 0xa, 0xb );
564   int regSize = machine().root_device().memregion("user2")->bytes();
565   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x8, 0x9, 0xa, 0xb);
546566   memn_driver_init();
547567}
548568
549569DRIVER_INIT_MEMBER(namcos10_state,gunbalna)
550570{
551   decrypt_bios( machine(), "user2", 0x8400, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x9, 0x8, 0xa, 0xb );
571   int regSize = machine().root_device().memregion("user2")->bytes();
572   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x5, 0x4, 0x7, 0x6, 0x0, 0x1, 0x3, 0x2, 0xd, 0xf, 0xc, 0xe, 0x9, 0x8, 0xa, 0xb);
552573   memn_driver_init();
553574}
554575
555576DRIVER_INIT_MEMBER(namcos10_state,chocovdr)
556577{
557   decrypt_bios( machine(), "user2", 0x8400, 0x5, 0x4, 0x6, 0x7, 0x1, 0x0, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x8, 0xb, 0xa, 0x9 );
578   int regSize = machine().root_device().memregion("user2")->bytes();
579   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x5, 0x4, 0x6, 0x7, 0x1, 0x0, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x8, 0xb, 0xa, 0x9);
558580   memn_driver_init();
559581}
560582
561583DRIVER_INIT_MEMBER(namcos10_state,panikuru)
562584{
563   decrypt_bios( machine(), "user2", 0x8400, 0x6, 0x4, 0x7, 0x5, 0x0, 0x1, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x9, 0x8, 0xb, 0xa );
585   int regSize = machine().root_device().memregion("user2")->bytes();
586   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x6, 0x4, 0x7, 0x5, 0x0, 0x1, 0x2, 0x3, 0xc, 0xf, 0xe, 0xd, 0x9, 0x8, 0xb, 0xa);
564587   memn_driver_init();
565588}
566589
567590DRIVER_INIT_MEMBER(namcos10_state,nflclsfb)
568591{
569   decrypt_bios( machine(), "user2", 0x8400, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9 );
592   int regSize = machine().root_device().memregion("user2")->bytes();
593   decrypt_bios(machine(), "user2", 0x8400, regSize, 0x6, 0x5, 0x4, 0x7, 0x1, 0x3, 0x0, 0x2, 0xc, 0xd, 0xe, 0xf, 0x8, 0xb, 0xa, 0x9);
570594   memn_driver_init();
571595}
572596
573597DRIVER_INIT_MEMBER(namcos10_state,konotako)
574598{
575   decrypt_bios( machine(), "user2", 0x8400, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa );
599   decrypt_bios(machine(), "user2", 0x008400, 0x028000, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
600   decrypt_bios(machine(), "user2", 0x0b4000, 0xfdc000, 0x6, 0x7, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0xd, 0xc, 0xf, 0xe, 0x8, 0x9, 0xb, 0xa);
576601   memn_driver_init();
577602}
578603
r248620r248621
615640   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
616641MACHINE_CONFIG_END
617642
643static MACHINE_CONFIG_DERIVED(ns10_konotako, namcos10_memn)
644/* decrypter device (CPLD in hardware?) */
645MCFG_DEVICE_ADD("decrypter", KONOTAKO_DECRYPTER, 0)
646MACHINE_CONFIG_END
647
648static MACHINE_CONFIG_DERIVED(ns10_startrgn, namcos10_memn)
649/* decrypter device (CPLD in hardware?) */
650MCFG_DEVICE_ADD("decrypter", STARTRGN_DECRYPTER, 0)
651MACHINE_CONFIG_END
652
618653static INPUT_PORTS_START( namcos10 )
619654   /* IN 0 */
620655   PORT_START("SYSTEM")
r248620r248621
750785   ROM_FILL( 0x0000000, 0x400000, 0x55 )
751786
752787   ROM_REGION16_LE( 0x2100000, "user2", 0 ) /* main prg */
753   ROM_LOAD( "gnn2a.8e",         0x0000000, 0x1080000, CRC(31b39221) SHA1(7fcb14aaa26c531928a6cd704e746d0e3ae3e031) )
754   ROM_LOAD( "gnn2a.8d",         0x1080000, 0x1080000, CRC(82d2cfb5) SHA1(4b5e713a55e74a7b32b1b9b5811892df2df86256) )
788   // protection issues preventing the last NAND block to be dumped
789   ROM_LOAD("gnn2a.8e", 0x0000000, 0x1080000, BAD_DUMP CRC(31b39221) SHA1(7fcb14aaa26c531928a6cd704e746d0e3ae3e031))
790   ROM_LOAD( "gnn2a.8d",         0x1080000, 0x1080000, BAD_DUMP CRC(82d2cfb5) SHA1(4b5e713a55e74a7b32b1b9b5811892df2df86256) )
755791ROM_END
756792
757793ROM_START( gunbalina )
r248620r248621
759795   ROM_FILL( 0x0000000, 0x400000, 0x55 )
760796
761797   ROM_REGION16_LE( 0x2100000, "user2", 0 ) /* main prg */
762   ROM_LOAD( "gnn1a.8e",         0x0000000, 0x1080000, CRC(981b03d4) SHA1(1c55458f1b2964afe2cf4e9d84548c0699808e9f) )
763   ROM_LOAD( "gnn1a.8d",         0x1080000, 0x1080000, CRC(6cd343e0) SHA1(dcec44abae1504025895f42fe574549e5010f7d5) )
798   // protection issues preventing the last NAND block to be dumped
799   ROM_LOAD( "gnn1a.8e",         0x0000000, 0x1080000, BAD_DUMP CRC(981b03d4) SHA1(1c55458f1b2964afe2cf4e9d84548c0699808e9f) )
800   ROM_LOAD( "gnn1a.8d",         0x1080000, 0x1080000, BAD_DUMP CRC(6cd343e0) SHA1(dcec44abae1504025895f42fe574549e5010f7d5) )
764801ROM_END
765802
766803ROM_START( chocovdr )
r248620r248621
806843ROM_END
807844
808845
809GAME( 2000, mrdrilr2,  0,        namcos10_memm, namcos10, namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Japan, DR21 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
810GAME( 2000, mrdrlr2a,  mrdrilr2, namcos10_memm, namcos10, namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Asia, DR22 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
811GAME( 2000, ptblank3,  0,        namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
812GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
813GAME( 2001, gjspace,   0,        namcos10_memn, namcos10, namcos10_state, gjspace,  ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
814GAME( 2001, mrdrilrg,  0,        namcos10_memn, namcos10, namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
815GAME( 2001, mrdrilrga, mrdrilrg, namcos10_memn, namcos10, namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G ALT (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
816GAME( 2001, knpuzzle,  0,        namcos10_memn, namcos10, namcos10_state, knpuzzle, ROT0, "Namco", "Kotoba no Puzzle Mojipittan (Japan, KPM1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
817GAME( 2002, chocovdr,  0,        namcos10_memn, namcos10, namcos10_state, chocovdr, ROT0, "Namco", "Uchuu Daisakusen: Chocovader Contactee (Japan, CVC1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
818GAME( 2002, startrgn,  0,        namcos10_memn, namcos10, namcos10_state, startrgn, ROT0, "Namco", "Star Trigon (Japan, STT1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
819GAME( 2002, panikuru,  0,        namcos10_memn, namcos10, namcos10_state, panikuru, ROT0, "Namco", "Panicuru Panekuru (Japan, PPA1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
820GAME( 2003, nflclsfb,  0,        namcos10_memn, namcos10, namcos10_state, nflclsfb, ROT0, "Namco", "NFL Classic Football (US, NCF3 Ver.A.)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
821GAME( 2003, gamshara,  0,        namcos10_memn, namcos10, namcos10_state, gamshara, ROT0, "Mitchell", "Gamshara (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
822GAME( 2003, konotako,  0,        namcos10_memn, namcos10, namcos10_state, konotako, ROT0, "Mitchell", "Kono Tako (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
846GAME( 2000, mrdrilr2,  0,        namcos10_memm, namcos10,     namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Japan, DR21 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
847GAME( 2000, mrdrlr2a,  mrdrilr2, namcos10_memm, namcos10,     namcos10_state, mrdrilr2, ROT0, "Namco", "Mr. Driller 2 (Asia, DR22 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
848GAME( 2000, ptblank3,  0,        namcos10_memn, namcos10,     namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
849GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10,     namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
850GAME( 2001, gjspace,   0,        namcos10_memn, namcos10,     namcos10_state, gjspace,  ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
851GAME( 2001, mrdrilrg,  0,        namcos10_memn, namcos10,     namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
852GAME( 2001, mrdrilrga, mrdrilrg, namcos10_memn, namcos10,     namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G ALT (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks
853GAME( 2001, knpuzzle,  0,        namcos10_memn, namcos10,     namcos10_state, knpuzzle, ROT0, "Namco", "Kotoba no Puzzle Mojipittan (Japan, KPM1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
854GAME( 2002, chocovdr,  0,        namcos10_memn, namcos10,     namcos10_state, chocovdr, ROT0, "Namco", "Uchuu Daisakusen: Chocovader Contactee (Japan, CVC1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
855GAME( 2002, startrgn,  0,        ns10_startrgn, namcos10,     namcos10_state, startrgn, ROT0, "Namco", "Star Trigon (Japan, STT1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
856GAME( 2002, panikuru,  0,        namcos10_memn, namcos10,     namcos10_state, panikuru, ROT0, "Namco", "Panicuru Panekuru (Japan, PPA1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
857GAME( 2003, nflclsfb,  0,        namcos10_memn, namcos10,     namcos10_state, nflclsfb, ROT0, "Namco", "NFL Classic Football (US, NCF3 Ver.A.)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
858GAME( 2003, gamshara,  0,        namcos10_memn, namcos10,     namcos10_state, gamshara, ROT0, "Mitchell", "Gamshara (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
859GAME( 2003, konotako,  0,        ns10_konotako, namcos10,     namcos10_state, konotako, ROT0, "Mitchell", "Kono Tako (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
trunk/src/mame/machine/ns10crypt.c
r0r248621
1// license:BSD-3
2// copyright-holders:Andreas Naive
3/****************************************************************************
4Namco System 10 decryption emulation
5
6(As of 2015-08, this file is still pretty much a WIP; changes are expected as
7out knowledge progress.)
8
9The decryption used by type-2 System10 PCBs (MEM-N) acts on 16-bit words and is
10designed to operate in a serial way: once the decryption is triggered, every
11word is XORed with a mask calculated over data taken from the previous words
12(both encrypted and decrypted). Type-1 PCBs seem to use a similar
13scheme, probably involving the word address too and a bitswap, but his relation
14to what is described here needs further investigation.
15
16In type-2 PCBs, the encrypted data is always contained in the first ROM of the
17game (8E), and it's always stored spanning an integer number of NAND blocks
18(the K9F2808U0B is organized in blocks of 16 KiB, each containing 32 pages of
190x200 bytes). The first part of the encrypted data is stored at about the end
20of the ROM, and apparently all the blocks in that area are processed in
21reverse order (first the one nearest the end, then the second nearest, etc);
22the second part goes inmediately after it from a logic perspective, but it's
23physically located at the area starting at 0x28000 in the ROM. Games, after
24some bootup code has been executed, will copy the encrypted content from
25the ROM to RAM, moment at which the decryption is triggered.
26
27Most games do a single decryption run, so the process is only initialized once;
28however, at least one game (gamshara) does write to the triggering registers
29more than once, effectively resetting the internal state of the decrypter
30several times. (gamshara do it every 5 NAND blocks).
31
32The calculation of the XOR masks seem to operate this way: most bits are
33calculated by using linear equations over GF(2) taking as input data the bits from
34previously processed words; however, one nonlinear calculation is performed
35per word processed, and that calculation can affect several bits from the
36mask (but, apparently, the same nonlinear terms affect all of them),
37though in most cases only one bit is involved. Till now, most of the linear
38relations seem to depend only on the previous 3 words, but there are some
39bits from those showing nonlinear behaviour which seem to use farther words;
40this is still being investigated, and the implementation is probable to
41change to reflect new findings.
42
43The bits affected by the nonlinear calculations are given below:
44chocovdr  -> #10
45gamshara  -> #2
46gjspace   -> a subset of {#3, #4, #5, #10, #11}, maybe all of them
47gunbalina -> #11
48knpuzzle  -> #1
49konotako  -> #15
50mrdrilrg  -> #0 & #4
51nflclsfb  -> #2
52panikuru  -> #2
53ptblank3  -> #11
54startrgn  -> #4
55
56
57TO-DO:
58* Research the nonlinear calculations in most of the games.
59* Determine how many previous words the hardware is really using, and change
60the implementation accordingly.
61
62Observing the linear equations, there is a keen difference between bits using
63just a bunch of previous bits, and others using much more bits from more words;
64simplyfing the latter ones could be handy, and probably closer to what the
65hardware is doing. Two possible simplyfications could be:
66A) The linear relations are creating lots of identities involving the bits
67from the sequence; they could be exploited to simplify the equations (but
68only when the implementation be stable, to avoid duplicating work).
69B) It's possible that some of those calculations are being stored and then
70used as another input bits for subsequent masks. Determining that (supposed)
71bits and factoring out them would simplify the expressions, in case they
72really exist.
73*****************************************************************************/
74
75#include "emu.h"
76#include "ns10crypt.h"
77
78const device_type KONOTAKO_DECRYPTER = &device_creator<konotako_decrypter_device>;
79const device_type STARTRGN_DECRYPTER = &device_creator<startrgn_decrypter_device>;
80
81ns10_decrypter_device::ns10_decrypter_device(device_type type, const ns10_crypto_logic &logic, const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
82   : device_t(mconfig, type, "Namco System 10 Decrypter", tag, owner, clock, "ns10_crypto", __FILE__)
83   , _active(false)
84   , _logic(logic)
85{
86}
87
88void ns10_decrypter_device::activate()
89{
90   init();
91   _active = true;
92}
93
94void ns10_decrypter_device::deactivate()
95{
96   _active = false;
97}
98
99bool ns10_decrypter_device::is_active()const
100{
101   return _active;
102}
103
104UINT16 ns10_decrypter_device::decrypt(UINT16 cipherword)
105{
106   UINT16 plainword = cipherword ^ _mask;
107
108   _previous_cipherwords <<= 16;
109   _previous_cipherwords  ^= cipherword;
110   _previous_plainwords  <<= 16;
111   _previous_plainwords   ^= plainword;
112
113   _mask = 0;
114   for (int j = 15; j >= 0; --j)
115   {
116      _mask <<= 1;
117      _mask ^= gf2_reduce(_logic.eMask[j] & _previous_cipherwords);
118      _mask ^= gf2_reduce(_logic.dMask[j] & _previous_plainwords);
119   }
120   _mask ^= _logic.xMask;
121   _mask ^= _logic.nonlinear_calculation(_previous_cipherwords, _previous_plainwords);
122
123   return plainword;
124}
125
126void ns10_decrypter_device::device_start()
127{
128   int reduction;
129
130   // create a look-up table of GF2 reductions of 16-bits words
131   for (int i = 0; i < 0x10000; ++i)
132   {
133      reduction = 0;
134      for (int j = 0; j < 16; ++j)
135         reduction ^= BIT(i, j);
136
137      _gf2Reduction[i] = reduction;
138   }
139}
140
141void ns10_decrypter_device::init()
142{
143   _previous_cipherwords = 0;
144   _previous_plainwords  = 0;
145   _mask                 = 0;
146}
147
148int ns10_decrypter_device::gf2_reduce(UINT64 num)
149{
150   return
151      _gf2Reduction[num & 0xffff]         ^
152      _gf2Reduction[(num >> 16) & 0xffff] ^
153      _gf2Reduction[(num >> 32) & 0xffff] ^
154      _gf2Reduction[num >> 48];
155}
156
157
158// game-specific logic
159
160static UINT16 konotako_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
161{
162   UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
163   return ((previous_masks >> 7) & (previous_masks >> 15) & 1) << 15;
164}
165
166static const ns10_decrypter_device::ns10_crypto_logic konotako_crypto_logic = {
167   {
168      0x000000000000004cull, 0x00000000d39e3d3dull, 0x0000000000001110ull, 0x0000000000002200ull,
169      0x000000003680c008ull, 0x0000000000000281ull, 0x0000000000005002ull, 0x00002a7371895a47ull,
170      0x0000000000000003ull, 0x00002a7371897a4eull, 0x00002a73aea17a41ull, 0x00002a73fd895a4full,
171      0x000000005328200aull, 0x0000000000000010ull, 0x0000000000000040ull, 0x0000000000000200ull,
172   }, {
173      0x000000000000008cull, 0x0000000053003d25ull, 0x0000000000001120ull, 0x0000000000002200ull,
174      0x0000000037004008ull, 0x0000000000000282ull, 0x0000000000006002ull, 0x0000060035005a47ull,
175      0x0000000000000003ull, 0x0000060035001a4eull, 0x0000060025007a41ull, 0x00000600b5005a2full,
176      0x000000009000200bull, 0x0000000000000310ull, 0x0000000000001840ull, 0x0000000000000400ull,
177   },
178   0x0748,
179   konotako_nonlinear_calc
180};
181
182static UINT16 startrgn_nonlinear_calc(UINT64 previous_cipherwords, UINT64 previous_plainwords)
183{
184   UINT64 previous_masks = previous_cipherwords ^ previous_plainwords;
185   return ((previous_masks >> 12) & (previous_masks >> 14) & 1) << 4;
186}
187
188static const ns10_decrypter_device::ns10_crypto_logic startrgn_crypto_logic = {
189   {
190      0x00003e4bfe92c6a9ull, 0x000000000000010cull, 0x00003e4b7bd6c4aaull, 0x0000b1a904b8fab8ull,
191      0x0000000000000080ull, 0x0000000000008c00ull, 0x0000b1a9b2f0b4cdull, 0x000000006c100828ull,
192      0x000000006c100838ull, 0x0000b1a9d3913fcdull, 0x000000006161aa00ull, 0x0000000000006040ull,
193      0x0000000000000420ull, 0x0000000000001801ull, 0x00003e4b7bd6deabull, 0x0000000000000105ull,
194   }, {
195      0x000012021f00c6a8ull, 0x0000000000000008ull, 0x000012020b1046aaull, 0x000012001502fea8ull,
196      0x0000000000002000ull, 0x0000000000008800ull, 0x000012001e02b4cdull, 0x000000002c0008aaull,
197      0x000000002c00083aull, 0x000012003f027ecdull, 0x0000000021008a00ull, 0x0000000000002040ull,
198      0x0000000000000428ull, 0x0000000000001001ull, 0x000012020b10ceabull, 0x0000000000000144ull,
199   },
200   0x8c46,
201   startrgn_nonlinear_calc
202};
203
204// game-specific devices
205
206konotako_decrypter_device::konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
207   : ns10_decrypter_device(KONOTAKO_DECRYPTER, konotako_crypto_logic, mconfig, tag, owner, clock)
208{
209}
210
211startrgn_decrypter_device::startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
212   : ns10_decrypter_device(STARTRGN_DECRYPTER, startrgn_crypto_logic, mconfig, tag, owner, clock)
213{
214}
trunk/src/mame/machine/ns10crypt.h
r0r248621
1// license:BSD-3
2// copyright-holders:Andreas Naive
3
4#ifndef _NS10CRYPT_H_
5#define _NS10CRYPT_H_
6
7class ns10_decrypter_device : public device_t
8{
9public:
10   // this encodes the decryption logic, which varies per game
11   // and is probably hard-coded into the CPLD
12   struct ns10_crypto_logic
13   {
14      UINT64 eMask[16];
15      UINT64 dMask[16];
16      UINT16 xMask;
17      UINT16(*nonlinear_calculation)(UINT64, UINT64);  // preliminary encoding; need research
18   };
19
20   void activate();
21   void deactivate();
22   bool is_active()const;
23
24   UINT16 decrypt(UINT16 cipherword);
25
26protected:
27   ns10_decrypter_device(
28      device_type type, const ns10_decrypter_device::ns10_crypto_logic &logic,
29      const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
30
31private:
32   UINT16 _mask;
33   UINT64 _previous_cipherwords;
34   UINT64 _previous_plainwords;
35   bool _active;
36   const ns10_crypto_logic& _logic;
37   int _gf2Reduction[0x10000];
38
39   void device_start();
40   void init();
41   int gf2_reduce(UINT64 num);
42};
43
44// game-specific devices
45
46class konotako_decrypter_device : public ns10_decrypter_device
47{
48public:
49   konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
50};
51
52class startrgn_decrypter_device : public ns10_decrypter_device
53{
54public:
55   startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
56};
57
58
59extern const device_type KONOTAKO_DECRYPTER;
60extern const device_type STARTRGN_DECRYPTER;
61
62#endif


Previous 199869 Revisions Next


© 1997-2024 The MAME Team