various refactoring (nw)

This commit is contained in:
David Haywood 2013-07-21 03:17:18 +00:00
parent d806c0a326
commit e13481c1a6
14 changed files with 659 additions and 754 deletions

View File

@ -102,7 +102,7 @@ static ADDRESS_MAP_START( boogwing_map, AS_PROGRAM, 16, boogwing_state )
AM_RANGE(0x24e6c0, 0x24e6c1) AM_READ_PORT("DSW")
AM_RANGE(0x24e138, 0x24e139) AM_READ_PORT("SYSTEM")
AM_RANGE(0x24e344, 0x24e345) AM_READ_PORT("INPUTS")
AM_RANGE(0x24e000, 0x24e7ff) AM_WRITE_LEGACY(deco16_104_prot_w) AM_SHARE("prot16ram")
/*READD AM_RANGE(0x24e000, 0x24e7ff) AM_WRITE_LEGACY(deco16_104_prot_w) AM_SHARE("prot16ram") */
AM_RANGE(0x260000, 0x26000f) AM_DEVWRITE("tilegen1", deco16ic_device, pf_control_w)
AM_RANGE(0x264000, 0x265fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_r, pf1_data_w)
@ -566,8 +566,6 @@ DRIVER_INIT_MEMBER(boogwing_state,boogwing)
deco56_remap_gfx(machine(), "gfx6");
deco102_decrypt_cpu(machine(), "maincpu", 0x42ba, 0x00, 0x18);
memcpy(dst, src, 0x100000);
decoprot104_reset(machine());
}
GAME( 1992, boogwing, 0, boogwing, boogwing, boogwing_state, boogwing, ROT0, "Data East Corporation", "Boogie Wings (Euro v1.5, 92.12.07)", GAME_SUPPORTS_SAVE )

View File

@ -139,6 +139,24 @@ WRITE16_MEMBER(cninja_state::cninja_pf34_control_w)
}
READ16_MEMBER( cninja_state::cninja_protection_region_0_104_r )
{
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco104->read_data( deco146_addr, mem_mask, cs );
return data;
}
WRITE16_MEMBER( cninja_state::cninja_protection_region_0_104_w )
{
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
m_deco104->write_data( space, deco146_addr, data, mem_mask, cs );
}
static ADDRESS_MAP_START( cninja_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x000000, 0x0bffff) AM_ROM
@ -160,8 +178,11 @@ static ADDRESS_MAP_START( cninja_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x1a4000, 0x1a47ff) AM_RAM AM_SHARE("spriteram") /* Sprites */
AM_RANGE(0x1b4000, 0x1b4001) AM_DEVWRITE("spriteram", buffered_spriteram16_device, write) /* DMA flag */
AM_RANGE(0x1bc000, 0x1bc0ff) AM_WRITE_LEGACY(deco16_104_cninja_prot_w) AM_SHARE("prot16ram") /* Protection writes */
AM_RANGE(0x1bc000, 0x1bcfff) AM_READ_LEGACY(deco16_104_cninja_prot_r) AM_SHARE("prot16ram") /* Protection device */
// AM_RANGE(0x1bc000, 0x1bc0ff) AM_WRITE_LEGACY(deco16_104_cninja_prot_w) AM_SHARE("prot16ram") /* Protection writes */
// AM_RANGE(0x1bc000, 0x1bcfff) AM_READ_LEGACY(deco16_104_cninja_prot_r) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x1bc000, 0x1bffff) AM_READWRITE(cninja_protection_region_0_104_r,cninja_protection_region_0_104_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x308000, 0x308fff) AM_WRITENOP /* Bootleg only */
ADDRESS_MAP_END
@ -201,7 +222,7 @@ READ16_MEMBER( cninja_state::sshangha_protection_region_8_146_r )
int real_address = 0x1a0000 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 0 );
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
return data;
}
@ -220,7 +241,7 @@ READ16_MEMBER( cninja_state::sshangha_protection_region_6_146_r )
int real_address = 0x198000 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 0 );
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
// if ((realdat & mem_mask) != (data & mem_mask))
@ -304,24 +325,15 @@ ADDRESS_MAP_END
READ16_MEMBER( cninja_state::mutantf_protection_region_0_146_r )
{
// UINT16 realdat = deco16_66_prot_r(space,offset&0x3ff,mem_mask);
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 0 );
// if ((realdat & mem_mask) != (data & mem_mask))
// logerror("returned %04x instead of %04x (real address %08x)\n", data, realdat, real_address);
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
return data;
}
WRITE16_MEMBER( cninja_state::mutantf_protection_region_0_146_w )
{
// deco16_66_prot_w(space,offset&0x3ff,data,mem_mask);
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
@ -329,6 +341,7 @@ WRITE16_MEMBER( cninja_state::mutantf_protection_region_0_146_w )
}
static ADDRESS_MAP_START( mutantf_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x100000, 0x103fff) AM_RAM
@ -907,10 +920,6 @@ void cninja_state::machine_start()
{
save_item(NAME(m_scanline));
save_item(NAME(m_irq_mask));
decoprot104_reset(machine());
decoprot146_reset(machine());
}
void cninja_state::machine_reset()
@ -969,6 +978,9 @@ static MACHINE_CONFIG_START( cninja, cninja_state )
decospr_device::set_gfx_region(*device, 3);
decospr_device::set_pri_callback(*device, cninja_pri_callback);
MCFG_DECO104_ADD("ioprot104")
MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -1025,6 +1037,10 @@ static MACHINE_CONFIG_START( stoneage, cninja_state )
decospr_device::set_gfx_region(*device, 3);
decospr_device::set_pri_callback(*device, cninja_pri_callback);
MCFG_DECO104_ADD("ioprot104")
MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")

View File

@ -64,6 +64,9 @@ public:
virtual void machine_start();
virtual void machine_reset();
UINT32 screen_update_dblewing(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
READ16_MEMBER( wf_protection_region_0_104_r );
WRITE16_MEMBER( wf_protection_region_0_104_w );
};
UINT16 dblwings_pri_callback(UINT16 x)
@ -99,6 +102,23 @@ UINT32 dblewing_state::screen_update_dblewing(screen_device &screen, bitmap_ind1
return 0;
}
READ16_MEMBER( dblewing_state::wf_protection_region_0_104_r )
{
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco104->read_data( deco146_addr, mem_mask, cs );
return data;
}
WRITE16_MEMBER( dblewing_state::wf_protection_region_0_104_w )
{
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
m_deco104->write_data( space, deco146_addr, data, mem_mask, cs );
}
static ADDRESS_MAP_START( dblewing_map, AS_PROGRAM, 16, dblewing_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
@ -108,7 +128,8 @@ static ADDRESS_MAP_START( dblewing_map, AS_PROGRAM, 16, dblewing_state )
AM_RANGE(0x104000, 0x104fff) AM_RAM AM_SHARE("pf1_rowscroll")
AM_RANGE(0x106000, 0x106fff) AM_RAM AM_SHARE("pf2_rowscroll")
AM_RANGE(0x280000, 0x2807ff) AM_DEVREADWRITE("ioprot104", deco104_device, dblewing_prot_r, dblewing_prot_w) AM_SHARE("prot16ram")
// AM_RANGE(0x280000, 0x2807ff) AM_DEVREADWRITE("ioprot104", deco104_device, dblewing_prot_r, dblewing_prot_w) AM_SHARE("prot16ram")
AM_RANGE(0x280000, 0x283fff) AM_READWRITE(wf_protection_region_0_104_r,wf_protection_region_0_104_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x284000, 0x284001) AM_RAM
@ -379,6 +400,9 @@ static MACHINE_CONFIG_START( dblewing, dblewing_state )
decospr_device::set_pri_callback(*device, dblwings_pri_callback);
MCFG_DECO104_ADD("ioprot104")
MCFG_DECO104_SET_USE_DOUBLEWINGS_HACK
MCFG_DECO146_SET_INTERFACE_SCRAMBLE_INTERLEAVE
MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -466,8 +490,6 @@ DRIVER_INIT_MEMBER(dblewing_state,dblewing)
{
deco56_decrypt_gfx(machine(), "gfx1");
deco102_decrypt_cpu(machine(), "maincpu", 0x399d, 0x25, 0x3d);
decoprot104_reset(machine());
}

View File

@ -723,9 +723,9 @@ READ32_MEMBER( deco32_state::fghthist_protection_region_0_146_r )
mem_mask >>=16;
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0) & 0x7fff;
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8,7,6,5,4,3,2,1, 0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 1 );
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
@ -742,7 +742,7 @@ WRITE32_MEMBER( deco32_state::fghthist_protection_region_0_146_w )
mem_mask >>=16;
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0) & 0x7fff;
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8,7,6,5,4,3,2,1, 0) & 0x7fff;
UINT8 cs = 0;
m_deco146->write_data( space, deco146_addr, data, mem_mask, cs );
}
@ -1645,9 +1645,6 @@ static const eeprom_interface eeprom_interface_tattass =
MACHINE_RESET_MEMBER(deco32_state,deco32)
{
m_raster_irq_timer = machine().device<timer_device>("int_timer");
decoprot104_reset(machine());
decoprot146_reset(machine());
}
INTERRUPT_GEN_MEMBER(deco32_state::deco32_vbl_interrupt)
@ -1810,6 +1807,8 @@ static MACHINE_CONFIG_START( fghthist, deco32_state ) /* DE-0380-2 PCB */
MCFG_DECO146_SET_PORTA_CALLBACK( deco32_state, port_a_fghthist )
MCFG_DECO146_SET_PORTB_CALLBACK( deco32_state, port_b_fghthist )
MCFG_DECO146_SET_PORTC_CALLBACK( deco32_state, port_c_fghthist )
MCFG_DECO146_SET_INTERFACE_SCRAMBLE_INTERLEAVE
MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR
MCFG_VIDEO_START_OVERRIDE(deco32_state,fghthist)
@ -1863,6 +1862,7 @@ static MACHINE_CONFIG_START( fghthsta, deco32_state ) /* DE-0395-1 PCB */
MCFG_DECO146_SET_PORTA_CALLBACK( deco32_state, port_a_fghthist )
MCFG_DECO146_SET_PORTB_CALLBACK( deco32_state, port_b_fghthist )
MCFG_DECO146_SET_PORTC_CALLBACK( deco32_state, port_c_fghthist )
MCFG_DECO146_SET_INTERFACE_SCRAMBLE_INTERLEAVE
MCFG_VIDEO_START_OVERRIDE(deco32_state,fghthist)
@ -3438,8 +3438,6 @@ DRIVER_INIT_MEMBER(deco32_state,fghthist)
{
deco56_decrypt_gfx(machine(), "gfx1");
deco74_decrypt_gfx(machine(), "gfx2");
decoprot146_reset(machine());
}
DRIVER_INIT_MEMBER(dragngun_state,lockload)

View File

@ -106,7 +106,7 @@ READ16_MEMBER( funkyjet_state::funkyjet_protection_region_0_146_r )
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, /* note, same bitswap as fghthist */ 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 0 );
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
// if ((realdat & mem_mask) != (data & mem_mask))
// printf("returned %04x instead of %04x (real address %08x swapped addr %08x)\n", data, realdat, real_address, deco146_addr);
@ -314,7 +314,7 @@ static const deco16ic_interface funkyjet_deco16ic_tilegen1_intf =
void funkyjet_state::machine_start()
{
decoprot146_reset(machine());
}
static MACHINE_CONFIG_START( funkyjet, funkyjet_state )

View File

@ -311,7 +311,7 @@ static const deco16ic_interface pktgaldx_deco16ic_tilegen1_intf =
void pktgaldx_state::machine_start()
{
decoprot104_reset(machine());
}
static MACHINE_CONFIG_START( pktgaldx, pktgaldx_state )

View File

@ -134,7 +134,8 @@ static ADDRESS_MAP_START( rohga_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x200000, 0x20000f) AM_DEVWRITE("tilegen1", deco16ic_device, pf_control_w)
AM_RANGE(0x240000, 0x24000f) AM_DEVWRITE("tilegen2", deco16ic_device, pf_control_w)
AM_RANGE(0x280000, 0x2807ff) AM_MIRROR(0x800) AM_READWRITE_LEGACY(deco16_104_rohga_prot_r,deco16_104_rohga_prot_w) AM_SHARE("prot16ram") /* Protection device */
// AM_RANGE(0x280000, 0x2807ff) AM_MIRROR(0x800) AM_READWRITE_LEGACY(deco16_104_rohga_prot_r,deco16_104_rohga_prot_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x280000, 0x283fff) AM_READWRITE(wf_protection_region_0_104_r,wf_protection_region_0_104_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x2c0000, 0x2c0001) AM_READ_PORT("DSW3")
@ -160,6 +161,24 @@ static ADDRESS_MAP_START( rohga_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x3f0000, 0x3f3fff) AM_RAM /* Main ram */
ADDRESS_MAP_END
READ16_MEMBER( rohga_state::wf_protection_region_0_104_r )
{
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco104->read_data( deco146_addr, mem_mask, cs );
return data;
}
WRITE16_MEMBER( rohga_state::wf_protection_region_0_104_w )
{
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
m_deco104->write_data( space, deco146_addr, data, mem_mask, cs );
}
static ADDRESS_MAP_START( wizdfire_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x000000, 0x1fffff) AM_ROM
@ -187,33 +206,25 @@ static ADDRESS_MAP_START( wizdfire_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x380000, 0x381fff) AM_RAM_DEVWRITE("deco_common", decocomn_device, buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x390008, 0x390009) AM_DEVWRITE("deco_common", decocomn_device, palette_dma_w)
AM_RANGE(0xfe4000, 0xfe47ff) AM_READWRITE_LEGACY(deco16_104_prot_r,deco16_104_prot_w) AM_SHARE("prot16ram") /* Protection device */
// AM_RANGE(0xfe4000, 0xfe47ff) AM_READWRITE_LEGACY(deco16_104_prot_r,deco16_104_prot_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0xfe4000, 0xfe7fff) AM_READWRITE(wf_protection_region_0_104_r,wf_protection_region_0_104_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0xfdc000, 0xffffff) AM_RAM
ADDRESS_MAP_END
READ16_MEMBER( rohga_state::nb_protection_region_0_146_r )
{
//UINT16 realdat = deco16_146_nitroball_prot_r(space,offset&0x3ff,mem_mask);
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* 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;
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 1 );
//if ((realdat & mem_mask) != (data & mem_mask))
// printf("returned %04x instead of %04x (real address %08x)\n", data, realdat, real_address);
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
return data;
}
WRITE16_MEMBER( rohga_state::nb_protection_region_0_146_w )
{
// deco16_146_nitroball_prot_w(space,offset&0x3ff,data,mem_mask);
int real_address = 0 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* 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;
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
m_deco146->write_data( space, deco146_addr, data, mem_mask, cs );
}
@ -258,7 +269,8 @@ static ADDRESS_MAP_START( schmeisr_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x200000, 0x20000f) AM_DEVWRITE("tilegen1", deco16ic_device, pf_control_w)
AM_RANGE(0x240000, 0x24000f) AM_DEVWRITE("tilegen2", deco16ic_device, pf_control_w)
AM_RANGE(0x280000, 0x2807ff) AM_MIRROR(0x800) AM_READWRITE_LEGACY(deco16_104_rohga_prot_r,deco16_104_rohga_prot_w) AM_SHARE("prot16ram") /* Protection device */
//AM_RANGE(0x280000, 0x2807ff) AM_MIRROR(0x800) AM_READWRITE_LEGACY(deco16_104_rohga_prot_r,deco16_104_rohga_prot_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x280000, 0x283fff) AM_READWRITE(wf_protection_region_0_104_r,wf_protection_region_0_104_w) AM_SHARE("prot16ram") /* Protection device */
AM_RANGE(0x2c0000, 0x2c0001) AM_READ_PORT("DSW3")
AM_RANGE(0x300000, 0x300001) AM_READ_PORT("DSW3") AM_WRITE(rohga_buffer_spriteram16_w) /* write 1 for sprite dma */
@ -842,6 +854,8 @@ static MACHINE_CONFIG_START( rohga, rohga_state )
MCFG_DEVICE_ADD("spritegen1", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 3);
MCFG_DECO104_ADD("ioprot104")
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
@ -895,6 +909,9 @@ static MACHINE_CONFIG_START( wizdfire, rohga_state )
MCFG_DEVICE_ADD("spritegen2", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 4);
MCFG_DECO104_ADD("ioprot104")
MCFG_DECO146_SET_INTERFACE_SCRAMBLE_REVERSE
MCFG_VIDEO_START_OVERRIDE(rohga_state,wizdfire)
/* sound hardware */
@ -953,6 +970,9 @@ static MACHINE_CONFIG_START( nitrobal, rohga_state )
MCFG_VIDEO_START_OVERRIDE(rohga_state,wizdfire)
MCFG_DECO146_ADD("ioprot")
MCFG_DECO146_SET_INTERFACE_SCRAMBLE_REVERSE
MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
@ -1005,6 +1025,7 @@ static MACHINE_CONFIG_START( schmeisr, rohga_state )
MCFG_DEVICE_ADD("spritegen1", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 3);
MCFG_DECO104_ADD("ioprot104")
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
@ -1555,8 +1576,6 @@ DRIVER_INIT_MEMBER(rohga_state,rohga)
{
deco56_decrypt_gfx(machine(), "gfx1");
deco56_decrypt_gfx(machine(), "gfx2");
decoprot104_reset(machine());
}
DRIVER_INIT_MEMBER(rohga_state,wizdfire)
@ -1564,8 +1583,6 @@ DRIVER_INIT_MEMBER(rohga_state,wizdfire)
deco74_decrypt_gfx(machine(), "gfx1");
deco74_decrypt_gfx(machine(), "gfx2");
deco74_decrypt_gfx(machine(), "gfx3");
decoprot104_reset(machine());
}
DRIVER_INIT_MEMBER(rohga_state,nitrobal)
@ -1573,8 +1590,6 @@ DRIVER_INIT_MEMBER(rohga_state,nitrobal)
deco56_decrypt_gfx(machine(), "gfx1");
deco56_decrypt_gfx(machine(), "gfx2");
deco74_decrypt_gfx(machine(), "gfx3");
decoprot146_reset(machine());
}
DRIVER_INIT_MEMBER(rohga_state,schmeisr)
@ -1587,8 +1602,6 @@ DRIVER_INIT_MEMBER(rohga_state,schmeisr)
deco74_decrypt_gfx(machine(), "gfx1");
deco74_decrypt_gfx(machine(), "gfx2");
decoprot104_reset(machine());
}
GAME( 1991, rohga, 0, rohga, rohga, rohga_state, rohga, ROT0, "Data East Corporation", "Rohga Armor Force (Asia/Europe v5.0)", GAME_SUPPORTS_SAVE )

View File

@ -132,7 +132,7 @@ READ16_MEMBER( sshangha_state::sshangha_protection_region_d_146_r )
int real_address = 0x3f4000 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 0 );
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
return data;
}
@ -149,7 +149,7 @@ READ16_MEMBER( sshangha_state::sshangha_protection_region_8_146_r )
int real_address = 0x3e0000 + (offset *2);
int deco146_addr = BITSWAP32(real_address, /* NC */31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11,/**/ 17,16,15,14, 10,9,8, 7,6,5,4, 3,2,1,0) & 0x7fff;
UINT8 cs = 0;
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs, 0 );
UINT16 data = m_deco146->read_data( deco146_addr, mem_mask, cs );
return data;
}

View File

@ -20,6 +20,7 @@ public:
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_deco146(*this, "ioprot"),
m_deco104(*this, "ioprot104"),
m_decocomn(*this, "deco_common"),
m_deco_tilegen1(*this, "tilegen1"),
m_deco_tilegen2(*this, "tilegen2"),
@ -41,6 +42,7 @@ public:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<deco146_device> m_deco146;
optional_device<deco104_device> m_deco104;
required_device<decocomn_device> m_decocomn;
required_device<deco16ic_device> m_deco_tilegen1;
required_device<deco16ic_device> m_deco_tilegen2;
@ -91,4 +93,7 @@ public:
DECLARE_READ16_MEMBER( mutantf_protection_region_0_146_r );
DECLARE_WRITE16_MEMBER( mutantf_protection_region_0_146_w );
DECLARE_READ16_MEMBER( cninja_protection_region_0_104_r );
DECLARE_WRITE16_MEMBER( cninja_protection_region_0_104_w );
};

View File

@ -20,6 +20,7 @@ public:
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_deco146(*this, "ioprot"),
m_deco104(*this, "ioprot104"),
m_decocomn(*this, "deco_common"),
m_deco_tilegen1(*this, "tilegen1"),
m_deco_tilegen2(*this, "tilegen2"),
@ -39,6 +40,7 @@ public:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<deco146_device> m_deco146;
optional_device<deco104_device> m_deco104;
required_device<decocomn_device> m_decocomn;
required_device<deco16ic_device> m_deco_tilegen1;
required_device<deco16ic_device> m_deco_tilegen2;
@ -74,6 +76,8 @@ public:
READ16_MEMBER( nb_protection_region_0_146_r );
WRITE16_MEMBER( nb_protection_region_0_146_w );
READ16_MEMBER( wf_protection_region_0_104_r );
WRITE16_MEMBER( wf_protection_region_0_104_w );
};
/*----------- defined in video/rohga.c -----------*/
UINT16 rohga_pri_callback(UINT16 x);

View File

@ -72,23 +72,12 @@
// the same way some 146 games require an address XOR of 0x44a at some point during the read chain
// there are 104 games requiring a xor of 0x2a4
#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;
static UINT16 deco16_mask;
static int decoprot_last_write=0, decoprot_last_write_val=0;
static UINT16 decoprot_buffer_ram[0x800];
static UINT16 decoprot_buffer_ram2[0x800];
static UINT16 *deco16_prot_ram;
static UINT32 *deco32_prot_ram;
const device_type DECO104PROT = &device_creator<deco104_device>;
@ -96,17 +85,35 @@ const device_type DECO104PROT = &device_creator<deco104_device>;
deco104_device::deco104_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, DECO104PROT, "DECO104PROT", tag, owner, clock, "deco104", __FILE__)
: deco_146_base_device(mconfig, DECO104PROT, "DECO104PROT", tag, owner, clock, "deco104", __FILE__)
{
m_bankswitch_swap_read_address = 0x66;
m_magic_read_address_xor = 0x2a4;
m_magic_read_address_xor_enabled = 0;
m_xor_port = 0x42;
m_mask_port = 0xee;
m_soundlatch_port = 0xa8;
m_use_dblewings_hacks = 0;
}
void deco104_device::device_config_complete()
{
}
void deco104_device::set_use_dblewing_hacks(device_t &device, int use_hacks)
{
deco104_device &dev = downcast<deco104_device &>(device);
dev.m_use_dblewings_hacks = use_hacks;
}
void deco104_device::device_start()
{
deco_146_base_device::device_start();
// double wing
save_item(NAME(m_008_data));
save_item(NAME(m_104_data));
@ -140,6 +147,8 @@ void deco104_device::device_start()
void deco104_device::device_reset()
{
deco_146_base_device::device_reset();
// double wing
m_008_data = 0;
m_104_data = 0;
@ -174,179 +183,220 @@ void deco104_device::device_reset()
/***************************************************************************/
void decoprot104_reset(running_machine &machine)
UINT16 deco104_device::read_data_getloc(UINT16 offset, int& location)
{
deco16_xor=0;
// deco16_mask=0xffff;
deco16_mask=0x0; // wizard fire doesn't initialize it, but accesses addresses rohga needs the mask applied on
const UINT16* prot_ram=m_current_rambank;
decoprot_last_write=decoprot_last_write_val=0;
decoprot_buffer_ram_selected=0;
location = 0x00;
deco16_prot_ram = reinterpret_cast<UINT16 *>(machine.root_device().memshare("prot16ram")->ptr());
deco32_prot_ram = reinterpret_cast<UINT32 *>(machine.root_device().memshare("prot32ram")->ptr());
if (m_use_dblewings_hacks==1)
{
switch (offset)
{
//case 0x4c0: /* was 0x664 */ /* was 0x16a*/ return m_boss_move; // boss 1 movement // in shared sim
case 0x13a: /* was 0x39e */ /* was 0x6d6*/ return m_boss_move; // boss 1 2nd pilot
case 0x0ce: /* was 0x26a */ /* was 0x748*/ return m_boss_move; // boss 1 3rd pilot
machine.save().save_item(NAME(deco16_xor));
machine.save().save_item(NAME(deco16_mask));
machine.save().save_item(NAME(decoprot_last_write));
machine.save().save_item(NAME(decoprot_last_write_val));
machine.save().save_item(NAME(decoprot_buffer_ram_selected));
machine.save().save_item(NAME(decoprot_buffer_ram));
machine.save().save_item(NAME(decoprot_buffer_ram2));
}
case 0x492: /* was 0x636 */ /* was 0x566*/ return 0x0009; // boss BGM,might be a variable one (read->write to the sound latch)
case 0x440: /* was 0x6e4 */ /* was 0x1ea*/ return m_boss_shoot_type; // boss 1 shoot type
case 0x312: /* was 0x1b6 */ /* was 0x596*/ return m_boss_3_data; // boss 3 appearing
//case 0x32a: /* was 0x18e */ /* was 0x692*/ return m_boss_4_data; // in shared sim
case 0x72e: /* was 0x58a */ /* was 0x6b0*/ return m_boss_5_data;
//case 0x3d2: /* was 0x176 */ /* was 0x51e*/ return m_boss_5sx_data; // in shared sim
case 0x21e: /* was 0x0ba */ /* was 0x784*/ return m_boss_6_data;
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;
case 0x78c: /* was 0x528 */ /* was 0x330*/ return 0; // controls bonuses such as shoot type,bombs etc.
case 0x114: /* was 0x3b0 */ /* was 0x1d4*/ return m_70c_data; //controls restart points
case 0x674: /* was 0x4d0 */ /* was 0x0ac*/ return (ioport(":DSW")->read() & 0x40) << 4;//flip screen
case 0x726: /* was 0x582 */ /* was 0x4b0*/return m_608_data;//coinage
case 0x4e4: /* was 0x640 */ /* was 0x068*/
{
switch (ioport(":DSW")->read() & 0x0300) //I don't know how to relationate this...
{
case 0x0000: return 0x000;//0
case 0x0100: return 0x060;//3
case 0x0200: return 0x0d0;//6
case 0x0300: return 0x160;//b
}
}
//case 0x334: /* was 0x190 */ /* was 0x094*/ return m_104_data;// p1 inputs select screen OK // in shared sim
//case 0x0fc: /* was 0x258 */ /* was 0x24c*/return m_008_data;//read DSW (mirror for coinage/territory) // in shared sim
//case 0x36c: /* was 0x1c8 */ /* was 0x298*/return ioport(":IN1")->read();//vblank // in shared sim
case 0x5b2: /* was 0x716 */ /* was 0x476*/return ioport(":IN1")->read();//mirror for coins
//case 0x292: /* was 0x036 */ /* was 0x506*/return ioport(":DSW")->read(); // in shared sim
case 0x146: /* was 0x3e2 */ /* was 0x5d8*/return m_406_data;
case 0x73c: /* was 0x598 */ /* was 0x2b4*/return ioport(":IN0")->read();
case 0x644: /* was 0x4e0 */ /* was 0x1a8*/return (ioport(":DSW")->read() & 0x4000) >> 12;//allow continue
// case 0x45c: /* was 0x6f8 */ /* was 0x3ec*/return m_70c_data; //score entry // in shared sim
case 0x0b8: /* was 0x21c */ /* was 0x246*/return m_580_data; // these three controls "perfect bonus" I suppose...
case 0x6d2: /* was 0x476 */ /* was 0x52e*/return m_580_data;
//case 0x782: /* was 0x526 */ /* was 0x532*/return m_580_data; // in shared sim
switch (offset) {
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("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);
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 0x564: /* was 0x7c0 */ /* was 0x0f8*/ return 0; // m_080_data;
//case 0x294: /* was 0x030 */ /* was 0x104*/ return 0; // in shared sim (ram buffer change!)
//case 0x2d0: /* was 0x074 */ /* was 0x10e*/ return 0;// in shared sim (ram buffer change!)
//case 0x2b8: /* was 0x01c */ /* was 0x206*/ return 0; // m_70c_data;// in shared sim (ram buffer change!)
case 0x1fc: /* was 0x358 */ /* was 0x25c*/return 0;
case 0x23c: /* was 0x098 */ /* was 0x284*/ return 0; // 3rd player 2nd boss
case 0x7a2: /* was 0x506 */ /* was 0x432*/return 0; // boss on water level?
case 0x0c2: /* was 0x266 */ /* was 0x54a*/ return 0; // 3rd player 2nd boss
case 0x21a: /* was 0x0be */ /* was 0x786*/return 0;
}
}
switch (offset>>1)
{
case 0x088/2: /* Player 1 & 2 input ports */ return machine().root_device().ioport(":IN0")->read(); // also caveman ninja + wizard fire
case 0x36c/2: return machine().root_device().ioport(":IN1")->read(); // also caveman ninja + wizard fire
case 0x44c/2: return ((machine().root_device().ioport(":IN1")->read() & 0x7)<<13)|((machine().root_device().ioport(":IN1")->read() & 0x8)<<9);
case 0x292/2: /* Dips */ return machine().root_device().ioport(":DSW")->read(); // also wizard fire
case 0x044/2: location = 0x2c; return ((((DECO_PORT(location)&0x000f)<<12)) ^ m_xor) & (~m_nand);
case 0x282/2: location = 0x26; return ((DECO_PORT(location)&0x000f)<<12) & (~m_nand);
case 0x0d4/2: location = 0x6e; return ((DECO_PORT(location)&0x0ff0)<<4) | ((DECO_PORT(location)&0x000e)<<3) | ((DECO_PORT(location)&0x0001)<<7);
case 0x5a2/2: return (((DECO_PORT(0x24)&0xff00)>>4) | ((DECO_PORT(0x24)&0x000f)<<0) | ((DECO_PORT(0x24)&0x00f0)<<8)) & (~m_nand);
case 0x570/2: return (((DECO_PORT(0x24)&0xf0f0)>>0) | ((DECO_PORT(0x24)&0x000f)<<8)) ^ m_xor;
case 0x32e/2: return (((DECO_PORT(0x46)&0xf000)>>0) | ((DECO_PORT(0x46)&0x00ff)<<4)) & (~m_nand);
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 0x1be/2: return ((((DECO_PORT(0xc2)&0x0ff0)<<4) | ((DECO_PORT(0xc2)&0x0003)<<6) | ((DECO_PORT(0xc2)&0x000c)<<2)) ^ m_xor) & (~m_nand);
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 0x0a8/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 0x156/2: return (((DECO_PORT(0xde)&0xff00)<<0) | ((DECO_PORT(0xde)&0x000f)<<4) | ((DECO_PORT(0xde)&0x00f0)>>4)) & (~m_nand);
case 0x0a8/2: return (((DECO_PORT(0xde)&0xff00)>>4) | ((DECO_PORT(0xde)&0x000f)<<0) | ((DECO_PORT(0xde)&0x00f0)<<8)) & (~m_nand);
case 0x64a/2: return (((DECO_PORT(0xde)&0xfff0)>>4) | ((DECO_PORT(0xde)&0x000c)<<10) | ((DECO_PORT(0xde)&0x0003)<<14)) & (~m_nand);
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 0x212/2: return (((DECO_PORT(0x6e)&0xff00)>>4) | ((DECO_PORT(0x6e)&0x00f0)<<8) | ((DECO_PORT(0x6e)&0x000f)<<0)) ^ m_xor;
case 0x70a/2: return (((DECO_PORT(0xde)&0x00f0)<<8) | ((DECO_PORT(0xde)&0x0007)<<9) | ((DECO_PORT(0xde)&0x0008)<<5)) ^ m_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 0x514/2: return (((DECO_PORT(0x32)&0x0ff0)<<4) | ((DECO_PORT(0x32)&0x000c)<<2) | ((DECO_PORT(0x32)&0x0003)<<6)) & (~m_nand);
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 0x722/2: return (((DECO_PORT(0xdc)&0x0fff)<<4) ^ m_xor) & (~m_nand);
case 0x574/2: return ((((DECO_PORT(0xdc)&0xfff0)>>0) | ((DECO_PORT(0xdc)&0x0003)<<2) | ((DECO_PORT(0xdc)&0x000c)>>2)) ^ m_xor) & (~m_nand);
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 0x340/2: return ((DECO_PORT(0x90)&0xfff0) | ((DECO_PORT(0x90)&0x7)<<1) | ((DECO_PORT(0x90)&0x8)>>3)) ^ m_xor;
case 0x4a4/2: return (((DECO_PORT(0xce)&0x0ff0) | ((DECO_PORT(0xce)&0xf000)>>12) | ((DECO_PORT(0xce)&0x000f)<<12)) ^ m_xor) & (~m_nand);
case 0x256/2: return ((((DECO_PORT(0xce)&0xf000)>>12) | ((DECO_PORT(0xce)&0x0fff)<<4))) & (~m_nand);
case 0x79a/2: return (((DECO_PORT(0xc8)&0xfff0)>>4) | ((DECO_PORT(0xc8)&0x0008)<<9) | ((DECO_PORT(0xc8)&0x0007)<<13)) ^ m_xor;
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 0x79c/2: return ((DECO_PORT(0xc6)&0xf000) | ((DECO_PORT(0xc6)&0x00ff)<<4) | ((DECO_PORT(0xc6)&0x0f00)>>8)) & (~m_nand);
case 0x15e/2: return (((DECO_PORT(0x98)&0x0ff0)<<4) | ((DECO_PORT(0x98)&0xf000)>>12) | ((DECO_PORT(0x98)&0x0003)<<6) | ((DECO_PORT(0x98)&0x000c)<<2)) ^ m_xor;
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 0x01e/2: return ((((DECO_PORT(0xc4)&0xf000)>>4) | ((DECO_PORT(0xc4)&0x0f00)<<4) | ((DECO_PORT(0xc4)&0x00ff)<<0)) ^ m_xor) & (~m_nand);
case 0x23a/2: return ((((DECO_PORT(0x86)&0xfff0)>>0) | ((DECO_PORT(0x86)&0x0003)<<2) | ((DECO_PORT(0x86)&0x000c)>>2)) ^ m_xor);
case 0x06e/2: return ((((DECO_PORT(0x96)&0xf000)>>8) | ((DECO_PORT(0x96)&0x0f0f)<<0) | ((DECO_PORT(0x96)&0x00f0)<<8)) ^ m_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)) ^ m_xor);// & (~m_nand);
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); // 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 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)) ^ m_xor) & (~m_nand);
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 0x02c/2: return (((DECO_PORT(0x82)&0x0f0f)>>0) | ((DECO_PORT(0x82)&0xf000)>>8) | ((DECO_PORT(0x82)&0x00f0)<<8)) & (~m_nand);
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 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)) ^ m_xor);
case 0x168/2: return ((((DECO_PORT(0x84)&0x0ff0)<<4) | ((DECO_PORT(0x84)&0x000e)<<3) | ((DECO_PORT(0x84)&0x0001)<<5))) & (~m_nand);
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); // 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);
case 0x72a/2: return ((((DECO_PORT(0x86)&0xfff0)>>4) | ((DECO_PORT(0x86)&0x0003)<<14) | ((DECO_PORT(0x86)&0x000c)<<10)) ^ m_xor) & (~m_nand);
case 0x178/2: return (((DECO_PORT(0x88)&0x00ff)<<8) | ((DECO_PORT(0x88)&0xff00)>>8)) & (~m_nand); // also wizard fire
case 0x40e/2: return ((((DECO_PORT(0x8a)&0xf000)>>0) | ((DECO_PORT(0x8a)&0x00ff)<<4)) ^ m_xor) & (~m_nand);
case 0x248/2: return ((((DECO_PORT(0x8c)&0xff00)>>8) | ((DECO_PORT(0x8c)&0x00f0)<<4) | ((DECO_PORT(0x8c)&0x000f)<<12)) ^ m_xor) & (~m_nand);
case 0x27e/2: return ((((DECO_PORT(0x94)&0x00f0)<<8)) ^ m_xor) & (~m_nand);
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 0x00c/2: return ((DECO_PORT(0xd6)&0xf000)>>12) | ((DECO_PORT(0xd6)&0x0fff)<<4);
case 0x090/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 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)) ^ m_xor);
case 0x546/2: return (((DECO_PORT(0x62)&0xf0f0)>>0) | ((DECO_PORT(0x62)&0x000f)<<8)) & (~m_nand);
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 0x008/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 0x4b8/2: return (((DECO_PORT(0x46)&0xf000)>>12) | ((DECO_PORT(0x46)&0x0f00)>>4) | ((DECO_PORT(0x46)&0x00ff)<<8)) ^ m_xor;
case 0x65c/2: return ((((DECO_PORT(0x44)&0xf000)>>12) | ((DECO_PORT(0x44)&0x0fff)<<4)) ^ m_xor) & (~m_nand);
case 0x32a/2: return ((((DECO_PORT(0xc0)&0x0ff0)<<4) | ((DECO_PORT(0xc0)&0x000e)<<3) | ((DECO_PORT(0xc0)&0x0001)<<7))) & (~m_nand);// ^ m_xor;
case 0x008/2: return ((((DECO_PORT(0x94)&0xfff0)<<0) | ((DECO_PORT(0x94)&0x000e)>>1) | ((DECO_PORT(0x94)&0x0001)<<3))) & (~m_nand);// ^ m_xor;
case 0x456/2: return (((DECO_PORT(0x26)&0xfff0)<<0) | ((DECO_PORT(0x26)&0x0007)<<1) | ((DECO_PORT(0x26)&0x0008)>>3));// ^ m_xor;
case 0x190/2: return ((((DECO_PORT(0x44)&0xf000)<<0) | ((DECO_PORT(0x44)&0x00ff)<<4))) & (~m_nand);// ^ m_xor;
case 0x3f2/2: return ((((DECO_PORT(0x48)&0x000f)<<12) | ((DECO_PORT(0x48)&0x00f0)<<4))) & (~m_nand);// ^ m_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 0x19e/2: return ((((DECO_PORT(0x3c)&0xf000)>>12) | ((DECO_PORT(0x3c)&0x0f00)<<4) | ((DECO_PORT(0x3c)&0x00f0)>>0) | ((DECO_PORT(0x3c)&0x000f)<<8)) ^ m_xor) & (~m_nand);
case 0x2a2/2: return ((((DECO_PORT(0x44)&0xff00)>>8) | ((DECO_PORT(0x44)&0x00f0)<<8) | ((DECO_PORT(0x44)&0x000e)<<7) | ((DECO_PORT(0x44)&0x0001)<<11)) ^ m_xor) & (~m_nand);
case 0x748/2: return (((DECO_PORT(0x44)&0xfff0)<<0) | ((DECO_PORT(0x44)&0x000e)>>1) | ((DECO_PORT(0x44)&0x0001)<<3));// & (~m_nand);
case 0x686/2: return (((DECO_PORT(0x46)&0xf000)>>4) | ((DECO_PORT(0x46)&0x0f00)>>8) | ((DECO_PORT(0x46)&0x00f0)<<8) | ((DECO_PORT(0x46)&0x000f)<<4));// & (~m_nand);
case 0x4c4/2: return ((DECO_PORT(0x3c)&0x000f)<<12) & (~m_nand);
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 0x348/2: return ((((DECO_PORT(0x44)&0xf000)>>12) | ((DECO_PORT(0x44)&0x0ff0)<<4) | ((DECO_PORT(0x44)&0x000e)<<3) | ((DECO_PORT(0x44)&0x0001)<<7))) ^ m_xor;// & (~m_nand);
case 0x200/2: return (((DECO_PORT(0xa0)&0xfff0)>>4) | ((DECO_PORT(0xa0)&0x0007)<<13) | ((DECO_PORT(0xa0)&0x0008)<<9));// & (~m_nand);
case 0x254/2: return ((((DECO_PORT(0x7e)&0x0ff0)<<4) | ((DECO_PORT(0x7e)&0x000c)<<2) | ((DECO_PORT(0x7e)&0x0003)<<6))) ^ m_xor;// & (~m_nand);
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 0x058/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 0x48e/2: return ((((DECO_PORT(0x46)&0xf000)>>12) | ((DECO_PORT(0x46)&0x0f00)>>4) | ((DECO_PORT(0x46)&0x00f0)<<4) | ((DECO_PORT(0x46)&0x000f)<<12)));// /*^ m_xor*/) & (~m_nand);
case 0x4ba/2: return (((DECO_PORT(0x24)&0xf000)>>12) | ((DECO_PORT(0x24)&0x0ff0)<<4) | ((DECO_PORT(0x24)&0x000c)<<2) | ((DECO_PORT(0x24)&0x0003)<<6)) & (~m_nand);
case 0x092/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 0x1f0/2: return ((((DECO_PORT(0xa2)&0xf000)>>12) | ((DECO_PORT(0xa2)&0x0f00)>>4) | ((DECO_PORT(0xa2)&0x00ff)<<8)) ^ m_xor) & (~m_nand);
case 0x24e/2: return ((((DECO_PORT(0x46)&0xf000)>>8) | ((DECO_PORT(0x46)&0x0f00)>>0) | ((DECO_PORT(0x46)&0x00f0)>>4) | ((DECO_PORT(0x46)&0x000f)<<12)) ^ m_xor);// & (~m_nand);
case 0x594/2: return ((((DECO_PORT(0x40)&0x00f0)<<8) | ((DECO_PORT(0x40)&0x000c)<<6) | ((DECO_PORT(0x40)&0x0003)<<10)) ^ m_xor);// & (~m_nand);
case 0x7e2/2: return ((((DECO_PORT(0x96)&0xf000)<<0) | ((DECO_PORT(0x96)&0x00f0)<<4) | ((DECO_PORT(0x96)&0x000f)<<4))) ^ m_xor;// | ((DECO_PORT(0x96)&0x0001)<<7));// ^ m_xor);// & (~m_nand);
case 0x18c/2: return (((DECO_PORT(0x22)&0xfff0)>>4) | ((DECO_PORT(0x22)&0x000e)<<11) | ((DECO_PORT(0x22)&0x0001)<<15));// ^ m_xor);// & (~m_nand);
case 0x1fa/2: return ((((DECO_PORT(0x26)&0xf000)>>8) | ((DECO_PORT(0x26)&0x0f00)<<0) | ((DECO_PORT(0x26)&0x00f0)>>4) | ((DECO_PORT(0x26)&0x000f)<<12))) ^ m_xor;// & (~m_nand);
case 0x70e/2: return ((((DECO_PORT(0x26)&0x0ff0)<<4) | ((DECO_PORT(0x26)&0x000c)<<2) | ((DECO_PORT(0x26)&0x0003)<<6))) ^ m_xor;// & (~m_nand);
case 0x33a/2: return DECO_PORT(0x60) & (~m_nand);
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 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); // 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);
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 0x2ae/2: return ((DECO_PORT(0x9c)&0xf000)<<0) | ((DECO_PORT(0x9c)&0x0ff0)>>4) | ((DECO_PORT(0x9c)&0x000f)<<8);// & (~m_nand);
case 0x096/2: return ((((DECO_PORT(0x22)&0xff00)>>8) | ((DECO_PORT(0x22)&0x00f0)<<8) | ((DECO_PORT(0x22)&0x000e)<<7) | ((DECO_PORT(0x22)&0x0001)<<11)) ^ m_xor) & (~m_nand);
case 0x33e/2: return (((DECO_PORT(0x0)&0xf000)>>12) | ((DECO_PORT(0x0)&0x0f00)>>4) | ((DECO_PORT(0x0)&0x00f0)<<4) | ((DECO_PORT(0x0)&0x000f)<<12)) & (~m_nand); // also wizard fire
case 0x6c4/2: /* Reads from here flip buffers */location = 0x66; /* Flip occurs AFTER this data has been calculated*/return ((DECO_PORT(location)&0xf0f0) | ((DECO_PORT(location)&0x000f)<<8)) & (~m_nand);
case 0x700/2: /* Reads from here flip buffers */location = 0x66; return (((DECO_PORT(location)&0xf000)>>4) | ((DECO_PORT(location)&0x00f0)<<8)) ^ m_xor;
case 0x444/2: location = 0x66; return ((DECO_PORT(location)&0x00f0)<<8) | ((DECO_PORT(location)&0x0007)<<9) | ((DECO_PORT(location)&0x0008)<<5);
case 0x2d0/2: location = 0x66; return (((DECO_PORT(location)&0xf000)>>4) | ((DECO_PORT(location)&0x00f0)<<8)) ^ m_xor;
case 0x2b8/2: location = 0x66; return ((DECO_PORT(location)&0x00f0)<<8) ^ m_xor;
case 0x294/2: location = 0x66; return ((DECO_PORT(location)&0x000f)<<12);
case 0x1e8/2: location = 0x66; return 0; // todo
case 0x49c/2: return (((DECO_PORT(0x6c)&0x00f0)<<8) ^ m_xor) & (~m_nand);
case 0x44e/2: return (((DECO_PORT(0x44)&0x00f0)<<4) | ((DECO_PORT(0x44)&0x000f)<<12)) ^ m_xor;
case 0x3ca/2: return (((DECO_PORT(0x1e)&0xfff0)>>4) | ((DECO_PORT(0x1e)&0x0003)<<14) | ((DECO_PORT(0x1e)&0x000c)<<10)) ^ m_xor;
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);
case 0x03c/2: return (((DECO_PORT(0x1e)&0x0003)<<14) | ((DECO_PORT(0x1e)&0x000c)<<10)) & (~m_nand);
case 0x174/2: return (((DECO_PORT(0x1e)&0xff00)>>8) | ((DECO_PORT(0x1e)&0x00f0)<<8) | ((DECO_PORT(0x1e)&0x0007)<<9) | ((DECO_PORT(0x1e)&0x0008)<<5)) & (~m_nand);
case 0x34a/2: return (((DECO_PORT(0x4)&0xff00)>>0) | ((DECO_PORT(0x4)&0x00f0)>>4) | ((DECO_PORT(0x4)&0x000f)<<4)) & (~m_nand);
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 0x072/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 0x072/2: return ((((DECO_PORT(0xa)&0xf000)>>8) | ((DECO_PORT(0xa)&0x0ff0)<<4) | ((DECO_PORT(0xa)&0x000f)>>0))) & (~m_nand);
case 0x36e/2: return ((((DECO_PORT(0xc)&0xf000)>>0) | ((DECO_PORT(0xc)&0x0ff0)>>4) | ((DECO_PORT(0xc)&0x000f)<<8))) & (~m_nand);
case 0x590/2: return ((((DECO_PORT(0xe)&0xfff0)>>4) | ((DECO_PORT(0xe)&0x000e)<<11) | ((DECO_PORT(0xe)&0x0001)<<15))) ^ m_xor;
case 0x7b6/2: return ((((DECO_PORT(0x2)&0xf000)>>8) | ((DECO_PORT(0x2)&0x0ff0)<<4) | ((DECO_PORT(0x2)&0x000f)<<0)) ^ m_xor) & (~m_nand);
case 0x588/2: return ((((DECO_PORT(0x4)&0xff00)>>4) | ((DECO_PORT(0x4)&0x00f0)<<8) | ((DECO_PORT(0x4)&0x000f)<<0)) ^ m_xor) & (~m_nand);
case 0x1f6/2: return (((DECO_PORT(0x6)&0xf000)>>12) | ((DECO_PORT(0x6)&0x0ff0)<<4) | ((DECO_PORT(0x6)&0x0007)<<5) | ((DECO_PORT(0x6)&0x0008)<<1)) ^ m_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)) & (~m_nand);
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 0x7cc/2: return ((((DECO_PORT(0xc)&0xfff0)>>4) | ((DECO_PORT(0xc)&0x000e)<<11) | ((DECO_PORT(0xc)&0x0001)<<15)) ^ m_xor) & (~m_nand);
case 0x1bc/2: return (((DECO_PORT(0xe)&0xf000)>>12) | ((DECO_PORT(0xe)&0x0f00)>>4) | ((DECO_PORT(0xe)&0x00ff)<<8)) & (~m_nand);
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 0x454/2: return (((DECO_PORT(0x82)&0xf000)>>8) | ((DECO_PORT(0x82)&0x0f00)>>0) | ((DECO_PORT(0x82)&0x00f0)>>4) | ((DECO_PORT(0x82)&0x000f)<<12)) ^ m_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 0x250/2: return (((DECO_PORT(0x62)&0xf0f0)<<0) | ((DECO_PORT(0x62)&0x0f00)>>8) | ((DECO_PORT(0x62)&0x000f)<<8)) & (~m_nand);
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 0x04a/2: /* Schmeizr Robo only */ return DECO_PORT(0x9e) & (~deco16_mask);
case 0x7e8/2: /* Schmeizr Robo only */ return DECO_PORT(0x4a) ^ deco16_xor;
case 0x56a/2: /* Schmeizr Robo only */ return (((DECO_PORT(0x7c)&0xfff0)>>4) | ((DECO_PORT(0x7c)&0x000e)<<11) | ((DECO_PORT(0x7c)&0x0001)<<15)) & (~m_nand);
case 0x39a/2: /* Schmeizr Robo only */ return ((((DECO_PORT(0x7e)&0xfff0)>>4) | ((DECO_PORT(0x7e)&0x000e)<<11) | ((DECO_PORT(0x7e)&0x0001)<<15)) ^ m_xor) & (~m_nand);
case 0x188/2: /* Schmeizr Robo only */ return (((m_nand&0x0003)<<6) | ((m_nand&0x000c)<<2) | ((m_nand&0x00f0)<<4) | ((m_nand&0x0f00)<<4)) & (~m_nand);
case 0x3cc/2: /* Schmeizr Robo only */ return m_nand;
case 0x04a/2: /* Schmeizr Robo only */ return DECO_PORT(0x9e) & (~m_nand);
case 0x7e8/2: /* Schmeizr Robo only */ return DECO_PORT(0x4a) ^ m_xor;
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);
@ -433,8 +483,8 @@ UINT16 deco104_read_core(address_space &space, int offset, UINT16 mem_mask)
// 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 0x2cc/2: /* was 0x334*/ return machine().root_device().ioport(":IN1")->read();
case 0x3b0/2: /* was 0x0dc*/ return 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!)
@ -470,159 +520,12 @@ UINT16 deco104_read_core(address_space &space, int offset, UINT16 mem_mask)
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);
//logerror("Protection PC %06x: warning - read unmapped memory address %04x\n",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;
}
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);
}
/*
*/
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).
*/
offset &=0x7f;
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);
}
/**********************************************************************************/
@ -657,8 +560,11 @@ WRITE16_HANDLER( dietgo_104_prot_w )
/**********************************************************************************/
static UINT16 deco16_prot_ram[0x800];
READ16_HANDLER( deco16_104_pktgaldx_prot_r )
{
const UINT16* prot_ram=deco16_prot_ram;
switch (offset * 2)
{
@ -677,8 +583,10 @@ READ16_HANDLER( deco16_104_pktgaldx_prot_r )
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",space.device().safe_pc(),offset<<1,data);
}
/**********************************************************************************/
@ -687,253 +595,130 @@ WRITE16_HANDLER( deco16_104_pktgaldx_prot_w )
/* protection.. involves more addresses than this .. */
/* this is going to be typical deco '104' protection...
writes one place, reads back data shifted in another
the addresses below are the ones seen accessed by the
game so far...
we need to log the PC of each read/write and check to
see if the code makes any of them move obvious
// protection
// AM_RANGE(0x280104, 0x280105) AM_WRITENOP // ??
// AM_RANGE(0x2800ac, 0x2800ad) AM_READ_PORT("DSW") // dips
// AM_RANGE(0x280298, 0x280299) AM_READ_PORT("SYSTEM") // vbl
// AM_RANGE(0x280506, 0x280507) AM_READ_PORT("UNK")
// AM_RANGE(0x2802b4, 0x2802b5) AM_READ_PORT("P1_P2") // inverted?
// AM_RANGE(0x280330, 0x280331) AM_READNOP // sound?
// AM_RANGE(0x280380, 0x280381) AM_WRITENOP // sound
*/
READ16_MEMBER(deco104_device::dblewing_prot_r)
void deco104_device::write_protport(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask)
{
int deco104_addrxx = BITSWAP32(offset*2, 31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11, 17,16,15,14, 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0) & 0x7fff;
deco_146_base_device::write_protport(space,address,data,mem_mask);
deco104_addrxx ^= DECO104_MAGIC_XOR;
switch (deco104_addrxx)
if (m_use_dblewings_hacks==1)
{
//case 0x4c0: /* was 0x664 */ /* was 0x16a*/ return m_boss_move; // boss 1 movement // in shared sim
case 0x13a: /* was 0x39e */ /* was 0x6d6*/ return m_boss_move; // boss 1 2nd pilot
case 0x0ce: /* was 0x26a */ /* was 0x748*/ return m_boss_move; // boss 1 3rd pilot
case 0x492: /* was 0x636 */ /* was 0x566*/ return 0x0009; // boss BGM,might be a variable one (read->write to the sound latch)
case 0x440: /* was 0x6e4 */ /* was 0x1ea*/ return m_boss_shoot_type; // boss 1 shoot type
case 0x312: /* was 0x1b6 */ /* was 0x596*/ return m_boss_3_data; // boss 3 appearing
//case 0x32a: /* was 0x18e */ /* was 0x692*/ return m_boss_4_data; // in shared sim
case 0x72e: /* was 0x58a */ /* was 0x6b0*/ return m_boss_5_data;
//case 0x3d2: /* was 0x176 */ /* was 0x51e*/ return m_boss_5sx_data; // in shared sim
case 0x21e: /* was 0x0ba */ /* was 0x784*/ return m_boss_6_data;
case 0x78c: /* was 0x528 */ /* was 0x330*/ return 0; // controls bonuses such as shoot type,bombs etc.
case 0x114: /* was 0x3b0 */ /* was 0x1d4*/ return m_70c_data; //controls restart points
case 0x674: /* was 0x4d0 */ /* was 0x0ac*/ return (ioport(":DSW")->read() & 0x40) << 4;//flip screen
case 0x726: /* was 0x582 */ /* was 0x4b0*/return m_608_data;//coinage
case 0x4e4: /* was 0x640 */ /* was 0x068*/
switch (address)
{
switch (ioport(":DSW")->read() & 0x0300) //I don't know how to relationate this...
{
case 0x0000: return 0x000;//0
case 0x0100: return 0x060;//3
case 0x0200: return 0x0d0;//6
case 0x0300: return 0x160;//b
}
case 0x0c0: /* was 0x088*/
m_088_data = data;
if(m_088_data == 0) { m_boss_4_data = 0; }
else if(m_088_data & 0x8000) { m_boss_4_data = 0x50; }
else { m_boss_4_data = 0x40; }
return;
case 0x030: /* was 0x104*/
m_104_data = data;
return; // p1 inputs select screen OK
case 0x0e4: /* was 0x18a*/
m_18a_data = data;
switch (m_18a_data)
{
case 0x6b94: m_boss_5_data = 0x10; break; //initialize
case 0x7c68: m_boss_5_data = 0x60; break; //go up
case 0xfb1d: m_boss_5_data = 0x50; break;
case 0x977c: m_boss_5_data = 0x50; break;
case 0x8a49: m_boss_5_data = 0x60; break;
}
return;
case 0x008: /* was 0x200*/
m_200_data = data;
switch (m_200_data)
{
case 0x5a19: m_boss_move = 1; break;
case 0x3b28: m_boss_move = 2; break;
case 0x1d4d: m_boss_move = 1; break;
}
//popmessage("%04x",m_200_data);
return;
case 0x088: /* was 0x280*/
m_280_data = data;
switch (m_280_data)
{
case 0x6b94: m_boss_5sx_data = 0x10; break;
case 0x7519: m_boss_5sx_data = 0x60; break;
case 0xfc68: m_boss_5sx_data = 0x50; break;
case 0x02dd: m_boss_5sx_data = 0x50; break;
case 0x613c: m_boss_5sx_data = 0x50; break;
}
//printf("%04x\n",m_280_data);
return;
//case 0x0a8: /* was 0x380*/
// drvstate->soundlatch_byte_w(space, 0, data & 0xff);
// cpudev = (cpu_device*)machine().device(":audiocpu");
// if (cpudev) cpudev->set_input_line(0, HOLD_LINE);
// m_sound_irq |= 0x02;
// m_audiocpu->set_input_line(0, (m_sound_irq != 0) ? ASSERT_LINE : CLEAR_LINE);
// return;
case 0x0b8: /* was 0x384*/
m_384_data = data;
switch(m_384_data)
{
case 0xaa41: m_boss_6_data = 1; break;
case 0x5a97: m_boss_6_data = 2; break;
case 0xbac5: m_boss_6_data = 3; break;
case 0x0afb: m_boss_6_data = 4; break;
case 0x6a99: m_boss_6_data = 5; break;
case 0xda8f: m_boss_6_data = 6; break;
}
return;
case 0x0fc: /* was 0x38e*/
m_38e_data = data;
switch(m_38e_data)
{
case 0x6c13: m_boss_shoot_type = 3; break;
case 0xc311: m_boss_shoot_type = 0; break;
case 0x1593: m_boss_shoot_type = 1; break;
case 0xf9db: m_boss_shoot_type = 2; break;
case 0xf742: m_boss_shoot_type = 3; break;
case 0xeff5: m_boss_move = 1; break;
case 0xd2f1: m_boss_move = 2; break;
//default: printf("%04x\n",m_38e_data); break;
//case 0xe65a: m_boss_shoot_type = 0; break;
}
return;
case 0x0f2: /* was 0x58c*/ // 3rd player 1st level
m_58c_data = data;
if(m_58c_data == 0) { m_boss_move = 5; }
else { m_boss_move = 2; }
return;
case 0x04e: /* was 0x60a*/
m_60a_data = data;
if(m_60a_data & 0x8000) { m_boss_3_data = 2; }
else { m_boss_3_data = 9; }
return;
case 0x0a2: /* was 0x580*/
m_580_data = data;
return;
case 0x016: /* was 0x406*/
m_406_data = data;
return; // p2 inputs select screen OK
case 0x040: /* was 0x008*/ { m_008_data = data; return; }
case 0x080: /* was 0x080*/ { m_080_data = data; return; } // p3 3rd boss?
case 0x0d8: /* was 0x28c*/ { m_28c_data = data; return; }
case 0x042: /* was 0x408*/ { m_408_data = data; return; } // 3rd player 1st level?
case 0x056: /* was 0x40e*/ { m_40e_data = data; return; } // 3rd player 2nd level?
case 0x04a: /* was 0x608*/ { m_608_data = data; return; }
case 0x07a: /* was 0x70c*/ { m_70c_data = data; return; }
case 0x0ee: /* was 0x78a*/ { m_78a_data = data; return; }
case 0x0ea: /* was 0x788*/ { m_788_data = data; return; }
}
//case 0x334: /* was 0x190 */ /* was 0x094*/ return m_104_data;// p1 inputs select screen OK // in shared sim
//case 0x0fc: /* was 0x258 */ /* was 0x24c*/return m_008_data;//read DSW (mirror for coinage/territory) // in shared sim
//case 0x36c: /* was 0x1c8 */ /* was 0x298*/return ioport(":IN1")->read();//vblank // in shared sim
case 0x5b2: /* was 0x716 */ /* was 0x476*/return ioport(":IN1")->read();//mirror for coins
//case 0x292: /* was 0x036 */ /* was 0x506*/return ioport(":DSW")->read(); // in shared sim
case 0x146: /* was 0x3e2 */ /* was 0x5d8*/return m_406_data;
case 0x73c: /* was 0x598 */ /* was 0x2b4*/return ioport(":IN0")->read();
case 0x644: /* was 0x4e0 */ /* was 0x1a8*/return (ioport(":DSW")->read() & 0x4000) >> 12;//allow continue
// case 0x45c: /* was 0x6f8 */ /* was 0x3ec*/return m_70c_data; //score entry // in shared sim
case 0x0b8: /* was 0x21c */ /* was 0x246*/return m_580_data; // these three controls "perfect bonus" I suppose...
case 0x6d2: /* was 0x476 */ /* was 0x52e*/return m_580_data;
//case 0x782: /* was 0x526 */ /* was 0x532*/return m_580_data; // in shared sim
case 0x564: /* was 0x7c0 */ /* was 0x0f8*/ return 0; // m_080_data;
//case 0x294: /* was 0x030 */ /* was 0x104*/ return 0; // in shared sim (ram buffer change!)
//case 0x2d0: /* was 0x074 */ /* was 0x10e*/ return 0;// in shared sim (ram buffer change!)
//case 0x2b8: /* was 0x01c */ /* was 0x206*/ return 0; // m_70c_data;// in shared sim (ram buffer change!)
case 0x1fc: /* was 0x358 */ /* was 0x25c*/return 0;
case 0x23c: /* was 0x098 */ /* was 0x284*/ return 0; // 3rd player 2nd boss
case 0x7a2: /* was 0x506 */ /* was 0x432*/return 0; // boss on water level?
case 0x0c2: /* was 0x266 */ /* was 0x54a*/ return 0; // 3rd player 2nd boss
case 0x21a: /* was 0x0be */ /* was 0x786*/return 0;
}
// printf("dblewing prot r %08x, %04x, %04x\n", space.device().safe_pc(), offset * 2, mem_mask);
mame_printf_debug("dblewing prot r %08x, %04x, %04x\n", space.device().safe_pc(), offset * 2, mem_mask);
return deco104_read_core(space, deco104_addrxx/2, mem_mask);
return 0;//machine().rand();
}
WRITE16_MEMBER(deco104_device::dblewing_prot_w)
{
// if (offset * 2 != 0x380)
// printf("dblewing prot w %08x, %04x, %04x %04x\n", space.device().safe_pc(), offset * 2, mem_mask, data);
driver_device *drvstate = machine().driver_data<driver_device>();
cpu_device* cpudev = 0;
int deco104_addrxx = BITSWAP32(offset *2, 31,30,29,28,27,26,25,24,23,22,21,20,19,18, 13,12,11, 17,16,15,14, 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0) & 0x7fff;
deco104_addrxx &=0xff;
if (decoprot_buffer_ram_selected)
COMBINE_DATA(&decoprot_buffer_ram[deco104_addrxx/2]);
else
COMBINE_DATA(&deco16_prot_ram[deco104_addrxx/2]);
driver_device *state = space.machine().driver_data<driver_device>();
if (deco104_addrxx == (0xa8))
{
state->soundlatch_byte_w(space, 0, data & 0xff);
space.machine().device("audiocpu")->execute().set_input_line(0, HOLD_LINE);
}
// These are set regardless of bank
if (deco104_addrxx==0x42)
COMBINE_DATA(&deco16_xor);
if (deco104_addrxx==0xee)
COMBINE_DATA(&deco16_mask);
switch (deco104_addrxx)
{
case 0x0c0: /* was 0x088*/
m_088_data = data;
if(m_088_data == 0) { m_boss_4_data = 0; }
else if(m_088_data & 0x8000) { m_boss_4_data = 0x50; }
else { m_boss_4_data = 0x40; }
return;
case 0x030: /* was 0x104*/
m_104_data = data;
return; // p1 inputs select screen OK
case 0x0e4: /* was 0x18a*/
m_18a_data = data;
switch (m_18a_data)
{
case 0x6b94: m_boss_5_data = 0x10; break; //initialize
case 0x7c68: m_boss_5_data = 0x60; break; //go up
case 0xfb1d: m_boss_5_data = 0x50; break;
case 0x977c: m_boss_5_data = 0x50; break;
case 0x8a49: m_boss_5_data = 0x60; break;
}
return;
case 0x008: /* was 0x200*/
m_200_data = data;
switch (m_200_data)
{
case 0x5a19: m_boss_move = 1; break;
case 0x3b28: m_boss_move = 2; break;
case 0x1d4d: m_boss_move = 1; break;
}
//popmessage("%04x",m_200_data);
return;
case 0x088: /* was 0x280*/
m_280_data = data;
switch (m_280_data)
{
case 0x6b94: m_boss_5sx_data = 0x10; break;
case 0x7519: m_boss_5sx_data = 0x60; break;
case 0xfc68: m_boss_5sx_data = 0x50; break;
case 0x02dd: m_boss_5sx_data = 0x50; break;
case 0x613c: m_boss_5sx_data = 0x50; break;
}
//printf("%04x\n",m_280_data);
return;
case 0x0a8: /* was 0x380*/
drvstate->soundlatch_byte_w(space, 0, data & 0xff);
cpudev = (cpu_device*)machine().device(":audiocpu");
if (cpudev) cpudev->set_input_line(0, HOLD_LINE);
// m_sound_irq |= 0x02;
// m_audiocpu->set_input_line(0, (m_sound_irq != 0) ? ASSERT_LINE : CLEAR_LINE);
return;
case 0x0b8: /* was 0x384*/
m_384_data = data;
switch(m_384_data)
{
case 0xaa41: m_boss_6_data = 1; break;
case 0x5a97: m_boss_6_data = 2; break;
case 0xbac5: m_boss_6_data = 3; break;
case 0x0afb: m_boss_6_data = 4; break;
case 0x6a99: m_boss_6_data = 5; break;
case 0xda8f: m_boss_6_data = 6; break;
}
return;
case 0x0fc: /* was 0x38e*/
m_38e_data = data;
switch(m_38e_data)
{
case 0x6c13: m_boss_shoot_type = 3; break;
case 0xc311: m_boss_shoot_type = 0; break;
case 0x1593: m_boss_shoot_type = 1; break;
case 0xf9db: m_boss_shoot_type = 2; break;
case 0xf742: m_boss_shoot_type = 3; break;
case 0xeff5: m_boss_move = 1; break;
case 0xd2f1: m_boss_move = 2; break;
//default: printf("%04x\n",m_38e_data); break;
//case 0xe65a: m_boss_shoot_type = 0; break;
}
return;
case 0x0f2: /* was 0x58c*/ // 3rd player 1st level
m_58c_data = data;
if(m_58c_data == 0) { m_boss_move = 5; }
else { m_boss_move = 2; }
return;
case 0x04e: /* was 0x60a*/
m_60a_data = data;
if(m_60a_data & 0x8000) { m_boss_3_data = 2; }
else { m_boss_3_data = 9; }
return;
case 0x0a2: /* was 0x580*/
m_580_data = data;
return;
case 0x016: /* was 0x406*/
m_406_data = data;
return; // p2 inputs select screen OK
case 0x040: /* was 0x008*/ { m_008_data = data; return; }
case 0x080: /* was 0x080*/ { m_080_data = data; return; } // p3 3rd boss?
case 0x0d8: /* was 0x28c*/ { m_28c_data = data; return; }
case 0x042: /* was 0x408*/ { m_408_data = data; return; } // 3rd player 1st level?
case 0x056: /* was 0x40e*/ { m_40e_data = data; return; } // 3rd player 2nd level?
case 0x04a: /* was 0x608*/ { m_608_data = data; return; }
case 0x07a: /* was 0x70c*/ { m_70c_data = data; return; }
case 0x0ee: /* was 0x78a*/ { m_78a_data = data; return; }
case 0x0ea: /* was 0x788*/ { m_788_data = data; return; }
}
// printf("dblewing prot w %08x, %04x, %04x %04x\n", space.device().safe_pc(), offset * 2, mem_mask, data);
}

View File

@ -2,24 +2,37 @@
#ifndef __DECO104_H__
#define __DECO104_H__
#include "deco146.h"
#define MCFG_DECO104_SET_USE_DOUBLEWINGS_HACK \
deco104_device::set_use_dblewing_hacks(*device, 1 );
/* Data East 104 protection chip */
class deco104_device : public device_t
class deco104_device : public deco_146_base_device
{
public:
deco104_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ16_MEMBER(dblewing_prot_r);
DECLARE_WRITE16_MEMBER(dblewing_prot_w);
virtual UINT16 read_data_getloc(UINT16 address, int& location);
static void set_use_dblewing_hacks(device_t &device, int use_hacks);
protected:
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual void write_protport(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask);
/* for the buggy double wing sim */
/* protection */
int m_use_dblewings_hacks;
UINT16 m_008_data;
UINT16 m_104_data;
UINT16 m_406_data;
@ -59,17 +72,13 @@ extern const device_type DECO104PROT;
#define MCFG_DECO104_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, DECO104PROT, 0)
// old
void decoprot104_reset(running_machine &machine);
DECLARE_READ16_HANDLER( deco16_104_prot_r );
DECLARE_READ16_HANDLER( deco16_104_cninja_prot_r );
DECLARE_READ16_HANDLER( deco16_104_rohga_prot_r );
DECLARE_READ16_HANDLER( deco16_104_pktgaldx_prot_r );
DECLARE_WRITE16_HANDLER( deco16_104_prot_w );
DECLARE_WRITE16_HANDLER( deco16_104_cninja_prot_w );
DECLARE_WRITE16_HANDLER( deco16_104_rohga_prot_w );
DECLARE_WRITE16_HANDLER( deco16_104_pktgaldx_prot_w );
DECLARE_READ16_HANDLER( dietgo_104_prot_r );
DECLARE_WRITE16_HANDLER( dietgo_104_prot_w );

View File

@ -41,46 +41,12 @@
*/
#include "emu.h"
#include "deco146.h"
#include "machine/eeprom.h"
// for older handlers
#define DECO_PORT(p) (prot_ram[p/2])
//#define DECO_REVERSE(p) (prot_ram[BITSWAP16(p, 15,14,13,12,11 ,1,2,3,4,5,6,7,8,9,10, 0) /2])
static UINT8 deco146prot_buffer_ram_selected=0;
static UINT16 deco146_xor=0;
static UINT16 deco146_mask;
static int deco146prot_last_write=0, deco146prot_last_write_val=0;
static UINT16 deco146prot_buffer_ram[0x800];
static UINT16 deco146prot_buffer_ram2[0x800];
static UINT16 *deco16_prot_ram;
static UINT32 *deco32_prot_ram;
void decoprot146_reset(running_machine &machine)
{
deco146_xor=0;
deco146_mask=0xffff;
deco146prot_last_write=deco146prot_last_write_val=0;
deco146prot_buffer_ram_selected=0;
deco16_prot_ram = reinterpret_cast<UINT16 *>(machine.root_device().memshare("prot16ram")->ptr());
deco32_prot_ram = reinterpret_cast<UINT32 *>(machine.root_device().memshare("prot32ram")->ptr());
machine.save().save_item(NAME(deco146_xor));
machine.save().save_item(NAME(deco146_mask));
machine.save().save_item(NAME(deco146prot_last_write));
machine.save().save_item(NAME(deco146prot_last_write_val));
machine.save().save_item(NAME(deco146prot_buffer_ram_selected));
machine.save().save_item(NAME(deco146prot_buffer_ram));
machine.save().save_item(NAME(deco146prot_buffer_ram2));
}
@ -1129,18 +1095,18 @@ struct deco146port_xx
UINT16 reorder(UINT16 input, UINT8 *weights)
{
UINT16 temp = 0;
for(int i = 0; i < 16; i++)
{
if(input & (1 << i)) // if input bit is set
{
if(weights[i] != 0xFF) // and weight exists for output bit
{
temp |= 1 << weights[i]; // set that bit
}
}
}
return temp;
UINT16 temp = 0;
for(int i = 0; i < 16; i++)
{
if(input & (1 << i)) // if input bit is set
{
if(weights[i] != 0xFF) // and weight exists for output bit
{
temp |= 1 << weights[i]; // set that bit
}
}
}
return temp;
}
@ -1148,8 +1114,10 @@ UINT16 reorder(UINT16 input, UINT8 *weights)
/* there are probably less dumb ways of doing the CS logic, it could be hooked up
more like the system16 mapper chips */
void deco146_device::write_data(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask, UINT8 &csflags)
void deco_146_base_device::write_data(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask, UINT8 &csflags)
{
address = BITSWAP16(address>>1, 15,14,13,12,11,10, m_external_addrswap[9],m_external_addrswap[8] ,m_external_addrswap[7],m_external_addrswap[6],m_external_addrswap[5],m_external_addrswap[4],m_external_addrswap[3],m_external_addrswap[2],m_external_addrswap[1],m_external_addrswap[0]) << 1;
csflags = 0;
int upper_addr_bits = (address & 0x7800) >> 11;
@ -1202,19 +1170,9 @@ void deco146_device::write_data(address_space &space, UINT16 address, UINT16 dat
void deco146_device::soundlatch_write_callback(address_space &space, UINT16 data, UINT16 mem_mask)
UINT16 deco_146_base_device::read_protport(UINT16 address, UINT16 mem_mask)
{
driver_device *drvstate = machine().driver_data<driver_device>();
drvstate->soundlatch_byte_w(space, 0, data & 0xff);
cpu_device* cpudev = (cpu_device*)machine().device(":audiocpu");
if (cpudev) cpudev->set_input_line(0, HOLD_LINE);
}
UINT16 deco146_device::read_protport(UINT16 address, UINT16 mem_mask, int extra_read_address_xor)
{
UINT16 retdata = 0;
// if we read the last written address immediately after then ignore all other logic and just return what was written unmodified
if ((address==m_latchaddr) && (m_latchflag==1))
@ -1226,76 +1184,19 @@ UINT16 deco146_device::read_protport(UINT16 address, UINT16 mem_mask, int extra_
m_latchflag = 0;
if (extra_read_address_xor) address ^= 0x44a;
if (m_magic_read_address_xor_enabled) address ^= m_magic_read_address_xor;
// otherwise process the data..
int location = port_table[address>>1].write_offset;
// I haven't completed the input remap ports yet
// if (location==INPUT_PORT_A_NV) fatalerror("read unverified port INPUT_PORT_A_NV (%04x)", address);
// if (location==INPUT_PORT_B_NV) fatalerror("read unverified port INPUT_PORT_B_NV (%04x)", address);
// if (location==INPUT_PORT_C_NV) fatalerror("read unverified port INPUT_PORT_C_NV (%04x)", address);
int location = 0;
UINT16 realret = read_data_getloc(address, location);
if (location==INPUT_PORT_A)
if (location == m_bankswitch_swap_read_address) // this has a special meaning
{
retdata = m_port_a_r(0);
}
else if (location==INPUT_PORT_B)
{
retdata = m_port_b_r(0);
}
else if (location==INPUT_PORT_C)
{
retdata = m_port_c_r(0);
}
else
{
retdata = m_current_rambank[location>>1];
}
if (location>=0)
{
logerror("read_protport (real ram addres %02x) | %04x %04x | ", location, address, mem_mask);
logerror("remap { ");
for (int i=0;i<16;i++)
{
//logerror(" %02x, ", remapdata[((address>>1)*16)+i]);
}
logerror(" }");
if ((port_table[address>>1].use_xor)) logerror("read is affected by XOR | ");
if ((port_table[address>>1].use_nand)) logerror("read is affected by NAND | ");
logerror("would return %04x | ", retdata);
}
UINT16 realret;
/*if (location>=0)*/ realret = reorder(retdata, &port_table[address>>1].mapping[0] );
//else realret = retdata; // todo reordering on the input port mirrors too!
if (port_table[address>>1].use_xor) realret ^= m_xor;
if (port_table[address>>1].use_nand) realret = (realret & ~m_nand);
if (location>=0)
{
logerror("actual return %04x \n", realret);
}
if (location == 0x78) // this has a special meaning
{
logerror("(bankswitch) %04x %04x\n", address, mem_mask);
// logerror("(bankswitch) %04x %04x\n", address, mem_mask);
if (m_current_rambank==m_rambank0)
m_current_rambank = m_rambank1;
@ -1307,27 +1208,27 @@ UINT16 deco146_device::read_protport(UINT16 address, UINT16 mem_mask, int extra_
return realret;
}
void deco146_device::write_protport(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask)
void deco_146_base_device::write_protport(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask)
{
m_latchaddr = address;
m_latchdata = data;
m_latchflag = 1;
if ((address&0xff) == 0x2c)
if ((address&0xff) == m_xor_port)
{
logerror("LOAD XOR REGISTER %04x %04x\n", data, mem_mask);
COMBINE_DATA(&m_xor);
}
else if ((address&0xff) == 0x36)
else if ((address&0xff) == m_mask_port)
{
logerror("LOAD NAND REGISTER %04x %04x\n", data, mem_mask);
COMBINE_DATA(&m_nand);
}
else if ((address&0xff) == 0x64)
else if ((address&0xff) == m_soundlatch_port)
{
logerror("LOAD SOUND LATCH %04x %04x\n", data, mem_mask);
COMBINE_DATA(&m_soundlatch);
soundlatch_write_callback(space, data, mem_mask);
m_soundlatch_w(space, data, mem_mask);
}
// always store
@ -1336,8 +1237,11 @@ void deco146_device::write_protport(address_space &space, UINT16 address, UINT16
}
UINT16 deco146_device::read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags, int extra_read_address_xor)
UINT16 deco_146_base_device::read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags)
{
address = BITSWAP16(address>>1, 15,14,13,12,11,10, m_external_addrswap[9],m_external_addrswap[8] ,m_external_addrswap[7],m_external_addrswap[6],m_external_addrswap[5],m_external_addrswap[4],m_external_addrswap[3],m_external_addrswap[2],m_external_addrswap[1],m_external_addrswap[0]) << 1;
UINT16 retdata = 0;
csflags = 0;
int upper_addr_bits = (address & 0x7800) >> 11;
@ -1362,7 +1266,7 @@ UINT16 deco146_device::read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags
if (i==0) // the first cs is our internal protection area
{
//logerror("read matches cs table (protection) %01x %04x %04x\n", i, real_address, mem_mask);
return read_protport( real_address, mem_mask, extra_read_address_xor);
return read_protport( real_address, mem_mask);
}
else
{
@ -1380,20 +1284,31 @@ UINT16 deco146_device::read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags
}
const device_type DECO146PROT = &device_creator<deco146_device>;
//const device_type DECO146BASE = &device_creator<deco_146_base_device>;
deco146_device::deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, DECO146PROT, "DECO146PROT", tag, owner, clock, "deco146", __FILE__)
deco_146_base_device::deco_146_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
{
m_port_a_r = deco146_port_read_cb(FUNC(deco146_device::port_a_default), this);
m_port_b_r = deco146_port_read_cb(FUNC(deco146_device::port_b_default), this);
m_port_c_r = deco146_port_read_cb(FUNC(deco146_device::port_c_default), this);
m_port_a_r = deco146_port_read_cb(FUNC(deco_146_base_device::port_a_default), this);
m_port_b_r = deco146_port_read_cb(FUNC(deco_146_base_device::port_b_default), this);
m_port_c_r = deco146_port_read_cb(FUNC(deco_146_base_device::port_c_default), this);
m_soundlatch_w = deco146_port_write_cb(FUNC(deco_146_base_device::soundlatch_default), this);
m_external_addrswap[0] = 0;
m_external_addrswap[1] = 1;
m_external_addrswap[2] = 2;
m_external_addrswap[3] = 3;
m_external_addrswap[4] = 4;
m_external_addrswap[5] = 5;
m_external_addrswap[6] = 6;
m_external_addrswap[7] = 7;
m_external_addrswap[8] = 8;
m_external_addrswap[9] = 9;
}
void deco146_device::device_config_complete()
void deco_146_base_device::device_config_complete()
{
}
@ -1401,30 +1316,57 @@ void deco146_device::device_config_complete()
UINT16 deco146_device::port_a_default(int unused)
UINT16 deco_146_base_device::port_a_default(int unused)
{
return ioport(":INPUTS")->read();
}
UINT16 deco146_device::port_b_default(int unused)
UINT16 deco_146_base_device::port_b_default(int unused)
{
return ioport(":SYSTEM")->read();
}
UINT16 deco146_device::port_c_default(int unused)
UINT16 deco_146_base_device::port_c_default(int unused)
{
return ioport(":DSW")->read();
}
void deco_146_base_device::soundlatch_default(address_space &space, UINT16 data, UINT16 mem_mask)
{
driver_device *drvstate = machine().driver_data<driver_device>();
drvstate->soundlatch_byte_w(space, 0, data & 0xff);
cpu_device* cpudev = (cpu_device*)machine().device(":audiocpu");
if (cpudev) cpudev->set_input_line(0, HOLD_LINE);
}
void deco_146_base_device::set_port_a_cb(device_t &device,deco146_port_read_cb port_cb) { deco_146_base_device &dev = downcast<deco_146_base_device &>(device); dev.m_port_a_r = port_cb; }
void deco_146_base_device::set_port_b_cb(device_t &device,deco146_port_read_cb port_cb) { deco_146_base_device &dev = downcast<deco_146_base_device &>(device); dev.m_port_b_r = port_cb; }
void deco_146_base_device::set_port_c_cb(device_t &device,deco146_port_read_cb port_cb) { deco_146_base_device &dev = downcast<deco_146_base_device &>(device); dev.m_port_c_r = port_cb; }
void deco_146_base_device::set_soundlatch_cb(device_t &device,deco146_port_write_cb port_cb) { deco_146_base_device &dev = downcast<deco_146_base_device &>(device); dev.m_soundlatch_w = port_cb; }
void deco_146_base_device::set_interface_scramble(device_t &device,UINT8 a9, UINT8 a8, UINT8 a7, UINT8 a6, UINT8 a5, UINT8 a4, UINT8 a3,UINT8 a2,UINT8 a1,UINT8 a0)
{
deco_146_base_device &dev = downcast<deco_146_base_device &>(device);
dev.m_external_addrswap[9] = a9;
dev.m_external_addrswap[8] = a8;
dev.m_external_addrswap[7] = a7;
dev.m_external_addrswap[6] = a6;
dev.m_external_addrswap[5] = a5;
dev.m_external_addrswap[4] = a4;
dev.m_external_addrswap[3] = a3;
dev.m_external_addrswap[2] = a2;
dev.m_external_addrswap[1] = a1;
dev.m_external_addrswap[0] = a0;
}
void deco_146_base_device::set_use_magic_read_address_xor(device_t &device, int use_xor)
{
deco_146_base_device &dev = downcast<deco_146_base_device &>(device);
dev.m_magic_read_address_xor_enabled = use_xor;
}
void deco146_device::set_port_a_cb(device_t &device,deco146_port_read_cb port_cb) { deco146_device &dev = downcast<deco146_device &>(device); dev.m_port_a_r = port_cb; }
void deco146_device::set_port_b_cb(device_t &device,deco146_port_read_cb port_cb) { deco146_device &dev = downcast<deco146_device &>(device); dev.m_port_b_r = port_cb; }
void deco146_device::set_port_c_cb(device_t &device,deco146_port_read_cb port_cb) { deco146_device &dev = downcast<deco146_device &>(device); dev.m_port_c_r = port_cb; }
void deco146_device::device_start()
void deco_146_base_device::device_start()
{
for (int i=0;i<0x80;i++)
@ -1439,9 +1381,14 @@ void deco146_device::device_start()
m_port_a_r.bind_relative_to(*owner());
m_port_b_r.bind_relative_to(*owner());
m_port_c_r.bind_relative_to(*owner());
m_soundlatch_w.bind_relative_to(*owner());
save_item(NAME(m_xor));
save_item(NAME(m_nand));
}
void deco146_device::device_reset()
void deco_146_base_device::device_reset()
{
region_selects[0] = 0;
region_selects[1] = 0;
@ -1461,6 +1408,13 @@ void deco146_device::device_reset()
m_latchaddr = 0xffff;
m_latchdata = 0x0000;
m_latchflag = 0;
m_xor=0;
// m_nand=0xffff;
m_nand=0x0; // wizard fire doesn't initialize it, but accesses addresses rohga needs the mask applied on
}
/****************************************************************************************************
@ -1483,7 +1437,7 @@ void deco146_device::device_reset()
// alt read addresses (same as nitroball if you reverse lnes)
READ16_MEMBER(deco146_device::robocop2_prot_r)
READ16_MEMBER(deco_146_base_device::robocop2_prot_r)
{
switch (offset << 1)
{
@ -1503,7 +1457,7 @@ READ16_MEMBER(deco146_device::robocop2_prot_r)
// alt read addresses (same as nitroball if you reverse lnes)
/* Same as Robocop 2 protection chip */
READ16_MEMBER(deco146_device::lemmings_prot_r)
READ16_MEMBER(deco_146_base_device::lemmings_prot_r)
{
switch (offset << 1)
{
@ -1521,7 +1475,7 @@ READ16_MEMBER(deco146_device::lemmings_prot_r)
}
// standard read addresses
READ32_MEMBER(deco146_device::captaven_prot_r)
READ32_MEMBER(deco_146_base_device::captaven_prot_r)
{
/* Protection/IO chip 75, same as Lemmings & Robocop 2 */
switch (offset<<2) {
@ -1536,7 +1490,7 @@ READ32_MEMBER(deco146_device::captaven_prot_r)
// alt read addresses? make sure this isn't 104
READ32_MEMBER(deco146_device::dragngun_prot_r)
READ32_MEMBER(deco_146_base_device::dragngun_prot_r)
{
// logerror("%08x:Read prot %08x (%08x)\n",space.device().safe_pc(),offset<<1,mem_mask);
@ -1554,7 +1508,7 @@ READ32_MEMBER(deco146_device::dragngun_prot_r)
}
READ32_MEMBER(deco146_device::stadhr96_prot_146_r)
READ32_MEMBER(deco_146_base_device::stadhr96_prot_146_r)
{
/*
cpu #0 (PC=00041BD0): unmapped program memory dword write to 00708004 = 000F0000 & FFFFFFFF
@ -1580,8 +1534,56 @@ READ32_MEMBER(deco146_device::stadhr96_prot_146_r)
return 0;
}
WRITE32_MEMBER(deco146_device::stadhr96_prot_146_w)
WRITE32_MEMBER(deco_146_base_device::stadhr96_prot_146_w)
{
printf("%08x: Write prot %04x %08x\n", space.device().safe_pc(), offset, data);
}
const device_type DECO146PROT = &device_creator<deco146_device>;
// 104 will probably use this too, once we have real tables for it!
UINT16 deco146_device::read_data_getloc(UINT16 address, int& location)
{
UINT16 retdata = 0;
location = port_table[address>>1].write_offset;
if (location==INPUT_PORT_A)
{
retdata = m_port_a_r(0);
}
else if (location==INPUT_PORT_B)
{
retdata = m_port_b_r(0);
}
else if (location==INPUT_PORT_C)
{
retdata = m_port_c_r(0);
}
else
{
retdata = m_current_rambank[location>>1];
}
UINT16 realret = reorder(retdata, &port_table[address>>1].mapping[0] );
if (port_table[address>>1].use_xor) realret ^= m_xor;
if (port_table[address>>1].use_nand) realret = (realret & ~m_nand);
return realret;
}
deco146_device::deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: deco_146_base_device(mconfig, DECO146PROT, "DECO146PROT", tag, owner, clock, "deco146", __FILE__)
{
m_bankswitch_swap_read_address = 0x78;
m_magic_read_address_xor = 0x44a;
m_magic_read_address_xor_enabled = 0;
m_xor_port = 0x2c;
m_mask_port = 0x36;
m_soundlatch_port = 0x64;
}

View File

@ -3,31 +3,54 @@
#define __DECO146_H__
typedef device_delegate<UINT16 (int unused)> deco146_port_read_cb;
typedef device_delegate<void (address_space &space, UINT16 data, UINT16 mem_mask)> deco146_port_write_cb;
#define MCFG_DECO146_SET_PORTA_CALLBACK( _class, _method) \
deco146_device::set_port_a_cb(*device, deco146_port_read_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
deco_146_base_device::set_port_a_cb(*device, deco146_port_read_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
#define MCFG_DECO146_SET_PORTB_CALLBACK( _class, _method) \
deco146_device::set_port_b_cb(*device, deco146_port_read_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
deco_146_base_device::set_port_b_cb(*device, deco146_port_read_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
#define MCFG_DECO146_SET_PORTC_CALLBACK( _class, _method) \
deco146_device::set_port_c_cb(*device, deco146_port_read_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
deco_146_base_device::set_port_c_cb(*device, deco146_port_read_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
#define MCFG_DECO146_SET_SOUNDLATCH_CALLBACK( _class, _method) \
deco_146_base_device::set_soundlatch_cb(*device, deco146_port_write_cb(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
// there are some standard ways the chip gets hooked up, so have them here ready to use
#define MCFG_DECO146_SET_INTERFACE_SCRAMBLE( a9,a8,a7,a6,a5,a4,a3,a2,a1,a0 ) \
deco_146_base_device::set_interface_scramble(*device, a9,a8,a7,a6,a5,a4,a3,a2,a1,a0);
#define MCFG_DECO146_SET_INTERFACE_SCRAMBLE_REVERSE \
deco_146_base_device::set_interface_scramble(*device, 0,1,2,3,4,5,6,7,8,9);
#define MCFG_DECO146_SET_INTERFACE_SCRAMBLE_INTERLEAVE \
deco_146_base_device::set_interface_scramble(*device, 4,5,3,6,2,7,1,8,0,9 );
#define MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR \
deco_146_base_device::set_use_magic_read_address_xor(*device, 1 );
/* Data East 146 protection chip */
class deco146_device : public device_t
class deco_146_base_device : public device_t
{
public:
deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
//deco_146_base_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
deco_146_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
void write_data(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask, UINT8 &csflags);
UINT16 read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags, int extra_read_address_xor);
UINT16 read_data(UINT16 address, UINT16 mem_mask, UINT8 &csflags);
static void set_port_a_cb(device_t &device,deco146_port_read_cb port_cb);
static void set_port_b_cb(device_t &device,deco146_port_read_cb port_cb);
static void set_port_c_cb(device_t &device,deco146_port_read_cb port_cb);
static void set_soundlatch_cb(device_t &device,deco146_port_write_cb port_cb);
static void set_interface_scramble(device_t &device,UINT8 a9, UINT8 a8, UINT8 a7, UINT8 a6, UINT8 a5, UINT8 a4, UINT8 a3,UINT8 a2,UINT8 a1,UINT8 a0);
static void set_use_magic_read_address_xor(device_t &device, int use_xor);
// legacy stuff
DECLARE_READ32_MEMBER(dragngun_prot_r);
@ -40,10 +63,34 @@ public:
deco146_port_read_cb m_port_a_r;
deco146_port_read_cb m_port_b_r;
deco146_port_read_cb m_port_c_r;
deco146_port_write_cb m_soundlatch_w;
UINT16 port_a_default(int unused);
UINT16 port_b_default(int unused);
UINT16 port_c_default(int unused);
void soundlatch_default(address_space &space, UINT16 data, UINT16 mem_mask);
UINT8 m_bankswitch_swap_read_address;
UINT16 m_magic_read_address_xor;
int m_magic_read_address_xor_enabled;
UINT8 m_xor_port;
UINT8 m_mask_port;
UINT8 m_soundlatch_port;
UINT8 m_external_addrswap[10];
virtual UINT16 read_data_getloc(UINT16 address, int& location) = 0;
// for older handlers
#define DECO146__PORT(p) (prot_ram[p/2])
protected:
@ -51,15 +98,14 @@ protected:
virtual void device_start();
virtual void device_reset();
UINT16 read_protport(UINT16 address, UINT16 mem_mask, int extra_read_address_xor);
void write_protport(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask);
UINT16 read_protport(UINT16 address, UINT16 mem_mask);
virtual void write_protport(address_space &space, UINT16 address, UINT16 data, UINT16 mem_mask);
UINT16 m_rambank0[0x80];
UINT16 m_rambank1[0x80];
UINT16* m_current_rambank;
void soundlatch_write_callback(address_space &space, UINT16 data, UINT16 mem_mask);
UINT16 m_nand;
UINT16 m_xor;
@ -77,14 +123,21 @@ private:
};
extern const device_type DECO146PROT;
extern const device_type DECO146BASE;
class deco146_device : public deco_146_base_device
{
public:
deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual UINT16 read_data_getloc(UINT16 address, int& location);
};
extern const device_type DECO146PROT;
#define MCFG_DECO146_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, DECO146PROT, 0)
// old
void decoprot146_reset(running_machine &machine);