#include "driver.h"
//#include "vidhrdw/generic.h"
#include "vidhrdw/konamiic.h"
#include "machine/eeprom.h"
//#include "cpu/m68000/m68000.h"
//#include "cpu/z80/z80.h"



int xmen_vh_start(void);
void xmen_vh_stop(void);
void xmen_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);


static int K052109_halfword_r(int offset)
{
	return K052109_r(offset >> 1);
}

static void K052109_halfword_w(int offset,int data)
{
	if ((data & 0x00ff0000) == 0)
		K052109_w(offset >> 1,data & 0xff);
}

static void K053251_halfword_w(int offset,int data)
{
	if ((data & 0x00ff0000) == 0)
		K053251_w(offset >> 1,data & 0xff);
}



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

  EEPROM

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

static int init_eeprom_count;


static struct EEPROM_interface eeprom_interface =
{
	7,				/* address bits */
	8,				/* data bits */
	"011000",		/*  read command */
	"011100",		/* write command */
	0,				/* erase command */
	"0100000000000",/* lock command */
	"0100110000000" /* unlock command */
};

static void eeprom_init(void)
{
	EEPROM_init(&eeprom_interface);
	init_eeprom_count = 0;
}

static int eeprom_r(int offset)
{
	int res;

if (errorlog) fprintf(errorlog,"%06x eeprom_r\n",cpu_get_pc());
	/* bit 6 is EEPROM data */
	/* bit 7 is EEPROM ready */
	/* bit 14 is service button */
	res = (EEPROM_read_bit() << 6) | input_port_2_r(0);
	if (init_eeprom_count)
	{
		init_eeprom_count--;
		res &= 0xbfff;
	}
	return res;
}

static void eeprom_w(int offset,int data)
{
if (errorlog) fprintf(errorlog,"%06x: write %04x to 108000\n",cpu_get_pc(),data);
	if ((data & 0x00ff0000) == 0)
	{
		/* bit 0 = coin counter */
		coin_counter_w(0,data & 0x01);

		/* bit 2 is data */
		/* bit 3 is clock (active high) */
		/* bit 4 is cs (active low) */
		EEPROM_write_bit(data & 0x04);
		EEPROM_set_cs_line((data & 0x10) ? CLEAR_LINE : ASSERT_LINE);
		EEPROM_set_clock_line((data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
	}
	else
	{
		/* bit 8 = enable sprite ROM reading */
		K053246_set_OBJCHA_line((data & 0x0100) ? ASSERT_LINE : CLEAR_LINE);
		/* bit 9 = enable char ROM reading through the video RAM */
		K052109_set_RMRD_line((data & 0x0200) ? ASSERT_LINE : CLEAR_LINE);
	}
}

static int xmen_sound_r(int offset)
{
	/* fake self test pass until we emulate the sound chip */
	return 0x000f;
}

static void xmen_sound_w(int offset,int data)
{
	if (offset == 0)
	{
		if ((data & 0x00ff0000) == 0)
			soundlatch_w(0,data & 0xff);
	}
	if (offset == 2) cpu_cause_interrupt(1,0xff);
}

static void xmen_18fa00_w(int offset,int data)
{
	/* bit 2 is interrupt enable */
	interrupt_enable_w(0,data & 0x04);
}

static void sound_bankswitch(int offset,int data)
{
	int bankaddress;
	unsigned char *RAM = memory_region(Machine->drv->cpu[1].memory_region);


	bankaddress = 0x10000 + (data & 0x07) * 0x4000;
	cpu_setbank(4,&RAM[bankaddress]);
}



static struct MemoryReadAddress readmem[] =
{
	{ 0x000000, 0x03ffff, MRA_ROM },
	{ 0x080000, 0x0fffff, MRA_ROM },
	{ 0x100000, 0x100fff, K053247_word_r },
	{ 0x101000, 0x101fff, MRA_BANK2 },
	{ 0x104000, 0x104fff, paletteram_word_r },
	{ 0x108054, 0x108055, xmen_sound_r },
	{ 0x10a000, 0x10a001, input_port_0_r },
	{ 0x10a002, 0x10a003, input_port_1_r },
	{ 0x10a004, 0x10a005, eeprom_r },
	{ 0x10a00c, 0x10a00d, K053246_word_r },
	{ 0x110000, 0x113fff, MRA_BANK1 },	/* main RAM */
	{ 0x18c000, 0x197fff, K052109_halfword_r },
	{ -1 }	/* end of table */
};

static struct MemoryWriteAddress writemem[] =
{
	{ 0x000000, 0x03ffff, MWA_ROM },
	{ 0x080000, 0x0fffff, MWA_ROM },
	{ 0x100000, 0x100fff, K053247_word_w },
	{ 0x101000, 0x101fff, MWA_BANK2 },
	{ 0x104000, 0x104fff, paletteram_xBBBBBGGGGGRRRRR_word_w, &paletteram },
	{ 0x108000, 0x108001, eeprom_w },
	{ 0x108020, 0x108027, K053246_word_w },
	{ 0x10804c, 0x10804f, xmen_sound_w },
	{ 0x108060, 0x10807f, K053251_halfword_w },
	{ 0x10a000, 0x10a001, watchdog_reset_w },
	{ 0x110000, 0x113fff, MWA_BANK1 },	/* main RAM */
	{ 0x18fa00, 0x18fa01, xmen_18fa00_w },
	{ 0x18c000, 0x197fff, K052109_halfword_w },
	{ -1 }	/* end of table */
};

static struct MemoryReadAddress sound_readmem[] =
{
	{ 0x0000, 0x7fff, MRA_ROM },
	{ 0x8000, 0xbfff, MRA_BANK4 },
	{ 0xc000, 0xdfff, MRA_RAM },
	{ 0xec01, 0xec01, YM2151_status_port_0_r },
	{ 0xf002, 0xf002, soundlatch_r },
	{ -1 }	/* end of table */
};

static struct MemoryWriteAddress sound_writemem[] =
{
	{ 0x0000, 0xbfff, MWA_ROM },
	{ 0xc000, 0xdfff, MWA_RAM },
	{ 0xe800, 0xe800, YM2151_register_port_0_w },
	{ 0xec01, 0xec01, YM2151_data_port_0_w },
//	{ 0xf000, 0xf000, soundlatch2_w },	/* to main cpu */
	{ 0xf800, 0xf800, sound_bankswitch },
	{ -1 }	/* end of table */
};



INPUT_PORTS_START( xmen )
	PORT_START	/* IN1 */
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER4 )
	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER4 )
	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER4 )
	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN4 )

	PORT_START	/* IN0 */
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER1 )
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER3 )
	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER3 )
	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER3 )
	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN3 )

	PORT_START	/* COIN  EEPROM and service */
	PORT_BIT( 0x003f, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* unused? */
	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN )	/* EEPROM data */
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* EEPROM status - always 1 */
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START3 )
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START4 )
	PORT_BIT( 0x3000, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* unused? */
	PORT_BITX(0x4000, IP_ACTIVE_LOW, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE )
	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* unused? */
INPUT_PORTS_END

INPUT_PORTS_START( xmen2p )
	PORT_START	/* IN1 */
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN2 )
/*
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER4 )
	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER4 )
	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER4 )
	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER4 )
	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN4 )
*/

	PORT_START	/* IN0 */
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER1 )
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER1 )
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN1 )
/*
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER3 )
	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER3 )
	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER3 )
	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER3 )
	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN3 )
*/

	PORT_START	/* COIN  EEPROM and service */
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN3 )
	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN4 )
	PORT_BIT( 0x003c, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* unused? */
	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN )	/* EEPROM data */
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* EEPROM status - always 1 */
	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x3000, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* unused? */
	PORT_BITX(0x4000, IP_ACTIVE_LOW, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE )
	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )	/* unused? */
INPUT_PORTS_END



static struct YM2151interface ym2151_interface =
{
	1,			/* 1 chip */
	3579545,	/* 3.579545 MHz */
	{ YM3012_VOL(100,MIXER_PAN_LEFT,100,MIXER_PAN_RIGHT) },
	{ 0 }
};



static int xmen_interrupt(void)
{
	if (cpu_getiloops() == 0) return m68_level5_irq();
	else return m68_level3_irq();
}

static struct MachineDriver xmen_machine_driver =
{
	/* basic machine hardware */
	{
		{
			CPU_M68000,
			16000000,	/* ? */
			0,
			readmem,writemem,0,0,
			xmen_interrupt,2
		},
		{
			CPU_Z80 | CPU_AUDIO_CPU,
			2*3579545,	/* ????? */
			3,
			sound_readmem,sound_writemem,0,0,
			ignore_interrupt,0	/* IRQs are triggered by the main CPU */
		}
	},
	60, DEFAULT_60HZ_VBLANK_DURATION,	/* frames per second, vblank duration */
	1,	/* 1 CPU slice per frame - interleaving is forced when a sound command is written */
	eeprom_init,

	/* video hardware */
	64*8, 32*8, { 14*8, (64-14)*8-1, 2*8, 30*8-1 },
	0,	/* gfx decoded by konamiic.c */
	2048, 2048,
	0,

	VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
	0,
	xmen_vh_start,
	xmen_vh_stop,
	xmen_vh_screenrefresh,

	/* sound hardware */
	SOUND_SUPPORTS_STEREO,0,0,0,
	{
		{
			SOUND_YM2151,
			&ym2151_interface
		}
	}
};



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

  Game driver(s)

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

ROM_START( xmen )
    ROM_REGION(0x100000)
    ROM_LOAD_EVEN( "065ubb04.10d",  0x00000, 0x20000, 0xf896c93b )
    ROM_LOAD_ODD ( "065ubb05.10f",  0x00000, 0x20000, 0xe02e5d64 )
    ROM_LOAD_EVEN( "xmen17g.bin",   0x80000, 0x40000, 0xb31dc44c )
    ROM_LOAD_ODD ( "xmen17j.bin",   0x80000, 0x40000, 0x13842fe6 )

    ROM_REGION(0x200000)	/* graphics (addressable by the main CPU) */
    ROM_LOAD( "xmen1l.bin",   0x000000, 0x100000, 0x6b649aca )	/* tiles */
    ROM_LOAD( "xmen1h.bin",   0x100000, 0x100000, 0xc5dc8fc4 )

	ROM_REGION(0x400000)	/* graphics (addressable by the main CPU) */
    ROM_LOAD( "xmen12l.bin",  0x000000, 0x100000, 0xea05d52f )	/* sprites */
    ROM_LOAD( "xmen17l.bin",  0x100000, 0x100000, 0x96b91802 )
    ROM_LOAD( "xmen22h.bin",  0x200000, 0x100000, 0x321ed07a )
    ROM_LOAD( "xmen22l.bin",  0x300000, 0x100000, 0x46da948e )

    ROM_REGION(0x30000)		/* 64k+128k fpr sound cpu */
    ROM_LOAD( "065-a01.6f",   0x00000, 0x20000, 0x147d3a4d )
	ROM_RELOAD(               0x10000, 0x20000 )

    ROM_REGION(0x200000)	/* samples for the 054544 */
    ROM_LOAD( "xmenc25.bin",  0x000000, 0x200000, 0x5adbcee0 )
ROM_END

ROM_START( xmen6p )
    ROM_REGION(0x100000)
    ROM_LOAD_EVEN( "xmenb04.bin",   0x00000, 0x20000, 0x0f09b8e0 )
    ROM_LOAD_ODD ( "xmenb05.bin",   0x00000, 0x20000, 0x867becbf )
    ROM_LOAD_EVEN( "xmen17g.bin",   0x80000, 0x40000, 0xb31dc44c )
    ROM_LOAD_ODD ( "xmen17j.bin",   0x80000, 0x40000, 0x13842fe6 )

    ROM_REGION(0x200000)	/* graphics (addressable by the main CPU) */
    ROM_LOAD( "xmen1l.bin",   0x000000, 0x100000, 0x6b649aca )	/* tiles */
    ROM_LOAD( "xmen1h.bin",   0x100000, 0x100000, 0xc5dc8fc4 )

	ROM_REGION(0x400000)	/* graphics (addressable by the main CPU) */
    ROM_LOAD( "xmen12l.bin",  0x000000, 0x100000, 0xea05d52f )	/* sprites */
    ROM_LOAD( "xmen17l.bin",  0x100000, 0x100000, 0x96b91802 )
    ROM_LOAD( "xmen22h.bin",  0x200000, 0x100000, 0x321ed07a )
    ROM_LOAD( "xmen22l.bin",  0x300000, 0x100000, 0x46da948e )

    ROM_REGION(0x30000)		/* 64k+128k fpr sound cpu */
    ROM_LOAD( "065-a01.6f",   0x00000, 0x20000, 0x147d3a4d )
	ROM_RELOAD(               0x10000, 0x20000 )

    ROM_REGION(0x200000)	/* samples for the 054544 */
    ROM_LOAD( "xmenc25.bin",  0x000000, 0x200000, 0x5adbcee0 )
ROM_END

ROM_START( xmen2pj )
    ROM_REGION(0x100000)
    ROM_LOAD_EVEN( "065jaa04.10d",  0x00000, 0x20000, 0x66746339 )
    ROM_LOAD_ODD ( "065jaa05.10f",  0x00000, 0x20000, 0x1215b706 )
    ROM_LOAD_EVEN( "xmen17g.bin",   0x80000, 0x40000, 0xb31dc44c )
    ROM_LOAD_ODD ( "xmen17j.bin",   0x80000, 0x40000, 0x13842fe6 )

    ROM_REGION(0x200000)	/* graphics (addressable by the main CPU) */
    ROM_LOAD( "xmen1l.bin",   0x000000, 0x100000, 0x6b649aca )	/* tiles */
    ROM_LOAD( "xmen1h.bin",   0x100000, 0x100000, 0xc5dc8fc4 )

	ROM_REGION(0x400000)	/* graphics (addressable by the main CPU) */
    ROM_LOAD( "xmen12l.bin",  0x000000, 0x100000, 0xea05d52f )	/* sprites */
    ROM_LOAD( "xmen17l.bin",  0x100000, 0x100000, 0x96b91802 )
    ROM_LOAD( "xmen22h.bin",  0x200000, 0x100000, 0x321ed07a )
    ROM_LOAD( "xmen22l.bin",  0x300000, 0x100000, 0x46da948e )

    ROM_REGION(0x30000)		/* 64k+128k fpr sound cpu */
    ROM_LOAD( "065-a01.6f",   0x00000, 0x20000, 0x147d3a4d )
	ROM_RELOAD(               0x10000, 0x20000 )

    ROM_REGION(0x200000)	/* samples for the 054544 */
    ROM_LOAD( "xmenc25.bin",  0x000000, 0x200000, 0x5adbcee0 )
ROM_END



static void gfx_untangle(void)
{
	konami_rom_deinterleave_2(1);
	konami_rom_deinterleave_4(2);
}


static int nvram_load(void)
{
	void *f;

	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,0)) != 0)
	{
		EEPROM_load(f);
		osd_fclose(f);
	}
	else
		init_eeprom_count = 10;

	return 1;
}

static void nvram_save(void)
{
	void *f;

	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,1)) != 0)
	{
		EEPROM_save(f);
		osd_fclose(f);
	}
}



struct GameDriver driver_xmen =
{
	__FILE__,
	0,
	"xmen",
	"X-Men (4 Players)",
	"1992",
	"Konami",
	"Nicola Salmoria (MAME driver)\nAlex Pasadyn (MAME driver)\nJeff Slutter (hardware info)\nHowie Cohen (hardware info)",
	0,
	&xmen_machine_driver,
	0,

	rom_xmen,
	gfx_untangle, 0,
	0,
	0,

	input_ports_xmen,

	0, 0, 0,
	ORIENTATION_DEFAULT | GAME_IMPERFECT_SOUND,

	nvram_load, nvram_save
};

static void xmen6p_patch(void)
{
	unsigned char *RAM = memory_region(Machine->drv->cpu[0].memory_region);

	WRITE_WORD(&RAM[0x21a6],0x4e71);
	WRITE_WORD(&RAM[0x21a8],0x4e71);
	WRITE_WORD(&RAM[0x21aa],0x4e71);

	gfx_untangle();
}

struct GameDriver driver_xmen6p =
{
	__FILE__,
	&driver_xmen,
	"xmen6p",
	"X-Men (6 Players)",
	"1992",
	"Konami",
	"Nicola Salmoria (MAME driver)\nAlex Pasadyn (MAME driver)\nJeff Slutter (hardware info)\nHowie Cohen (hardware info)",
	0,
	&xmen_machine_driver,
	0,

	rom_xmen6p,
	xmen6p_patch, 0,
	0,
	0,

	input_ports_xmen,

	0, 0, 0,
	ORIENTATION_DEFAULT | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING,

	nvram_load, nvram_save
};

struct GameDriver driver_xmen2pj =
{
	__FILE__,
	&driver_xmen,
	"xmen2pj",
	"X-Men (2 Players Japan)",
	"1992",
	"Konami",
	"Nicola Salmoria (MAME driver)\nAlex Pasadyn (MAME driver)\nJeff Slutter (hardware info)\nHowie Cohen (hardware info)",
	0,
	&xmen_machine_driver,
	0,

	rom_xmen2pj,
	gfx_untangle, 0,
	0,
	0,

	input_ports_xmen2p,

	0, 0, 0,
	ORIENTATION_DEFAULT | GAME_IMPERFECT_SOUND,

	nvram_load, nvram_save
};
