Previous 199869 Revisions Next

r23579 Sunday 9th June, 2013 at 23:28:29 UTC by David Haywood
Improved Dragon World II protection routines [iq_132]
[src/mame/drivers]pgm.c
[src/mame/includes]pgm.h
[src/mame/machine]pgmprot5.c

trunk/src/mame/drivers/pgm.c
r23578r23579
39213921GAME( 1997, orlegend111c, orlegend,  pgm_asic3,     orlegend, pgm_asic3_state, orlegend,   ROT0,   "IGS", "Oriental Legend / Xi You Shi E Zhuan (ver. 111, Chinese Board)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) // V0001 no date!          - runs as HongKong, China, China
39223922GAME( 1997, orlegend105k, orlegend,  pgm_asic3,     orld105k, pgm_asic3_state, orlegend,   ROT0,   "IGS", "Oriental Legend / Xi You Shi E Zhuan (ver. 105, Korean Board)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )  // V0000 no date!          - runs as Korea
39233923
3924GAME( 1997, drgw2,        pgm,       pgm,     pgm, pgm_state,      drgw2,      ROT0,   "IGS", "Dragon World II (ver. 110X, Export)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3925GAME( 1997, dw2v100x,     drgw2,     pgm,     pgm, pgm_state,      dw2v100x,   ROT0,   "IGS", "Dragon World II (ver. 100X, Export)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3926GAME( 1997, drgw2j,       drgw2,     pgm,     pgm, pgm_state,      drgw2j,     ROT0,   "IGS", "Chuugokuryuu II (ver. 100J, Japan)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3927GAME( 1997, drgw2c,       drgw2,     pgm,     pgm, pgm_state,      drgw2c,     ROT0,   "IGS", "Zhong Guo Long II (ver. 100C, China)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3924GAME( 1997, drgw2,        pgm,       pgm_012_025_drgw2,     pgm, pgm_012_025_state,      drgw2,      ROT0,   "IGS", "Dragon World II (ver. 110X, Export)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3925GAME( 1997, dw2v100x,     drgw2,     pgm_012_025_drgw2,     pgm, pgm_012_025_state,      dw2v100x,   ROT0,   "IGS", "Dragon World II (ver. 100X, Export)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3926GAME( 1997, drgw2j,       drgw2,     pgm_012_025_drgw2,     pgm, pgm_012_025_state,      drgw2j,     ROT0,   "IGS", "Chuugokuryuu II (ver. 100J, Japan)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
3927GAME( 1997, drgw2c,       drgw2,     pgm_012_025_drgw2,     pgm, pgm_012_025_state,      drgw2c,     ROT0,   "IGS", "Zhong Guo Long II (ver. 100C, China)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
39283928
3929GAME( 1998, killbld,      pgm,       pgm_022_025_kb, killbld, pgm_022_025_state,  killbld,    ROT0,   "IGS", "The Killing Blade (ver. 109, Chinese Board)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) /* region provided by protection device */
3930GAME( 1998, killbld104,   killbld,   pgm_022_025_kb, killbld, pgm_022_025_state,  killbld,    ROT0,   "IGS", "The Killing Blade (ver. 104)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) /* region provided by protection device */
3931
39293932// region provided by internal ARM rom
39303933GAME( 1999, photoy2k,     pgm,       pgm_arm_type1,     photoy2k, pgm_arm_type1_state, photoy2k,   ROT0,   "IGS", "Photo Y2K (ver. 105)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) /* region provided by protection device */
39313934GAME( 1999, photoy2k104,  photoy2k,  pgm_arm_type1,     photoy2k, pgm_arm_type1_state, photoy2k,   ROT0,   "IGS", "Photo Y2K (ver. 104)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) /* region provided by protection device */
r23578r23579
39773980GAME( 2001, ddp2100c,     ddp2,      pgm_arm_type2,    pgm, pgm_arm_type2_state,     ddp2,       ROT270, "IGS", "DoDonPachi II - Bee Storm (China, ver. 100)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
39783981
39793982
3980
3981
39823983// japan region only?
39833984GAME( 2001, dw2001,       pgm,       pgm_arm_type2,     dw2001, pgm_arm_type2_state,   dw2001,    ROT0,   "IGS", "Dragon World 2001 (V100?, Japan)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) // 02/21/01 16:05:16
39843985
r23578r23579
39933994GAME( 2002, dmnfrntpcb,   dmnfrnt,   pgm_arm_type3,     pgm, pgm_arm_type3_state,    dmnfrnt,    ROT0,   "IGS", "Demon Front (68k label V107KR, ROM M107KR 11/03/03) (ARM label V106KR, ROM 10/16/03 S106KR) (JAMMA PCB)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) // works but reports version mismatch (wants internal rom version and region to match external?)
39943995
39953996
3996
39973997/* these don't use an External ARM rom, and don't have any weak internal functions which would allow the internal ROM to be read out */
39983998GAME( 2002, ddpdoj,       0,         pgm_arm_type1_cave,    pgm, pgm_arm_type1_state,     ddp3,      ROT270, "Cave", "DoDonPachi Dai-Ou-Jou V101 (2002.04.05.Master Ver)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) // is there a v101 without the . after 05?
39993999GAME( 2002, ddpdoja,    ddpdoj,      pgm_arm_type1_cave,    pgm, pgm_arm_type1_state,     ddp3,      ROT270, "Cave", "DoDonPachi Dai-Ou-Jou V100 (2002.04.05.Master Ver)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
r23578r23579
40124012   Partially Working, playable, but some imperfections
40134013   -----------------------------------------------------------------------------------------------------------------------*/
40144014
4015   // it's playable, but the region check is still patched (different IGS025 chips return different sequences so that the game can determine the region)
4016GAME( 1998, killbld,      pgm,       pgm_022_025_kb, killbld, pgm_022_025_state,  killbld,    ROT0,   "IGS", "The Killing Blade (ver. 109, Chinese Board)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
4017GAME( 1998, killbld104,   killbld,   pgm_022_025_kb, killbld, pgm_022_025_state,  killbld,    ROT0,   "IGS", "The Killing Blade (ver. 104)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
4018
40194015GAME( 1998, olds,         pgm,       pgm_028_025_ol,    olds, pgm_028_025_state,     olds,       ROT0,   "IGS", "Oriental Legend Special / Xi You Shi E Zhuan Super (ver. 101, Korean Board)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
40204016GAME( 1998, olds100,      olds,      pgm_028_025_ol,    olds, pgm_028_025_state,     olds,       ROT0,   "IGS", "Oriental Legend Special / Xi You Shi E Zhuan Super (ver. 100, set 1)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
40214017GAME( 1998, olds100a,     olds,      pgm_028_025_ol,    olds, pgm_028_025_state,     olds,       ROT0,   "IGS", "Oriental Legend Special / Xi You Shi E Zhuan Super (ver. 100, set 2)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) // crashes on some bosses, high score table etc.
4022GAME( 1998, olds103t,     olds,      pgm,               pgm,  pgm_state,             pgm,        ROT0,   "IGS", "Oriental Legend Special / Xi You Shi E Zhuan Super (ver. 103, China, Tencent) (unprotected)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) // why is this version not protected? internal leak? bootleg?
4018// this version was specially made for a Chinese online gaming company. While it may not be entirely suitable for
4019// mame, it can give some insight into how protection should work.
4020GAME( 1998, olds103t,     olds,      pgm,               pgm,  pgm_state,             pgm,        ROT0,   "IGS", "Oriental Legend Special / Xi You Shi E Zhuan Super (ver. 103, China, Tencent) (unprotected)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
40234021
4024
4025
40264022GAME( 1999, kov,          pgm,       pgm_arm_type1_sim,     sango, pgm_arm_type1_state,    kov,        ROT0,   "IGS", "Knights of Valour / Sangoku Senki (ver. 117)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_SUPPORTS_SAVE ) /* need internal rom of IGS027A */                 // V0008 04/27/99 10:33:33
40274023GAME( 1999, kov115,       kov,       pgm_arm_type1_sim,     sango, pgm_arm_type1_state,    kov,        ROT0,   "IGS", "Knights of Valour / Sangoku Senki (ver. 115)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_SUPPORTS_SAVE ) /* need internal rom of IGS027A */                 // V0006 02/22/99 11:53:18
40284024GAME( 1999, kov100,       kov,       pgm_arm_type1_sim,     sango, pgm_arm_type1_state,    kov,        ROT0,   "IGS", "Knights of Valour / Sangoku Senki (ver. 100, Japanese Board)", GAME_IMPERFECT_SOUND | GAME_UNEMULATED_PROTECTION | GAME_SUPPORTS_SAVE ) /* need internal rom of IGS027A */ // V0002 01/31/99 01:54:16
trunk/src/mame/machine/pgmprot5.c
r23578r23579
1313 IGS025 is some kind of state machine / logic device which the game
1414 uses for various security checks bitswap checks.
1515
16 To do:
17   How is the additional xor data is calculated?
18   Should the "hold" value be reset if the power is turned off? How?
19   Patches are actually overlays or just hacks?
20
2116 ***********************************************************************/
2217
2318#include "emu.h"
2419#include "includes/pgm.h"
2520
26
2721/* Dragon World 2 */
2822
29READ16_MEMBER(pgm_state::dw2_d80000_r )
23void pgm_012_025_state::pgm_drgw2_decrypt()
3024{
31   UINT16 ret;
32/*  UINT16 test;
25   int i;
26   UINT16 *src = (UINT16 *) (memregion("maincpu")->base()+0x100000);
3327
34    switch (dw2_asic_reg[0])
35    {
36        case 0x05: // Read to $80eec0
37        case 0x13: // Read to $80eeb8
38        case 0x1f: // Read to $80eeb8
39        case 0x40: // Read to $80eeb8, increase counters
40        case 0xf4: // Read to $80eeb8
41        case 0xf6: // Read to $80eeb8
42        case 0xf8: // Read to $80eeb8
43        break;
28   int rom_size = 0x80000;
4429
45        default:
46            logerror("%06x: warning, reading with igs003_reg = %02x\n", space.device().safe_pc(), dw2_asic_reg[0]);
47    }
30   for (i = 0; i < rom_size / 2; i++)
31   {
32      UINT16 x = src[i];
4833
49    test = BITSWAP16(m_mainram[protection_address], 14,11,8,6,4,3,1,0, 5,2,9,7,10,13,12,15) & 0xff; // original hack
50*/
51   // This bitswap seems to also be common to a few IGS protection devices (igs011.c, Oriental Legend)
52   ret = BITSWAP16(dw2_asic_hold, 14,11,8,6,4,3,1,0, 5,2,9,7,10,13,12,15) & 0xff;
53/*
54    if ((ret != test) || (dw2_asic_hold != m_mainram[protection_address])) {
55        logerror ("Protection calculation error: SIMRET: %2.2x, HACKRET: %2.2x, SIMHOLD: %4.4x, REALHOLD: %4.4x\n", ret, test, dw2_asic_hold, m_mainram[protection_address]);
56    }
57*/
58   return ret;
34      if (((i & 0x20890) == 0) || ((i & 0x20000) == 0x20000 && (i & 0x01500) != 0x01400))
35         x ^= 0x0002;
36
37      if (((i & 0x20400) == 0 && (i & 0x02010) != 0x02010) || ((i & 0x20000) == 0x20000 && (i & 0x00148) != 0x00140))
38         x ^= 0x0400;
39
40      src[i] = x;
41   }
5942}
6043
61WRITE16_MEMBER(pgm_state::dw2_d80000_w )
44// All tables all xored by 'warning' information at $1354ee (drgw2)
45static const UINT8 drgw2_source_data[0x08][0xec] =
6246{
63   COMBINE_DATA(&dw2_asic_reg[offset]);
47   { 0, },   // Region 0, not used
48   {    // Region 1, $13A886
49      0x67, 0x51, 0xF3, 0x19, 0xA0, 0x11, 0xB1, 0x11, 0xB0, 0xEE, 0xE3, 0xF6, 0xBE, 0x81, 0x35, 0xE3,
50      0xFB, 0xE6, 0xEF, 0xDF, 0x61, 0x01, 0xFA, 0x22, 0x5D, 0x43, 0x01, 0xA5, 0x3B, 0x17, 0xD4, 0x74,
51      0xF0, 0xF4, 0xF3, 0x43, 0xB5, 0x19, 0x04, 0xD5, 0x84, 0xCE, 0x87, 0xFE, 0x35, 0x3E, 0xC4, 0x3C,
52      0xC7, 0x85, 0x2A, 0x33, 0x00, 0x86, 0xD0, 0x4D, 0x65, 0x4B, 0xF9, 0xE9, 0xC0, 0xBA, 0xAA, 0x77,
53      0x9E, 0x66, 0xF6, 0x0F, 0x4F, 0x3A, 0xB6, 0xF1, 0x64, 0x9A, 0xE9, 0x25, 0x1A, 0x5F, 0x22, 0xA3,
54      0xA2, 0xBF, 0x4B, 0x77, 0x3F, 0x34, 0xC9, 0x6E, 0xDB, 0x12, 0x5C, 0x33, 0xA5, 0x8B, 0x6C, 0xB1,
55      0x74, 0xC8, 0x40, 0x4E, 0x2F, 0xE7, 0x46, 0xAE, 0x99, 0xFC, 0xB0, 0x55, 0x54, 0xDF, 0xA7, 0xA1,
56      0x0F, 0x5E, 0x49, 0xCF, 0x56, 0x3C, 0x90, 0x2B, 0xAC, 0x65, 0x6E, 0xDB, 0x58, 0x3E, 0xC9, 0x00,
57      0xAE, 0x53, 0x4D, 0x92, 0xFA, 0x40, 0xB2, 0x6B, 0x65, 0x4B, 0x90, 0x8A, 0x0C, 0xE2, 0xA5, 0x9A,
58      0xD0, 0x20, 0x29, 0x55, 0xA4, 0x44, 0xAC, 0x51, 0x87, 0x54, 0x53, 0x34, 0x24, 0x4B, 0x81, 0x67,
59      0x34, 0x4C, 0x5F, 0x31, 0x4E, 0xF2, 0xF1, 0x19, 0x18, 0x1C, 0x34, 0x38, 0xE1, 0x81, 0x17, 0xCF,
60      0x24, 0xB9, 0x9A, 0xCB, 0x34, 0x51, 0x50, 0x59, 0x44, 0xB1, 0x0B, 0x50, 0x95, 0x6C, 0x48, 0x7E,
61      0x14, 0xA4, 0xC6, 0xD9, 0xD3, 0xA5, 0xD6, 0xD0, 0xC5, 0x97, 0xF0, 0x45, 0xD0, 0x98, 0x51, 0x91,
62      0x9F, 0xA3, 0x43, 0x51, 0x05, 0x90, 0xEE, 0xCA, 0x7E, 0x5F, 0x72, 0x53, 0xB1, 0xD3, 0xAF, 0x36,
63      0x08, 0x75, 0xB0, 0x9B, 0xE0, 0x0D, 0x43, 0x88, 0xAA, 0x27, 0x44, 0x11
64   },
65   { 0, },   // Region 2, not used
66   { 0, },   // Region 3, not used
67   { 0, },   // Region 4, not used
68   {   // Region 5, $13ab42 (drgw2c)
69      0x7F, 0x41, 0xF3, 0x39, 0xA0, 0x11, 0xA1, 0x11, 0xB0, 0xA2, 0x4C, 0x23, 0x13, 0xE9, 0x25, 0x3D,
70      0x0F, 0x72, 0x3A, 0x9D, 0xB5, 0x96, 0xD1, 0xDA, 0x07, 0x29, 0x41, 0x9A, 0xAD, 0x70, 0xBA, 0x46,
71      0x63, 0x2B, 0x7F, 0x3D, 0xBE, 0x40, 0xAD, 0xD4, 0x4C, 0x73, 0x27, 0x58, 0xA7, 0x65, 0xDC, 0xD6,
72      0xFD, 0xDE, 0xB5, 0x6E, 0xD6, 0x6C, 0x75, 0x1A, 0x32, 0x45, 0xD5, 0xE3, 0x6A, 0x14, 0x6D, 0x80,
73      0x84, 0x15, 0xAF, 0xCC, 0x7B, 0x61, 0x51, 0x82, 0x40, 0x53, 0x7F, 0x38, 0xA0, 0xD6, 0x8F, 0x61,
74      0x79, 0x19, 0xE5, 0x99, 0x84, 0xD8, 0x78, 0x27, 0x3F, 0x16, 0x97, 0x78, 0x4F, 0x7B, 0x0C, 0xA6,
75      0x37, 0xDB, 0xC6, 0x0C, 0x24, 0xB4, 0xC7, 0x94, 0x9D, 0x92, 0xD2, 0x3B, 0xD5, 0x11, 0x6F, 0x0A,
76      0xDB, 0x76, 0x66, 0xE7, 0xCD, 0x18, 0x2B, 0x66, 0xD8, 0x41, 0x40, 0x58, 0xA2, 0x01, 0x1E, 0x6D,
77      0x44, 0x75, 0xE7, 0x19, 0x4F, 0xB2, 0xE8, 0xC4, 0x96, 0x77, 0x62, 0x02, 0xC9, 0xDC, 0x59, 0xF3,
78      0x43, 0x8D, 0xC8, 0xFE, 0x9E, 0x2A, 0xBA, 0x32, 0x3B, 0x62, 0xE3, 0x92, 0x6E, 0xC2, 0x08, 0x4D,
79      0x51, 0xCD, 0xF9, 0x3A, 0x3E, 0xC9, 0x50, 0x27, 0x21, 0x25, 0x97, 0xD7, 0x0E, 0xF8, 0x39, 0x38,
80      0xF5, 0x86, 0x94, 0x93, 0xBF, 0xEB, 0x18, 0xA8, 0xFC, 0x24, 0xF5, 0xF9, 0x99, 0x20, 0x3D, 0xCD,
81      0x2C, 0x94, 0x25, 0x79, 0x28, 0x77, 0x8F, 0x2F, 0x10, 0x69, 0x86, 0x30, 0x43, 0x01, 0xD7, 0x9A,
82      0x17, 0xE3, 0x47, 0x37, 0xBD, 0x62, 0x75, 0x42, 0x78, 0xF4, 0x2B, 0x57, 0x4C, 0x0A, 0xDB, 0x53,
83      0x4D, 0xA1, 0x0A, 0xD6, 0x3A, 0x16, 0x15, 0xAA, 0x2C, 0x6C, 0x39, 0x42
84   },
85   {   // Region 6, $13ab42 (drgw2), $13ab2e (dw2v100x)
86      0x12, 0x09, 0xF3, 0x29, 0xA0, 0x11, 0xA0, 0x11, 0xB0, 0xD5, 0x66, 0xA1, 0x28, 0x4A, 0x21, 0xC0,
87      0xD3, 0x9B, 0x86, 0x80, 0x57, 0x6F, 0x41, 0xC2, 0xE4, 0x2F, 0x0B, 0x91, 0xBD, 0x3A, 0x7A, 0xBA,
88      0x00, 0xE5, 0x35, 0x02, 0x74, 0x7D, 0x8B, 0x21, 0x57, 0x10, 0x0F, 0xAE, 0x44, 0xBB, 0xE2, 0x37,
89      0x18, 0x7B, 0x52, 0x3D, 0x8C, 0x59, 0x9E, 0x20, 0x1F, 0x0A, 0xCC, 0x1C, 0x8E, 0x6A, 0xD7, 0x95,
90      0x2B, 0x34, 0xB0, 0x82, 0x6D, 0xFD, 0x25, 0x33, 0xAA, 0x3B, 0x2B, 0x70, 0x15, 0x87, 0x31, 0x5D,
91      0xBB, 0x29, 0x19, 0x95, 0xD5, 0x8E, 0x24, 0x28, 0x5E, 0xD0, 0x20, 0x83, 0x46, 0x4A, 0x21, 0x70,
92      0x5B, 0xCD, 0xAE, 0x7B, 0x61, 0xA1, 0xFA, 0xF4, 0x2B, 0x84, 0x15, 0x6E, 0x36, 0x5D, 0x1B, 0x24,
93      0x0F, 0x09, 0x3A, 0x61, 0x38, 0x0F, 0x18, 0x35, 0x11, 0x38, 0xB4, 0xBD, 0xEE, 0xF7, 0xEC, 0x0F,
94      0x1D, 0xB7, 0x48, 0x01, 0xAA, 0x09, 0x8F, 0x61, 0xB5, 0x0F, 0x1D, 0x26, 0x39, 0x2E, 0x8C, 0xD6,
95      0x26, 0x5C, 0x3D, 0x23, 0x63, 0xE9, 0x6B, 0x97, 0xB4, 0x9F, 0x7B, 0xB6, 0xBA, 0xA0, 0x7C, 0xC6,
96      0x25, 0xA1, 0x73, 0x36, 0x67, 0x7F, 0x74, 0x1E, 0x1D, 0xDA, 0x70, 0xBF, 0xA5, 0x63, 0x35, 0x39,
97      0x24, 0x8C, 0x9F, 0x85, 0x16, 0xD8, 0x50, 0x95, 0x71, 0xC0, 0xF6, 0x1E, 0x6D, 0x80, 0xED, 0x15,
98      0xEB, 0x63, 0xE9, 0x1B, 0xF6, 0x78, 0x31, 0xC6, 0x5C, 0xDD, 0x19, 0xBD, 0xDF, 0xA7, 0xEC, 0x50,
99      0x22, 0xAD, 0xBB, 0xF6, 0xEB, 0xD6, 0xA3, 0x20, 0xC9, 0xE6, 0x9F, 0xCB, 0xF2, 0x97, 0xB9, 0x54,
100      0x12, 0x66, 0xA6, 0xBE, 0x4A, 0x12, 0x43, 0xEC, 0x00, 0xEA, 0x49, 0x02
101   },
102   { 0, }   // Region 7, not used
103};
64104
65   if (offset == 0)
66      return;
105void pgm_012_025_state::drgw2_protection_calculate_hold(int y, int z)
106{
107   unsigned short old = m_drgw2_prot_hold;
67108
68   switch (dw2_asic_reg[0])
109   m_drgw2_prot_hold = ((old << 1) | (old >> 15));
110
111   m_drgw2_prot_hold ^= 0x2bad;
112   m_drgw2_prot_hold ^= BIT(z, y);
113   m_drgw2_prot_hold ^= BIT( old,  7) <<  0;
114   m_drgw2_prot_hold ^= BIT(~old, 13) <<  4;
115   m_drgw2_prot_hold ^= BIT( old,  3) << 11;
116
117   m_drgw2_prot_hold ^= (m_drgw2_prot_hilo & ~0x0408) << 1;
118}
119
120void pgm_012_025_state::drgw2_protection_calculate_hilo()
121{
122   UINT8 source;
123
124   m_drgw2_prot_hilo_select++;
125   if (m_drgw2_prot_hilo_select > 0xeb) {
126      m_drgw2_prot_hilo_select = 0;
127   }
128
129   source = m_drgw2_source_data[m_drgw2_protection_region][m_drgw2_prot_hilo_select];
130
131   if (m_drgw2_prot_hilo_select & 1)
69132   {
70      case 0x08:
71         // This reg doesn't seem to be used for anything useful but is
72         // initialized. Ok to use as reset??
73         // The last "hold" value used is stored in NVRAM. Otherwise we either
74         // need to set the "hold" value as non-volatile or wipe NVRAM.
75         dw2_asic_hold = m_mainram[protection_address]; // hack
76      break;
133      m_drgw2_prot_hilo = (m_drgw2_prot_hilo & 0x00ff) | (source << 8);
134   }
135   else
136   {
137      m_drgw2_prot_hilo = (m_drgw2_prot_hilo & 0xff00) | (source << 0);
138   }
139}
77140
78      case 0x09: // Used only on init...
79      case 0x0a:
80      case 0x0b:
81      case 0x0c:
82      break;
141READ16_MEMBER(pgm_012_025_state::drgw2_d80000_protection_r )
142{
143   switch (m_drgw2_cmd)
144   {
145           case 0x05:
146      {
147         switch (m_drgw2_ptr)
148         {
149            case 1: return 0x3f00 | ((m_drgw2_protection_region >> 0) & 0xff);
83150
84      case 0x15: // ????
85      case 0x17:
86      break;
151            case 2:
152               return 0x3f00 | ((m_drgw2_protection_region >> 8) & 0xff);
87153
154            case 3:
155               return 0x3f00 | ((m_drgw2_protection_region >> 16) & 0xff);
156
157            case 4:
158               return 0x3f00 | ((m_drgw2_protection_region >> 24) & 0xff);
159
160            case 5:
161            default:
162               return 0x3f00 | BITSWAP8(m_drgw2_prot_hold, 5,2,9,7,10,13,12,15);
163         }
164
165         return 0x3f00;
166      }
167
168      case 0x40:
169         drgw2_protection_calculate_hilo();
170         return 0;
171
172   //   case 0x13: // Read to $80eeb8
173   //   case 0x1f: // Read to $80eeb8
174   //   case 0xf4: // Read to $80eeb8
175   //   case 0xf6: // Read to $80eeb8
176   //   case 0xf8: // Read to $80eeb8
177   //      return 0;
178   
179   //   default:
180   //      logerror("%06x: warning, reading with igs003_reg = %02x\n", space.device().safe_pc(), m_drgw2_cmd);
181   }
182
183   return 0;
184}
185
186WRITE16_MEMBER(pgm_012_025_state::drgw2_d80000_protection_w )
187{
188   if (offset == 0)
189   {
190      m_drgw2_cmd = data;
191      return;
192   }
193
194   switch (m_drgw2_cmd)
195   {
88196      case 0x20:
89197      case 0x21:
90198      case 0x22:
r23578r23579
93201      case 0x25:
94202      case 0x26:
95203      case 0x27:
96      {
97         // computed ~$107000
98         UINT16 old;
204         m_drgw2_ptr++;
205         drgw2_protection_calculate_hold(m_drgw2_cmd & 0x0f, data & 0xff);
206      break;
99207
100         dw2_asic_y = dw2_asic_reg[0] & 0x07;
101         dw2_asic_z = data;
208   //   case 0x08: // Used only on init..
209   //   case 0x09:
210   //   case 0x0a:
211   //   case 0x0b:
212   //   case 0x0c:
213   //   break;
102214
103         // drgw2c = $80eecc, drgw2/dw2v100x = $80cb7c, drgw2j = $8091ca
104         old = dw2_asic_hold;
215   //   case 0x15: // ????
216   //   case 0x17:
217   //   case 0xf2:
218   //   break;
105219
106         // drgw2c = $80eece, drgw2/dw2v100x = $80cb7e, drgw2j = $8091cc
107
108         // roation, fixed xor, and z/y xor all also common to asic-type protection devices
109         dw2_asic_hold  = old << 1;
110         dw2_asic_hold |= BIT(old, 15); // rotate
111         dw2_asic_hold ^= 0x2bad;
112         dw2_asic_hold ^= BIT(dw2_asic_z, dw2_asic_y);
113
114         dw2_asic_hold ^= BIT( old,  7);
115         dw2_asic_hold ^= BIT( old,  3) << 11;
116         dw2_asic_hold ^= BIT(~old, 13) <<  4; // inverted!
117
118   /*
119           // additional...
120           // how is this calculated? is it ever used??
121           // drgw2c = $80eeca, drgw2/dw2v100x = $80cb7a, drgw2j = $809168
122           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 0) << 1;
123           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 1) << 2;
124           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 2) << 3;
125           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 4) << 5;
126           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 5) << 6;
127           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 6) << 7;
128           dw2_asic_hold ^= BIT(space.read_byte(0x80eecb), 7) << 8;
129           dw2_asic_hold ^= BIT(space.read_byte(0x80eeca), 0) << 9;
130           dw2_asic_hold ^= BIT(space.read_byte(0x80eeca), 1) << 10;
131           dw2_asic_hold ^= BIT(space.read_byte(0x80eeca), 3) << 12;
132           dw2_asic_hold ^= BIT(space.read_byte(0x80eeca), 4) << 13;
133           dw2_asic_hold ^= BIT(space.read_byte(0x80eeca), 5) << 14;
134           dw2_asic_hold ^= BIT(space.read_byte(0x80eeca), 6) << 15;
135   */
136      }
137      break;
138
139      case 0xf2: // ????
140      break;
141
142      default:
143         logerror("%06x: warning, writing to igs003_reg %02x = %02x\n", space.device().safe_pc(), dw2_asic_reg[0], data);
220   //   default:
221   //      logerror("%06x: warning, writing to igs003_reg %02x = %02x\n", space.device().safe_pc(), m_drgw2_cmd, data);
144222   }
145223}
146224
147// What purpose to writes to this region serve? Written, but never read back? Must be related to the protection device?
148WRITE16_MEMBER(pgm_state::dw2_unk_w)
225MACHINE_RESET_MEMBER(pgm_012_025_state,drgw2)
149226{
150//  logerror("%06x: warning, writing to address %6.6x = %4.4x\n", space.device().safe_pc(), 0xd00000+(offset*2), data);
227   MACHINE_RESET_CALL_MEMBER(pgm);
228
229   m_drgw2_cmd = 0;
230   m_drgw2_ptr = 0;
231   m_drgw2_prot_hilo = 0;
232   m_drgw2_prot_hilo_select = 0;
233   m_drgw2_prot_hold = 0;
151234}
152235
153void pgm_state::pgm_dw2_decrypt()
236void pgm_012_025_state::drgw2_common_init()
154237{
155   int i;
156   UINT16 *src = (UINT16 *) (memregion("maincpu")->base()+0x100000);
238   m_drgw2_source_data = drgw2_source_data;
157239
158   int rom_size = 0x80000;
240   pgm_basic_init();
241   pgm_drgw2_decrypt();
159242
160   for (i=0; i<rom_size/2; i++) {
161      UINT16 x = src[i];
243   save_item(NAME(m_drgw2_cmd));
244   save_item(NAME(m_drgw2_ptr));
245   save_item(NAME(m_drgw2_prot_hilo));
246   save_item(NAME(m_drgw2_prot_hilo_select));
247   save_item(NAME(m_drgw2_prot_hold));
248}
162249
163      if (((i & 0x20890) == 0) || ((i & 0x20000) == 0x20000 && (i & 0x01500) != 0x01400))
164         x ^= 0x0002;
250static ADDRESS_MAP_START( drgw2_mem, AS_PROGRAM, 16, pgm_012_025_state )
251   AM_IMPORT_FROM(pgm_mem)
252   AM_RANGE(0x100000, 0x1fffff) AM_ROMBANK("bank1") /* Game ROM */
253   AM_RANGE(0xd00000, 0xd00fff) AM_NOP   // Written, but never read back? Related to the protection device?
254   AM_RANGE(0xd80000, 0xd80003) AM_READWRITE(drgw2_d80000_protection_r, drgw2_d80000_protection_w)
255ADDRESS_MAP_END
165256
166      if (((i & 0x20400) == 0 && (i & 0x02010) != 0x02010) || ((i & 0x20000) == 0x20000 && (i & 0x00148) != 0x00140))
167         x ^= 0x0400;
257MACHINE_CONFIG_START( pgm_012_025_drgw2, pgm_012_025_state )
258   MCFG_FRAGMENT_ADD(pgmbase)
168259
169      src[i] = x;
170   }
171}
260   MCFG_CPU_MODIFY("maincpu")
261   MCFG_CPU_PROGRAM_MAP(drgw2_mem)
172262
173void pgm_state::drgwld2_common_init()
174{
175   pgm_basic_init();
176   pgm_dw2_decrypt();
263   MCFG_MACHINE_RESET_OVERRIDE(pgm_012_025_state,drgw2)
264MACHINE_CONFIG_END
177265
178   m_maincpu->space(AS_PROGRAM).install_read_handler(0xd80000, 0xd80003, read16_delegate(FUNC(pgm_state::dw2_d80000_r),this));
179   m_maincpu->space(AS_PROGRAM).install_write_handler(0xd80000, 0xd80003, write16_delegate(FUNC(pgm_state::dw2_d80000_w),this));
180   m_maincpu->space(AS_PROGRAM).install_write_handler(0xd00000, 0xd00fff, write16_delegate(FUNC(pgm_state::dw2_unk_w),this));
181}
182266
183DRIVER_INIT_MEMBER(pgm_state,drgw2)
267DRIVER_INIT_MEMBER(pgm_012_025_state,drgw2)
184268{
185269   /* incomplete? */
186270   UINT16 *mem16 = (UINT16 *)memregion("maincpu")->base();
187271
188   drgwld2_common_init();
272   drgw2_common_init();
189273
190   protection_address = 0xcb7e/2; // $80cb7e;
274   m_drgw2_protection_region = 0x00000006;
191275
192276   /* These ROM patches are not hacks, the protection device
193277      overlays the normal ROM code, this has been confirmed on a real PCB
r23578r23579
197281   mem16[0x1311ce / 2] = 0x4e93;
198282}
199283
200DRIVER_INIT_MEMBER(pgm_state,dw2v100x)
284DRIVER_INIT_MEMBER(pgm_012_025_state,dw2v100x)
201285{
202286   UINT16 *mem16 = (UINT16 *)memregion("maincpu")->base();
203287
204   drgwld2_common_init();
288   drgw2_common_init();
205289
206   protection_address = 0xcb7e/2; // $80cb7e;
290   m_drgw2_protection_region = 0x00000006;
207291
208292   /* These ROM patches are not hacks, the protection device
209293      overlays the normal ROM code, this has been confirmed on a real PCB
r23578r23579
213297   mem16[0x1311ba / 2] = 0x4e93;
214298}
215299
216DRIVER_INIT_MEMBER(pgm_state,drgw2c)
300DRIVER_INIT_MEMBER(pgm_012_025_state,drgw2c)
217301{
218302   UINT16 *mem16 = (UINT16 *)memregion("maincpu")->base();
219303
220   drgwld2_common_init();
304   drgw2_common_init();
221305
222   protection_address = 0xeece/2; // $80eece;
306   m_drgw2_protection_region = 0x00000005;
223307
224308   /* These ROM patches are not hacks, the protection device
225309      overlays the normal ROM code, this has been confirmed on a real PCB
r23578r23579
229313   mem16[0x1304f2 / 2] = 0x4e93;
230314}
231315
232DRIVER_INIT_MEMBER(pgm_state,drgw2j)
316DRIVER_INIT_MEMBER(pgm_012_025_state,drgw2j)
233317{
234318   UINT16 *mem16 = (UINT16 *)memregion("maincpu")->base();
235319
236   drgwld2_common_init();
320   drgw2_common_init();
237321
238   protection_address = 0x91cc/2; // $8091cc;
322   m_drgw2_protection_region = 0x00000001;
239323
240324   /* These ROM patches are not hacks, the protection device
241325      overlays the normal ROM code, this has been confirmed on a real PCB
trunk/src/mame/includes/pgm.h
r23578r23579
122122   void screen_eof_pgm(screen_device &screen, bool state);
123123   TIMER_DEVICE_CALLBACK_MEMBER(pgm_interrupt);
124124
125   // from pgmprot5.c
126   int protection_address;
127
128   UINT16 dw2_asic_reg[2];
129   UINT8 dw2_asic_z;
130   UINT8 dw2_asic_y;
131   UINT16 dw2_asic_hold;
132
133   DECLARE_READ16_MEMBER( dw2_d80000_r );
134   DECLARE_WRITE16_MEMBER( dw2_d80000_w );
135   DECLARE_WRITE16_MEMBER(dw2_unk_w);
136   void pgm_dw2_decrypt();
137   void drgwld2_common_init();
138125   inline void pgm_draw_pix( int xdrawpos, int pri, UINT16* dest, UINT8* destpri, UINT16 srcdat);
139126   inline void pgm_draw_pix_nopri( int xdrawpos, UINT16* dest, UINT8* destpri, UINT16 srcdat);
140127   inline void pgm_draw_pix_pri( int xdrawpos, UINT16* dest, UINT8* destpri, UINT16 srcdat);
r23578r23579
401388   DECLARE_READ16_MEMBER( killbld_igs025_prot_r );
402389};
403390
391/* for machine/pgmprot5.c type games */
392class pgm_012_025_state : public pgm_state
393{
394public:
395   pgm_012_025_state(const machine_config &mconfig, device_type type, const char *tag)
396      : pgm_state(mconfig, type, tag) {
397   }
398
399   UINT32 m_drgw2_protection_region;
400
401   const UINT8 (*m_drgw2_source_data)[0xec];
402
403   UINT16         m_drgw2_prot_hold;
404   UINT16         m_drgw2_prot_hilo;
405   UINT16         m_drgw2_prot_hilo_select;
406   int           m_drgw2_cmd;
407   int           m_drgw2_ptr;
408
409   void pgm_drgw2_decrypt();
410   void drgw2_common_init();
411
412   DECLARE_DRIVER_INIT(drgw2);
413   DECLARE_DRIVER_INIT(dw2v100x);
414   DECLARE_DRIVER_INIT(drgw2c);
415   DECLARE_DRIVER_INIT(drgw2j);
416
417   DECLARE_MACHINE_RESET(drgw2);
418
419   DECLARE_READ16_MEMBER( drgw2_d80000_protection_r );
420   DECLARE_WRITE16_MEMBER( drgw2_d80000_protection_w );
421
422   void drgw2_protection_calculate_hilo();
423   void drgw2_protection_calculate_hold(int y, int z);
424};
425
404426/* for machine/pgmprot6.c type games */
405427class pgm_028_025_state : public pgm_state
406428{
r23578r23579
508530INPUT_PORTS_EXTERN( killbld );
509531INPUT_PORTS_EXTERN( dw3 );
510532
533/*----------- defined in machine/pgmprot5.c -----------*/
534
535MACHINE_CONFIG_EXTERN( pgm_012_025_drgw2 );
536
511537/*----------- defined in machine/pgmprot6.c -----------*/
512538
513539MACHINE_CONFIG_EXTERN( pgm_028_025_ol );

Previous 199869 Revisions Next


© 1997-2024 The MAME Team