/*
 *	Thunder Ceptor board
 *	(C) 1986 Namco
 *
 *	Hardware analyzed by nono
 *	Driver by BUT
 */

#include "driver.h"
#include "state.h"
#include "cpu/m6502/m6502.h"
#include "cpu/m6809/m6809.h"
#include "cpu/m6800/m6800.h"
#include "cpu/m68000/m68000.h"
#include "namcoic.h"

#ifdef TINY_COMPILE
// to avoid link error
int namcos2_gametype;
#endif


extern PALETTE_INIT( tceptor );
extern VIDEO_START( tceptor );
extern VIDEO_UPDATE( tceptor );

extern READ_HANDLER( tceptor_tile_ram_r );
extern WRITE_HANDLER( tceptor_tile_ram_w );
extern READ_HANDLER( tceptor_tile_attr_r );
extern WRITE_HANDLER( tceptor_tile_attr_w );
extern READ_HANDLER( tceptor_bg_ram_r );
extern WRITE_HANDLER( tceptor_bg_ram_w );
extern WRITE_HANDLER( tceptor_bg_scroll_w );

extern data8_t *tceptor_tile_ram;
extern data8_t *tceptor_tile_attr;
extern data8_t *tceptor_bg_ram;
extern data16_t *tceptor_sprite_ram;


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

static data8_t *m6502_a_shared_ram;
static data8_t *m6502_b_shared_ram;
static data8_t *m68k_shared_ram;
static data8_t *mcu_shared_ram;

static int m6809_irq_enable;
static int m68k_irq_enable;
static int mcu_irq_enable;


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

static READ_HANDLER( m6502_a_shared_r )
{
	return m6502_a_shared_ram[offset];
}

static WRITE_HANDLER( m6502_a_shared_w )
{
	m6502_a_shared_ram[offset] = data;
}

static READ_HANDLER( m6502_b_shared_r )
{
	return m6502_b_shared_ram[offset];
}

static WRITE_HANDLER( m6502_b_shared_w )
{
	m6502_b_shared_ram[offset] = data;
}


static READ_HANDLER( m68k_shared_r )
{
	return m68k_shared_ram[offset];
}

static WRITE_HANDLER( m68k_shared_w )
{
	m68k_shared_ram[offset] = data;
}

static READ16_HANDLER( m68k_shared_word_r )
{
	return m68k_shared_ram[offset];
}

static WRITE16_HANDLER( m68k_shared_word_w )
{
	if (ACCESSING_LSB16)
		m68k_shared_ram[offset] = data & 0xff;
}


static READ_HANDLER( mcu_shared_r )
{
	return mcu_shared_ram[offset];
}

static WRITE_HANDLER( mcu_shared_w )
{
	mcu_shared_ram[offset] = data;
}


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

static INTERRUPT_GEN( m6809_vb_interrupt )
{
	if (m6809_irq_enable)
		cpu_set_irq_line(0, 0, HOLD_LINE);
	else
		m6809_irq_enable = 1;
}

static WRITE_HANDLER( m6809_irq_enable_w )
{
	m6809_irq_enable = 1;
}

static WRITE_HANDLER( m6809_irq_disable_w )
{
	m6809_irq_enable = 0;
}


static INTERRUPT_GEN( m68k_vb_interrupt )
{
	if (m68k_irq_enable)
		cpu_set_irq_line(3, MC68000_IRQ_1, HOLD_LINE);
}

static WRITE16_HANDLER( m68k_irq_enable_w )
{
	m68k_irq_enable = data;
}


static INTERRUPT_GEN( mcu_vb_interrupt )
{
	if (mcu_irq_enable)
		cpu_set_irq_line(4, 0, HOLD_LINE);
	else
		mcu_irq_enable = 1;
}

static WRITE_HANDLER( mcu_irq_enable_w )
{
	mcu_irq_enable = 1;
}

static WRITE_HANDLER( mcu_irq_disable_w )
{
	mcu_irq_enable = 0;
}


static WRITE_HANDLER( voice_w )
{
	DAC_signed_data_16_w(0, data ? (data + 1) * 0x100 : 0x8000);
}


/* fix dsw/input data to memory mapped data */
static data8_t fix_input0(data8_t in1, data8_t in2)
{
	data8_t r = 0;

	r |= (in1 & 0x80) >> 7;
	r |= (in1 & 0x20) >> 4;
	r |= (in1 & 0x08) >> 1;
	r |= (in1 & 0x02) << 2;
	r |= (in2 & 0x80) >> 3;
	r |= (in2 & 0x20) >> 0;
	r |= (in2 & 0x08) << 3;
	r |= (in2 & 0x02) << 6;

	return r;
}

static data8_t fix_input1(data8_t in1, data8_t in2)
{
	data8_t r = 0;

	r |= (in1 & 0x40) >> 6;
	r |= (in1 & 0x10) >> 3;
	r |= (in1 & 0x04) >> 0;
	r |= (in1 & 0x01) << 3;
	r |= (in2 & 0x40) >> 2;
	r |= (in2 & 0x10) << 1;
	r |= (in2 & 0x04) << 4;
	r |= (in2 & 0x01) << 7;

	return r;
}

static READ_HANDLER( dsw0_r )
{
	return fix_input0(readinputport(0), readinputport(1));
}

static READ_HANDLER( dsw1_r )
{
	return fix_input1(readinputport(0), readinputport(1));
}

static READ_HANDLER( input0_r )
{
	return fix_input0(readinputport(2), readinputport(3));
}

static READ_HANDLER( input1_r )
{
	return fix_input1(readinputport(2), readinputport(3));
}

static READ_HANDLER( readFF )
{
	return 0xff;
}

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

static MEMORY_READ_START( m6809_readmem )
	{ 0x0000, 0x00ff, MRA_RAM },
	{ 0x0100, 0x16ff, MRA_RAM },
	{ 0x1700, 0x17ff, MRA_RAM },
	{ 0x1800, 0x1bff, tceptor_tile_ram_r },
	{ 0x1c00, 0x1fff, tceptor_tile_attr_r },
	{ 0x2000, 0x3fff, tceptor_bg_ram_r },		// background (VIEW RAM)
	{ 0x4000, 0x40ff, namcos1_wavedata_r },
	{ 0x4000, 0x43ff, mcu_shared_r },
	{ 0x4f00, 0x4f00, MRA_NOP },			// unknown
	{ 0x4f01, 0x4f01, input_port_4_r },		// analog input (accel)
	{ 0x4f02, 0x4f02, input_port_5_r },		// analog input (left/right)
	{ 0x4f03, 0x4f03, input_port_6_r },		// analog input (up/down)
	{ 0x6000, 0x7fff, m68k_shared_r },		// COM RAM
	{ 0x8000, 0xffff, MRA_ROM },
MEMORY_END

static MEMORY_WRITE_START( m6809_writemem )
	{ 0x0000, 0x00ff, MWA_RAM },
	{ 0x0100, 0x16ff, MWA_RAM },
	{ 0x1700, 0x17ff, MWA_RAM },
	{ 0x1800, 0x1bff, tceptor_tile_ram_w, &tceptor_tile_ram },
	{ 0x1c00, 0x1fff, tceptor_tile_attr_w, &tceptor_tile_attr },
	{ 0x2000, 0x3fff, tceptor_bg_ram_w, &tceptor_bg_ram },	// background (VIEW RAM)
	{ 0x4000, 0x40ff, namcos1_wavedata_w },
	{ 0x4000, 0x43ff, mcu_shared_w },
	{ 0x4800, 0x4800, MWA_NOP },			// 3D scope left/right?
	{ 0x4f00, 0x4f03, MWA_NOP },			// analog input control?
	{ 0x5000, 0x5006, tceptor_bg_scroll_w },	// bg scroll
	{ 0x6000, 0x7fff, m68k_shared_w, &m68k_shared_ram },
	{ 0x8000, 0x8000, m6809_irq_disable_w },
	{ 0x8800, 0x8800, m6809_irq_enable_w },
	{ 0x8000, 0xffff, MWA_ROM },
MEMORY_END


static MEMORY_READ_START( m6502_a_readmem )
	{ 0x0000, 0x00ff, m6502_b_shared_r },
	{ 0x0100, 0x01ff, MRA_RAM },
	{ 0x0200, 0x02ff, MRA_RAM },
	{ 0x0300, 0x030f, MRA_RAM },
	{ 0x2001, 0x2001, YM2151_status_port_0_r },
	{ 0x3000, 0x30ff, m6502_a_shared_r },
	{ 0x8000, 0xffff, MRA_ROM },
MEMORY_END

static MEMORY_WRITE_START( m6502_a_writemem )
	{ 0x0000, 0x00ff, m6502_b_shared_w },
	{ 0x0100, 0x01ff, MWA_RAM },
	{ 0x0200, 0x02ff, MWA_RAM },
	{ 0x0300, 0x030f, MWA_RAM },
	{ 0x2000, 0x2000, YM2151_register_port_0_w },
	{ 0x2001, 0x2001, YM2151_data_port_0_w },
	{ 0x3000, 0x30ff, m6502_a_shared_w, &m6502_a_shared_ram },
	{ 0x3c01, 0x3c01, MWA_RAM },
	{ 0x8000, 0xffff, MWA_ROM },
MEMORY_END


static MEMORY_READ_START( m6502_b_readmem )
	{ 0x0000, 0x00ff, m6502_b_shared_r },
	{ 0x0100, 0x01ff, MRA_RAM },
	{ 0x8000, 0xffff, MRA_ROM },
MEMORY_END

static MEMORY_WRITE_START( m6502_b_writemem )
	{ 0x0000, 0x00ff, m6502_b_shared_w, &m6502_b_shared_ram },
	{ 0x0100, 0x01ff, MWA_RAM },
	{ 0x4000, 0x4000, voice_w },			// voice data
	{ 0x5000, 0x5000, MWA_RAM },			// voice ctrl??
	{ 0x8000, 0xffff, MWA_ROM },
MEMORY_END


static MEMORY_READ16_START( m68k_readmem )
	{ 0x000000, 0x00ffff, MRA16_ROM },		// M68K ERROR 1
	{ 0x100000, 0x10ffff, MRA16_ROM },		// not sure
	{ 0x200000, 0x203fff, MRA16_RAM },		// M68K ERROR 0
	{ 0x700000, 0x703fff, m68k_shared_word_r },
MEMORY_END

static MEMORY_WRITE16_START( m68k_writemem )
	{ 0x000000, 0x00ffff, MWA16_ROM },
	{ 0x100000, 0x10ffff, MWA16_ROM },		// not sure
	{ 0x200000, 0x203fff, MWA16_RAM },
	{ 0x300000, 0x300001, MWA16_RAM },
	{ 0x400000, 0x4001ff, MWA16_RAM, &tceptor_sprite_ram },
	{ 0x500000, 0x51ffff, namco_road16_w },
	{ 0x600000, 0x600001, m68k_irq_enable_w },	// not sure
	{ 0x700000, 0x703fff, m68k_shared_word_w },
MEMORY_END


static MEMORY_READ_START( mcu_readmem )
	{ 0x0000, 0x001f, hd63701_internal_registers_r },
	{ 0x0080, 0x00ff, MRA_RAM },
	{ 0x1000, 0x10ff, namcos1_wavedata_r },
	{ 0x1000, 0x13ff, mcu_shared_r },
	{ 0x1400, 0x154d, MRA_RAM },
	{ 0x17c0, 0x17ff, MRA_RAM },
	{ 0x2000, 0x20ff, m6502_a_shared_r },
	{ 0x2100, 0x2100, dsw0_r },
	{ 0x2101, 0x2101, dsw1_r },
	{ 0x2200, 0x2200, input0_r },
	{ 0x2201, 0x2201, input1_r },
	{ 0x8000, 0xbfff, MRA_ROM },
	{ 0xc000, 0xc7ff, MRA_RAM },
	{ 0xc800, 0xdfff, MRA_RAM },			// Battery Backup
	{ 0xf000, 0xffff, MRA_ROM },
MEMORY_END

static MEMORY_WRITE_START( mcu_writemem )
	{ 0x0000, 0x001f, hd63701_internal_registers_w },
	{ 0x0080, 0x00ff, MWA_RAM },
	{ 0x1000, 0x10ff, namcos1_wavedata_w, &namco_wavedata },
	{ 0x1100, 0x113f, namcos1_sound_w, &namco_soundregs },
	{ 0x1000, 0x13ff, mcu_shared_w, &mcu_shared_ram },
	{ 0x1400, 0x154d, MWA_RAM },
	{ 0x17c0, 0x17ff, MWA_RAM },
	{ 0x2000, 0x20ff, m6502_a_shared_w },
	{ 0x8000, 0x8000, mcu_irq_disable_w },
	{ 0x8800, 0x8800, mcu_irq_enable_w },
	{ 0x8000, 0xbfff, MWA_ROM },
	{ 0xc000, 0xc7ff, MWA_RAM },
	{ 0xc800, 0xdfff, MWA_RAM, &generic_nvram, &generic_nvram_size },	// Battery Backup
	{ 0xf000, 0xffff, MWA_ROM },
MEMORY_END


static PORT_READ_START( mcu_readport )
	{ HD63701_PORT1, HD63701_PORT1, readFF },
	{ HD63701_PORT2, HD63701_PORT2, readFF },
PORT_END

static PORT_WRITE_START( mcu_writeport )
	{ HD63701_PORT1, HD63701_PORT1, MWA_NOP },
	{ HD63701_PORT2, HD63701_PORT2, MWA_NOP },
PORT_END


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

INPUT_PORTS_START( tceptor )
	PORT_START      /* DSW 1 */
	PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_A ) )
	PORT_DIPSETTING(    0x02, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(    0x03, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x01, DEF_STR( 3C_2C ) )
	PORT_DIPSETTING(    0x00, DEF_STR( 4C_3C ) )
	PORT_DIPSETTING(    0x07, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x06, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(    0x05, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(    0x04, DEF_STR( 1C_4C ) )
	PORT_DIPNAME( 0x18, 0x18, DEF_STR( Coin_B ) )
	PORT_DIPSETTING(    0x10, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x08, DEF_STR( 3C_2C ) )
	PORT_DIPSETTING(    0x00, DEF_STR( 4C_3C ) )
	PORT_DIPSETTING(    0x18, DEF_STR( 1C_1C ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x40, "Freeze" )
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START      /* DSW 2 */
	PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(    0x02, "A" )
	PORT_DIPSETTING(    0x03, "B" )
	PORT_DIPSETTING(    0x01, "C" )
	PORT_DIPSETTING(    0x00, "D" )
	PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START      /* Memory Mapped Port */
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )	// shot
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )	// bomb
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )	// shot
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )	// bomb
	PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START      /* Memory Mapped Port */
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_SERVICE( 0x04, IP_ACTIVE_LOW )		// TEST SW
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 )
	PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START	/* ADC0809 - 8 CHANNEL ANALOG - CHANNEL 1 */
	PORT_ANALOGX( 0xff, 0x00, IPT_PEDAL, 100, 16, 0x00, 0xd6, KEYCODE_Z, IP_JOY_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT )

	PORT_START	/* ADC0809 - 8 CHANNEL ANALOG - CHANNEL 2 */
	PORT_ANALOG(  0xff, 0x7f, IPT_AD_STICK_X | IPF_CENTER, 100, 16, 0x00, 0xfe )

	PORT_START	/* ADC08090 - 8 CHANNEL ANALOG - CHANNEL 3 */
	PORT_ANALOG(  0xff, 0x7f, IPT_AD_STICK_Y | IPF_CENTER, 100, 16, 0x00, 0xfe )
INPUT_PORTS_END

INPUT_PORTS_START( tceptor2 )
	PORT_START      /* DSW 1 */
	PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_A ) )
	PORT_DIPSETTING(    0x02, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(    0x03, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x01, DEF_STR( 3C_2C ) )
	PORT_DIPSETTING(    0x00, DEF_STR( 4C_3C ) )
	PORT_DIPSETTING(    0x07, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(    0x06, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(    0x05, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(    0x04, DEF_STR( 1C_4C ) )
	PORT_DIPNAME( 0x18, 0x18, DEF_STR( Coin_B ) )
	PORT_DIPSETTING(    0x10, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x08, DEF_STR( 3C_2C ) )
	PORT_DIPSETTING(    0x00, DEF_STR( 4C_3C ) )
	PORT_DIPSETTING(    0x18, DEF_STR( 1C_1C ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x40, "Freeze" )
	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START      /* DSW 2 */
	PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(    0x02, "A" )
	PORT_DIPSETTING(    0x03, "B" )
	PORT_DIPSETTING(    0x01, "C" )
	PORT_DIPSETTING(    0x00, "D" )
	PORT_DIPNAME( 0x04, 0x00, "MODE" )		// set default as 2D mode
	PORT_DIPSETTING(    0x00, "2D" )
	PORT_DIPSETTING(    0x04, "3D" )
	PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START      /* Memory Mapped Port */
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )	// shot
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )	// bomb
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )	// shot
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )	// bomb
	PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START      /* Memory Mapped Port */
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 )
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_SERVICE( 0x04, IP_ACTIVE_LOW )		// TEST SW
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 )
	PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START	/* ADC0809 - 8 CHANNEL ANALOG - CHANNEL 1 */
	PORT_ANALOGX( 0xff, 0x00, IPT_PEDAL, 100, 16, 0x00, 0xd6, KEYCODE_Z, IP_JOY_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT )

	PORT_START	/* ADC0809 - 8 CHANNEL ANALOG - CHANNEL 2 */
	PORT_ANALOG(  0xff, 0x7f, IPT_AD_STICK_X | IPF_CENTER, 100, 16, 0x00, 0xfe )

	PORT_START	/* ADC08090 - 8 CHANNEL ANALOG - CHANNEL 3 */
	PORT_ANALOG(  0xff, 0x7f, IPT_AD_STICK_Y | IPF_CENTER, 100, 16, 0x00, 0xfe )
INPUT_PORTS_END


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

static struct GfxLayout tile_layout =
{
	8, 8,
	512,
	2,
	{ 0x0000, 0x0004 }, //,  0x8000, 0x8004 },
	{ 8*8, 8*8+1, 8*8+2, 8*8+3, 0*8+0, 0*8+1, 0*8+2, 0*8+3 },
	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
	2*8*8
};

static struct GfxDecodeInfo gfxdecodeinfo[] =
{
	{ REGION_GFX1, 0, &tile_layout,     0,  256 },

	/* decode in VIDEO_START */
	//{ REGION_GFX2, 0, &bg_layout,    2048,   64 },
	//{ REGION_GFX3, 0, &spr16_layout, 1024,   64 },
	//{ REGION_GFX4, 0, &spr32_layout, 1024,   64 },
	{ -1 }
};


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

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

static struct namco_interface namco_interface =
{
	49152000/2048,		/* 24000Hz */
	8,			/* number of voices */
	50,			/* playback volume */
	-1,			/* memory region */
	1			/* stereo */
};

static struct DACinterface dac_interface =
{
	1,			/* 1 channel */
	{ 50 }			/* mixing level */
};


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

static MACHINE_INIT( tceptor )
{
	m6809_irq_enable = 0;
	m68k_irq_enable = 0;
	mcu_irq_enable = 0;
}

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

static MACHINE_DRIVER_START( tceptor )

	/* basic machine hardware */
	MDRV_CPU_ADD(M6809, 49152000/32)
	MDRV_CPU_MEMORY(m6809_readmem,m6809_writemem)
	MDRV_CPU_VBLANK_INT(m6809_vb_interrupt,1)

	MDRV_CPU_ADD(M65C02, 49152000/24)
	MDRV_CPU_FLAGS(CPU_AUDIO_CPU)
	MDRV_CPU_MEMORY(m6502_a_readmem,m6502_a_writemem)

	MDRV_CPU_ADD(M65C02, 49152000/24)
	MDRV_CPU_FLAGS(CPU_AUDIO_CPU)
	MDRV_CPU_MEMORY(m6502_b_readmem,m6502_b_writemem)

	MDRV_CPU_ADD(M68000, 49152000/4)
	MDRV_CPU_MEMORY(m68k_readmem,m68k_writemem)
	MDRV_CPU_VBLANK_INT(m68k_vb_interrupt,1)

	MDRV_CPU_ADD(HD63701, 49152000/32)	/* or compatible 6808 with extra instructions */
	MDRV_CPU_MEMORY(mcu_readmem,mcu_writemem)
	MDRV_CPU_PORTS(mcu_readport,mcu_writeport)
	MDRV_CPU_VBLANK_INT(mcu_vb_interrupt,1)

	MDRV_FRAMES_PER_SECOND( (18432000.0 / 2) / (576 * 264) )
	MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
	MDRV_INTERLEAVE(100)

	MDRV_NVRAM_HANDLER(generic_1fill)

	MDRV_MACHINE_INIT(tceptor)

	/* video hardware */
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_NEEDS_6BITS_PER_GUN)
	MDRV_SCREEN_SIZE(38*8, 32*8)
	MDRV_VISIBLE_AREA(2*8, 34*8-1 + 2*8, 0*8, 28*8-1 + 0)
	MDRV_GFXDECODE(gfxdecodeinfo)
	MDRV_PALETTE_LENGTH(1024)
	MDRV_COLORTABLE_LENGTH(4096)

	MDRV_PALETTE_INIT(tceptor)
	MDRV_VIDEO_START(tceptor)
	MDRV_VIDEO_UPDATE(tceptor)

	/* sound hardware */
	MDRV_SOUND_ATTRIBUTES(SOUND_SUPPORTS_STEREO)
	MDRV_SOUND_ADD(YM2151, ym2151_interface)
	MDRV_SOUND_ADD(NAMCO, namco_interface)
	MDRV_SOUND_ADD(DAC, dac_interface)
MACHINE_DRIVER_END


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

static DRIVER_INIT( tceptor )
{
	state_save_register_int("tceptor", 0, "m6809_irq_enable",  &m6809_irq_enable);
	state_save_register_int("tceptor", 0, "m68k_irq_enable",   &m68k_irq_enable);
	state_save_register_int("tceptor", 0, "mcu_irq_enable",    &mcu_irq_enable);
}


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

  Game driver(s)

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

ROM_START( tceptor )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )			// 68A09EP
	ROM_LOAD( "tc1-1.10f",  0x08000, 0x08000, 0x4C6B063E )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )			// RC65C02
	ROM_LOAD( "tc1-21.1m",  0x08000, 0x08000, 0x2D0B2FA8 )

	ROM_REGION( 0x10000, REGION_CPU3, 0 )			// RC65C02
	ROM_LOAD( "tc1-22.3m",  0x08000, 0x08000, 0x9F5A3E98 )

	ROM_REGION( 0x110000, REGION_CPU4, 0 )			// MC68000-12
	ROM_LOAD16_BYTE( "tc1-4.8c",     0x000000, 0x08000, 0xAE98B673 )
	ROM_LOAD16_BYTE( "tc1-3.10c",    0x000001, 0x08000, 0x779A4B25 )
	// socket 8d and 10d are emtpy

	ROM_REGION( 0x10000, REGION_CPU5, 0 )			// Custom 60A1
	ROM_LOAD( "tc1-2.3a",    0x08000, 0x4000, 0xB6DEF610 )
	ROM_LOAD( "pl1-mcu.bin", 0x0f000, 0x1000, 0x6ef08fb3 ) /* microcontroller */

	ROM_REGION( 0x02000, REGION_GFX1, ROMREGION_DISPOSE )	// text tilemap
	ROM_LOAD( "tc1-18.6b",  0x00000, 0x02000, 0x662B5650 )

	ROM_REGION( 0x10000, REGION_GFX2, ROMREGION_DISPOSE )	// background
	ROM_LOAD( "tc1-20.10e", 0x00000, 0x08000, 0x3E5054B7 )
	ROM_LOAD( "tc1-19.10d", 0x08000, 0x04000, 0x7406E6E7 )

	ROM_REGION( 0x10000, REGION_GFX3, ROMREGION_DISPOSE )	// 16x16 sprites
	ROM_LOAD( "tc1-16.8t",  0x00000, 0x08000, 0x7C72BE33 )
	ROM_LOAD( "tc1-15.10t", 0x08000, 0x08000, 0x51268075 )

	ROM_REGION( 0x80000, REGION_GFX4, ROMREGION_DISPOSE )	// 32x32 sprites
	ROM_LOAD( "tc1-8.8m",   0x00000, 0x10000, 0x192A1F1F )
	ROM_LOAD( "tc1-10.8p",  0x10000, 0x08000, 0x7876BCEF )
	ROM_RELOAD(             0x18000, 0x08000 )
	ROM_LOAD( "tc1-12.8r",  0x20000, 0x08000, 0xE8F55842 )
	ROM_RELOAD(             0x28000, 0x08000 )
	ROM_LOAD( "tc1-14.8s",  0x30000, 0x08000, 0x723ACF62 )
	ROM_RELOAD(             0x38000, 0x08000 )
	ROM_LOAD( "tc1-7.10m",  0x40000, 0x10000, 0x828C80D5 )
	ROM_LOAD( "tc1-9.10p",  0x50000, 0x08000, 0x145CF59B )
	ROM_RELOAD(             0x58000, 0x08000 )
	ROM_LOAD( "tc1-11.10r", 0x60000, 0x08000, 0xAD7C6C7E )
	ROM_RELOAD(             0x68000, 0x08000 )
	ROM_LOAD( "tc1-13.10s", 0x70000, 0x08000, 0xE67CEF29 )
	ROM_RELOAD(             0x78000, 0x08000 )

	ROM_REGION( 0x3600, REGION_PROMS, 0 )
	ROM_LOAD( "tc1-3.1k",   0x00000, 0x00400, 0xFD2FCB57 )	// red components
	ROM_LOAD( "tc1-1.1h",   0x00400, 0x00400, 0x0241CF67 )	// green components
	ROM_LOAD( "tc1-2.1j",   0x00800, 0x00400, 0xEA9EB3DA )	// blue components
	ROM_LOAD( "tc1-5.6a",   0x00c00, 0x00400, 0xAFA8EDA8 )	// tiles color table
	ROM_LOAD( "tc1-4.2e",   0x01000, 0x00100, 0xA4E73D53 )	// road color table
	ROM_LOAD( "tc1-6.7s",   0x01100, 0x00400, 0x72707677 )	// sprite color table
	ROM_LOAD( "tc1-17.7k",  0x01500, 0x02000, 0x90DB1BF6 )	// sprite related
ROM_END

ROM_START( tceptor2 )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )			// 68A09EP
	ROM_LOAD( "tc2-1.10f",  0x08000, 0x08000, 0xF953F153 )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )			// RC65C02
	ROM_LOAD( "tc1-21.1m",  0x08000, 0x08000, 0x2D0B2FA8 )

	ROM_REGION( 0x10000, REGION_CPU3, 0 )			// RC65C02
	ROM_LOAD( "tc1-22.3m",  0x08000, 0x08000, 0x9F5A3E98 )

	ROM_REGION( 0x110000, REGION_CPU4, 0 )			// MC68000-12
	ROM_LOAD16_BYTE( "tc2-4.8c",     0x000000, 0x08000, 0x6C2EFC04 )
	ROM_LOAD16_BYTE( "tc2-3.10c",    0x000001, 0x08000, 0x312B781A )
	ROM_LOAD16_BYTE( "tc2-6.8d",     0x100000, 0x08000, 0x20711F14 )
	ROM_LOAD16_BYTE( "tc2-5.10d",    0x100001, 0x08000, 0x925F2560 )

	ROM_REGION( 0x10000, REGION_CPU5, 0 )			// Custom 60A1
	ROM_LOAD( "tc1-2.3a",    0x08000, 0x4000, 0xB6DEF610 )
	ROM_LOAD( "pl1-mcu.bin", 0x0f000, 0x1000, 0x6ef08fb3 ) /* microcontroller */

	ROM_REGION( 0x02000, REGION_GFX1, ROMREGION_DISPOSE )	// text tilemap
	ROM_LOAD( "tc1-18.6b",  0x00000, 0x02000, 0x662B5650 )

	ROM_REGION( 0x10000, REGION_GFX2, ROMREGION_DISPOSE )	// background
	ROM_LOAD( "tc2-20.10e", 0x00000, 0x08000, 0xE72738FC )
	ROM_LOAD( "tc2-19.10d", 0x08000, 0x04000, 0x9C221E21 )

	ROM_REGION( 0x10000, REGION_GFX3, ROMREGION_DISPOSE )	// 16x16 sprites
	ROM_LOAD( "tc2-16.8t",  0x00000, 0x08000, 0xDCF4DA96 )
	ROM_LOAD( "tc2-15.10t", 0x08000, 0x08000, 0xFB0A9F89 )

	ROM_REGION( 0x80000, REGION_GFX4, ROMREGION_DISPOSE )	// 32x32 sprites
	ROM_LOAD( "tc2-8.8m",   0x00000, 0x10000, 0x03528D79 )
	ROM_LOAD( "tc2-10.8p",  0x10000, 0x10000, 0x561105EB )
	ROM_LOAD( "tc2-12.8r",  0x20000, 0x10000, 0x626CA8FB )
	ROM_LOAD( "tc2-14.8s",  0x30000, 0x10000, 0xB9EEC79D )
	ROM_LOAD( "tc2-7.10m",  0x40000, 0x10000, 0x0E3523E0 )
	ROM_LOAD( "tc2-9.10p",  0x50000, 0x10000, 0xCCFD9FF6 )
	ROM_LOAD( "tc2-11.10r", 0x60000, 0x10000, 0x40724380 )
	ROM_LOAD( "tc2-13.10s", 0x70000, 0x10000, 0x519EC7C1 )

	ROM_REGION( 0x3600, REGION_PROMS, 0 )
	ROM_LOAD( "tc2-3.1k",   0x00000, 0x00400, 0xE3504F1A )	// red components
	ROM_LOAD( "tc2-1.1h",   0x00400, 0x00400, 0xE8A96FDA )	// green components
	ROM_LOAD( "tc2-2.1j",   0x00800, 0x00400, 0xC65EDA61 )	// blue components
	ROM_LOAD( "tc1-5.6a",   0x00c00, 0x00400, 0xAFA8EDA8 )	// tiles color table
	ROM_LOAD( "tc2-4.2e",   0x01000, 0x00100, 0x6B49FC30 )	// road color table
	ROM_LOAD( "tc2-6.7s",   0x01100, 0x00400, 0xBADCDA76 )	// sprite color table
	ROM_LOAD( "tc1-17.7k",  0x01500, 0x02000, 0x90DB1BF6 )	// sprite related
ROM_END


/*  ( YEAR  NAME      PARENT    MACHINE   INPUT     INIT      MONITOR   COMPANY FULLNAME ) */
GAME( 1986, tceptor,  0,        tceptor,  tceptor,  tceptor,  ROT0,     "Namco",  "Thunder Ceptor")
GAME( 1986, tceptor2, tceptor,  tceptor,  tceptor2, tceptor,  ROT0,     "Namco",  "Thunder Ceptor II")
