summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/wrally.c
blob: a7e2927dd3ea614e9a19dad229fe2ef45e107800 (plain) (tree)

























































































































































                                                                                      
/***************************************************************************

    World Rally

    Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
    I/O ports)

***************************************************************************/

#include "driver.h"

UINT16 *wrally_encr_table[2];

/***************************************************************************

    World Rally Video RAM encryption

***************************************************************************/

static int subxor1(int data,int res)
{
	res ^= 0x0002;
	if (BIT(data,0) ^ !BIT(data,5))
	{
		res ^= 0x0800;
		if (BIT(data,2) ^ BIT(data,3)) res ^= 0x0001;
		if (BIT(data,6) && !BIT(data,11) && BIT(data,5)) res ^= 0x0001;
	}

	return res;
}

static int subxor2(int data,int res)
{
	res ^= 0x0020;
	if (BIT(data,8) ^ !BIT(data,5))
	{
		res ^= 0x0008;
		if (BIT(data,4) ^ BIT(data,3)) res ^= 0x0100;
		if (BIT(data,6) && !BIT(data,11) && BIT(data,5)) res ^= 0x0100;
	}

	return res;
}

static int wrally_decode_vram(int data)
{
	int res = 0;


	res = BITSWAP16(data,5,7,9,12,2,14,13,15,3,6,8,11,4,10,0,1);

	res ^= 0x0062;

	if (BIT(data,9))  res ^= 0x5004;

	if ( BIT(data,5) ^ (!BIT(data,9) &&  BIT(data,7)))  res ^= 0x0200;
	if (!BIT(data,5) ^ (!BIT(data,9) &&  BIT(data,12))) res ^= 0x0400;

	if (BIT(data,3) ^ BIT(data,6))  res ^= 0x0101;

	if (BIT(data,3) ^ BIT(data,5))
	{
		res ^= 0x0808;
		if (BIT(data,2) ^ BIT(data,3)) res ^= 0x0001;
		if (BIT(data,4) ^ BIT(data,3)) res ^= 0x0100;
	}

	if ((BIT(data,9) && !BIT(data,10)) || BIT(data,5))
	{
		res ^= 0x0010;

		if (!BIT(data,11)) res ^= 0x0141;

		if (BIT(data,6) && !BIT(data,11))
		{
			res ^= 0x0888;
			if (!BIT(data,2)) res ^= 0x0001;
			if (!BIT(data,4)) res ^= 0x0100;
		}
	}

	if (BIT(data,9) && !BIT(data,10))
	{
		res ^= 0x8600;
		if (!BIT(data,14)) res = subxor1(data,res);
		if (!BIT(data,5))  res = subxor2(data,res);

		if (BIT(data,6) && !BIT(data,11))
		{
			if (BIT(data,0) && !BIT(data,5)) res ^= 0x0001;
			if (BIT(data,8) && !BIT(data,5)) res ^= 0x0100;
		}
	}

	if (BIT(data,5) ^  BIT(data,14))
	{
		if ( BIT(data,14))                 res = subxor1(data,res);
		if (!BIT(data,9) &&  BIT(data,12)) res = subxor1(data,res);
	}

	if (BIT(data,5) ^ !BIT(data,13))
	{
		if ( BIT(data,5))                  res = subxor2(data,res);
		if ( BIT(data,9) &&  BIT(data,10)) res = subxor2(data,res);
		if (!BIT(data,9) && !BIT(data,7))  res = subxor2(data,res);
	}

	return res;
}

/***************************************************************************

    World Rally memory handlers

***************************************************************************/

WRITE16_HANDLER( OKIM6295_bankswitch_w )
{
	UINT8 *RAM = memory_region(REGION_SOUND1);

	if (ACCESSING_LSB){
		memcpy(&RAM[0x30000], &RAM[0x40000 + (data & 0x0f)*0x10000], 0x10000);
	}
}

WRITE16_HANDLER( wrally_coin_counter_w )
{
	coin_counter_w( (offset >> 3) & 0x01, data & 0x01);
}

WRITE16_HANDLER( wrally_coin_lockout_w )
{
	coin_lockout_w( (offset >> 3) & 0x01, ~data & 0x01);
}

/***************************************************************************

    World Rally init machine

***************************************************************************/

DRIVER_INIT( wrally )
{
	int i;

	/* recreate encryption tables on start up */
	wrally_encr_table[0] = (UINT16 *)auto_malloc(0x10000*2);
	wrally_encr_table[1] = (UINT16 *)auto_malloc(0x10000*2);
	for (i = 0; i < 0x10000; i++){
		wrally_encr_table[0][i] = wrally_decode_vram(i);
		wrally_encr_table[1][i] = wrally_decode_vram(i);
	}
}