#include "driver.h"
#include "cpu/m6502/m6502.h"
#include "video/crtc6845.h"
#include "sound/sn76477.h"
#include "sound/custom.h"
#include "sound/samples.h"

#ifndef M_LN2
#define M_LN2		0.69314718055994530942
#endif


/* video */

extern UINT8 *rockola_videoram2;
extern UINT8 *rockola_charram;

extern WRITE8_HANDLER( rockola_videoram_w );
extern WRITE8_HANDLER( rockola_videoram2_w );
extern WRITE8_HANDLER( rockola_colorram_w );
extern WRITE8_HANDLER( rockola_charram_w );
extern WRITE8_HANDLER( rockola_flipscreen_w );
extern WRITE8_HANDLER( rockola_scrollx_w );
extern WRITE8_HANDLER( rockola_scrolly_w );

extern PALETTE_INIT( rockola );
extern VIDEO_START( rockola );
extern VIDEO_UPDATE( rockola );

/* audio */

extern const char *vanguard_sample_names[];

extern WRITE8_HANDLER( vanguard_sound_w );
extern WRITE8_HANDLER( vanguard_speech_w );

void *rockola_sh_start(int clock, const struct CustomSound_interface *config);
void rockola_set_music_clock(double clock_time);
void rockola_set_music_freq(int freq);
int rockola_music0_playing(void);

/* IN2 + music0 playing */
static READ8_HANDLER( vanguard_port_3_r )
{
	return readinputport(3) | (rockola_music0_playing() ? 0x10 : 0x00);
}


/* Memory Maps */

static ADDRESS_MAP_START( vanguard_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x03ff) AM_RAM
	AM_RANGE(0x0400, 0x07ff) AM_RAM AM_WRITE(rockola_videoram2_w) AM_BASE(&rockola_videoram2)
	AM_RANGE(0x0800, 0x0bff) AM_RAM AM_WRITE(rockola_videoram_w) AM_BASE(&videoram)
	AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_WRITE(rockola_colorram_w) AM_BASE(&colorram)
	AM_RANGE(0x1000, 0x1fff) AM_RAM AM_WRITE(rockola_charram_w) AM_BASE(&rockola_charram)
	AM_RANGE(0x3000, 0x3000) AM_WRITE(crtc6845_address_w)
	AM_RANGE(0x3001, 0x3001) AM_WRITE(crtc6845_register_w)
	AM_RANGE(0x3100, 0x3102) AM_WRITE(vanguard_sound_w)
	AM_RANGE(0x3103, 0x3103) AM_WRITE(rockola_flipscreen_w)
	AM_RANGE(0x3104, 0x3104) AM_READ(input_port_0_r)	// IN0
	AM_RANGE(0x3105, 0x3105) AM_READ(input_port_1_r)	// IN1
	AM_RANGE(0x3106, 0x3106) AM_READ(input_port_2_r)	/* DSW */
	AM_RANGE(0x3107, 0x3107) AM_READ(vanguard_port_3_r)	// IN2 + music0 playing
	AM_RANGE(0x3200, 0x3200) AM_WRITE(rockola_scrollx_w)
	AM_RANGE(0x3300, 0x3300) AM_WRITE(rockola_scrolly_w)
	AM_RANGE(0x3400, 0x3400) AM_WRITE(vanguard_speech_w)	// speech
	AM_RANGE(0x4000, 0xbfff) AM_ROM
	AM_RANGE(0xf000, 0xffff) AM_ROM	/* for the reset / interrupt vectors */
ADDRESS_MAP_END


/* Input Ports */

/* Derived from Zarzon. Might not reflect the actual hardware. */

INPUT_PORTS_START( vanguard )
	PORT_START	// IN0
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 )
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON4 )
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 )
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY

	PORT_START	// IN1
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_COCKTAIL
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_COCKTAIL
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL

	PORT_START	// DSW0
	PORT_DIPNAME( 0x01, 0x01, DEF_STR( Cabinet ) )
	PORT_DIPSETTING(    0x01, DEF_STR( Upright ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Cocktail ) )
	PORT_DIPNAME( 0x4e, 0x02, DEF_STR( Coinage ) )
	PORT_DIPSETTING(    0x42, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x02, "1 Coin/1 Credit 2/3" )
	PORT_DIPSETTING(    0x00, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(    0x48, "1 Coin/2 Credits 2/5" )
	PORT_DIPSETTING(    0x08, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(    0x44, "1 Coin/3 Credits 2/7" )
	PORT_DIPSETTING(    0x04, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(    0x4c, "1 Coin/6 Credits 2/13" )
	PORT_DIPSETTING(    0x0c, DEF_STR( 1C_7C ) )
/*
    PORT_DIPSETTING(    0x06, DEF_STR( 1C_2C ) )
    PORT_DIPSETTING(    0x0a, DEF_STR( 1C_2C ) )
    PORT_DIPSETTING(    0x0e, DEF_STR( 1C_2C ) )
    PORT_DIPSETTING(    0x40, "1 Coin/1 Credit + Bonus" )
    PORT_DIPSETTING(    0x46, "1 Coin/1 Credit + Bonus" )
    PORT_DIPSETTING(    0x4a, "1 Coin/1 Credit + Bonus" )
    PORT_DIPSETTING(    0x4e, "1 Coin/1 Credit + Bonus" )
*/
	PORT_DIPNAME( 0x30, 0x00, DEF_STR( Lives ) )
	PORT_DIPSETTING(    0x00, "3" )
	PORT_DIPSETTING(    0x10, "4" )
	PORT_DIPSETTING(    0x20, "5" )
/*  PORT_DIPSETTING(    0x30, "3" ) */
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )

	PORT_START	// IN2
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_IMPULSE(1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_IMPULSE(1)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_SPECIAL )	/* music0 playing */
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START1 )
INPUT_PORTS_END


/* Graphics Layouts */

static const gfx_layout charlayout =
{
	8,8,    /* 8*8 characters */
	RGN_FRAC(1,2),
	2,      /* 2 bits per pixel */
	{ 0, RGN_FRAC(1,2) }, /* the two bitplanes are separated */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
	8*8     /* every char takes 8 consecutive bytes */
};

static const gfx_layout charlayout_memory =
{
	8,8,    /* 8*8 characters */
	256,	/* 256 characters */
	2,      /* 2 bits per pixel */
	{ 0, 256*8*8 }, /* the two bitplanes are separated */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
	8*8     /* every char takes 8 consecutive bytes */
};

/* Graphics Decode Information */

static GFXDECODE_START( vanguard )
	GFXDECODE_ENTRY( 0,           0x1000, charlayout_memory,   0, 8 )	/* the game dynamically modifies this */
	GFXDECODE_ENTRY( REGION_GFX1, 0x0000, charlayout,        8*4, 8 )
GFXDECODE_END

/* Sound Interfaces */

static struct CustomSound_interface custom_interface =
{
	rockola_sh_start
};

static struct Samplesinterface vanguard_samples_interface =
{
	3,	/* 3 channel */
	vanguard_sample_names
};

static struct SN76477interface vanguard_sn76477_intf_1 =
{
	RES_K(470),		/*  4  noise_res     */
	RES_M(1.5),		/*  5  filter_res    */
	CAP_P(220),		/*  6  filter_cap    */
	0,				/*  7  decay_res     */
	0,				/*  8  attack_decay_cap  */
	0,				/* 10  attack_res    */
	RES_K(47),		/* 11  amplitude_res     */
	RES_K(4.7),		/* 12  feedback_res      */
	0,				/* 16  vco_voltage   */
	0,				/* 17  vco_cap       */
	0,				/* 18  vco_res       */
	0,				/* 19  pitch_voltage     */
	0,				/* 20  slf_res       */
	0,				/* 21  slf_cap       */
	0,				/* 23  oneshot_cap   */
	0,				/* 24  oneshot_res   */
	0,			    /* 22  vco                    */
	0,				/* 26  mixer A           */
	1,				/* 25  mixer B           */
	0,				/* 27  mixer C           */
	1,				/* 1   envelope 1        */
	1,				/* 28  envelope 2        */
	1			    /* 9   enable (variable)      */

	// SHOT A   GND: 2,9,26,27  +5V: 15,25
};

static struct SN76477interface vanguard_sn76477_intf_2 =
{
	RES_K(10),		/*  4  noise_res     */
	RES_K(30),		/*  5  filter_res    */
	0,				/*  6  filter_cap    */
	0,				/*  7  decay_res     */
	0,				/*  8  attack_decay_cap  */
	0,				/* 10  attack_res    */
	RES_K(47),		/* 11  amplitude_res     */
	RES_K(4.7),		/* 12  feedback_res      */
	0,				/* 16  vco_voltage   */
	0,				/* 17  vco_cap       */
	0,				/* 18  vco_res       */
	0,				/* 19  pitch_voltage     */
	0,				/* 20  slf_res       */
	0,				/* 21  slf_cap       */
	0,				/* 23  oneshot_cap   */
	0,				/* 24  oneshot_res   */
	0,			    /* 22  vco                    */
	0,				/* 26  mixer A           */
	1,				/* 25  mixer B           */
	0,				/* 27  mixer C           */
	0,				/* 1   envelope 1        */
	1,				/* 28  envelope 2        */
	1			    /* 9   enable (variable)      */

	// SHOT B   GND: 1,2,26,27  +5V: 15,25,28
};

/* Interrupt Generators */

static INTERRUPT_GEN( rockola_interrupt )
{
	if (cpu_getiloops() != 0)
	{
		UINT8 val = readinputport(3);

		coin_counter_w(0, val & 1);
		coin_counter_w(1, val & 2);

		/* user asks to insert coin: generate a NMI interrupt. */
		if (val & 0x03)
			cpunum_set_input_line(0, INPUT_LINE_NMI, PULSE_LINE);
	}
	else
		cpunum_set_input_line(0, M6502_IRQ_LINE, HOLD_LINE);	/* one IRQ per frame */
}

/* Machine Initialization */

static MACHINE_RESET( vanguard )
{
	// 41.6 Hz update (measured)
	rockola_set_music_clock(1 / 41.6);
}


/* Machine Drivers */


static MACHINE_DRIVER_START( vanguard )
	// basic machine hardware
	//MDRV_CPU_ADD_TAG("main", M6502, 11289000/8)   // 1.4 MHz
	MDRV_CPU_ADD_TAG("main", M6502, 930000)		// adjusted
	MDRV_CPU_PROGRAM_MAP(vanguard_map, 0)
	MDRV_CPU_VBLANK_INT(rockola_interrupt, 2)

	MDRV_SCREEN_REFRESH_RATE((11289000.0 / 16) / (45 * 32 * 8))
	MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)

	MDRV_MACHINE_RESET(vanguard)

	// video hardware
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MDRV_SCREEN_SIZE(32*8, 32*8)
	MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
	MDRV_GFXDECODE(vanguard)
	MDRV_PALETTE_LENGTH(64)
	MDRV_COLORTABLE_LENGTH(16*4)

	MDRV_PALETTE_INIT(rockola)
	MDRV_VIDEO_START(rockola)
	MDRV_VIDEO_UPDATE(rockola)

	// sound hardware
	MDRV_SPEAKER_STANDARD_MONO("mono")

	MDRV_SOUND_ADD(CUSTOM, 0)
	MDRV_SOUND_CONFIG(custom_interface)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)

	MDRV_SOUND_ADD_TAG("samples", SAMPLES, 0)
	MDRV_SOUND_CONFIG(vanguard_samples_interface)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)

	MDRV_SOUND_ADD_TAG("SN76477.1", SN76477, 0)
	MDRV_SOUND_CONFIG(vanguard_sn76477_intf_1)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)

	MDRV_SOUND_ADD_TAG("SN76477.2", SN76477, 0)
	MDRV_SOUND_CONFIG(vanguard_sn76477_intf_2)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MACHINE_DRIVER_END

/* Misfitmame start */

ROM_START( vantris )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )	/* 64k for code */
	ROM_LOAD( "sk4_ic07.bin", 0x4000, 0x1000, CRC(6a29e354) SHA1(ff953962ebc14a28cfc96f8e269cb1e1c188ed8a) )
	ROM_LOAD( "sk4_ic08.bin", 0x5000, 0x1000, CRC(302bba54) SHA1(1944f229481328a0635fafda65054106f42a532a) )
	ROM_LOAD( "sk4_ic09.bin", 0x6000, 0x1000, CRC(424755f6) SHA1(b4762b40c7ed70d4b90319a1a30983a41a096afb) )
	ROM_LOAD( "sk4_ic10.bin", 0x7000, 0x1000, CRC(54603274) SHA1(31571a560dbe300417b3ed5b114fa1d9ef742da9) )
	ROM_LOAD( "vtr4_ic13.bin", 0x8000, 0x1000, CRC(f9f367a5 ))
	ROM_RELOAD(               0xf000, 0x1000 )	/* for the reset and interrupt vectors */
	ROM_LOAD( "sk4_ic14.bin", 0x9000, 0x1000, CRC(0d5b47d0) SHA1(922621c23f33fe756cb6baa12e5465c4e64f2dda) )
	ROM_LOAD( "sk4_ic15.bin", 0xa000, 0x1000, CRC(8549b8f8) SHA1(375bc6f7e15564d5cf7e00c44e2651793c56d6ca) )
	ROM_LOAD( "sk4_ic16.bin", 0xb000, 0x1000, CRC(062e0be2) SHA1(45aaf315a62f37460e32d3ba99caaacf4c994810) )

	ROM_REGION( 0x1000, REGION_GFX1, ROMREGION_DISPOSE )
	ROM_LOAD( "vtr5_ic50.bin", 0x0000, 0x0800, CRC(a7061526) SHA1(f5f5860a9dc468cb4177348e0b0592e5adda28f1) )
	ROM_LOAD( "vtr5_ic51.bin", 0x0800, 0x0800, CRC(67bd31ed) SHA1(24f03cf097e5382500a85483351f21913a98fdd5) )

	ROM_REGION( 0x0040, REGION_PROMS, 0 )
	ROM_LOAD( "vtr5_ic7.bin", 0x0000, 0x0020, CRC(90f17fc1) SHA1(fc92864178cbceccd6f7f2c75249b5c568bdbea8) ) /* foreground colors */
	ROM_LOAD( "vtr5_ic6.bin", 0x0020, 0x0020, CRC(90f17fc1) SHA1(fc92864178cbceccd6f7f2c75249b5c568bdbea8) ) /* background colors */

	ROM_REGION( 0x1000, REGION_SOUND1, 0 )	/* sound ROMs */
	ROM_LOAD( "vtr4_ic51.bin", 0x0000, 0x0800, CRC(fd4d8bb0) SHA1(d59ec7569147263aed50041b15aed2ca4f395c23) ) /* sound ROM 1 */
	ROM_LOAD( "vtr4_ic52.bin", 0x0800, 0x0800, CRC(cc4a0b6f) SHA1(251b24d60083d516c4ba686d75b41e04d10f7198) ) /* sound ROM 2 */

	ROM_REGION( 0x5800, REGION_SOUND2, 0 )	/* space for the speech ROMs (not supported) */
	//ROM_LOAD( "hd38882.bin",  0x0000, 0x4000, NO_DUMP )	/* HD38882 internal ROM */
	ROM_LOAD_OPTIONAL( "sk6_ic07.bin", 0x4000, 0x0800, CRC(2b7cbae9) SHA1(3d44a0232d7c94d8170cc06e90cc30bd57c99202) )
	ROM_LOAD_OPTIONAL( "sk6_ic08.bin", 0x4800, 0x0800, CRC(3b7e9d7c) SHA1(d9033188068b2aaa1502c89cf09f955eded8fa7a) )
	ROM_LOAD_OPTIONAL( "sk6_ic11.bin", 0x5000, 0x0800, CRC(c36df041) SHA1(8b51934229b961180d1edb99be3a4d337d37f66f) )
ROM_END

GAME( 1981, vantris,  0,        vanguard, vanguard, 0, ROT90, "SNK", "Vantris Tetris Hack", 0 )
/* Misfitmame end */
