diff options
author | Aaron Giles <aaron@aarongiles.com> | 2009-06-25 07:37:44 +0000 |
---|---|---|
committer | Aaron Giles <aaron@aarongiles.com> | 2009-06-25 07:37:44 +0000 |
commit | be41beaf71a00197ca55786d10f0b1956ad7ba8e (patch) | |
tree | badcc491f0cf7b2aeab3fb17130a66ad9468fcaf | |
parent | 13606274162fa82c179c006bd4e7fe1a4970357d (diff) |
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.
-rw-r--r-- | src/mame/drivers/kaneko16.c | 410 | ||||
-rw-r--r-- | src/mame/machine/kaneko16.c | 238 |
2 files changed, 281 insertions, 367 deletions
diff --git a/src/mame/drivers/kaneko16.c b/src/mame/drivers/kaneko16.c index 07d05bab7b3..bacbf246706 100644 --- a/src/mame/drivers/kaneko16.c +++ b/src/mame/drivers/kaneko16.c @@ -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,203 +3654,245 @@ where games specify the same decryption key the table used is the same, I don't UINT16 calc3_mcu_crc; -DRIVER_INIT( calc3 ) -{ - UINT8* rom = memory_region(machine,"cpu1"); +/* decryption tables */ - int x; - int offset = 0; - UINT8 numregions; +/* 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, +}; - calc3_mcu_crc = 0; - for (x=0;x<0x20000;x++) - { - calc3_mcu_crc+=rom[x]; - } - printf("crc %04x\n",calc3_mcu_crc); +/* 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 +}; - numregions = rom[offset+0]; - rom++; +/* 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; - for (x=0;x<numregions;x++) +// 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) { - 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); + 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; + } - // 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) - { + // 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 = blocksize_offset-3; - for (xx=0;xx<blocksize_offset-3;xx++) - { - printf("%02x ", rom[inline_table_base+xx]); - } + inline_table_size = calc3_blocksize_offset-3; } - - - offset+= blocksize_offset+1; + + offset+= calc3_blocksize_offset+1; length = rom[offset+0] | (rom[offset+1]<<8); - - printf("(length %04x)", length); - - printf("\n"); - offset+=2; - - //if (x==0x2d) + + if (inline_table_size) { - if (length != 0) + 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 (blocksize_offset==3) + if (inline_table_size) + { + for (i=0;i<length;i++) { - - // 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 + 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++) { - int l; - for (l=0;l<length;l++) - { - rom[offset+l] -= rom[inline_table_base + (l%inline_table_size)]; - } + UINT8 dat = rom[offset+i]; + dat -= table[i&0x3f]; + dstram[(dstoffset+i)^1] = dat; } - else - { - printf("blocksize offset < 3??\n"); + } + } + + calc3_dataend = offset+length+1; + } + + //printf("data base %04x data end %04x\n", calc3_database, calc3_dataend); + + return length; - } +} - // dump out file - { - FILE *fp; - char filename[256]; +static UINT8 calc3_decryption_key_byte; +static UINT8 calc3_unknown; +static UINT8 calc3_mode; +static UINT8 calc3_blocksize_offset; - sprintf(filename,"data_%s_tableno%02x_key%02x_inlineoffset%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); - } - } +DRIVER_INIT( calc3 ) +{ + UINT8* rom = memory_region(machine,"cpu1"); + UINT8 numregions; - } - } + int x; - offset+=length; + calc3_mcu_crc = 0; + for (x=0;x<0x20000;x++) + { + calc3_mcu_crc+=rom[x]; } + printf("crc %04x\n",calc3_mcu_crc); + numregions = rom[0]; + + for (x=0;x<numregions;x++) + { + UINT8* tmpdstram = malloc(0x2000); + int length; + memset(tmpdstram, 0x00,0x2000); + length = calc3_decompress_table(machine, x, tmpdstram, 0); + + // dump to file + if (length) + { + 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); + } + else + { + sprintf(filename,"data_%s_table_%04x k%02x (use indirect size %02x) m%02x u%02x length %04x", + machine->gamedrv->name, + 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); + } + } + 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); } } diff --git a/src/mame/machine/kaneko16.c b/src/mame/machine/kaneko16.c index e32f2f5dca2..3c0599cb3fb 100644 --- a/src/mame/machine/kaneko16.c +++ b/src/mame/machine/kaneko16.c @@ -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; - + + case 0x0001: + case 0x0002: + 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 + // there are parts of the code where i've seen up to '5' specified, and the game uploads 5 transfer commands // - - case 0x0001: { + int num_transfers = mcu_command; 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++) + + logerror("Calc3 transfer request, %d transfers\n", num_transfers); + + for (i=0;i<num_transfers;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); + 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); - 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: - { - - 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; - } } |