mirror of
https://github.com/holub/mame
synced 2025-05-10 16:21:42 +03:00
New WORKING game
-------------------- Lucky Boom [f205v, David Haywood] Refactoring of the PGM protection [David Haywood, iq_132]
This commit is contained in:
parent
58eb388fd5
commit
83cde9101e
6
.gitattributes
vendored
6
.gitattributes
vendored
@ -4286,6 +4286,12 @@ src/mame/machine/pckeybrd.c svneol=native#text/plain
|
||||
src/mame/machine/pcshare.c svneol=native#text/plain
|
||||
src/mame/machine/pgmcrypt.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot1.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot2.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot3.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot4.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot5.c svneol=native#text/plain
|
||||
src/mame/machine/pgmprot6.c svneol=native#text/plain
|
||||
src/mame/machine/pitnrun.c svneol=native#text/plain
|
||||
src/mame/machine/playch10.c svneol=native#text/plain
|
||||
src/mame/machine/psx.c svneol=native#text/plain
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* IGS ARM7 (IGS027A) based Mahjong / Gambling platform
|
||||
/* IGS ARM7 (IGS027A) based Mahjong / Gambling platform(s)
|
||||
Driver by Xing Xing
|
||||
|
||||
These games use the IGS027A processor.
|
||||
@ -242,48 +242,6 @@ static const UINT8 sdwx_tab[] =
|
||||
0x12,0x56,0x97,0x26,0x1D,0x5F,0xA7,0xF8,0x89,0x3F,0x14,0x36,0x72,0x3B,0x48,0x7B,
|
||||
0xF1,0xED,0x72,0xB7,0x7A,0x56,0x05,0xDE,0x7B,0x27,0x6D,0xCF,0x33,0x4C,0x14,0x86,
|
||||
};
|
||||
static void sdwx_decrypt(running_machine &machine)
|
||||
{
|
||||
|
||||
int i;
|
||||
UINT16 *src = (UINT16 *) machine.region("user1")->base();
|
||||
|
||||
int rom_size = 0x80000;
|
||||
|
||||
for(i=0; i<rom_size/2; i++) {
|
||||
UINT16 x = src[i];
|
||||
|
||||
if((i & 0x00480) != 0x00080)
|
||||
x ^= 0x0001;
|
||||
|
||||
|
||||
if((i & 0x004008) == 0x004008)
|
||||
x ^= 0x0002;
|
||||
|
||||
|
||||
// if((i & 0x000030) == 0x000010)
|
||||
// x ^= 0x0004;
|
||||
|
||||
if((i & 0x000242) != 0x000042)
|
||||
x ^= 0x0008;
|
||||
|
||||
if((i & 0x08100) == 0x08000)
|
||||
x ^= 0x0010;
|
||||
|
||||
if((i & 0x022004) != 0x000004)
|
||||
x ^= 0x0020;
|
||||
|
||||
if((i & 0x11800) != 0x10000)
|
||||
x ^= 0x0040;
|
||||
|
||||
if((i & 0x004820) == 0x004820)
|
||||
x ^= 0x0080;
|
||||
|
||||
x ^= sdwx_tab[(i >> 1) & 0xff] << 8;
|
||||
|
||||
src[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -416,14 +374,6 @@ MACHINE_CONFIG_END
|
||||
|
||||
|
||||
|
||||
static DRIVER_INIT( sdwx )
|
||||
{
|
||||
sdwx_decrypt(machine);
|
||||
sdwx_gfx_decrypt(machine);
|
||||
logerror("init OK!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
@ -690,7 +640,7 @@ ROM_START( gonefsh2 )
|
||||
ROM_REGION( 0x400000, "gfx2", 0 )
|
||||
ROM_LOAD( "gfii_cg.u17", 0x000000, 0x200000, CRC(2568359c) SHA1(f1f240246e53496bf624c84f7cae3edb9675579f) )
|
||||
|
||||
ROM_REGION( 0x200000, "unknown", 0 )
|
||||
ROM_REGION( 0x200000, "oki", 0 )
|
||||
ROM_LOAD( "gfii_sp.u13", 0x00000, 0x080000, CRC(61da1d58) SHA1(0a79578f0daf15f0efe2b0eeac59a60d8372a644) )
|
||||
ROM_END
|
||||
|
||||
@ -760,7 +710,7 @@ IGS 0027 - Custom programmed ARM9
|
||||
ROM_START( chessc2 )
|
||||
ROM_REGION( 0x04000, "maincpu", 0 )
|
||||
/* Internal rom of IGS027A ARM based MCU */
|
||||
ROM_LOAD( "gonefsh2_igs027a", 0x00000, 0x4000, NO_DUMP )
|
||||
ROM_LOAD( "chessc2_igs027a", 0x00000, 0x4000, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x80000, "user1", 0 ) // external ARM data / prg
|
||||
ROM_LOAD( "ccii_v-707uso.u12", 0x000000, 0x80000, CRC(5937b67b) SHA1(967b3adf6f5bf92d63ec460d595e473898a78372) )
|
||||
@ -771,12 +721,257 @@ ROM_START( chessc2 )
|
||||
ROM_REGION( 0x400000, "gfx2", 0 )
|
||||
ROM_LOAD( "ccii_cg.u17", 0x000000, 0x200000, CRC(47e45157) SHA1(4459799a4a6c30a2d0a3ad9ac54e92b62221e10b) )
|
||||
|
||||
ROM_REGION( 0x200000, "unknown", 0 )
|
||||
ROM_REGION( 0x200000, "oki", 0 )
|
||||
ROM_LOAD( "ccii_sp.u13", 0x00000, 0x080000, CRC(220a7b71) SHA1(7dab7baa97c20b83763cf46ef0a6e5e8c4d6a348) )
|
||||
ROM_END
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ROM_START( haunthig )
|
||||
ROM_REGION( 0x04000, "maincpu", 0 )
|
||||
/* Internal rom of IGS027A ARM based MCU */
|
||||
ROM_LOAD( "haunthig_igs027a", 0x00000, 0x4000, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x80000, "user1", 0 ) // external ARM data / prg
|
||||
ROM_LOAD( "hauntedhouse_ver-101us.u34", 0x000000, 0x80000, CRC(4bf045d4) SHA1(78c848fd69961df8d9b75f92ad57c3534fbf08db) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx1", 0 )
|
||||
ROM_LOAD( "haunted-h_text.u15", 0x000000, 0x80000, CRC(c23f48c8) SHA1(0cb1b6c61611a081ae4a3c0be51812045ff632fe) )
|
||||
|
||||
// are these PGM-like sprites?
|
||||
ROM_REGION( 0x400000, "gfx2", 0 )
|
||||
ROM_LOAD( "haunted-h_cg.u32", 0x000000, 0x400000, CRC(e0ea10e6) SHA1(e81be78fea93e72d4b1f4c0b58560bda46cf7948) )
|
||||
ROM_REGION( 0x400000, "gfx3", 0 )
|
||||
ROM_LOAD( "haunted-h_ext.u12", 0x000000, 0x400000, CRC(662eb883) SHA1(831ebe29e1e7a8b2c2fff7fbc608975771c3486c) )
|
||||
|
||||
|
||||
ROM_REGION( 0x200000, "oki", 0 )
|
||||
ROM_LOAD( "haunted-h_sp.u3", 0x00000, 0x200000, CRC(fe3fcddf) SHA1(ac57ab6d4e4883747c093bd19d0025cf6588cb2c) )
|
||||
ROM_END
|
||||
|
||||
static void pgm_create_dummy_internal_arm_region(running_machine &machine)
|
||||
{
|
||||
UINT16 *temp16 = (UINT16 *)machine.region("maincpu")->base();
|
||||
|
||||
// fill with RX 14
|
||||
int i;
|
||||
for (i=0;i<0x4000/2;i+=2)
|
||||
{
|
||||
temp16[i] = 0xff1e;
|
||||
temp16[i+1] = 0xe12f;
|
||||
|
||||
}
|
||||
|
||||
// jump straight to external area
|
||||
temp16[(0x0000)/2] = 0xd088;
|
||||
temp16[(0x0002)/2] = 0xe59f;
|
||||
temp16[(0x0004)/2] = 0x0680;
|
||||
temp16[(0x0006)/2] = 0xe3a0;
|
||||
temp16[(0x0008)/2] = 0xff10;
|
||||
temp16[(0x000a)/2] = 0xe12f;
|
||||
temp16[(0x0090)/2] = 0x0400;
|
||||
temp16[(0x0092)/2] = 0x1000;
|
||||
}
|
||||
|
||||
|
||||
static void sdwx_decrypt(running_machine &machine)
|
||||
{
|
||||
|
||||
int i;
|
||||
UINT16 *src = (UINT16 *) machine.region("user1")->base();
|
||||
|
||||
int rom_size = 0x80000;
|
||||
|
||||
for(i=0; i<rom_size/2; i++)
|
||||
{
|
||||
UINT16 x = src[i];
|
||||
|
||||
if((i & 0x000480) != 0x000080) x ^= 0x0001;
|
||||
if((i & 0x004008) == 0x004008) x ^= 0x0002;
|
||||
if((i & 0x000030) == 0x000010) x ^= 0x0004;
|
||||
if((i & 0x000242) != 0x000042) x ^= 0x0008;
|
||||
if((i & 0x008100) == 0x008000) x ^= 0x0010;
|
||||
if((i & 0x022004) != 0x000004) x ^= 0x0020;
|
||||
if((i & 0x011800) != 0x010000) x ^= 0x0040;
|
||||
if((i & 0x004820) == 0x004820) x ^= 0x0080;
|
||||
|
||||
x ^= sdwx_tab[(i >> 1) & 0xff] << 8;
|
||||
|
||||
src[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const UINT8 hauntedh_tab[0x100] = {
|
||||
0x49, 0x47, 0x53, 0x30, 0x32, 0x35, 0x34, 0x52, 0x44, 0x34, 0x30, 0x36, 0x30, 0x35, 0x32, 0x36,
|
||||
0x6C, 0x65, 0x33, 0xFD, 0x7A, 0x71, 0x3D, 0xB8, 0x07, 0xF1, 0x86, 0x96, 0x19, 0x5A, 0xA2, 0x05,
|
||||
0x49, 0xB1, 0xED, 0x2E, 0x7C, 0x7A, 0x65, 0x8B, 0xE1, 0xE3, 0xC8, 0xAA, 0x2B, 0x32, 0xEE, 0x3F,
|
||||
0x10, 0x6C, 0x69, 0x70, 0x02, 0x47, 0x5B, 0x5D, 0x2D, 0x52, 0x97, 0xEF, 0xB1, 0x63, 0xFB, 0xE3,
|
||||
0x21, 0x41, 0x0C, 0x17, 0x3C, 0x93, 0xD4, 0x13, 0xEB, 0x08, 0xF9, 0xDB, 0x7A, 0xC8, 0x1E, 0xF4,
|
||||
0x1B, 0x1B, 0x7F, 0xB4, 0x98, 0x59, 0xC8, 0xCF, 0x58, 0x12, 0x36, 0x1F, 0x96, 0x7D, 0xF0, 0xB3,
|
||||
0xDC, 0x26, 0xA8, 0x1C, 0xC6, 0xD4, 0x6E, 0xF3, 0xF5, 0xB9, 0xD4, 0xAF, 0x52, 0xDD, 0x48, 0xA5,
|
||||
0x85, 0xCC, 0xAD, 0x60, 0xB4, 0x7F, 0x3C, 0x24, 0x80, 0x88, 0x9B, 0xBD, 0x3E, 0x82, 0x3B, 0x8D,
|
||||
0x73, 0xB8, 0xF7, 0xD5, 0x92, 0x15, 0xeb, 0x43, 0xF9, 0x4C, 0x91, 0xBD, 0x29, 0x48, 0x22, 0x6D,
|
||||
0x45, 0xD6, 0x2C, 0x0D, 0xCE, 0x91, 0x70, 0x74, 0x9D, 0x0E, 0xFE, 0x62, 0x22, 0x49, 0x94, 0x88,
|
||||
0xDB, 0x50, 0x33, 0xDB, 0x18, 0x2E, 0x03, 0x1B, 0xED, 0x1A, 0x69, 0x9E, 0x78, 0xE1, 0x66, 0x62,
|
||||
0x54, 0x91, 0x33, 0x52, 0x5E, 0x67, 0x1B, 0xD9, 0xA7, 0xFB, 0x98, 0xA5, 0xBA, 0xAA, 0xB1, 0xBD,
|
||||
0x0F, 0x44, 0x93, 0xC6, 0xCF, 0xF7, 0x6F, 0x91, 0xCA, 0x7B, 0x93, 0xEA, 0xB6, 0x7F, 0xCC, 0x9C,
|
||||
0xAB, 0x54, 0xFB, 0xC8, 0xDB, 0xD9, 0xF5, 0x68, 0x96, 0xA7, 0xA1, 0x1F, 0x7D, 0x7D, 0x4C, 0x43,
|
||||
0x06, 0xED, 0x50, 0x2D, 0x30, 0x48, 0xE6, 0xC0, 0x88, 0xC8, 0x48, 0x38, 0x5D, 0xFC, 0x0a, 0x35,
|
||||
0x3F, 0x79, 0xBA, 0x07, 0xBE, 0xBF, 0xB7, 0x3B, 0x61, 0x69, 0x4F, 0x67, 0xE5, 0x9A, 0x1D, 0x33
|
||||
};
|
||||
|
||||
static void hauntedh_decrypt(running_machine &machine)
|
||||
{
|
||||
int i;
|
||||
UINT16 *src = (UINT16 *) machine.region("user1")->base();
|
||||
|
||||
int rom_size = 0x080000;
|
||||
|
||||
for(i=0; i<rom_size/2; i++) {
|
||||
UINT16 x = src[i];
|
||||
|
||||
if ((i & 0x040480) != 0x000080) x ^= 0x0001;
|
||||
// if ((i & 0x104008) == 0x104008) x ^= 0x0002;
|
||||
// if ((i & 0x080030) == 0x080010) x ^= 0x0004;
|
||||
if ((i & 0x000042) != 0x000042) x ^= 0x0008;
|
||||
// if ((i & 0x048100) == 0x048000) x ^= 0x0010;
|
||||
if ((i & 0x002004) != 0x000004) x ^= 0x0020;
|
||||
if ((i & 0x001800) != 0x000000) x ^= 0x0040;
|
||||
if ((i & 0x004820) == 0x004820) x ^= 0x0080;
|
||||
|
||||
x ^= hauntedh_tab[(i>> 1) & 0xff] << 8;
|
||||
|
||||
src[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const UINT8 chessc2_tab[0x100] = {
|
||||
0x49, 0x47, 0x53, 0x30, 0x30, 0x38, 0x32, 0x52, 0x44, 0x34, 0x30, 0x32, 0x31, 0x32, 0x31, 0x31,
|
||||
0x28, 0xCA, 0x9C, 0xAD, 0xBB, 0x2D, 0xF0, 0x41, 0x6E, 0xCE, 0xAD, 0x73, 0xAE, 0x1C, 0xD1, 0x14,
|
||||
0x6F, 0x9A, 0x75, 0x18, 0xA8, 0x91, 0x68, 0xe4, 0x09, 0xF4, 0x0F, 0xD7, 0xFF, 0x93, 0x7D, 0x1B,
|
||||
0xEB, 0x84, 0xce, 0xAD, 0x9E, 0xCF, 0xC9, 0xAB, 0x18, 0x59, 0xb6, 0xde, 0x82, 0x13, 0x7C, 0x88,
|
||||
0x69, 0x63, 0xFF, 0x6F, 0x3C, 0xD2, 0xB9, 0x29, 0x09, 0xF8, 0x97, 0xAA, 0x74, 0xA5, 0x16, 0x0D,
|
||||
0xF9, 0x51, 0x9E, 0x9f, 0x63, 0xC6, 0x1E, 0x32, 0x8C, 0x0C, 0xE9, 0xA0, 0x56, 0x95, 0xD1, 0x9D,
|
||||
0xEA, 0xA9, 0x82, 0xC3, 0x30, 0x15, 0x21, 0xD8, 0x8F, 0x10, 0x25, 0x61, 0xE6, 0x6D, 0x75, 0x6D,
|
||||
0xCB, 0x08, 0xC3, 0x9B, 0x03, 0x6A, 0x28, 0x6D, 0x42, 0xBF, 0x00, 0xd2, 0x24, 0xFA, 0x08, 0xEE,
|
||||
0x6B, 0x46, 0xB7, 0x2C, 0x7B, 0xB0, 0xDA, 0x86, 0x13, 0x14, 0x73, 0x14, 0x4D, 0x45, 0xD3, 0xD4,
|
||||
0xD9, 0x80, 0xF5, 0xB8, 0x76, 0x13, 0x1E, 0xF6, 0xB1, 0x4A, 0xB3, 0x8B, 0xE2, 0x9A, 0x5A, 0x11,
|
||||
0x64, 0x11, 0x55, 0xC3, 0x14, 0xFD, 0x1B, 0xCe, 0x0C, 0xDC, 0x38, 0xDA, 0xA1, 0x84, 0x66, 0xD9,
|
||||
0x9b, 0x93, 0xED, 0x0F, 0xB4, 0x19, 0x38, 0x62, 0x53, 0x85, 0xB9, 0xE5, 0x89, 0xCd, 0xFE, 0x9E,
|
||||
0x4D, 0xE2, 0x14, 0x9F, 0xF4, 0x53, 0x1C, 0x46, 0xf4, 0x40, 0x2C, 0xCC, 0xDa, 0x82, 0x69, 0x15,
|
||||
0x88, 0x18, 0x62, 0xB7, 0xB4, 0xD5, 0xAF, 0x4B, 0x9E, 0x48, 0xCA, 0xF4, 0x11, 0xEC, 0x2D, 0x2C,
|
||||
0x9D, 0x91, 0xAD, 0xDA, 0x13, 0x0A, 0x16, 0x86, 0x41, 0x18, 0x08, 0x01, 0xef, 0x97, 0x11, 0x1f,
|
||||
0x1A, 0xE7, 0x0C, 0xC9, 0x6D, 0x9D, 0xB9, 0x49, 0x0B, 0x6B, 0x9E, 0xD4, 0x72, 0x4D, 0x1D, 0x59
|
||||
};
|
||||
|
||||
static void chessc2_decrypt(running_machine &machine)
|
||||
{
|
||||
int i;
|
||||
UINT16 *src = (UINT16 *) machine.region("user1")->base();
|
||||
|
||||
int rom_size = 0x80000;
|
||||
|
||||
for(i=0; i<rom_size/2; i++) {
|
||||
UINT16 x = src[i];
|
||||
|
||||
if ((i & 0x040480) != 0x000080) x ^= 0x0001;
|
||||
if ((i & 0x004008) == 0x004008) x ^= 0x0002;
|
||||
// if ((i & 0x080030) == 0x080010) x ^= 0x0004;
|
||||
if ((i & 0x000242) != 0x000042) x ^= 0x0008;
|
||||
if ((i & 0x008100) == 0x008000) x ^= 0x0010;
|
||||
if ((i & 0x002004) != 0x000004) x ^= 0x0020; // correct??
|
||||
if ((i & 0x011800) != 0x010000) x ^= 0x0040;
|
||||
if ((i & 0x004820) == 0x004820) x ^= 0x0080;
|
||||
|
||||
x ^= chessc2_tab[(i>> 1) & 0xff] << 8;
|
||||
|
||||
src[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const UINT8 klxyj_tab[0x100] = {
|
||||
0x49, 0x47, 0x53, 0x30, 0x30, 0x30, 0x38, 0x52, 0x44, 0x34, 0x30, 0x31, 0x30, 0x39, 0x32, 0x34,
|
||||
0x3F, 0x0F, 0x66, 0x9A, 0xBF, 0x0D, 0x06, 0x55, 0x09, 0x01, 0xEB, 0x72, 0xEB, 0x9B, 0x89, 0xFA,
|
||||
0x24, 0xD1, 0x5D, 0xCA, 0xE6, 0x8A, 0x8C, 0xE0, 0x92, 0x8D, 0xBF, 0xE4, 0xAF, 0xAA, 0x3E, 0xFA,
|
||||
0x2B, 0x27, 0x4B, 0xC7, 0xD6, 0x6D, 0xC1, 0xC2, 0x1C, 0xF4, 0xED, 0xBD, 0x03, 0x6C, 0xAD, 0xB3,
|
||||
0x65, 0x2D, 0xC7, 0xD3, 0x6E, 0xE0, 0x8C, 0xCE, 0x59, 0x6F, 0xAE, 0x5E, 0x66, 0x2B, 0x5E, 0x17,
|
||||
0x20, 0x3D, 0xA9, 0x72, 0xCD, 0x4F, 0x14, 0x17, 0x35, 0x7B, 0x77, 0x6B, 0x98, 0x73, 0x17, 0x5A,
|
||||
0xEA, 0xF2, 0x07, 0x66, 0x51, 0x64, 0xC1, 0xF0, 0xE2, 0xD1, 0x00, 0xC6, 0x97, 0x0F, 0xE0, 0xEE,
|
||||
0x94, 0x28, 0x39, 0xB2, 0x9B, 0x0A, 0x38, 0xED, 0xCC, 0x6E, 0x40, 0x94, 0xA2, 0x0A, 0x00, 0x88,
|
||||
0x2B, 0xFA, 0xD5, 0x9A, 0x87, 0x6C, 0x62, 0xDF, 0xA4, 0x8B, 0x6D, 0x37, 0x38, 0xAE, 0xFD, 0x18,
|
||||
0xFF, 0xC2, 0xB2, 0xA0, 0x37, 0xF5, 0x64, 0xDB, 0x59, 0xA5, 0x00, 0x51, 0x19, 0x88, 0x9F, 0xD4,
|
||||
0xA0, 0x1C, 0xE7, 0x88, 0x08, 0x51, 0xA7, 0x33, 0x19, 0x75, 0xAE, 0xC7, 0x42, 0x61, 0xEC, 0x2D,
|
||||
0xDB, 0xE2, 0xCC, 0x54, 0x9A, 0x6A, 0xD1, 0x7A, 0x53, 0xF8, 0x6F, 0xBA, 0xF4, 0x45, 0x2C, 0xD7,
|
||||
0xC0, 0x30, 0xF7, 0x47, 0xCC, 0x6B, 0xC8, 0x83, 0xB7, 0x67, 0x7A, 0x8E, 0xAD, 0x7E, 0xE5, 0xC4,
|
||||
0x9F, 0x60, 0x40, 0xE5, 0xBC, 0xC0, 0xB5, 0x61, 0x33, 0x3F, 0x46, 0xE6, 0x2D, 0x98, 0xDF, 0x28,
|
||||
0x05, 0x0E, 0xBC, 0xF0, 0xCA, 0x13, 0xFE, 0x68, 0xF7, 0x3A, 0x89, 0xA5, 0x71, 0x5F, 0x21, 0x76,
|
||||
0xC2, 0x14, 0xC5, 0x6C, 0x95, 0x4f, 0x4f, 0x2A, 0x71, 0x52, 0x3C, 0xEE, 0xAA, 0xDB, 0xf1, 0x00
|
||||
};
|
||||
|
||||
static void klxyj_decrypt(running_machine &machine)
|
||||
{
|
||||
int i;
|
||||
UINT16 *src = (UINT16 *) machine.region("user1")->base();
|
||||
|
||||
int rom_size = 0x80000;
|
||||
|
||||
for(i=0; i<rom_size/2; i++) {
|
||||
UINT16 x = src[i];
|
||||
|
||||
if ((i & 0x040480) != 0x000080) x ^= 0x0001;
|
||||
if ((i & 0x004008) == 0x004008) x ^= 0x0002;
|
||||
// if ((i & 0x080030) == 0x080010) x ^= 0x0004;
|
||||
if ((i & 0x000242) != 0x000042) x ^= 0x0008;
|
||||
if ((i & 0x008100) == 0x008000) x ^= 0x0010;
|
||||
if ((i & 0x002004) != 0x000004) x ^= 0x0020;
|
||||
if ((i & 0x011800) != 0x010000) x ^= 0x0040;
|
||||
if ((i & 0x004820) == 0x004820) x ^= 0x0080;
|
||||
|
||||
x ^= klxyj_tab[(i>> 1) & 0xff] << 8;
|
||||
|
||||
src[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
static DRIVER_INIT( igs_m027 )
|
||||
{
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( sdwx )
|
||||
{
|
||||
sdwx_decrypt(machine);
|
||||
sdwx_gfx_decrypt(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( klxyj )
|
||||
{
|
||||
klxyj_decrypt(machine);
|
||||
//sdwx_gfx_decrypt(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( chessc2 )
|
||||
{
|
||||
chessc2_decrypt(machine);
|
||||
//sdwx_gfx_decrypt(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( hauntedh )
|
||||
{
|
||||
hauntedh_decrypt(machine);
|
||||
//sdwx_gfx_decrypt(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game Drivers
|
||||
@ -784,11 +979,12 @@ ROM_END
|
||||
***************************************************************************/
|
||||
|
||||
GAME( 2002, sdwx, 0, igs_majhong, sdwx, sdwx, ROT0, "IGS", "Sheng Dan Wu Xian", GAME_NO_SOUND | GAME_NOT_WORKING ) // aka Christmas 5 Line?
|
||||
GAME( 200?, sddz, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Super Dou Di Zhu", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 2000, bigd2, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Big D2", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, lhzb3, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Long Hu Zheng Ba 3", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, lhzb4, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Long Hu Zheng Ba 4", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, klxyj, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Kuai Le Xi You Ji", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 2000, mgfx, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Man Guan Fu Xing", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, gonefsh2, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Gone Fishing 2", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, chessc2, 0, igs_majhong, sdwx, 0, ROT0, "IGS", "Chess Challenge 2", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, sddz, 0, igs_majhong, sdwx, igs_m027, ROT0, "IGS", "Super Dou Di Zhu", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 2000, bigd2, 0, igs_majhong, sdwx, igs_m027, ROT0, "IGS", "Big D2", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, lhzb3, 0, igs_majhong, sdwx, igs_m027, ROT0, "IGS", "Long Hu Zheng Ba 3", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, lhzb4, 0, igs_majhong, sdwx, igs_m027, ROT0, "IGS", "Long Hu Zheng Ba 4", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, klxyj, 0, igs_majhong, sdwx, klxyj, ROT0, "IGS", "Kuai Le Xi You Ji", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 2000, mgfx, 0, igs_majhong, sdwx, igs_m027, ROT0, "IGS", "Man Guan Fu Xing", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, gonefsh2, 0, igs_majhong, sdwx, igs_m027, ROT0, "IGS", "Gone Fishing 2", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, chessc2, 0, igs_majhong, sdwx, chessc2, ROT0, "IGS", "Chess Challenge 2", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
GAME( 200?, haunthig, 0, igs_majhong, sdwx, hauntedh, ROT0, "IGS", "Haunted House (IGS)", GAME_NO_SOUND | GAME_NOT_WORKING )
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -292,6 +292,25 @@ static ADDRESS_MAP_START( sderby_map, AS_PROGRAM, 16 )
|
||||
AM_RANGE(0xffc000, 0xffffff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( luckboom_map, AS_PROGRAM, 16 )
|
||||
AM_RANGE(0x000000, 0x07ffff) AM_ROM
|
||||
AM_RANGE(0x100000, 0x100fff) AM_RAM_WRITE(sderby_videoram_w) AM_BASE_MEMBER(sderby_state,m_videoram) /* bg */
|
||||
AM_RANGE(0x101000, 0x101fff) AM_RAM_WRITE(sderby_md_videoram_w) AM_BASE_MEMBER(sderby_state,m_md_videoram) /* mid */
|
||||
AM_RANGE(0x102000, 0x103fff) AM_RAM_WRITE(sderby_fg_videoram_w) AM_BASE_MEMBER(sderby_state,m_fg_videoram) /* fg */
|
||||
AM_RANGE(0x104000, 0x10400b) AM_WRITE(sderby_scroll_w)
|
||||
AM_RANGE(0x10400c, 0x10400d) AM_WRITENOP /* ??? - check code at 0x000456 (executed once at startup) */
|
||||
AM_RANGE(0x10400e, 0x10400f) AM_WRITENOP /* ??? - check code at 0x000524 (executed once at startup) */
|
||||
AM_RANGE(0x200000, 0x200fff) AM_RAM AM_BASE_MEMBER(sderby_state,m_spriteram) AM_SIZE_MEMBER(sderby_state,m_spriteram_size)
|
||||
AM_RANGE(0x308000, 0x30800d) AM_READ(sderby_input_r)
|
||||
AM_RANGE(0x308008, 0x308009) AM_WRITE(sderby_out_w) /* output port */
|
||||
AM_RANGE(0x30800e, 0x30800f) AM_DEVREADWRITE8_MODERN("oki", okim6295_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x380000, 0x380fff) AM_WRITE(paletteram16_RRRRRGGGGGBBBBBx_word_w) AM_BASE_GENERIC(paletteram)
|
||||
AM_RANGE(0x500000, 0x500001) AM_WRITENOP /* unknown... write 0x01 in game, and 0x00 on reset */
|
||||
AM_RANGE(0xe00000, 0xe007ff) AM_RAM AM_SHARE("nvram")
|
||||
AM_RANGE(0xff0000, 0xffffff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( spacewin_map, AS_PROGRAM, 16 )
|
||||
AM_RANGE(0x000000, 0x03ffff) AM_ROM
|
||||
AM_RANGE(0x100000, 0x100fff) AM_RAM_WRITE(sderby_videoram_w) AM_BASE_MEMBER(sderby_state,m_videoram) /* bg */
|
||||
@ -359,6 +378,26 @@ static INPUT_PORTS_START( sderby )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( luckboom )
|
||||
PORT_START("IN0") /* 0x308000.w */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_SERVICE_NO_TOGGLE(0x1000, IP_ACTIVE_LOW)
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( spacewin )
|
||||
PORT_START("IN0") /* 0x308000.w */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_POKER_HOLD1 )
|
||||
@ -478,6 +517,30 @@ static MACHINE_CONFIG_START( sderby, sderby_state )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_START( luckboom, sderby_state )
|
||||
|
||||
MCFG_CPU_ADD("maincpu", M68000, 12000000)
|
||||
MCFG_CPU_PROGRAM_MAP(luckboom_map)
|
||||
MCFG_CPU_VBLANK_INT("screen", irq4_line_hold)
|
||||
|
||||
MCFG_NVRAM_ADD_0FILL("nvram")
|
||||
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
|
||||
MCFG_SCREEN_SIZE(64*8, 64*8)
|
||||
MCFG_SCREEN_VISIBLE_AREA(4*8, 44*8-1, 3*8, 33*8-1)
|
||||
MCFG_SCREEN_UPDATE_STATIC(sderby)
|
||||
|
||||
MCFG_GFXDECODE(sderby)
|
||||
MCFG_PALETTE_LENGTH(0x1000)
|
||||
MCFG_VIDEO_START(sderby)
|
||||
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_OKIM6295_ADD("oki", 1056000, OKIM6295_PIN7_HIGH) /* clock frequency & pin 7 not verified */
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_START( spacewin, sderby_state )
|
||||
|
||||
MCFG_CPU_ADD("maincpu", M68000, 12000000)
|
||||
@ -718,6 +781,53 @@ ROM_START( croupiera )
|
||||
ROM_LOAD( "8.bin", 0x200000, 0x80000, CRC(d4c2b7da) SHA1(515be861443acc5b911241dbaafa42e02f79985a))
|
||||
ROM_END
|
||||
|
||||
/*
|
||||
Lucky Boom (c)1996 Playmark
|
||||
|
||||
QTY Type clock position function
|
||||
1x MC68000P12 u24 16/32-bit Microprocessor - main
|
||||
1x M6295 u146 4-Channel Mixing ADCPM Voice Synthesis LSI - sound
|
||||
1x KA358 u155 Dual Operational Amplifier - sound
|
||||
1x TDA2003 TD1 Audio Amplifier - sound
|
||||
1x oscillator 24.000000MHz XL1
|
||||
1x oscillator 28.000000MHz XL2
|
||||
1x blu resonator 1000J Y1
|
||||
|
||||
ROMs
|
||||
QTY Type position status
|
||||
1x TMS27C020 1 dumped
|
||||
2x AM27C010 2,3 dumped
|
||||
5x TMS27C010 4-8 dumped
|
||||
|
||||
RAMs
|
||||
QTY Type position
|
||||
8x HM3-65728BK-5 u42,u73,u74,u75,u80,u81,u124,u125
|
||||
2x HY62256ALP-10 u2,u6
|
||||
2x KM6264BL-7L u36,u37
|
||||
PLDs
|
||||
QTY Type position status
|
||||
2x A1020B-PL84C u110,u137 read protected
|
||||
4x TIBPAL22V10ACNT u1,u77,u111,u112 read protected
|
||||
*/
|
||||
|
||||
|
||||
|
||||
ROM_START( luckboom )
|
||||
ROM_REGION( 0x80000, "maincpu", 0 ) /* 68000 Code */
|
||||
ROM_LOAD16_BYTE( "2.u16", 0x00000, 0x20000, CRC(0a20eaca) SHA1(edd325b60b3a3ce84e89f8be91b9e19f82d15317) )
|
||||
ROM_LOAD16_BYTE( "3.u15", 0x00001, 0x20000, CRC(0d3bb24c) SHA1(31826ec29650aa8b70e1b713678401113e008832) )
|
||||
|
||||
ROM_REGION( 0x080000, "oki", 0 ) /* Samples */
|
||||
ROM_LOAD( "1.u147", 0x00000, 0x40000, CRC(0d42c0a3) SHA1(1b1d4c7dcbb063e8bf133063770b753947d1a017) )
|
||||
|
||||
ROM_REGION( 0xa0000, "gfx1", 0 ) /* Sprites */
|
||||
ROM_LOAD( "4.u141", 0x000000, 0x20000, CRC(3aeccad7) SHA1(4104dd3ae928c1a876ac9b460fe18b58ce1206f7) )
|
||||
ROM_LOAD( "5.u142", 0x020000, 0x20000, CRC(4e4f9ac6) SHA1(e9b0c48195d8b21cdab16d66423ff43e6292ef2c) )
|
||||
ROM_LOAD( "6.u143", 0x040000, 0x20000, CRC(d1b4910e) SHA1(cfcb14bcd992bceaa634b20eb2d446caa62b6d82) )
|
||||
ROM_LOAD( "7.u144", 0x060000, 0x20000, CRC(00334bad) SHA1(2d8af2a4b517ceb1ae5504b15086c8faaf934b53) )
|
||||
ROM_LOAD( "8.u145", 0x080000, 0x20000, CRC(dc12df50) SHA1(0796d6428dc3a032ea55e06e8e07245a256ed036) )
|
||||
ROM_END
|
||||
|
||||
|
||||
/******************************
|
||||
* Game Drivers *
|
||||
@ -728,3 +838,4 @@ GAMEL( 1996, sderby, 0, sderby, sderby, 0, ROT0, "Playmark", "
|
||||
GAMEL( 1996, spacewin, 0, spacewin, spacewin, 0, ROT0, "Playmark", "Scacco Matto / Space Win", 0, layout_spacewin )
|
||||
GAMEL( 1997, croupier, 0, pmroulet, pmroulet, 0, ROT0, "Playmark", "Croupier (Playmark Roulette v.20.05)", GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING, layout_pmroulet )
|
||||
GAMEL( 1997, croupiera, croupier, pmroulet, pmroulet, 0, ROT0, "Playmark", "Croupier (Playmark Roulette v.09.04)", GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING, layout_pmroulet )
|
||||
GAME ( 1996, luckboom, 0, luckboom, luckboom, 0, ROT0, "Playmark", "Lucky Boom", 0 )
|
||||
|
@ -1,4 +1,14 @@
|
||||
|
||||
#include "machine/v3021.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/arm7/arm7.h"
|
||||
#include "sound/ics2115.h"
|
||||
#include "cpu/arm7/arm7core.h"
|
||||
#include "machine/nvram.h"
|
||||
|
||||
#define PGMARM7LOGERROR 0
|
||||
|
||||
class pgm_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -72,15 +82,6 @@ public:
|
||||
UINT32 m_kb_regs[0x10];
|
||||
UINT16 m_olds_bs;
|
||||
UINT16 m_olds_cmd3;
|
||||
// pstars
|
||||
UINT16 m_pstars_key;
|
||||
UINT16 m_pstars_int[2];
|
||||
UINT32 m_pstars_regs[16];
|
||||
UINT32 m_pstars_val;
|
||||
UINT16 m_pstar_e7;
|
||||
UINT16 m_pstar_b1;
|
||||
UINT16 m_pstar_ce;
|
||||
UINT16 m_pstar_ram[3];
|
||||
// ASIC 3 (oriental legends protection)
|
||||
UINT8 m_asic3_reg;
|
||||
UINT8 m_asic3_latch[3];
|
||||
@ -90,29 +91,68 @@ public:
|
||||
UINT8 m_asic3_h1;
|
||||
UINT8 m_asic3_h2;
|
||||
UINT16 m_asic3_hold;
|
||||
// ASIC28
|
||||
UINT16 m_asic28_key;
|
||||
UINT16 m_asic28_regs[10];
|
||||
UINT16 m_asic_params[256];
|
||||
UINT16 m_asic28_rcnt;
|
||||
UINT32 m_eoregs[16];
|
||||
// Oldsplus simulation
|
||||
UINT16 m_oldsplus_key;
|
||||
UINT16 m_oldsplus_int[2];
|
||||
UINT32 m_oldsplus_val;
|
||||
UINT16 m_oldsplus_ram[0x100];
|
||||
UINT32 m_oldsplus_regs[0x100];
|
||||
|
||||
UINT32* m_arm_ram;
|
||||
|
||||
};
|
||||
|
||||
/* for machine/pgmprot1.c type games */
|
||||
class pgm_kovarmsim_state : public pgm_state
|
||||
{
|
||||
public:
|
||||
pgm_kovarmsim_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: pgm_state(mconfig, type, tag) {
|
||||
|
||||
m_ddp3internal_slot = 0;
|
||||
}
|
||||
|
||||
UINT16 m_value0;
|
||||
UINT16 m_value1;
|
||||
UINT16 m_valuekey;
|
||||
UINT16 m_ddp3lastcommand;
|
||||
UINT32 m_valueresponse;
|
||||
int m_ddp3internal_slot;
|
||||
UINT32 m_ddp3slots[0x100];
|
||||
|
||||
// pstars / oldsplus
|
||||
UINT16 m_pstar_e7;
|
||||
UINT16 m_pstar_b1;
|
||||
UINT16 m_pstar_ce;
|
||||
UINT16 m_extra_ram[0x100];
|
||||
|
||||
typedef void (*pgm_arm_sim_command_handler)(pgm_kovarmsim_state *state, int pc);
|
||||
|
||||
pgm_arm_sim_command_handler arm_sim_handler;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern UINT16 *pgm_mainram; // used by nvram handler, we cannot move it to driver data struct
|
||||
|
||||
/*----------- defined in drivers/pgm.c -----------*/
|
||||
|
||||
void pgm_basic_init( running_machine &machine, bool set_bank = true );
|
||||
|
||||
INPUT_PORTS_EXTERN( pgm );
|
||||
|
||||
/* we only need half of these because CavePGM has it's own MACHINE DRIVER in pgmprot1.c - refactor */
|
||||
TIMER_DEVICE_CALLBACK( pgm_interrupt );
|
||||
|
||||
GFXDECODE_EXTERN( pgm );
|
||||
|
||||
MACHINE_CONFIG_EXTERN( pgm );
|
||||
|
||||
ADDRESS_MAP_EXTERN( pgm_z80_mem, 8 );
|
||||
ADDRESS_MAP_EXTERN( pgm_z80_io, 8 );
|
||||
void pgm_sound_irq( device_t *device, int level );
|
||||
|
||||
ADDRESS_MAP_EXTERN( pgm_mem, 16 );
|
||||
ADDRESS_MAP_EXTERN( pgm_basic_mem, 16 );
|
||||
ADDRESS_MAP_EXTERN( pgm_base_mem, 16 );
|
||||
|
||||
MACHINE_START( pgm );
|
||||
MACHINE_RESET( pgm );
|
||||
|
||||
/*----------- defined in machine/pgmcrypt.c -----------*/
|
||||
|
||||
void pgm_kov_decrypt(running_machine &machine);
|
||||
@ -141,27 +181,101 @@ void pgm_happy6_decrypt(running_machine &machine);
|
||||
|
||||
/*----------- defined in machine/pgmprot.c -----------*/
|
||||
|
||||
READ16_HANDLER( pstars_protram_r );
|
||||
READ16_HANDLER( pstars_r );
|
||||
WRITE16_HANDLER( pstars_w );
|
||||
DRIVER_INIT( orlegend );
|
||||
|
||||
READ16_HANDLER( pgm_asic3_r );
|
||||
WRITE16_HANDLER( pgm_asic3_w );
|
||||
WRITE16_HANDLER( pgm_asic3_reg_w );
|
||||
INPUT_PORTS_EXTERN( orlegend );
|
||||
INPUT_PORTS_EXTERN( orld105k );
|
||||
|
||||
READ16_HANDLER( sango_protram_r );
|
||||
READ16_HANDLER( asic28_r );
|
||||
WRITE16_HANDLER( asic28_w );
|
||||
/*----------- defined in machine/pgmprot1.c -----------*/
|
||||
|
||||
READ16_HANDLER( dw2_d80000_r );
|
||||
/* emulations */
|
||||
DRIVER_INIT( photoy2k );
|
||||
DRIVER_INIT( kovsh );
|
||||
DRIVER_INIT( kovshp );
|
||||
DRIVER_INIT( kovlsqh2 );
|
||||
DRIVER_INIT( kovqhsgs );
|
||||
|
||||
MACHINE_CONFIG_EXTERN( kov );
|
||||
|
||||
READ16_HANDLER( oldsplus_protram_r );
|
||||
READ16_HANDLER( oldsplus_r );
|
||||
WRITE16_HANDLER( oldsplus_w );
|
||||
/* simulations */
|
||||
DRIVER_INIT( ddp3 );
|
||||
DRIVER_INIT( ket );
|
||||
DRIVER_INIT( espgal );
|
||||
DRIVER_INIT( puzzli2 );
|
||||
DRIVER_INIT( py2k2 );
|
||||
DRIVER_INIT( pstar );
|
||||
DRIVER_INIT( kov );
|
||||
DRIVER_INIT( kovboot );
|
||||
DRIVER_INIT( oldsplus );
|
||||
|
||||
MACHINE_CONFIG_EXTERN( kov_simulated_arm );
|
||||
MACHINE_CONFIG_EXTERN( cavepgm );
|
||||
|
||||
INPUT_PORTS_EXTERN( sango );
|
||||
INPUT_PORTS_EXTERN( sango_ch );
|
||||
INPUT_PORTS_EXTERN( photoy2k );
|
||||
INPUT_PORTS_EXTERN( oldsplus );
|
||||
INPUT_PORTS_EXTERN( pstar );
|
||||
INPUT_PORTS_EXTERN( py2k2 );
|
||||
INPUT_PORTS_EXTERN( puzzli2 );
|
||||
INPUT_PORTS_EXTERN( kovsh );
|
||||
|
||||
/*----------- defined in machine/pgmprot2.c -----------*/
|
||||
|
||||
/* emulations */
|
||||
MACHINE_CONFIG_EXTERN( kov2 );
|
||||
|
||||
DRIVER_INIT( kov2 );
|
||||
DRIVER_INIT( kov2p );
|
||||
DRIVER_INIT( martmast );
|
||||
DRIVER_INIT( ddp2 );
|
||||
|
||||
/* simulations (or missing) */
|
||||
|
||||
DRIVER_INIT( dw2001 );
|
||||
|
||||
INPUT_PORTS_EXTERN( ddp2 );
|
||||
INPUT_PORTS_EXTERN( kov2 );
|
||||
INPUT_PORTS_EXTERN( martmast );
|
||||
INPUT_PORTS_EXTERN( dw2001 );
|
||||
|
||||
/*----------- defined in machine/pgmprot3.c -----------*/
|
||||
|
||||
MACHINE_CONFIG_EXTERN( svg );
|
||||
|
||||
DRIVER_INIT( theglad );
|
||||
DRIVER_INIT( svg );
|
||||
DRIVER_INIT( svgpcb );
|
||||
DRIVER_INIT( killbldp );
|
||||
DRIVER_INIT( dmnfrnt );
|
||||
DRIVER_INIT( happy6 );
|
||||
|
||||
/*----------- defined in machine/pgmprot4.c -----------*/
|
||||
|
||||
MACHINE_CONFIG_EXTERN( killbld );
|
||||
MACHINE_CONFIG_EXTERN( dw3 );
|
||||
|
||||
DRIVER_INIT( killbld );
|
||||
DRIVER_INIT( drgw3 );
|
||||
|
||||
INPUT_PORTS_EXTERN( killbld );
|
||||
INPUT_PORTS_EXTERN( dw3 );
|
||||
|
||||
/*----------- defined in machine/pgmprot5.c -----------*/
|
||||
|
||||
DRIVER_INIT( drgw2 );
|
||||
DRIVER_INIT( dw2v100x );
|
||||
DRIVER_INIT( drgw2c );
|
||||
DRIVER_INIT( drgw2j );
|
||||
|
||||
/*----------- defined in machine/pgmprot6.c -----------*/
|
||||
|
||||
MACHINE_CONFIG_EXTERN( olds );
|
||||
|
||||
DRIVER_INIT( olds );
|
||||
|
||||
INPUT_PORTS_EXTERN( olds );
|
||||
|
||||
MACHINE_RESET( kov );
|
||||
void install_protection_asic_sim_kov(running_machine &machine);
|
||||
|
||||
/*----------- defined in video/pgm.c -----------*/
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
1624
src/mame/machine/pgmprot1.c
Normal file
1624
src/mame/machine/pgmprot1.c
Normal file
File diff suppressed because it is too large
Load Diff
387
src/mame/machine/pgmprot2.c
Normal file
387
src/mame/machine/pgmprot2.c
Normal file
@ -0,0 +1,387 @@
|
||||
/***********************************************************************
|
||||
PGM IGA027A (55857F type) ARM protection emulation
|
||||
|
||||
these are emulation of the 'kov2' type ARM device
|
||||
used by
|
||||
|
||||
Knights of Valor 2 (kov2)
|
||||
Knights of Valor 2 Nine Dragons (kov2p) *
|
||||
DoDonPachi 2 - Bee Storm (ddp2)
|
||||
Martial Masters (martmast)
|
||||
|
||||
* using a hacked kov2 internal ROM
|
||||
|
||||
the following also use this device, but the internal
|
||||
ROMs are not yet dumped
|
||||
|
||||
Dragon World 2001 (dw2001)
|
||||
|
||||
----
|
||||
|
||||
These games use a larger region of shared RAM than the 55857E
|
||||
type and have a communication based on interrupts
|
||||
|
||||
----
|
||||
|
||||
All of these games have an external ARM rom.
|
||||
|
||||
The external ARM roms are encrypted, the internal ARM rom uploads
|
||||
the decryption tables.
|
||||
|
||||
Game Region is supplied by internal ARM rom.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/pgm.h"
|
||||
|
||||
|
||||
static READ32_HANDLER( arm7_latch_arm_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
device_set_input_line(state->m_prot, ARM7_FIRQ_LINE, CLEAR_LINE ); // guess
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("ARM7: Latch read: %08x (%08x) (%06x)\n", state->m_kov2_latchdata_68k_w, mem_mask, cpu_get_pc(&space->device()));
|
||||
return state->m_kov2_latchdata_68k_w;
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( arm7_latch_arm_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("ARM7: Latch write: %08x (%08x) (%06x)\n", data, mem_mask, cpu_get_pc(&space->device()));
|
||||
|
||||
COMBINE_DATA(&state->m_kov2_latchdata_arm_w);
|
||||
}
|
||||
|
||||
static READ32_HANDLER( arm7_shareram_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("ARM7: ARM7 Shared RAM Read: %04x = %08x (%08x) (%06x)\n", offset << 2, state->m_arm7_shareram[offset], mem_mask, cpu_get_pc(&space->device()));
|
||||
return state->m_arm7_shareram[offset];
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( arm7_shareram_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("ARM7: ARM7 Shared RAM Write: %04x = %08x (%08x) (%06x)\n", offset << 2, data, mem_mask, cpu_get_pc(&space->device()));
|
||||
COMBINE_DATA(&state->m_arm7_shareram[offset]);
|
||||
}
|
||||
|
||||
static READ16_HANDLER( arm7_latch_68k_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("M68K: Latch read: %04x (%04x) (%06x)\n", state->m_kov2_latchdata_arm_w & 0x0000ffff, mem_mask, cpu_get_pc(&space->device()));
|
||||
return state->m_kov2_latchdata_arm_w;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( arm7_latch_68k_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("M68K: Latch write: %04x (%04x) (%06x)\n", data & 0x0000ffff, mem_mask, cpu_get_pc(&space->device()));
|
||||
COMBINE_DATA(&state->m_kov2_latchdata_68k_w);
|
||||
|
||||
device_set_input_line(state->m_prot, ARM7_FIRQ_LINE, ASSERT_LINE ); // guess
|
||||
}
|
||||
|
||||
static READ16_HANDLER( arm7_ram_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
UINT16 *share16 = (UINT16 *)state->m_arm7_shareram;
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("M68K: ARM7 Shared RAM Read: %04x = %04x (%08x) (%06x)\n", BYTE_XOR_LE(offset), share16[BYTE_XOR_LE(offset)], mem_mask, cpu_get_pc(&space->device()));
|
||||
return share16[BYTE_XOR_LE(offset)];
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( arm7_ram_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
UINT16 *share16 = (UINT16 *)state->m_arm7_shareram;
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("M68K: ARM7 Shared RAM Write: %04x = %04x (%04x) (%06x)\n", BYTE_XOR_LE(offset), data, mem_mask, cpu_get_pc(&space->device()));
|
||||
COMBINE_DATA(&share16[BYTE_XOR_LE(offset)]);
|
||||
}
|
||||
|
||||
/* 55857F? */
|
||||
/* Knights of Valor 2, Martial Masters, DoDonpachi 2 */
|
||||
/* no execute only space? */
|
||||
static ADDRESS_MAP_START( kov2_mem, AS_PROGRAM, 16)
|
||||
AM_IMPORT_FROM(pgm_mem)
|
||||
AM_RANGE(0x100000, 0x5fffff) AM_ROMBANK("bank1") /* Game ROM */
|
||||
AM_RANGE(0xd00000, 0xd0ffff) AM_READWRITE(arm7_ram_r, arm7_ram_w) /* ARM7 Shared RAM */
|
||||
AM_RANGE(0xd10000, 0xd10001) AM_READWRITE(arm7_latch_68k_r, arm7_latch_68k_w) /* ARM7 Latch */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( 55857F_arm7_map, AS_PROGRAM, 32 )
|
||||
AM_RANGE(0x00000000, 0x00003fff) AM_ROM
|
||||
AM_RANGE(0x08000000, 0x083fffff) AM_ROM AM_REGION("user1", 0)
|
||||
AM_RANGE(0x10000000, 0x100003ff) AM_RAM
|
||||
AM_RANGE(0x18000000, 0x1800ffff) AM_RAM AM_BASE_MEMBER(pgm_state, m_arm_ram)
|
||||
AM_RANGE(0x38000000, 0x38000003) AM_READWRITE(arm7_latch_arm_r, arm7_latch_arm_w) /* 68k Latch */
|
||||
AM_RANGE(0x48000000, 0x4800ffff) AM_READWRITE(arm7_shareram_r, arm7_shareram_w) AM_BASE_MEMBER(pgm_state, m_arm7_shareram)
|
||||
AM_RANGE(0x50000000, 0x500003ff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/******* ARM 55857F *******/
|
||||
|
||||
MACHINE_CONFIG_DERIVED( kov2, pgm )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(kov2_mem)
|
||||
|
||||
/* protection CPU */
|
||||
MCFG_CPU_ADD("prot", ARM7, 20000000) // 55857F
|
||||
MCFG_CPU_PROGRAM_MAP(55857F_arm7_map)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
|
||||
|
||||
static void kov2_latch_init( running_machine &machine )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
state->m_kov2_latchdata_68k_w = 0;
|
||||
state->m_kov2_latchdata_arm_w = 0;
|
||||
|
||||
state->save_item(NAME(state->m_kov2_latchdata_68k_w));
|
||||
state->save_item(NAME(state->m_kov2_latchdata_arm_w));
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( kov2_arm_region_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
int regionhack = input_port_read(space->machine(), "RegionHack");
|
||||
if (pc==0x190 && regionhack != 0xff) data = (data & 0xffff0000) | (regionhack << 0);
|
||||
COMBINE_DATA(&state->m_arm7_shareram[0x138/4]);
|
||||
}
|
||||
|
||||
DRIVER_INIT( kov2 )
|
||||
{
|
||||
pgm_basic_init(machine);
|
||||
pgm_kov2_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
|
||||
// we only have a HK internal ROM dumped for now, allow us to override that for debugging purposes.
|
||||
machine.device("prot")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x48000138, 0x4800013b, FUNC(kov2_arm_region_w));
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT( kov2p )
|
||||
{
|
||||
// this hacks the identification of the kov2 rom to return the string required for kov2p
|
||||
// this isn't guaranteed to work properly (and definitely wouldn't on real hardware due to the internal
|
||||
// ROM uploading the encryption table) The internal ROM should be dumped properly.
|
||||
pgm_basic_init(machine);
|
||||
pgm_kov2p_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
|
||||
UINT8 *mem8 = (UINT8 *)machine.region("user1")->base();
|
||||
mem8[0xDE] = 0xC0;
|
||||
mem8[0xDF] = 0x46;
|
||||
mem8[0x4ED8] = 0xA8;// B0
|
||||
mem8[0x4EDC] = 0x9C;// A4
|
||||
mem8[0x4EE0] = 0x5C;// 64
|
||||
mem8[0x4EE4] = 0x94;// 9C
|
||||
mem8[0x4EE8] = 0xE8;// F0
|
||||
mem8[0x4EEC] = 0x6C;// 74
|
||||
mem8[0x4EF0] = 0xD4;// DC
|
||||
mem8[0x4EF4] = 0x50;// 58
|
||||
mem8[0x4EF8] = 0x80;// 88
|
||||
mem8[0x4EFC] = 0x9C;// A4
|
||||
mem8[0x4F00] = 0x28;// 30
|
||||
mem8[0x4F04] = 0x30;// 38
|
||||
mem8[0x4F08] = 0x34;// 3C
|
||||
mem8[0x4F0C] = 0x1C;// 24
|
||||
mem8[0x1FFFFC] = 0x33;
|
||||
mem8[0x1FFFFD] = 0x99;
|
||||
|
||||
// we only have a HK internal ROM dumped for now, allow us to override that for debugging purposes.
|
||||
machine.device("prot")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x48000138, 0x4800013b, FUNC(kov2_arm_region_w));
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( martmast_arm_region_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
int regionhack = input_port_read(space->machine(), "RegionHack");
|
||||
if (pc==0x170 && regionhack != 0xff) data = (data & 0xffff0000) | (regionhack << 0);
|
||||
COMBINE_DATA(&state->m_arm7_shareram[0x138/4]);
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT( martmast )
|
||||
{
|
||||
pgm_basic_init(machine);
|
||||
pgm_mm_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
|
||||
// we only have a USA / CHINA internal ROMs dumped for now, allow us to override that for debugging purposes.
|
||||
machine.device("prot")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x48000138, 0x4800013b, FUNC(martmast_arm_region_w));
|
||||
}
|
||||
|
||||
|
||||
static WRITE32_HANDLER( ddp2_arm_region_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
int regionhack = input_port_read(space->machine(), "RegionHack");
|
||||
if (pc==0x0174 && regionhack != 0xff) data = (data & 0x0000ffff) | (regionhack << 16);
|
||||
COMBINE_DATA(&state->m_arm7_shareram[0x0]);
|
||||
}
|
||||
|
||||
static READ32_HANDLER( ddp2_speedup_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
UINT32 data = state->m_arm_ram[0x300c/4];
|
||||
|
||||
if (pc==0x080109b4)
|
||||
{
|
||||
/* if we've hit the loop where this is read and both values are 0 then the only way out is an interrupt */
|
||||
int r4 = (cpu_get_reg(&space->device(), ARM7_R4));
|
||||
r4 += 0xe;
|
||||
|
||||
if (r4==0x18002f9e)
|
||||
{
|
||||
UINT32 data2 = state->m_arm_ram[0x2F9C/4]&0xffff0000;
|
||||
if ((data==0x00000000) && (data2==0x00000000)) device_spin_until_interrupt(&space->device());
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static READ16_HANDLER( ddp2_main_speedup_r )
|
||||
{
|
||||
|
||||
UINT16 data = pgm_mainram[0x0ee54/2];
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
|
||||
if (pc == 0x149dce) device_spin_until_interrupt(&space->device());
|
||||
if (pc == 0x149cfe) device_spin_until_interrupt(&space->device());
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
DRIVER_INIT( ddp2 )
|
||||
{
|
||||
pgm_basic_init(machine);
|
||||
pgm_ddp2_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
|
||||
// we only have a Japan internal ROM dumped for now, allow us to override that for debugging purposes.
|
||||
machine.device("prot")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x48000000, 0x48000003, FUNC(ddp2_arm_region_w));
|
||||
|
||||
machine.device("prot")->memory().space(AS_PROGRAM)->install_legacy_read_handler(0x1800300c, 0x1800300f, FUNC(ddp2_speedup_r));
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_read_handler(0x80ee54, 0x80ee55, FUNC(ddp2_main_speedup_r));
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT( dw2001 )
|
||||
{
|
||||
//pgm_state *state = machine.driver_data<pgm_state>();
|
||||
UINT16 *mem16 = (UINT16 *)machine.region("maincpu")->base();
|
||||
|
||||
pgm_basic_init(machine);
|
||||
kov2_latch_init(machine);
|
||||
pgm_mm_decrypt(machine); // encryption is the same as martial masters
|
||||
|
||||
mem16[0x11e90c / 2] = 0x4e71;
|
||||
mem16[0x11e90e / 2] = 0x4e71;
|
||||
|
||||
mem16[0x11e91a / 2] = 0x4e71;
|
||||
|
||||
mem16[0x11eaf6 / 2] = 0x4e71;
|
||||
mem16[0x11eaf8 / 2] = 0x4e71;
|
||||
|
||||
mem16[0x11eb04 / 2] = 0x4e71;
|
||||
|
||||
/* patch ARM area with fake code */
|
||||
UINT16 *temp16 = (UINT16 *)machine.region("prot")->base();
|
||||
temp16[(0x0000)/2] = 0xd088;
|
||||
temp16[(0x0002)/2] = 0xe59f;
|
||||
temp16[(0x0004)/2] = 0x0680;
|
||||
temp16[(0x0006)/2] = 0xe3a0;
|
||||
temp16[(0x0008)/2] = 0x0001;
|
||||
temp16[(0x000a)/2] = 0xe280;
|
||||
temp16[(0x000c)/2] = 0xff10;
|
||||
temp16[(0x000e)/2] = 0xe12f;
|
||||
|
||||
temp16[(0x0090)/2] = 0x0400;
|
||||
temp16[(0x0092)/2] = 0x1000;
|
||||
|
||||
}
|
||||
|
||||
INPUT_PORTS_START( ddp2 )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_START("RegionHack") /* Region - actually supplied by protection device */
|
||||
PORT_CONFNAME( 0x00ff, 0x00ff, DEF_STR( Region ) )
|
||||
PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
|
||||
PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
|
||||
PORT_CONFSETTING( 0x0002, "Japan (Cave license)" )
|
||||
PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
|
||||
PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
|
||||
PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
|
||||
PORT_CONFSETTING( 0x00ff, "Untouched" ) // don't hack the region
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( kov2 )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_START("RegionHack") /* Region - actually supplied by protection device */
|
||||
PORT_CONFNAME( 0x00ff, 0x00ff, DEF_STR( Region ) )
|
||||
PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
|
||||
PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
|
||||
PORT_CONFSETTING( 0x0002, "Japan (Cave license)" )
|
||||
PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
|
||||
PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
|
||||
PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
|
||||
PORT_CONFSETTING( 0x00ff, "Untouched" ) // don't hack the region
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( martmast )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_START("RegionHack") /* Region - actually supplied by protection device */
|
||||
PORT_CONFNAME( 0x00ff, 0x00ff, DEF_STR( Region ) )
|
||||
PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
|
||||
PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
|
||||
PORT_CONFSETTING( 0x0002, DEF_STR( Japan ) )
|
||||
PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
|
||||
PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
|
||||
PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
|
||||
PORT_CONFSETTING( 0x0006, DEF_STR( USA ) )
|
||||
PORT_CONFSETTING( 0x00ff, "Untouched" ) // don't hack the region
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( dw2001 )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_MODIFY("Region") /* Region - supplied by protection device */
|
||||
PORT_CONFNAME( 0x000f, 0x0005, DEF_STR( Region ) )
|
||||
PORT_CONFSETTING( 0x0000, DEF_STR( China ) )
|
||||
PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
|
||||
PORT_CONFSETTING( 0x0002, "Japan (Alta license)" )
|
||||
PORT_CONFSETTING( 0x0003, DEF_STR( Korea ) )
|
||||
PORT_CONFSETTING( 0x0004, DEF_STR( Hong_Kong ) )
|
||||
PORT_CONFSETTING( 0x0005, DEF_STR( World ) )
|
||||
INPUT_PORTS_END
|
298
src/mame/machine/pgmprot3.c
Normal file
298
src/mame/machine/pgmprot3.c
Normal file
@ -0,0 +1,298 @@
|
||||
/***********************************************************************
|
||||
PGM IGA027A (55857G type) ARM protection emulation
|
||||
|
||||
these are emulation of the 'dmnfrnt' type ARM device
|
||||
used by
|
||||
|
||||
Demon Front (dmnfrnt) *1
|
||||
The Gladiator (theglad)
|
||||
Spectral vs. Generation (svg)
|
||||
Happy 6-in-1 (happy6)
|
||||
The Killing Blade Plus (killbldp) *2
|
||||
|
||||
None of these work at all, with the following exception.
|
||||
|
||||
*1 - We bypass the internal ROM entirely! Game doesn't jump back
|
||||
*2 - Partial dump of the internal ROM is used, but 'Execute Only' region is missing
|
||||
|
||||
----
|
||||
|
||||
These games use a large amount of shared RAM which is banked between CPUs
|
||||
|
||||
----
|
||||
|
||||
All of these games have an external ARM rom.
|
||||
|
||||
The internal ROMs contain an 'execute only' region at the start of the
|
||||
ROM which prevents reading out.
|
||||
|
||||
IGS027A type 55857G has also been seen on various IGS gambling boards
|
||||
as the main CPU (eg. Haunted House, see igs_m027a)
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/pgm.h"
|
||||
|
||||
static WRITE32_HANDLER( svg_arm7_ram_sel_w )
|
||||
{
|
||||
// printf("svg_arm7_ram_sel_w %08x\n", data);
|
||||
space->machine().scheduler().synchronize(); // force resync
|
||||
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
state->m_svg_ram_sel = data & 1;
|
||||
}
|
||||
|
||||
static READ32_HANDLER( svg_arm7_shareram_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
return state->m_svg_shareram[state->m_svg_ram_sel & 1][offset];
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( svg_arm7_shareram_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
COMBINE_DATA(&state->m_svg_shareram[state->m_svg_ram_sel & 1][offset]);
|
||||
}
|
||||
|
||||
static READ16_HANDLER( svg_m68k_ram_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int ram_sel = (state->m_svg_ram_sel & 1) ^ 1;
|
||||
UINT16 *share16 = (UINT16 *)(state->m_svg_shareram[ram_sel & 1]);
|
||||
|
||||
return share16[BYTE_XOR_LE(offset)];
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( svg_m68k_ram_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int ram_sel = (state->m_svg_ram_sel & 1) ^ 1;
|
||||
UINT16 *share16 = (UINT16 *)(state->m_svg_shareram[ram_sel & 1]);
|
||||
|
||||
COMBINE_DATA(&share16[BYTE_XOR_LE(offset)]);
|
||||
}
|
||||
|
||||
static READ16_HANDLER( svg_68k_nmi_r )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( svg_68k_nmi_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
generic_pulse_irq_line(state->m_prot, ARM7_FIRQ_LINE, 1);
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( svg_latch_68k_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("M68K: Latch write: %04x (%04x) (%06x)\n", data & 0x0000ffff, mem_mask, cpu_get_pc(&space->device()));
|
||||
COMBINE_DATA(&state->m_kov2_latchdata_68k_w);
|
||||
}
|
||||
|
||||
|
||||
static READ16_HANDLER( svg_latch_68k_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("M68K: Latch read: %04x (%04x) (%06x)\n", state->m_kov2_latchdata_arm_w & 0x0000ffff, mem_mask, cpu_get_pc(&space->device()));
|
||||
return state->m_kov2_latchdata_arm_w;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static READ32_HANDLER( svg_latch_arm_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("ARM7: Latch read: %08x (%08x) (%06x)\n", state->m_kov2_latchdata_68k_w, mem_mask, cpu_get_pc(&space->device()));
|
||||
return state->m_kov2_latchdata_68k_w;
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( svg_latch_arm_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
if (PGMARM7LOGERROR)
|
||||
logerror("ARM7: Latch write: %08x (%08x) (%06x)\n", data, mem_mask, cpu_get_pc(&space->device()));
|
||||
|
||||
COMBINE_DATA(&state->m_kov2_latchdata_arm_w);
|
||||
}
|
||||
|
||||
/* 55857G? */
|
||||
/* Demon Front, The Gladiator, Happy 6-in-1, Spectral Vs. Generation, Killing Blade EX */
|
||||
/* the ones with an EXECUTE ONLY region of ARM space? */
|
||||
static ADDRESS_MAP_START( svg_68k_mem, AS_PROGRAM, 16)
|
||||
AM_IMPORT_FROM(pgm_mem)
|
||||
AM_RANGE(0x100000, 0x1fffff) AM_ROMBANK("bank1") /* Game ROM */
|
||||
|
||||
AM_RANGE(0x500000, 0x51ffff) AM_READWRITE(svg_m68k_ram_r, svg_m68k_ram_w) /* ARM7 Shared RAM */
|
||||
AM_RANGE(0x5c0000, 0x5c0001) AM_READWRITE(svg_68k_nmi_r, svg_68k_nmi_w) /* ARM7 FIQ */
|
||||
AM_RANGE(0x5c0300, 0x5c0301) AM_READWRITE(svg_latch_68k_r, svg_latch_68k_w) /* ARM7 Latch */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( 55857G_arm7_map, AS_PROGRAM, 32 )
|
||||
AM_RANGE(0x00000000, 0x00003fff) AM_ROM
|
||||
AM_RANGE(0x08000000, 0x087fffff) AM_ROM AM_REGION("user1", 0)
|
||||
AM_RANGE(0x10000000, 0x100003ff) AM_RAM
|
||||
AM_RANGE(0x18000000, 0x1803ffff) AM_RAM AM_BASE_MEMBER(pgm_state, m_arm_ram)
|
||||
AM_RANGE(0x38000000, 0x3801ffff) AM_READWRITE(svg_arm7_shareram_r, svg_arm7_shareram_w)
|
||||
AM_RANGE(0x48000000, 0x48000003) AM_READWRITE(svg_latch_arm_r, svg_latch_arm_w) /* 68k Latch */
|
||||
AM_RANGE(0x40000018, 0x4000001b) AM_WRITE(svg_arm7_ram_sel_w) /* RAM SEL */
|
||||
AM_RANGE(0x50000000, 0x500003ff) AM_RAM
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/******* ARM 55857G *******/
|
||||
|
||||
MACHINE_CONFIG_DERIVED( svg, pgm )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(svg_68k_mem)
|
||||
|
||||
/* protection CPU */
|
||||
MCFG_CPU_ADD("prot", ARM7, 33333333) // 55857G
|
||||
MCFG_CPU_PROGRAM_MAP(55857G_arm7_map)
|
||||
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
|
||||
static void svg_basic_init(running_machine &machine)
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
pgm_basic_init(machine);
|
||||
state->m_svg_shareram[0] = auto_alloc_array(machine, UINT32, 0x10000 / 4);
|
||||
state->m_svg_shareram[1] = auto_alloc_array(machine, UINT32, 0x10000 / 4);
|
||||
state->m_svg_ram_sel = 0;
|
||||
|
||||
state->save_pointer(NAME(state->m_svg_shareram[0]), 0x10000 / 4);
|
||||
state->save_pointer(NAME(state->m_svg_shareram[1]), 0x10000 / 4);
|
||||
state->save_item(NAME(state->m_svg_ram_sel));
|
||||
}
|
||||
|
||||
static void pgm_create_dummy_internal_arm_region(running_machine &machine)
|
||||
{
|
||||
UINT16 *temp16 = (UINT16 *)machine.region("prot")->base();
|
||||
|
||||
// fill with RX 14
|
||||
int i;
|
||||
for (i=0;i<0x4000/2;i+=2)
|
||||
{
|
||||
temp16[i] = 0xff1e;
|
||||
temp16[i+1] = 0xe12f;
|
||||
|
||||
}
|
||||
|
||||
// jump straight to external area
|
||||
temp16[(0x0000)/2] = 0xd088;
|
||||
temp16[(0x0002)/2] = 0xe59f;
|
||||
temp16[(0x0004)/2] = 0x0680;
|
||||
temp16[(0x0006)/2] = 0xe3a0;
|
||||
temp16[(0x0008)/2] = 0xff10;
|
||||
temp16[(0x000a)/2] = 0xe12f;
|
||||
temp16[(0x0090)/2] = 0x0400;
|
||||
temp16[(0x0092)/2] = 0x1000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void kov2_latch_init( running_machine &machine )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
state->m_kov2_latchdata_68k_w = 0;
|
||||
state->m_kov2_latchdata_arm_w = 0;
|
||||
|
||||
state->save_item(NAME(state->m_kov2_latchdata_68k_w));
|
||||
state->save_item(NAME(state->m_kov2_latchdata_arm_w));
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT( theglad )
|
||||
{
|
||||
svg_basic_init(machine);
|
||||
pgm_theglad_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
DRIVER_INIT( svg )
|
||||
{
|
||||
svg_basic_init(machine);
|
||||
pgm_svg_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
DRIVER_INIT( svgpcb )
|
||||
{
|
||||
svg_basic_init(machine);
|
||||
pgm_svgpcb_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
||||
|
||||
DRIVER_INIT( killbldp )
|
||||
{
|
||||
svg_basic_init(machine);
|
||||
pgm_killbldp_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
}
|
||||
|
||||
static READ32_HANDLER( dmnfrnt_speedup_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
if (pc == 0x8000fea) device_eat_cycles(&space->device(), 500);
|
||||
// else printf("dmn_speedup_r %08x\n", pc);
|
||||
return state->m_arm_ram[0x000444/4];
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dmnfrnt_main_speedup_r )
|
||||
{
|
||||
UINT16 data = pgm_mainram[0xa03c/2];
|
||||
int pc = cpu_get_pc(&space->device());
|
||||
if (pc == 0x10193a) device_spin_until_interrupt(&space->device());
|
||||
else if (pc == 0x1019a4) device_spin_until_interrupt(&space->device());
|
||||
return data;
|
||||
}
|
||||
|
||||
DRIVER_INIT( dmnfrnt )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
svg_basic_init(machine);
|
||||
pgm_dfront_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
|
||||
/* put some fake code for the ARM here ... */
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
|
||||
machine.device("prot")->memory().space(AS_PROGRAM)->install_legacy_read_handler(0x18000444, 0x18000447, FUNC(dmnfrnt_speedup_r));
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_read_handler(0x80a03c, 0x80a03d, FUNC(dmnfrnt_main_speedup_r));
|
||||
|
||||
state->m_svg_ram_sel = 1;
|
||||
|
||||
// the internal rom probably also supplies the region here
|
||||
// we have to copy it to both shared ram regions because it reads from a different one before the attract story?
|
||||
// could be a timing error? or shared ram behavior isn't how we think it is?
|
||||
UINT16 *share16;
|
||||
share16 = (UINT16 *)(state->m_svg_shareram[1]);
|
||||
share16[0x158/2] = 0x0005;
|
||||
share16 = (UINT16 *)(state->m_svg_shareram[0]);
|
||||
share16[0x158/2] = 0x0005;
|
||||
}
|
||||
|
||||
DRIVER_INIT( happy6 )
|
||||
{
|
||||
svg_basic_init(machine);
|
||||
pgm_happy6_decrypt(machine);
|
||||
kov2_latch_init(machine);
|
||||
pgm_create_dummy_internal_arm_region(machine);
|
||||
}
|
608
src/mame/machine/pgmprot4.c
Normal file
608
src/mame/machine/pgmprot4.c
Normal file
@ -0,0 +1,608 @@
|
||||
/***********************************************************************
|
||||
PGM 022 + 025 PGM protection emulation
|
||||
|
||||
these are simulations of the IGS 022 and 025 protection combination
|
||||
used on the following PGM games
|
||||
|
||||
The Killing Blade
|
||||
Dragon World 3*
|
||||
Dragon World 3 EX*
|
||||
|
||||
* preliminary, not working
|
||||
|
||||
----
|
||||
|
||||
IGS022 is an encrypted DMA device, most likely an MCU of some sort
|
||||
|
||||
IGS025 is some kind of state machine / logic device which the game
|
||||
uses for various securit checks, and to determine the region of the
|
||||
game based on string sequences.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/pgm.h"
|
||||
|
||||
/* The IGS022 is an MCU which performs encrypted DMA used by
|
||||
- The Killing Blade
|
||||
- Dragon World 3
|
||||
|
||||
There is also an automatic transfer which happens on startup using params stored in the data ROM.
|
||||
This has been verified on real hardware running without any 68k game program.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static void IGS022_do_dma(running_machine& machine, UINT16 src, UINT16 dst, UINT16 size, UINT16 mode)
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
UINT16 param;
|
||||
/*
|
||||
P_SRC =0x300290 (offset from prot rom base)
|
||||
P_DST =0x300292 (words from 0x300000)
|
||||
P_SIZE=0x300294 (words)
|
||||
P_MODE=0x300296
|
||||
|
||||
Mode 5 direct
|
||||
Mode 6 swap nibbles and bytes
|
||||
|
||||
1,2,3 table based ops
|
||||
*/
|
||||
|
||||
//mame_printf_debug("src %04x dst %04x size %04x mode %04x\n", src, dst, size, mode);
|
||||
|
||||
//if (src&1) mame_printf_debug("odd offset\n");
|
||||
|
||||
param = mode >> 8;
|
||||
mode &=0xf; // what are the other bits?
|
||||
|
||||
|
||||
if ((mode == 0) || (mode == 1) || (mode == 2) || (mode == 3))
|
||||
{
|
||||
/* mode3 applies a xor from a 0x100 byte table to the data being
|
||||
transferred
|
||||
|
||||
the table is stored at the start of the protection rom.
|
||||
|
||||
the param used with the mode gives a start offset into the table
|
||||
|
||||
odd offsets seem to change the table slightly (see rawDataOdd)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
unsigned char rawDataOdd[256] = {
|
||||
0xB6, 0xA8, 0xB1, 0x5D, 0x2C, 0x5D, 0x4F, 0xC1,
|
||||
0xCF, 0x39, 0x3A, 0xB7, 0x65, 0x85, 0xD9, 0xEE,
|
||||
0xDB, 0x7B, 0x5F, 0x81, 0x03, 0x6D, 0xEB, 0x07,
|
||||
0x0F, 0xB5, 0x61, 0x59, 0xCD, 0x60, 0x06, 0x21,
|
||||
0xA0, 0x99, 0xDD, 0x27, 0x42, 0xD7, 0xC5, 0x5B,
|
||||
0x3B, 0xC6, 0x4F, 0xA2, 0x20, 0xF6, 0x61, 0x61,
|
||||
0x8C, 0x46, 0x8C, 0xCA, 0xE0, 0x0E, 0x2C, 0xE9,
|
||||
0xBA, 0x0F, 0x45, 0x6D, 0x36, 0x1C, 0x18, 0x37,
|
||||
0xE7, 0x85, 0x89, 0xA4, 0x94, 0x46, 0x30, 0x9B,
|
||||
0xB2, 0xF4, 0x41, 0x55, 0xA5, 0x63, 0x1C, 0xEF,
|
||||
0xB7, 0x18, 0xB3, 0xB1, 0xD4, 0x72, 0xA0, 0x1C,
|
||||
0x0B, 0x97, 0x02, 0xB6, 0xC5, 0x1F, 0x1B, 0x94,
|
||||
0xC3, 0x83, 0xAA, 0xAC, 0xD9, 0x44, 0x09, 0xD7,
|
||||
0x6C, 0xDB, 0x07, 0xA9, 0xAD, 0x64, 0x83, 0xF1,
|
||||
0x92, 0x09, 0xCD, 0x0E, 0x99, 0x2F, 0xBC, 0xF8,
|
||||
0x3C, 0x63, 0x8F, 0x0A, 0x33, 0x03, 0x84, 0x91,
|
||||
0x6C, 0xAC, 0x3A, 0x15, 0xCB, 0x67, 0xC7, 0x69,
|
||||
0xA1, 0x92, 0x99, 0x74, 0xEE, 0x90, 0x0D, 0xBE,
|
||||
0x57, 0x30, 0xD1, 0xBA, 0xE5, 0xDE, 0xFA, 0xD6,
|
||||
0x83, 0x8C, 0xE4, 0x43, 0x36, 0x5E, 0xCD, 0x84,
|
||||
0x1A, 0x18, 0x31, 0xB9, 0x20, 0x48, 0xE3, 0xA8,
|
||||
0x89, 0x32, 0xF0, 0x90, 0x21, 0x80, 0x33, 0xAE,
|
||||
0x3C, 0xA6, 0xB8, 0x8C, 0x72, 0x17, 0xD1, 0x0C,
|
||||
0x1A, 0x29, 0xFA, 0x38, 0x87, 0xC9, 0x6E, 0xC7,
|
||||
0x05, 0xDE, 0x85, 0x6E, 0x92, 0x7E, 0xD4, 0xED,
|
||||
0x5C, 0xD3, 0x03, 0xD4, 0xFE, 0xCB, 0x6C, 0x19,
|
||||
0x7A, 0x83, 0x79, 0x5B, 0xF6, 0x71, 0xBA, 0xF4,
|
||||
0x37, 0x53, 0xC9, 0xC1, 0xDE, 0xDB, 0xDE, 0xB1,
|
||||
0x64, 0x17, 0x31, 0x0E, 0xD7, 0xA2, 0x13, 0x8E,
|
||||
0x52, 0x8D, 0xCB, 0x19, 0x3D, 0x0B, 0x31, 0x58,
|
||||
0x4A, 0xDE, 0x0C, 0x01, 0x2B, 0x85, 0x2D, 0xE5,
|
||||
0x13, 0x22, 0x48, 0xB6, 0xF3, 0x2D, 0x00, 0x9A
|
||||
};
|
||||
*/
|
||||
int x;
|
||||
UINT16 *PROTROM = (UINT16*)machine.region("igs022data")->base();
|
||||
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
//UINT16 *RAMDUMP = (UINT16*)space->machine().region("user2")->base();
|
||||
//UINT16 dat = RAMDUMP[dst + x];
|
||||
|
||||
UINT16 dat2 = PROTROM[src + x];
|
||||
|
||||
UINT8 extraoffset = param&0xfe; // the lowest bit changed the table addressing in tests, see 'rawDataOdd' table instead.. it's still related to the main one, not identical
|
||||
UINT8* dectable = (UINT8*)machine.region("igs022data")->base();//rawDataEven; // the basic decryption table is at the start of the mcu data rom! at least in killbld
|
||||
UINT16 extraxor = ((dectable[((x*2)+0+extraoffset)&0xff]) << 8) | (dectable[((x*2)+1+extraoffset)&0xff] << 0);
|
||||
|
||||
dat2 = ((dat2 & 0x00ff)<<8) | ((dat2 & 0xff00)>>8);
|
||||
|
||||
// mode==0 plain
|
||||
if (mode==3) dat2 ^= extraxor;
|
||||
if (mode==2) dat2 += extraxor;
|
||||
if (mode==1) dat2 -= extraxor;
|
||||
|
||||
//if (dat!=dat2)
|
||||
// printf("Mode %04x Param %04x Mismatch %04x %04x\n", mode, param, dat, dat2);
|
||||
|
||||
state->m_sharedprotram[dst + x] = dat2;
|
||||
}
|
||||
|
||||
/* Killing Blade: hack, patches out some additional security checks... we need to emulate them instead! */
|
||||
// different region IGS025 devices supply different sequences - we currently only have the china sequence for Killing Blade
|
||||
//if ((mode==3) && (param==0x54) && (src*2==0x2120) && (dst*2==0x2600)) state->m_sharedprotram[0x2600 / 2] = 0x4e75;
|
||||
|
||||
}
|
||||
if (mode == 4)
|
||||
{
|
||||
mame_printf_debug("unhandled copy mode %04x!\n", mode);
|
||||
// not used by killing blade
|
||||
/* looks almost like a fixed value xor, but isn't */
|
||||
}
|
||||
else if (mode == 5)
|
||||
{
|
||||
/* mode 5 seems to be a straight copy */
|
||||
int x;
|
||||
UINT16 *PROTROM = (UINT16*)machine.region("igs022data")->base();
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
UINT16 dat = PROTROM[src + x];
|
||||
|
||||
|
||||
state->m_sharedprotram[dst + x] = dat;
|
||||
}
|
||||
}
|
||||
else if (mode == 6)
|
||||
{
|
||||
/* mode 6 seems to swap bytes and nibbles */
|
||||
int x;
|
||||
UINT16 *PROTROM = (UINT16*)machine.region("igs022data")->base();
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
UINT16 dat = PROTROM[src + x];
|
||||
|
||||
dat = ((dat & 0xf000) >> 12)|
|
||||
((dat & 0x0f00) >> 4)|
|
||||
((dat & 0x00f0) << 4)|
|
||||
((dat & 0x000f) << 12);
|
||||
|
||||
state->m_sharedprotram[dst + x] = dat;
|
||||
}
|
||||
}
|
||||
else if (mode == 7)
|
||||
{
|
||||
mame_printf_debug("unhandled copy mode %04x!\n", mode);
|
||||
// not used by killing blade
|
||||
/* weird mode, the params get left in memory? - maybe it's a NOP? */
|
||||
}
|
||||
else
|
||||
{
|
||||
mame_printf_debug("unhandled copy mode %04x!\n", mode);
|
||||
// not used by killing blade
|
||||
/* invalid? */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// the internal MCU boot code automatically does this DMA
|
||||
// and puts the version # of the data rom in ram
|
||||
static void IGS022_reset(running_machine& machine)
|
||||
{
|
||||
int i;
|
||||
UINT16 *PROTROM = (UINT16*)machine.region("igs022data")->base();
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
UINT16 tmp;
|
||||
|
||||
// fill ram with A5 patern
|
||||
for (i = 0; i < 0x4000/2; i++)
|
||||
state->m_sharedprotram[i] = 0xa55a;
|
||||
|
||||
// the auto-dma
|
||||
UINT16 src = PROTROM[0x100 / 2];
|
||||
UINT32 dst = PROTROM[0x102 / 2];
|
||||
UINT16 size = PROTROM[0x104/ 2];
|
||||
UINT16 mode = PROTROM[0x106 / 2];
|
||||
|
||||
src = ((src & 0xff00) >> 8) | ((src & 0x00ff) << 8);
|
||||
dst = ((dst & 0xff00) >> 8) | ((dst & 0x00ff) << 8);
|
||||
size = ((size & 0xff00) >> 8) | ((size & 0x00ff) << 8);
|
||||
mode &= 0xff;
|
||||
|
||||
src >>= 1;
|
||||
|
||||
printf("Auto-DMA %04x %04x %04x %04x\n",src,dst,size,mode);
|
||||
|
||||
IGS022_do_dma(machine,src,dst,size,mode);
|
||||
|
||||
// there is also a version ID? (or is it some kind of checksum) that is stored in the data rom, and gets copied..
|
||||
// Dragon World 3 checks it
|
||||
tmp = PROTROM[0x114/2];
|
||||
tmp = ((tmp & 0xff00) >> 8) | ((tmp & 0x00ff) << 8);
|
||||
state->m_sharedprotram[0x2a2/2] = tmp;
|
||||
}
|
||||
|
||||
static void IGS022_handle_command(running_machine& machine)
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
UINT16 cmd = state->m_sharedprotram[0x200/2];
|
||||
//mame_printf_debug("command %04x\n", cmd);
|
||||
if (cmd == 0x6d) //Store values to asic ram
|
||||
{
|
||||
UINT32 p1 = (state->m_sharedprotram[0x298/2] << 16) | state->m_sharedprotram[0x29a/2];
|
||||
UINT32 p2 = (state->m_sharedprotram[0x29c/2] << 16) | state->m_sharedprotram[0x29e/2];
|
||||
|
||||
if ((p2 & 0xffff) == 0x9) //Set value
|
||||
{
|
||||
int reg = (p2 >> 16) & 0xffff;
|
||||
if (reg & 0x200)
|
||||
state->m_kb_regs[reg & 0xff] = p1;
|
||||
}
|
||||
if ((p2 & 0xffff) == 0x6) //Add value
|
||||
{
|
||||
int src1 = (p1 >> 16) & 0xff;
|
||||
int src2 = (p1 >> 0) & 0xff;
|
||||
int dst = (p2 >> 16) & 0xff;
|
||||
state->m_kb_regs[dst] = state->m_kb_regs[src2] - state->m_kb_regs[src1];
|
||||
}
|
||||
if ((p2 & 0xffff) == 0x1) //Add Imm?
|
||||
{
|
||||
int reg = (p2 >> 16) & 0xff;
|
||||
int imm = (p1 >> 0) & 0xffff;
|
||||
state->m_kb_regs[reg] += imm;
|
||||
}
|
||||
if ((p2 & 0xffff) == 0xa) //Get value
|
||||
{
|
||||
int reg = (p1 >> 16) & 0xFF;
|
||||
state->m_sharedprotram[0x29c/2] = (state->m_kb_regs[reg] >> 16) & 0xffff;
|
||||
state->m_sharedprotram[0x29e/2] = state->m_kb_regs[reg] & 0xffff;
|
||||
}
|
||||
}
|
||||
if(cmd == 0x4f) //memcpy with encryption / scrambling
|
||||
{
|
||||
UINT16 src = state->m_sharedprotram[0x290 / 2] >> 1; // ?
|
||||
UINT32 dst = state->m_sharedprotram[0x292 / 2];
|
||||
UINT16 size = state->m_sharedprotram[0x294 / 2];
|
||||
UINT16 mode = state->m_sharedprotram[0x296 / 2];
|
||||
|
||||
IGS022_do_dma(machine, src,dst,size,mode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static WRITE16_HANDLER( killbld_igs025_prot_w )
|
||||
{
|
||||
// mame_printf_debug("killbrd prot r\n");
|
||||
// return 0;
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
offset &= 0xf;
|
||||
|
||||
if (offset == 0)
|
||||
state->m_kb_cmd = data;
|
||||
else //offset==2
|
||||
{
|
||||
logerror("%06X: ASIC25 W CMD %X VAL %X\n", cpu_get_pc(&space->device()), state->m_kb_cmd, data);
|
||||
if (state->m_kb_cmd == 0)
|
||||
state->m_kb_reg = data;
|
||||
else if (state->m_kb_cmd == 2)
|
||||
{
|
||||
if (data == 1) //Execute cmd
|
||||
{
|
||||
IGS022_handle_command(space->machine());
|
||||
state->m_kb_reg++;
|
||||
}
|
||||
}
|
||||
else if (state->m_kb_cmd == 4)
|
||||
state->m_kb_ptr = data;
|
||||
else if (state->m_kb_cmd == 0x20)
|
||||
state->m_kb_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( killbld_igs025_prot_r )
|
||||
{
|
||||
// mame_printf_debug("killbld prot w\n");
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
UINT16 res ;
|
||||
|
||||
offset &= 0xf;
|
||||
res = 0;
|
||||
|
||||
if (offset == 1)
|
||||
{
|
||||
if (state->m_kb_cmd == 1)
|
||||
{
|
||||
res = state->m_kb_reg & 0x7f;
|
||||
}
|
||||
else if (state->m_kb_cmd == 5)
|
||||
{
|
||||
|
||||
UINT8 kb_region_sequence[11] = {0x17, 0x14, 0x91, 0x89, 0x21, 0xD5, 0x7C, 0x65, 0x8F, 0x8E, 0xE1};
|
||||
UINT8 ret;
|
||||
|
||||
// this isn't properly understood.. should be some kind of bitswap / xor / shift..based on values written to 0x22/0x23 etc.?
|
||||
// return hardcoded china sequence results for now, avoids rom patch
|
||||
if (state->m_kb_region_sequence_position < 11)
|
||||
{
|
||||
ret = kb_region_sequence[state->m_kb_region_sequence_position];
|
||||
state->m_kb_region_sequence_position++;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 protvalue = 0x89911400 | input_port_read(space->machine(), "Region");
|
||||
ret = (protvalue >> (8 * (state->m_kb_ptr - 1))) & 0xff;
|
||||
}
|
||||
|
||||
res = 0x3f00 | ret; // always 0x3fxx in logged behavior...
|
||||
|
||||
}
|
||||
}
|
||||
logerror("%06X: ASIC25 R CMD %X VAL %X\n", cpu_get_pc(&space->device()), state->m_kb_cmd, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static MACHINE_RESET( killbld )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
MACHINE_RESET_CALL(pgm);
|
||||
/* fill the protection ram with a5 + auto dma */
|
||||
IGS022_reset(machine);
|
||||
|
||||
// Reset IGS025 stuff
|
||||
state->m_kb_cmd = 0;
|
||||
state->m_kb_reg = 0;
|
||||
state->m_kb_ptr = 0;
|
||||
state->m_kb_region_sequence_position = 0;
|
||||
memset(state->m_kb_regs, 0, 0x10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DRIVER_INIT( killbld )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
pgm_basic_init(machine);
|
||||
pgm_killbld_decrypt(machine);
|
||||
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0xd40000, 0xd40003, FUNC(killbld_igs025_prot_r), FUNC(killbld_igs025_prot_w));
|
||||
|
||||
state->m_kb_cmd = 0;
|
||||
state->m_kb_reg = 0;
|
||||
state->m_kb_ptr = 0;
|
||||
state->m_kb_region_sequence_position = 0;
|
||||
memset(state->m_kb_regs, 0, 0x10);
|
||||
|
||||
state->save_item(NAME(state->m_kb_region_sequence_position));
|
||||
state->save_item(NAME(state->m_kb_cmd));
|
||||
state->save_item(NAME(state->m_kb_reg));
|
||||
state->save_item(NAME(state->m_kb_ptr));
|
||||
state->save_item(NAME(state->m_kb_regs));
|
||||
}
|
||||
|
||||
static MACHINE_RESET( dw3 )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
|
||||
MACHINE_RESET_CALL(pgm);
|
||||
/* fill the protection ram with a5 + auto dma */
|
||||
IGS022_reset(machine);
|
||||
|
||||
/* game won't boot unless various values are in protection RAM
|
||||
- these should almost certainly end up there as the result of executing the protection
|
||||
commands are startup, but which, and how? */
|
||||
|
||||
// state->m_sharedprotram[0x200/2] = 0x006d;
|
||||
state->m_sharedprotram[0x202/2] = 0x007c; // it cares about this, operation status flag?
|
||||
|
||||
// state->m_sharedprotram[0x20c/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x20e/2] = 0x0007;
|
||||
// state->m_sharedprotram[0x210/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x212/2] = 0x0004;
|
||||
// state->m_sharedprotram[0x214/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x216/2] = 0x0007;
|
||||
// state->m_sharedprotram[0x218/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x21a/2] = 0x0004;
|
||||
|
||||
// state->m_sharedprotram[0x288/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x28a/2] = 0x00c2;
|
||||
// state->m_sharedprotram[0x28c/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x28e/2] = 0x00c2;
|
||||
// state->m_sharedprotram[0x290/2] = 0x0500;
|
||||
// state->m_sharedprotram[0x292/2] = 0x1000;
|
||||
// state->m_sharedprotram[0x294/2] = 0x00c3;
|
||||
// state->m_sharedprotram[0x296/2] = 0x7104;
|
||||
// state->m_sharedprotram[0x298/2] = 0x0000;
|
||||
// state->m_sharedprotram[0x29a/2] = 0x0003;
|
||||
// state->m_sharedprotram[0x29c/2] = 0x0108;
|
||||
// state->m_sharedprotram[0x29e/2] = 0x0009;
|
||||
|
||||
// state->m_sharedprotram[0x2a2/2] = 0x84f6; // it cares about this, it's the version number of the data rom, copied automatically!
|
||||
|
||||
// state->m_sharedprotram[0x2ac/2] = 0x006d;
|
||||
// state->m_sharedprotram[0x2ae/2] = 0x0000;
|
||||
|
||||
// state->m_sharedprotram[0x2b0/2] = 0xaf56;
|
||||
|
||||
|
||||
// Reset IGS025 stuff
|
||||
state->m_kb_cmd = 0;
|
||||
state->m_kb_reg = 0;
|
||||
state->m_kb_ptr = 0;
|
||||
state->m_kb_region_sequence_position = 0;
|
||||
memset(state->m_kb_regs, 0, 0x10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int reg;
|
||||
static int ptr=0;
|
||||
|
||||
#define DW3BITSWAP(s,d,bs,bd) d=((d&(~(1<<bd)))|(((s>>bs)&1)<<bd))
|
||||
static UINT8 dw3_swap;
|
||||
static WRITE16_HANDLER( drgw3_igs025_prot_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
offset&=0xf;
|
||||
|
||||
if(offset==0)
|
||||
state->m_kb_cmd=data;
|
||||
else //offset==2
|
||||
{
|
||||
printf("%06X: ASIC25 W CMD %X VAL %X\n",cpu_get_pc(&space->device()),state->m_kb_cmd,data);
|
||||
if(state->m_kb_cmd==0)
|
||||
reg=data;
|
||||
else if(state->m_kb_cmd==3) //??????????
|
||||
{
|
||||
dw3_swap = data;
|
||||
|
||||
printf("SWAP %02x\n",dw3_swap);
|
||||
}
|
||||
//else if(kb_cmd==4)
|
||||
// ptr=data;
|
||||
else if(state->m_kb_cmd==0x20)
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( drgw3_igs025_prot_r )
|
||||
{
|
||||
// mame_printf_debug("killbld prot w\n");
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
|
||||
UINT16 res ;
|
||||
|
||||
offset&=0xf;
|
||||
res=0;
|
||||
|
||||
if(offset==1)
|
||||
{
|
||||
if(state->m_kb_cmd==0) //swap
|
||||
{
|
||||
UINT8 v1=(dw3_swap+1)&0x7F;
|
||||
UINT8 v2=0;
|
||||
DW3BITSWAP(v1,v2,7,0);
|
||||
DW3BITSWAP(v1,v2,6,1);
|
||||
DW3BITSWAP(v1,v2,5,2);
|
||||
DW3BITSWAP(v1,v2,4,3);
|
||||
DW3BITSWAP(v1,v2,3,4);
|
||||
DW3BITSWAP(v1,v2,2,5);
|
||||
DW3BITSWAP(v1,v2,1,6);
|
||||
DW3BITSWAP(v1,v2,0,7);
|
||||
|
||||
res=v2;
|
||||
|
||||
}
|
||||
else if(state->m_kb_cmd==1)
|
||||
{
|
||||
res=reg&0x7f;
|
||||
}
|
||||
else if(state->m_kb_cmd==5)
|
||||
{
|
||||
UINT32 protvalue;
|
||||
protvalue = 0x60000|input_port_read(space->machine(), "Region");
|
||||
res=(protvalue>>(8*(ptr-1)))&0xff;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
logerror("%06X: ASIC25 R CMD %X VAL %X\n",cpu_get_pc(&space->device()),state->m_kb_cmd,res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
DRIVER_INIT( drgw3 )
|
||||
{
|
||||
pgm_basic_init(machine);
|
||||
|
||||
/*
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
|
||||
{
|
||||
int x;
|
||||
UINT16 *RAMDUMP = (UINT16*)machine.region("user2")->base();
|
||||
for (x=0;x<(0x4000/2);x++)
|
||||
{
|
||||
state->m_sharedprotram[x] = RAMDUMP[x];
|
||||
if((x>=0x100)&&(x<0x110)) printf("data 0x%4x, offset:%x\n",state->m_sharedprotram[x],x);
|
||||
}
|
||||
}
|
||||
*/
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0xDA5610, 0xDA5613, FUNC(drgw3_igs025_prot_r), FUNC(drgw3_igs025_prot_w));
|
||||
|
||||
pgm_dw3_decrypt(machine);
|
||||
}
|
||||
|
||||
|
||||
static ADDRESS_MAP_START( killbld_mem, AS_PROGRAM, 16)
|
||||
AM_IMPORT_FROM(pgm_mem)
|
||||
AM_RANGE(0x100000, 0x2fffff) AM_ROMBANK("bank1") /* Game ROM */
|
||||
AM_RANGE(0x300000, 0x303fff) AM_RAM AM_BASE_MEMBER(pgm_state, m_sharedprotram) // Shared with protection device
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
|
||||
MACHINE_CONFIG_DERIVED( killbld, pgm )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(killbld_mem)
|
||||
|
||||
MCFG_MACHINE_RESET(killbld)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
MACHINE_CONFIG_DERIVED( dw3, pgm )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(killbld_mem)
|
||||
|
||||
MCFG_MACHINE_RESET(dw3)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( killbld )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_MODIFY("Region") /* Region - supplied by protection device */
|
||||
PORT_DIPNAME( 0x00ff, 0x0021, "Region (not currently working)" ) // different regions supply different protection code sequences, we only have the China one ATM
|
||||
PORT_DIPSETTING( 0x0016, DEF_STR( Taiwan ) )
|
||||
PORT_DIPSETTING( 0x0017, DEF_STR( China ) )
|
||||
PORT_DIPSETTING( 0x0018, DEF_STR( Hong_Kong ) )
|
||||
PORT_DIPSETTING( 0x0019, DEF_STR( Japan ) )
|
||||
// PORT_DIPSETTING( 0x001a, "1a" ) // invalid
|
||||
// PORT_DIPSETTING( 0x001b, "1b" ) // invalid
|
||||
// PORT_DIPSETTING( 0x001c, "1c" ) // invalid
|
||||
// PORT_DIPSETTING( 0x001d, "1d" ) // invalid
|
||||
// PORT_DIPSETTING( 0x001e, "1e" ) // invalid
|
||||
// PORT_DIPSETTING( 0x001f, "1f" ) // invalid
|
||||
PORT_DIPSETTING( 0x0020, DEF_STR( Korea ) )
|
||||
PORT_DIPSETTING( 0x0021, DEF_STR( World ) )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( dw3 )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_MODIFY("Region") /* Region - supplied by protection device */
|
||||
PORT_CONFNAME( 0x000f, 0x0006, DEF_STR( Region ) )
|
||||
PORT_CONFSETTING( 0x0000, "0" )
|
||||
PORT_CONFSETTING( 0x0001, "1" )
|
||||
PORT_CONFSETTING( 0x0002, "2" )
|
||||
PORT_CONFSETTING( 0x0003, "3" )
|
||||
PORT_CONFSETTING( 0x0004, "4" )
|
||||
PORT_CONFSETTING( 0x0005, "5" )
|
||||
PORT_CONFSETTING( 0x0006, DEF_STR( World ) )
|
||||
PORT_CONFSETTING( 0x0007, "7" )
|
||||
|
||||
INPUT_PORTS_END
|
112
src/mame/machine/pgmprot5.c
Normal file
112
src/mame/machine/pgmprot5.c
Normal file
@ -0,0 +1,112 @@
|
||||
/***********************************************************************
|
||||
PGM 012 + 025 PGM protection emulation
|
||||
|
||||
these are simulations of the IGS 012 and 025 protection combination
|
||||
used on the following PGM games
|
||||
|
||||
Dragon World 2
|
||||
|
||||
----
|
||||
|
||||
IGS012 provides ROM overlay???
|
||||
|
||||
IGS025 is some kind of state machine / logic device which the game
|
||||
uses for various security checks bitswap checks.
|
||||
|
||||
Simulation is incomplete for some regions
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/pgm.h"
|
||||
|
||||
|
||||
/* Dragon World 2 */
|
||||
|
||||
#define DW2BITSWAP(s,d,bs,bd) d=((d&(~(1<<bd)))|(((s>>bs)&1)<<bd))
|
||||
//Use this handler for reading from 0xd80000-0xd80002
|
||||
READ16_HANDLER( dw2_d80000_r )
|
||||
{
|
||||
// addr&=0xff;
|
||||
// if(dw2reg<0x20) //NOT SURE!!
|
||||
{
|
||||
//The value at 0x80EECE is computed in the routine at 0x107c18
|
||||
UINT16 d = pgm_mainram[0xEECE/2];
|
||||
UINT16 d2 = 0;
|
||||
d = (d >> 8) | (d << 8);
|
||||
DW2BITSWAP(d, d2, 7, 0);
|
||||
DW2BITSWAP(d, d2, 4, 1);
|
||||
DW2BITSWAP(d, d2, 5, 2);
|
||||
DW2BITSWAP(d, d2, 2, 3);
|
||||
DW2BITSWAP(d, d2, 15, 4);
|
||||
DW2BITSWAP(d, d2, 1, 5);
|
||||
DW2BITSWAP(d, d2, 10, 6);
|
||||
DW2BITSWAP(d, d2, 13, 7);
|
||||
// ... missing bitswaps here (8-15) there is not enough data to know them
|
||||
// the code only checks the lowest 8 bytes
|
||||
return d2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void drgwld2_common_init(running_machine &machine)
|
||||
{
|
||||
pgm_basic_init(machine);
|
||||
pgm_dw2_decrypt(machine);
|
||||
/*
|
||||
Info from Elsemi
|
||||
Here is how to "bypass" the dw2 hang protection, it fixes the mode
|
||||
select and after failing in the 2nd stage (probably there are other checks
|
||||
out there).
|
||||
*/
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_read_handler(0xd80000, 0xd80003, FUNC(dw2_d80000_r));
|
||||
}
|
||||
|
||||
DRIVER_INIT( drgw2 )
|
||||
{ /* incomplete? */
|
||||
UINT16 *mem16 = (UINT16 *)machine.region("maincpu")->base();
|
||||
drgwld2_common_init(machine);
|
||||
/* These ROM patches are not hacks, the protection device
|
||||
overlays the normal ROM code, this has been confirmed on a real PCB
|
||||
although some addresses may be missing */
|
||||
mem16[0x131098 / 2] = 0x4e93;
|
||||
mem16[0x13113e / 2] = 0x4e93;
|
||||
mem16[0x1311ce / 2] = 0x4e93;
|
||||
}
|
||||
|
||||
DRIVER_INIT( dw2v100x )
|
||||
{
|
||||
UINT16 *mem16 = (UINT16 *)machine.region("maincpu")->base();
|
||||
drgwld2_common_init(machine);
|
||||
|
||||
mem16[0x131084 / 2] = 0x4e93;
|
||||
mem16[(0x131084+0xa6) / 2] = 0x4e93;
|
||||
mem16[(0x131084+0x136) / 2] = 0x4e93;
|
||||
}
|
||||
|
||||
DRIVER_INIT( drgw2c )
|
||||
{
|
||||
UINT16 *mem16 = (UINT16 *)machine.region("maincpu")->base();
|
||||
drgwld2_common_init(machine);
|
||||
/* These ROM patches are not hacks, the protection device
|
||||
overlays the normal ROM code, this has been confirmed on a real PCB
|
||||
although some addresses may be missing */
|
||||
mem16[0x1303bc / 2] = 0x4e93;
|
||||
mem16[0x130462 / 2] = 0x4e93;
|
||||
mem16[0x1304f2 / 2] = 0x4e93;
|
||||
}
|
||||
|
||||
DRIVER_INIT( drgw2j )
|
||||
{
|
||||
UINT16 *mem16 = (UINT16 *)machine.region("maincpu")->base();
|
||||
drgwld2_common_init(machine);
|
||||
/* These ROM patches are not hacks, the protection device
|
||||
overlays the normal ROM code, this has been confirmed on a real PCB
|
||||
although some addresses may be missing */
|
||||
mem16[0x1302c0 / 2] = 0x4e93;
|
||||
mem16[0x130366 / 2] = 0x4e93;
|
||||
mem16[0x1303f6 / 2] = 0x4e93;
|
||||
}
|
||||
|
245
src/mame/machine/pgmprot6.c
Normal file
245
src/mame/machine/pgmprot6.c
Normal file
@ -0,0 +1,245 @@
|
||||
/***********************************************************************
|
||||
PGM 012 + 28 PGM protection emulation
|
||||
|
||||
these are simulations of the IGS 012 and 025 protection combination
|
||||
used on the following PGM games
|
||||
|
||||
Oriental Legend Super
|
||||
|
||||
----
|
||||
|
||||
IGS28 is some kind of encrypted DMA device, works with data in an
|
||||
external ROM, more advaned version of IGS022?
|
||||
|
||||
IGS025 is some kind of state machine, bitswaps etc.
|
||||
|
||||
Simulation is incomplete
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/pgm.h"
|
||||
|
||||
static UINT32 olds_prot_addr( UINT16 addr )
|
||||
{
|
||||
UINT32 mode = addr & 0xff;
|
||||
UINT32 offset = addr >> 8;
|
||||
UINT32 realaddr;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x5:
|
||||
case 0xa:
|
||||
realaddr = 0x402a00 + (offset << 2);
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
case 0x8:
|
||||
realaddr = 0x402e00 + (offset << 2);
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
realaddr = 0x40307e;
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
realaddr = 0x403090;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
realaddr = 0x40309a;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
realaddr = 0x4030a4;
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
realaddr = 0x403000;
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
realaddr = 0x40306e;
|
||||
break;
|
||||
|
||||
default:
|
||||
realaddr = 0;
|
||||
}
|
||||
return realaddr;
|
||||
}
|
||||
|
||||
static UINT32 olds_read_reg( running_machine &machine, UINT16 addr )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
UINT32 protaddr = (olds_prot_addr(addr) - 0x400000) / 2;
|
||||
return state->m_sharedprotram[protaddr] << 16 | state->m_sharedprotram[protaddr + 1];
|
||||
}
|
||||
|
||||
static void olds_write_reg( running_machine &machine, UINT16 addr, UINT32 val )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
state->m_sharedprotram[(olds_prot_addr(addr) - 0x400000) / 2] = val >> 16;
|
||||
state->m_sharedprotram[(olds_prot_addr(addr) - 0x400000) / 2 + 1] = val & 0xffff;
|
||||
}
|
||||
|
||||
static MACHINE_RESET( olds )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
UINT16 *mem16 = (UINT16 *)machine.region("user2")->base();
|
||||
int i;
|
||||
|
||||
MACHINE_RESET_CALL(pgm);
|
||||
|
||||
/* populate shared protection ram with data read from pcb .. */
|
||||
for (i = 0; i < 0x4000 / 2; i++)
|
||||
{
|
||||
state->m_sharedprotram[i] = mem16[i];
|
||||
}
|
||||
|
||||
//ROM:004008B4 .word 0xFBA5
|
||||
for(i = 0; i < 0x4000 / 2; i++)
|
||||
{
|
||||
if (state->m_sharedprotram[i] == (0xffff - i))
|
||||
state->m_sharedprotram[i] = 0x4e75;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( olds_r )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
UINT16 res = 0;
|
||||
|
||||
if (offset == 1)
|
||||
{
|
||||
if (state->m_kb_cmd == 1)
|
||||
res = state->m_kb_reg & 0x7f;
|
||||
if (state->m_kb_cmd == 2)
|
||||
res = state->m_olds_bs | 0x80;
|
||||
if (state->m_kb_cmd == 3)
|
||||
res = state->m_olds_cmd3;
|
||||
else if (state->m_kb_cmd == 5)
|
||||
{
|
||||
UINT32 protvalue = 0x900000 | input_port_read(space->machine(), "Region"); // region from protection device.
|
||||
res = (protvalue >> (8 * (state->m_kb_ptr - 1))) & 0xff; // includes region 1 = taiwan , 2 = china, 3 = japan (title = orlegend special), 4 = korea, 5 = hongkong, 6 = world
|
||||
|
||||
}
|
||||
}
|
||||
logerror("%06X: ASIC25 R CMD %X VAL %X\n", cpu_get_pc(&space->device()), state->m_kb_cmd, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( olds_w )
|
||||
{
|
||||
pgm_state *state = space->machine().driver_data<pgm_state>();
|
||||
if (offset == 0)
|
||||
state->m_kb_cmd = data;
|
||||
else //offset==2
|
||||
{
|
||||
logerror("%06X: ASIC25 W CMD %X VAL %X\n",cpu_get_pc(&space->device()), state->m_kb_cmd, data);
|
||||
if (state->m_kb_cmd == 0)
|
||||
state->m_kb_reg = data;
|
||||
else if(state->m_kb_cmd == 2) //a bitswap=
|
||||
{
|
||||
int reg = 0;
|
||||
if (data & 0x01)
|
||||
reg |= 0x40;
|
||||
if (data & 0x02)
|
||||
reg |= 0x80;
|
||||
if (data & 0x04)
|
||||
reg |= 0x20;
|
||||
if (data & 0x08)
|
||||
reg |= 0x10;
|
||||
state->m_olds_bs = reg;
|
||||
}
|
||||
else if (state->m_kb_cmd == 3)
|
||||
{
|
||||
UINT16 cmd = state->m_sharedprotram[0x3026 / 2];
|
||||
switch (cmd)
|
||||
{
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
break;
|
||||
case 0x64:
|
||||
{
|
||||
UINT16 cmd0 = state->m_sharedprotram[0x3082 / 2];
|
||||
UINT16 val0 = state->m_sharedprotram[0x3050 / 2]; //CMD_FORMAT
|
||||
{
|
||||
if ((cmd0 & 0xff) == 0x2)
|
||||
olds_write_reg(space->machine(), val0, olds_read_reg(space->machine(), val0) + 0x10000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state->m_olds_cmd3 = ((data >> 4) + 1) & 0x3;
|
||||
}
|
||||
else if (state->m_kb_cmd == 4)
|
||||
state->m_kb_ptr = data;
|
||||
else if(state->m_kb_cmd == 0x20)
|
||||
state->m_kb_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( olds_prot_swap_r )
|
||||
{
|
||||
if (cpu_get_pc(&space->device()) < 0x100000) //bios
|
||||
return pgm_mainram[0x178f4 / 2];
|
||||
else //game
|
||||
return pgm_mainram[0x178d8 / 2];
|
||||
|
||||
}
|
||||
|
||||
DRIVER_INIT( olds )
|
||||
{
|
||||
pgm_state *state = machine.driver_data<pgm_state>();
|
||||
pgm_basic_init(machine);
|
||||
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0xdcb400, 0xdcb403, FUNC(olds_r), FUNC(olds_w));
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_read_handler(0x8178f4, 0x8178f5, FUNC(olds_prot_swap_r));
|
||||
|
||||
state->m_kb_cmd = 0;
|
||||
state->m_kb_reg = 0;
|
||||
state->m_kb_ptr = 0;
|
||||
state->m_olds_bs = 0;
|
||||
state->m_olds_cmd3 = 0;
|
||||
|
||||
state->save_item(NAME(state->m_kb_cmd));
|
||||
state->save_item(NAME(state->m_kb_reg));
|
||||
state->save_item(NAME(state->m_kb_ptr));
|
||||
state->save_item(NAME(state->m_olds_bs));
|
||||
state->save_item(NAME(state->m_olds_cmd3));
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( olds_mem, AS_PROGRAM, 16)
|
||||
AM_IMPORT_FROM(pgm_mem)
|
||||
AM_RANGE(0x100000, 0x3fffff) AM_ROMBANK("bank1") /* Game ROM */
|
||||
AM_RANGE(0x400000, 0x403fff) AM_RAM AM_BASE_MEMBER(pgm_state, m_sharedprotram) // Shared with protection device
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
MACHINE_CONFIG_DERIVED( olds, pgm )
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(olds_mem)
|
||||
|
||||
MCFG_MACHINE_RESET(olds)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( olds )
|
||||
PORT_INCLUDE ( pgm )
|
||||
|
||||
PORT_MODIFY("Region") /* Region - supplied by protection device */
|
||||
PORT_CONFNAME( 0x000f, 0x0006, DEF_STR( Region ) )
|
||||
/* includes the following regions:
|
||||
1 = taiwan, 2 = china, 3 = japan (title = orlegend special),
|
||||
4 = korea, 5 = hong kong, 6 = world */
|
||||
PORT_CONFSETTING( 0x0001, DEF_STR( Taiwan ) )
|
||||
PORT_CONFSETTING( 0x0002, DEF_STR( China ) )
|
||||
PORT_CONFSETTING( 0x0003, DEF_STR( Japan ) )
|
||||
PORT_CONFSETTING( 0x0004, DEF_STR( Korea ) )
|
||||
PORT_CONFSETTING( 0x0005, DEF_STR( Hong_Kong ) )
|
||||
PORT_CONFSETTING( 0x0006, DEF_STR( World ) )
|
||||
INPUT_PORTS_END
|
@ -8537,6 +8537,7 @@ sderby // (c) 1996
|
||||
croupier // (c) 1997 Playmark
|
||||
croupiera // (c) 1997 Playmark
|
||||
spacewin
|
||||
luckboom
|
||||
|
||||
// Pacific Novelty games
|
||||
sharkatt // (c) 1980
|
||||
@ -8927,6 +8928,7 @@ klxyj // (c) 200?
|
||||
mgfx // (c) 200?
|
||||
gonefsh2 // (c) 200?
|
||||
chessc2 // (c) 200?
|
||||
haunthig // (c) 200?
|
||||
|
||||
// IGS PGM System Games
|
||||
pgm
|
||||
|
@ -757,6 +757,12 @@ $(MAMEOBJ)/igs.a: \
|
||||
$(DRIVERS)/spoker.o \
|
||||
$(MACHINE)/pgmcrypt.o \
|
||||
$(MACHINE)/pgmprot.o \
|
||||
$(MACHINE)/pgmprot1.o \
|
||||
$(MACHINE)/pgmprot2.o \
|
||||
$(MACHINE)/pgmprot3.o \
|
||||
$(MACHINE)/pgmprot4.o \
|
||||
$(MACHINE)/pgmprot5.o \
|
||||
$(MACHINE)/pgmprot6.o \
|
||||
|
||||
$(MAMEOBJ)/irem.a: \
|
||||
$(DRIVERS)/m10.o $(VIDEO)/m10.o \
|
||||
|
Loading…
Reference in New Issue
Block a user