#include "driver.h"
#include "sound/ay8910.h"
#include "sound/dac.h"
#include "sound/samples.h"
#include "sound/sp0250.h"


extern UINT8 *gottlieb_charram;

extern WRITE8_HANDLER( gottlieb_videoram_w );
extern WRITE8_HANDLER( gottlieb_charram_w );
extern WRITE8_HANDLER( gottlieb_video_outputs_w );
extern WRITE8_HANDLER( usvsthem_video_outputs_w );
extern WRITE8_HANDLER( gottlieb_paletteram_w );

extern VIDEO_START( gottlieb );
extern VIDEO_UPDATE( gottlieb );

extern WRITE8_HANDLER( gottlieb_sh_w );

extern UINT8 *riot_ram;
extern READ8_HANDLER( riot_ram_r );
extern READ8_HANDLER( gottlieb_riot_r );
extern WRITE8_HANDLER( riot_ram_w );
extern WRITE8_HANDLER( gottlieb_riot_w );
extern WRITE8_HANDLER( gottlieb_speech_w );
extern WRITE8_HANDLER( gottlieb_speech_clock_DAC_w );
extern void gottlieb_sound_init(void);
extern WRITE8_HANDLER( gottlieb_nmi_rate_w );
extern WRITE8_HANDLER( gottlieb_cause_dac_nmi_w );


static UINT8 *audiobuffer_region;

MACHINE_RESET( gottlieb )
{
	audiobuffer_region = memory_region(REGION_USER1);
}


static int track[2];

READ8_HANDLER( gottlieb_track_0_r )
{
	return input_port_2_r(offset) - track[0];
}

READ8_HANDLER( gottlieb_track_1_r )
{
	return input_port_3_r(offset) - track[1];
}

WRITE8_HANDLER( gottlieb_track_reset_w )
{
	/* reset the trackball counters */
	track[0] = input_port_2_r(offset);
	track[1] = input_port_3_r(offset);
}

WRITE8_HANDLER( reactor_output_w )
{
	set_led_status(0,data & 0x20);
	set_led_status(1,data & 0x40);
	set_led_status(2,data & 0x80);
	gottlieb_video_outputs_w(offset,data);
}

static int current_frame = 1;
static int laserdisc_playing;
static int lasermpx;
static int audioptr;
static int audioready=1;
static int skipfirstbyte;
static int discready;
static int lastcmd;
static int odd_field;
static int access_time;


/* The only sure thing I know about the Philips 24-bit frame number code is that the
 * 4 most significant bits are 1's and these four 1's are used to detect a valid frame
 * number when shifting bits from right to left...
 * From the audio code it seems it's a simple BCD numbering...
 * (what happens when four consecutive 1's are inside the number, eg 00078 ?)
 * Only 19 bits are returned to the game machine, this gives a max frame number of 79999.
 * The size of the audio buffer is 1024 bytes. When it is full, the "audio buffer ready"
 * flag is raised, and the frame decoder tries again to synchronize with a 0x67 pattern
 * Each 1024-byte buffer contains target data for 53 frames;
 * target data for each frame is 19-bytes long including one byte of checksum
 * and the frame number code of the first of these 53 frames is stored at the beginning
 * This gives a total of 1+3+3+19*53=1014 bytes, the 10 last bytes are ignored
 */

READ8_HANDLER( gottlieb_laserdisc_status_r )
{
	int tmp;
	switch (offset)
	{
		case 0:
			tmp = current_frame % 100;
			logerror("LSB frame read: %d\n",tmp);
			return ((tmp / 10) << 4) | (tmp % 10);
			break;
		case 1:
			tmp = (current_frame / 100) % 100;
			logerror("MSB frame read: %d\n",tmp);
			return ((tmp / 10) << 4) | (tmp % 10);
			break;
		case 2:
			if (lasermpx == 1) {
				/* bits 0-2 frame number MSN */
				/* bit 3 audio buffer ready */
				/* bit 4 ready to send new laserdisc command? */
				/* bit 5 disc ready */
				/* bit 6 break in audio trasmission */
				/* bit 7 missing audio clock */
				return ((current_frame / 10000) & 0x7) | (audioready << 3) | 0x10 | (discready << 5);
			} else {	/* read audio buffer */
				if (skipfirstbyte) audioptr++;
				skipfirstbyte = 0;
				if (audiobuffer_region) {
					logerror("audio bufread: %02x\n",audiobuffer_region[audioptr]);
					return audiobuffer_region[audioptr++];
				} else {
					logerror("audiobuffer is null !!");
					return 0xFF; /* don't know what to do in this case ;-) */
				}
			}
			break;
	}

	return 0;
}

WRITE8_HANDLER( gottlieb_laserdisc_mpx_w )
{
	lasermpx = data & 1;
	if (lasermpx==0) skipfirstbyte=1;	/* first byte of the 1K buffer (0x67) is not returned... */
}

WRITE8_HANDLER( gottlieb_laserdisc_command_w )
{
	static int loop;
	int cmd;

	/* commands are written in three steps, the first two the command is */
	/* written (maybe one to load the latch, the other to start the send), */
	/* the third 0 (maybe to clear the latch) */
	if (data == 0) return;
	if (loop++ & 1) return;

	if ((data & 0xe0) != 0x20)
	{
logerror("error: laserdisc command %02x\n",data);
		return;
	}

	cmd =	((data & 0x10) >> 4) |
			((data & 0x08) >> 2) |
			((data & 0x04) >> 0) |
			((data & 0x02) << 2) |
			((data & 0x01) << 4);

logerror("laserdisc command %02x -> %02x\n",data,cmd);
	if (lastcmd == 0x0b && (cmd & 0x10))	/* seek frame # */
	{
		current_frame = current_frame * 10 + (cmd & 0x0f);
		while (current_frame >= 100000)
			current_frame -= 100000;
		audioptr = -1;
	}
	else
	{
		if (cmd == 0x04)					/* step forward */
		{
			laserdisc_playing = 0;
			current_frame++;
		}
		if (cmd == 0x05) 					/* play */
		{
			laserdisc_playing = 1;
			discready = 1;
		}
		if (cmd == 0x0b)					/* seek frame */
		{
			laserdisc_playing = 0;
			discready = 0;
			access_time = 60;		/* 1s access time */
		}
		if (cmd == 0x0f)	 				/* stop */
		{
			laserdisc_playing = 0;
			discready = 0;
		}
		lastcmd = cmd;
	}
}

INTERRUPT_GEN( gottlieb_interrupt )
{
	if (access_time > 0) {
		access_time--;
		if (access_time == 0)
			discready = 1;
	} else if (laserdisc_playing) {
		odd_field ^= 1;
		if (odd_field)		/* the manual says the video frame number is only present in the odd field) */
		{
			current_frame++;
logerror("current frame : %d\n",current_frame);

			if (current_frame%53==0)
			{
				int seq = current_frame / 53;
				if (seq >= 44) {	/* 44*53 frames without target data at the beginning of the disc */
					audioptr = (seq - 44)*1024;
					audioready = 1;
				}
			}
			else audioready = 0;
		}
	}
	cpunum_set_input_line(0, INPUT_LINE_NMI, PULSE_LINE);
}


static ADDRESS_MAP_START( reactor_map, ADDRESS_SPACE_PROGRAM, 8 )
	ADDRESS_MAP_FLAGS( AMEF_ABITS(16) )
	AM_RANGE(0x00000, 0x01fff) AM_RAM
	AM_RANGE(0x02000, 0x020ff) AM_WRITE(MWA8_RAM) AM_BASE(&spriteram) AM_SIZE(&spriteram_size)
	AM_RANGE(0x03000, 0x033ff) AM_MIRROR(0x0400) AM_READWRITE(MRA8_RAM, gottlieb_videoram_w) AM_BASE(&videoram)
	AM_RANGE(0x04000, 0x04fff) AM_READWRITE(MRA8_RAM, gottlieb_charram_w) AM_BASE(&gottlieb_charram)
	AM_RANGE(0x06000, 0x0601f) AM_WRITE(gottlieb_paletteram_w) AM_BASE(&paletteram)
	AM_RANGE(0x07000, 0x07000) AM_READWRITE(input_port_0_r, watchdog_reset_w)	/* DSW */
	AM_RANGE(0x07001, 0x07001) AM_READWRITE(input_port_1_r, gottlieb_track_reset_w)	/* buttons */
	AM_RANGE(0x07002, 0x07002) AM_READWRITE(gottlieb_track_0_r, gottlieb_sh_w)	/* trackball H */
	AM_RANGE(0x07003, 0x07003) AM_READWRITE(gottlieb_track_1_r, reactor_output_w)	/* trackball V */
	AM_RANGE(0x07004, 0x07004) AM_READ(input_port_4_r)	/* joystick */
	AM_RANGE(0x08000, 0x0ffff) AM_ROM
ADDRESS_MAP_END


static ADDRESS_MAP_START( gottlieb_map, ADDRESS_SPACE_PROGRAM, 8 )
	ADDRESS_MAP_FLAGS( AMEF_ABITS(16) )
	AM_RANGE(0x00000, 0x00fff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
	AM_RANGE(0x01000, 0x01fff) AM_RAM AM_REGION(REGION_CPU1, 0x1000)	/* or ROM */
	AM_RANGE(0x02000, 0x02fff) AM_RAM AM_REGION(REGION_CPU1, 0x2000) 	/* or ROM */
	AM_RANGE(0x03000, 0x037ff) AM_RAM AM_BASE(&spriteram) AM_SIZE(&spriteram_size)	// argusg wants to check this
	AM_RANGE(0x03800, 0x03bff) AM_MIRROR(0x0400) AM_READWRITE(MRA8_RAM, gottlieb_videoram_w) AM_BASE(&videoram)
	AM_RANGE(0x04000, 0x04fff) AM_READWRITE(MRA8_RAM, gottlieb_charram_w) AM_BASE(&gottlieb_charram)
	AM_RANGE(0x05000, 0x0501f) AM_WRITE(gottlieb_paletteram_w) AM_BASE(&paletteram)
	AM_RANGE(0x05800, 0x05800) AM_READWRITE(input_port_0_r, watchdog_reset_w)	/* DSW */
	AM_RANGE(0x05801, 0x05801) AM_READWRITE(input_port_1_r, gottlieb_track_reset_w)	/* buttons */
	AM_RANGE(0x05802, 0x05802) AM_READWRITE(gottlieb_track_0_r, gottlieb_sh_w)	/* trackball H */
	AM_RANGE(0x05803, 0x05803) AM_READWRITE(gottlieb_track_1_r, gottlieb_video_outputs_w)	/* trackball V */
	AM_RANGE(0x05804, 0x05804) AM_READ(input_port_4_r)	/* joystick */
	AM_RANGE(0x05805, 0x05807) AM_READ(gottlieb_laserdisc_status_r)
	AM_RANGE(0x06000, 0x0ffff) AM_ROM
ADDRESS_MAP_END


ADDRESS_MAP_START( gottlieb_sound_readmem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x01ff) AM_READ(riot_ram_r)
	AM_RANGE(0x0200, 0x03ff) AM_READ(gottlieb_riot_r)
	AM_RANGE(0x6000, 0x7fff) AM_READ(MRA8_ROM)
			 /* A15 not decoded except in expansion socket */
	AM_RANGE(0x8000, 0x81ff) AM_READ(riot_ram_r)
	AM_RANGE(0x8200, 0x83ff) AM_READ(gottlieb_riot_r)
	AM_RANGE(0xe000, 0xffff) AM_READ(MRA8_ROM)
ADDRESS_MAP_END

ADDRESS_MAP_START( gottlieb_sound_writemem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x01ff) AM_WRITE(riot_ram_w) AM_BASE(&riot_ram)
	AM_RANGE(0x0200, 0x03ff) AM_WRITE(gottlieb_riot_w)
	AM_RANGE(0x1000, 0x1000) AM_WRITE(DAC_0_data_w)
	AM_RANGE(0x2000, 0x2000) AM_WRITE(gottlieb_speech_w)
	AM_RANGE(0x3000, 0x3000) AM_WRITE(gottlieb_speech_clock_DAC_w)
	AM_RANGE(0x6000, 0x7fff) AM_WRITE(MWA8_ROM)
			 /* A15 not decoded except in expansion socket */
	AM_RANGE(0x8000, 0x81ff) AM_WRITE(riot_ram_w)
	AM_RANGE(0x8200, 0x83ff) AM_WRITE(gottlieb_riot_w)
	AM_RANGE(0x9000, 0x9000) AM_WRITE(DAC_0_data_w)
	AM_RANGE(0xa000, 0xa000) AM_WRITE(gottlieb_speech_w)
	AM_RANGE(0xb000, 0xb000) AM_WRITE(gottlieb_speech_clock_DAC_w)
	AM_RANGE(0xe000, 0xffff) AM_WRITE(MWA8_ROM)
ADDRESS_MAP_END


INPUT_PORTS_START( reactor )
	PORT_START_TAG("DSW")
	PORT_DIPNAME( 0x01, 0x01, "Sound with Logos" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x01, DEF_STR( On ) )
	PORT_DIPNAME( 0x02, 0x02, "Bounce Chambers Points" )
	PORT_DIPSETTING(    0x00, "10" )
	PORT_DIPSETTING(    0x02, "15" )
	PORT_DIPNAME( 0x04, 0x04, DEF_STR( Free_Play ) )
	PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x08, 0x08, "Sound with Instructions" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x08, DEF_STR( On ) )
	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Cabinet ) )
	PORT_DIPSETTING(    0x10, DEF_STR( Upright ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Cocktail ) )
	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Coinage ) )
	PORT_DIPSETTING(    0x00, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(    0x20, DEF_STR( 1C_1C ) )
	PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Bonus_Life ) )
	PORT_DIPSETTING(    0x00, "10000" )
	PORT_DIPSETTING(    0x40, "12000" )
	PORT_DIPSETTING(    0xc0, "15000" )
	PORT_DIPSETTING(    0x80, "20000" )

	PORT_START_TAG("IN1")
	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Select in Service Mode") PORT_CODE(KEYCODE_F1)
	PORT_SERVICE( 0x02, IP_ACTIVE_LOW )
	PORT_BIT ( 0xfc, IP_ACTIVE_HIGH, IPT_UNKNOWN )

	PORT_START_TAG("IN2")	/* trackball H */
	PORT_BIT( 0xff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(15) PORT_KEYDELTA(20)

	PORT_START_TAG("IN3")	/* trackball V */
	PORT_BIT( 0xff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(15) PORT_KEYDELTA(20)

	PORT_START_TAG("IN4")
	PORT_BIT ( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
	PORT_BIT ( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT ( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 )
	PORT_BIT ( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 )
	PORT_BIT ( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
	PORT_BIT ( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
	PORT_BIT ( 0xc0, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END

INPUT_PORTS_START( qbert )
	PORT_START_TAG("DSW")
	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
	PORT_DIPNAME( 0x02, 0x02, "Kicker" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x02, DEF_STR( On ) )
	PORT_DIPNAME( 0x04, 0x00, DEF_STR( Cabinet ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
	PORT_DIPSETTING(    0x04, DEF_STR( Cocktail ) )
	PORT_DIPNAME( 0x08, 0x00, "Auto Round Advance (Cheat)")
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x08, DEF_STR( On ) )
	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Free_Play ) )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
	PORT_DIPNAME( 0x20, 0x00, "SW5" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
	PORT_DIPNAME( 0x40, 0x00, "SW7" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x40, DEF_STR( On ) )
	PORT_DIPNAME( 0x80, 0x00, "SW8" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x80, DEF_STR( On ) )
	PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
/* 0x40 must be connected to the IP16 line */

	PORT_START_TAG("IN1")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN1 )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN2 )
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
	PORT_SERVICE( 0x40, IP_ACTIVE_LOW )
	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Select in Service Mode") PORT_CODE(KEYCODE_F1)

	PORT_START_TAG("IN2")	/* trackball H not used */
	PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START_TAG("IN3")	/* trackball V not used */
	PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START_TAG("IN4")      /* joystick */
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
INPUT_PORTS_END


/* the games can store char gfx data in either a 4k RAM area (128 chars), or */
/* a 8k ROM area (256 chars). */
static const gfx_layout charRAMlayout =
{
	8,8,    /* 8*8 characters */
	128,    /* 128 characters */
	4,      /* 4 bits per pixel */
	{ 0, 1, 2, 3 },
	{ 0, 4, 8, 12, 16, 20, 24, 28},
	{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
	32*8    /* every char takes 32 consecutive bytes */
};

static const gfx_layout charROMlayout =
{
	8,8,    /* 8*8 characters */
	256,    /* 256 characters */
	4,      /* 4 bits per pixel */
	{ 0, 1, 2, 3 },
	{ 0, 4, 8, 12, 16, 20, 24, 28},
	{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
	32*8    /* every char takes 32 consecutive bytes */
};

static const gfx_layout spritelayout =
{
	16,16,
	RGN_FRAC(1,4),
	4,      /* 4 bits per pixel */
	{ RGN_FRAC(0,4), RGN_FRAC(1,4), RGN_FRAC(2,4), RGN_FRAC(3,4) },
	{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16,
			8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16 },
	32*8
};

static GFXDECODE_START( charRAM )
	GFXDECODE_ENTRY( 0,           0x4000, charRAMlayout, 0, 1 )	/* the game dynamically modifies this */
	GFXDECODE_ENTRY( REGION_GFX2, 0x0000, spritelayout,  0, 1 )
GFXDECODE_END

static GFXDECODE_START( charROM )
	GFXDECODE_ENTRY( REGION_GFX1, 0x0000, charROMlayout, 0, 1 )
	GFXDECODE_ENTRY( REGION_GFX2, 0x0000, spritelayout,  0, 1 )
GFXDECODE_END


static const char *reactor_sample_names[] =
{
	"*reactor",
	"fx_53.wav", /* "8 left" */
	"fx_54.wav", /* "16 left" */
	"fx_55.wav", /* "24 left" */
	"fx_56.wav", /* "32 left" */
	"fx_57.wav", /* "40 left" */
	"fx_58.wav", /* "warning, core unstable" */
	"fx_59.wav", /* "bonus" */
	"fx_31.wav", /* "chamber activated" */
	"fx_39a.wav", /* "2000" */
	"fx_39b.wav", /* "5000" */
	"fx_39c.wav", /* "10000" */
	"fx_39d.wav", /* "15000" */
	"fx_39e.wav", /* "20000" */
	"fx_39f.wav", /* "25000" */
	"fx_39g.wav", /* "30000" */
	"fx_39h.wav", /* "35000" */
	"fx_39i.wav", /* "40000" */
	"fx_39j.wav", /* "45000" */
	"fx_39k.wav", /* "50000" */
	"fx_39l.wav", /* "55000" */
     0	/* end of array */
};

static const char *qbert_sample_names[] =
{
	"*qbert",
	"fx_17a.wav", /* random speech, voice clock 255 */
	"fx_17b.wav", /* random speech, voice clock 255 */
	"fx_17c.wav", /* random speech, voice clock 255 */
	"fx_17d.wav", /* random speech, voice clock 255 */
	"fx_17e.wav", /* random speech, voice clock 255 */
	"fx_17f.wav", /* random speech, voice clock 255 */
	"fx_17g.wav", /* random speech, voice clock 255 */
	"fx_17h.wav", /* random speech, voice clock 255 */
	"fx_18a.wav", /* random speech, voice clock 176 */
	"fx_18b.wav", /* random speech, voice clock 176 */
	"fx_18c.wav", /* random speech, voice clock 176 */
	"fx_18d.wav", /* random speech, voice clock 176 */
	"fx_18e.wav", /* random speech, voice clock 176 */
	"fx_18f.wav", /* random speech, voice clock 176 */
	"fx_18g.wav", /* random speech, voice clock 176 */
	"fx_18h.wav", /* random speech, voice clock 176 */
	"fx_19a.wav", /* random speech, voice clock 128 */
	"fx_19b.wav", /* random speech, voice clock 128 */
	"fx_19c.wav", /* random speech, voice clock 128 */
	"fx_19d.wav", /* random speech, voice clock 128 */
	"fx_19e.wav", /* random speech, voice clock 128 */
	"fx_19f.wav", /* random speech, voice clock 128 */
	"fx_19g.wav", /* random speech, voice clock 128 */
	"fx_19h.wav", /* random speech, voice clock 128 */
	"fx_20a.wav", /* random speech, voice clock 96 */
	"fx_20b.wav", /* random speech, voice clock 96 */
	"fx_20c.wav", /* random speech, voice clock 96 */
	"fx_20d.wav", /* random speech, voice clock 96 */
	"fx_20e.wav", /* random speech, voice clock 96 */
	"fx_20f.wav", /* random speech, voice clock 96 */
	"fx_20g.wav", /* random speech, voice clock 96 */
	"fx_20h.wav", /* random speech, voice clock 96 */
	"fx_21a.wav", /* random speech, voice clock 62 */
	"fx_21b.wav", /* random speech, voice clock 62 */
	"fx_21c.wav", /* random speech, voice clock 62 */
	"fx_21d.wav", /* random speech, voice clock 62 */
	"fx_21e.wav", /* random speech, voice clock 62 */
	"fx_21f.wav", /* random speech, voice clock 62 */
	"fx_21g.wav", /* random speech, voice clock 62 */
	"fx_21h.wav", /* random speech, voice clock 62 */
	"fx_22.wav", /* EH2 with decreasing voice clock */
	"fx_23.wav", /* O1 with varying voice clock */
	"fx_28.wav", /* "hello, I'm ready" */
	"fx_36.wav", /* "byebye" */
	"knocker.wav",
	0	/* end of array */
};

static struct Samplesinterface qbert_samples_interface =
{
 	1,	/* one channel */
	qbert_sample_names
};

static struct Samplesinterface reactor_samples_interface =
{
	1,	/* one channel */
	reactor_sample_names
};

#define gottlieb_samples_interface qbert_samples_interface	/* not used */
#define krull_samples_interface qbert_samples_interface		/* not used */


/********************************************************************
*
*  Machine Driver macro
*  ====================
*
*  There are two versions of the machine driver,
*  one for revision 1 sound board (1x6502 + DAC + Votrax),
*  one for revision 2 (2x6502 + DAC + GI SP-0250 speech chip + 2x8910).
*  They are identical apart form the sound CPU subsections.
*
********************************************************************/

/* games using the revision 1 sound board */
static MACHINE_DRIVER_START( gottlieb )

	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", I8088, 5000000)	/* 5 MHz */
	MDRV_CPU_PROGRAM_MAP(gottlieb_map,0)
	MDRV_CPU_VBLANK_INT(gottlieb_interrupt,1)

	MDRV_CPU_ADD_TAG("sound", M6502, 3579545/4)	/* the board can be set to /2 as well */
	/* audio CPU */
	MDRV_CPU_PROGRAM_MAP(gottlieb_sound_readmem,gottlieb_sound_writemem)
								/* NMIs are triggered by the Votrax SC-01 */
	MDRV_SCREEN_REFRESH_RATE(61)
	MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1018)	/* frames per second, vblank duration */)

	MDRV_MACHINE_RESET(gottlieb)
	MDRV_NVRAM_HANDLER(generic_1fill)

	/* 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, 30*8-1)
	MDRV_GFXDECODE(charROM)
	MDRV_PALETTE_LENGTH(16)

	MDRV_VIDEO_START(gottlieb)
	MDRV_VIDEO_UPDATE(gottlieb)

	/* sound hardware */
	MDRV_SPEAKER_STANDARD_MONO("mono")

	MDRV_SOUND_ADD(DAC, 0)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_DRIVER_END


static MACHINE_DRIVER_START( reactor )

	/* basic machine hardware */
	MDRV_IMPORT_FROM(gottlieb)
	MDRV_CPU_MODIFY("main")
	MDRV_CPU_PROGRAM_MAP(reactor_map,0)

	MDRV_NVRAM_HANDLER(NULL)

	/* video hardware */
	MDRV_GFXDECODE(charRAM)

	MDRV_SOUND_ADD(SAMPLES, 0)
	MDRV_SOUND_CONFIG(reactor_samples_interface)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_DRIVER_END


static MACHINE_DRIVER_START( qbert )

	/* basic machine hardware */
	MDRV_IMPORT_FROM(gottlieb)

	/* video hardware */
	MDRV_SOUND_ADD(SAMPLES, 0)
	MDRV_SOUND_CONFIG(qbert_samples_interface)
	MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_DRIVER_END



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

  Game driver(s)

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


ROM_START( qbert )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for code */
	ROM_LOAD( "qb-rom2.bin",  0xa000, 0x2000, CRC(fe434526) SHA1(4cfc5d52dd6c82163e035af82d6112c0c93a3797) )
	ROM_LOAD( "qb-rom1.bin",  0xc000, 0x2000, CRC(55635447) SHA1(ca6acdef1c9e06b33efe1f0a2df2dfb03723cfbe) )
	ROM_LOAD( "qb-rom0.bin",  0xe000, 0x2000, CRC(8e318641) SHA1(7f8f66d1e6a7905e93cce07fc92e8801370b7194) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )	/* 64k for sound cpu */
	ROM_LOAD( "qb-snd1.bin",  0xf000, 0x800, CRC(15787c07) SHA1(8b7d03fbf2ebaa71b3a7e2f636a0d1bb9b796e43) )
	ROM_RELOAD(               0x7000, 0x800 ) /* A15 is not decoded */
	ROM_LOAD( "qb-snd2.bin",  0xf800, 0x800, CRC(58437508) SHA1(09d8053e7e99679b602dcda230d64db7fe6cb7f5) )
	ROM_RELOAD(               0x7800, 0x800 ) /* A15 is not decoded */

	ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE )
	ROM_LOAD( "qb-bg0.bin",   0x0000, 0x1000, CRC(7a9ba824) SHA1(12aa6df499eb6996ee35f56acac403ff6290f844) )	/* chars */
	ROM_LOAD( "qb-bg1.bin",   0x1000, 0x1000, CRC(22e5b891) SHA1(5bb67e333255c0ea679ab4312256a8a71a950db8) )

	ROM_REGION( 0x8000, REGION_GFX2, ROMREGION_DISPOSE )
	ROM_LOAD( "qb-fg3.bin",   0x0000, 0x2000, CRC(dd436d3a) SHA1(ae16087a6ceec84551b5d7aae4036e0ed432cbb7) )	/* sprites */
	ROM_LOAD( "qb-fg2.bin",   0x2000, 0x2000, CRC(f69b9483) SHA1(06894a1474c79c1274efbd32d7371179e7e0a661) )
	ROM_LOAD( "qb-fg1.bin",   0x4000, 0x2000, CRC(224e8356) SHA1(f7f26b879aa8b964ff6311136ed8157e44de736c) )
	ROM_LOAD( "qb-fg0.bin",   0x6000, 0x2000, CRC(2f695b85) SHA1(807d16459838f129e10b913890bbc95065d5dd40) )
ROM_END

GAME( 1982, qbert,    0,        qbert,    qbert,    0,        ROT270, "Gottlieb", "Q*bert (US set 1)", 0 )

/* Misfitmame start */

static ADDRESS_MAP_START( reacths_map, ADDRESS_SPACE_PROGRAM, 8 )
	ADDRESS_MAP_FLAGS( AMEF_ABITS(16) )
	AM_RANGE(0x00000, 0x003ff) AM_RAM
	AM_RANGE(0x00400, 0x007ff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
	AM_RANGE(0x00800, 0x01fff) AM_RAM
	AM_RANGE(0x02000, 0x020ff) AM_WRITE(MWA8_RAM) AM_BASE(&spriteram) AM_SIZE(&spriteram_size)
	AM_RANGE(0x03000, 0x033ff) AM_MIRROR(0x0400) AM_READWRITE(MRA8_RAM, gottlieb_videoram_w) AM_BASE(&videoram)
	AM_RANGE(0x04000, 0x04fff) AM_READWRITE(MRA8_RAM, gottlieb_charram_w) AM_BASE(&gottlieb_charram)
	AM_RANGE(0x06000, 0x0601f) AM_WRITE(gottlieb_paletteram_w) AM_BASE(&paletteram)
	AM_RANGE(0x07000, 0x07000) AM_READWRITE(input_port_0_r, watchdog_reset_w)	/* DSW */
	AM_RANGE(0x07001, 0x07001) AM_READWRITE(input_port_1_r, gottlieb_track_reset_w)	/* buttons */
	AM_RANGE(0x07002, 0x07002) AM_READWRITE(gottlieb_track_0_r, gottlieb_sh_w)	/* trackball H */
	AM_RANGE(0x07003, 0x07003) AM_READWRITE(gottlieb_track_1_r, reactor_output_w)	/* trackball V */
	AM_RANGE(0x07004, 0x07004) AM_READ(input_port_4_r)	/* joystick */
	AM_RANGE(0x08000, 0x0ffff) AM_ROM
ADDRESS_MAP_END

static MACHINE_DRIVER_START( reacths )
	/* basic machine hardware */
	MDRV_IMPORT_FROM(reactor)

	/* basic machine hardware */
	MDRV_CPU_MODIFY("main")
	MDRV_CPU_PROGRAM_MAP(reacths_map,0)
	MDRV_NVRAM_HANDLER(generic_1fill)
MACHINE_DRIVER_END

ROM_START( 711qbert )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for code */
	ROM_LOAD( "mqb-rom2.bin", 0xa000, 0x2000, CRC(6860f957) SHA1(ebd68aeb6d54868295bd20cf64ee0187a52df0e3) )
	ROM_LOAD( "mqb-rom1.bin", 0xc000, 0x2000, CRC(11f0a4e4) SHA1(a805e51c40042fae209ace277abd9b35a990905b) )
	ROM_LOAD( "mqb-rom0.bin", 0xe000, 0x2000, CRC(12a90cb2) SHA1(a33203aea79fe43d1233a16e3fdddaceac6e4a20) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* 64k for sound cpu */
	ROM_LOAD( "mqb-snd1.bin", 0xf000, 0x0800, CRC(e704b450) SHA1(d509f54658e9f0264b9ab865a6f36e5423a28904) )
	ROM_RELOAD(               0x7000, 0x0800 ) /* A15 is not decoded */
	ROM_LOAD( "mqb-snd2.bin", 0xf800, 0x0800, CRC(c6a98bf8) SHA1(cc5b5bb5966f5d79226f1f665a3f9fc934f4ef7f) )
	ROM_RELOAD(               0x7800, 0x0800 ) /* A15 is not decoded */

	ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE )
	ROM_LOAD( "qb-bg0.bin",   0x0000, 0x1000, CRC(7a9ba824) SHA1(12aa6df499eb6996ee35f56acac403ff6290f844) ) /* chars */
	ROM_LOAD( "qb-bg1.bin",   0x1000, 0x1000, CRC(22e5b891) SHA1(5bb67e333255c0ea679ab4312256a8a71a950db8) )

	ROM_REGION( 0x8000, REGION_GFX2, ROMREGION_DISPOSE )
	ROM_LOAD( "mqb-fg3.bin",  0x0000, 0x2000, CRC(ee595eda) SHA1(11777d95ba79bd0ec7b964b76c1dc129db857816) )	/* sprites */
	ROM_LOAD( "mqb-fg2.bin",  0x2000, 0x2000, CRC(59884c78) SHA1(5e77ef46ccd55f79a5fa90521baa7c22e3783fe5) )
	ROM_LOAD( "mqb-fg1.bin",  0x4000, 0x2000, CRC(2a60e3ad) SHA1(9ed83017f6c8e44337ad76c68b095f2c3300aadb) )
	ROM_LOAD( "mqb-fg0.bin",  0x6000, 0x2000, CRC(b11ad9d8) SHA1(5264598f33aa76455ae4107d0f265c2a372ed67a) )
ROM_END

ROM_START( pbert )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for code */
	ROM_LOAD( "qb-rom2.bin",  0xa000, 0x2000, CRC(fe434526) SHA1(4cfc5d52dd6c82163e035af82d6112c0c93a3797) )
	ROM_LOAD( "qb-rom1.bin",  0xc000, 0x2000, CRC(55635447) SHA1(ca6acdef1c9e06b33efe1f0a2df2dfb03723cfbe) )
	ROM_LOAD( "qb-rom0.bin",  0xe000, 0x2000, CRC(8e318641) SHA1(7f8f66d1e6a7905e93cce07fc92e8801370b7194) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )	/* 64k for sound cpu */
	ROM_LOAD( "qb-snd1.bin",  0xf000, 0x800, CRC(15787c07) SHA1(8b7d03fbf2ebaa71b3a7e2f636a0d1bb9b796e43) )
	ROM_RELOAD(               0x7000, 0x800 ) /* A15 is not decoded */
	ROM_LOAD( "qb-snd2.bin",  0xf800, 0x800, CRC(58437508) SHA1(09d8053e7e99679b602dcda230d64db7fe6cb7f5) )
	ROM_RELOAD(               0x7800, 0x800 ) /* A15 is not decoded */

	ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE )
	ROM_LOAD( "pb-bg0.bin",   0x0000, 0x1000, CRC(14e193e9) SHA1(5d67b3da848d4a90a4f9bf7f6145ce1aa33188f7) )	/* chars */
	ROM_LOAD( "pb-bg1.bin",   0x1000, 0x1000, CRC(a91180f9) SHA1(c8a3ceae19afe9a0ad1e05bed99585e6bacbc09b) )

	ROM_REGION( 0x8000, REGION_GFX2, ROMREGION_DISPOSE )
	ROM_LOAD( "pb-fg3.bin",   0x0000, 0x2000, CRC(26def34c) SHA1(b36dd87e4c36d201aaec0c283e5f3d1ad4056d5d) )	/* sprites */
	ROM_LOAD( "pb-fg2.bin",   0x2000, 0x2000, CRC(cf3309ca) SHA1(5be9a28b3681990729f0582f9d2c3dd0314bdd15) )
	ROM_LOAD( "pb-fg1.bin",   0x4000, 0x2000, CRC(a5f3a203) SHA1(4d7d45e5ba87acd8c44421f2c7fb2129a1866f03) )
	ROM_LOAD( "pb-fg0.bin",   0x6000, 0x2000, CRC(495d90e9) SHA1(d4d28c30901eb09da8933c03b2178152f0fc7b84) )
ROM_END

ROM_START( reacths )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for code */
	ROM_LOAD( "rom7",         0x8000, 0x1000, CRC(a62d86fd) SHA1(9ffce668c6f0155568ccb62a6f12a9513f3c513f) )
	ROM_LOAD( "rom6",         0x9000, 0x1000, CRC(6ed841f3) SHA1(b94272457e6a2d0ec46b510d71d69b4ab92a44aa) )
	ROM_LOAD( "rom5",         0xa000, 0x1000, CRC(d90576a3) SHA1(52af7164dc59b9f7d8a1b3ef9d4c1fc81496899f) )
	ROM_LOAD( "rom4hs",       0xb000, 0x1000, CRC(579dda3f) SHA1(5946339218dcae25703490bfc561d06fdb3e19dd) )
	ROM_LOAD( "rom3",         0xc000, 0x1000, CRC(f8881385) SHA1(baa7ef7309aab9b382442b25ede5d7ecd6e2c370) )
	ROM_LOAD( "rom2",         0xd000, 0x1000, CRC(3caba35b) SHA1(4d3b894821a2cff0ef55cec2b1f62f2e33009b4d) )
	ROM_LOAD( "rom1",         0xe000, 0x1000, CRC(944e1ddf) SHA1(6b487f1cb405e2ba9345190e8ab6022c790882c1) )
	ROM_LOAD( "rom0hs",       0xf000, 0x1000, CRC(a5dce41d) SHA1(b4615e1bbf8c6b9d86a7636166185d1de93fbedb) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )	/* 64k for sound cpu */
	ROM_LOAD( "snd1",         0xf000, 0x800, CRC(d958a0fd) SHA1(3c383076c68a929f96d844e89b09f3075f331906) )
	ROM_RELOAD(               0x7000, 0x800 ) /* A15 is not decoded */
	ROM_LOAD( "snd2",         0xf800, 0x800, CRC(5dc86942) SHA1(a449fcfb25521a0e7523184518b5204dac56e5f8) )
	ROM_RELOAD(               0x7800, 0x800 ) /* A15 is not decoded */

	/* no gfx1 (RAM is used) */

	ROM_REGION( 0x8000, REGION_GFX2, ROMREGION_DISPOSE )
	/* 0000-0fff empty */
	ROM_LOAD( "fg3",          0x1000, 0x1000, CRC(8416ad53) SHA1(f868259b97675e58b6a7f1dc3c2a4ecf6aa0570e) )	/* sprites */
	/* 2000-2fff empty */
	ROM_LOAD( "fg2",          0x3000, 0x1000, CRC(5489605a) SHA1(f4bbaaa8cd881dc164b118d1e516edeeea54c1d8) )
	/* 4000-4fff empty */
	ROM_LOAD( "fg1",          0x5000, 0x1000, CRC(18396c57) SHA1(39d90a842a03091414ed58d4128b524ecc20c9f1) )
	/* 6000-6fff empty */
	ROM_LOAD( "fg0",          0x7000, 0x1000, CRC(d1f20e15) SHA1(dba9aa0fec8b720a33d78b3dd1d7f74040048f7e) )
ROM_END

ROM_START( vbert )
	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for code */
	ROM_LOAD( "qb-rom2.bin",  0xa000, 0x2000, CRC(fe434526) SHA1(4cfc5d52dd6c82163e035af82d6112c0c93a3797) )
	ROM_LOAD( "qb-rom1.bin",  0xc000, 0x2000, CRC(55635447) SHA1(ca6acdef1c9e06b33efe1f0a2df2dfb03723cfbe) )
	ROM_LOAD( "qb-rom0.bin",  0xe000, 0x2000, CRC(8e318641) SHA1(7f8f66d1e6a7905e93cce07fc92e8801370b7194) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )	/* 64k for sound cpu */
	ROM_LOAD( "qb-snd1.bin",  0xf000, 0x800, CRC(15787c07) SHA1(8b7d03fbf2ebaa71b3a7e2f636a0d1bb9b796e43) )
	ROM_RELOAD(               0x7000, 0x800 ) /* A15 is not decoded */
	ROM_LOAD( "qb-snd2.bin",  0xf800, 0x800, CRC(58437508) SHA1(09d8053e7e99679b602dcda230d64db7fe6cb7f5) )
	ROM_RELOAD(               0x7800, 0x800 ) /* A15 is not decoded */

	ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE )
	ROM_LOAD( "vb-bg0.bin",   0x0000, 0x1000, CRC(8963b939) SHA1(1416f56938163b4cdc212758eb2c3f6b773c7e32) )	/* chars */
	ROM_LOAD( "vb-bg1.bin",   0x1000, 0x1000, CRC(96033c96) SHA1(0a5780377bfd3baeeb2d899aa230e503539f7c92) )

	ROM_REGION( 0x8000, REGION_GFX2, ROMREGION_DISPOSE )
	ROM_LOAD( "vb-fg3.bin",   0x0000, 0x2000, CRC(8cb4bdb4) SHA1(7b9b626b93daa4d2639a1e87ace61b1d254af96c) )	/* sprites */
	ROM_LOAD( "vb-fg2.bin",   0x2000, 0x2000, CRC(79883cc3) SHA1(01cfca389021747e2d750fc8bb251abb2d5fe7a8) )
	ROM_LOAD( "vb-fg1.bin",   0x4000, 0x2000, CRC(b0fe9bd5) SHA1(be2990904efff19adbe18eb674727214ffae9ad3) )
	ROM_LOAD( "vb-fg0.bin",   0x6000, 0x2000, CRC(4c3db270) SHA1(212f1c353511fb4166a7ad0135dd295a2a16af8d) )
ROM_END

GAME( 1982, 711qbert, qbert,    qbert,    qbert,    0,        ROT270, "Hack", "7-11 Q*bert", 0 )
GAME( 2003, pbert,    qbert, 	qbert,    qbert,    0,        ROT270, "Grand Master Peter", "P*bert", 0 )
GAME( 2001, reacths,  0,        reacths,  reactor,  0,        ROT0,   "JRok", "Reactor [h]", 0 ) // www.jrok.com/files/rsave.html
GAME( 2003, vbert,    qbert, 	qbert,    qbert,    0,        ROT270, "Grand Master Peter", "V*bert", 0 )
/* Misfitmame end */

