diff --git a/src/mame/machine/315-5881_crypt.c b/src/mame/machine/315-5881_crypt.c index bedbb2b6f09..0d9ee7cfc60 100644 --- a/src/mame/machine/315-5881_crypt.c +++ b/src/mame/machine/315-5881_crypt.c @@ -529,109 +529,110 @@ of the function. Even so, it would still be pretty slow, so caching techniques c UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequence_key, UINT16 counter, UINT16 data) { int j; - int aux,aux2; - int A,B; + int aux, aux2; + int A, B; int middle_result; UINT32 fn1_subkeys[4]; UINT32 fn2_subkeys[4]; /* Game-key scheduling; this could be done just once per game at initialization time */ - memset(fn1_subkeys,0,sizeof(UINT32)*4); - memset(fn2_subkeys,0,sizeof(UINT32)*4); + memset(fn1_subkeys, 0, sizeof(UINT32) * 4); + memset(fn2_subkeys, 0, sizeof(UINT32) * 4); - for (j=0; j<38; ++j) { - if (BIT(game_key, fn1_game_key_scheduling[j][0])!=0) { - aux = fn1_game_key_scheduling[j][1]%24; - aux2 = fn1_game_key_scheduling[j][1]/24; - fn1_subkeys[aux2] ^= (1<> 8; - A = (aux & 0xff) ^ feistel_function(B,fn1_sboxes[0],fn1_subkeys[0]); + A = (aux & 0xff) ^ feistel_function(B, fn1_sboxes[0], fn1_subkeys[0]); // 2nd round - B = B ^ feistel_function(A,fn1_sboxes[1],fn1_subkeys[1]); + B = B ^ feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]); // 3rd round - A = A ^ feistel_function(B,fn1_sboxes[2],fn1_subkeys[2]); + A = A ^ feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]); // 4th round - B = B ^ feistel_function(A,fn1_sboxes[3],fn1_subkeys[3]); + B = B ^ feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]); - middle_result = (B<<8)|A; + middle_result = (B << 8) | A; /* Middle-result-key sheduling */ - for (j=0; j<16; ++j) { - if (BIT(middle_result,j)!=0) { - aux = fn2_middle_result_scheduling[j]%24; - aux2 = fn2_middle_result_scheduling[j]/24; - fn2_subkeys[aux2] ^= (1<> 8; - A = (aux & 0xff) ^ feistel_function(B,fn2_sboxes[0],fn2_subkeys[0]); + A = (aux & 0xff) ^ feistel_function(B, fn2_sboxes[0], fn2_subkeys[0]); // 2nd round - B = B ^ feistel_function(A,fn2_sboxes[1],fn2_subkeys[1]); + B = B ^ feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]); // 3rd round - A = A ^ feistel_function(B,fn2_sboxes[2],fn2_subkeys[2]); + A = A ^ feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]); // 4th round - B = B ^ feistel_function(A,fn2_sboxes[3],fn2_subkeys[3]); + B = B ^ feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]); - aux = (B<<8)|A; + aux = (B << 8) | A; - aux = BITSWAP16(aux,15,7,6,14,13,12,5,4, 3,2,11,10,9,1,0,8); + aux = BITSWAP16(aux, 15, 7, 6, 14, 13, 12, 5, 4, 3, 2, 11, 10, 9, 1, 0, 8); return aux; } + UINT16 sega_315_5881_crypt_device::get_decrypted_16() { UINT16 enc; @@ -643,20 +644,34 @@ UINT16 sega_315_5881_crypt_device::get_decrypted_16() dec_hist = dec; prot_cur_address ++; + return res; } + void sega_315_5881_crypt_device::enc_start() { + dec_hist = 0; // seems to be needed by astrass at least otherwise any call after the first one will be influenced by the one before it. + block_pos = 0; buffer_pos = BUFFER_SIZE; dec_header = get_decrypted_16() << 16; dec_header |= get_decrypted_16(); + // the lower header bits are 2 values that multiply together to get the current stream length + // in astrass the first block is 0xffff (for a 0x10000 block) followed by 0x3f3f (for a 0x1000 block) + // etc. after each block a new header must be read, it looks like compressed and uncompressed blocks + // can be mixed like this, I don't know if the length is src length of decompressed length. + int blockx = ((dec_header & 0x00ff) >> 0) + 1; + int blocky = ((dec_header & 0xff00) >> 8) + 1; + block_size = blockx * blocky; + if(dec_header & FLAG_COMPRESSED) { line_buffer_size = dec_header & FLAG_LINE_SIZE_512 ? 512 : 256; line_buffer_pos = line_buffer_size; buffer_bit = 7; } + +// printf("header %08x\n", dec_header); enc_ready = true; } @@ -667,6 +682,14 @@ void sega_315_5881_crypt_device::enc_fill() UINT16 val = get_decrypted_16(); buffer[i] = val; buffer[i+1] = val >> 8; + block_pos+=2; + if (block_pos == block_size) + { + // if we reach the size specified we need to read a new header + // todo: how should this work with compressed blocks?? + + enc_start(); + } } buffer_pos = 0; } diff --git a/src/mame/machine/315-5881_crypt.h b/src/mame/machine/315-5881_crypt.h index 6b73ffd0700..46862165342 100644 --- a/src/mame/machine/315-5881_crypt.h +++ b/src/mame/machine/315-5881_crypt.h @@ -40,7 +40,7 @@ protected: private: enum { - BUFFER_SIZE = 32768, LINE_SIZE = 512, + BUFFER_SIZE = 32768*8, LINE_SIZE = 512*8, FLAG_COMPRESSED = 0x10000, FLAG_LINE_SIZE_512 = 0x20000 }; @@ -54,6 +54,8 @@ private: bool enc_ready; int buffer_pos, line_buffer_pos, line_buffer_size, buffer_bit; + int block_size; + int block_pos; struct sbox { UINT8 table[64];