mirror of
https://github.com/holub/mame
synced 2025-06-23 12:58:37 +03:00
From: David Haywood
Kaneko16 improvements. This is the one that eliminates the hardcoded table with the initial program snippet in, gets it from the rom instead, and generally cleans things up.
This commit is contained in:
parent
1360627416
commit
be41beaf71
@ -80,6 +80,9 @@ Dip locations verified from manual for:
|
||||
#include "sound/2151intf.h"
|
||||
#include "sound/okim6295.h"
|
||||
|
||||
UINT16* kaneko16_calc3_fakeram;
|
||||
static UINT16* kaneko16_mainram;
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
|
||||
@ -789,7 +792,7 @@ static WRITE16_HANDLER( shogwarr_oki_bank_w )
|
||||
|
||||
static ADDRESS_MAP_START( shogwarr, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM
|
||||
AM_RANGE(0x100000, 0x10ffff) AM_RAM // Work RAM
|
||||
AM_RANGE(0x100000, 0x10ffff) AM_RAM AM_BASE(&kaneko16_mainram) // Work RAM
|
||||
AM_RANGE(0x200000, 0x20ffff) AM_READWRITE(SMH_RAM,calc3_mcu_ram_w) AM_BASE(&kaneko16_mcu_ram) // Shared With MCU
|
||||
AM_RANGE(0x280000, 0x280001) AM_WRITE(calc3_mcu_com0_w)
|
||||
AM_RANGE(0x290000, 0x290001) AM_WRITE(calc3_mcu_com1_w)
|
||||
@ -813,6 +816,8 @@ static ADDRESS_MAP_START( shogwarr, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
AM_RANGE(0xb80006, 0xb80007) AM_READ_PORT("UNK")
|
||||
AM_RANGE(0xd00000, 0xd00001) AM_NOP // ? (bit 0)
|
||||
AM_RANGE(0xe00000, 0xe00001) AM_WRITE(shogwarr_oki_bank_w) // Samples Bankswitching
|
||||
|
||||
AM_RANGE(0xf00000, 0xffffff) AM_RAM AM_BASE(&kaneko16_calc3_fakeram) // I copy protection data tables here because I don't know where they really go. NOT ON PCB
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
@ -1974,7 +1979,18 @@ static INTERRUPT_GEN( shogwarr_interrupt )
|
||||
{
|
||||
case 2: cpu_set_input_line(device, 2, HOLD_LINE); break;
|
||||
case 1: cpu_set_input_line(device, 3, HOLD_LINE); break;
|
||||
case 0: cpu_set_input_line(device, 4, HOLD_LINE); break;
|
||||
|
||||
// the code for this interupt is provided by the MCU..
|
||||
//case 0: cpu_set_input_line(device, 4, HOLD_LINE); break;
|
||||
case 0:
|
||||
{
|
||||
// hack, clear this ram address to get into test mode (interrupt would clear it)
|
||||
if (kaneko16_mainram[0x2dfe/2]==0xff00)
|
||||
{
|
||||
kaneko16_mainram[0x2dfe/2]=0x0000;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3615,8 +3631,8 @@ followed by several tables in the following format
|
||||
|
||||
OFFSET 0 - the location of a word which specifies the size of the block
|
||||
- this is usually '3', but if it's larger than 3 it enables an 'inline encryption' mode, whereby the decryption table is stored in the
|
||||
- right before the length register
|
||||
|
||||
- right before the length register
|
||||
|
||||
OFFSET 1 - a 'mode' register of some sort, usually 0,1,2 or 3 for used data, shogun also called a 'blank' command (length 0) with mode 8
|
||||
|
||||
OFFSET 2 - unknown, might be some kind of 'step' register
|
||||
@ -3629,7 +3645,7 @@ OFFSET 4-5 (or after the inline decryption table) - the length of the current bl
|
||||
|
||||
OFFSET 6-size - data for thie block
|
||||
|
||||
this continues for the number of blocks specified
|
||||
this continues for the number of blocks specified
|
||||
after all the blocks there is a 0x1000 block of data which is the same between games
|
||||
|
||||
where games specify the same decryption key the table used is the same, I don't know where these tables come from.
|
||||
@ -3638,13 +3654,195 @@ where games specify the same decryption key the table used is the same, I don't
|
||||
|
||||
UINT16 calc3_mcu_crc;
|
||||
|
||||
/* decryption tables */
|
||||
|
||||
/* table 0x00 = not encrypted? */
|
||||
static UINT8 calc3_table00[64] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
/* ok */
|
||||
static UINT8 calc3_table01[64] = {
|
||||
0xce,0xab,0xa1,0xaa,0x20,0x20,0xcb,0x57,0x5b,0x65,0xd6,0x65,0x5e,0x92,0x6c,0x0a,
|
||||
0xf8,0xea,0xb6,0xfd,0x76,0x35,0x47,0xaf,0xed,0xe0,0xcc,0x4d,0x4c,0xd6,0x74,0x78,
|
||||
0x20,0x1c,0x1f,0xc1,0x25,0x2e,0x49,0xe7,0x90,0x1b,0xb4,0xcf,0x1e,0x61,0xd7,0x46,
|
||||
0xda,0x89,0x08,0x77,0xb1,0x81,0x6b,0x2d,0xb6,0xbc,0x99,0xc9,0x35,0x0a,0x0f,0x01
|
||||
};
|
||||
|
||||
/* ok */
|
||||
static UINT8 calc3_table15[64] = {
|
||||
0x0C,0xEB,0x30,0x25,0xA8,0xED,0xE3,0x23,0xAC,0x2B,0x8D,0x34,0x88,0x9F,0x55,0xB5,
|
||||
0xBF,0x15,0xE3,0x7C,0x54,0xD4,0x72,0xA9,0x7E,0x80,0x27,0x9F,0xA3,0x3F,0xA1,0x4D,
|
||||
0x84,0x1B,0xD1,0xB2,0xB5,0xA7,0x0C,0xA0,0x51,0xE6,0x5E,0xC0,0xEB,0x68,0x22,0xD6,
|
||||
0xC8,0xB6,0xCF,0x46,0x4B,0xF0,0x15,0xD7,0xB0,0xB5,0x29,0xB8,0xFD,0x43,0x5C,0xC0
|
||||
};
|
||||
|
||||
/* partial guessed tables
|
||||
unsigned char table31[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b,
|
||||
0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xdc,
|
||||
0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0xde,
|
||||
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xb1
|
||||
};
|
||||
|
||||
|
||||
unsigned char tableb0[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x81,
|
||||
0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x5b
|
||||
};
|
||||
|
||||
unsigned char tableb7[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd7,
|
||||
0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x82,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x26,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x33
|
||||
};
|
||||
|
||||
unsigned char tablebb[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x3d,
|
||||
0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x69,
|
||||
0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x9e,
|
||||
0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x4d
|
||||
};
|
||||
*/
|
||||
|
||||
// global so we can use them in the filename when we save out the data (debug..)
|
||||
static UINT8 calc3_decryption_key_byte;
|
||||
static UINT8 calc3_unknown;
|
||||
static UINT8 calc3_mode;
|
||||
static UINT8 calc3_blocksize_offset;
|
||||
static UINT16 calc3_dataend;
|
||||
static UINT16 calc3_database;
|
||||
|
||||
// endian safe? you're having a laugh
|
||||
int calc3_decompress_table(running_machine* machine, int tabnum, UINT8* dstram, int dstoffset)
|
||||
{
|
||||
UINT8* rom = memory_region(machine,"cpu1");
|
||||
UINT8 numregions;
|
||||
UINT16 length;
|
||||
int x;
|
||||
int offset = 0;
|
||||
numregions = rom[offset+0];
|
||||
|
||||
if (tabnum > numregions)
|
||||
{
|
||||
printf("CALC3 error, requested table > num tables!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rom++;
|
||||
|
||||
// scan through the linked list to find the start of the requested table info
|
||||
for (x=0;x<tabnum;x++)
|
||||
{
|
||||
UINT8 blocksize_offset = rom[offset+0]; // location of the 'block length'
|
||||
offset+= blocksize_offset+1;
|
||||
length = rom[offset+0] | (rom[offset+1]<<8);
|
||||
offset+=length+2;
|
||||
}
|
||||
|
||||
// we're at the start of the block, get the info about it
|
||||
{
|
||||
UINT16 inline_table_base = 0;
|
||||
UINT16 inline_table_size = 0;
|
||||
calc3_database = offset;
|
||||
calc3_blocksize_offset = rom[offset+0]; // location of the 'block length'
|
||||
calc3_mode = rom[offset+1];
|
||||
calc3_unknown = rom[offset+2];
|
||||
calc3_decryption_key_byte = rom[offset+3];
|
||||
|
||||
|
||||
// if blocksize_offset > 3, it appears to specify the encryption table as 'inline' which can be of any size (odd or even) and loops over the bytes to decrypt
|
||||
// the decryption key specified seems to be ignored?
|
||||
if (calc3_blocksize_offset>3)
|
||||
{
|
||||
inline_table_base = offset+4;
|
||||
inline_table_size = calc3_blocksize_offset-3;
|
||||
}
|
||||
|
||||
offset+= calc3_blocksize_offset+1;
|
||||
length = rom[offset+0] | (rom[offset+1]<<8);
|
||||
offset+=2;
|
||||
|
||||
if (inline_table_size)
|
||||
{
|
||||
printf("Block %02x Found Base %04x - Inline Encryption (size %02x) - Mode? %02x Unknown %02x Key (unused?) %02x Length %04x\n", tabnum, calc3_database, inline_table_size, calc3_mode, calc3_unknown, calc3_decryption_key_byte, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Block %02x Found Base %04x - Mode? %02x Unknown %02x Key (unused?) %02x Length %04x\n", tabnum, calc3_database, calc3_mode, calc3_unknown, calc3_decryption_key_byte, length);
|
||||
}
|
||||
|
||||
|
||||
// copy + decrypt the table to the specified memory area
|
||||
if (dstram)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (length==0x00)
|
||||
{
|
||||
// shogwarr does this with 'mode' as 0x08, which probably has some special meaning
|
||||
//printf("CALC3: requested 0 length table!\n");
|
||||
}
|
||||
|
||||
if (inline_table_size)
|
||||
{
|
||||
for (i=0;i<length;i++)
|
||||
{
|
||||
UINT8 dat = rom[offset+i];
|
||||
dat -= rom[inline_table_base + (i%inline_table_size)];
|
||||
dstram[(dstoffset+i)^1] = dat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8* table = calc3_table00;
|
||||
|
||||
// 0x00 seems to have no 'encryption'
|
||||
if (calc3_decryption_key_byte == 0x00) table = calc3_table00;
|
||||
|
||||
// currently only handle 2 of the formats :-(
|
||||
if (calc3_decryption_key_byte == 0x01) table = calc3_table01;
|
||||
if (calc3_decryption_key_byte == 0x15) table = calc3_table15;
|
||||
|
||||
for (i=0;i<length;i++)
|
||||
{
|
||||
UINT8 dat = rom[offset+i];
|
||||
dat -= table[i&0x3f];
|
||||
dstram[(dstoffset+i)^1] = dat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calc3_dataend = offset+length+1;
|
||||
}
|
||||
|
||||
//printf("data base %04x data end %04x\n", calc3_database, calc3_dataend);
|
||||
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
static UINT8 calc3_decryption_key_byte;
|
||||
static UINT8 calc3_unknown;
|
||||
static UINT8 calc3_mode;
|
||||
static UINT8 calc3_blocksize_offset;
|
||||
|
||||
DRIVER_INIT( calc3 )
|
||||
{
|
||||
UINT8* rom = memory_region(machine,"cpu1");
|
||||
UINT8 numregions;
|
||||
|
||||
int x;
|
||||
int offset = 0;
|
||||
UINT8 numregions;
|
||||
|
||||
calc3_mcu_crc = 0;
|
||||
for (x=0;x<0x20000;x++)
|
||||
@ -3652,189 +3850,49 @@ DRIVER_INIT( calc3 )
|
||||
calc3_mcu_crc+=rom[x];
|
||||
}
|
||||
printf("crc %04x\n",calc3_mcu_crc);
|
||||
|
||||
numregions = rom[offset+0];
|
||||
rom++;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
numregions = rom[0];
|
||||
|
||||
for (x=0;x<numregions;x++)
|
||||
{
|
||||
UINT8* tmpdstram = malloc(0x2000);
|
||||
int length;
|
||||
int startoffset = offset;
|
||||
int xx;
|
||||
int blocksize_offset = rom[offset+0]; // location of the 'block length'
|
||||
int decryption_key_byte = rom[offset+3];
|
||||
int inline_table_base = 0;
|
||||
int inline_table_size = 0;
|
||||
UINT8 mode = rom[offset+1];
|
||||
UINT8 unknown = rom[offset+2];
|
||||
|
||||
|
||||
printf("%04x keydat %02x - bsofs:%02x m:%02x u:%02x k:%02x | ", startoffset, x, blocksize_offset,mode,unknown,decryption_key_byte);
|
||||
|
||||
// if blocksize_offset > 3, it seems to specify the decryption table (or _a_ decryption table) inline of specified length, which loops over the data
|
||||
if (blocksize_offset>3)
|
||||
memset(tmpdstram, 0x00,0x2000);
|
||||
length = calc3_decompress_table(machine, x, tmpdstram, 0);
|
||||
|
||||
// dump to file
|
||||
if (length)
|
||||
{
|
||||
inline_table_base = offset+4;
|
||||
inline_table_size = blocksize_offset-3;
|
||||
for (xx=0;xx<blocksize_offset-3;xx++)
|
||||
{
|
||||
printf("%02x ", rom[inline_table_base+xx]);
|
||||
FILE *fp;
|
||||
char filename[256];
|
||||
|
||||
if (calc3_blocksize_offset==3)
|
||||
{
|
||||
sprintf(filename,"data_%s_table_%04x k%02x m%02x u%02x length %04x",
|
||||
machine->gamedrv->name,
|
||||
x, calc3_decryption_key_byte, calc3_mode, calc3_unknown, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
offset+= blocksize_offset+1;
|
||||
length = rom[offset+0] | (rom[offset+1]<<8);
|
||||
|
||||
printf("(length %04x)", length);
|
||||
|
||||
printf("\n");
|
||||
|
||||
offset+=2;
|
||||
|
||||
//if (x==0x2d)
|
||||
{
|
||||
if (length != 0)
|
||||
else
|
||||
{
|
||||
|
||||
if (blocksize_offset==3)
|
||||
{
|
||||
|
||||
// these tables are guessed, where do they come from? internal mcu rom? 0x1000 block at the end? are they related?
|
||||
UINT8* table = 0;
|
||||
|
||||
/* ok */
|
||||
UINT8 table01[64] = {
|
||||
0xce,0xab,0xa1,0xaa,0x20,0x20,0xcb,0x57,0x5b,0x65,0xd6,0x65,0x5e,0x92,0x6c,0x0a,
|
||||
0xf8,0xea,0xb6,0xfd,0x76,0x35,0x47,0xaf,0xed,0xe0,0xcc,0x4d,0x4c,0xd6,0x74,0x78,
|
||||
0x20,0x1c,0x1f,0xc1,0x25,0x2e,0x49,0xe7,0x90,0x1b,0xb4,0xcf,0x1e,0x61,0xd7,0x46,
|
||||
0xda,0x89,0x08,0x77,0xb1,0x81,0x6b,0x2d,0xb6,0xbc,0x99,0xc9,0x35,0x0a,0x0f,0x01
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* ok */
|
||||
UINT8 table15[64] = {
|
||||
0x0C,0xEB,0x30,0x25,0xA8,0xED,0xE3,0x23,0xAC,0x2B,0x8D,0x34,0x88,0x9F,0x55,0xB5,
|
||||
0xBF,0x15,0xE3,0x7C,0x54,0xD4,0x72,0xA9,0x7E,0x80,0x27,0x9F,0xA3,0x3F,0xA1,0x4D,
|
||||
0x84,0x1B,0xD1,0xB2,0xB5,0xA7,0x0C,0xA0,0x51,0xE6,0x5E,0xC0,0xEB,0x68,0x22,0xD6,
|
||||
0xC8,0xB6,0xCF,0x46,0x4B,0xF0,0x15,0xD7,0xB0,0xB5,0x29,0xB8,0xFD,0x43,0x5C,0xC0
|
||||
};
|
||||
|
||||
|
||||
/* used by shogun & brapboys */
|
||||
unsigned char table31[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b,
|
||||
0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xdc,
|
||||
0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0xde,
|
||||
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xb1
|
||||
};
|
||||
|
||||
/* not ok */
|
||||
unsigned char table3f[64] = {
|
||||
0x29,0x34,0xD9,0x20,0x61,0x54,0x5F,0x6C,0x21,0x7E,0x5A,0x0F,0xD0,0x35,0x3B,0x2E,
|
||||
0x44,0x4C,0x71,0xE5,0x53,0x93,0x59,0x1A,0x1A,0xB5,0xE7,0x7A,0x0F,0x61,0x13,0xBD,
|
||||
0xC7,0xA8,0x05,0x2A,0x86,0xA7,0x00,0x5A,0x8B,0x65,0x10,0xBE,0x18,0xFE,0x71,0xE3,
|
||||
0x43,0x02,0xC3,0xF5,0x7E,0x18,0xF1,0x82,0xE7,0xE7,0xDC,0x01,0x4F,0x36,0xCA,0x13
|
||||
};
|
||||
|
||||
|
||||
|
||||
unsigned char tableb0[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x81,
|
||||
0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x5b
|
||||
};
|
||||
|
||||
unsigned char tableb7[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd7,
|
||||
0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x82,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x26,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x33
|
||||
};
|
||||
|
||||
unsigned char tablebb[64] = {
|
||||
// x x x ok x x x ok x x x ok x x x ok
|
||||
0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x3d,
|
||||
0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x69,
|
||||
0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x9e,
|
||||
0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x4d
|
||||
};
|
||||
/* not ok */
|
||||
unsigned char tablebf[64] = {
|
||||
0x9B, 0x8F, 0xDC, 0xBE, 0xE1, 0xD9, 0xE1, 0x86, 0x10, 0x4E, 0xBA, 0xC4, 0x8D, 0x6E, 0xD8, 0x9B,
|
||||
0x2F, 0x0F, 0xAC, 0x2C, 0xCB, 0x00, 0x92, 0x5D, 0x80, 0xED, 0x7E, 0xD9, 0xC3, 0x82, 0x69, 0x58,
|
||||
0x29, 0xD3, 0x78, 0x21, 0xF7, 0xFC, 0xF1, 0xCD, 0x69, 0x04, 0xDD, 0x4D, 0xC4, 0x08, 0x7C, 0x2F,
|
||||
0x1D, 0x95, 0x6C, 0x1C, 0xE7, 0x55, 0x98, 0xA6, 0x3D, 0xEE, 0xE1, 0x40, 0xF4, 0x27, 0x8E, 0x8E
|
||||
};
|
||||
|
||||
if (decryption_key_byte == 0x01) table = table01;
|
||||
if (decryption_key_byte == 0x15) table = table15;
|
||||
if (decryption_key_byte == 0x31) table = table31;
|
||||
if (decryption_key_byte == 0x3f) table = table3f;
|
||||
if (decryption_key_byte == 0xb0) table = tableb0;
|
||||
if (decryption_key_byte == 0xb7) table = tableb7;
|
||||
if (decryption_key_byte == 0xbb) table = tablebb;
|
||||
if (decryption_key_byte == 0xbf) table = tablebf;
|
||||
|
||||
if (table)
|
||||
{
|
||||
int l;
|
||||
for (l=0;l<length;l++)
|
||||
{
|
||||
rom[offset+l] -= table[l&0x3f];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (blocksize_offset>3)// inline decryption table case
|
||||
{
|
||||
int l;
|
||||
for (l=0;l<length;l++)
|
||||
{
|
||||
rom[offset+l] -= rom[inline_table_base + (l%inline_table_size)];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("blocksize offset < 3??\n");
|
||||
|
||||
}
|
||||
|
||||
// dump out file
|
||||
{
|
||||
FILE *fp;
|
||||
char filename[256];
|
||||
|
||||
sprintf(filename,"data_%s_tableno%02x_key%02x_inlineoffset%02x_length%04x",
|
||||
sprintf(filename,"data_%s_table_%04x k%02x (use indirect size %02x) m%02x u%02x length %04x",
|
||||
machine->gamedrv->name,
|
||||
x,
|
||||
decryption_key_byte,
|
||||
blocksize_offset,
|
||||
length);
|
||||
|
||||
|
||||
fp=fopen(filename, "w+b");
|
||||
if (fp)
|
||||
{
|
||||
fwrite(&rom[offset], length, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
x, calc3_decryption_key_byte, calc3_blocksize_offset-3, calc3_mode, calc3_unknown, length);
|
||||
}
|
||||
}
|
||||
|
||||
fp=fopen(filename, "w+b");
|
||||
if (fp)
|
||||
{
|
||||
fwrite(tmpdstram, length, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
offset+=length;
|
||||
free(tmpdstram);
|
||||
}
|
||||
|
||||
|
||||
// there is also a 0x1000 block of data at the end.. same on both games, maybe it's related to the decryption tables??
|
||||
// the calc3_dataend points to the data after the last block processed, as we process all the blocks in the above loop, we assume this points
|
||||
// to that extra block of data
|
||||
|
||||
// dump out the 0x1000 sized block at the end
|
||||
{
|
||||
FILE *fp;
|
||||
@ -3846,7 +3904,7 @@ DRIVER_INIT( calc3 )
|
||||
fp=fopen(filename, "w+b");
|
||||
if (fp)
|
||||
{
|
||||
fwrite(&rom[offset], 0x1000, 1, fp);
|
||||
fwrite(&rom[calc3_dataend], 0x1000, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
@ -313,80 +313,9 @@ CALC3_MCU_COM_W(3)
|
||||
*/
|
||||
UINT32 writeaddress;
|
||||
extern UINT16 calc3_mcu_crc;
|
||||
extern UINT16* kaneko16_calc3_fakeram;
|
||||
|
||||
// todo: change this to get it from the decrypted rom, it's block 0x19, and we have decrypted it (as specified in the parameters)
|
||||
static const UINT16 shogwarr_snip_[] = {
|
||||
0x48E7,0xFFFE, // movem.l D0-D7/A0-A6, -(A7)
|
||||
|
||||
0x3039,0x00A8,0x0000, // move.w $a80000.l, D0
|
||||
0x4279,0x0020,0xFFFE, // clr.w $20fffe.l
|
||||
|
||||
0x41F9,0x0020,0x0000, // lea $200000.l, A0
|
||||
0x7000, // moveq #$0, D0
|
||||
|
||||
0x43E8,0x01C6, // lea ($1c6,A0), A1
|
||||
0x7E02, // moveq #$2, D7
|
||||
0xD059, // add.w (A1)+, D0
|
||||
0x51CF,0xFFFC, // dbra D7, 207ffe
|
||||
|
||||
0x43E9,0x0002, // lea ($2,A1), A1
|
||||
0x7E04, // moveq #$4, D7
|
||||
0xD059, // add.w (A1)+, D0
|
||||
0x51CF,0xFFFC, // dbra D7, 20800a
|
||||
|
||||
0x4640, // not.w D0
|
||||
0x5340, // subq.w #1, D0
|
||||
0x0068,0x0030,0x0216, // ori.w #$30, ($216,A0)
|
||||
|
||||
0xB07A,0x009A, // cmp.w ($9a,PC), D0; ($2080b6)
|
||||
0x670A, // beq 20802a
|
||||
|
||||
0x0268,0x000F,0x0216, // andi.w #$f, ($216,A0)
|
||||
0x4268,0x0218, // clr.w ($218,A0)
|
||||
|
||||
0x5468,0x0216, // addq.w #2, ($216,A0)
|
||||
0x42A8,0x030C, // clr.l ($30c,A0)
|
||||
0x117C,0x0020,0x030C, // move.b #$20, ($30c,A0)
|
||||
|
||||
0x3E3C,0x0001, // move.w #$1, D7
|
||||
|
||||
0x0C68,0x0008,0x0218, // cmpi.w #$8, ($218,A0)
|
||||
0x6C00,0x0068, // bge 2080ac
|
||||
|
||||
0x117C,0x0080,0x0310, // move.b #$80, ($310,A0)
|
||||
0x117C,0x0008,0x0311, // move.b #$8, ($311,A0)
|
||||
0x317C,0x7800,0x0312, // move.w #$7800, ($312,A0)
|
||||
0x5247, // addq.w #1, D7
|
||||
0x0C68,0x0040,0x0216, // cmpi.w #$40, ($216,A0)
|
||||
0x6D08, // blt 20806a
|
||||
|
||||
0x5468,0x0218, // addq.w #2, ($218,A0)
|
||||
0x6000,0x0044, // bra 2080ac
|
||||
|
||||
0x117C,0x0041,0x0314, // move.b #$41, ($314,A0)
|
||||
|
||||
0x0C39,0x0001,0x0010,0x2E12,// cmpi.b #$1, $102e12.l
|
||||
0x6606, // bne 208080
|
||||
|
||||
0x117C,0x0040,0x0314, // move.b #$40, ($314,A0)
|
||||
|
||||
0x117C,0x000C,0x0315, // move.b #$c, ($315,A0)
|
||||
0x317C,0x7000,0x0316, // move.w #$7000, ($316,A0)
|
||||
0x5247, // addq.w #1, D7
|
||||
|
||||
0x0839,0x0001,0x0010,0x2E15,// btst #$1, $102e15.l ; service mode
|
||||
0x6714, // beq 2080ac
|
||||
|
||||
0x117C,0x0058,0x0318, // move.b #$58, ($318,A0)
|
||||
0x117C,0x0006,0x0319, // move.b #$6, ($319,A0)
|
||||
0x317C,0x6800,0x031A, // move.w #$6800, ($31a,A0)
|
||||
0x5247, // addq.w #1, D7
|
||||
|
||||
0x3147,0x030A, // move.w D7, ($30a,A0)
|
||||
0x4CDF,0x7FFF, // movem.l (A7)+, D0-D7/A0-A6
|
||||
0x4E73, // rte
|
||||
0xC747,
|
||||
};
|
||||
extern int calc3_decompress_table(running_machine* machine, int tabnum, UINT8* dstram, int dstoffset);
|
||||
|
||||
|
||||
static void calc3_mcu_run(running_machine *machine)
|
||||
@ -396,7 +325,7 @@ static void calc3_mcu_run(running_machine *machine)
|
||||
if ( calc3_mcu_status != (1|2|4|8) ) return;
|
||||
|
||||
//calc3_mcu_status = 0;
|
||||
|
||||
|
||||
mcu_command = kaneko16_mcu_ram[calc3_mcu_command_offset/2 + 0];
|
||||
|
||||
if (mcu_command == 0) return;
|
||||
@ -404,13 +333,13 @@ static void calc3_mcu_run(running_machine *machine)
|
||||
logerror("%s : MCU executed command at %04X: %04X\n",
|
||||
cpuexec_describe_context(machine),calc3_mcu_command_offset,mcu_command);
|
||||
|
||||
|
||||
|
||||
switch (mcu_command)
|
||||
{
|
||||
|
||||
case 0x00ff:
|
||||
{
|
||||
|
||||
|
||||
|
||||
int param1 = kaneko16_mcu_ram[(0>>1) + 1];
|
||||
int param2 = kaneko16_mcu_ram[(0>>1) + 2];
|
||||
@ -443,6 +372,7 @@ static void calc3_mcu_run(running_machine *machine)
|
||||
|
||||
// clear old command (handshake to main cpu)
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+0] = 0x0000;
|
||||
/*
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+1] = 0x0000;
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+2] = 0x0000;
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+3] = 0x0000;
|
||||
@ -450,133 +380,59 @@ static void calc3_mcu_run(running_machine *machine)
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+5] = 0x0000;
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+6] = 0x0000;
|
||||
kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+7] = 0x0000;
|
||||
|
||||
*/
|
||||
calc3_mcu_command_offset = param3; // where next command will be written?
|
||||
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
// the 'case' seems to be the number of commands in the list
|
||||
// there are parts of the code where i've seen up to '5' specified, and the game uploads 5 transfer commands
|
||||
//
|
||||
|
||||
|
||||
case 0x0001:
|
||||
{
|
||||
int i;
|
||||
int param1 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 1];
|
||||
int param2 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 2];
|
||||
int param3 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 3];
|
||||
int param4 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 4];
|
||||
int param5 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 5];
|
||||
int param6 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 6];
|
||||
int param7 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+ 7];
|
||||
|
||||
UINT32 writebackaddress = (param1&0x00ff) | (param2&0xff00);
|
||||
UINT8 command1tabl = (param1&0xff00) >> 8;
|
||||
UINT16 command1addr = (param1&0x00ff) | (param2&0xff00);
|
||||
|
||||
|
||||
logerror("params %04x %04x %04x %04x %04x %04x %04x\n",
|
||||
param1,param2,param3,param4,param5,param6,param7);
|
||||
logerror("command 1 addr %04x command 1 table %02x\n", command1addr, command1tabl);
|
||||
|
||||
// clear old command (handshake to main cpu)
|
||||
kaneko16_mcu_ram[calc3_mcu_command_offset>>1] = 0x0000;
|
||||
|
||||
|
||||
|
||||
// execute the command:
|
||||
|
||||
// param1 ?
|
||||
//kaneko16_mcu_ram[param2/2 + 0] = 0x0000; // ?
|
||||
//kaneko16_mcu_ram[param2/2 + 1] = 0x0000; // ?
|
||||
//kaneko16_mcu_ram[param2/2 + 2] = 0x0000; // ?
|
||||
//kaneko16_mcu_ram[param2/2 + 3] = 0x0000; // ? addr.l
|
||||
//kaneko16_mcu_ram[param2/2 + 4] = 0x00e0; // 0000e0: 4e73 rte
|
||||
|
||||
//UINT32 writeaddress = (param2);
|
||||
|
||||
|
||||
|
||||
writeaddress&=0xffff;
|
||||
|
||||
|
||||
for(i=0;i<sizeof(shogwarr_snip_) / 2;i++)
|
||||
{
|
||||
// printf("writes\n %08x", (writeaddress+i)*2);
|
||||
kaneko16_mcu_ram[(writeaddress/2)+i] = shogwarr_snip_[i];
|
||||
}
|
||||
|
||||
kaneko16_mcu_ram[(writebackaddress/2)+0] = 0x0020;
|
||||
kaneko16_mcu_ram[(writebackaddress/2)+1] = writeaddress;
|
||||
|
||||
// calc3_mcu_command_offset = param3; // where next command will be written?
|
||||
// calc3_mcu_status =0;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0002:
|
||||
{
|
||||
|
||||
|
||||
int param1 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 1];
|
||||
int param2 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 2];
|
||||
int param3 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 3];
|
||||
int param4 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 4];
|
||||
int param5 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 5];
|
||||
int param6 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 6];
|
||||
int param7 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+ 7];
|
||||
|
||||
|
||||
UINT8 command1tabl = (param1&0xff00) >> 8;
|
||||
UINT16 command1addr = (param1&0x00ff) | (param2&0xff00);
|
||||
UINT8 command2tabl = (param3&0xff00) >> 8;
|
||||
UINT16 command2addr = (param3&0x00ff) | (param4&0xff00);
|
||||
|
||||
logerror("params %04x %04x %04x %04x %04x %04x %04x\n",
|
||||
param1,param2,param3,param4,param5,param6,param7);
|
||||
logerror("command 1 addr %04x command 1 table %02x | command 2 addr %04x command 2 table %02x\n", command1addr, command1tabl, command2addr, command2tabl);
|
||||
|
||||
// clear old command (handshake to main cpu)
|
||||
kaneko16_mcu_ram[calc3_mcu_command_offset>>1] = 0x0000;
|
||||
|
||||
// execute the command:
|
||||
;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0003:
|
||||
case 0x0004:
|
||||
case 0x0005:
|
||||
case 0x0006:
|
||||
case 0x0007:
|
||||
// the 'case' seems to be the number of commands in the list
|
||||
// there are parts of the code where i've seen up to '5' specified, and the game uploads 5 transfer commands
|
||||
//
|
||||
{
|
||||
int num_transfers = mcu_command;
|
||||
int i;
|
||||
|
||||
logerror("Calc3 transfer request, %d transfers\n", num_transfers);
|
||||
|
||||
for (i=0;i<num_transfers;i++)
|
||||
{
|
||||
int param1 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 1 + (2*i)];
|
||||
int param2 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 2 + (2*i)];
|
||||
UINT8 commandtabl = (param1&0xff00) >> 8;
|
||||
UINT16 commandaddr = (param1&0x00ff) | (param2&0xff00);
|
||||
UINT32 fakeoffs;
|
||||
|
||||
logerror("transfer %d table %02x writeback address %04x\n", i, commandtabl, commandaddr);
|
||||
|
||||
// the data SHOULD be written somewhere to main ram, probably related to the writeaddress set in command 0xff
|
||||
// but I'm not sure how, for now write it back to a FAKE region instead
|
||||
fakeoffs = 0x1e00*commandtabl;
|
||||
|
||||
calc3_decompress_table(machine, commandtabl, (UINT8*)kaneko16_calc3_fakeram, fakeoffs);
|
||||
|
||||
// write back WHERE we wrote the data to the address specified so that the code can jump to it etc.
|
||||
fakeoffs+=0xf00000;
|
||||
fakeoffs+=2;// the first 2 bytes don't seem to be the offset it expects to jump to..
|
||||
|
||||
printf("writing back fake address %08x to %08x\n", fakeoffs, commandaddr);
|
||||
kaneko16_mcu_ram[(commandaddr>>1)+0] = (fakeoffs>>16)&0xffff;
|
||||
kaneko16_mcu_ram[(commandaddr>>1)+1] = (fakeoffs&0xffff);
|
||||
|
||||
int param1 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 1];
|
||||
int param2 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 2];
|
||||
int param3 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 3];
|
||||
int param4 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 4];
|
||||
int param5 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 5];
|
||||
int param6 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1) + 6];
|
||||
int param7 = kaneko16_mcu_ram[(calc3_mcu_command_offset>>1)+ 7];
|
||||
|
||||
|
||||
UINT8 command1tabl = (param1&0xff00) >> 8;
|
||||
UINT16 command1addr = (param1&0x00ff) | (param2&0xff00);
|
||||
UINT8 command2tabl = (param3&0xff00) >> 8;
|
||||
UINT16 command2addr = (param3&0x00ff) | (param4&0xff00);
|
||||
UINT8 command3tabl = (param5&0xff00) >> 8;
|
||||
UINT16 command3addr = (param5&0x00ff) | (param6&0xff00);
|
||||
|
||||
logerror("params %04x %04x %04x %04x %04x %04x %04x\n",
|
||||
param1,param2,param3,param4,param5,param6,param7);
|
||||
logerror("command 1 addr %04x command 1 table %02x | command 2 addr %04x command 2 table %02x | command 3 addr %04x command 3 table %02x\n", command1addr, command1tabl, command2addr, command2tabl, command3addr, command3tabl);
|
||||
|
||||
// clear old command (handshake to main cpu)
|
||||
kaneko16_mcu_ram[calc3_mcu_command_offset>>1] = 0x0000;
|
||||
|
||||
// execute the command:
|
||||
}
|
||||
|
||||
// reset 'number of commands' to 0 to indicate processing complete to the main cpu.
|
||||
kaneko16_mcu_ram[calc3_mcu_command_offset>>1] = 0x0000;;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user