refactor deco104 to pump most games through a standard function, a function that will eventually be much better once Charles gets his hands on a board :-)

This commit is contained in:
David Haywood 2013-07-20 22:30:26 +00:00
parent df346d7397
commit 62fe409324
2 changed files with 290 additions and 333 deletions

View File

@ -326,7 +326,7 @@ static INPUT_PORTS_START( rohga )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW1_2")
PORT_START("DSW")
PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )
@ -424,7 +424,7 @@ static INPUT_PORTS_START( wizdfire )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW1_2")
PORT_START("DSW")
PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )
@ -581,7 +581,7 @@ static INPUT_PORTS_START( schmeisr )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW1_2")
PORT_START("DSW")
PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )

View File

@ -75,6 +75,8 @@
#define DECO104_MAGIC_XOR 0x2a4
#define DECO_PORT(p) (prot_ram[p/2])
#define DECO_NEW_PORT(p) (prot_ram[p/2])
static UINT8 decoprot_buffer_ram_selected=0;
static UINT16 deco16_xor=0;
@ -175,7 +177,9 @@ void deco104_device::device_reset()
void decoprot104_reset(running_machine &machine)
{
deco16_xor=0;
deco16_mask=0xffff;
// deco16_mask=0xffff;
deco16_mask=0x0; // wizard fire doesn't initialize it, but accesses addresses rohga needs the mask applied on
decoprot_last_write=decoprot_last_write_val=0;
decoprot_buffer_ram_selected=0;
@ -191,328 +195,16 @@ void decoprot104_reset(running_machine &machine)
machine.save().save_item(NAME(decoprot_buffer_ram2));
}
/***************************************************************************/
WRITE16_HANDLER( deco16_104_prot_w ) /* Wizard Fire */
{
int deco104_addr = BITSWAP32(offset*2, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 1,2,3, 4,5,6,7, 8,9,10,0) & 0x7fff;
driver_device *state = space.machine().driver_data<driver_device>();
if (deco104_addr == (0xa8))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
return;
}
if (deco104_addr != (0x00))
if (deco104_addr != (0x88))
if (deco104_addr != (0xa8))
if (deco104_addr != (0x14))
if (deco104_addr != (0x94))
if (deco104_addr != (0xd4))
if (deco104_addr != (0xec))
if (deco104_addr != (0x3c))
if (deco104_addr != (0xc2))
if (deco104_addr != (0x5a))
if (deco104_addr != (0xda))
//if (deco104_addr != (0x206))
if (deco104_addr != (0x76))
if (deco104_addr != (0xbe))
if (deco104_addr != (0x62))
printf("CONTROL PC %06x: warning - write protection memory address %04x %04x\n", space.device().safe_pc(), deco104_addr, data);
COMBINE_DATA(&deco16_prot_ram[deco104_addr>>1]);
}
#define DECO_RV_PORT(p) (deco16_prot_ram[ BITSWAP32(p, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18,17, 12,11,10,/**/ 16,15,14,13, 0,1,2,3,4,5,6,7,8,9)])
#define DECO_NEW_PORT(p) (deco16_prot_ram[p/2])
/*
*/
READ16_HANDLER( deco16_104_prot_r ) /* Wizard Fire */
{
int deco104_addr = BITSWAP32(offset*2, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 1,2,3, 4,5,6,7, 8,9,10,0) & 0x7fff;
switch (deco104_addr) {
case 0x088: /* was 0x110*/ /* Player input */ return space.machine().root_device().ioport("IN0")->read(); // also used in rohga sim
case 0x36c: /* was 0x36c*/ return space.machine().root_device().ioport("IN1")->read(); // also used in rohga sim
case 0x2cc: /* was 0x334*/ return space.machine().root_device().ioport("IN1")->read();
case 0x3b0: /* was 0x0dc*/ return space.machine().root_device().ioport("IN1")->read()<<4;
case 0x292: /* was 0x494*/ /* Dips */ return space.machine().root_device().ioport("DSW1_2")->read(); // also used in rohga sim
case 0x224: /* was 0x244*/ return DECO_NEW_PORT(0x00);
case 0x33e: /* was 0x7cc*/ return ((DECO_NEW_PORT(0x00)&0x000f)<<12) | ((DECO_NEW_PORT(0x00)&0x00f0)<<4) | ((DECO_NEW_PORT(0x00)&0x0f00)>>4) | ((DECO_NEW_PORT(0x00)&0xf000)>>12); // also used in rohga sim
case 0x030: /* was 0x0c0*/ return (((DECO_NEW_PORT(0x00)&0x000e)>>1) | ((DECO_NEW_PORT(0x00)&0x0001)<<3))<<12;
case 0x118: /* was 0x188*/ return (((DECO_NEW_PORT(0x00)&0x000e)>>1) | ((DECO_NEW_PORT(0x00)&0x0001)<<3))<<12;
case 0x7a6: /* was 0x65e*/ return (((DECO_NEW_PORT(0x00)&0x000c)>>2) | ((DECO_NEW_PORT(0x00)&0x0003)<<2))<<12;
case 0x73a: /* was 0x5ce*/ return ((DECO_NEW_PORT(0x00)<<8)&0xf000) | ((DECO_NEW_PORT(0x00)&0xe)<<7) | ((DECO_NEW_PORT(0x00)&0x1)<<11);
case 0x586: /* was 0x61a*/ return (DECO_NEW_PORT(0x00)<<8)&0xff00;
case 0x692: /* was 0x496*/ return DECO_NEW_PORT(0x88);
case 0x502: /* was 0x40a*/ return ((DECO_NEW_PORT(0x88)&0x000f)<<12) | ((DECO_NEW_PORT(0x88)&0x00f0)>>4) | ((DECO_NEW_PORT(0x88)&0x0f00)<<0) | ((DECO_NEW_PORT(0x88)&0xf000)>>8);
case 0x178: /* was 0x1e8*/ return ((DECO_NEW_PORT(0x88)&0x00ff)<<8) | ((DECO_NEW_PORT(0x88)&0xff00)>>8); // also used in rohga sim
case 0x3d2: /* was 0x4bc*/ return ((DECO_NEW_PORT(0x88)&0x0ff0)<<4) | ((DECO_NEW_PORT(0x88)&0x0003)<<6) | ((DECO_NEW_PORT(0x88)&0x000c)<<2);
case 0x762: /* was 0x46e*/ return ((DECO_NEW_PORT(0x88)&0xfff0)<<0) | ((DECO_NEW_PORT(0x88)&0x0007)<<1) | ((DECO_NEW_PORT(0x88)&0x0008)>>3);
case 0x264: /* was 0x264*/ return ((DECO_NEW_PORT(0x88)&0x000f)<<8) | ((DECO_NEW_PORT(0x88)&0x00f0)>>0) | ((DECO_NEW_PORT(0x88)&0x0f00)<<4);
case 0x4e8: /* was 0x172*/ return ((DECO_NEW_PORT(0x88)&0x000f)<<4) | ((DECO_NEW_PORT(0x88)&0x00f0)<<4) | ((DECO_NEW_PORT(0x88)&0xf000)<<0);
case 0x284: /* was 0x214*/ return DECO_NEW_PORT(0x14);
case 0x74a: /* was 0x52e*/ return ((DECO_NEW_PORT(0x14)&0x000f)<<8) | ((DECO_NEW_PORT(0x14)&0x00f0)>>0) | ((DECO_NEW_PORT(0x14)&0x0f00)>>8) | ((DECO_NEW_PORT(0x14)&0xf000)>>0);
case 0x5e0: /* was 0x07a*/ return ((DECO_NEW_PORT(0x14)&0x000f)<<8) | ((DECO_NEW_PORT(0x14)&0x00f0)>>0) | ((DECO_NEW_PORT(0x14)&0x0f00)>>8) | ((DECO_NEW_PORT(0x14)&0xf000)>>0);
case 0x06c: /* was 0x360*/ return ((DECO_NEW_PORT(0x14)&0x000f)<<8) | ((DECO_NEW_PORT(0x14)&0x00f0)>>0) | ((DECO_NEW_PORT(0x14)&0x0f00)>>8) | ((DECO_NEW_PORT(0x14)&0xf000)>>0);
case 0x3b2: /* was 0x4dc*/ return ((DECO_NEW_PORT(0x14)&0x0ff0)<<4) | ((DECO_NEW_PORT(0x14)&0x0007)<<5) | ((DECO_NEW_PORT(0x14)&0x0008)<<1);
case 0x15c: /* was 0x3a8*/ return ((DECO_NEW_PORT(0x14)&0x000e)<<3) | ((DECO_NEW_PORT(0x14)&0x0001)<<7) | ((DECO_NEW_PORT(0x14)&0x0ff0)<<4) | ((DECO_NEW_PORT(0x14)&0xf000)>>12);
case 0x6f4: /* was 0x2f6*/ return ((DECO_NEW_PORT(0x14)&0xff00)>>8) | ((DECO_NEW_PORT(0x14)&0x00f0)<<8) | ((DECO_NEW_PORT(0x14)&0x000c)<<6) | ((DECO_NEW_PORT(0x14)&0x0003)<<10);
case 0x27e: /* was 0x7e4*/ return (DECO_NEW_PORT(0x94)&0x00f0)<<8; // also used in rohga sim
case 0x6ca: /* was 0x536*/ return ((DECO_NEW_PORT(0xd4)&0x000f)<<8) | ((DECO_NEW_PORT(0xd4)&0x00f0)<<0) | ((DECO_NEW_PORT(0xd4)&0x0f00)<<4) | ((DECO_NEW_PORT(0xd4)&0xf000)>>12);
case 0x7d0: /* was 0x0be*/ return ((DECO_NEW_PORT(0xec)&0x000f)<<4) | ((DECO_NEW_PORT(0xec)&0x00f0)<<4) | ((DECO_NEW_PORT(0xec)&0x0f00)>>8) | ((DECO_NEW_PORT(0xec)&0xf000)>>0);
case 0x092: /* was 0x490*/ return (DECO_NEW_PORT(0x3c)&0xfff0) | ((DECO_NEW_PORT(0x3c)&0x0007)<<1) | ((DECO_NEW_PORT(0x3c)&0x0008)>>3); // also used in rohga sim
case 0x08e: /* was 0x710*/ return (DECO_NEW_PORT(0xc2)&0xfff0) | ((DECO_NEW_PORT(0xc2)&0x0007)<<1) | ((DECO_NEW_PORT(0xc2)&0x0008)>>3); // also used in rohga sim
case 0x544: /* was 0x22a*/ return ((DECO_NEW_PORT(0x5a)&0xff00)>>8) | ((DECO_NEW_PORT(0x5a)&0x00f0)<<8) | ((DECO_NEW_PORT(0x5a)&0x0001)<<11) | ((DECO_NEW_PORT(0x5a)&0x000e)<<7);
case 0x646: /* was 0x626*/ return ((DECO_NEW_PORT(0xda)&0x000f)<<8) | ((DECO_NEW_PORT(0xda)&0x00f0)<<8) | ((DECO_NEW_PORT(0xda)&0x0f00)>>4) | ((DECO_NEW_PORT(0xda)&0xf000)>>12);
case 0x222: /* was 0x444*/ return DECO_NEW_PORT(0x206); // (old comment was 'rohga') /* this CAN'T be right (port addr > 0x100), is it even used by this game or some c+p error? */
case 0x35a: /* was 0x5ac*/ return ((DECO_NEW_PORT(0x76)&0xfff0)>>4) | ((DECO_NEW_PORT(0x76)&0x0007)<<13) | ((DECO_NEW_PORT(0x76)&0x0008)<<9);
case 0x0a6: /* was 0x650*/ return ((DECO_NEW_PORT(0xbe)&0xfff0)>>4) | ((DECO_NEW_PORT(0xbe)&0x000f)<<12); // also used in rohga sim
case 0x352: /* was 0x4ac*/ return ((DECO_NEW_PORT(0x62)&0x0007)<<13) | ((DECO_NEW_PORT(0x62)&0x0008)<<9);
}
logerror("Deco Protection PC %06x: warning - read unmapped memory address %04x\n",space.device().safe_pc(),deco104_addr);
return 0;
}
/***************************************************************************/
/***************************************************************************/
WRITE16_HANDLER( deco16_104_cninja_prot_w )
{
driver_device *state = space.machine().driver_data<driver_device>();
if (offset == (0xa8 / 2))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
return;
}
COMBINE_DATA(&deco16_prot_ram[offset]);
}
READ16_HANDLER( deco16_104_cninja_prot_r )
{
int real_offset = offset << 1;
// keep read ports consistent with rohga / wizard fire etc.
// see note at top
real_offset ^= DECO104_MAGIC_XOR;
// what if we xor with 0x224 and use that (readback of port 0) as the base.. and bitswap the address further?
// could be interesting....
switch (real_offset)
{
case 0x224: /* was 0x080 */ /* Master level control */ return deco16_prot_ram[0x0/2];
case 0x27a: /* was 0x0de */ /* Restart position control */ return deco16_prot_ram[0x2/2];
case 0x242: /* was 0x0e6 */ /* The number of credits in the system. */ return deco16_prot_ram[0x4/2];
case 0x222: /* was 0x086 */ /* End of game check. See 0x1814 */ return deco16_prot_ram[0x6/2];
case 0x2fe: /* was 0x05a */ /* Moved to 0x140000 on int */ return deco16_prot_ram[0x10/2];
case 0x220: /* was 0x084 */ /* Moved to 0x14000a on int */ return deco16_prot_ram[0x12/2];
case 0x284: /* was 0x020 */ /* Moved to 0x14000c on int */ return deco16_prot_ram[0x14/2];
case 0x2d6: /* was 0x072 */ /* Moved to 0x14000e on int */ return deco16_prot_ram[0x16/2];
case 0x278: /* was 0x0dc */ /* Moved to 0x150000 on int */ return deco16_prot_ram[0x18/2];
case 0x2ca: /* was 0x06e */ /* Moved to 0x15000a on int */ return deco16_prot_ram[0x1a/2]; /* Not used on bootleg */
case 0x2c8: /* was 0x06c */ /* Moved to 0x15000c on int */ return deco16_prot_ram[0x1c/2];
case 0x2ac: /* was 0x008 */ /* Moved to 0x15000e on int */ return deco16_prot_ram[0x1e/2];
case 0x292: /* was 0x036 */ /* Dip switches */ return space.machine().root_device().ioport("DSW")->read();
case 0x36c: /* was 0x1c8 */ /* Coins */ return space.machine().root_device().ioport("IN1")->read();
case 0x088: /* was 0x22c */ /* Player 1 & 2 input ports */ return space.machine().root_device().ioport("IN0")->read();
case 0x016: /* was 0x2b2 */ return deco16_prot_ram[0x0fc/2]; // 0xad65
case 0x68e: /* was 0x42a */ return deco16_prot_ram[0x092/2]; // 0xb2b7
case 0x692: /* was 0x436 */ return deco16_prot_ram[0x088/2]; // 0xea5a
case 0x6e4: /* was 0x440 */ return deco16_prot_ram[0x098/2]; // 0x7aa0
case 0x6e2: /* was 0x446 */ return deco16_prot_ram[0x090/2]; // 0x5fdf
case 0x6fc: /* was 0x458 */ return deco16_prot_ram[0x082/2]; // 0x108d
case 0x624: /* was 0x480 */ return deco16_prot_ram[0x09a/2]; // 0xfbe4
case 0x62a: /* was 0x48e */ return deco16_prot_ram[0x08a/2]; // 0x67a2
case 0x638: /* was 0x49c */ return deco16_prot_ram[0x094/2]; // 0xb62a
case 0x614: /* was 0x4b0 */ return deco16_prot_ram[0x096/2]; // 0x3555
case 0x664: /* was 0x4c0 */ return deco16_prot_ram[0x09e/2]; // 0x6a34
case 0x662: /* was 0x4c6 */ return deco16_prot_ram[0x08c/2]; // 0xc6ef
case 0x64e: /* was 0x4ea */ return deco16_prot_ram[0x086/2]; // 0x9feb
case 0x65e: /* was 0x4fa */ return deco16_prot_ram[0x09c/2]; // 0x1dcb
case 0x7ac: /* was 0x508 */ return deco16_prot_ram[0x08e/2]; // 0xed9c
case 0x7b0: /* was 0x514 */ return deco16_prot_ram[0x080/2]; // 0xf6e2
case 0x7b8: /* was 0x51c */ return deco16_prot_ram[0x084/2]; // 0xbdb9
case 0x780: /* was 0x524 */ return deco16_prot_ram[0x0b8/2]; // 0x5d26
case 0x782: /* was 0x526 */ return deco16_prot_ram[0x0a2/2]; // 0x4770
case 0x7f6: /* was 0x552 */ return deco16_prot_ram[0x0ac/2]; // 0x0843
case 0x7f0: /* was 0x554 */ return deco16_prot_ram[0x0ba/2]; // 0x9b79
case 0x7ca: /* was 0x56e */ return deco16_prot_ram[0x0a0/2]; // 0xd1be
case 0x7d4: /* was 0x570 */ return deco16_prot_ram[0x0b4/2]; // 0xc950
case 0x724: /* was 0x580 */ return deco16_prot_ram[0x0b2/2]; // 0xa600
case 0x73e: /* was 0x59a */ return deco16_prot_ram[0x0ae/2]; // 0x2b24
case 0x77c: /* was 0x5d8 */ return deco16_prot_ram[0x0b6/2]; // 0x17c1
case 0x750: /* was 0x5f4 */ return deco16_prot_ram[0x0aa/2]; // 0xf152
case 0x752: /* was 0x5f6 */ return deco16_prot_ram[0x0be/2]; // 0x97ce
case 0x75c: /* was 0x5f8 */ return deco16_prot_ram[0x0bc/2]; // 0xa485
case 0x4a0: /* was 0x604 */ return deco16_prot_ram[0x0a4/2]; // 0x0e88
case 0x4a8: /* was 0x60c */ return deco16_prot_ram[0x0b0/2]; // 0xab89
case 0x4be: /* was 0x61a */ return deco16_prot_ram[0x0a6/2]; // 0x64ba
case 0x4ee: /* was 0x64a */ return deco16_prot_ram[0x0cc/2]; // 0x0ae9
case 0x4d4: /* was 0x670 */ return deco16_prot_ram[0x0d4/2]; // 0x4ec2
case 0x4da: /* was 0x67e */ return deco16_prot_ram[0x0ca/2]; // 0x61c3
case 0x430: /* was 0x694 */ return deco16_prot_ram[0x0d2/2]; // 0x3b4f
case 0x40c: /* was 0x6a8 */ return deco16_prot_ram[0x0d6/2]; // 0x0c27
case 0x40a: /* was 0x6ae */ return deco16_prot_ram[0x0da/2]; // 0x3a72
case 0x410: /* was 0x6b4 */ return deco16_prot_ram[0x0de/2]; // 0x15d2
case 0x460: /* was 0x6c4 */ return deco16_prot_ram[0x0c8/2]; // 0x5849
case 0x46c: /* was 0x6c8 */ return deco16_prot_ram[0x0d0/2]; // 0x186c
case 0x468: /* was 0x6cc */ return deco16_prot_ram[0x0c0/2]; // 0x713e
case 0x47a: /* was 0x6de */ return deco16_prot_ram[0x0c2/2]; // 0xa87e
case 0x45c: /* was 0x6f8 */ return deco16_prot_ram[0x0d8/2]; // 0x9a31
case 0x45a: /* was 0x6fe */ return deco16_prot_ram[0x0c6/2]; // 0xec69
case 0x5a4: /* was 0x700 */ return deco16_prot_ram[0x0ce/2]; // 0x82d9
case 0x5ae: /* was 0x70a */ return deco16_prot_ram[0x0dc/2]; // 0x628c
case 0x5b0: /* was 0x714 */ return deco16_prot_ram[0x0c4/2]; // 0xda45
case 0x5e8: /* was 0x74c */ return deco16_prot_ram[0x0e4/2]; // 0x8e3d
case 0x5c0: /* was 0x764 */ return deco16_prot_ram[0x0fe/2]; // 0xdef7
case 0x5d4: /* was 0x770 */ return deco16_prot_ram[0x0f4/2]; // 0xe7fe
case 0x5d6: /* was 0x772 */ return deco16_prot_ram[0x0ec/2]; // 0x23ca
case 0x5d0: /* was 0x774 */ return deco16_prot_ram[0x0e2/2]; // 0xe62c
case 0x5da: /* was 0x77e */ return deco16_prot_ram[0x0e8/2]; // 0x6683
case 0x52c: /* was 0x788 */ return deco16_prot_ram[0x0e0/2]; // 0xd60b
case 0x53c: /* was 0x798 */ return deco16_prot_ram[0x0fa/2]; // 0x9e1a
case 0x500: /* was 0x7a4 */ return deco16_prot_ram[0x0f0/2]; // 0x578f
case 0x566: /* was 0x7c2 */ return deco16_prot_ram[0x0f8/2]; // 0x0503
case 0x54e: /* was 0x7ea */ return deco16_prot_ram[0x0e6/2]; // 0x8654
case 0x548: /* was 0x7ec */ return deco16_prot_ram[0x0f6/2]; // 0xa1e1
case 0x55e: /* was 0x7fa */ return deco16_prot_ram[0x0ea/2]; // 0x5146
case 0x55a: /* was 0x7fe */ return deco16_prot_ram[0x0f2/2]; // 0x91d4
}
logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",space.device().safe_pc(),offset);
return 0;
}
/***************************************************************************/
/***************************************************************************/
WRITE16_HANDLER( deco16_104_rohga_prot_w )
{
/*
Schmeizr uses a feature of this chip that other games don't seem to exploit. There
appear to be two banks of data ports (referred to here as front and back buffers).
These banks are switched when certain addresses are read - also very good protection
against trojans as it is non-obvious when data ports are switched.
It appears to work as follows.. When the front buffer is active (the state upon
reset) any writes to data ports push the existing front buffer word into the back
buffer (ie, a FIFO latch type of system). When the back buffer is active, any writes
to data ports affect the back buffer only - the front buffer data is not affected, and
there is no FIFO action.
By default the read ports return a scrambled address and scrambled data from a
front buffer port. When the back buffer is active most read ports return scrambled
data from the back buffer, however some ports work exclusively on front buffer data
even if the back buffer is selected.
There doesn't appear to be any way to detect what bank is currently selected - it
seems game code must maintain this state (if it matters).
*/
if (decoprot_buffer_ram_selected)
COMBINE_DATA(&decoprot_buffer_ram[offset]);
else
COMBINE_DATA(&deco16_prot_ram[offset]);
driver_device *state = space.machine().driver_data<driver_device>();
if (offset == (0xa8 / 2))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
return;
}
// These are set regardless of bank
if (offset==0x42/2)
COMBINE_DATA(&deco16_xor);
if (offset==0xee/2)
COMBINE_DATA(&deco16_mask);
offset=offset*2;
//logerror("CONTROL PC %06x: warning - write protection memory address %04x %04x\n",space.device().safe_pc(),offset,data);
if (offset==0xee || offset==0x42 || offset==0xa8)
return;
// logerror("CONTROL PC %06x: warning - write protection memory address %04x %04x\n",space.device().safe_pc(),offset,data);
#if 1
// 66 7c 7e 28 58 4a 9e
if (offset==0x66 || offset==0x7c || offset==0x7e || offset==0x28 || offset==0x58 || offset==0x4a)
return;
if (offset==0x9e || offset==0x7c || offset==0x7e || offset==0x28 || offset==0x58 || offset==0x4a)
return;
#endif
#if 1
if (offset>=0x80 && offset<0xa0)
return;
if (offset>=0xc0 && offset<0xd0)
return;
// if (offset==0x3c)
// logerror("CONTROL PC %06x: warning - write protection memory address %04x %04x\n",space.device().safe_pc(),offset,data);
// Actually read:
// 22 24 26 2c 2e 30 32 3c 40 44 46 48 60 62 66 6a 6e 76 7e 80 82 84 86 88 8a 8c 90 94 96 98 9a 9c a0 c0 c4 c6 c8 cc ce d6 dc de
// check 74 b0 b4 d4
// 24 2a 2c 2e 30 3c 44 48 66 6a 74 a0 b0 b4 d4 d6
// 32 60 7e
// 22 26 a4 a6
// 62 6e d0 dc de d2 d8 da 46
if (offset==0x24 || offset==0x2a || offset==0x2c || offset==0x2e || offset==0x30 || offset==0x3c)
return;
if (offset==0x44 || offset==0x48 || offset==0x66 || offset==0x6a || offset==0x74 || offset==0xa0)
return;
if (offset==0xb0 || offset==0xb4 || offset==0xd4 || offset==0xd6)
return;
if (offset==0x32 || offset==0x60 || offset==0x7e || offset==0xa4 || offset==0xa6)
return;
if (offset==0x22 || offset==0x26 || offset==0x62 || offset==0xd0 || offset==0xdc)
return;
if (offset==0xde || offset==0xd2 || offset==0xd8 || offset==0xda || offset==0x46)
return;
if (offset==0x20 || offset==0x40)
return;
if (offset==0x6e || offset==0xaa || offset==0xac || offset==0xa2)
return;
#endif
logerror("CONTROL PC %06x: warning - write unmapped protection memory address %04x %04x\n",space.device().safe_pc(),offset,data);
}
READ16_HANDLER( deco16_104_rohga_prot_r )
UINT16 deco104_read_core(address_space &space, int offset, UINT16 mem_mask)
{
const UINT16* prot_ram=decoprot_buffer_ram_selected ? decoprot_buffer_ram : deco16_prot_ram;
// if (offset!=0x88/2 && offset!=0x44c/2 && offset!=0x36c/2 && offset!=0x292/2)
// logerror("Protection PC %06x: warning - read prot address %04x\n",space.device().safe_pc(),offset<<1);
switch (offset) {
case 0x088/2: /* Player 1 & 2 input ports */ return space.machine().root_device().ioport("IN0")->read();
case 0x36c/2: return space.machine().root_device().ioport("IN1")->read();
case 0x088/2: /* Player 1 & 2 input ports */ return space.machine().root_device().ioport("IN0")->read(); // also caveman ninja + wizard fire
case 0x36c/2: return space.machine().root_device().ioport("IN1")->read(); // also caveman ninja + wizard fire
case 0x44c/2: return ((space.machine().root_device().ioport("IN1")->read() & 0x7)<<13)|((space.machine().root_device().ioport("IN1")->read() & 0x8)<<9);
case 0x292/2: /* Dips */ return space.machine().root_device().ioport("DSW1_2")->read();
case 0x292/2: /* Dips */ return space.machine().root_device().ioport("DSW")->read(); // also wizard fire
case 0x044/2: return ((((DECO_PORT(0x2c)&0x000f)<<12)) ^ deco16_xor) & (~deco16_mask);
case 0x282/2: return ((DECO_PORT(0x26)&0x000f)<<12) & (~deco16_mask);
case 0x0d4/2: return ((DECO_PORT(0x6e)&0x0ff0)<<4) | ((DECO_PORT(0x6e)&0x000e)<<3) | ((DECO_PORT(0x6e)&0x0001)<<7);
@ -542,25 +234,25 @@ READ16_HANDLER( deco16_104_rohga_prot_r )
case 0x34e/2: return ((DECO_PORT(0xde)&0x0ff0)<<4) | ((DECO_PORT(0xde)&0xf000)>>8) | ((DECO_PORT(0xde)&0x000f)<<0);
case 0x722/2: return (((DECO_PORT(0xdc)&0x0fff)<<4) ^ deco16_xor) & (~deco16_mask);
case 0x574/2: return ((((DECO_PORT(0xdc)&0xfff0)>>0) | ((DECO_PORT(0xdc)&0x0003)<<2) | ((DECO_PORT(0xdc)&0x000c)>>2)) ^ deco16_xor) & (~deco16_mask);
case 0x5ae/2: return DECO_PORT(0xdc);
case 0x410/2: return DECO_PORT(0xde);
case 0x5ae/2: return DECO_PORT(0xdc); // also caveman ninja
case 0x410/2: return DECO_PORT(0xde); // also caveman ninja
case 0x340/2: return ((DECO_PORT(0x90)&0xfff0) | ((DECO_PORT(0x90)&0x7)<<1) | ((DECO_PORT(0x90)&0x8)>>3)) ^ deco16_xor;
case 0x4a4/2: return (((DECO_PORT(0xce)&0x0ff0) | ((DECO_PORT(0xce)&0xf000)>>12) | ((DECO_PORT(0xce)&0x000f)<<12)) ^ deco16_xor) & (~deco16_mask);
case 0x256/2: return ((((DECO_PORT(0xce)&0xf000)>>12) | ((DECO_PORT(0xce)&0x0fff)<<4))) & (~deco16_mask);
case 0x79a/2: return (((DECO_PORT(0xc8)&0xfff0)>>4) | ((DECO_PORT(0xc8)&0x0008)<<9) | ((DECO_PORT(0xc8)&0x0007)<<13)) ^ deco16_xor;
case 0x65e/2: return DECO_PORT(0x9c);
case 0x65e/2: return DECO_PORT(0x9c); // also caveman ninja
case 0x79c/2: return ((DECO_PORT(0xc6)&0xf000) | ((DECO_PORT(0xc6)&0x00ff)<<4) | ((DECO_PORT(0xc6)&0x0f00)>>8)) & (~deco16_mask);
case 0x15e/2: return (((DECO_PORT(0x98)&0x0ff0)<<4) | ((DECO_PORT(0x98)&0xf000)>>12) | ((DECO_PORT(0x98)&0x0003)<<6) | ((DECO_PORT(0x98)&0x000c)<<2)) ^ deco16_xor;
case 0x6e4/2: return DECO_PORT(0x98);
case 0x6e4/2: return DECO_PORT(0x98); // also caveman ninja
case 0x01e/2: return ((((DECO_PORT(0xc4)&0xf000)>>4) | ((DECO_PORT(0xc4)&0x0f00)<<4) | ((DECO_PORT(0xc4)&0x00ff)<<0)) ^ deco16_xor) & (~deco16_mask);
case 0x23a/2: return ((((DECO_PORT(0x86)&0xfff0)>>0) | ((DECO_PORT(0x86)&0x0003)<<2) | ((DECO_PORT(0x86)&0x000c)>>2)) ^ deco16_xor);
case 0x06e/2: return ((((DECO_PORT(0x96)&0xf000)>>8) | ((DECO_PORT(0x96)&0x0f0f)<<0) | ((DECO_PORT(0x96)&0x00f0)<<8)) ^ deco16_xor);
case 0x3a2/2: return ((((DECO_PORT(0x94)&0xf000)>>8) | ((DECO_PORT(0x94)&0x0f00)>>8) | ((DECO_PORT(0x94)&0x00f0)<<8) | ((DECO_PORT(0x94)&0x000e)<<7) | ((DECO_PORT(0x94)&0x0001)<<11)) ^ deco16_xor);// & (~deco16_mask);
case 0x4a6/2: return ((DECO_PORT(0x8c)&0xff00)>>0) | ((DECO_PORT(0x8c)&0x00f0)>>4) | ((DECO_PORT(0x8c)&0x000f)<<4);
case 0x7b0/2: return DECO_PORT(0x80);
case 0x7b0/2: return DECO_PORT(0x80); // also caveman ninja
case 0x5aa/2: return ((((DECO_PORT(0x98)&0x0f00)>>8) | ((DECO_PORT(0x98)&0xf000)>>8) | ((DECO_PORT(0x98)&0x00f0)<<8) | ((DECO_PORT(0x98)&0x000e)<<7) | ((DECO_PORT(0x98)&0x0001)<<11)) ^ deco16_xor) & (~deco16_mask);
case 0x662/2: return DECO_PORT(0x8c);
case 0x624/2: return DECO_PORT(0x9a);
case 0x662/2: return DECO_PORT(0x8c); // also caveman ninja
case 0x624/2: return DECO_PORT(0x9a); // also caveman ninja
case 0x02c/2: return (((DECO_PORT(0x82)&0x0f0f)>>0) | ((DECO_PORT(0x82)&0xf000)>>8) | ((DECO_PORT(0x82)&0x00f0)<<8)) & (~deco16_mask);
case 0x1b4/2: return ((DECO_PORT(0xcc)&0x00f0)<<4) | ((DECO_PORT(0xcc)&0x000f)<<12);
case 0x7ce/2: return ((DECO_PORT(0x80)&0x000e)<<11) | ((DECO_PORT(0x80)&0x0001)<<15);
@ -569,7 +261,7 @@ READ16_HANDLER( deco16_104_rohga_prot_r )
case 0x314/2: return ((((DECO_PORT(0x84)&0x0ff0)<<4) | ((DECO_PORT(0x84)&0x000e)<<3) | ((DECO_PORT(0x84)&0x0001)<<5)));
case 0x5e2/2: return ((((DECO_PORT(0x84)&0x00f0)<<8) | ((DECO_PORT(0x84)&0x000e)<<7) | ((DECO_PORT(0x84)&0x0001)<<9)));
case 0x72a/2: return ((((DECO_PORT(0x86)&0xfff0)>>4) | ((DECO_PORT(0x86)&0x0003)<<14) | ((DECO_PORT(0x86)&0x000c)<<10)) ^ deco16_xor) & (~deco16_mask);
case 0x178/2: return (((DECO_PORT(0x88)&0x00ff)<<8) | ((DECO_PORT(0x88)&0xff00)>>8)) & (~deco16_mask);
case 0x178/2: return (((DECO_PORT(0x88)&0x00ff)<<8) | ((DECO_PORT(0x88)&0xff00)>>8)) & (~deco16_mask); // also wizard fire
case 0x40e/2: return ((((DECO_PORT(0x8a)&0xf000)>>0) | ((DECO_PORT(0x8a)&0x00ff)<<4)) ^ deco16_xor) & (~deco16_mask);
case 0x248/2: return ((((DECO_PORT(0x8c)&0xff00)>>8) | ((DECO_PORT(0x8c)&0x00f0)<<4) | ((DECO_PORT(0x8c)&0x000f)<<12)) ^ deco16_xor) & (~deco16_mask);
case 0x27e/2: return ((((DECO_PORT(0x94)&0x00f0)<<8)) ^ deco16_xor) & (~deco16_mask);
@ -616,7 +308,7 @@ READ16_HANDLER( deco16_104_rohga_prot_r )
case 0x3f4/2: return DECO_PORT(0x6e)<<4;
case 0x2ae/2: return ((DECO_PORT(0x9c)&0xf000)<<0) | ((DECO_PORT(0x9c)&0x0ff0)>>4) | ((DECO_PORT(0x9c)&0x000f)<<8);// & (~deco16_mask);
case 0x096/2: return ((((DECO_PORT(0x22)&0xff00)>>8) | ((DECO_PORT(0x22)&0x00f0)<<8) | ((DECO_PORT(0x22)&0x000e)<<7) | ((DECO_PORT(0x22)&0x0001)<<11)) ^ deco16_xor) & (~deco16_mask);
case 0x33e/2: return (((DECO_PORT(0x0)&0xf000)>>12) | ((DECO_PORT(0x0)&0x0f00)>>4) | ((DECO_PORT(0x0)&0x00f0)<<4) | ((DECO_PORT(0x0)&0x000f)<<12)) & (~deco16_mask);
case 0x33e/2: return (((DECO_PORT(0x0)&0xf000)>>12) | ((DECO_PORT(0x0)&0x0f00)>>4) | ((DECO_PORT(0x0)&0x00f0)<<4) | ((DECO_PORT(0x0)&0x000f)<<12)) & (~deco16_mask); // also wizard fire
case 0x6c4/2: /* Reads from here flip buffers */decoprot_buffer_ram_selected^=1;/* Flip occurs AFTER this data has been calculated*/return ((DECO_PORT(0x66)&0xf0f0) | ((DECO_PORT(0x66)&0x000f)<<8)) & (~deco16_mask);
case 0x700/2: /* Reads from here flip buffers */decoprot_buffer_ram_selected^=1;return (((DECO_PORT(0x66)&0xf000)>>4) | ((DECO_PORT(0x66)&0x00f0)<<8)) ^ deco16_xor;
case 0x444/2: decoprot_buffer_ram_selected^=1;return ((DECO_PORT(0x66)&0x00f0)<<8) | ((DECO_PORT(0x66)&0x0007)<<9) | ((DECO_PORT(0x66)&0x0008)<<5);
@ -627,7 +319,7 @@ READ16_HANDLER( deco16_104_rohga_prot_r )
case 0x49c/2: return (((DECO_PORT(0x6c)&0x00f0)<<8) ^ deco16_xor) & (~deco16_mask);
case 0x44e/2: return (((DECO_PORT(0x44)&0x00f0)<<4) | ((DECO_PORT(0x44)&0x000f)<<12)) ^ deco16_xor;
case 0x3ca/2: return (((DECO_PORT(0x1e)&0xfff0)>>4) | ((DECO_PORT(0x1e)&0x0003)<<14) | ((DECO_PORT(0x1e)&0x000c)<<10)) ^ deco16_xor;
case 0x2ac/2: return DECO_PORT(0x1e);
case 0x2ac/2: return DECO_PORT(0x1e); // also caveman ninja
case 0x03c/2: return (((DECO_PORT(0x1e)&0x0003)<<14) | ((DECO_PORT(0x1e)&0x000c)<<10)) & (~deco16_mask);
case 0x174/2: return (((DECO_PORT(0x1e)&0xff00)>>8) | ((DECO_PORT(0x1e)&0x00f0)<<8) | ((DECO_PORT(0x1e)&0x0007)<<9) | ((DECO_PORT(0x1e)&0x0008)<<5)) & (~deco16_mask);
case 0x34a/2: return (((DECO_PORT(0x4)&0xff00)>>0) | ((DECO_PORT(0x4)&0x00f0)>>4) | ((DECO_PORT(0x4)&0x000f)<<4)) & (~deco16_mask);
@ -643,7 +335,7 @@ READ16_HANDLER( deco16_104_rohga_prot_r )
case 0x63e/2: return ((((DECO_PORT(0xa)&0x0ff0)<<4) | ((DECO_PORT(0xa)&0xf000)>>12) | ((DECO_PORT(0xa)&0x0003)<<6) | ((DECO_PORT(0xa)&0x000c)<<2)));
case 0x7cc/2: return ((((DECO_PORT(0xc)&0xfff0)>>4) | ((DECO_PORT(0xc)&0x000e)<<11) | ((DECO_PORT(0xc)&0x0001)<<15)) ^ deco16_xor) & (~deco16_mask);
case 0x1bc/2: return (((DECO_PORT(0xe)&0xf000)>>12) | ((DECO_PORT(0xe)&0x0f00)>>4) | ((DECO_PORT(0xe)&0x00ff)<<8)) & (~deco16_mask);
case 0x780/2: return DECO_PORT(0xb8);
case 0x780/2: return DECO_PORT(0xb8); // also caveman ninja
case 0x454/2: return (((DECO_PORT(0x82)&0xf000)>>8) | ((DECO_PORT(0x82)&0x0f00)>>0) | ((DECO_PORT(0x82)&0x00f0)>>4) | ((DECO_PORT(0x82)&0x000f)<<12)) ^ deco16_xor;
case 0x53e/2: return ((DECO_PORT(0x9e)&0x0003)<<14) | ((DECO_PORT(0x9e)&0x000c)<<10);
case 0x250/2: return (((DECO_PORT(0x62)&0xf0f0)<<0) | ((DECO_PORT(0x62)&0x0f00)>>8) | ((DECO_PORT(0x62)&0x000f)<<8)) & (~deco16_mask);
@ -658,11 +350,276 @@ READ16_HANDLER( deco16_104_rohga_prot_r )
case 0x0fc/2: /* Schmeizr Robo only */ return DECO_PORT(0x4a);
case 0x38c/2: /* Schmeizr Robo only */ return DECO_PORT(0x28);
case 0x028/2: /* Schmeizr Robo only */ return DECO_PORT(0x58);
// caveman ninja cases
case 0x224/2: /* was 0x080 */ /* Master level control */ return prot_ram[0x0/2];
case 0x27a/2: /* was 0x0de */ /* Restart position control */ return prot_ram[0x2/2];
case 0x242/2: /* was 0x0e6 */ /* The number of credits in the system. */ return prot_ram[0x4/2];
case 0x222/2: /* was 0x086 */ /* End of game check. See 0x1814 */ return prot_ram[0x6/2];
case 0x2fe/2: /* was 0x05a */ /* Moved to 0x140000 on int */ return prot_ram[0x10/2];
case 0x220/2: /* was 0x084 */ /* Moved to 0x14000a on int */ return prot_ram[0x12/2];
case 0x284/2: /* was 0x020 */ /* Moved to 0x14000c on int */ return prot_ram[0x14/2];
case 0x2d6/2: /* was 0x072 */ /* Moved to 0x14000e on int */ return prot_ram[0x16/2];
case 0x278/2: /* was 0x0dc */ /* Moved to 0x150000 on int */ return prot_ram[0x18/2];
case 0x2ca/2: /* was 0x06e */ /* Moved to 0x15000a on int */ return prot_ram[0x1a/2]; /* Not used on bootleg */
case 0x2c8/2: /* was 0x06c */ /* Moved to 0x15000c on int */ return prot_ram[0x1c/2];
//case 0x2ac/2: /* was 0x008 */ /* Moved to 0x15000e on int */ return prot_ram[0x1e/2];
//case 0x292/2: /* was 0x036 */ /* Dip switches */ return space.machine().root_device().ioport("DSW")->read();
//case 0x36c/2: /* was 0x1c8 */ /* Coins */ return space.machine().root_device().ioport("IN1")->read();
//case 0x088/2: /* was 0x22c */ /* Player 1 & 2 input ports */ return space.machine().root_device().ioport("IN0")->read();
case 0x016/2: /* was 0x2b2 */ return prot_ram[0x0fc/2]; // 0xad65
case 0x68e/2: /* was 0x42a */ return prot_ram[0x092/2]; // 0xb2b7
case 0x692/2: /* was 0x436 */ return prot_ram[0x088/2]; // 0xea5a
//case 0x6e4/2: /* was 0x440 */ return prot_ram[0x098/2]; // 0x7aa0
case 0x6e2/2: /* was 0x446 */ return prot_ram[0x090/2]; // 0x5fdf
case 0x6fc/2: /* was 0x458 */ return prot_ram[0x082/2]; // 0x108d
//case 0x624/2: /* was 0x480 */ return prot_ram[0x09a/2]; // 0xfbe4
case 0x62a/2: /* was 0x48e */ return prot_ram[0x08a/2]; // 0x67a2
case 0x638/2: /* was 0x49c */ return prot_ram[0x094/2]; // 0xb62a
case 0x614/2: /* was 0x4b0 */ return prot_ram[0x096/2]; // 0x3555
case 0x664/2: /* was 0x4c0 */ return prot_ram[0x09e/2]; // 0x6a34
//case 0x662/2: /* was 0x4c6 */ return prot_ram[0x08c/2]; // 0xc6ef
case 0x64e/2: /* was 0x4ea */ return prot_ram[0x086/2]; // 0x9feb
//case 0x65e/2: /* was 0x4fa */ return prot_ram[0x09c/2]; // 0x1dcb
case 0x7ac/2: /* was 0x508 */ return prot_ram[0x08e/2]; // 0xed9c
//case 0x7b0/2: /* was 0x514 */ return prot_ram[0x080/2]; // 0xf6e2
case 0x7b8/2: /* was 0x51c */ return prot_ram[0x084/2]; // 0xbdb9
//case 0x780/2: /* was 0x524 */ return prot_ram[0x0b8/2]; // 0x5d26
case 0x782/2: /* was 0x526 */ return prot_ram[0x0a2/2]; // 0x4770
case 0x7f6/2: /* was 0x552 */ return prot_ram[0x0ac/2]; // 0x0843
case 0x7f0/2: /* was 0x554 */ return prot_ram[0x0ba/2]; // 0x9b79
case 0x7ca/2: /* was 0x56e */ return prot_ram[0x0a0/2]; // 0xd1be
case 0x7d4/2: /* was 0x570 */ return prot_ram[0x0b4/2]; // 0xc950
case 0x724/2: /* was 0x580 */ return prot_ram[0x0b2/2]; // 0xa600
case 0x73e/2: /* was 0x59a */ return prot_ram[0x0ae/2]; // 0x2b24
case 0x77c/2: /* was 0x5d8 */ return prot_ram[0x0b6/2]; // 0x17c1
case 0x750/2: /* was 0x5f4 */ return prot_ram[0x0aa/2]; // 0xf152
case 0x752/2: /* was 0x5f6 */ return prot_ram[0x0be/2]; // 0x97ce
case 0x75c/2: /* was 0x5f8 */ return prot_ram[0x0bc/2]; // 0xa485
case 0x4a0/2: /* was 0x604 */ return prot_ram[0x0a4/2]; // 0x0e88
case 0x4a8/2: /* was 0x60c */ return prot_ram[0x0b0/2]; // 0xab89
case 0x4be/2: /* was 0x61a */ return prot_ram[0x0a6/2]; // 0x64ba
case 0x4ee/2: /* was 0x64a */ return prot_ram[0x0cc/2]; // 0x0ae9
case 0x4d4/2: /* was 0x670 */ return prot_ram[0x0d4/2]; // 0x4ec2
case 0x4da/2: /* was 0x67e */ return prot_ram[0x0ca/2]; // 0x61c3
case 0x430/2: /* was 0x694 */ return prot_ram[0x0d2/2]; // 0x3b4f
case 0x40c/2: /* was 0x6a8 */ return prot_ram[0x0d6/2]; // 0x0c27
case 0x40a/2: /* was 0x6ae */ return prot_ram[0x0da/2]; // 0x3a72
//case 0x410/2: /* was 0x6b4 */ return prot_ram[0x0de/2]; // 0x15d2
case 0x460/2: /* was 0x6c4 */ return prot_ram[0x0c8/2]; // 0x5849
case 0x46c/2: /* was 0x6c8 */ return prot_ram[0x0d0/2]; // 0x186c
case 0x468/2: /* was 0x6cc */ return prot_ram[0x0c0/2]; // 0x713e
case 0x47a/2: /* was 0x6de */ return prot_ram[0x0c2/2]; // 0xa87e
case 0x45c/2: /* was 0x6f8 */ return prot_ram[0x0d8/2]; // 0x9a31
case 0x45a/2: /* was 0x6fe */ return prot_ram[0x0c6/2]; // 0xec69
case 0x5a4/2: /* was 0x700 */ return prot_ram[0x0ce/2]; // 0x82d9
//case 0x5ae/2: /* was 0x70a */ return prot_ram[0x0dc/2]; // 0x628c
case 0x5b0/2: /* was 0x714 */ return prot_ram[0x0c4/2]; // 0xda45
case 0x5e8/2: /* was 0x74c */ return prot_ram[0x0e4/2]; // 0x8e3d
case 0x5c0/2: /* was 0x764 */ return prot_ram[0x0fe/2]; // 0xdef7
case 0x5d4/2: /* was 0x770 */ return prot_ram[0x0f4/2]; // 0xe7fe
case 0x5d6/2: /* was 0x772 */ return prot_ram[0x0ec/2]; // 0x23ca
case 0x5d0/2: /* was 0x774 */ return prot_ram[0x0e2/2]; // 0xe62c
case 0x5da/2: /* was 0x77e */ return prot_ram[0x0e8/2]; // 0x6683
case 0x52c/2: /* was 0x788 */ return prot_ram[0x0e0/2]; // 0xd60b
case 0x53c/2: /* was 0x798 */ return prot_ram[0x0fa/2]; // 0x9e1a
case 0x500/2: /* was 0x7a4 */ return prot_ram[0x0f0/2]; // 0x578f
case 0x566/2: /* was 0x7c2 */ return prot_ram[0x0f8/2]; // 0x0503
case 0x54e/2: /* was 0x7ea */ return prot_ram[0x0e6/2]; // 0x8654
case 0x548/2: /* was 0x7ec */ return prot_ram[0x0f6/2]; // 0xa1e1
case 0x55e/2: /* was 0x7fa */ return prot_ram[0x0ea/2]; // 0x5146
case 0x55a/2: /* was 0x7fe */ return prot_ram[0x0f2/2]; // 0x91d4
// wizard fire cases
//case 0x088/2: /* was 0x110*/ /* Player input */ return space.machine().root_device().ioport("IN0")->read(); // also used in rohga sim
//case 0x36c/2: /* was 0x36c*/ return space.machine().root_device().ioport("IN1")->read(); // also used in rohga sim
case 0x2cc/2: /* was 0x334*/ return space.machine().root_device().ioport("IN1")->read();
case 0x3b0/2: /* was 0x0dc*/ return space.machine().root_device().ioport("IN1")->read()<<4;
//case 0x292/2: /* was 0x494*/ /* Dips */ return space.machine().root_device().ioport("DSW1_2")->read(); // also used in rohga sim // also caveman ninja
//case 0x224/2: /* was 0x244*/ return DECO_NEW_PORT(0x00); // also caveman ninja
//case 0x33e/2: /* was 0x7cc*/ return ((DECO_NEW_PORT(0x00)&0x000f)<<12) | ((DECO_NEW_PORT(0x00)&0x00f0)<<4) | ((DECO_NEW_PORT(0x00)&0x0f00)>>4) | ((DECO_NEW_PORT(0x00)&0xf000)>>12); // also used in rohga sim (NOTE, ROHGA APPLIES MASK, CHECK!)
case 0x030/2: /* was 0x0c0*/ return (((DECO_NEW_PORT(0x00)&0x000e)>>1) | ((DECO_NEW_PORT(0x00)&0x0001)<<3))<<12;
case 0x118/2: /* was 0x188*/ return (((DECO_NEW_PORT(0x00)&0x000e)>>1) | ((DECO_NEW_PORT(0x00)&0x0001)<<3))<<12;
case 0x7a6/2: /* was 0x65e*/ return (((DECO_NEW_PORT(0x00)&0x000c)>>2) | ((DECO_NEW_PORT(0x00)&0x0003)<<2))<<12;
case 0x73a/2: /* was 0x5ce*/ return ((DECO_NEW_PORT(0x00)<<8)&0xf000) | ((DECO_NEW_PORT(0x00)&0xe)<<7) | ((DECO_NEW_PORT(0x00)&0x1)<<11);
case 0x586/2: /* was 0x61a*/ return (DECO_NEW_PORT(0x00)<<8)&0xff00;
//case 0x692/2: /* was 0x496*/ return DECO_NEW_PORT(0x88); // also caveman ninja
case 0x502/2: /* was 0x40a*/ return ((DECO_NEW_PORT(0x88)&0x000f)<<12) | ((DECO_NEW_PORT(0x88)&0x00f0)>>4) | ((DECO_NEW_PORT(0x88)&0x0f00)<<0) | ((DECO_NEW_PORT(0x88)&0xf000)>>8);
//case 0x178/2: /* was 0x1e8*/ return ((DECO_NEW_PORT(0x88)&0x00ff)<<8) | ((DECO_NEW_PORT(0x88)&0xff00)>>8); // also used in rohga sim (NOTE, ROHGA APPLIES MASK, CHECK!)
case 0x3d2/2: /* was 0x4bc*/ return ((DECO_NEW_PORT(0x88)&0x0ff0)<<4) | ((DECO_NEW_PORT(0x88)&0x0003)<<6) | ((DECO_NEW_PORT(0x88)&0x000c)<<2);
case 0x762/2: /* was 0x46e*/ return ((DECO_NEW_PORT(0x88)&0xfff0)<<0) | ((DECO_NEW_PORT(0x88)&0x0007)<<1) | ((DECO_NEW_PORT(0x88)&0x0008)>>3);
case 0x264/2: /* was 0x264*/ return ((DECO_NEW_PORT(0x88)&0x000f)<<8) | ((DECO_NEW_PORT(0x88)&0x00f0)>>0) | ((DECO_NEW_PORT(0x88)&0x0f00)<<4);
case 0x4e8/2: /* was 0x172*/ return ((DECO_NEW_PORT(0x88)&0x000f)<<4) | ((DECO_NEW_PORT(0x88)&0x00f0)<<4) | ((DECO_NEW_PORT(0x88)&0xf000)<<0);
//case 0x284/2: /* was 0x214*/ return DECO_NEW_PORT(0x14); // also caveman ninja
case 0x74a/2: /* was 0x52e*/ return ((DECO_NEW_PORT(0x14)&0x000f)<<8) | ((DECO_NEW_PORT(0x14)&0x00f0)>>0) | ((DECO_NEW_PORT(0x14)&0x0f00)>>8) | ((DECO_NEW_PORT(0x14)&0xf000)>>0);
case 0x5e0/2: /* was 0x07a*/ return ((DECO_NEW_PORT(0x14)&0x000f)<<8) | ((DECO_NEW_PORT(0x14)&0x00f0)>>0) | ((DECO_NEW_PORT(0x14)&0x0f00)>>8) | ((DECO_NEW_PORT(0x14)&0xf000)>>0);
case 0x06c/2: /* was 0x360*/ return ((DECO_NEW_PORT(0x14)&0x000f)<<8) | ((DECO_NEW_PORT(0x14)&0x00f0)>>0) | ((DECO_NEW_PORT(0x14)&0x0f00)>>8) | ((DECO_NEW_PORT(0x14)&0xf000)>>0);
case 0x3b2/2: /* was 0x4dc*/ return ((DECO_NEW_PORT(0x14)&0x0ff0)<<4) | ((DECO_NEW_PORT(0x14)&0x0007)<<5) | ((DECO_NEW_PORT(0x14)&0x0008)<<1);
case 0x15c/2: /* was 0x3a8*/ return ((DECO_NEW_PORT(0x14)&0x000e)<<3) | ((DECO_NEW_PORT(0x14)&0x0001)<<7) | ((DECO_NEW_PORT(0x14)&0x0ff0)<<4) | ((DECO_NEW_PORT(0x14)&0xf000)>>12);
case 0x6f4/2: /* was 0x2f6*/ return ((DECO_NEW_PORT(0x14)&0xff00)>>8) | ((DECO_NEW_PORT(0x14)&0x00f0)<<8) | ((DECO_NEW_PORT(0x14)&0x000c)<<6) | ((DECO_NEW_PORT(0x14)&0x0003)<<10);
//case 0x27e/2: /* was 0x7e4*/ return (DECO_NEW_PORT(0x94)&0x00f0)<<8; // also used in rohga sim (NOTE, ROHGA APPLIES XOR and MASK, CHECK!)
case 0x6ca/2: /* was 0x536*/ return ((DECO_NEW_PORT(0xd4)&0x000f)<<8) | ((DECO_NEW_PORT(0xd4)&0x00f0)<<0) | ((DECO_NEW_PORT(0xd4)&0x0f00)<<4) | ((DECO_NEW_PORT(0xd4)&0xf000)>>12);
case 0x7d0/2: /* was 0x0be*/ return ((DECO_NEW_PORT(0xec)&0x000f)<<4) | ((DECO_NEW_PORT(0xec)&0x00f0)<<4) | ((DECO_NEW_PORT(0xec)&0x0f00)>>8) | ((DECO_NEW_PORT(0xec)&0xf000)>>0);
//case 0x092/2: /* was 0x490*/ return (DECO_NEW_PORT(0x3c)&0xfff0) | ((DECO_NEW_PORT(0x3c)&0x0007)<<1) | ((DECO_NEW_PORT(0x3c)&0x0008)>>3); // also used in rohga sim
case 0x08e/2: /* was 0x710*/ return (DECO_NEW_PORT(0xc2)&0xfff0) | ((DECO_NEW_PORT(0xc2)&0x0007)<<1) | ((DECO_NEW_PORT(0xc2)&0x0008)>>3);
case 0x544/2: /* was 0x22a*/ return ((DECO_NEW_PORT(0x5a)&0xff00)>>8) | ((DECO_NEW_PORT(0x5a)&0x00f0)<<8) | ((DECO_NEW_PORT(0x5a)&0x0001)<<11) | ((DECO_NEW_PORT(0x5a)&0x000e)<<7);
case 0x646/2: /* was 0x626*/ return ((DECO_NEW_PORT(0xda)&0x000f)<<8) | ((DECO_NEW_PORT(0xda)&0x00f0)<<8) | ((DECO_NEW_PORT(0xda)&0x0f00)>>4) | ((DECO_NEW_PORT(0xda)&0xf000)>>12);
//case 0x222/2: /* was 0x444*/ return DECO_NEW_PORT(0x06); // (old comment was 'rohga') /* this CAN'T be right (port addr > 0x100), is it even used by this game or some c+p error? */
case 0x35a/2: /* was 0x5ac*/ return ((DECO_NEW_PORT(0x76)&0xfff0)>>4) | ((DECO_NEW_PORT(0x76)&0x0007)<<13) | ((DECO_NEW_PORT(0x76)&0x0008)<<9);
case 0x0a6/2: /* was 0x650*/ return ((DECO_NEW_PORT(0xbe)&0xfff0)>>4) | ((DECO_NEW_PORT(0xbe)&0x000f)<<12); // also used in rohga sim
case 0x352/2: /* was 0x4ac*/ return ((DECO_NEW_PORT(0x62)&0x0007)<<13) | ((DECO_NEW_PORT(0x62)&0x0008)<<9);
}
logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",space.device().safe_pc(),offset);
return 0x0000;
}
/***************************************************************************/
WRITE16_HANDLER( deco16_104_prot_w ) /* Wizard Fire */
{
int deco104_addr = BITSWAP32(offset*2, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 1,2,3, 4,5,6,7, 8,9,10,0) & 0x7fff;
deco104_addr &=0xff;
if (decoprot_buffer_ram_selected)
COMBINE_DATA(&decoprot_buffer_ram[deco104_addr/2]);
else
COMBINE_DATA(&deco16_prot_ram[deco104_addr/2]);
driver_device *state = space.machine().driver_data<driver_device>();
if (deco104_addr == (0xa8))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
return;
}
logerror("Protection PC %06x: warning - read unmapped protection address %04x\n",space.device().safe_pc(),offset<<1);
if (deco104_addr != (0x00))
if (deco104_addr != (0x88))
if (deco104_addr != (0xa8))
if (deco104_addr != (0x14))
if (deco104_addr != (0x94))
if (deco104_addr != (0xd4))
if (deco104_addr != (0xec))
if (deco104_addr != (0x3c))
if (deco104_addr != (0xc2))
if (deco104_addr != (0x5a))
if (deco104_addr != (0xda))
//if (deco104_addr != (0x206))
if (deco104_addr != (0x76))
if (deco104_addr != (0xbe))
if (deco104_addr != (0x62))
printf("CONTROL PC %06x: warning - write protection memory address %04x %04x\n", space.device().safe_pc(), deco104_addr, data);
return 0;
}
/*
*/
READ16_HANDLER( deco16_104_prot_r ) /* Wizard Fire */
{
int deco104_addr = BITSWAP32(offset*2, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 1,2,3, 4,5,6,7, 8,9,10,0) & 0x7fff;
return deco104_read_core(space, deco104_addr/2, mem_mask);
}
/***************************************************************************/
/***************************************************************************/
WRITE16_HANDLER( deco16_104_cninja_prot_w )
{
driver_device *state = space.machine().driver_data<driver_device>();
offset &=0x7f;
if (decoprot_buffer_ram_selected)
COMBINE_DATA(&decoprot_buffer_ram[offset]);
else
COMBINE_DATA(&deco16_prot_ram[offset]);
if (offset == (0xa8 / 2))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
return;
}
}
READ16_HANDLER( deco16_104_cninja_prot_r )
{
int real_offset = offset << 1;
real_offset ^= DECO104_MAGIC_XOR;
return deco104_read_core(space, real_offset/2, mem_mask);
}
/***************************************************************************/
/***************************************************************************/
WRITE16_HANDLER( deco16_104_rohga_prot_w )
{
offset &=0x7f;
/*
Schmeizr uses a feature of this chip that other games don't seem to exploit. There
appear to be two banks of data ports (referred to here as front and back buffers).
These banks are switched when certain addresses are read - also very good protection
against trojans as it is non-obvious when data ports are switched.
It appears to work as follows.. When the front buffer is active (the state upon
reset) any writes to data ports push the existing front buffer word into the back
buffer (ie, a FIFO latch type of system). When the back buffer is active, any writes
to data ports affect the back buffer only - the front buffer data is not affected, and
there is no FIFO action.
By default the read ports return a scrambled address and scrambled data from a
front buffer port. When the back buffer is active most read ports return scrambled
data from the back buffer, however some ports work exclusively on front buffer data
even if the back buffer is selected.
There doesn't appear to be any way to detect what bank is currently selected - it
seems game code must maintain this state (if it matters).
*/
if (decoprot_buffer_ram_selected)
COMBINE_DATA(&decoprot_buffer_ram[offset]);
else
COMBINE_DATA(&deco16_prot_ram[offset]);
driver_device *state = space.machine().driver_data<driver_device>();
if (offset == (0xa8 / 2))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
return;
}
// These are set regardless of bank
if (offset==0x42/2)
COMBINE_DATA(&deco16_xor);
if (offset==0xee/2)
COMBINE_DATA(&deco16_mask);
}
READ16_HANDLER( deco16_104_rohga_prot_r )
{
return deco104_read_core(space, offset, mem_mask);
}
/**********************************************************************************/