evidence suggests there there aren't 2 channels. (nw)

This commit is contained in:
David Haywood 2016-02-01 17:57:54 +00:00
parent f099454e95
commit 0e38af3983
2 changed files with 61 additions and 65 deletions

View File

@ -12,15 +12,12 @@
Package Type: TQFP100 Package Type: TQFP100
This appears to be a dual channel compression chip, used in 1996, predating the 5881. Decathlete accesses the chip at 2 different addresses, however, I don't think there
Decathlete uses it to compress ALL the game graphics, Dead or Alive uses it for a are 2 channels / sets of registers, instead the 2nd set of addresses are just a
dumb security check, decompressing a single string. mirror that allows access to a different set of source roms; the tables etc. are
re-uploaded before every transfer.
Each channel appears to be connected to a different set of ROMs, however there is Dead of Alive has the source data in RAM, not ROM.
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 This is similar to how some 5881 games were set up, with the ST-V versions decrypting
data directly from ROM and the Model 2 ones using a RAM source buffer. data directly from ROM and the Model 2 ones using a RAM source buffer.
@ -54,11 +51,12 @@ sega_315_5838_comp_device::sega_315_5838_comp_device(const machine_config &mconf
void sega_315_5838_comp_device::device_start() void sega_315_5838_comp_device::device_start()
{ {
m_decathlt_lastcount = 0;
m_decathlt_prot_uploadmode = 0;
m_decathlt_prot_uploadoffset = 0;
for (auto & elem : m_channel) for (auto & elem : m_channel)
{ {
elem.m_decathlt_lastcount = 0;
elem.m_decathlt_prot_uploadmode = 0;
elem.m_decathlt_prot_uploadoffset = 0;
elem.m_read_ch.bind_relative_to(*owner()); elem.m_read_ch.bind_relative_to(*owner());
} }
@ -66,14 +64,10 @@ void sega_315_5838_comp_device::device_start()
void sega_315_5838_comp_device::device_reset() void sega_315_5838_comp_device::device_reset()
{ {
for (auto & elem : m_channel) m_srcoffset = 0;
{ m_decathlt_lastcount = 0;
elem.m_srcoffset = 0; m_decathlt_prot_uploadmode = 0;
elem.m_decathlt_lastcount = 0; m_decathlt_prot_uploadoffset = 0;
elem.m_decathlt_prot_uploadmode = 0;
elem.m_decathlt_prot_uploadoffset = 0;
}
m_protstate = 0; m_protstate = 0;
} }
@ -105,46 +99,46 @@ UINT32 sega_315_5838_comp_device::genericdecathlt_prot_r(UINT32 mem_mask, int ch
// UINT32 *fake0 = (UINT32*)memregion( ":fake0" )->base(); // UINT32 *fake0 = (UINT32*)memregion( ":fake0" )->base();
// UINT32 retvalue = 0xffff; // UINT32 retvalue = 0xffff;
switch (m_channel[channel].m_srcoffset) switch (m_srcoffset)
{ {
default: default:
m_channel[channel].m_decathlt_lastcount++; m_decathlt_lastcount++;
UINT32 tempdata = 0; UINT32 tempdata = 0;
tempdata |= m_channel[channel].m_read_ch(m_channel[channel].m_srcoffset) << 0; tempdata |= m_channel[channel].m_read_ch(m_srcoffset) << 0;
m_channel[channel].m_srcoffset++; m_srcoffset++;
tempdata |= m_channel[channel].m_read_ch(m_channel[channel].m_srcoffset) << 16; tempdata |= m_channel[channel].m_read_ch(m_srcoffset) << 16;
m_channel[channel].m_srcoffset++; m_srcoffset++;
#ifdef DEBUG_DATA_DUMP #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); //printf("read addr %08x, blah_r %08x - read count count %08x\n", m_srcoffset*2, tempdata, m_decathlt_lastcount*4);
fwrite(&tempdata, 1, 4, tempfile); fwrite(&tempdata, 1, 4, tempfile);
#else #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); logerror("read addr %08x, blah_r %08x - read count count %08x\n", m_srcoffset*2, tempdata, m_decathlt_lastcount*4);
#endif #endif
return tempdata; return tempdata;
#if 0 #if 0
case 0x03228e4: case 0x03228e4:
if (fake0) retvalue = fake0[(((0x20080/4)+m_channel[channel].m_decathlt_lastcount))]; if (fake0) retvalue = fake0[(((0x20080/4)+m_decathlt_lastcount))];
m_channel[channel].m_decathlt_lastcount++; m_decathlt_lastcount++;
return retvalue; return retvalue;
case 0x00a9f3a: case 0x00a9f3a:
if (fake0) retvalue = fake0[(((0x00000/4)+m_channel[channel].m_decathlt_lastcount))]; if (fake0) retvalue = fake0[(((0x00000/4)+m_decathlt_lastcount))];
m_channel[channel].m_decathlt_lastcount++; m_decathlt_lastcount++;
return retvalue; return retvalue;
case 0x0213ab4: case 0x0213ab4:
if (fake0) retvalue = fake0[(((0x40000/4)+m_channel[channel].m_decathlt_lastcount))]; if (fake0) retvalue = fake0[(((0x40000/4)+m_decathlt_lastcount))];
m_channel[channel].m_decathlt_lastcount++; m_decathlt_lastcount++;
return retvalue; return retvalue;
case 0x01efaf0: case 0x01efaf0:
if (fake0) retvalue = fake0[(((0x60000/4)+m_channel[channel].m_decathlt_lastcount))]; if (fake0) retvalue = fake0[(((0x60000/4)+m_decathlt_lastcount))];
m_channel[channel].m_decathlt_lastcount++; m_decathlt_lastcount++;
return retvalue; return retvalue;
case 0x033f16c: case 0x033f16c:
@ -185,14 +179,14 @@ UINT32 sega_315_5838_comp_device::genericdecathlt_prot_r(UINT32 mem_mask, int ch
void sega_315_5838_comp_device::set_prot_addr(UINT32 data, UINT32 mem_mask, int channel) void sega_315_5838_comp_device::set_prot_addr(UINT32 data, UINT32 mem_mask, int channel)
{ {
// printf("set_prot_addr\n"); // printf("set_prot_addr\n");
COMBINE_DATA(&m_channel[channel].m_srcoffset); COMBINE_DATA(&m_srcoffset);
//if (m_decathlt_part==0) logerror("%d, last read count was %06x\n",channel, m_channel[channel].m_decathlt_lastcount*4); //if (m_decathlt_part==0) logerror("%d, last read count was %06x\n",channel, m_decathlt_lastcount*4);
m_channel[channel].m_decathlt_lastcount = 0; m_decathlt_lastcount = 0;
if (mem_mask == 0x0000ffff) if (mem_mask == 0x0000ffff)
{ {
printf("set source address to %08x (channel %d)\n", m_channel[channel].m_srcoffset, channel); printf("set source address to %08x (channel %d)\n", m_srcoffset, channel);
} }
@ -203,24 +197,24 @@ void sega_315_5838_comp_device::set_prot_addr(UINT32 data, UINT32 mem_mask, int
fclose(tempfile); fclose(tempfile);
char filename[256]; char filename[256];
sprintf(filename, "%d_compressed_%08x", channel, m_channel[channel].m_srcoffset * 2); sprintf(filename, "%d_compressed_%08x", channel, m_srcoffset * 2);
tempfile = fopen(filename, "w+b"); tempfile = fopen(filename, "w+b");
// the table and dictionary are uploaded repeatedly, usually before groups of data transfers but // 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) // it's always the same tables (one pair for each channel)
{ {
FILE* fp; FILE* fp;
sprintf(filename, "%d_compressed_table1", channel); sprintf(filename, "%d_compressed_table1_%08x", channel, m_srcoffset * 2);
fp = fopen(filename, "w+b"); fp = fopen(filename, "w+b");
fwrite(&m_channel[channel].m_decathlt_prottable1, 24, 2, fp); fwrite(&m_decathlt_prottable1, 24, 2, fp);
fclose(fp); fclose(fp);
} }
{ {
FILE* fp; FILE* fp;
sprintf(filename, "%d_compressed_dictionary", channel); sprintf(filename, "%d_compressed_dictionary_%08x", channel, m_srcoffset * 2);
fp = fopen(filename, "w+b"); fp = fopen(filename, "w+b");
fwrite(&m_channel[channel].m_decathlt_dictionary, 128, 2, fp); fwrite(&m_decathlt_dictionaryy, 128, 2, fp);
fclose(fp); fclose(fp);
} }
} }
@ -233,13 +227,13 @@ void sega_315_5838_comp_device::set_upload_mode(UINT16 data, int channel)
if ((data == 0x8000) || (data == 0x0000)) if ((data == 0x8000) || (data == 0x0000))
{ {
// logerror("changed to upload mode 1\n"); // logerror("changed to upload mode 1\n");
m_channel[channel].m_decathlt_prot_uploadmode = 1; m_decathlt_prot_uploadmode = 1;
m_channel[channel].m_decathlt_prot_uploadoffset = 0; m_decathlt_prot_uploadoffset = 0;
} }
else if ((data == 0x8080) || (data == 0x0080)) else if ((data == 0x8080) || (data == 0x0080))
{ {
m_channel[channel].m_decathlt_prot_uploadmode = 2; m_decathlt_prot_uploadmode = 2;
m_channel[channel].m_decathlt_prot_uploadoffset = 0; m_decathlt_prot_uploadoffset = 0;
} }
else else
{ {
@ -249,30 +243,30 @@ void sega_315_5838_comp_device::set_upload_mode(UINT16 data, int channel)
void sega_315_5838_comp_device::upload_table_data(UINT16 data, int channel) void sega_315_5838_comp_device::upload_table_data(UINT16 data, int channel)
{ {
if (m_channel[channel].m_decathlt_prot_uploadmode == 1) if (m_decathlt_prot_uploadmode == 1)
{ {
if (m_channel[channel].m_decathlt_prot_uploadoffset >= 24) if (m_decathlt_prot_uploadoffset >= 24)
{ {
fatalerror("upload mode 1 error, too big\n"); fatalerror("upload mode 1 error, too big\n");
return; return;
} }
//logerror("uploading table 1 %04x %04x\n",m_channel[channel].m_decathlt_prot_uploadoffset, data&0xffff); //logerror("uploading table 1 %04x %04x\n",m_decathlt_prot_uploadoffset, data&0xffff);
m_channel[channel].m_decathlt_prottable1[m_channel[channel].m_decathlt_prot_uploadoffset] = data & 0xffff; m_decathlt_prottable1[m_decathlt_prot_uploadoffset] = data & 0xffff;
m_channel[channel].m_decathlt_prot_uploadoffset++; m_decathlt_prot_uploadoffset++;
printf("unk table 1 %04x (channel %d)\n", data & 0xffff, channel); printf("unk table 1 %04x (channel %d)\n", data & 0xffff, channel);
} }
else if (m_channel[channel].m_decathlt_prot_uploadmode == 2) else if (m_decathlt_prot_uploadmode == 2)
{ {
if (m_channel[channel].m_decathlt_prot_uploadoffset >= 128) if (m_decathlt_prot_uploadoffset >= 128)
{ {
fatalerror("upload mode 2 error, too big\n"); fatalerror("upload mode 2 error, too big\n");
return; return;
} }
//logerror("uploading table 2 %04x %04x\n",m_channel[channel].m_decathlt_prot_uploadoffset, data&0xffff); //logerror("uploading table 2 %04x %04x\n",m_decathlt_prot_uploadoffset, data&0xffff);
m_channel[channel].m_decathlt_dictionary[m_channel[channel].m_decathlt_prot_uploadoffset] = data & 0xffff; m_decathlt_dictionaryy[m_decathlt_prot_uploadoffset] = data & 0xffff;
m_channel[channel].m_decathlt_prot_uploadoffset++; m_decathlt_prot_uploadoffset++;
printf("dictionary %04x (channel %d)\n", data & 0xffff, channel); printf("dictionary %04x (channel %d)\n", data & 0xffff, channel);
} }
} }

View File

@ -65,17 +65,19 @@ protected:
virtual void device_reset() override; virtual void device_reset() override;
private: private:
// Decathlete specific variables and functions (see machine/decathlt.c)
struct channel_type
{
UINT32 m_srcoffset;
UINT16 m_decathlt_prottable1[24]; UINT16 m_decathlt_prottable1[24];
UINT16 m_decathlt_dictionary[128]; UINT16 m_decathlt_dictionaryy[128];
UINT32 m_srcoffset;
UINT32 m_decathlt_lastcount; UINT32 m_decathlt_lastcount;
UINT32 m_decathlt_prot_uploadmode; UINT32 m_decathlt_prot_uploadmode;
UINT32 m_decathlt_prot_uploadoffset; UINT32 m_decathlt_prot_uploadoffset;
// Decathlete specific variables and functions (see machine/decathlt.c)
struct channel_type
{
sega_dec_read_delegate m_read_ch; sega_dec_read_delegate m_read_ch;
}; };