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

	CPS-2

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

#include "driver.h"
#include "deprecat.h"
#include "machine/eeprom.h"
#include "cpu/m68000/m68000.h"
#include "sound/qsound.h"
#include "chd.h"

#include "cps1.h"       /* External CPS1 definitions */

/*
Export this function so that the video routine can drive the
Q-Sound hardware
*/
#ifdef UNUSED_FUNCTION
WRITE16_HANDLER( cps2_qsound_sharedram_w )
{
    qsound_sharedram1_w(offset/2, data, 0xff00);
}
#endif


/*************************************
 *
 *  Constants
 *
 *************************************/

/* Maximum size of Q Sound Z80 region */
#define QSOUND_SIZE 0x50000

/* Maximum 680000 code size */
#undef  CODE_SIZE
#define CODE_SIZE   0x0400000


/*************************************
 *
 *  Global variables
 *
 *************************************/

static int readpaddle;
static int cps2networkpresent;


/*************************************
 *
 *  Interrupt generation
 *
 *************************************/

static INTERRUPT_GEN( cps2_interrupt )
{
	static int scancount;

	/* 2 is vblank, 4 is some sort of scanline interrupt, 6 is both at the same time. */

	if(scancount >= 261)
	{
		scancount = -1;
		cps1_scancalls = 0;
	}
	scancount++;

	if (cps1_cps_b_regs[0x10/2] & 0x8000)
		cps1_cps_b_regs[0x10/2] = cps1_cps_b_regs[0x10/2] & 0x1ff;
	if (cps1_cps_b_regs[0x12/2] & 0x8000)
		cps1_cps_b_regs[0x12/2] = cps1_cps_b_regs[0x12/2] & 0x1ff;

//  popmessage("%04x %04x - %04x %04x",cps1_scanline1,cps1_scanline2,cps1_cps_b_regs[0x10/2],cps1_cps_b_regs[0x12/2]);

	/* raster effects */
	if(cps1_scanline1 == scancount || (cps1_scanline1 < scancount && !cps1_scancalls))
	{
		cps1_cps_b_regs[0x10/2] = 0;
		cpunum_set_input_line(machine, 0, 4, HOLD_LINE);
		cps2_set_sprite_priorities();
		video_screen_update_partial(machine->primary_screen, 16 - 10 + scancount);	/* visarea.min_y - [first visible line?] + scancount */
		cps1_scancalls++;
//          popmessage("IRQ4 scancounter = %04i",scancount);
	}

	/* raster effects */
	if(cps1_scanline2 == scancount || (cps1_scanline2 < scancount && !cps1_scancalls))
	{
		cps1_cps_b_regs[0x12/2] = 0;
		cpunum_set_input_line(machine, 0, 4, HOLD_LINE);
		cps2_set_sprite_priorities();
		video_screen_update_partial(machine->primary_screen, 16 - 10 + scancount);	/* visarea.min_y - [first visible line?] + scancount */
		cps1_scancalls++;
//          popmessage("IRQ4 scancounter = %04i",scancount);
	}

	if(scancount == 256)  /* VBlank */
	{
		cps1_cps_b_regs[0x10/2] = cps1_scanline1;
		cps1_cps_b_regs[0x12/2] = cps1_scanline2;
		cpunum_set_input_line(machine, 0, 2, HOLD_LINE);
		if(cps1_scancalls)
		{
			cps2_set_sprite_priorities();
			video_screen_update_partial(machine->primary_screen, 256);
		}
		cps2_objram_latch();
	}
	//popmessage("Raster calls = %i",cps1_scancalls);
}


/*************************************
 *
 *  EEPROM
 *
 *************************************/

static const eeprom_interface cps2_eeprom_interface =
{
	6,		/* address bits */
	16,		/* data bits */
	"0110",	/*  read command */
	"0101",	/* write command */
	"0111"	/* erase command */
};

static NVRAM_HANDLER( cps2 )
{
	if (read_or_write)
		eeprom_save(file);
	else
	{
        eeprom_init(&cps2_eeprom_interface);

		if (file)
			eeprom_load(file);
	}
}

static WRITE16_HANDLER( cps2_eeprom_port_w )
{
    if (ACCESSING_BITS_8_15)
    {
	/* bit 0 - Unused */
	/* bit 1 - Unused */
	/* bit 2 - Unused */
	/* bit 3 - Unused? */
	/* bit 4 - Eeprom data  */
	/* bit 5 - Eeprom clock */
	/* bit 6 - */
	/* bit 7 - */

	/* EEPROM */
	eeprom_write_bit(data & 0x1000);
	eeprom_set_clock_line((data & 0x2000) ? ASSERT_LINE : CLEAR_LINE);
	eeprom_set_cs_line((data & 0x4000) ? CLEAR_LINE : ASSERT_LINE);
	}

	if (ACCESSING_BITS_0_7)
	{
	/* bit 0 - coin counter 1 */
	/* bit 0 - coin counter 2 */
	/* bit 2 - Unused */
	/* bit 3 - Allows access to Z80 address space (Z80 reset) */
	/* bit 4 - lock 1  */
	/* bit 5 - lock 2  */
	/* bit 6 - */
	/* bit 7 - */

        /* Z80 Reset */
		cpunum_set_input_line(machine, 1, INPUT_LINE_RESET, (data & 0x0008) ? CLEAR_LINE : ASSERT_LINE);

	coin_counter_w(0, data & 0x0001);
	if( (strncmp(machine->gamedrv->name,"pzloop2",8)==0) ||
 	    (strncmp(machine->gamedrv->name,"pzloop2j",8)==0) )
	{
		// Puzz Loop 2 uses coin counter 2 input to switch between stick and paddle controls
		readpaddle = data & 0x0002;
	}
	else
	{
		coin_counter_w(1, data & 0x0002);
	}

	if(strncmp(machine->gamedrv->name,"mmatrix",7)==0)		// Mars Matrix seems to require the coin lockout bit to be reversed
	{
		coin_lockout_w(0,data & 0x0010);
		coin_lockout_w(1,data & 0x0020);
		coin_lockout_w(2,data & 0x0040);
		coin_lockout_w(3,data & 0x0080);
	}
	else
	{
		coin_lockout_w(0,~data & 0x0010);
		coin_lockout_w(1,~data & 0x0020);
		coin_lockout_w(2,~data & 0x0040);
		coin_lockout_w(3,~data & 0x0080);
	}

	/*
    set_led_status(0,data & 0x01);
    set_led_status(1,data & 0x10);
    set_led_status(2,data & 0x20);
    */
    }
}


/*************************************
 *
 *  Sound ?
 *
 *************************************/

static READ16_HANDLER( cps2_qsound_volume_r )
{
	/* Extra adapter memory (0x660000-0x663fff) available when bit 14 = 0 */
	/* Network adapter (ssf2tb) present when bit 15 = 0 */
	/* Only game known to use both these so far is SSF2TB */

	if(cps2networkpresent)
		return 0x2021;
	else
		return 0xe021;
}


/*************************************
 *
 *  ???
 *
 *************************************/

static UINT8  cps2_read8(offs_t address)
{
	return m68k_read_pcrelative_8(address);
}

static UINT16 cps2_read16(offs_t address)
{
	return m68k_read_pcrelative_16(address);
}

static UINT32 cps2_read32(offs_t address)
{
	return m68k_read_pcrelative_32(address);
}


/*************************************
 *
 *  Read handlers
 *
 *************************************/

static READ16_HANDLER( kludge_r )
{
	return 0xffff;
}



/*************************************
 *
 *  Memory map
 *
 *************************************/

static ADDRESS_MAP_START( cps2_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x3fffff) AM_READ(SMH_ROM)                   /* 68000 ROM */
	AM_RANGE(0x400000, 0x40000b) AM_READ(SMH_RAM)                   /* CPS2 object output */
	AM_RANGE(0x618000, 0x619fff) AM_READ(qsound_sharedram1_r)       /* Q RAM */
	AM_RANGE(0x662000, 0x662001) AM_READ(SMH_RAM)                   /* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x662008, 0x662009) AM_READ(SMH_RAM)                   /* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x662020, 0x662021) AM_READ(SMH_RAM)                   /* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x660000, 0x663fff) AM_READ(SMH_RAM)                   /* When bit 14 of 0x804030 equals 0 this space is available. Many games store highscores and other info here if available. */
	AM_RANGE(0x664000, 0x664001) AM_READ(SMH_RAM)                   /* Unknown - Only used if 0x660000-0x663fff available (could be RAM enable?) */
	AM_RANGE(0x700000, 0x701fff) AM_READ(cps2_objram1_r)			/* misfitmame - Object RAM, used by Razoola Suicide tester */
	AM_RANGE(0x708000, 0x709fff) AM_READ(cps2_objram2_r)            /* Object RAM */
	AM_RANGE(0x70a000, 0x70bfff) AM_READ(cps2_objram2_r)            /* mirror */
	AM_RANGE(0x70c000, 0x70dfff) AM_READ(cps2_objram2_r)            /* mirror */
	AM_RANGE(0x70e000, 0x70ffff) AM_READ(cps2_objram2_r)            /* mirror */
	AM_RANGE(0x800140, 0x80017f) AM_READ(cps1_cps_b_r)              /* mirror (sfa) */
	AM_RANGE(0x804000, 0x804001) AM_READ_PORT("IN0")                /* IN0 */
	AM_RANGE(0x804010, 0x804011) AM_READ_PORT("IN1")                /* IN1 */
	AM_RANGE(0x804020, 0x804021) AM_READ_PORT("IN2")                /* IN2 + EEPROM */
	AM_RANGE(0x804030, 0x804031) AM_READ(cps2_qsound_volume_r)      /* Master volume. Also when bit 14=0 addon memory is present, when bit 15=0 network adapter present. */
	AM_RANGE(0x8040b0, 0x8040b3) AM_READ(kludge_r)                  /* unknown (xmcotaj hangs if this is 0) */
	AM_RANGE(0x804140, 0x80417f) AM_READ(cps1_cps_b_r)              /* CPS-B custom */
	AM_RANGE(0x900000, 0x92ffff) AM_READ(SMH_RAM)                   /* Video RAM */
	AM_RANGE(0xff0000, 0xffffff) AM_READ(SMH_RAM)                   /* RAM */
ADDRESS_MAP_END

static ADDRESS_MAP_START( cps2_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x3fffff) AM_WRITE(SMH_ROM)                  /* ROM */
	AM_RANGE(0x400000, 0x40000b) AM_WRITE(SMH_RAM) AM_BASE(&cps2_output) AM_SIZE(&cps2_output_size)    /* CPS2 output */
	AM_RANGE(0x618000, 0x619fff) AM_WRITE(qsound_sharedram1_w)        /* Q RAM */
	AM_RANGE(0x662000, 0x662001) AM_WRITE(SMH_RAM)                  /* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x662008, 0x662009) AM_WRITE(SMH_RAM)                  /* Network adapter related, accessed in SSF2TB (not sure if this port is write only yet)*/
	AM_RANGE(0x662020, 0x662021) AM_WRITE(SMH_RAM)                  /* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x660000, 0x663fff) AM_WRITE(SMH_RAM)                  /* When bit 14 of 0x804030 equals 0 this space is available. Many games store highscores and other info here if available. */
	AM_RANGE(0x664000, 0x664001) AM_WRITE(SMH_RAM)                  /* Unknown - Only used if 0x660000-0x663fff available (could be RAM enable?) */
	AM_RANGE(0x700000, 0x701fff) AM_WRITE(cps2_objram1_w) AM_BASE(&cps2_objram1)     /* Object RAM, no game seems to use it directly */
	AM_RANGE(0x708000, 0x709fff) AM_WRITE(cps2_objram2_w) AM_BASE(&cps2_objram2)     /* Object RAM */
	AM_RANGE(0x70a000, 0x70bfff) AM_WRITE(cps2_objram2_w)             /* mirror */
	AM_RANGE(0x70c000, 0x70dfff) AM_WRITE(cps2_objram2_w)             /* mirror */
	AM_RANGE(0x70e000, 0x70ffff) AM_WRITE(cps2_objram2_w)             /* mirror */
	AM_RANGE(0x800100, 0x80013f) AM_WRITE(cps1_cps_a_w) AM_BASE(&cps1_cps_a_regs)	/* mirror (sfa) */
	AM_RANGE(0x800140, 0x80017f) AM_WRITE(cps1_cps_b_w) AM_BASE(&cps1_cps_b_regs)	/* mirror (sfa) */
	AM_RANGE(0x804040, 0x804041) AM_WRITE(cps2_eeprom_port_w)         /* EEPROM */
	AM_RANGE(0x8040a0, 0x8040a1) AM_WRITE(SMH_NOP)                  /* Unknown (reset once on startup) */
	AM_RANGE(0x8040e0, 0x8040e1) AM_WRITE(cps2_objram_bank_w)         /* bit 0 = Object ram bank swap */
	AM_RANGE(0x804100, 0x80413f) AM_WRITE(cps1_cps_a_w) AM_BASE(&cps1_cps_a_regs)	/* CPS-A custom */
	AM_RANGE(0x804140, 0x80417f) AM_WRITE(cps1_cps_b_w) AM_BASE(&cps1_cps_b_regs)	/* CPS-B custom */
	AM_RANGE(0x900000, 0x92ffff) AM_WRITE(cps1_gfxram_w) AM_BASE(&cps1_gfxram) AM_SIZE(&cps1_gfxram_size)
	AM_RANGE(0xff0000, 0xffffff) AM_WRITE(SMH_RAM)                  /* RAM */
ADDRESS_MAP_END

static ADDRESS_MAP_START( phoenix_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x3fffff) AM_WRITE(SMH_ROM)				/* ROM */
	AM_RANGE(0x618000, 0x619fff) AM_WRITE(qsound_sharedram1_w)		/* Q RAM */
	AM_RANGE(0x662000, 0x662001) AM_WRITE(SMH_RAM)				/* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x662008, 0x662009) AM_WRITE(SMH_RAM)				/* Network adapter related, accessed in SSF2TB (not sure if this port is write only yet)*/
	AM_RANGE(0x662020, 0x662021) AM_WRITE(SMH_RAM)				/* Network adapter related, accessed in SSF2TB */
	AM_RANGE(0x660000, 0x663fff) AM_WRITE(SMH_RAM)				/* When bit 14 of 0x804030 equals 0 this space is available. Many games store highscores and other info here if available. */
	AM_RANGE(0x664000, 0x664001) AM_WRITE(SMH_RAM)				/* Unknown - Only used if 0x660000-0x663fff available (could be RAM enable?) */
	AM_RANGE(0x700000, 0x701fff) AM_WRITE(cps2_objram1_w) AM_BASE(&cps2_objram1)	/* Object RAM, no game seems to use it directly */
	AM_RANGE(0x708000, 0x709fff) AM_WRITE(cps2_objram2_w) AM_BASE(&cps2_objram2)	/* Object RAM */
	AM_RANGE(0x70a000, 0x70bfff) AM_WRITE(cps2_objram2_w)			/* mirror */
	AM_RANGE(0x70c000, 0x70dfff) AM_WRITE(cps2_objram2_w)			/* mirror */
	AM_RANGE(0x70e000, 0x70ffff) AM_WRITE(cps2_objram2_w)			/* mirror */
	AM_RANGE(0x800100, 0x80013f) AM_WRITE(cps1_cps_a_w) AM_BASE(&cps1_cps_a_regs)	/* mirror (sfa) */
	AM_RANGE(0x800140, 0x80017f) AM_WRITE(cps1_cps_b_w) AM_BASE(&cps1_cps_b_regs)	/* mirror (sfa) */
	AM_RANGE(0x804040, 0x804041) AM_WRITE(cps2_eeprom_port_w)		/* EEPROM */
	AM_RANGE(0x8040a0, 0x8040a1) AM_WRITE(SMH_NOP)				/* Unknown (reset once on startup) */
	AM_RANGE(0x8040e0, 0x8040e1) AM_WRITE(cps2_objram_bank_w)		/* bit 0 = Object ram bank swap */
	AM_RANGE(0x804100, 0x80413f) AM_WRITE(cps1_cps_a_w) AM_BASE(&cps1_cps_a_regs)	/* CPS-A custom */
	AM_RANGE(0x804140, 0x80417f) AM_WRITE(cps1_cps_b_w) AM_BASE(&cps1_cps_b_regs)	/* CPS-B custom */
	AM_RANGE(0x900000, 0x92ffff) AM_WRITE(cps1_gfxram_w) AM_BASE(&cps1_gfxram) AM_SIZE(&cps1_gfxram_size)
	AM_RANGE(0xff0000, 0xffffef) AM_WRITE(SMH_RAM)				/* RAM */
	AM_RANGE(0xfffff0, 0xfffffb) AM_WRITE(SMH_RAM) AM_BASE(&cps2_output) AM_SIZE(&cps2_output_size)	/* CPS2 output */
ADDRESS_MAP_END

/*************************************
 *
 *  Generic port definitions
 *
 *************************************/

/* 4 players and 4 buttons */
static INPUT_PORTS_START( cps2_4p4b )
    PORT_START("IN0")      /* IN0 (0x00) */
    PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
    PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
    PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
    PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
    PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
    PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
    PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
    PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
    PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
    PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
    PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
    PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)

    PORT_START("IN1")      /* IN1 (0x10) */
    PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3)
    PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3)
    PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3)
    PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3)
    PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
    PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3)
    PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4)
    PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4)
    PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4)
    PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4)
    PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4)
    PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4)
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4)
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(4)

    PORT_START("IN2")      /* IN2 (0x20) */
    PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(eeprom_bit_r, NULL)
	PORT_SERVICE_NO_TOGGLE( 0x0002, IP_ACTIVE_LOW )
    PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 )
    PORT_BIT( 0x00f8, IP_ACTIVE_LOW, IPT_UNKNOWN )
    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( 0x1000, IP_ACTIVE_LOW, IPT_COIN1 )
    PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_COIN2 )
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_COIN3 )
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN4 )
INPUT_PORTS_END

/* 4 players and 3 buttons */
static INPUT_PORTS_START( cps2_4p3b )
	PORT_INCLUDE(cps2_4p4b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(1) */
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(2) */

	PORT_MODIFY("IN1")
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(3) */
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(4) */
INPUT_PORTS_END

/* 4 players and 2 buttons */
static INPUT_PORTS_START( cps2_4p2b )
	PORT_INCLUDE(cps2_4p3b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(1) */
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(2) */

	PORT_MODIFY("IN1")
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(3) */
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(4) */
INPUT_PORTS_END

/* 3 players and 4 buttons */
static INPUT_PORTS_START( cps2_3p4b )
	PORT_INCLUDE(cps2_4p4b)

	PORT_MODIFY("IN1")
    PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )           /* PORT_PLAYER(4) inputs */

	PORT_MODIFY("IN2")
    PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )           /* START4 */
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )           /* COIN4 */
INPUT_PORTS_END

/* 3 players and 3 buttons */
static INPUT_PORTS_START( cps2_3p3b )
	PORT_INCLUDE(cps2_3p4b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(1) */
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(2) */

	PORT_MODIFY("IN1")
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(3) */
INPUT_PORTS_END

/* 3 players and 2 buttons */
#ifdef UNUSED_DEFINITION
static INPUT_PORTS_START( cps2_3p2b )
	PORT_INCLUDE(cps2_3p3b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(1) */
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(2) */

	PORT_MODIFY("IN1")
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(3) */
INPUT_PORTS_END
#endif

/* 2 players and 4 buttons */
static INPUT_PORTS_START( cps2_2p4b )
	PORT_INCLUDE(cps2_3p4b)

	PORT_MODIFY("IN1")
    PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )           /* PORT_PLAYER(3) inputs */

	PORT_MODIFY("IN2")
    PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )           /* START3 */
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )           /* COIN3 */
INPUT_PORTS_END

/* 2 players and 3 buttons */
static INPUT_PORTS_START( cps2_2p3b )
	PORT_INCLUDE(cps2_2p4b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(1) */
    PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(2) */
INPUT_PORTS_END

/* 2 players and 2 buttons */
static INPUT_PORTS_START( cps2_2p2b )
	PORT_INCLUDE(cps2_2p3b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(1) */
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(2) */
INPUT_PORTS_END

/* 2 players and 1 button */
static INPUT_PORTS_START( cps2_2p1b )
	PORT_INCLUDE(cps2_2p2b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON2 PORT_PLAYER(1) */
    PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON2 PORT_PLAYER(2) */
INPUT_PORTS_END

/* 2 players and 6 buttons (2 rows of 3 buttons) */
static INPUT_PORTS_START( cps2_2p6b )
	PORT_INCLUDE(cps2_2p3b)

	PORT_MODIFY("IN1")
    PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
    PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
    PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
    PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
    PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)

	PORT_MODIFY("IN2")
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
INPUT_PORTS_END

/* 1 player and 4 buttons */
static INPUT_PORTS_START( cps2_1p4b )
	PORT_INCLUDE(cps2_2p4b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )           /* PORT_PLAYER(2) inputs */

	PORT_MODIFY("IN2")
    PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED )           /* START2 */
    PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED )           /* COIN2 */
INPUT_PORTS_END

/* 1 player and 3 buttons */
static INPUT_PORTS_START( cps2_1p3b )
	PORT_INCLUDE(cps2_1p4b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON4 PORT_PLAYER(1) */
INPUT_PORTS_END

/* 1 player and 2 buttons */
static INPUT_PORTS_START( cps2_1p2b )
	PORT_INCLUDE(cps2_1p3b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )           /* BUTTON3 PORT_PLAYER(1) */
INPUT_PORTS_END


/*************************************
 *
 *  Game-specific port definitions
 *
 *************************************/

/* According to the "test mode", buttons layout look like a 2 players 6 buttons machine where buttons have been removed */
static INPUT_PORTS_START( cybots )
	PORT_INCLUDE(cps2_2p6b)

	PORT_MODIFY("IN1")
    PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
    PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED )                     /* BUTTON5 PORT_PLAYER(1) */
    PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED )                     /* BUTTON6 PORT_PLAYER(1) */
    PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
    PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED )                     /* BUTTON5 PORT_PLAYER(2) */

	PORT_MODIFY("IN2")
    PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )                     /* BUTTON6 PORT_PLAYER(2) */
INPUT_PORTS_END

/* 2 players, no joysticks which are replaced with 4 buttons, no other buttons */
static INPUT_PORTS_START( qndream )
	PORT_INCLUDE(cps2_2p4b)

	PORT_MODIFY("IN0")
    PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
    PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
    PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
    PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
    PORT_BIT( 0x00f0, IP_ACTIVE_LOW, IPT_UNUSED )
    PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
    PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
    PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
    PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
    PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END

/* 2 players and 1 button - either 2 8-way joysticks, 2 2-way joysticks, or 2 paddles */
static INPUT_PORTS_START( pzloop2 )
	PORT_INCLUDE(cps2_2p1b)

	PORT_START("PADDLE1")
	PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(15) PORT_PLAYER(1)

	PORT_START("PADDLE2")
	PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(15) PORT_PLAYER(2)
INPUT_PORTS_END

/* 1 player and 3 buttons, but 2 coins slots */
static INPUT_PORTS_START( choko )
	PORT_INCLUDE(cps2_1p3b)

	PORT_MODIFY("IN2")
    PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_COIN2 )
INPUT_PORTS_END


/*************************************
 *
 *  Graphics layouts
 *
 *************************************/

static const gfx_layout cps1_layout8x8 =
{
	8,8,
	RGN_FRAC(1,1),
	4,
	{ 0, 1, 2, 3 },
	{ 1*4, 0*4, 3*4, 2*4, 5*4, 4*4, 7*4, 6*4 },
	{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
	64*8
};

static const gfx_layout cps1_layout8x8_2 =
{
	8,8,
	RGN_FRAC(1,1),
	4,
	{ 0, 1, 2, 3 },
	{ 9*4, 8*4, 11*4, 10*4, 13*4, 12*4, 15*4, 14*4 },
	{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
	64*8
};

static GFXLAYOUT_RAW( layout16x16, 4, 16, 16, 8*8, 128*8 )
static GFXLAYOUT_RAW( layout32x32, 4, 32, 32, 16*8, 512*8 )

static GFXDECODE_START( cps2 )
	GFXDECODE_ENTRY( "gfx", 0, cps1_layout8x8,   0, 0x100 )
	GFXDECODE_ENTRY( "gfx", 0, cps1_layout8x8_2, 0, 0x100 )
	GFXDECODE_ENTRY( "gfx", 0, layout16x16, 0, 0x100 )
	GFXDECODE_ENTRY( "gfx", 0, layout32x32, 0, 0x100 )
GFXDECODE_END


/*************************************
 *
 *  M68K encryption interface
 *
 *************************************/

static const m68k_encryption_interface cps2_encryption =
{
	cps2_read8, cps2_read16, cps2_read32,
	cps2_read16, cps2_read32
};


/*************************************
 *
 *  Machine driver
 *
 *************************************/

static MACHINE_DRIVER_START( cps2 )

	/* basic machine hardware */
	MDRV_CPU_ADD("main", M68000, 16000000)
	MDRV_CPU_CONFIG(cps2_encryption)
	MDRV_CPU_PROGRAM_MAP(cps2_readmem,cps2_writemem)
	MDRV_CPU_VBLANK_INT_HACK(cps2_interrupt,262)	// 262  /* ??? interrupts per frame */

	MDRV_CPU_ADD("audio", Z80, 8000000)
	MDRV_CPU_PROGRAM_MAP(qsound_sub_map,0)
	MDRV_CPU_PERIODIC_INT(irq0_line_hold, 251)	/* 251 is good (see 'mercy mercy mercy'section of sgemf attract mode for accurate sound sync */

//  MDRV_INTERLEAVE(262)  /* 262 scanlines, for raster effects */

	MDRV_NVRAM_HANDLER(cps2)

	/* video hardware */
	MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)

	MDRV_SCREEN_ADD("main", RASTER)
	MDRV_SCREEN_REFRESH_RATE(59.633333)
	MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MDRV_SCREEN_SIZE(64*8, 32*8)
	MDRV_SCREEN_VISIBLE_AREA(8*8, (64-8)*8-1, 2*8, 30*8-1 )

	MDRV_GFXDECODE(cps2)
	MDRV_PALETTE_LENGTH(0xc00)

	MDRV_VIDEO_START(cps2)
	MDRV_VIDEO_EOF(cps1)
	MDRV_VIDEO_UPDATE(cps1)

	/* sound hardware */
	MDRV_SPEAKER_STANDARD_STEREO("left", "right")

	MDRV_SOUND_ADD("qsound", QSOUND, QSOUND_CLOCK)
	MDRV_SOUND_ROUTE(0, "left", 1.0)
	MDRV_SOUND_ROUTE(1, "right", 1.0)
MACHINE_DRIVER_END

static MACHINE_DRIVER_START( phoenix )
	MDRV_IMPORT_FROM(cps2)

	MDRV_CPU_MODIFY("main")
	MDRV_CPU_PROGRAM_MAP(cps2_readmem,phoenix_writemem)
MACHINE_DRIVER_END

/*************************************
 *
 *  ROM definitions
 *
 *************************************/

ROM_START( armwar )
	ROM_REGION( CODE_SIZE, "main", 0 )      /* 68000 code */
	ROM_LOAD16_WORD_SWAP( "pwge.03c", 0x000000, 0x80000, CRC(31f74931) SHA1(66150fc9896acca1691c9d586abeb2c7299bb9ad) )
	ROM_LOAD16_WORD_SWAP( "pwge.04c", 0x080000, 0x80000, CRC(16f34f5f) SHA1(b831e3915d8cbffdfe4720d356e5196cdebdb6e7) )
	ROM_LOAD16_WORD_SWAP( "pwge.05b", 0x100000, 0x80000, CRC(4403ed08) SHA1(cc78c84105a58e43e7a6429281397d68b91e86e5) )
	ROM_LOAD16_WORD_SWAP( "pwg.06",   0x180000, 0x80000, CRC(87a60ce8) SHA1(e2085c7c8c6792d055dbbb023c7f4e4aa38ae924) )
	ROM_LOAD16_WORD_SWAP( "pwg.07",   0x200000, 0x80000, CRC(f7b148df) SHA1(f369669713cf647222094c570a2eacd48a8637cf) )
	ROM_LOAD16_WORD_SWAP( "pwg.08",   0x280000, 0x80000, CRC(cc62823e) SHA1(edaf9bebdfc65ae5414090abd6844176eec39a00) )
	ROM_LOAD16_WORD_SWAP( "pwg.09a",  0x300000, 0x80000, CRC(4c26baee) SHA1(685f050206b9b904ce6a1ae9a8e8f019012cea43) )
	ROM_LOAD16_WORD_SWAP( "pwg.10",   0x380000, 0x80000, CRC(07c4fb28) SHA1(58a1ff3d105be7df833dd4f32973766649efcbcf) )

	ROM_REGION( 0x1400000, "gfx", 0 )
	ROMX_LOAD( "pwg.13m",   0x0000000, 0x400000, CRC(ae8fe08e) SHA1(b6f09663dcda69b5d7ac13e4afaf1efd692fb61e) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.15m",   0x0000002, 0x400000, CRC(db560f58) SHA1(0c3716b32eb24544ff5d16b5dcadce195cd10d00) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.17m",   0x0000004, 0x400000, CRC(bc475b94) SHA1(a157664450895a146a532581dd6f4b63dff21c86) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.19m",   0x0000006, 0x400000, CRC(07439ff7) SHA1(f71e07c6d77c32828f5e319268b24b13a1a4b0c2) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.14m",   0x1000000, 0x100000, CRC(c3f9ba63) SHA1(66191a52c39daa89b17ede5804ee41c028036f14) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.16m",   0x1000002, 0x100000, CRC(815b0e7b) SHA1(549785daac3122253fb94f6541bc7016147f5306) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.18m",   0x1000004, 0x100000, CRC(0109c71b) SHA1(eb51284ee0c85ff8f605fe1d166b7aa202be1344) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.20m",   0x1000006, 0x100000, CRC(eb75ffbe) SHA1(e9d1deca60be696ac5bff2017fb5de3525e5239a) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION( QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "pwg.01",   0x00000, 0x08000, CRC(18a5c0e4) SHA1(bb1353dd74884aaeec9b5f1d0b284d9cad53c0ff) )
	ROM_CONTINUE(         0x10000, 0x18000 )
	ROM_LOAD( "pwg.02",   0x28000, 0x20000, CRC(c9dfffa6) SHA1(64e71028befe9a2514074be765dd020e1d2ea70b) )

	ROM_REGION( 0x400000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "pwg.11m",   0x000000, 0x200000, CRC(a78f7433) SHA1(e47ffba7b9dac9d0dda985c5d966194be18260f7) )
	ROM_LOAD16_WORD_SWAP( "pwg.12m",   0x200000, 0x200000, CRC(77438ed0) SHA1(733ca6c6a792e66e2aa12c5fc06dd459527afe4b) )
ROM_END

ROM_START( dimahoo )
	ROM_REGION( CODE_SIZE, "main", 0 )      /* 68000 code */
	ROM_LOAD16_WORD_SWAP( "gdme_03.03", 0x000000, 0x80000, CRC(968fcecd) SHA1(82d6eb6488df48bc7b977fc900c24b29bd6573a9) )
	ROM_LOAD16_WORD_SWAP( "gmd.04",  0x080000, 0x80000, CRC(37485567) SHA1(643c41fce6057bcaef0e0bedc62914c33d97eeaf) )
	ROM_LOAD16_WORD_SWAP( "gmd.05",  0x100000, 0x80000, CRC(da269ffb) SHA1(e99b04192030b6006cf67b563f40cea29c1b2e78) )
	ROM_LOAD16_WORD_SWAP( "gmd.06",  0x180000, 0x80000, CRC(55b483c9) SHA1(d47e077312f3c044d3647b79fa9e0581ccff5992) )

	ROM_REGION( 0x1000000, "gfx", 0 )
	ROMX_LOAD( "gmd.13m",   0x000000, 0x400000, CRC(80dd19f0) SHA1(0fd8b1e8d73cc83e6c34f0d94487938da2344f76) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "gmd.15m",   0x000002, 0x400000, CRC(dfd93a78) SHA1(c343d5ddcc25bd0739491e7439d7c0d0a8881a04) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "gmd.17m",   0x000004, 0x400000, CRC(16356520) SHA1(058713bef30c1b1d8b7dd0ceaaa57a3ab9751a70) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "gmd.19m",   0x000006, 0x400000, CRC(dfc33031) SHA1(a1ceaeddc2a79d5b79f1b107cac2ef6a5e621e77) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION( QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "gmd.01",   0x00000, 0x08000, CRC(3f9bc985) SHA1(1616bbee82877b1052a07531066f5009a80706be) )
	ROM_CONTINUE(         0x10000, 0x18000 )
	ROM_LOAD( "gmd.02",   0x28000, 0x20000, CRC(3fd39dde) SHA1(6a6e3ef9baa430ee83ab2312aa0221bae4d73dbd) )

	ROM_REGION( 0x800000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "gmd.11m",   0x000000, 0x400000, CRC(06a65542) SHA1(a1b3df70c90055a3cd59d0149fd18a74eff5bcc9) )
	ROM_LOAD16_WORD_SWAP( "gmd.12m",   0x400000, 0x400000, CRC(50bc7a31) SHA1(7283569fc646c39f4c693f14e0ce7ff2ee49111a) )
ROM_END

ROM_START( mmatrix )
	ROM_REGION( CODE_SIZE, "main", 0 )      /* 68000 code */
	ROM_LOAD16_WORD_SWAP( "mmxu.03", 0x000000, 0x80000, CRC(ab65b599) SHA1(d4c35f5a6cf0b37a35c466f0e347a660b2e0b21b) )
	ROM_LOAD16_WORD_SWAP( "mmxu.04", 0x080000, 0x80000, CRC(0135fc6c) SHA1(e40c8fa51dcb300b3ee72dc7de137e0b39dea490) )
	ROM_LOAD16_WORD_SWAP( "mmxu.05", 0x100000, 0x80000, CRC(f1fd2b84) SHA1(d34816eff4af98009f94f5dd14097b39426e0468) )

	ROM_REGION( 0x2000000, "gfx", 0 )
	ROMX_LOAD( "mmx.13m",   0x0000000, 0x400000, CRC(04748718) SHA1(d2e84d9dcc779c08469d815ccd709f30705954b8) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.15m",   0x0000002, 0x400000, CRC(38074f44) SHA1(2002c4862c156b314bc4f3372b713c48e0667ec3) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.17m",   0x0000004, 0x400000, CRC(e4635e35) SHA1(48ef7a82df83b981ddd6138c241ca129ab770e8e) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.19m",   0x0000006, 0x400000, CRC(4400a3f2) SHA1(d0aa805ccbb153896e5983da1c398d1df4f40371) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.14m",   0x1000000, 0x400000, CRC(d52bf491) SHA1(2398895cfdcf86fc485472e33df2cc446539e977) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.16m",   0x1000002, 0x400000, CRC(23f70780) SHA1(691ee8964815b0ce54704e7feb59ca79b634f26d) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.18m",   0x1000004, 0x400000, CRC(2562c9d5) SHA1(e7defc3d33db632c4035ae069f2f2332c58afaf5) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.20m",   0x1000006, 0x400000, CRC(583a9687) SHA1(1d0b08b1e88509245db3c2090f0201938fd750b4) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION( QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "mmx.01",   0x00000, 0x08000, CRC(c57e8171) SHA1(dedb92af1910d38727f816e6f507d25148f31b74) )
	ROM_CONTINUE(         0x10000, 0x18000 )

	ROM_REGION( 0x800000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "mmx.11m",   0x000000, 0x400000, CRC(4180b39f) SHA1(cabb1c358eae1bb6cfed07f5b92e4acd38650667) )
	ROM_LOAD16_WORD_SWAP( "mmx.12m",   0x400000, 0x400000, CRC(95e22a59) SHA1(b3431d170c0a1a0d826ad0af21300b9180e3f114) )
ROM_END

/*************************************
 *
 *  Games initialisation
 *
 *************************************/

static DRIVER_INIT( cps2 )
{
	/* Decrypt the game - see machine/cps2crpt.c */
	DRIVER_INIT_CALL(cps2crpt);
	cps2networkpresent = 0;

	cpunum_set_clockscale(machine, 0, 0.7375f); /* RAM access waitstates etc. aren't emulated - slow the CPU to compensate */
}



/*************************************
 *
 *  Game drivers
 *
 *************************************/

GAME( 1994, armwar,   0,        cps2, cps2_3p3b, cps2,     ROT0,   "Capcom", "Armored Warriors (Euro 941024)", 0 )
GAME( 2000, dimahoo,  0,        cps2, cps2_2p3b, cps2,     ROT270, "Eighting/Raizing, distributed by Capcom", "Dimahoo (Euro 000121)", 0 )
GAME( 2000, mmatrix,  0,        cps2, cps2_2p1b, cps2,     ROT0,   "Capcom, supported by Takumi", "Mars Matrix: Hyper Solid Shooting (USA 000412)", 0 )

/* misfitmame start */

ROM_START( armward )
	ROM_REGION( CODE_SIZE, "main", 0 )      /* 68000 code */
	ROM_LOAD16_WORD_SWAP( "armward.03a", 0x000000, 0x80000, CRC(496bd483) SHA1(c3a116ea019843aba666a0d7e7bd2975622306e3) )
	ROM_LOAD16_WORD_SWAP( "armward.04a", 0x080000, 0x80000, CRC(9bd6a38f) SHA1(da90162b7bff223df59ac362a5f61c580a86d967) )
	ROM_LOAD16_WORD_SWAP( "armward.05a", 0x100000, 0x80000, CRC(4c11d30f) SHA1(463ba1845b1239c839e9419cbc6762d52b7918db) )
	ROM_LOAD16_WORD_SWAP( "pwg.06",   0x180000, 0x80000, CRC(87a60ce8) SHA1(e2085c7c8c6792d055dbbb023c7f4e4aa38ae924) )
	ROM_LOAD16_WORD_SWAP( "pwg.07",   0x200000, 0x80000, CRC(f7b148df) SHA1(f369669713cf647222094c570a2eacd48a8637cf) )
	ROM_LOAD16_WORD_SWAP( "pwg.08",   0x280000, 0x80000, CRC(cc62823e) SHA1(edaf9bebdfc65ae5414090abd6844176eec39a00) )
	ROM_LOAD16_WORD_SWAP( "pwg.09a",  0x300000, 0x80000, CRC(4c26baee) SHA1(685f050206b9b904ce6a1ae9a8e8f019012cea43) )
	ROM_LOAD16_WORD_SWAP( "pwg.10",   0x380000, 0x80000, CRC(07c4fb28) SHA1(58a1ff3d105be7df833dd4f32973766649efcbcf) )

	ROM_REGION( 0x1400000, "gfx", 0 )
	ROMX_LOAD( "pwg.13m",   0x0000000, 0x400000, CRC(ae8fe08e) SHA1(b6f09663dcda69b5d7ac13e4afaf1efd692fb61e) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.15m",   0x0000002, 0x400000, CRC(db560f58) SHA1(0c3716b32eb24544ff5d16b5dcadce195cd10d00) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.17m",   0x0000004, 0x400000, CRC(bc475b94) SHA1(a157664450895a146a532581dd6f4b63dff21c86) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.19m",   0x0000006, 0x400000, CRC(07439ff7) SHA1(f71e07c6d77c32828f5e319268b24b13a1a4b0c2) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.14m",   0x1000000, 0x100000, CRC(c3f9ba63) SHA1(66191a52c39daa89b17ede5804ee41c028036f14) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.16m",   0x1000002, 0x100000, CRC(815b0e7b) SHA1(549785daac3122253fb94f6541bc7016147f5306) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.18m",   0x1000004, 0x100000, CRC(0109c71b) SHA1(eb51284ee0c85ff8f605fe1d166b7aa202be1344) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pwg.20m",   0x1000006, 0x100000, CRC(eb75ffbe) SHA1(e9d1deca60be696ac5bff2017fb5de3525e5239a) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION( QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "pwg.01",   0x00000, 0x08000, CRC(18a5c0e4) SHA1(bb1353dd74884aaeec9b5f1d0b284d9cad53c0ff) )
	ROM_CONTINUE(         0x10000, 0x18000 )
	ROM_LOAD( "pwg.02",   0x28000, 0x20000, CRC(c9dfffa6) SHA1(64e71028befe9a2514074be765dd020e1d2ea70b) )

	ROM_REGION( 0x400000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "pwg.11m",   0x000000, 0x200000, CRC(a78f7433) SHA1(e47ffba7b9dac9d0dda985c5d966194be18260f7) )
	ROM_LOAD16_WORD_SWAP( "pwg.12m",   0x200000, 0x200000, CRC(77438ed0) SHA1(733ca6c6a792e66e2aa12c5fc06dd459527afe4b) )
ROM_END

ROM_START( dimahood )
	ROM_REGION( CODE_SIZE, "main", 0 )      /* 68000 code */
	ROM_LOAD16_WORD_SWAP( "dimahood.03", 0x000000, 0x80000, CRC(12888435) SHA1(38204359c505ae861341936cd0fd2517411b8995) )
	ROM_LOAD16_WORD_SWAP( "gmd.04",  0x080000, 0x80000, CRC(37485567) SHA1(643c41fce6057bcaef0e0bedc62914c33d97eeaf) )
	ROM_LOAD16_WORD_SWAP( "gmd.05",  0x100000, 0x80000, CRC(da269ffb) SHA1(e99b04192030b6006cf67b563f40cea29c1b2e78) )
	ROM_LOAD16_WORD_SWAP( "dimahood.06",  0x180000, 0x80000, CRC(d825efda) SHA1(7299f3629d5136f567f5cf373754ea13b2190533) )

	ROM_REGION( 0x1000000, "gfx", 0 )
	ROMX_LOAD( "gmd.13m",   0x000000, 0x400000, CRC(80dd19f0) SHA1(0fd8b1e8d73cc83e6c34f0d94487938da2344f76) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "gmd.15m",   0x000002, 0x400000, CRC(dfd93a78) SHA1(c343d5ddcc25bd0739491e7439d7c0d0a8881a04) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "gmd.17m",   0x000004, 0x400000, CRC(16356520) SHA1(058713bef30c1b1d8b7dd0ceaaa57a3ab9751a70) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "gmd.19m",   0x000006, 0x400000, CRC(dfc33031) SHA1(a1ceaeddc2a79d5b79f1b107cac2ef6a5e621e77) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION( QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "gmd.01",   0x00000, 0x08000, CRC(3f9bc985) SHA1(1616bbee82877b1052a07531066f5009a80706be) )
	ROM_CONTINUE(         0x10000, 0x18000 )
	ROM_LOAD( "gmd.02",   0x28000, 0x20000, CRC(3fd39dde) SHA1(6a6e3ef9baa430ee83ab2312aa0221bae4d73dbd) )

	ROM_REGION( 0x800000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "gmd.11m",   0x000000, 0x400000, CRC(06a65542) SHA1(a1b3df70c90055a3cd59d0149fd18a74eff5bcc9) )
	ROM_LOAD16_WORD_SWAP( "gmd.12m",   0x400000, 0x400000, CRC(50bc7a31) SHA1(7283569fc646c39f4c693f14e0ce7ff2ee49111a) )
ROM_END

ROM_START( mmatrixd )
	ROM_REGION( CODE_SIZE, "main", 0 )      /* 68000 code */
	ROM_LOAD16_WORD_SWAP( "mmatrixd.03", 0x000000, 0x80000, CRC(36711e60) SHA1(a192e786798f69320761017437ee4d2d47dc80c5) )
	ROM_LOAD16_WORD_SWAP( "mmatrixd.04", 0x080000, 0x80000, CRC(4687226f) SHA1(b831582f578eb1e40bce1d1cbf231e4c27f510cd) )
	ROM_LOAD16_WORD_SWAP( "mmatrixd.05", 0x100000, 0x80000, CRC(52124398) SHA1(0a18b9d2a7e3335ddf7ff9ac5c5f8298951f8c67) )

	ROM_REGION( 0x2000000, "gfx", 0 )
	ROMX_LOAD( "mmx.13m",   0x0000000, 0x400000, CRC(04748718) SHA1(d2e84d9dcc779c08469d815ccd709f30705954b8) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.15m",   0x0000002, 0x400000, CRC(38074f44) SHA1(2002c4862c156b314bc4f3372b713c48e0667ec3) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.17m",   0x0000004, 0x400000, CRC(e4635e35) SHA1(48ef7a82df83b981ddd6138c241ca129ab770e8e) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.19m",   0x0000006, 0x400000, CRC(4400a3f2) SHA1(d0aa805ccbb153896e5983da1c398d1df4f40371) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.14m",   0x1000000, 0x400000, CRC(d52bf491) SHA1(2398895cfdcf86fc485472e33df2cc446539e977) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.16m",   0x1000002, 0x400000, CRC(23f70780) SHA1(691ee8964815b0ce54704e7feb59ca79b634f26d) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.18m",   0x1000004, 0x400000, CRC(2562c9d5) SHA1(e7defc3d33db632c4035ae069f2f2332c58afaf5) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "mmx.20m",   0x1000006, 0x400000, CRC(583a9687) SHA1(1d0b08b1e88509245db3c2090f0201938fd750b4) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION( QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "mmx.01",   0x00000, 0x08000, CRC(c57e8171) SHA1(dedb92af1910d38727f816e6f507d25148f31b74) )
	ROM_CONTINUE(         0x10000, 0x18000 )

	ROM_REGION( 0x800000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "mmx.11m",   0x000000, 0x400000, CRC(4180b39f) SHA1(cabb1c358eae1bb6cfed07f5b92e4acd38650667) )
	ROM_LOAD16_WORD_SWAP( "mmx.12m",   0x400000, 0x400000, CRC(95e22a59) SHA1(b3431d170c0a1a0d826ad0af21300b9180e3f114) )
ROM_END

ROM_START( suicide )
	ROM_REGION(CODE_SIZE, "main", 0 )
	ROM_LOAD16_WORD_SWAP( "suicide.03", 0x000000, 0x80000, CRC(4d5eea90) SHA1(c6f6361650d64401354111bf111bd924126b7035) )

	ROM_REGION( 0xC00000, "gfx", 0 )
	ROM_FILL(              0x000000, 0x800000, 0 )
	ROMX_LOAD( "pzf.14m",  0x800000, 0x100000, CRC(2d4881cb) SHA1(fd3baa183c25bed153b19c251980e2fb761600e2) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pzf.16m",  0x800002, 0x100000, CRC(4b0fd1be) SHA1(377aafdcdb7a866b1c8487670e3598d8197976e4) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pzf.18m",  0x800004, 0x100000, CRC(e43aac33) SHA1(d041e0688c3807d3363861a7f216de43b34d846c) , ROM_GROUPWORD | ROM_SKIP(6) )
	ROMX_LOAD( "pzf.20m",  0x800006, 0x100000, CRC(7f536ff1) SHA1(905b9d62ef7bef47297c7f4a4dd697aed6df38a5) , ROM_GROUPWORD | ROM_SKIP(6) )

	ROM_REGION(QSOUND_SIZE, "audio", 0 ) /* 64k for the audio CPU (+banks) */
	ROM_LOAD( "pzf.01",   0x00000, 0x08000, CRC(600fb2a3) SHA1(1fab1c2a23bf6ad8309d29ddbbc29435a8aeea13) )
	ROM_CONTINUE(         0x10000, 0x18000 )
	ROM_LOAD( "pzf.02",   0x28000, 0x20000, CRC(496076e0) SHA1(1ee4e135140afd0e8e03231e570cd77d140f6367) )

	ROM_REGION( 0x400000, "qsound", 0 ) /* QSound samples */
	ROM_LOAD16_WORD_SWAP( "pzf.11m",   0x000000, 0x200000, CRC(78442743) SHA1(b61190bb586871de6d54af580e3e1d9cc0de0acb) )
	ROM_LOAD16_WORD_SWAP( "pzf.12m",   0x200000, 0x200000, CRC(399d2c7b) SHA1(e849dea97b8d16540415c0d9bbc4f9f4eb755ec4) )
ROM_END

/* Phoenix */

GAME( 2008, armward,  armwar,   phoenix, cps2_3p3b, cps2,     ROT0,   "Razoola", "Armored Warriors (Euro 941024 Phoenix Edition)", 0 )
GAME( 2008, dimahood, dimahoo,  phoenix, cps2_2p3b, cps2,     ROT270, "Razoola", "Dimahoo (USA 000121 Phoenix Edition)", 0 )
GAME( 2008, mmatrixd, mmatrix,  phoenix, cps2_2p1b, cps2,     ROT0,   "Razoola", "Mars Matrix: Hyper Solid Shooting (USA 000412 Phoenix Edition)", 0 )

/* Misc */

GAME( 1996, suicide,  0,	cps2, cps2_2p2b, cps2,     ROT0,   "Razoola", "Suicide Test", 0 )

/* misfitmame end */

