summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/decoprot.c
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2007-12-17 15:19:59 +0000
committer Aaron Giles <aaron@aarongiles.com>2007-12-17 15:19:59 +0000
commit7b77f1218624ea26dbb2efd85a19f795f5d4e02e (patch)
tree19209304095572b4fd61c2a2d6a5aa75c4e471ad /src/mame/machine/decoprot.c
parent3da7f476068b3ffef713218ba2fc1bd5030f2c38 (diff)
Initial checkin of MAME 0.121.mame0121
Diffstat (limited to 'src/mame/machine/decoprot.c')
-rw-r--r--src/mame/machine/decoprot.c1772
1 files changed, 1772 insertions, 0 deletions
diff --git a/src/mame/machine/decoprot.c b/src/mame/machine/decoprot.c
new file mode 100644
index 00000000000..4acf0a102c6
--- /dev/null
+++ b/src/mame/machine/decoprot.c
@@ -0,0 +1,1772 @@
+/****************************************************************************
+
+ Data East protection/IO chips
+
+
+ Game Custom chip number
+ ------------------------------------------------
+ Edward Randy 60
+ Mutant Fighter 66
+ Captain America 75
+ Robocop 2 75
+ Lemmings 75
+ Caveman Ninja 104
+ Wizard Fire 104
+ Pocket Gal DX 104
+ Boogie Wings 104
+ Rohga 104
+ Diet GoGo 104
+ Funky Jet 146
+ Nitro Ball 146
+ Super Shanghai Dragon's Eye 146
+ Dragon Gun 146
+ Fighter's History 146 (ID scratched off)
+ Stadium Hero 96 146
+ Tattoo Assassins ?
+
+ This series of chips is used for I/O and copy protection. They are all
+ 16 bit word based chips, with 0x400 write addresses, and 0x400 read
+ addresses. The basic idea of the protection is that read & write
+ addresses don't match. So if you write to write address 0, you might
+ read that data back at read address 10, and something else will be at 0.
+ In addition, the data read back may be bit shifted in various ways.
+ Games can be very well protected by writing variables to the chip, and
+ expecting certain values back from certain read addresses. With care,
+ it can be impossible to tell from the game code what values go where,
+ and what shifting goes on. Eg, writing 10 values to the chip, of which
+ 7 are dummy values, then reading back 3 particular values, and using them
+ in a multiplication and add calculation to get a jump address for the
+ program. Even if you can guess one of many possible legal jump addresses
+ it's hard to tell what values should be bit shifted in what way.
+
+ It's also been found some chips contain a hardwired XOR port and hardwired
+ NAND port which affects only certain read values.
+
+ The chips also handle the interface to the sound cpu via a write address,
+ and game inputs via several read addresses. The I/O input data is also
+ mirrored to several locations, some with bit shifting.
+
+ Although several games use chip 104, each seems to be different, the
+ address lines leading to the chip on each game are probably arranged
+ differently, to further scramble reads/writes. From hardware tests
+ chips 60 && 66 appear to be identical.
+
+ Update January - April 2006:
+ Further work on examining the 146 chip has revealed that if you
+ read an address immediately after writing it, you always get
+ the written value returned. This behaviour is confirmed
+ to only exist for one read/write 'tick' - any other read will
+ return that location to its usual state - ie, bit shifter
+ or input port. This has been emulated for the 146 chip in
+ Nitroball and Fighters History but the behaviour probably
+ also exists in earlier chips as it explains the 'one-shot'
+ ports in Mutant Fighter.
+
+ The 'double buffer' feature seen in the 104 chip is also
+ confirmed to exist in the 146 chip. Again, this may well
+ be present in the earlier chip too.
+
+ Emulation by Bryan McPhail, mish@tendril.co.uk
+
+***************************************************************************/
+
+#include "driver.h"
+#include "machine/eeprom.h"
+#include "decoprot.h"
+
+#define DECO_PORT(p) (prot_ram[p/2])
+
+static UINT8 decoprot_buffer_ram_selected=0;
+static UINT16 deco16_xor=0;
+static UINT16 deco16_mask=0xffff;
+static int decoprot_last_write=0, decoprot_last_write_val=0;
+static UINT16 decoprot_buffer_ram[0x800];
+static UINT16 decoprot_buffer_ram2[0x800];
+
+UINT16 *deco16_prot_ram;
+UINT32 *deco32_prot_ram;
+
+/***************************************************************************/
+
+void decoprot_reset(void)
+{
+ deco16_xor=0;
+ deco16_mask=0xffff;
+ decoprot_last_write=decoprot_last_write_val=0;
+ decoprot_buffer_ram_selected=0;
+
+ state_save_register_global(deco16_xor);
+ state_save_register_global(deco16_mask);
+ state_save_register_global(decoprot_last_write);
+ state_save_register_global(decoprot_last_write_val);
+ state_save_register_global(decoprot_buffer_ram_selected);
+ state_save_register_global_array(decoprot_buffer_ram);
+ state_save_register_global_array(decoprot_buffer_ram2);
+}
+
+/***************************************************************************/
+
+WRITE16_HANDLER( deco16_104_prot_w ) /* Wizard Fire */
+{
+ if (offset==(0x150/2)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ return;
+ }
+
+ if (offset!=(0x150>>1) && offset!=(0x0>>1) && offset!=(0x110>>1) && offset!=(0x280>>1)
+ && offset!=(0x290>>1) && offset!=(0x2b0>>1) && offset!=(0x370>>1) && offset!=(0x3c0>>1)
+ && offset!=(0x370>>1) && offset!=(0x3c0>>1) && offset!=(0x430>>1) && offset!=(0x460>>1)
+ && offset!=(0x5a0>>1) && offset!=(0x5b0>>1) && offset!=(0x6e0>>1) && offset!=(0x7d0>>1)
+ )
+ logerror("CONTROL PC %06x: warning - write protection memory address %04x %04x\n",activecpu_get_pc(),offset<<1,data);
+
+ COMBINE_DATA(&deco16_prot_ram[offset]);
+}
+
+READ16_HANDLER( deco16_104_prot_r ) /* Wizard Fire */
+{
+ switch (offset<<1) {
+ case 0x110: /* Player input */
+ return readinputport(0);
+
+ case 0x36c: /* Coins */
+ case 0x334: /* Probably also, c6, 2c0, 2e0, 4b2, 46a, 4da, rohga is 44c */
+ return readinputport(1);
+ case 0x0dc:
+ return readinputport(1)<<4;
+
+ case 0x494: /* Dips */
+ return readinputport(2);
+
+ case 0x244:
+ return deco16_prot_ram[0];
+ case 0x7cc:
+ return ((deco16_prot_ram[0]&0x000f)<<12) | ((deco16_prot_ram[0]&0x00f0)<<4) | ((deco16_prot_ram[0]&0x0f00)>>4) | ((deco16_prot_ram[0]&0xf000)>>12);
+ case 0x0c0:
+ return (((deco16_prot_ram[0]&0x000e)>>1) | ((deco16_prot_ram[0]&0x0001)<<3))<<12;
+ case 0x188:
+ return (((deco16_prot_ram[0]&0x000e)>>1) | ((deco16_prot_ram[0]&0x0001)<<3))<<12;
+ case 0x65e:
+ return (((deco16_prot_ram[0]&0x000c)>>2) | ((deco16_prot_ram[0]&0x0003)<<2))<<12;
+ case 0x5ce:
+ return ((deco16_prot_ram[0]<<8)&0xf000) | ((deco16_prot_ram[0]&0xe)<<7) | ((deco16_prot_ram[0]&0x1)<<11);
+ case 0x61a:
+ return (deco16_prot_ram[0]<<8)&0xff00;
+
+ case 0x496:
+ return deco16_prot_ram[0x110/2];
+ case 0x40a:
+ return ((deco16_prot_ram[0x110/2]&0x000f)<<12) | ((deco16_prot_ram[0x110/2]&0x00f0)>>4) | ((deco16_prot_ram[0x110/2]&0x0f00)<<0) | ((deco16_prot_ram[0x110/2]&0xf000)>>8);
+ case 0x1e8:
+ return ((deco16_prot_ram[0x110/2]&0x00ff)<<8) | ((deco16_prot_ram[0x110/2]&0xff00)>>8);
+ case 0x4bc:
+ return ((deco16_prot_ram[0x110/2]&0x0ff0)<<4) | ((deco16_prot_ram[0x110/2]&0x0003)<<6) | ((deco16_prot_ram[0x110/2]&0x000c)<<2);
+ case 0x46e:
+ return ((deco16_prot_ram[0x110/2]&0xfff0)<<0) | ((deco16_prot_ram[0x110/2]&0x0007)<<1) | ((deco16_prot_ram[0x110/2]&0x0008)>>3);
+ case 0x264:
+ return ((deco16_prot_ram[0x110/2]&0x000f)<<8) | ((deco16_prot_ram[0x110/2]&0x00f0)>>0) | ((deco16_prot_ram[0x110/2]&0x0f00)<<4);
+ case 0x172:
+ return ((deco16_prot_ram[0x110/2]&0x000f)<<4) | ((deco16_prot_ram[0x110/2]&0x00f0)<<4) | ((deco16_prot_ram[0x110/2]&0xf000)<<0);
+
+ case 0x214:
+ return deco16_prot_ram[0x280/2];
+ case 0x52e:
+ return ((deco16_prot_ram[0x280/2]&0x000f)<<8) | ((deco16_prot_ram[0x280/2]&0x00f0)>>0) | ((deco16_prot_ram[0x280/2]&0x0f00)>>8) | ((deco16_prot_ram[0x280/2]&0xf000)>>0);
+ case 0x07a:
+ return ((deco16_prot_ram[0x280/2]&0x000f)<<8) | ((deco16_prot_ram[0x280/2]&0x00f0)>>0) | ((deco16_prot_ram[0x280/2]&0x0f00)>>8) | ((deco16_prot_ram[0x280/2]&0xf000)>>0);
+ case 0x360:
+ return ((deco16_prot_ram[0x280/2]&0x000f)<<8) | ((deco16_prot_ram[0x280/2]&0x00f0)>>0) | ((deco16_prot_ram[0x280/2]&0x0f00)>>8) | ((deco16_prot_ram[0x280/2]&0xf000)>>0);
+ case 0x4dc:
+ return ((deco16_prot_ram[0x280/2]&0x0ff0)<<4) | ((deco16_prot_ram[0x280/2]&0x0007)<<5) | ((deco16_prot_ram[0x280/2]&0x0008)<<1);
+ case 0x3a8:
+ return ((deco16_prot_ram[0x280/2]&0x000e)<<3) | ((deco16_prot_ram[0x280/2]&0x0001)<<7) | ((deco16_prot_ram[0x280/2]&0x0ff0)<<4) | ((deco16_prot_ram[0x280/2]&0xf000)>>12);
+ case 0x2f6:
+ return ((deco16_prot_ram[0x280/2]&0xff00)>>8) | ((deco16_prot_ram[0x280/2]&0x00f0)<<8) | ((deco16_prot_ram[0x280/2]&0x000c)<<6) | ((deco16_prot_ram[0x280/2]&0x0003)<<10);
+
+ case 0x7e4:
+ return (deco16_prot_ram[0x290/2]&0x00f0)<<8;
+
+ case 0x536:
+ return ((deco16_prot_ram[0x2b0/2]&0x000f)<<8) | ((deco16_prot_ram[0x2b0/2]&0x00f0)<<0) | ((deco16_prot_ram[0x2b0/2]&0x0f00)<<4) | ((deco16_prot_ram[0x2b0/2]&0xf000)>>12);
+
+ case 0x0be:
+ return ((deco16_prot_ram[0x370/2]&0x000f)<<4) | ((deco16_prot_ram[0x370/2]&0x00f0)<<4) | ((deco16_prot_ram[0x370/2]&0x0f00)>>8) | ((deco16_prot_ram[0x370/2]&0xf000)>>0);
+
+ case 0x490:
+ return (deco16_prot_ram[0x3c0/2]&0xfff0) | ((deco16_prot_ram[0x3c0/2]&0x0007)<<1) | ((deco16_prot_ram[0x3c0/2]&0x0008)>>3);
+
+ case 0x710:
+ return (deco16_prot_ram[0x430/2]&0xfff0) | ((deco16_prot_ram[0x430/2]&0x0007)<<1) | ((deco16_prot_ram[0x430/2]&0x0008)>>3);
+
+ case 0x22a:
+ return ((deco16_prot_ram[0x5a0/2]&0xff00)>>8) | ((deco16_prot_ram[0x5a0/2]&0x00f0)<<8) | ((deco16_prot_ram[0x5a0/2]&0x0001)<<11) | ((deco16_prot_ram[0x5a0/2]&0x000e)<<7);
+
+ case 0x626:
+ return ((deco16_prot_ram[0x5b0/2]&0x000f)<<8) | ((deco16_prot_ram[0x5b0/2]&0x00f0)<<8) | ((deco16_prot_ram[0x5b0/2]&0x0f00)>>4) | ((deco16_prot_ram[0x5b0/2]&0xf000)>>12);
+
+ case 0x444:
+ return deco16_prot_ram[0x604/2]; //rohga
+
+ case 0x5ac:
+ return ((deco16_prot_ram[0x6e0/2]&0xfff0)>>4) | ((deco16_prot_ram[0x6e0/2]&0x0007)<<13) | ((deco16_prot_ram[0x6e0/2]&0x0008)<<9);
+
+ case 0x650:
+ return ((deco16_prot_ram[0x7d0/2]&0xfff0)>>4) | ((deco16_prot_ram[0x7d0/2]&0x000f)<<12);
+
+ case 0x4ac:
+ return ((deco16_prot_ram[0x460/2]&0x0007)<<13) | ((deco16_prot_ram[0x460/2]&0x0008)<<9);
+ }
+
+ logerror("Deco Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return 0;
+}
+
+/***************************************************************************/
+
+WRITE16_HANDLER( deco16_60_prot_w ) /* Edward Randy */
+{
+ if (offset==(0x64/2)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ }
+
+ COMBINE_DATA(&deco16_prot_ram[offset]);
+
+// 0 4 2c 32 34 36 3c 3e 40 54 56 58 6a 76 80 84 88 8a 8c 8e 90 92 94 96 9e a0 a2 a4 a6 a8 aa ac ae b0
+
+if (offset!=0x32 && offset!=0x36/2 && offset!=0x9e/2 && offset!=0x76/2
+ && offset!=4/2 && offset!=0x2c/2 && offset!=0x3c/2 && offset!=0x3e/2
+ && offset!=0x80/2 && offset!=0x84/2 &&offset!=0x88/2 && offset!=0x8c/2 && offset!=0x90/2 && offset!=0x94/2
+ && offset!=0xa0/2 &&offset!=0xa2/2 && offset!=0xa4/2 && offset!=0xa6/2 && offset!=0xa8/2
+ && offset!=0xaa/2 && offset!=0xac/2 && offset!=0xae/2 && offset!=0xb0/2
+ && (offset<0xd0/2 || offset>0xe0/2)
+ && (offset<4 || offset>17)
+ && offset!=0x40/2 && offset!=0x54/2 && offset!=0x56/2 && offset!=0x58/2 && offset!=0x6a/2 && offset!=0x2c/2
+ && offset!=0 && offset!=0x34 && offset!=0x8a && offset!=0x8e && offset!=0x92 && offset!=0x96
+ )
+logerror("Protection PC %06x: warning - write %04x to %04x\n",activecpu_get_pc(),data,offset<<1);
+
+}
+
+READ16_HANDLER( deco16_60_prot_r ) /* Edward Randy */
+{
+ switch (offset<<1) {
+ /* Video registers */
+ case 0x32a: /* Moved to 0x140006 on int */
+ return deco16_prot_ram[0x80/2];
+ case 0x380: /* Moved to 0x140008 on int */
+ return deco16_prot_ram[0x84/2];
+ case 0x63a: /* Moved to 0x150002 on int */
+ return deco16_prot_ram[0x88/2];
+ case 0x42a: /* Moved to 0x150004 on int */
+ return deco16_prot_ram[0x8c/2];
+ case 0x030: /* Moved to 0x150006 on int */
+ return deco16_prot_ram[0x90/2];
+ case 0x6b2: /* Moved to 0x150008 on int */
+ return deco16_prot_ram[0x94/2];
+
+ case 0x6fa:
+ return deco16_prot_ram[0x4/2];
+ case 0xe4:
+ return (deco16_prot_ram[0x4/2]&0xf000)|((deco16_prot_ram[0x4/2]&0x00ff)<<4)|((deco16_prot_ram[0x4/2]&0x0f00)>>8);
+
+ case 0x390:
+ return deco16_prot_ram[0x2c/2];
+ case 0x3b2:
+ return deco16_prot_ram[0x3c/2];
+ case 0x440:
+ return deco16_prot_ram[0x3e/2];
+
+ case 0x6fc:
+ return deco16_prot_ram[0x66/2];
+
+ case 0x15a:
+ return deco16_prot_ram[0xa0/2];
+ case 0x102:
+ return deco16_prot_ram[0xa2/2];
+ case 0x566:
+ return deco16_prot_ram[0xa4/2];
+ case 0xd2:
+ return deco16_prot_ram[0xa6/2];
+ case 0x4a6:
+ return deco16_prot_ram[0xa8/2];
+ case 0x3dc:
+ return deco16_prot_ram[0xaa/2];
+ case 0x2a0:
+ return deco16_prot_ram[0xac/2];
+ case 0x392:
+ return deco16_prot_ram[0xae/2];
+ case 0x444:
+ return deco16_prot_ram[0xb0/2];
+
+ case 0x5ea:
+ return deco16_prot_ram[0xb8/2];
+ case 0x358:
+ return deco16_prot_ram[0xba/2];
+ case 0x342:
+ return deco16_prot_ram[0xbc/2];
+ case 0x3c:
+ return deco16_prot_ram[0xbe/2];
+ case 0x656:
+ return deco16_prot_ram[0xc0/2];
+ case 0x18c:
+ return deco16_prot_ram[0xc2/2];
+ case 0x370:
+ return deco16_prot_ram[0xc4/2];
+ case 0x5c6:
+ return deco16_prot_ram[0xc6/2];
+
+ /* C8 written but not read */
+
+ case 0x248:
+ return deco16_prot_ram[0xd0/2];
+ case 0x1ea:
+ return deco16_prot_ram[0xd2/2];
+ case 0x4cc:
+ return deco16_prot_ram[0xd4/2];
+ case 0x724:
+ return deco16_prot_ram[0xd6/2];
+ case 0x578:
+ return deco16_prot_ram[0xd8/2];
+ case 0x63e:
+ return deco16_prot_ram[0xda/2];
+ case 0x4ba:
+ return deco16_prot_ram[0xdc/2];
+ case 0x1a:
+ return deco16_prot_ram[0xde/2];
+ case 0x120:
+ return deco16_prot_ram[0xe0/2];
+ case 0x7c2: /* (Not checked for mask/xor but seems standard) */
+ return deco16_prot_ram[0x50/2];
+
+ /* memcpy selectors, transfer occurs in interrupt */
+ case 0x32e: return deco16_prot_ram[4]; /* src msb */
+ case 0x6d8: return deco16_prot_ram[5]; /* src lsb */
+ case 0x010: return deco16_prot_ram[6]; /* dst msb */
+ case 0x07a: return deco16_prot_ram[7]; /* src lsb */
+
+ case 0x37c: return deco16_prot_ram[8]; /* src msb */
+ case 0x250: return deco16_prot_ram[9];
+ case 0x04e: return deco16_prot_ram[10];
+ case 0x5ba: return deco16_prot_ram[11];
+ case 0x5f4: return deco16_prot_ram[12]; /* length */
+
+ case 0x38c: return deco16_prot_ram[13]; /* src msb */
+ case 0x02c: return deco16_prot_ram[14];
+ case 0x1e6: return deco16_prot_ram[15];
+ case 0x3e4: return deco16_prot_ram[16];
+ case 0x174: return deco16_prot_ram[17]; /* length */
+
+ /* Player 1 & 2 controls, read in IRQ then written *back* to protection device */
+ case 0x50: /* written to 9e byte */
+ return readinputport(0);
+ case 0x6f8: /* written to 76 byte */
+ return (readinputport(0)>>8)|(readinputport(0)<<8); /* byte swap IN0 */
+
+ case 0x5c: /* After coin insert, high 0x8000 bit set starts game */
+ return deco16_prot_ram[0x3b];
+ case 0x3a6: /* Top byte OR'd with above, masked to 7 */
+ return deco16_prot_ram[0x9e/2];
+ case 0xc6:
+ return ((deco16_prot_ram[0x9e/2]&0xff00)>>8) | ((deco16_prot_ram[0x9e/2]&0x00ff)<<8);
+
+ case 0xac: /* Dip switches */
+ return readinputport(2);
+ case 0xc2:
+ return readinputport(2) ^ deco16_prot_ram[0x2c/2];
+
+ case 0x5d4: /* The state of the dips last frame */
+ return deco16_prot_ram[0x34/2];
+
+ case 0x7bc:
+ return ((deco16_prot_ram[0x76/2]&0xff00)>>8) | ((deco16_prot_ram[0x76/2]&0x00ff)<<8);
+
+ case 0x2f6: /* Stage clear flag */
+ return (((deco16_prot_ram[0]&0xfff0)>>0) | ((deco16_prot_ram[0]&0x000c)>>2) | ((deco16_prot_ram[0]&0x0003)<<2)) & (~deco16_prot_ram[0x36/2]);
+
+ case 0x76a: /* Coins */
+ return readinputport(1);
+
+ case 0x284: /* Bit shifting with inverted mask register */
+ return (((deco16_prot_ram[0x40/2]&0xfff0)>>0) | ((deco16_prot_ram[0x40/2]&0x0007)<<1) | ((deco16_prot_ram[0x40/2]&0x0008)>>3)) & (~deco16_prot_ram[0x36/2]);
+ case 0x6c4: /* Bit shifting with inverted mask register */
+ return (((deco16_prot_ram[0x54/2]&0xf000)>>4) | ((deco16_prot_ram[0x54/2]&0x0f00)>>4) | ((deco16_prot_ram[0x54/2]&0x00f0)>>4) | ((deco16_prot_ram[0x54/2]&0x0003)<<14) | ((deco16_prot_ram[0x54/2]&0x000c)<<10)) & (~deco16_prot_ram[0x36/2]);
+ case 0x33e: /* Bit shifting with inverted mask register */
+ return (((deco16_prot_ram[0x56/2]&0xff00)>>0) | ((deco16_prot_ram[0x56/2]&0x00f0)>>4) | ((deco16_prot_ram[0x56/2]&0x000f)<<4)) & (~deco16_prot_ram[0x36/2]);
+ case 0x156: /* Bit shifting with inverted mask register */
+ return (((deco16_prot_ram[0x58/2]&0xfff0)>>4) | ((deco16_prot_ram[0x58/2]&0x000e)<<11) | ((deco16_prot_ram[0x58/2]&0x0001)<<15)) & (~deco16_prot_ram[0x36/2]);
+ case 0x286: /* Bit shifting with inverted mask register */
+ return (((deco16_prot_ram[0x6a/2]&0x00f0)<<4) | ((deco16_prot_ram[0x6a/2]&0x0f00)<<4) | ((deco16_prot_ram[0x6a/2]&0x0007)<<5) | ((deco16_prot_ram[0x6a/2]&0x0008)<<1)) & (~deco16_prot_ram[0x36/2]);
+
+ case 0x7d6: /* XOR IN0 */
+ return readinputport(0) ^ deco16_prot_ram[0x2c/2];
+ case 0x4b4:
+ return ((deco16_prot_ram[0x32/2]&0x00f0)<<8) | ((deco16_prot_ram[0x32/2]&0x000e)<<7) | ((deco16_prot_ram[0x32/2]&0x0001)<<11);
+ }
+
+ logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset*2);
+ return 0;
+}
+
+/***************************************************************************/
+
+static int mutantf_port_0e_hack=0, mutantf_port_6a_hack=0,mutantf_port_e8_hack=0;
+
+WRITE16_HANDLER( deco16_66_prot_w ) /* Mutant Fighter */
+{
+ if (offset==(0x64/2)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ return;
+ }
+
+ COMBINE_DATA(&deco16_prot_ram[offset]);
+
+ /* See below */
+ if (offset==(0xe/2))
+ mutantf_port_0e_hack=data;
+ else
+ mutantf_port_0e_hack=0x800;
+
+ if (offset==(0x6a/2))
+ mutantf_port_6a_hack=data;
+ else
+ mutantf_port_6a_hack=0x2866;
+
+ if (offset==(0xe8/2))
+ mutantf_port_e8_hack=data;
+ else
+ mutantf_port_e8_hack=0x2401;
+
+// 2 4 c e 18 1e 22 2c 2e 34 36 38 3a 42 48 58 6a 72 7a 82 88 92 a2 a4 aa b0 b6 b8 dc e4 e8 f4 fa 1c8 308 7e8 40e
+ offset=offset<<1;
+ if (offset!=0x02 && offset!=0xc && offset!=0xe && offset!=0x18 && offset!=0x2c && offset!=0x2e && offset!=0x34
+ && offset!=0x42 && offset!=0x58 && offset!=0x6a && offset!=0x72 && offset!=0x7a && offset!=0xb8
+ && offset!=0xdc && offset!=0xe8 && offset!=0xf4 && offset!=0x1c8 && offset!=0x7e8
+ && offset!=0xe && offset!=0x48 && offset!=0xaa && offset!=0xb0 && offset!=0x36
+ && offset!=0xa4 && offset!=0x4 && offset!=0x82 && offset!=0x88 && offset!=0x22
+ && offset!=0xb6 && offset!=0xfa && offset!=0xe4 && offset!=0x3a && offset!=0x1e
+ && offset!=0x38 && offset!=0x92 && offset!=0xa2 && offset!=0x308 && offset!=0x40e
+ )
+ logerror("Protection PC %06x: warning - write %04x to %04x\n",activecpu_get_pc(),data,offset);
+}
+
+READ16_HANDLER( deco16_66_prot_r ) /* Mutant Fighter */
+{
+ if (offset!=0xe/2)
+ mutantf_port_0e_hack=0x0800;
+ if (offset!=0x6a/2)
+ mutantf_port_6a_hack=0x2866;
+
+ switch (offset*2) {
+ case 0xac: /* Dip switches */
+ return readinputport(2);
+ case 0xc2: /* Dip switches */
+ return readinputport(2) ^ deco16_prot_ram[0x2c/2];
+ case 0x46: /* Coins */
+ return readinputport(1) ^ deco16_prot_ram[0x2c/2];
+ case 0x50: /* Player 1 & 2 input ports */
+ return readinputport(0);
+ case 0x63c: /* Player 1 & 2 input ports */
+ return readinputport(0) ^ deco16_prot_ram[0x2c/2];
+
+ case 0x5f4:
+ return deco16_prot_ram[0x18/2];
+ case 0x7e8:
+ return deco16_prot_ram[0x58/2];
+ case 0x1c8:
+ return deco16_prot_ram[0x6a/2];
+ case 0x10:
+ return deco16_prot_ram[0xc/2];
+ case 0x672:
+ return deco16_prot_ram[0x72/2];
+ case 0x5ea:
+ return deco16_prot_ram[0xb8/2];
+ case 0x1e8:
+ return deco16_prot_ram[0x2/2];
+ case 0xf6:
+ return deco16_prot_ram[0x42/2];
+ case 0x692:
+ return deco16_prot_ram[0x2e/2];
+ case 0x63a:
+ return deco16_prot_ram[0x88/2];
+ case 0x7a:
+ return deco16_prot_ram[0xe/2];
+ case 0x40e:
+ return deco16_prot_ram[0x7a/2];
+ case 0x602:
+ return deco16_prot_ram[0x92/2];
+ case 0x5d4:
+ return deco16_prot_ram[0x34/2];
+ case 0x6fa:
+ return deco16_prot_ram[0x4/2];
+ case 0x3dc:
+ return deco16_prot_ram[0xaa/2];
+ case 0x444:
+ return deco16_prot_ram[0xb0/2];
+ case 0x102:
+ return deco16_prot_ram[0xa2/2];
+ case 0x458:
+ return deco16_prot_ram[0xb6/2];
+ case 0x2a6:
+ return deco16_prot_ram[0xe8/2];
+ case 0x626:
+ return deco16_prot_ram[0xf4/2];
+ case 0x762:
+ return deco16_prot_ram[0x82/2];
+ case 0x308:
+ return deco16_prot_ram[0x38/2];
+ case 0x1e6:
+ return deco16_prot_ram[0x1e/2];
+ case 0x566:
+ return deco16_prot_ram[0xa4/2];
+ case 0x5b6:
+ return deco16_prot_ram[0xe4/2];
+ case 0x77c:
+ return deco16_prot_ram[0xfa/2];
+ case 0x4ba:
+ return deco16_prot_ram[0xdc/2];
+
+ case 0x1e:
+ return deco16_prot_ram[0xf4/2] ^ deco16_prot_ram[0x2c/2];
+ case 0x18e:
+ return ((deco16_prot_ram[0x1e/2]&0x000f)<<12) | ((deco16_prot_ram[0x1e/2]&0x0ff0)>>0) | ((deco16_prot_ram[0x1e/2]&0xf000)>>12);
+ case 0x636:
+ return ((deco16_prot_ram[0x18/2]&0x00ff)<<8) | ((deco16_prot_ram[0x18/2]&0x0f00)>>4) | ((deco16_prot_ram[0x18/2]&0xf000)>>12);
+ case 0x7d4:
+ return ((deco16_prot_ram[0xc/2]&0x0ff0)<<4) | ((deco16_prot_ram[0xc/2]&0x000c)<<2) | ((deco16_prot_ram[0xc/2]&0x0003)<<6);
+ case 0x542:
+ return ((deco16_prot_ram[0x92/2]&0x00ff)<<8) ^ deco16_prot_ram[0x2c/2];
+ case 0xb0:
+ return (((deco16_prot_ram[0xc/2]&0x000f)<<12) | ((deco16_prot_ram[0xc/2]&0x00f0)<<4) | ((deco16_prot_ram[0xc/2]&0xff00)>>8)) ^ deco16_prot_ram[0x2c/2];
+ case 0x4:
+ return (((deco16_prot_ram[0x18/2]&0x00f0)<<8) | ((deco16_prot_ram[0x18/2]&0x0003)<<10) | ((deco16_prot_ram[0x18/2]&0x000c)<<6)) & (~deco16_prot_ram[0x36/2]);
+
+ case 0xe: /* On real hardware this value only seems to persist for 1 read or write, then reverts to 0800. Hmm */
+ {
+ int ret=mutantf_port_0e_hack;
+ mutantf_port_0e_hack=0x800;
+ //logerror("Protection PC %06x: warning - read unknown memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return ret;
+ }
+
+ case 0x6a: /* On real hardware this value only seems to persist for 1 read or write, then reverts to 0x2866. Hmm */
+ {
+ int ret=mutantf_port_6a_hack;
+ mutantf_port_6a_hack=0x2866;
+ //logerror("Protection PC %06x: warning - read unknown memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return ret;
+ }
+
+ case 0xe8: /* On real hardware this value only seems to persist for 1 read or write, then reverts to 0x2401. Hmm */
+ {
+ int ret=mutantf_port_e8_hack;
+ mutantf_port_e8_hack=0x2401;
+ //logerror("Protection PC %06x: warning - read unknown memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return ret;
+ }
+
+ case 0xaa: /* ??? */
+ //logerror("Protection PC %06x: warning - read unknown memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return 0xc080;
+
+ case 0x42: /* Strange, but consistent */
+ //logerror("Protection PC %06x: warning - read unknown memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return deco16_prot_ram[0x2c/2]^0x5302;
+
+ case 0x48: /* Correct for test data, but I wonder if the 0x1800 is from an address, not a constant */
+ //logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return (0x1800) & (~deco16_prot_ram[0x36/2]);
+
+ case 0x52:
+ return (0x2188) & (~deco16_prot_ram[0x36/2]);
+
+ case 0x82:
+ return ((0x0022 ^ deco16_prot_ram[0x2c/2])) & (~deco16_prot_ram[0x36/2]);
+
+ case 0xc:
+ return 0x2000;
+ }
+
+#ifdef MAME_DEBUG
+ popmessage("Deco66: Read unmapped port %04x\n",offset*2);
+#endif
+
+ logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset<<1);
+ return 0;
+}
+
+/***************************************************************************/
+
+WRITE16_HANDLER( deco16_104_cninja_prot_w )
+{
+ if (offset==(0xa8/2)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ return;
+ }
+
+ COMBINE_DATA(&deco16_prot_ram[offset]);
+}
+
+READ16_HANDLER( deco16_104_cninja_prot_r )
+{
+ switch (offset<<1) {
+ case 0x80: /* Master level control */
+ return deco16_prot_ram[0];
+
+ case 0xde: /* Restart position control */
+ return deco16_prot_ram[1];
+
+ case 0xe6: /* The number of credits in the system. */
+ return deco16_prot_ram[2];
+
+ case 0x86: /* End of game check. See 0x1814 */
+ return deco16_prot_ram[3];
+
+ /* Video registers */
+ case 0x5a: /* Moved to 0x140000 on int */
+ return deco16_prot_ram[8];
+ case 0x84: /* Moved to 0x14000a on int */
+ return deco16_prot_ram[9];
+ case 0x20: /* Moved to 0x14000c on int */
+ return deco16_prot_ram[10];
+ case 0x72: /* Moved to 0x14000e on int */
+ return deco16_prot_ram[11];
+ case 0xdc: /* Moved to 0x150000 on int */
+ return deco16_prot_ram[12];
+ case 0x6e: /* Moved to 0x15000a on int */
+ return deco16_prot_ram[13]; /* Not used on bootleg */
+ case 0x6c: /* Moved to 0x15000c on int */
+ return deco16_prot_ram[14];
+ case 0x08: /* Moved to 0x15000e on int */
+ return deco16_prot_ram[15];
+
+ case 0x36: /* Dip switches */
+ return readinputport(2);
+
+ case 0x1c8: /* Coins */
+ return readinputport(1);
+
+ case 0x22c: /* Player 1 & 2 input ports */
+ return readinputport(0);
+ }
+
+ logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset);
+ return 0;
+}
+
+/***************************************************************************/
+
+WRITE16_HANDLER( deco16_146_funkyjet_prot_w )
+{
+ COMBINE_DATA(&deco16_prot_ram[offset]);
+
+ if (offset == (0x10a >> 1)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ return;
+ }
+}
+
+READ16_HANDLER( deco16_146_funkyjet_prot_r )
+{
+ switch (offset)
+ {
+ case 0x0be >> 1:
+ return deco16_prot_ram[0x106>>1];
+ case 0x11e >> 1:
+ return deco16_prot_ram[0x500>>1];
+
+ case 0x148 >> 1: /* EOR mask for joysticks */
+ return deco16_prot_ram[0x70e>>1];
+
+ case 0x1da >> 1:
+ return deco16_prot_ram[0x100>>1];
+ case 0x21c >> 1:
+ return deco16_prot_ram[0x504>>1];
+ case 0x226 >> 1:
+ return deco16_prot_ram[0x58c>>1];
+ case 0x24c >> 1:
+ return deco16_prot_ram[0x78e>>1];
+ case 0x250 >> 1:
+ return deco16_prot_ram[0x304>>1];
+ case 0x2d4 >> 1:
+ return deco16_prot_ram[0x102>>1];
+ case 0x2d8 >> 1: /* EOR mask for credits */
+ return deco16_prot_ram[0x502>>1];
+
+ case 0x3a6 >> 1:
+ return deco16_prot_ram[0x104>>1];
+ case 0x3a8 >> 1: /* See 93e4/9376 */
+ return deco16_prot_ram[0x500>>1];
+ case 0x3e8 >> 1:
+ return deco16_prot_ram[0x50c>>1];
+
+ case 0x4e4 >> 1:
+ return deco16_prot_ram[0x702>>1];
+ case 0x562 >> 1:
+ return deco16_prot_ram[0x18e>>1];
+ case 0x56c >> 1:
+ return deco16_prot_ram[0x50c>>1];
+
+ case 0x688 >> 1:
+ return deco16_prot_ram[0x300>>1];
+ case 0x788 >> 1:
+ return deco16_prot_ram[0x700>>1];
+
+ case 0x7d4 >> 1: /* !? On the bootleg these address checks are NOP'd, so a BEQ is never taken */
+ return 0x10; //deco16_prot_ram[0x7da>>1];
+
+ case 0x27c >>1: /* From bootleg code at 0x400 */
+ return ((deco16_prot_ram[0x70e>>1]>>4)&0x0fff) | ((deco16_prot_ram[0x70e>>1]&0x0001)<<15) | ((deco16_prot_ram[0x70e>>1]&0x000e)<<11);
+ case 0x192 >>1: /* From bootleg code at 0x400 */
+ return ((deco16_prot_ram[0x78e>>1]<<0)&0xf000);
+
+ case 0x5be >> 1: /* Confirmed from bootleg code at 0xc07c */
+ return ((deco16_prot_ram[0x70e>>1]<<4)&0xff00) | (deco16_prot_ram[0x70e>>1]&0x000f);
+ case 0x5ca >> 1: /* Confirmed from bootleg code at 0xc05e */
+ return ((deco16_prot_ram[0x78e>>1]>>4)&0xff00) | (deco16_prot_ram[0x78e>>1]&0x000f) | ((deco16_prot_ram[0x78e>>1]<<8)&0xf000);
+
+ case 0x00c >> 1: /* Player 1 & Player 2 joysticks & fire buttons */
+ return (readinputport(0) + (readinputport(1) << 8));
+ case 0x778 >> 1: /* Credits */
+ return readinputport(2);
+ case 0x382 >> 1: /* DIPS */
+ return (readinputport(3) + (readinputport(4) << 8));
+ }
+
+ if (activecpu_get_pc()!=0xc0ea) logerror("CPU #0 PC %06x: warning - read unmapped control address %06x\n",activecpu_get_pc(),offset<<1);
+
+ 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]);
+
+ if (offset==(0xa8/2)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,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",activecpu_get_pc(),offset,data);
+ if (offset==0xee || offset==0x42 || offset==0xa8)
+ return;
+
+// logerror("CONTROL PC %06x: warning - write protection memory address %04x %04x\n",activecpu_get_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",activecpu_get_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",activecpu_get_pc(),offset,data);
+}
+
+READ16_HANDLER( deco16_104_rohga_prot_r )
+{
+ 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",activecpu_get_pc(),offset<<1);
+
+ switch (offset) {
+ case 0x88/2: /* Player 1 & 2 input ports */
+ return readinputport(0);
+ case 0x36c/2:
+ return readinputport(1);
+ case 0x44c/2:
+
+ return ((readinputport(1)&0x7)<<13)|((readinputport(1)&0x8)<<9);
+ case 0x292/2: /* Dips */
+ return readinputport(2);
+
+ case 0x44/2:
+ return ((((DECO_PORT(0x2c)&0x000f)<<12)) ^ deco16_xor) & (~deco16_mask);
+ case 0x282/2:
+ return ((DECO_PORT(0x26)&0x000f)<<12) & (~deco16_mask);
+ case 0xd4/2:
+ return ((DECO_PORT(0x6e)&0x0ff0)<<4) | ((DECO_PORT(0x6e)&0x000e)<<3) | ((DECO_PORT(0x6e)&0x0001)<<7);
+ case 0x5a2/2:
+ return (((DECO_PORT(0x24)&0xff00)>>4) | ((DECO_PORT(0x24)&0x000f)<<0) | ((DECO_PORT(0x24)&0x00f0)<<8)) & (~deco16_mask);
+ case 0x570/2:
+ return (((DECO_PORT(0x24)&0xf0f0)>>0) | ((DECO_PORT(0x24)&0x000f)<<8)) ^ deco16_xor;
+ case 0x32e/2:
+ return (((DECO_PORT(0x46)&0xf000)>>0) | ((DECO_PORT(0x46)&0x00ff)<<4)) & (~deco16_mask);
+ case 0x4dc/2:
+ return ((DECO_PORT(0x62)&0x00ff)<<8);
+ case 0x1be/2:
+ return ((((DECO_PORT(0xc2)&0x0ff0)<<4) | ((DECO_PORT(0xc2)&0x0003)<<6) | ((DECO_PORT(0xc2)&0x000c)<<2)) ^ deco16_xor) & (~deco16_mask);
+
+ case 0x420/2:
+ return ((DECO_PORT(0x2e)&0xf000)>>4) | ((DECO_PORT(0x2e)&0x0f00)<<4) | ((DECO_PORT(0x2e)&0x00f0)>>4) | ((DECO_PORT(0x2e)&0x000f)<<4);
+
+ case 0x390/2:
+ return DECO_PORT(0x2c);
+
+ case 0x756/2:
+ return ((DECO_PORT(0x60)&0xfff0)>>4) | ((DECO_PORT(0x60)&0x0007)<<13) | ((DECO_PORT(0x60)&0x0008)<<9);
+ case 0x424/2:
+ return ((DECO_PORT(0x60)&0xf000)>>4) | ((DECO_PORT(0x60)&0x0f00)<<4) | ((DECO_PORT(0x60)&0x00f0)>>0) | ((DECO_PORT(0x60)&0x000f)<<0);
+
+ case 0x156/2:
+ return (((DECO_PORT(0xde)&0xff00)<<0) | ((DECO_PORT(0xde)&0x000f)<<4) | ((DECO_PORT(0xde)&0x00f0)>>4)) & (~deco16_mask);
+ case 0xa8/2:
+ return (((DECO_PORT(0xde)&0xff00)>>4) | ((DECO_PORT(0xde)&0x000f)<<0) | ((DECO_PORT(0xde)&0x00f0)<<8)) & (~deco16_mask);
+ case 0x64a/2:
+ return (((DECO_PORT(0xde)&0xfff0)>>4) | ((DECO_PORT(0xde)&0x000c)<<10) | ((DECO_PORT(0xde)&0x0003)<<14)) & (~deco16_mask);
+
+ case 0x16e/2:
+ return DECO_PORT(0x6a);
+
+ case 0x39c/2:
+ return (DECO_PORT(0x6a)&0x00ff) | ((DECO_PORT(0x6a)&0xf000)>>4) | ((DECO_PORT(0x6a)&0x0f00)<<4);
+ case 0x212/2:
+ return (((DECO_PORT(0x6e)&0xff00)>>4) | ((DECO_PORT(0x6e)&0x00f0)<<8) | ((DECO_PORT(0x6e)&0x000f)<<0)) ^ deco16_xor;
+
+ case 0x70a/2:
+ return (((DECO_PORT(0xde)&0x00f0)<<8) | ((DECO_PORT(0xde)&0x0007)<<9) | ((DECO_PORT(0xde)&0x0008)<<5)) ^ deco16_xor;
+
+ case 0x7a0/2:
+ return (DECO_PORT(0x6e)&0x00ff) | ((DECO_PORT(0x6e)&0xf000)>>4) | ((DECO_PORT(0x6e)&0x0f00)<<4);
+ case 0x162/2:
+ return DECO_PORT(0x6e);
+
+ case 0x384/2:
+ return ((DECO_PORT(0xdc)&0xf000)>>12) | ((DECO_PORT(0xdc)&0x0ff0)<<4) | ((DECO_PORT(0xdc)&0x000c)<<2) | ((DECO_PORT(0xdc)&0x0003)<<6);
+
+ case 0x302/2:
+ return DECO_PORT(0x24);
+ case 0x334/2:
+ return DECO_PORT(0x30);
+ case 0x34c/2:
+ return DECO_PORT(0x3c);
+
+ case 0x514/2:
+ return (((DECO_PORT(0x32)&0x0ff0)<<4) | ((DECO_PORT(0x32)&0x000c)<<2) | ((DECO_PORT(0x32)&0x0003)<<6)) & (~deco16_mask);
+
+ 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 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 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 0x1e/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 0x6e/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 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 0x2c/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);
+ case 0x41a/2:
+ return ((((DECO_PORT(0x84)&0x00f0)<<8) | ((DECO_PORT(0x84)&0xf000)>>8) | ((DECO_PORT(0x84)&0x0f00)>>8) | ((DECO_PORT(0x84)&0x0003)<<10) | ((DECO_PORT(0x84)&0x000c)<<6)) ^ deco16_xor);
+ case 0x168/2:
+ return ((((DECO_PORT(0x84)&0x0ff0)<<4) | ((DECO_PORT(0x84)&0x000e)<<3) | ((DECO_PORT(0x84)&0x0001)<<5))) & (~deco16_mask);
+ 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 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);
+
+ case 0x22c/2:
+ return ((DECO_PORT(0xc4)&0x00f0)<<8);
+ case 0x77e/2:
+ return ((DECO_PORT(0x62)&0xf000)>>12) | ((DECO_PORT(0x62)&0x0ff0)<<0) | ((DECO_PORT(0x62)&0x000f)<<12);
+ case 0xc/2:
+ return ((DECO_PORT(0xd6)&0xf000)>>12) | ((DECO_PORT(0xd6)&0x0fff)<<4);
+
+ case 0x90/2:
+ return DECO_PORT(0x44);
+ case 0x246/2:
+ return ((((DECO_PORT(0x48)&0xff00)>>8) | ((DECO_PORT(0x48)&0x00f0)<<8) | ((DECO_PORT(0x48)&0x0f00)>>8) | ((DECO_PORT(0x48)&0x0003)<<10) | ((DECO_PORT(0x48)&0x000c)<<6)) ^ deco16_xor);
+ case 0x546/2:
+ return (((DECO_PORT(0x62)&0xf0f0)>>0) | ((DECO_PORT(0x62)&0x000f)<<8)) & (~deco16_mask);
+ case 0x2e2/2:
+ return ((DECO_PORT(0xc6)&0x000e)<<11) | ((DECO_PORT(0xc6)&0x0001)<<15);
+ case 0x3c0/2:
+ return DECO_PORT(0x22);
+ case 0x4b8/2:
+ return (((DECO_PORT(0x46)&0xf000)>>12) | ((DECO_PORT(0x46)&0x0f00)>>4) | ((DECO_PORT(0x46)&0x00ff)<<8)) ^ deco16_xor;
+ case 0x65c/2:
+ return ((((DECO_PORT(0x44)&0xf000)>>12) | ((DECO_PORT(0x44)&0x0fff)<<4)) ^ deco16_xor) & (~deco16_mask);
+
+ case 0x32a/2:
+ return ((((DECO_PORT(0xc0)&0x0ff0)<<4) | ((DECO_PORT(0xc0)&0x000e)<<3) | ((DECO_PORT(0xc0)&0x0001)<<7))) & (~deco16_mask);// ^ deco16_xor;
+ case 0x8/2:
+ return ((((DECO_PORT(0x94)&0xfff0)<<0) | ((DECO_PORT(0x94)&0x000e)>>1) | ((DECO_PORT(0x94)&0x0001)<<3))) & (~deco16_mask);// ^ deco16_xor;
+ case 0x456/2:
+ return (((DECO_PORT(0x26)&0xfff0)<<0) | ((DECO_PORT(0x26)&0x0007)<<1) | ((DECO_PORT(0x26)&0x0008)>>3));// ^ deco16_xor;
+ case 0x190/2:
+ return ((((DECO_PORT(0x44)&0xf000)<<0) | ((DECO_PORT(0x44)&0x00ff)<<4))) & (~deco16_mask);// ^ deco16_xor;
+ case 0x3f2/2:
+ return ((((DECO_PORT(0x48)&0x000f)<<12) | ((DECO_PORT(0x48)&0x00f0)<<4))) & (~deco16_mask);// ^ deco16_xor;
+ case 0x2be/2:
+ return ((DECO_PORT(0x40)&0x00ff)<<8);
+
+ case 0x19e/2:
+ return ((((DECO_PORT(0x3c)&0xf000)>>12) | ((DECO_PORT(0x3c)&0x0f00)<<4) | ((DECO_PORT(0x3c)&0x00f0)>>0) | ((DECO_PORT(0x3c)&0x000f)<<8)) ^ deco16_xor) & (~deco16_mask);
+ case 0x2a2/2:
+ return ((((DECO_PORT(0x44)&0xff00)>>8) | ((DECO_PORT(0x44)&0x00f0)<<8) | ((DECO_PORT(0x44)&0x000e)<<7) | ((DECO_PORT(0x44)&0x0001)<<11)) ^ deco16_xor) & (~deco16_mask);
+ case 0x748/2:
+ return (((DECO_PORT(0x44)&0xfff0)<<0) | ((DECO_PORT(0x44)&0x000e)>>1) | ((DECO_PORT(0x44)&0x0001)<<3));// & (~deco16_mask);
+ case 0x686/2:
+ return (((DECO_PORT(0x46)&0xf000)>>4) | ((DECO_PORT(0x46)&0x0f00)>>8) | ((DECO_PORT(0x46)&0x00f0)<<8) | ((DECO_PORT(0x46)&0x000f)<<4));// & (~deco16_mask);
+ case 0x4c4/2:
+ return ((DECO_PORT(0x3c)&0x000f)<<12) & (~deco16_mask);
+ case 0x538/2:
+ return ((DECO_PORT(0x3c)&0x000f)<<12);
+ case 0x63a/2:
+ return ((DECO_PORT(0x3c)&0x000f)<<12);
+ case 0x348/2:
+ return ((((DECO_PORT(0x44)&0xf000)>>12) | ((DECO_PORT(0x44)&0x0ff0)<<4) | ((DECO_PORT(0x44)&0x000e)<<3) | ((DECO_PORT(0x44)&0x0001)<<7))) ^ deco16_xor;// & (~deco16_mask);
+ case 0x200/2:
+ return (((DECO_PORT(0xa0)&0xfff0)>>4) | ((DECO_PORT(0xa0)&0x0007)<<13) | ((DECO_PORT(0xa0)&0x0008)<<9));// & (~deco16_mask);
+ case 0x254/2:
+ return ((((DECO_PORT(0x7e)&0x0ff0)<<4) | ((DECO_PORT(0x7e)&0x000c)<<2) | ((DECO_PORT(0x7e)&0x0003)<<6))) ^ deco16_xor;// & (~deco16_mask);
+ case 0x182/2:
+ return ((DECO_PORT(0x46)&0xf000)<<0) | ((DECO_PORT(0x46)&0x0f00)>>8) | ((DECO_PORT(0x46)&0x00f0)>>0) | ((DECO_PORT(0x46)&0x000f)<<8);
+ case 0x58/2:
+ return DECO_PORT(0x46);
+ case 0x48e/2:
+ return ((((DECO_PORT(0x46)&0xf000)>>12) | ((DECO_PORT(0x46)&0x0f00)>>4) | ((DECO_PORT(0x46)&0x00f0)<<4) | ((DECO_PORT(0x46)&0x000f)<<12)));// /*^ deco16_xor*/) & (~deco16_mask);
+
+ case 0x4ba/2:
+ return (((DECO_PORT(0x24)&0xf000)>>12) | ((DECO_PORT(0x24)&0x0ff0)<<4) | ((DECO_PORT(0x24)&0x000c)<<2) | ((DECO_PORT(0x24)&0x0003)<<6)) & (~deco16_mask);
+ case 0x92/2:
+ return (((DECO_PORT(0x3c)&0xfff0)>>0) | ((DECO_PORT(0x3c)&0x0007)<<1) | ((DECO_PORT(0x3c)&0x0008)>>3));
+ case 0x1f0/2:
+ return ((((DECO_PORT(0xa2)&0xf000)>>12) | ((DECO_PORT(0xa2)&0x0f00)>>4) | ((DECO_PORT(0xa2)&0x00ff)<<8)) ^ deco16_xor) & (~deco16_mask);
+ case 0x24e/2:
+ return ((((DECO_PORT(0x46)&0xf000)>>8) | ((DECO_PORT(0x46)&0x0f00)>>0) | ((DECO_PORT(0x46)&0x00f0)>>4) | ((DECO_PORT(0x46)&0x000f)<<12)) ^ deco16_xor);// & (~deco16_mask);
+ case 0x594/2:
+ return ((((DECO_PORT(0x40)&0x00f0)<<8) | ((DECO_PORT(0x40)&0x000c)<<6) | ((DECO_PORT(0x40)&0x0003)<<10)) ^ deco16_xor);// & (~deco16_mask);
+
+ case 0x7e2/2:
+ return ((((DECO_PORT(0x96)&0xf000)<<0) | ((DECO_PORT(0x96)&0x00f0)<<4) | ((DECO_PORT(0x96)&0x000f)<<4))) ^ deco16_xor;// | ((DECO_PORT(0x96)&0x0001)<<7));// ^ deco16_xor);// & (~deco16_mask);
+ case 0x18c/2:
+ return (((DECO_PORT(0x22)&0xfff0)>>4) | ((DECO_PORT(0x22)&0x000e)<<11) | ((DECO_PORT(0x22)&0x0001)<<15));// ^ deco16_xor);// & (~deco16_mask);
+ case 0x1fa/2:
+ return ((((DECO_PORT(0x26)&0xf000)>>8) | ((DECO_PORT(0x26)&0x0f00)<<0) | ((DECO_PORT(0x26)&0x00f0)>>4) | ((DECO_PORT(0x26)&0x000f)<<12))) ^ deco16_xor;// & (~deco16_mask);
+ case 0x70e/2:
+ return ((((DECO_PORT(0x26)&0x0ff0)<<4) | ((DECO_PORT(0x26)&0x000c)<<2) | ((DECO_PORT(0x26)&0x0003)<<6))) ^ deco16_xor;// & (~deco16_mask);
+ case 0x33a/2:
+ return DECO_PORT(0x60) & (~deco16_mask);
+ case 0x1e2/2:
+ return ((DECO_PORT(0xd0)&0xf000)>>12) | ((DECO_PORT(0xd0)&0x0f00)>>4) | ((DECO_PORT(0xd0)&0x00ff)<<8);
+ 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 0x96/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 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);
+ case 0x2d0/2:
+ decoprot_buffer_ram_selected^=1;
+ return (((DECO_PORT(0x66)&0xf000)>>4) | ((DECO_PORT(0x66)&0x00f0)<<8)) ^ deco16_xor;
+ case 0x2b8/2:
+ decoprot_buffer_ram_selected^=1;
+ return ((DECO_PORT(0x66)&0x00f0)<<8) ^ deco16_xor;
+ case 0x294/2:
+ decoprot_buffer_ram_selected^=1;
+ return ((DECO_PORT(0x66)&0x000f)<<12);
+ case 0x1e8/2:
+ decoprot_buffer_ram_selected^=1;
+ return 0; // todo
+
+ 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 0x3c/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);
+ case 0x324/2:
+ return (((DECO_PORT(0x6)&0xf000)>>12) | ((DECO_PORT(0x6)&0x0ff0)<<4) | ((DECO_PORT(0x6)&0x0007)<<5) | ((DECO_PORT(0x6)&0x0008)<<1));
+ case 0x344/2:
+ return (((DECO_PORT(0x8)&0xf000)>>8) | ((DECO_PORT(0x8)&0x0f00)>>8) | ((DECO_PORT(0x8)&0x00f0)<<4) | ((DECO_PORT(0x8)&0x000f)<<12));
+ case 0x72/2:
+ return ((((DECO_PORT(0xa)&0xf000)>>8) | ((DECO_PORT(0xa)&0x0ff0)<<4) | ((DECO_PORT(0xa)&0x000f)>>0))) & (~deco16_mask);
+ case 0x36e/2:
+ return ((((DECO_PORT(0xc)&0xf000)>>0) | ((DECO_PORT(0xc)&0x0ff0)>>4) | ((DECO_PORT(0xc)&0x000f)<<8))) & (~deco16_mask);
+
+ case 0x590/2:
+ return ((((DECO_PORT(0xe)&0xfff0)>>4) | ((DECO_PORT(0xe)&0x000e)<<11) | ((DECO_PORT(0xe)&0x0001)<<15))) ^ deco16_xor;
+ case 0x7b6/2:
+ return ((((DECO_PORT(0x2)&0xf000)>>8) | ((DECO_PORT(0x2)&0x0ff0)<<4) | ((DECO_PORT(0x2)&0x000f)<<0)) ^ deco16_xor) & (~deco16_mask);
+ case 0x588/2:
+ return ((((DECO_PORT(0x4)&0xff00)>>4) | ((DECO_PORT(0x4)&0x00f0)<<8) | ((DECO_PORT(0x4)&0x000f)<<0)) ^ deco16_xor) & (~deco16_mask);
+ case 0x1f6/2:
+ return (((DECO_PORT(0x6)&0xf000)>>12) | ((DECO_PORT(0x6)&0x0ff0)<<4) | ((DECO_PORT(0x6)&0x0007)<<5) | ((DECO_PORT(0x6)&0x0008)<<1)) ^ deco16_xor;
+ case 0x4c0/2:
+ return (((DECO_PORT(0x8)&0xf000)>>4) | ((DECO_PORT(0x8)&0x0f00)<<4) | ((DECO_PORT(0x8)&0x00f0)>>4) | ((DECO_PORT(0x8)&0x000f)<<4)) & (~deco16_mask);
+ 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 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);
+
+
+ case 0x150/2: /* Shared */
+ return DECO_PORT(0x7e);
+ case 0x10e/2: /* Schmeizr Robo only */
+ return DECO_PORT(0x7c);
+ case 0x56a/2: /* Schmeizr Robo only */
+ return (((DECO_PORT(0x7c)&0xfff0)>>4) | ((DECO_PORT(0x7c)&0x000e)<<11) | ((DECO_PORT(0x7c)&0x0001)<<15)) & (~deco16_mask);
+ case 0x39a/2: /* Schmeizr Robo only */
+ return ((((DECO_PORT(0x7e)&0xfff0)>>4) | ((DECO_PORT(0x7e)&0x000e)<<11) | ((DECO_PORT(0x7e)&0x0001)<<15)) ^ deco16_xor) & (~deco16_mask);
+ case 0x188/2: /* Schmeizr Robo only */
+ return (((deco16_mask&0x0003)<<6) | ((deco16_mask&0x000c)<<2) | ((deco16_mask&0x00f0)<<4) | ((deco16_mask&0x0f00)<<4)) & (~deco16_mask);
+ case 0x3cc/2: /* Schmeizr Robo only */
+ return deco16_mask;
+ case 0x4a/2: /* Schmeizr Robo only */
+ return DECO_PORT(0x9e) & (~deco16_mask);
+ case 0x7e8/2: /* Schmeizr Robo only */
+ return DECO_PORT(0x4a) ^ deco16_xor;
+ case 0xfc/2: /* Schmeizr Robo only */
+ return DECO_PORT(0x4a);
+ case 0x38c/2: /* Schmeizr Robo only */
+ return DECO_PORT(0x28);
+ case 0x28/2: /* Schmeizr Robo only */
+ return DECO_PORT(0x58);
+ }
+
+ logerror("Protection PC %06x: warning - read unmapped protection address %04x\n",activecpu_get_pc(),offset<<1);
+
+ return 0;
+}
+
+/**********************************************************************************/
+
+static WRITE16_HANDLER( deco16_146_core_prot_w )
+{
+ const int writeport=offset;
+ const int sndport=0x260;
+ const int xorport=0x340;
+ const int maskport=0x6c0;
+
+ if (writeport==sndport) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ return;
+ }
+
+ if (writeport==xorport)
+ COMBINE_DATA(&deco16_xor);
+ if (writeport==maskport)
+ COMBINE_DATA(&deco16_mask);
+
+ if (decoprot_buffer_ram_selected)
+ COMBINE_DATA(&decoprot_buffer_ram2[offset>>1]);
+ else
+ COMBINE_DATA(&decoprot_buffer_ram[offset>>1]);
+
+// if (offset!=0x5e0 && offset!=0x340 && offset!=0 && offset!=0x3d0 && offset!=0x280)
+// logerror("%08x: Write protection port %04x, data %04x (%08x)\n", activecpu_get_pc(), offset, data, mem_mask);
+}
+
+static READ16_HANDLER( deco16_146_core_prot_r )
+{
+// const UINT16* prot_ram=decoprot_buffer_ram;
+ UINT16 val;
+ const UINT16* prot_ram=decoprot_buffer_ram_selected ? decoprot_buffer_ram2 : decoprot_buffer_ram;
+
+ switch (offset)
+ {
+ case 0x582: /* Player 1 & Player 2 */
+ return readinputport(0);
+ case 0x04c: /* Coins/VBL */
+ return readinputport(1);
+ case 0x672: /* Dip switches */
+ return readinputport(2);
+
+ case 0x13a:
+ return ((DECO_PORT(0x190)&0x00f0)<<8) | ((DECO_PORT(0x190)&0x0003)<<10) | ((DECO_PORT(0x190)&0x000c)<<6);
+
+ case 0x53c:
+ return ((DECO_PORT(0x30)&0x0ff0)<<4) | ((DECO_PORT(0x30)&0xf000)>>8);
+
+ case 0x6c:
+ return ((DECO_PORT(0x370)&0x00ff)<<8);
+
+ case 0xa:
+ return ((DECO_PORT(0x310)&0x0fff)<<4);
+
+ case 0x4f6:
+ return ((DECO_PORT(0x20)&0x00f0)<<8) | ((DECO_PORT(0x20)&0x0007)<<9) | ((DECO_PORT(0x20)&0x0008)<<5);
+
+ case 0xea:
+ return ((DECO_PORT(0x1c0)&0xf000)<<0) | ((DECO_PORT(0x1c0)&0x00ff)<<4);
+
+ case 0x12e:
+ return ((DECO_PORT(0x1f0)&0xf000)>>4) | ((DECO_PORT(0x1f0)&0x0f00)<<4) | ((DECO_PORT(0x1f0)&0x00f0)>>4) | ((DECO_PORT(0x1f0)&0x000f)<<4);
+
+ case 0x316:
+ return ((DECO_PORT(0x290)&0xf000)>>4) | ((DECO_PORT(0x290)&0x0f00)<<4) | ((DECO_PORT(0x290)&0x00ff)<<0);
+
+ case 0x3c6:
+ return ((DECO_PORT(0x170)&0xfff0)<<0) | ((DECO_PORT(0x170)&0x000e)>>1) | ((DECO_PORT(0x170)&0x0001)<<3);
+
+ case 0x4d0:
+ return ((DECO_PORT(0x20)&0x00f0)<<8) | ((DECO_PORT(0x20)&0x0007)<<9) | ((DECO_PORT(0x20)&0x0008)<<5);
+
+ case 0x53a:
+ return ((DECO_PORT(0x370)&0xffff)<<0);
+
+ case 0x552:
+ return ((DECO_PORT(0x240)&0xfff0)<<0) | ((DECO_PORT(0x240)&0x0007)<<1) | ((DECO_PORT(0x240)&0x0008)>>3);
+
+ case 0x54c:
+ return ((DECO_PORT(0x2f0)&0x00ff)<<8);
+
+ case 0x5da:
+ return ((DECO_PORT(0x130)&0x00f0)<<8) | ((DECO_PORT(0x130)&0x000e)<<7) | ((DECO_PORT(0x130)&0x0001)<<11);
+
+ case 0x6be:
+ return ((DECO_PORT(0x150)&0xf000)>>12) | ((DECO_PORT(0x150)&0x0ff0)<<0) | ((DECO_PORT(0x150)&0x000f)<<12);
+
+ case 0x70a:
+ return ((DECO_PORT(0x1d0)&0x0ff0)<<4) | ((DECO_PORT(0x1d0)&0x0003)<<6) | ((DECO_PORT(0x1d0)&0x000c)<<2);
+
+ case 0x7e0:
+ return ((DECO_PORT(0x2b0)&0xfff0)<<0) | ((DECO_PORT(0x2b0)&0x0003)<<2) | ((DECO_PORT(0x2b0)&0x000c)>>2);
+
+ case 0x1de:
+ return ((DECO_PORT(0x1b0)&0x0ff0)<<4) | ((DECO_PORT(0x1b0)&0x000e)<<3) | ((DECO_PORT(0x1b0)&0x0001)<<7);
+
+ /*********************************************************************************/
+
+// case 0x582: return readinputport(0); /* IN0 */
+// case 0x672: return readinputport(1); /* IN1 */
+// case 0x04c: return EEPROM_read_bit();
+
+ case 0x468:
+ val=DECO_PORT(0x570);
+ val=((val&0x0003)<<6) | ((val&0x000c)<<2) | ((val&0x00f0)<<4) | ((val&0x0f00)<<4) | ((val&0xf000)>>12);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x1ea:
+ val=DECO_PORT(0x570);
+ val=((val&0x0003)<<10) | ((val&0x000c)<<6) | ((val&0x00f0)<<8) | ((val&0x0f00)>>8) | ((val&0xf000)>>8);
+ return val ^ deco16_xor;
+
+ case 0x7b6:
+ val=((DECO_PORT(0))&0xffff);
+ val=((val&0x000c)>>2) | ((val&0x0003)<<2) | ((val&0xfff0)<<0);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x01c:
+ val=((DECO_PORT(0))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)<<4) | ((val&0x0f00)>>8) | ((val&0xf000)>>8);
+ return val ^ deco16_xor;
+
+ case 0x1e0:
+ val=((DECO_PORT(0))&0xffff);
+ val=((val&0x000e)<<3) | ((val&0x0001)<<7) | ((val&0x00f0)<<4) | ((val&0x0f00)<<4) | ((val&0xf000)>>12);
+ return val ^ deco16_xor;
+
+ case 0x1d4:
+ val=((DECO_PORT(0))&0xffff);
+ val=((val&0x000f)<<0) | ((val&0x00f0)<<4) | ((val&0x0f00)<<4) | ((val&0xf000)>>8);
+ return val;
+
+ case 0x0c0:
+ val=((DECO_PORT(0x280))&0xffff);
+ val=((val&0x000f)<<4) | ((val&0x00f0)>>4) | ((val&0x0f00)<<4) | ((val&0xf000)>>4);
+ return val ^ deco16_xor;
+
+ case 0x794:
+ val=((DECO_PORT(0x280))&0xffff);
+ val=((val&0x0007)<<1) | ((val&0xfff0)>>0) | ((val&0x0008)>>3);
+ return val ^ deco16_xor;
+
+ case 0x30:
+ val=DECO_PORT(0x5e0);
+ val=((val&0x0007)<<13) | ((val&0x0008)<<9); /* Bottom bits are masked out before XOR */
+ return val ^ deco16_xor;
+
+ case 0x422:
+ val=((DECO_PORT(0x3d0))&0xffff);
+ val=((val&0x0007)<<1) | ((val&0xfff0)>>0) | ((val&0x0008)>>3);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x558:
+ val=((DECO_PORT(0x210))&0xffff);
+ val=((val&0x000f)<<0) | ((val&0x00f0)<<8) | ((val&0x0f00)>>0) | ((val&0xf000)>>8);
+ return val;
+
+ case 0x3e:
+ val=((DECO_PORT(0x210))&0xffff);
+ val=((val&0x000f)<<4) | ((val&0x00f0)>>4) | ((val&0x0f00)<<4) | ((val&0xf000)>>4);
+ return val & (~deco16_mask);
+
+ case 0x328:
+ val=((DECO_PORT(0x210))&0xffff);
+ val=((val&0x000e)<<3) | ((val&0x0001)<<7) | ((val&0x00f0)<<4) | ((val&0xf000)>>12) | ((val&0x0f00)<<4);
+ return val ^ deco16_xor;
+
+ case 0x476:
+ val=((DECO_PORT(0x210))&0xffff);
+ val=((val&0x000f)<<0) | ((val&0x00f0)<<8) | ((val&0xff00)>>4);
+ return val;
+
+ case 0x50a:
+ val=((DECO_PORT(0x210))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)>>4) | ((val&0x0f00)<<0) | ((val&0xf000)>>8);
+ return val;
+
+ case 0x5ae:
+ val=((DECO_PORT(0x210))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)>>4) | ((val&0x0f00)>>0) | ((val&0xf000)>>8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x1ae:
+ val=((DECO_PORT(0x3d0))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)<<4);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x7a4:
+ val=((DECO_PORT(0x620))&0xffff);
+ val=((val&0x000f)<<4) | ((val&0x00f0)<<4) | ((val&0x0f00)>>8) | ((val&0xf000)>>0);
+ return val;
+
+ case 0x2c4:
+ val=((DECO_PORT(0x410))&0xffff);
+ val=((val&0x00ff)<<8) | ((val&0xff00)>>8);
+ return val ^ deco16_xor;
+
+ case 0x76: /* Bitshifted XOR, with additional inverse mask on final output */
+ val=((DECO_PORT(0x2a0))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)<<4) | ((val&0x0f00)>>8) | ((val&0xf000)>>8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x714: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x2a0))&0xffff);
+ val=((val&0x0003)<<14) | ((val&0x000c)<<10) | ((val&0xfff0)>>4);
+ return val & (~deco16_mask);
+
+ case 0x642:
+ val=((DECO_PORT(0x2a0))&0xffff);
+ val=((val&0xf000)>>4) | ((val&0x0f00)>>8)| ((val&0x00f0)<<8) | ((val&0x000f)<<4);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x49a: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x580))&0xffff);
+ val=((val&0x000f)<<4) | ((val&0x00f0)>>4) | ((val&0xff00)>>0);
+ return val & (~deco16_mask);
+
+ case 0x49c: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x580))&0xffff);
+ val=((val&0x000e)<<7) | ((val&0x00f0)<<8) | ((val&0x0001)<<11);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x584: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x580))&0xffff);
+ val=((val&0xff00)>>8) | ((val&0x00f0)<<8) | ((val&0x0008)<<5) | ((val&0x0007)<<9);
+ return val & (~deco16_mask);
+
+ case 0x614: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x580))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)<<4) | ((val&0x0f00)>>4) | ((val&0xf000)>>12);
+ return val & (~deco16_mask);
+
+ case 0x162: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0xe0))&0xffff);
+ val=((val&0x0fff)<<4);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x18:
+ val=((DECO_PORT(0x230))&0xffff);
+ val=((val&0xfff0)>>4) | ((val&0x0007)<<13) | ((val&0x0008)<<9);
+ return val ^ deco16_xor;
+
+ case 0x7f6: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x230))&0xffff);
+ val=((val&0x000f)<<12) | ((val&0x00f0)<<4);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x1a0: /* Bitshifting with inverse mask on final output */
+ val=((DECO_PORT(0x230))&0xffff);
+ val=((val&0xff00)>>8) | ((val&0x00f0)<<8) | ((val&0x0003)<<10) | ((val&0x000c)<<6);
+ return val & (~deco16_mask);
+
+ case 0x4f8:
+ val=((DECO_PORT(0x2d0))&0xffff);
+ val=((val&0x0fff)<<4);
+ return val;
+
+ case 0x1d6:
+ val=((DECO_PORT(0xa0))&0xffff);
+ val=((val&0x0fff)<<4);
+ return val ^ deco16_xor;
+
+ case 0x254:
+ val=((DECO_PORT(0x320))&0xffff);
+ val=((val&0x0f00)<<4) | ((val&0x00f0)<<0) | ((val&0x000f)<<8);
+ return val & (~deco16_mask);
+
+ case 0x2ea:
+ val=((DECO_PORT(0x320))&0xffff);
+ val=((val&0x00ff)<<8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x21e:
+ val=((DECO_PORT(0x2f0))&0xffff);
+ val=((val&0xfff0)<<0) | ((val&0x0007)<<1) | ((val&0x0008)>>3);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x7b0:
+ val=((DECO_PORT(0x2f0))&0xffff);
+ val=((val&0xfff0)>>4) | ((val&0x0007)<<13) | ((val&0x0008)<<9);
+ return val ^ deco16_xor;
+
+ case 0x7da:
+ val=((DECO_PORT(0x2f0))&0xffff);
+ val=((val&0xff00)>>8) | ((val&0x000f)<<12) | ((val&0x00f0)<<4);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x280:
+ val=((DECO_PORT(0x2d0))&0xffff);
+ val=((val&0x000f)<<8) | ((val&0x00f0)<<8) | ((val&0xf000)>>12) | ((val&0x0f00)>>4);
+ return val ^ deco16_xor;
+
+ case 0x416:
+ val=((DECO_PORT(0x2e0))&0xffff);
+ val=((val&0x000f)<<8) | ((val&0x00f0)>>4) | ((val&0xf000)>>0) | ((val&0x0f00)>>4);
+ return val;
+
+
+ case 0xac:
+ val=((DECO_PORT(0x350))&0xffff);
+ val=((val&0x000f)<<4) | ((val&0x00f0)<<4) | ((val&0xf000)>>0) | ((val&0x0f00)>>8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x2c2:
+ val=((DECO_PORT(0x2e0))&0xffff);
+ val=((val&0xf000)<<0) | ((val&0x0ff0)>>4) | ((val&0x000f)<<8);
+ return val;
+
+ case 0x450:
+ val=((DECO_PORT(0x440))&0xffff);
+ val=((val&0xff00)>>8) | ((val&0x00f0)<<4) | ((val&0x000f)<<12);
+ return val;
+
+ case 0x504:
+ val=((DECO_PORT(0x440))&0xffff);
+ val=((val&0x000c)<<2) | ((val&0x0003)<<6)| ((val&0x0ff0)<<4);
+ return val ^ deco16_xor;
+
+ case 0xfe:
+ val=((DECO_PORT(0x440))&0xffff);
+ val=((val&0x0fff)<<4);
+ return val;
+
+ // 1c0 swap address
+ case 0x1c0:
+ decoprot_buffer_ram_selected^=1;
+ return 0;
+
+ case 0x0e2:
+ decoprot_buffer_ram_selected^=1;
+ val=((DECO_PORT(0x6c0))&0xffff);
+ return val ^ deco16_xor;
+
+ case 0x444:
+ val=((DECO_PORT(0xa0))&0xffff);
+ val=((val&0xfff0)>>4) | ((val&0x0007)<<13) | ((val&0x0008)<<9);
+ return val & (~deco16_mask);
+
+ case 0x46a:
+ val=((DECO_PORT(0x10))&0xffff);
+ val=((val&0xff00)>>8) | ((val&0x00f0)<<8)| ((val&0x0007)<<9) | ((val&0x0008)<<5);
+ return val;
+
+ case 0x80:
+ return DECO_PORT(0xe0);
+
+ case 0xb2:
+ val=((DECO_PORT(0x280))&0xffff);
+ val=((val&0x00f0)<<8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x250:
+ val=((DECO_PORT(0x160))&0xffff);
+ val=((val&0xf000)>>12) | ((val&0x0f00)<<4)| ((val&0x00f0)<<4) | ((val&0x000e)<<3) | ((val&0x0001)<<7);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x306:
+ val=((DECO_PORT(0x160))&0xffff);
+ val=((val&0x00f0)<<8) | ((val&0xf000)>>4);
+ return (val ^ deco16_xor);
+
+ case 0x608:
+ val=((DECO_PORT(0x160))&0xffff);
+ val=((val&0xf000)>>4) | ((val&0x0f00)>>4)| ((val&0x00f0)<<8) | ((val&0x000f)<<0);
+ return val & (~deco16_mask);
+
+ case 0x52e:
+ val=((DECO_PORT(0x160))&0xffff);
+ val=((val&0xf000)>>4) | ((val&0x0f00)<<4)| ((val&0x00f0)<<0) | ((val&0x000f)<<0);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x67a:
+ val=((DECO_PORT(0x390))&0xffff);
+ val=((val&0xf000)>>8) | ((val&0x0ff0)<<4)| ((val&0x000f)<<0);
+ return val;
+
+ case 0x6c2:
+ val=((DECO_PORT(0x390))&0xffff);
+ val=((val&0x00f0)<<8) | ((val&0x000c)<<6)| ((val&0x0003)<<10);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x3d8:
+ val=((DECO_PORT(0x7e0))&0xffff);
+ val=((val&0xf000)>>8) | ((val&0x0ff0)<<4)| ((val&0x000f)<<0);
+ return val & (~deco16_mask);
+
+ case 0x244:
+ val=((DECO_PORT(0x760))&0xffff);
+ val=((val&0x0f00)<<4) | ((val&0x00f0)>>0)| ((val&0x000f)<<8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x7e8:
+ val=((DECO_PORT(0x390))&0xffff);
+ val=((val&0x0f00)<<4) | ((val&0xf000)>>4)| ((val&0x00ff)>>0);
+ return (val ^ deco16_xor);
+
+ case 0x276:
+ val=((DECO_PORT(0x7e0))&0xffff);
+ val=((val&0x00ff)<<8);
+ return (val ^ deco16_xor) & (~deco16_mask);
+
+ case 0x540:
+ val=((DECO_PORT(0x530))&0xffff);
+ val=((val&0x00f0)<<8) | ((val&0x0007)<<9) | ((val&0x0008)<<5);
+ return val & (~deco16_mask);
+
+ case 0x5c2:
+ val=((DECO_PORT(0x7e0))&0xffff);
+ val=((val&0xf000)>>12) | ((val&0x0ff0)<<4)| ((val&0x000c)<<2)| ((val&0x0003)<<6);
+ return val;
+
+ case 0x15c:
+ val=((DECO_PORT(0x230))&0xffff);
+ val=((val&0xff00)<<0) | ((val&0x000f)<<4) | ((val&0x00f0)>>4);
+ return (val ^ deco16_xor);
+
+ case 0x2c:
+ val=((DECO_PORT(0x390))&0xffff);
+ val=((val&0x00ff)<<8);
+ return val & (~deco16_mask);
+ }
+
+ //logerror("Protection PC %06x: warning - read fully unmapped protection address %04x\n", activecpu_get_pc(), offset);
+
+ return 0;
+}
+
+/**********************************************************************************/
+
+WRITE32_HANDLER( deco16_146_fghthist_prot_w )
+{
+ UINT16 addr=BITSWAP16(offset<<1, 0, 0, 0, 0, 0, 10, 1, 9, 2, 8, 3, 7, 4, 6, 5, 0);
+
+ decoprot_last_write=addr;
+ decoprot_last_write_val=data>>16;
+
+ deco16_146_core_prot_w(addr, data>>16, mem_mask>>16);
+}
+
+READ32_HANDLER( deco16_146_fghthist_prot_r )
+{
+ UINT16 addr=BITSWAP16(offset<<1, 0, 0, 0, 0, 0, 10, 1, 9, 2, 8, 3, 7, 4, 6, 5, 0);
+ UINT16 val;
+
+ /* Special case inputs, because this is the only game with an eprom */
+ switch (addr)
+ {
+ case 0x582: return (readinputport(0)<<16) | 0xffff; /* IN0 */
+ case 0x672: return (readinputport(1)<<16) | 0xffff; /* IN1 */
+ case 0x04c: return (EEPROM_read_bit()<<16) | 0xffff;
+ }
+
+ /* Handle 'one shots' - writing data to an address, then immediately reading it back */
+ if (decoprot_last_write==addr)
+ {
+ //logerror("Hit one shot for %04x (return %04x)\n", addr, decoprot_last_write_val);
+ decoprot_last_write=-1;
+ return (decoprot_last_write_val<<16)|0xffff;
+ }
+ decoprot_last_write=-1;
+
+ val=deco16_146_core_prot_r(addr, mem_mask>>16);
+
+ if (addr!=0x7b6 && addr!=0x1c && addr!=0x1e0 && addr!=0x1d4
+ && addr!=0x2c4 && addr!=0x7a4 && addr!=0x30 // confirmed
+ && addr!=0x49a && addr!=0x49c && addr!=0x584 // confirmed
+ && addr!=0x162 // confirmed
+ && addr!=0x1a0 && addr!=0x7f6 && addr!=0x18 // confirmed
+ && addr!=0x422 && addr!=0x794 // confirmed
+ && addr!=0xc0 && addr!=0x280 && addr!=0x1c0 && addr!=0xe2 // confirmed
+ && addr!=0x6c0 // not confirmed butnot read
+ && addr!=0x1ae && addr!=0x1d6 && addr!=0x4f8 && addr!=0x614 // cnofirmed
+ && addr!=0x5ae && addr!=0x50a && addr!=0x476 && addr!=0x328 && addr!=0x3e && addr!=0x558 // dbl check these later
+ && addr!=0x444 && addr!=0x46a // confirmed
+ && activecpu_get_pc()!=0x16448 // hmm
+ && addr!=0x67a
+ && addr!=0x6c2 && addr!=0xac && addr!=0x416 && addr!=0x2c2 // confirmed
+ && addr!=0x3d8
+ && addr!=0x250 && addr!=0x306 && addr!=0x608 && addr!=0x52e // confirmed
+ && addr!=0x21e && addr!=0x7b0 && addr!=0x7da
+ && addr!=0xfe && addr!=0x504 && addr!=0x450 && addr!=0x276 // confirmed
+ && addr!=0x76 && addr!=0x714 && addr!=0x642 && addr!=0x7e8 && addr!=0x244 // confirmed
+ && addr!=0x2ea && addr!=0x254
+ && addr!=0x540 && addr!=0x5c2 // confirmed
+ && addr!=0x15c // confirmed
+ && addr!=0x80 && addr!=0xb2
+ && addr!=0x2c
+
+ && addr!=0x2e0 && addr!=0x350 && addr!=0x244 && addr!=0x2c4 && addr!=0xac && addr!=0x416 // not handled at all
+
+ // These addresses are read but the value is never used, and there are no side effects from reading
+ // these addresses - seems to purely be some code obfustication
+ && addr!=0x400 && addr!=0x640 && addr!= 0x4c0 && addr!= 0x660 && addr!=0x4e0 && addr!=0x6e0 && addr!=0x448 && addr!=0x648 && addr!=0x4c8 && addr!=0x6c8 && addr!=0x468 && addr!=0x668 && addr!=0x4e8 && addr!=0x6e8 && addr!=0x442 && addr!=0x4c2 && addr!=0x462 && addr!=0x662
+ && addr!=0x4e2 && addr!=0x6e2 && addr!=0x44a && addr!=0x64a && addr!=0x4ca && addr!=0x6ca && addr!=0x66a && addr!=0x4ea && addr!=0x6ea
+ && addr!=0x440 && addr!=0x460
+ )
+ {
+ logerror("Protection PC %06x: warning - read unmapped protection address %04x (ret %04x)\n", activecpu_get_pc(), addr, val);
+ popmessage("Read protection port %04x", addr);
+ }
+ // logerror("Protection PC %06x: warning - read unmapped protection address %04x (ret %04x)\n", activecpu_get_pc(), addr, val);
+
+ return (val<<16)|0xffff;
+}
+
+WRITE16_HANDLER( deco16_146_nitroball_prot_w )
+{
+ UINT16 addr=BITSWAP16(offset<<1, 0, 0, 0, 0, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+
+ deco16_146_core_prot_w(addr, data, mem_mask);
+}
+
+READ16_HANDLER( deco16_146_nitroball_prot_r )
+{
+ UINT16 addr=BITSWAP16(offset<<1, 0, 0, 0, 0, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+
+ return deco16_146_core_prot_r(addr, mem_mask);
+}
+
+/**********************************************************************************/
+
+READ16_HANDLER( dietgo_104_prot_r )
+{
+ switch (offset * 2)
+ {
+ case 0x298: return input_port_0_word_r(0, 0);
+ case 0x342: return input_port_1_word_r(0, 0);
+ case 0x506: return input_port_2_word_r(0, 0);
+ }
+
+ logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset<<1);
+
+ return 0;
+}
+
+WRITE16_HANDLER( dietgo_104_prot_w )
+{
+ if (offset==(0x380/2)) {
+ soundlatch_w(0,data&0xff);
+ cpunum_set_input_line(1,0,HOLD_LINE);
+ return;
+ }
+ logerror("Protection PC %06x: warning - write unmapped memory address %04x %04x\n",activecpu_get_pc(),offset<<1,data);
+}
+
+/**********************************************************************************/
+
+READ16_HANDLER( deco16_104_pktgaldx_prot_r )
+{
+ const UINT16* prot_ram=deco16_prot_ram;
+
+ switch (offset * 2)
+ {
+ case 0x5b2: return input_port_0_word_r(0, 0);
+ case 0x44c: return input_port_1_word_r(0, 0);
+ case 0x042: return input_port_2_word_r(0, 0);
+
+ case 0x510: return DECO_PORT(0);
+ case 0x51a: return DECO_PORT(2);
+ }
+
+ logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",activecpu_get_pc(),offset<<1);
+
+ return 0;
+}
+
+WRITE16_HANDLER( deco16_104_pktgaldx_prot_w )
+{
+ COMBINE_DATA(&deco16_prot_ram[offset]);
+// logerror("Protection PC %06x: warning - write unmapped memory address %04x %04x\n",activecpu_get_pc(),offset<<1,data);
+}
+
+/**********************************************************************************/
+