From 948ee3f714b03dfdf697fff0bf5b4788b390bb7e Mon Sep 17 00:00:00 2001 From: mamehaze Date: Wed, 28 Jan 2015 01:48:37 +0000 Subject: [PATCH] refactor decathlete protection a bit, hook up 'doa' to the table uploads for it too (nw) --- src/mame/machine/315-5838_317-0229_comp.c | 431 ++++++++++------------ src/mame/machine/315-5838_317-0229_comp.h | 47 ++- 2 files changed, 228 insertions(+), 250 deletions(-) diff --git a/src/mame/machine/315-5838_317-0229_comp.c b/src/mame/machine/315-5838_317-0229_comp.c index 007bce685cb..c35666a7e33 100644 --- a/src/mame/machine/315-5838_317-0229_comp.c +++ b/src/mame/machine/315-5838_317-0229_comp.c @@ -10,7 +10,8 @@ dumb security check, decompressing a single string. Each channel appears to be connected to a different set of ROMs, however there is - defintiely only 315-5838 single chip. + defintiely only a single 315-5838 chip. (could the different channels actually just + be mirror addresses, with part of the address determining the ROMs to use?) Dead of Alive only uses a single channel, and has the source data in RAM, not ROM. This is similar to how some 5881 games were set up, with the ST-V versions decrypting @@ -18,7 +19,7 @@ Looking at the values read I don't think there is any address based encryption, for example many blocks where you'd expect a zero fill start with repeating patterns - of 8f708f70 (different lengths) which would appear to relate to compressed 0x00 data + of 8f708f70 (different lengths) channel would appear to relate to compressed 0x00 data read addr 0071253c, blah_r 8f708f70 - read count count 00000004 read addr 00712540, blah_r 8f708f70 - read count count 00000008 @@ -46,21 +47,25 @@ sega_315_5838_comp_device::sega_315_5838_comp_device(const machine_config &mconf void sega_315_5838_comp_device::device_start() { - m_decathlt_lastcount = 0; - m_decathlt_prot_uploadmode = 0; - m_decathlt_prot_uploadoffset = 0; + for (int i = 0; i < 2; i++) + { + m_channel[i].m_decathlt_lastcount = 0; + m_channel[i].m_decathlt_prot_uploadmode = 0; + m_channel[i].m_decathlt_prot_uploadoffset = 0; + m_channel[i].m_read_ch.bind_relative_to(*owner()); - m_read_ch1.bind_relative_to(*owner()); - m_read_ch2.bind_relative_to(*owner()); + } } void sega_315_5838_comp_device::device_reset() { - memset(m_decathlt_protregs, 0, sizeof(m_decathlt_protregs)); - m_decathlt_lastcount = 0; - m_decathlt_prot_uploadmode = 0; - m_decathlt_prot_uploadoffset = 0; - m_decathlt_part = 1; + for (int i = 0; i < 2; i++) + { + m_channel[i].m_srcoffset = 0; + m_channel[i].m_decathlt_lastcount = 0; + m_channel[i].m_decathlt_prot_uploadmode = 0; + m_channel[i].m_decathlt_prot_uploadoffset = 0; + } m_protstate = 0; } @@ -77,281 +82,235 @@ FILE* tempfile; #endif -READ32_MEMBER(sega_315_5838_comp_device::decathlt_prot_r) +READ32_MEMBER(sega_315_5838_comp_device::decathlt_prot1_r) { - return genericdecathlt_prot_r(offset, mem_mask, 0); + return genericdecathlt_prot_r(mem_mask, 0); } -READ32_MEMBER(sega_315_5838_comp_device::decathlt_prot_ch2_r) +READ32_MEMBER(sega_315_5838_comp_device::decathlt_prot2_r) { - return genericdecathlt_prot_r(offset, mem_mask, 1); + return genericdecathlt_prot_r(mem_mask, 1); } -UINT32 sega_315_5838_comp_device::genericdecathlt_prot_r(UINT32 offset, UINT32 mem_mask, int which) +UINT32 sega_315_5838_comp_device::genericdecathlt_prot_r(UINT32 mem_mask, int channel) { - // UINT32 *fake0 = (UINT32*)memregion( ":fake0" )->base(); +// UINT32 retvalue = 0xffff; - if (offset==2) + switch (m_channel[channel].m_srcoffset) { -// UINT32 retvalue = 0xffff; + default: - switch (m_decathlt_protregs[0]) - { - default: + m_channel[channel].m_decathlt_lastcount++; - m_decathlt_lastcount++; + UINT32 tempdata = 0; + tempdata |= m_channel[channel].m_read_ch(m_channel[channel].m_srcoffset) << 0; + m_channel[channel].m_srcoffset++; + tempdata |= m_channel[channel].m_read_ch(m_channel[channel].m_srcoffset) << 16; + m_channel[channel].m_srcoffset++; - UINT32 tempdata = 0; - if (which == 0) - { - tempdata |= m_read_ch1(m_decathlt_protregs[0]) << 16; - m_decathlt_protregs[0]++; - tempdata |= m_read_ch1(m_decathlt_protregs[0]) << 0; - m_decathlt_protregs[0]++; - } - else - { - tempdata |= m_read_ch2(m_decathlt_protregs[0]) << 16; - m_decathlt_protregs[0]++; - tempdata |= m_read_ch2(m_decathlt_protregs[0]) << 0; - m_decathlt_protregs[0]++; - } + #ifdef DEBUG_DATA_DUMP + //printf("read addr %08x, blah_r %08x - read count count %08x\n", m_channel[channel].m_srcoffset*2, tempdata, m_channel[channel].m_decathlt_lastcount*4); + fwrite(&tempdata, 1, 4, tempfile); + #else + logerror("read addr %08x, blah_r %08x - read count count %08x\n", m_channel[channel].m_srcoffset*2, tempdata, m_channel[channel].m_decathlt_lastcount*4); + #endif - #ifdef DEBUG_DATA_DUMP - //printf("read addr %08x, blah_r %08x - read count count %08x\n", m_decathlt_protregs[0]*2, tempdata, m_decathlt_lastcount*4); - fwrite(&tempdata, 1, 4, tempfile); - #else - logerror("read addr %08x, blah_r %08x - read count count %08x\n", m_decathlt_protregs[0]*2, tempdata, m_decathlt_lastcount*4); - #endif - - return tempdata; + return tempdata; #if 0 - case 0x03228e4: - if (fake0) retvalue = fake0[(((0x20080/4)+m_decathlt_lastcount))]; - m_decathlt_lastcount++; - return retvalue; + case 0x03228e4: + if (fake0) retvalue = fake0[(((0x20080/4)+m_channel[channel].m_decathlt_lastcount))]; + m_channel[channel].m_decathlt_lastcount++; + return retvalue; - case 0x00a9f3a: - if (fake0) retvalue = fake0[(((0x00000/4)+m_decathlt_lastcount))]; - m_decathlt_lastcount++; - return retvalue; + case 0x00a9f3a: + if (fake0) retvalue = fake0[(((0x00000/4)+m_channel[channel].m_decathlt_lastcount))]; + m_channel[channel].m_decathlt_lastcount++; + return retvalue; - case 0x0213ab4: - if (fake0) retvalue = fake0[(((0x40000/4)+m_decathlt_lastcount))]; - m_decathlt_lastcount++; - return retvalue; + case 0x0213ab4: + if (fake0) retvalue = fake0[(((0x40000/4)+m_channel[channel].m_decathlt_lastcount))]; + m_channel[channel].m_decathlt_lastcount++; + return retvalue; - case 0x01efaf0: - if (fake0) retvalue = fake0[(((0x60000/4)+m_decathlt_lastcount))]; - m_decathlt_lastcount++; - return retvalue; + case 0x01efaf0: + if (fake0) retvalue = fake0[(((0x60000/4)+m_channel[channel].m_decathlt_lastcount))]; + m_channel[channel].m_decathlt_lastcount++; + return retvalue; - case 0x033f16c: - case 0x038929c: + case 0x033f16c: + case 0x038929c: - case 0x00de05a: - case 0x0334258: - case 0x019fb82: - case 0x033dbf6: - case 0x0011ac6: - case 0x00060dc: - case 0x0000002: - case 0x0008c90: - case 0x035cdc8: - case 0x0327960: - case 0x0329b8c: - case 0x00d6e92: - case 0x000081e: - case 0x00035d6: - case 0x00089a6: - case 0x03315f4: - case 0x0023fe0: - case 0x001e290: - case 0x0026e86: - case 0x0012494: - case 0x001b35a: - case 0x0018424: + case 0x00de05a: + case 0x0334258: + case 0x019fb82: + case 0x033dbf6: + case 0x0011ac6: + case 0x00060dc: + case 0x0000002: + case 0x0008c90: + case 0x035cdc8: + case 0x0327960: + case 0x0329b8c: + case 0x00d6e92: + case 0x000081e: + case 0x00035d6: + case 0x00089a6: + case 0x03315f4: + case 0x0023fe0: + case 0x001e290: + case 0x0026e86: + case 0x0012494: + case 0x001b35a: + case 0x0018424: - return retvalue; + return retvalue; #endif + } + + return 0xffffffff; +} + +void sega_315_5838_comp_device::set_prot_addr(UINT32 data, UINT32 mem_mask, int channel) +{ +// printf("set_prot_addr\n"); + COMBINE_DATA(&m_channel[channel].m_srcoffset); + + //if (m_decathlt_part==0) logerror("%d, last read count was %06x\n",channel, m_channel[channel].m_decathlt_lastcount*4); + m_channel[channel].m_decathlt_lastcount = 0; + + if (mem_mask == 0x0000ffff) + { + printf("set source address to %08x (channel %d)\n", m_channel[channel].m_srcoffset, channel); + } + + +#ifdef DEBUG_DATA_DUMP + if (mem_mask == 0x0000ffff) + { + if (tempfile) + fclose(tempfile); + + char filename[256]; + sprintf(filename, "%d_compressed_%08x", channel, m_channel[channel].m_srcoffset * 2); + tempfile = fopen(filename, "w+b"); + + // the table and dictionary are uploaded repeatedly, usually before groups of data transfers but + // it's always the same tables (one pair for each channel) + { + FILE* fp; + sprintf(filename, "%d_compressed_table1", channel); + fp = fopen(filename, "w+b"); + fwrite(&m_channel[channel].m_decathlt_prottable1, 24, 2, fp); + fclose(fp); } + { + FILE* fp; + sprintf(filename, "%d_compressed_dictionary", channel); + fp = fopen(filename, "w+b"); + fwrite(&m_channel[channel].m_decathlt_dictionary, 128, 2, fp); + fclose(fp); + } + } +#endif +} + +void sega_315_5838_comp_device::set_upload_mode(UINT16 data, int channel) +{ + if ((data == 0x8000) || (data == 0x0000)) + { + // logerror("changed to upload mode 1\n"); + m_channel[channel].m_decathlt_prot_uploadmode = 1; + m_channel[channel].m_decathlt_prot_uploadoffset = 0; + } + else if ((data == 0x8080) || (data == 0x0080)) + { + m_channel[channel].m_decathlt_prot_uploadmode = 2; + m_channel[channel].m_decathlt_prot_uploadoffset = 0; } else { - logerror("%06x Decathlete prot R offset %04x mask %08x regs %08x, %08x, %08x, %08x\n", safe_pc(), offset, mem_mask, m_decathlt_protregs[0], m_decathlt_protregs[1], m_decathlt_protregs[2], m_decathlt_protregs[3]); + fatalerror("unknown upload mode\n"); } - - return m_decathlt_protregs[offset]; } - -void sega_315_5838_comp_device::write_prot_data(UINT32 data, UINT32 mem_mask, int offset, int which) +void sega_315_5838_comp_device::upload_table_data(UINT16 data, int channel) { - - printf("write_prot_data %08x %08x %08x\n", offset, data, mem_mask); - - m_decathlt_protregs[offset] = (data&mem_mask)|(m_decathlt_protregs[offset]&~mem_mask); -// m_decathlt_protregs[0] = 0x0c00000/4; - - if (offset==0) // seems to set a source address + if (m_channel[channel].m_decathlt_prot_uploadmode == 1) { - m_decathlt_part ^=1; - - //if (m_decathlt_part==0) logerror("%d, last read count was %06x\n",which, m_decathlt_lastcount*4); - m_decathlt_lastcount = 0; - if (m_decathlt_part==1) logerror("%d Decathlete prot W offset %04x data %08x, %08x, >>> regs %08x <<<<, %08x, %08x, %08x\n",which, offset, data, m_decathlt_protregs[0], m_decathlt_protregs[0]*4, m_decathlt_protregs[1], m_decathlt_protregs[2], m_decathlt_protregs[3]); - -#ifdef DEBUG_DATA_DUMP - if (mem_mask == 0x0000ffff) + if (m_channel[channel].m_decathlt_prot_uploadoffset >= 24) { - if (tempfile) - fclose(tempfile); - - char filename[256]; - sprintf(filename, "%d_compressed_%08x", which, m_decathlt_protregs[0] ); - tempfile = fopen(filename, "w+b"); + fatalerror("upload mode 1 error, too big\n"); + return; } -#endif + //logerror("uploading table 1 %04x %04x\n",m_channel[channel].m_decathlt_prot_uploadoffset, data&0xffff); + m_channel[channel].m_decathlt_prottable1[m_channel[channel].m_decathlt_prot_uploadoffset] = data & 0xffff; + m_channel[channel].m_decathlt_prot_uploadoffset++; + printf("unk table 1 %04x (channel %d)\n", data & 0xffff, channel); } - - if (offset==1) // uploads 2 tables... + else if (m_channel[channel].m_decathlt_prot_uploadmode == 2) { - if (mem_mask==0xffff0000) + if (m_channel[channel].m_decathlt_prot_uploadoffset >= 128) { - if (data == 0x80000000) - { - // logerror("changed to upload mode 1\n"); - m_decathlt_prot_uploadmode = 1; - m_decathlt_prot_uploadoffset = 0; - } - else if (data == 0x80800000) - { - // logerror("changed to upload mode 2\n"); - m_decathlt_prot_uploadmode = 2; - m_decathlt_prot_uploadoffset = 0; - } - else - { - // logerror("unknown upload mode\n"); - m_decathlt_prot_uploadmode = 2; - m_decathlt_prot_uploadoffset = 0; - } - -// logerror("ARGH! %08x %08x\n",mem_mask,data); + fatalerror("upload mode 2 error, too big\n"); + return; } - else if (mem_mask==0x0000ffff) - { - if (m_decathlt_prot_uploadmode==1) - { - if (m_decathlt_prot_uploadoffset>=24) - { - // logerror("upload mode 1 error, too big\n"); - return; - } - //logerror("uploading table 1 %04x %04x\n",m_decathlt_prot_uploadoffset, data&0xffff); - m_decathlt_prottable1[m_decathlt_prot_uploadoffset]=data&0xffff; - m_decathlt_prot_uploadoffset++; - - printf("table 1 %04x\n", data & 0xffff); - - { - /* 0x18 (24) values in this table, rom data is 0x1800000 long, maybe it has - something to do with that? or 24-address b its? - - uploaded values appear to be 12-bit, some are repeated - */ - - { - FILE* fp; - if (which==1) fp = fopen("table1x","wb"); - else fp = fopen("table1","wb"); - - { - fwrite(&m_decathlt_prottable1,24,2,fp); - } - fclose(fp); - } - } - - } - else if (m_decathlt_prot_uploadmode==2) - { - if (m_decathlt_prot_uploadoffset>=128) - { - //logerror("upload mode 2 error, too big\n"); - return; - } - - //logerror("uploading table 2 %04x %04x\n",m_decathlt_prot_uploadoffset, data&0xffff); - m_decathlt_prottable2[m_decathlt_prot_uploadoffset]=data&0xffff; - m_decathlt_prot_uploadoffset++; - - printf("dictionary %04x\n", data & 0xffff); - - - { - /* the table uploaded here is a 256 byte table with 256 unique values, remaps something? */ - - { - FILE* fp; - if (which==1) fp = fopen("table2x","wb"); - else fp = fopen("table2","wb"); - - { - fwrite(&m_decathlt_prottable2,128,2,fp); - } - fclose(fp); - } - } - } - else - { - // logerror("unknown upload mode!\n"); - } - } + //logerror("uploading table 2 %04x %04x\n",m_channel[channel].m_decathlt_prot_uploadoffset, data&0xffff); + m_channel[channel].m_decathlt_dictionary[m_channel[channel].m_decathlt_prot_uploadoffset] = data & 0xffff; + m_channel[channel].m_decathlt_prot_uploadoffset++; + printf("dictionary %04x (channel %d)\n", data & 0xffff, channel); } - - if (offset>1) - { - // logerror("higher offset write\n"); - } - } -WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot1_w ) +void sega_315_5838_comp_device::write_prot_data(UINT32 data, UINT32 mem_mask, int channel, int rev_words) { - write_prot_data(data,mem_mask, offset, 0); - + if (mem_mask==0xffff0000) + { + if (rev_words==0) set_upload_mode(data >> 16, channel); + else upload_table_data(data >>16, channel); + } + else if (mem_mask == 0x0000ffff) + { + if (rev_words==0) upload_table_data(data & 0xffff, channel); + else set_upload_mode(data & 0xffff, channel); + } + else + { + fatalerror("write_prot_data invalid mem_mask\b"); + } } -WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot2_w ) -{ - write_prot_data(data,mem_mask, offset, 1); -} +WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot1_w_doa ) { write_prot_data(data, mem_mask, 0, 1); } +WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot1_w) { write_prot_data(data, mem_mask, 0, 0); } +WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot2_w) { write_prot_data(data, mem_mask, 1, 0); } + +WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot1_srcaddr_w ) { set_prot_addr(data, mem_mask, 0); } +WRITE32_MEMBER( sega_315_5838_comp_device::decathlt_prot2_srcaddr_w) { set_prot_addr(data, mem_mask, 1); } + void sega_315_5838_comp_device::install_decathlt_protection() { - /* It uploads 2 tables here, then performs what looks like a number of transfers, setting - a source address of some kind (scrambled?) and then making many reads from a single address */ - //todo, install these in the driver, they differ between games cpu_device* cpu = (cpu_device*)machine().device(":maincpu"); + cpu->space(AS_PROGRAM).install_write_handler(0x37FFFF0, 0x37FFFF3, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_srcaddr_w), this)); // set compressed data source address + cpu->space(AS_PROGRAM).install_write_handler(0x37FFFF4, 0x37FFFF7, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_w), this)); // upload tables + cpu->space(AS_PROGRAM).install_read_handler(0x37FFFF8, 0x37FFFFb, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_r), this)); // read decompressed data - cpu->space(AS_PROGRAM).install_readwrite_handler(0x37FFFF0, 0x37FFFFF, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot_r), this), write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_w), this)); - /* It accesses the device at this address too, with different tables, for the game textures, should it just act like a mirror, or a secondary device? */ - cpu->space(AS_PROGRAM).install_readwrite_handler(0x27FFFF0, 0x27FFFFF, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot_ch2_r), this), write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot2_w), this)); + // the device is addressed here too, uploading a different set of tables and accessing a different part of ROM + cpu->space(AS_PROGRAM).install_write_handler(0x27FFFF0, 0x27FFFF3, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot2_srcaddr_w), this)); // set compressed data source address + cpu->space(AS_PROGRAM).install_write_handler(0x27FFFF4, 0x27FFFF7, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot2_w), this)); // upload tables + cpu->space(AS_PROGRAM).install_read_handler(0x27FFFF8, 0x27FFFFb, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot2_r), this)); // read decompressed data } @@ -387,15 +346,7 @@ WRITE32_MEMBER(sega_315_5838_comp_device::doa_prot_w) { printf("doa_prot_w %08x %08x %08x\n", offset*4, data, mem_mask); - if (offset == 0x7ff2 / 4) - { - if (data == 0) - { - m_protstate = 0; - strcpy((char *)m_protram, " TECMO LTD. DEAD OR ALIVE 1996.10.22 VER. 1.00"); // this is the single decompressed string DOA needs - } - } - else logerror("Unhandled Protection WRITE %x @ %x mask %x (PC=%x)\n", data, offset, mem_mask, space.device().safe_pc()); + m_protstate = 0; } @@ -403,5 +354,13 @@ void sega_315_5838_comp_device::install_doa_protection() { //todo, install these in the driver, they differ between games cpu_device* cpu = (cpu_device*)machine().device(":maincpu"); + + m_protstate = 0; + strcpy((char *)m_protram, " TECMO LTD. DEAD OR ALIVE 1996.10.22 VER. 1.00"); // this is the single decompressed string DOA needs, note, 2 spaces at start, might indicate a dummy read like with 5881 on Model 2 + cpu->space(AS_PROGRAM).install_readwrite_handler(0x01d80000, 0x01dfffff, read32_delegate(FUNC(sega_315_5838_comp_device::doa_prot_r), this), write32_delegate(FUNC(sega_315_5838_comp_device::doa_prot_w), this)); + cpu->space(AS_PROGRAM).install_write_handler(0x01d87ff0, 0x01d87ff3, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_srcaddr_w), this)); // set compressed data source address (always set 0, data is in RAM) + cpu->space(AS_PROGRAM).install_write_handler(0x01d87ff4, 0x01d87ff7, write32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_w_doa), this)); // upload tab +// cpu->space(AS_PROGRAM).install_read_handler(0x01d87ff8, 0x01d87ffb, read32_delegate(FUNC(sega_315_5838_comp_device::decathlt_prot1_r), this)); // read decompressed data + } \ No newline at end of file diff --git a/src/mame/machine/315-5838_317-0229_comp.h b/src/mame/machine/315-5838_317-0229_comp.h index 63725020922..8afd515f051 100644 --- a/src/mame/machine/315-5838_317-0229_comp.h +++ b/src/mame/machine/315-5838_317-0229_comp.h @@ -4,6 +4,8 @@ #ifndef __SEGA315_5838_COMP__ #define __SEGA315_5838_COMP__ +#define CHANNELS 2 + typedef device_delegate sega_dec_read_delegate; extern const device_type SEGA315_5838_COMP; @@ -20,28 +22,36 @@ public: // construction/destruction sega_315_5838_comp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - sega_dec_read_delegate m_read_ch1; sega_dec_read_delegate m_read_ch2; static void set_read_cb_ch1(device_t &device,sega_dec_read_delegate readcb) { sega_315_5838_comp_device &dev = downcast(device); - dev.m_read_ch1 = readcb; + dev.m_channel[0].m_read_ch = readcb; } static void set_read_cb_ch2(device_t &device,sega_dec_read_delegate readcb) { sega_315_5838_comp_device &dev = downcast(device); - dev.m_read_ch2 = readcb; + dev.m_channel[1].m_read_ch = readcb; } - DECLARE_READ32_MEMBER(decathlt_prot_r); - DECLARE_READ32_MEMBER(decathlt_prot_ch2_r);; - UINT32 genericdecathlt_prot_r(UINT32 offset, UINT32 mem_mask, int which); + DECLARE_READ32_MEMBER(decathlt_prot1_r); + DECLARE_READ32_MEMBER(decathlt_prot2_r);; + UINT32 genericdecathlt_prot_r(UINT32 mem_mask, int channel); - void write_prot_data(UINT32 data, UINT32 mem_mask, int offset, int which); + void write_prot_data(UINT32 data, UINT32 mem_mask, int channel, int rev_words); + + void upload_table_data(UINT16 data, int channel); + void set_upload_mode(UINT16 data, int channel); + void set_prot_addr(UINT32 data, UINT32 mem_mask, int channel); + + DECLARE_WRITE32_MEMBER(decathlt_prot1_w_doa); DECLARE_WRITE32_MEMBER(decathlt_prot1_w); DECLARE_WRITE32_MEMBER(decathlt_prot2_w); + DECLARE_WRITE32_MEMBER(decathlt_prot1_srcaddr_w); + DECLARE_WRITE32_MEMBER(decathlt_prot2_srcaddr_w); + void install_decathlt_protection(); void install_doa_protection(); @@ -55,13 +65,22 @@ protected: private: // Decathlete specific variables and functions (see machine/decathlt.c) - UINT32 m_decathlt_protregs[4]; - UINT32 m_decathlt_lastcount; - UINT32 m_decathlt_part; - UINT32 m_decathlt_prot_uploadmode; - UINT32 m_decathlt_prot_uploadoffset; - UINT16 m_decathlt_prottable1[24]; - UINT16 m_decathlt_prottable2[128]; + struct channel_type + { + UINT32 m_srcoffset; + UINT16 m_decathlt_prottable1[24]; + UINT16 m_decathlt_dictionary[128]; + + UINT32 m_decathlt_lastcount; + UINT32 m_decathlt_prot_uploadmode; + UINT32 m_decathlt_prot_uploadoffset; + sega_dec_read_delegate m_read_ch; + + }; + + channel_type m_channel[2]; + + // Doa int m_protstate;