trunk/src/mame/drivers/namcos10.c
| r248620 | r248621 | |
| 269 | 269 | #include "emu.h" |
| 270 | 270 | #include "cpu/psx/psx.h" |
| 271 | 271 | #include "video/psx.h" |
| 272 | #include "machine/ns10crypt.h" |
| 272 | 273 | |
| 273 | 274 | class namcos10_state : public driver_device |
| 274 | 275 | { |
| r248620 | r248621 | |
| 283 | 284 | DECLARE_WRITE16_MEMBER(bank_w); |
| 284 | 285 | |
| 285 | 286 | // memn variant interface |
| 286 | | DECLARE_READ16_MEMBER (nand_status_r); |
| 287 | DECLARE_WRITE16_MEMBER(crypto_switch_w); |
| 288 | DECLARE_READ16_MEMBER(nand_status_r); |
| 287 | 289 | DECLARE_WRITE8_MEMBER(nand_address1_w); |
| 288 | 290 | DECLARE_WRITE8_MEMBER(nand_address2_w); |
| 289 | 291 | DECLARE_WRITE8_MEMBER(nand_address3_w); |
| r248620 | r248621 | |
| 301 | 303 | UINT32 bank_base; |
| 302 | 304 | UINT32 nand_address; |
| 303 | 305 | UINT16 block[0x1ff]; |
| 306 | ns10_decrypter_device* decrypter; |
| 304 | 307 | |
| 305 | 308 | UINT16 nand_read( UINT32 address ); |
| 306 | 309 | UINT16 nand_read2( UINT32 address ); |
| r248620 | r248621 | |
| 401 | 404 | // Block access to the nand. Something strange is going on with the |
| 402 | 405 | // status port. Interaction with the decryption is unclear at best. |
| 403 | 406 | |
| 407 | WRITE16_MEMBER(namcos10_state::crypto_switch_w) |
| 408 | { |
| 409 | if (BIT(data, 15) != 0) |
| 410 | decrypter->activate(); |
| 411 | else |
| 412 | decrypter->deactivate(); |
| 413 | } |
| 414 | |
| 404 | 415 | READ16_MEMBER(namcos10_state::nand_status_r ) |
| 405 | 416 | { |
| 406 | 417 | return 0; |
| r248620 | r248621 | |
| 451 | 462 | /* printf( "data<-%08x (%08x)\n", data, nand_address ); */ |
| 452 | 463 | nand_address++; |
| 453 | 464 | |
| 454 | | return data; |
| 465 | if (decrypter->is_active()) |
| 466 | return decrypter->decrypt(data); |
| 467 | else |
| 468 | return data; |
| 455 | 469 | } |
| 456 | 470 | |
| 457 | 471 | void namcos10_state::nand_copy( UINT32 *dst, UINT32 address, int len ) |
| r248620 | r248621 | |
| 475 | 489 | } |
| 476 | 490 | |
| 477 | 491 | static 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) |
| 480 | 493 | AM_RANGE(0x1f400000, 0x1f400003) AM_READ16(nand_status_r, 0x0000ffff) |
| 481 | 494 | AM_RANGE(0x1f410000, 0x1f410003) AM_WRITE8(nand_address1_w, 0x000000ff) |
| 482 | 495 | AM_RANGE(0x1f420000, 0x1f420003) AM_WRITE8(nand_address2_w, 0x000000ff) |
| r248620 | r248621 | |
| 492 | 505 | { |
| 493 | 506 | UINT8 *BIOS = (UINT8 *)memregion( "maincpu:rom" )->base(); |
| 494 | 507 | nand_base = (UINT8 *)memregion( "user2" )->base(); |
| 508 | decrypter = static_cast<ns10_decrypter_device*>(machine().root_device().subdevice("decrypter")); |
| 495 | 509 | |
| 496 | 510 | nand_copy( (UINT32 *)( BIOS + 0x0000000 ), 0x08000, 0x001c000 ); |
| 497 | 511 | nand_copy( (UINT32 *)( BIOS + 0x0020000 ), 0x24000, 0x03e0000 ); |
| 498 | 512 | } |
| 499 | 513 | |
| 500 | | static 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, |
| 514 | static 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, |
| 501 | 515 | int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0 ) |
| 502 | 516 | { |
| 503 | 517 | memory_region *region = machine.root_device().memregion( regionName ); |
| 504 | 518 | UINT16 *BIOS = (UINT16 *)( region->base() + start ); |
| 505 | | int len = (region->bytes()-start)/2; |
| 519 | int len = (end - start) / 2; |
| 506 | 520 | |
| 507 | 521 | for( int i = 0; i < len; i++ ) |
| 508 | 522 | { |
| r248620 | r248621 | |
| 513 | 527 | |
| 514 | 528 | DRIVER_INIT_MEMBER(namcos10_state,mrdrilr2) |
| 515 | 529 | { |
| 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); |
| 517 | 532 | } |
| 518 | 533 | |
| 519 | 534 | DRIVER_INIT_MEMBER(namcos10_state,gjspace) |
| 520 | 535 | { |
| 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); |
| 522 | 538 | memn_driver_init(); |
| 523 | 539 | } |
| 524 | 540 | |
| 525 | 541 | DRIVER_INIT_MEMBER(namcos10_state,mrdrilrg) |
| 526 | 542 | { |
| 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); |
| 528 | 545 | memn_driver_init(); |
| 529 | 546 | } |
| 530 | 547 | |
| 531 | 548 | DRIVER_INIT_MEMBER(namcos10_state,knpuzzle) |
| 532 | 549 | { |
| 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); |
| 534 | 552 | memn_driver_init(); |
| 535 | 553 | } |
| 536 | 554 | |
| 537 | 555 | DRIVER_INIT_MEMBER(namcos10_state,startrgn) |
| 538 | 556 | { |
| 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); |
| 540 | 559 | memn_driver_init(); |
| 541 | 560 | } |
| 542 | 561 | |
| 543 | 562 | DRIVER_INIT_MEMBER(namcos10_state,gamshara) |
| 544 | 563 | { |
| 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); |
| 546 | 566 | memn_driver_init(); |
| 547 | 567 | } |
| 548 | 568 | |
| 549 | 569 | DRIVER_INIT_MEMBER(namcos10_state,gunbalna) |
| 550 | 570 | { |
| 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); |
| 552 | 573 | memn_driver_init(); |
| 553 | 574 | } |
| 554 | 575 | |
| 555 | 576 | DRIVER_INIT_MEMBER(namcos10_state,chocovdr) |
| 556 | 577 | { |
| 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); |
| 558 | 580 | memn_driver_init(); |
| 559 | 581 | } |
| 560 | 582 | |
| 561 | 583 | DRIVER_INIT_MEMBER(namcos10_state,panikuru) |
| 562 | 584 | { |
| 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); |
| 564 | 587 | memn_driver_init(); |
| 565 | 588 | } |
| 566 | 589 | |
| 567 | 590 | DRIVER_INIT_MEMBER(namcos10_state,nflclsfb) |
| 568 | 591 | { |
| 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); |
| 570 | 594 | memn_driver_init(); |
| 571 | 595 | } |
| 572 | 596 | |
| 573 | 597 | DRIVER_INIT_MEMBER(namcos10_state,konotako) |
| 574 | 598 | { |
| 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); |
| 576 | 601 | memn_driver_init(); |
| 577 | 602 | } |
| 578 | 603 | |
| r248620 | r248621 | |
| 615 | 640 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 616 | 641 | MACHINE_CONFIG_END |
| 617 | 642 | |
| 643 | static MACHINE_CONFIG_DERIVED(ns10_konotako, namcos10_memn) |
| 644 | /* decrypter device (CPLD in hardware?) */ |
| 645 | MCFG_DEVICE_ADD("decrypter", KONOTAKO_DECRYPTER, 0) |
| 646 | MACHINE_CONFIG_END |
| 647 | |
| 648 | static MACHINE_CONFIG_DERIVED(ns10_startrgn, namcos10_memn) |
| 649 | /* decrypter device (CPLD in hardware?) */ |
| 650 | MCFG_DEVICE_ADD("decrypter", STARTRGN_DECRYPTER, 0) |
| 651 | MACHINE_CONFIG_END |
| 652 | |
| 618 | 653 | static INPUT_PORTS_START( namcos10 ) |
| 619 | 654 | /* IN 0 */ |
| 620 | 655 | PORT_START("SYSTEM") |
| r248620 | r248621 | |
| 750 | 785 | ROM_FILL( 0x0000000, 0x400000, 0x55 ) |
| 751 | 786 | |
| 752 | 787 | 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) ) |
| 755 | 791 | ROM_END |
| 756 | 792 | |
| 757 | 793 | ROM_START( gunbalina ) |
| r248620 | r248621 | |
| 759 | 795 | ROM_FILL( 0x0000000, 0x400000, 0x55 ) |
| 760 | 796 | |
| 761 | 797 | 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) ) |
| 764 | 801 | ROM_END |
| 765 | 802 | |
| 766 | 803 | ROM_START( chocovdr ) |
| r248620 | r248621 | |
| 806 | 843 | ROM_END |
| 807 | 844 | |
| 808 | 845 | |
| 809 | | GAME( 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 |
| 810 | | GAME( 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 |
| 811 | | GAME( 2000, ptblank3, 0, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 812 | | GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 813 | | GAME( 2001, gjspace, 0, namcos10_memn, namcos10, namcos10_state, gjspace, ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 814 | | GAME( 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 |
| 815 | | GAME( 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 |
| 816 | | GAME( 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 ) |
| 817 | | GAME( 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 ) |
| 818 | | GAME( 2002, startrgn, 0, namcos10_memn, namcos10, namcos10_state, startrgn, ROT0, "Namco", "Star Trigon (Japan, STT1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 819 | | GAME( 2002, panikuru, 0, namcos10_memn, namcos10, namcos10_state, panikuru, ROT0, "Namco", "Panicuru Panekuru (Japan, PPA1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 820 | | GAME( 2003, nflclsfb, 0, namcos10_memn, namcos10, namcos10_state, nflclsfb, ROT0, "Namco", "NFL Classic Football (US, NCF3 Ver.A.)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 821 | | GAME( 2003, gamshara, 0, namcos10_memn, namcos10, namcos10_state, gamshara, ROT0, "Mitchell", "Gamshara (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 822 | | GAME( 2003, konotako, 0, namcos10_memn, namcos10, namcos10_state, konotako, ROT0, "Mitchell", "Kono Tako (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 846 | GAME( 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 |
| 847 | GAME( 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 |
| 848 | GAME( 2000, ptblank3, 0, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 849 | GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 850 | GAME( 2001, gjspace, 0, namcos10_memn, namcos10, namcos10_state, gjspace, ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 851 | GAME( 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 |
| 852 | GAME( 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 |
| 853 | GAME( 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 ) |
| 854 | GAME( 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 ) |
| 855 | GAME( 2002, startrgn, 0, ns10_startrgn, namcos10, namcos10_state, startrgn, ROT0, "Namco", "Star Trigon (Japan, STT1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) |
| 856 | GAME( 2002, panikuru, 0, namcos10_memn, namcos10, namcos10_state, panikuru, ROT0, "Namco", "Panicuru Panekuru (Japan, PPA1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 857 | GAME( 2003, nflclsfb, 0, namcos10_memn, namcos10, namcos10_state, nflclsfb, ROT0, "Namco", "NFL Classic Football (US, NCF3 Ver.A.)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 858 | GAME( 2003, gamshara, 0, namcos10_memn, namcos10, namcos10_state, gamshara, ROT0, "Mitchell", "Gamshara (10021 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) |
| 859 | GAME( 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
| r0 | r248621 | |
| 1 | // license:BSD-3 |
| 2 | // copyright-holders:Andreas Naive |
| 3 | /**************************************************************************** |
| 4 | Namco System 10 decryption emulation |
| 5 | |
| 6 | (As of 2015-08, this file is still pretty much a WIP; changes are expected as |
| 7 | out knowledge progress.) |
| 8 | |
| 9 | The decryption used by type-2 System10 PCBs (MEM-N) acts on 16-bit words and is |
| 10 | designed to operate in a serial way: once the decryption is triggered, every |
| 11 | word 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 |
| 13 | scheme, probably involving the word address too and a bitswap, but his relation |
| 14 | to what is described here needs further investigation. |
| 15 | |
| 16 | In type-2 PCBs, the encrypted data is always contained in the first ROM of the |
| 17 | game (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 |
| 19 | 0x200 bytes). The first part of the encrypted data is stored at about the end |
| 20 | of the ROM, and apparently all the blocks in that area are processed in |
| 21 | reverse order (first the one nearest the end, then the second nearest, etc); |
| 22 | the second part goes inmediately after it from a logic perspective, but it's |
| 23 | physically located at the area starting at 0x28000 in the ROM. Games, after |
| 24 | some bootup code has been executed, will copy the encrypted content from |
| 25 | the ROM to RAM, moment at which the decryption is triggered. |
| 26 | |
| 27 | Most games do a single decryption run, so the process is only initialized once; |
| 28 | however, at least one game (gamshara) does write to the triggering registers |
| 29 | more than once, effectively resetting the internal state of the decrypter |
| 30 | several times. (gamshara do it every 5 NAND blocks). |
| 31 | |
| 32 | The calculation of the XOR masks seem to operate this way: most bits are |
| 33 | calculated by using linear equations over GF(2) taking as input data the bits from |
| 34 | previously processed words; however, one nonlinear calculation is performed |
| 35 | per word processed, and that calculation can affect several bits from the |
| 36 | mask (but, apparently, the same nonlinear terms affect all of them), |
| 37 | though in most cases only one bit is involved. Till now, most of the linear |
| 38 | relations seem to depend only on the previous 3 words, but there are some |
| 39 | bits from those showing nonlinear behaviour which seem to use farther words; |
| 40 | this is still being investigated, and the implementation is probable to |
| 41 | change to reflect new findings. |
| 42 | |
| 43 | The bits affected by the nonlinear calculations are given below: |
| 44 | chocovdr -> #10 |
| 45 | gamshara -> #2 |
| 46 | gjspace -> a subset of {#3, #4, #5, #10, #11}, maybe all of them |
| 47 | gunbalina -> #11 |
| 48 | knpuzzle -> #1 |
| 49 | konotako -> #15 |
| 50 | mrdrilrg -> #0 & #4 |
| 51 | nflclsfb -> #2 |
| 52 | panikuru -> #2 |
| 53 | ptblank3 -> #11 |
| 54 | startrgn -> #4 |
| 55 | |
| 56 | |
| 57 | TO-DO: |
| 58 | * Research the nonlinear calculations in most of the games. |
| 59 | * Determine how many previous words the hardware is really using, and change |
| 60 | the implementation accordingly. |
| 61 | |
| 62 | Observing the linear equations, there is a keen difference between bits using |
| 63 | just a bunch of previous bits, and others using much more bits from more words; |
| 64 | simplyfing the latter ones could be handy, and probably closer to what the |
| 65 | hardware is doing. Two possible simplyfications could be: |
| 66 | A) The linear relations are creating lots of identities involving the bits |
| 67 | from the sequence; they could be exploited to simplify the equations (but |
| 68 | only when the implementation be stable, to avoid duplicating work). |
| 69 | B) It's possible that some of those calculations are being stored and then |
| 70 | used as another input bits for subsequent masks. Determining that (supposed) |
| 71 | bits and factoring out them would simplify the expressions, in case they |
| 72 | really exist. |
| 73 | *****************************************************************************/ |
| 74 | |
| 75 | #include "emu.h" |
| 76 | #include "ns10crypt.h" |
| 77 | |
| 78 | const device_type KONOTAKO_DECRYPTER = &device_creator<konotako_decrypter_device>; |
| 79 | const device_type STARTRGN_DECRYPTER = &device_creator<startrgn_decrypter_device>; |
| 80 | |
| 81 | ns10_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 | |
| 88 | void ns10_decrypter_device::activate() |
| 89 | { |
| 90 | init(); |
| 91 | _active = true; |
| 92 | } |
| 93 | |
| 94 | void ns10_decrypter_device::deactivate() |
| 95 | { |
| 96 | _active = false; |
| 97 | } |
| 98 | |
| 99 | bool ns10_decrypter_device::is_active()const |
| 100 | { |
| 101 | return _active; |
| 102 | } |
| 103 | |
| 104 | UINT16 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 | |
| 126 | void 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 | |
| 141 | void ns10_decrypter_device::init() |
| 142 | { |
| 143 | _previous_cipherwords = 0; |
| 144 | _previous_plainwords = 0; |
| 145 | _mask = 0; |
| 146 | } |
| 147 | |
| 148 | int 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 | |
| 160 | static 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 | |
| 166 | static 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 | |
| 182 | static 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 | |
| 188 | static 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 | |
| 206 | konotako_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 | |
| 211 | startrgn_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 | } |