// license:BSD-3-Clause
// copyright-holders:Luca Elia, David Haywood
#include "emu.h"
#include "machine/jalcrpt.h"
void phantasm_rom_decode(running_machine &machine, const char *region)
{
uint16_t *RAM = (uint16_t *) machine.root_device().memregion(region)->base();
int i, size = machine.root_device().memregion(region)->bytes();
if (size > 0x40000) size = 0x40000;
for (i = 0 ; i < size/2 ; i++)
{
uint16_t x,y;
x = RAM[i];
// [0] def0 189a bc56 7234
// [1] fdb9 7531 eca8 6420
// [2] 0123 4567 ba98 fedc
#define BITSWAP_0 bitswap<16>(x,0xd,0xe,0xf,0x0,0x1,0x8,0x9,0xa,0xb,0xc,0x5,0x6,0x7,0x2,0x3,0x4)
#define BITSWAP_1 bitswap<16>(x,0xf,0xd,0xb,0x9,0x7,0x5,0x3,0x1,0xe,0xc,0xa,0x8,0x6,0x4,0x2,0x0)
#define BITSWAP_2 bitswap<16>(x,0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0xb,0xa,0x9,0x8,0xf,0xe,0xd,0xc)
if (i < 0x08000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_0;} else {y = BITSWAP_1;} }
else if (i < 0x10000/2) { y = BITSWAP_2; }
else if (i < 0x18000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_0;} else {y = BITSWAP_1;} }
else if (i < 0x20000/2) { y = BITSWAP_1; }
else { y = BITSWAP_2; }
#undef BITSWAP_0
#undef BITSWAP_1
#undef BITSWAP_2
RAM[i] = y;
}
}
void astyanax_rom_decode(running_machine &machine, const char *region)
{
uint16_t *RAM = (uint16_t *) machine.root_device().memregion(region)->base();
int i, size = machine.root_device().memregion(region)->bytes();
if (size > 0x40000) size = 0x40000;
for (i = 0 ; i < size/2 ; i++)
{
uint16_t x,y;
x = RAM[i];
// [0] def0 a981 65cb 7234
// [1] fdb9 7531 8ace 0246
// [2] 4567 0123 ba98 fedc
#define BITSWAP_0 bitswap<16>(x,0xd,0xe,0xf,0x0,0xa,0x9,0x8,0x1,0x6,0x5,0xc,0xb,0x7,0x2,0x3,0x4)
#define BITSWAP_1 bitswap<16>(x,0xf,0xd,0xb,0x9,0x7,0x5,0x3,0x1,0x8,0xa,0xc,0xe,0x0,0x2,0x4,0x6)
#define BITSWAP_2 bitswap<16>(x,0x4,0x5,0x6,0x7,0x0,0x1,0x2,0x3,0xb,0xa,0x9,0x8,0xf,0xe,0xd,0xc)
if (i < 0x08000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_0;} else {y = BITSWAP_1;} }
else if (i < 0x10000/2) { y = BITSWAP_2; }
else if (i < 0x18000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_0;} else {y = BITSWAP_1;} }
else if (i < 0x20000/2) { y = BITSWAP_1; }
else { y = BITSWAP_2; }
#undef BITSWAP_0
#undef BITSWAP_1
#undef BITSWAP_2
RAM[i] = y;
}
}
void rodland_rom_decode(running_machine &machine, const char *region)
{
uint16_t *RAM = (uint16_t *) machine.root_device().memregion(region)->base();
int i, size = machine.root_device().memregion(region)->bytes();
if (size > 0x40000) size = 0x40000;
for (i = 0 ; i < size/2 ; i++)
{
uint16_t x,y;
x = RAM[i];
// [0] d0a9 6ebf 5c72 3814 [1] 4567 0123 ba98 fedc
// [2] fdb9 ce07 5318 a246 [3] 4512 ed3b a967 08fc
#define BITSWAP_0 bitswap<16>(x,0xd,0x0,0xa,0x9,0x6,0xe,0xb,0xf,0x5,0xc,0x7,0x2,0x3,0x8,0x1,0x4);
#define BITSWAP_1 bitswap<16>(x,0x4,0x5,0x6,0x7,0x0,0x1,0x2,0x3,0xb,0xa,0x9,0x8,0xf,0xe,0xd,0xc);
#define BITSWAP_2 bitswap<16>(x,0xf,0xd,0xb,0x9,0xc,0xe,0x0,0x7,0x5,0x3,0x1,0x8,0xa,0x2,0x4,0x6);
#define BITSWAP_3 bitswap<16>(x,0x4,0x5,0x1,0x2,0xe,0xd,0x3,0xb,0xa,0x9,0x6,0x7,0x0,0x8,0xf,0xc);
if (i < 0x08000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_0;} else {y = BITSWAP_1;} }
else if (i < 0x10000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_2;} else {y = BITSWAP_3;} }
else if (i < 0x18000/2) { if ( (i | (0x248/2)) != i ) {y = BITSWAP_0;} else {y = BITSWAP_1;} }
else if (i < 0x20000/2) { y = BITSWAP_1; }
else { y = BITSWAP_3; }
#undef BITSWAP_0
#undef BITSWAP_1
#undef BITSWAP_2
#undef BITSWAP_3
RAM[i] = y;
}
}
/********** DECRYPT **********/
/* 4 known types */
/* SS91022-10: desertwr, gratiaa, tp2m32, gametngk */
/* SS92046_01: bbbxing, f1superb, tetrisp, hayaosi2 */
/* SS92047-01: gratia, kirarast */
/* SS92048-01: p47aces, 47pie2, 47pie2o */
void decrypt_ms32_tx(running_machine &machine, int addr_xor,int data_xor, const char *region)
{
int i;
uint8_t *source_data;
int source_size;
source_data = machine.root_device().memregion ( region )->base();
source_size = machine.root_device().memregion( region )->bytes();
std::vector<uint8_t> result_data(source_size);
addr_xor ^= 0x1005d;
for(i=0; i<source_size; i++)
{
int j;
/* two groups of cascading XORs for the address */
j = 0;
i ^= addr_xor;
if (BIT(i,18)) j ^= 0x40000; // 18
if (BIT(i,17)) j ^= 0x60000; // 17
if (BIT(i, 7)) j ^= 0x70000; // 16
if (BIT(i, 3)) j ^= 0x78000; // 15
if (BIT(i,14)) j ^= 0x7c000; // 14
if (BIT(i,13)) j ^= 0x7e000; // 13
if (BIT(i, 0)) j ^= 0x7f000; // 12
if (BIT(i,11)) j ^= 0x7f800; // 11
if (BIT(i,10)) j ^= 0x7fc00; // 10
if (BIT(i, 9)) j ^= 0x00200; // 9
if (BIT(i, 8)) j ^= 0x00300; // 8
if (BIT(i,16)) j ^= 0x00380; // 7
if (BIT(i, 6)) j ^= 0x003c0; // 6
if (BIT(i,12)) j ^= 0x003e0; // 5
if (BIT(i, 4)) j ^= 0x003f0; // 4
if (BIT(i,15)) j ^= 0x003f8; // 3
if (BIT(i, 2)) j ^= 0x003fc; // 2
if (BIT(i, 1)) j ^= 0x003fe; // 1
if (BIT(i, 5)) j ^= 0x003ff; // 0
i ^= addr_xor;
/* simple XOR for the data */
result_data[i] = source_data[j] ^ (i & 0xff) ^ data_xor;
}
memcpy (source_data, &result_data[0], source_size);
}
void decrypt_ms32_bg(running_machine &machine, int addr_xor,int data_xor, const char *region)
{
int i;
uint8_t *source_data;
int source_size;
source_data = machine.root_device().memregion ( region )->base();
source_size = machine.root_device().memregion( region )->bytes();
std::vector<uint8_t> result_data(source_size);
addr_xor ^= 0xc1c5b;
for(i=0; i<source_size; i++)
{
int j;
/* two groups of cascading XORs for the address */
j = (i & ~0xfffff); /* top bits are not affected */
i ^= addr_xor;
if (BIT(i,19)) j ^= 0x80000; // 19
if (BIT(i, 8)) j ^= 0xc0000; // 18
if (BIT(i,17)) j ^= 0xe0000; // 17
if (BIT(i, 2)) j ^= 0xf0000; // 16
if (BIT(i,15)) j ^= 0xf8000; // 15
if (BIT(i,14)) j ^= 0xfc000; // 14
if (BIT(i,13)) j ^= 0xfe000; // 13
if (BIT(i,12)) j ^= 0xff000; // 12
if (BIT(i, 1)) j ^= 0xff800; // 11
if (BIT(i,10)) j ^= 0xffc00; // 10
if (BIT(i, 9)) j ^= 0x00200; // 9
if (BIT(i, 3)) j ^= 0x00300; // 8
if (BIT(i, 7)) j ^= 0x00380; // 7
if (BIT(i, 6)) j ^= 0x003c0; // 6
if (BIT(i, 5)) j ^= 0x003e0; // 5
if (BIT(i, 4)) j ^= 0x003f0; // 4
if (BIT(i,18)) j ^= 0x003f8; // 3
if (BIT(i,16)) j ^= 0x003fc; // 2
if (BIT(i,11)) j ^= 0x003fe; // 1
if (BIT(i, 0)) j ^= 0x003ff; // 0
i ^= addr_xor;
/* simple XOR for the data */
result_data[i] = source_data[j] ^ (i & 0xff) ^ data_xor;
}
memcpy (source_data, &result_data[0], source_size);
}