Merge pull request #4889 from cam900/deco146_a

deco146.cpp : Updates
This commit is contained in:
R. Belmont 2019-04-14 15:45:34 -04:00 committed by GitHub
commit 4297e32d5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 93 additions and 109 deletions

View file

@ -103,7 +103,7 @@ READ16_MEMBER( boogwing_state::boogwing_protection_region_0_104_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco104->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco104->read_data( deco146_addr, cs );
return data;
}

View file

@ -68,7 +68,7 @@ READ16_MEMBER( cninja_state::cninja_protection_region_0_104_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_ioprot->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_ioprot->read_data( deco146_addr, cs );
return data;
}
@ -150,7 +150,7 @@ READ16_MEMBER( cninja_state::edrandy_protection_region_8_146_r )
int real_address = 0x1a0000 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_ioprot->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_ioprot->read_data( deco146_addr, cs );
return data;
}
@ -169,7 +169,7 @@ READ16_MEMBER( cninja_state::edrandy_protection_region_6_146_r )
int real_address = 0x198000 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_ioprot->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_ioprot->read_data( deco146_addr, cs );
// if ((realdat & mem_mask) != (data & mem_mask))
@ -259,7 +259,7 @@ READ16_MEMBER( cninja_state::mutantf_protection_region_0_146_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_ioprot->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_ioprot->read_data( deco146_addr, cs );
return data;
}

View file

@ -158,7 +158,7 @@ READ16_MEMBER( dblewing_state::wf_protection_region_0_104_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco104->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco104->read_data( deco146_addr, cs );
return data;
}

View file

@ -700,7 +700,7 @@ READ16_MEMBER( deco32_state::ioprot_r )
offs_t deco146_addr = bitswap<32>(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_t cs = 0;
return m_ioprot->read_data( deco146_addr, mem_mask, cs );
return m_ioprot->read_data( deco146_addr, cs );
}
WRITE16_MEMBER( deco32_state::ioprot_w )

View file

@ -279,7 +279,7 @@ READ16_MEMBER( deco_mlc_state::sh96_protection_region_0_146_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco146->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco146->read_data( deco146_addr, cs );
return data;
}

View file

@ -39,7 +39,7 @@ READ16_MEMBER( dietgo_state::dietgo_protection_region_0_104_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco104->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco104->read_data( deco146_addr, cs );
return data;
}

View file

@ -102,7 +102,7 @@ READ16_MEMBER( dreambal_state::dreambal_protection_region_0_104_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco104->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco104->read_data( deco146_addr, cs );
return data;
}

View file

@ -110,7 +110,7 @@ READ16_MEMBER( funkyjet_state::funkyjet_protection_region_0_146_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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 */ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) & 0x7fff;
uint8_t cs = 0;
uint16_t data = m_deco146->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco146->read_data( deco146_addr, 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);

View file

@ -48,7 +48,7 @@ READ16_MEMBER( lemmings_state::lem_protection_region_0_146_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco146->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco146->read_data( deco146_addr, cs );
return data;
}

View file

@ -80,7 +80,7 @@ READ16_MEMBER( pktgaldx_state::pktgaldx_protection_region_f_104_r )
{
int real_address = 0 + (offset *2);
uint8_t cs = 0;
uint16_t data = m_deco104->read_data( real_address&0x7fff, mem_mask, cs );
uint16_t data = m_deco104->read_data( real_address&0x7fff, cs );
return data;
}

View file

@ -146,7 +146,7 @@ READ16_MEMBER( rohga_state::ioprot_r )
int real_address = 0 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_ioprot->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_ioprot->read_data( deco146_addr, cs );
return data;
}

View file

@ -125,7 +125,7 @@ READ16_MEMBER( sshangha_state::sshangha_protection_region_d_146_r )
int real_address = 0x3f4000 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco146->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco146->read_data( deco146_addr, cs );
return data;
}
@ -142,7 +142,7 @@ READ16_MEMBER( sshangha_state::sshangha_protection_region_8_146_r )
int real_address = 0x3e0000 + (offset *2);
int deco146_addr = bitswap<32>(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_t cs = 0;
uint16_t data = m_deco146->read_data( deco146_addr, mem_mask, cs );
uint16_t data = m_deco146->read_data( deco146_addr, cs );
return data;
}

View file

@ -3,7 +3,7 @@
/****************************************************************************
Data East 104 based protection/IO chips
(a variation on the Deco 146 protection, see deco146.c for notes)
(a variation on the Deco 146 protection, see deco146.cpp for notes)
Emulation by David Haywood
based on findings by Charles MacDonald
@ -1048,12 +1048,10 @@ static deco146port_xx const port104_table[] = {
};
DEFINE_DEVICE_TYPE(DECO104PROT, deco104_device, "deco104", "DECO 104 Protection")
deco104_device::deco104_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
deco104_device::deco104_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: deco_146_base_device(mconfig, DECO104PROT, tag, owner, clock)
{
m_bankswitch_swap_read_address = 0x66;
@ -1067,8 +1065,6 @@ deco104_device::deco104_device(const machine_config &mconfig, const char *tag, d
}
void deco104_device::device_start()
{
deco_146_base_device::device_start();

View file

@ -13,7 +13,7 @@
class deco104_device : public deco_146_base_device
{
public:
deco104_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
deco104_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_start() override;

View file

@ -1119,14 +1119,14 @@ static deco146port_xx const port_table[] = {
/* 0x7fe */ { 0x04c, { NIB1__, NIB2__, NIB0__, NIB3__ }, 0, 1 }
};
inline uint16_t reorder(uint16_t input, uint8_t const *weights)
inline u16 reorder(u16 input, u8 const *weights)
{
uint16_t temp = 0;
for(int i = 0; i < 16; i++)
u16 temp = 0;
for (int i = 0; i < 16; i++)
{
if(input & (1 << i)) // if input bit is set
if (input & (1 << i)) // if input bit is set
{
if(weights[i] != 0xFF) // and weight exists for output bit
if (weights[i] != 0xFF) // and weight exists for output bit
{
temp |= 1 << weights[i]; // set that bit
}
@ -1139,9 +1139,9 @@ inline uint16_t reorder(uint16_t input, uint8_t const *weights)
/* there are probably less dumb ways of doing the CS logic, it could be hooked up
more like the system16 mapper chips */
void deco_146_base_device::write_data(uint16_t address, uint16_t data, uint16_t mem_mask, uint8_t &csflags)
void deco_146_base_device::write_data(u16 address, u16 data, u16 mem_mask, u8 &csflags)
{
address = bitswap<16>(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;
address = bitswap<16>(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;
@ -1151,9 +1151,9 @@ void deco_146_base_device::write_data(uint16_t address, uint16_t data, uint16_t
int real_address = address & 0xf;
logerror("write to config regs %04x %04x %04x\n", real_address, data, mem_mask);
if ((real_address>=0x2) && (real_address<=0x0c))
if ((real_address >= 0x2) && (real_address <= 0x0c))
{
region_selects[(real_address-2)/2] = data &0xf;
region_selects[(real_address - 2) / 2] = data & 0xf;
return;
}
else
@ -1164,16 +1164,16 @@ void deco_146_base_device::write_data(uint16_t address, uint16_t data, uint16_t
return; // or fall through?
}
for (int i=0;i<6;i++)
for (int i = 0; i < 6; i++)
{
int cs = region_selects[i];
if (cs==upper_addr_bits)
if (cs == upper_addr_bits)
{
int real_address = address & 0x7ff;
csflags |= (1 << i);
if (i==0) // the first cs is our internal protection area
if (i == 0) // the first cs is our internal protection area
{
// logerror("write matches cs table (protection) %01x %04x %04x %04x\n", i, real_address, data, mem_mask);
write_protport(real_address, data, mem_mask);
@ -1185,17 +1185,17 @@ void deco_146_base_device::write_data(uint16_t address, uint16_t data, uint16_t
}
}
if (csflags==0)
if (csflags == 0)
{
logerror("write not in cs table\n");
}
}
uint16_t deco_146_base_device::read_protport(uint16_t address, uint16_t mem_mask)
u16 deco_146_base_device::read_protport(u16 address)
{
// 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))
if (((address == m_latchaddr) && (m_latchflag == 1)) && (!machine().side_effects_disabled()))
{
logerror("returning latched data %04x\n", m_latchdata);
m_latchflag = 0;
@ -1207,19 +1207,15 @@ uint16_t deco_146_base_device::read_protport(uint16_t address, uint16_t mem_mask
if (m_magic_read_address_xor_enabled) address ^= m_magic_read_address_xor;
int location = 0;
uint16_t realret = read_data_getloc(address, location);
u16 realret = read_data_getloc(address, location);
if (location == m_bankswitch_swap_read_address) // this has a special meaning
if ((location == m_bankswitch_swap_read_address) && (!machine().side_effects_disabled())) // this has a special meaning
{
// logerror("(bankswitch) %04x %04x\n", address, mem_mask);
// logerror("(bankswitch) %04x %04x\n", address);
if (m_current_rambank==0)
m_current_rambank = 1;
else
m_current_rambank = 0;
m_current_rambank ^= 1;
}
return realret;
}
@ -1229,75 +1225,73 @@ TIMER_CALLBACK_MEMBER(deco_146_base_device::write_soundlatch)
m_soundlatch_irq_cb(ASSERT_LINE);
}
void deco_146_base_device::write_protport(uint16_t address, uint16_t data, uint16_t mem_mask)
void deco_146_base_device::write_protport(u16 address, u16 data, u16 mem_mask)
{
m_latchaddr = address;
m_latchdata = data;
m_latchflag = 1;
if ((address&0xff) == m_xor_port)
if ((address & 0xff) == m_xor_port)
{
logerror("LOAD XOR REGISTER %04x %04x\n", data, mem_mask);
COMBINE_DATA(&m_xor);
}
else if ((address&0xff) == m_mask_port)
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) == m_soundlatch_port)
else if ((address & 0xff) == m_soundlatch_port)
{
logerror("LOAD SOUND LATCH: %04x\n", data);
machine().scheduler().synchronize(timer_expired_delegate(FUNC(deco_146_base_device::write_soundlatch), this), data & 0xff);
}
// always store
if (m_current_rambank==0)
COMBINE_DATA(&m_rambank0[(address&0xff)>>1]);
else
COMBINE_DATA(&m_rambank1[(address&0xff)>>1]);
COMBINE_DATA(&m_rambank[m_current_rambank][(address & 0xff) >> 1]);
}
uint16_t deco_146_base_device::read_data(uint16_t address, uint16_t mem_mask, uint8_t &csflags)
u16 deco_146_base_device::read_data(u16 address, u8 &csflags)
{
address = bitswap<16>(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;
address = bitswap<16>(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_t retdata = 0;
u16 retdata = 0;
csflags = 0;
int upper_addr_bits = (address & 0x7800) >> 11;
if (upper_addr_bits == 0x8) // configuration registers are hardcoded to this area
{
int real_address = address & 0xf;
logerror("read config regs? %04x %04x\n", real_address, mem_mask);
if (!machine().side_effects_disabled())
logerror("read config regs? %04x\n", real_address);
return 0x0000;
}
// what gets priority?
for (int i=0;i<6;i++)
for (int i = 0; i < 6; i++)
{
int cs = region_selects[i];
if (cs==upper_addr_bits)
if (cs == upper_addr_bits)
{
int real_address = address & 0x7ff;
csflags |= (1 << i);
if (i==0) // the first cs is our internal protection area
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);
//logerror("read matches cs table (protection) %01x %04x\n", i, real_address);
return read_protport(real_address);
}
else
else if (!machine().side_effects_disabled())
{
logerror("read matches cs table (external connection) %01x %04x %04x\n", i, real_address, mem_mask);
logerror("read matches cs table (external connection) %01x %04x\n", i, real_address);
}
}
}
if (csflags==0)
if ((csflags == 0) && (!machine().side_effects_disabled()))
{
logerror("read not in cs table\n");
}
@ -1311,7 +1305,7 @@ u8 deco_146_base_device::soundlatch_r()
return m_soundlatch;
}
deco_146_base_device::deco_146_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
deco_146_base_device::deco_146_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock),
m_port_a_r(*this),
m_port_b_r(*this),
@ -1332,11 +1326,12 @@ deco_146_base_device::deco_146_base_device(const machine_config &mconfig, device
void deco_146_base_device::device_start()
{
for (int i=0;i<0x80;i++)
for (int bank = 0; bank < 2; bank++)
{
m_rambank[bank] = std::make_unique<u16[]>(0x80);
// the mutant fighter old sim assumes 0x0000
m_rambank0[i] = 0xffff;
m_rambank1[i] = 0xffff;
std::fill_n(&m_rambank[bank][0], 0x80, 0xffff);
save_pointer(NAME(m_rambank[bank]), 0x80, bank);
}
// bind our handler
@ -1348,8 +1343,6 @@ void deco_146_base_device::device_start()
save_item(NAME(m_xor));
save_item(NAME(m_nand));
save_item(NAME(m_rambank0));
save_item(NAME(m_rambank1));
save_item(NAME(m_current_rambank));
save_item(NAME(region_selects));
@ -1384,11 +1377,11 @@ void deco_146_base_device::device_reset()
}
uint16_t deco_146_base_device::read_data_getloc(uint16_t address, int& location)
u16 deco_146_base_device::read_data_getloc(u16 address, int& location)
{
uint16_t retdata = 0;
u16 retdata = 0;
location = m_lookup_table[address>>1].write_offset;
location = m_lookup_table[address >> 1].write_offset;
if (location==INPUT_PORT_A)
{
@ -1404,16 +1397,13 @@ uint16_t deco_146_base_device::read_data_getloc(uint16_t address, int& location)
}
else
{
if (m_current_rambank==0)
retdata = m_rambank0[location>>1];
else
retdata = m_rambank1[location>>1];
retdata = m_rambank[m_current_rambank][location >> 1];
}
uint16_t realret = reorder(retdata, &m_lookup_table[address>>1].mapping[0] );
u16 realret = reorder(retdata, &m_lookup_table[address >> 1].mapping[0] );
if (m_lookup_table[address>>1].use_xor) realret ^= m_xor;
if (m_lookup_table[address>>1].use_nand) realret = (realret & ~m_nand);
if (m_lookup_table[address >> 1].use_xor) realret ^= m_xor;
if (m_lookup_table[address >> 1].use_nand) realret = (realret & ~m_nand);
return realret;
}
@ -1422,7 +1412,7 @@ uint16_t deco_146_base_device::read_data_getloc(uint16_t address, int& location)
DEFINE_DEVICE_TYPE(DECO146PROT, deco146_device, "deco146", "DECO 146 Protection")
deco146_device::deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
deco146_device::deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: deco_146_base_device(mconfig, DECO146PROT, tag, owner, clock)
{
m_bankswitch_swap_read_address = 0x78;

View file

@ -38,27 +38,26 @@
struct deco146port_xx
{
int write_offset;
uint8_t mapping[16];
u8 mapping[16];
int use_xor;
int use_nand;
};
/* Data East 146 protection chip */
class deco_146_base_device : public device_t
{
public:
void write_data(uint16_t address, uint16_t data, uint16_t mem_mask, uint8_t &csflags);
uint16_t read_data(uint16_t address, uint16_t mem_mask, uint8_t &csflags);
void write_data(u16 address, u16 data, u16 mem_mask, u8 &csflags);
u16 read_data(u16 address, u8 &csflags);
auto port_a_cb() { return m_port_a_r.bind(); }
auto port_b_cb() { return m_port_b_r.bind(); }
auto port_c_cb() { return m_port_c_r.bind(); }
// there are some standard ways the chip gets hooked up, so have them here ready to use
void set_interface_scramble(uint8_t a9, uint8_t a8, uint8_t a7, uint8_t a6, uint8_t a5, uint8_t a4, uint8_t a3,uint8_t a2,uint8_t a1,uint8_t a0)
void set_interface_scramble(u8 a9, u8 a8, u8 a7, u8 a6, u8 a5, u8 a4, u8 a3,u8 a2,u8 a1,u8 a0)
{
m_external_addrswap[9] = a9;
m_external_addrswap[8] = a8;
@ -83,54 +82,53 @@ public:
devcb_read16 m_port_b_r;
devcb_read16 m_port_c_r;
uint8_t m_bankswitch_swap_read_address;
uint16_t m_magic_read_address_xor;
u8 m_bankswitch_swap_read_address;
u16 m_magic_read_address_xor;
bool m_magic_read_address_xor_enabled;
uint8_t m_xor_port;
uint8_t m_mask_port;
uint8_t m_soundlatch_port;
u8 m_xor_port;
u8 m_mask_port;
u8 m_soundlatch_port;
uint8_t m_external_addrswap[10];
u8 m_external_addrswap[10];
deco146port_xx const *m_lookup_table;
protected:
deco_146_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
deco_146_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_start() override;
virtual void device_reset() override;
uint16_t read_protport(uint16_t address, uint16_t mem_mask);
virtual void write_protport(uint16_t address, uint16_t data, uint16_t mem_mask);
virtual uint16_t read_data_getloc(uint16_t address, int& location);
u16 read_protport(u16 address);
virtual void write_protport(u16 address, u16 data, u16 mem_mask);
virtual u16 read_data_getloc(u16 address, int& location);
uint16_t m_rambank0[0x80];
uint16_t m_rambank1[0x80];
std::unique_ptr<u16[]> m_rambank[2];
int m_current_rambank;
uint16_t m_nand;
uint16_t m_xor;
u16 m_nand;
u16 m_xor;
uint16_t m_latchaddr;
uint16_t m_latchdata;
u16 m_latchaddr;
u16 m_latchdata;
uint8_t m_configregion; // which value of upper 4 address lines accesses the config region
u8 m_configregion; // which value of upper 4 address lines accesses the config region
int m_latchflag;
private:
TIMER_CALLBACK_MEMBER(write_soundlatch);
uint8_t region_selects[6];
u8 region_selects[6];
uint8_t m_soundlatch;
u8 m_soundlatch;
devcb_write_line m_soundlatch_irq_cb;
};
class deco146_device : public deco_146_base_device
{
public:
deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
DECLARE_DEVICE_TYPE(DECO146PROT, deco146_device)