#include "driver.h"
#include "machine/6821pia.h"
#include "audio/williams.h"
#include "williams.h"
#include "sound/dac.h"


#define MASTER_CLOCK		(12000000)
#define SOUND_CLOCK			(3579000)



/*************************************
 *
 *  Defender memory handlers
 *
 *************************************/


void defender_install_io_space(void)
{
	/* this routine dynamically installs the memory mapped above from c000-cfff */
	memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc000, 0xc00f, 0, 0x03e0, williams_paletteram_w);
	memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc010, 0xc01f, 0, 0x03e0, defender_video_control_w);
	memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc3ff, 0xc3ff, 0, 0,      williams_watchdog_reset_w);
	memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0xc400, 0xc4ff, 0, 0x0300, MRA8_BANK3);
	memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc400, 0xc4ff, 0, 0x0300, williams_cmos_w);
	memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0xc800, 0xcbff, 0, 0x03e0, williams_video_counter_r);
	memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0xcc00, 0xcc03, 0, 0x03e0, pia_1_r);
	memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xcc00, 0xcc03, 0, 0x03e0, pia_1_w);
	memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0xcc04, 0xcc07, 0, 0x03e0, pia_0_r);
	memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xcc04, 0xcc07, 0, 0x03e0, pia_0_w);
	memory_set_bankptr(3, generic_nvram);
}



/*************************************
 *
 *  General Williams memory handlers
 *
 *************************************/

static ADDRESS_MAP_START( williams_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x8fff) AM_READWRITE(MRA8_BANK1, MWA8_RAM) AM_BASE(&williams_videoram)
	AM_RANGE(0x9000, 0xbfff) AM_RAM
	AM_RANGE(0xc000, 0xc00f) AM_MIRROR(0x03f0) AM_WRITE(williams_paletteram_w) AM_BASE(&paletteram)
	AM_RANGE(0xc804, 0xc807) AM_MIRROR(0x00f0) AM_READWRITE(pia_0_r, pia_0_w)
	AM_RANGE(0xc80c, 0xc80f) AM_MIRROR(0x00f0) AM_READWRITE(pia_1_r, pia_1_w)
	AM_RANGE(0xc900, 0xc9ff) AM_WRITE(williams_vram_select_w)
	AM_RANGE(0xca00, 0xca07) AM_MIRROR(0x00f8) AM_WRITE(williams_blitter_w)
	AM_RANGE(0xcb00, 0xcbff) AM_READ(williams_video_counter_r)
	AM_RANGE(0xcbff, 0xcbff) AM_WRITE(williams_watchdog_reset_w)
	AM_RANGE(0xcc00, 0xcfff) AM_READWRITE(MRA8_RAM, williams_cmos_w) AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
	AM_RANGE(0xd000, 0xffff) AM_ROM
ADDRESS_MAP_END


/*************************************
 *
 *  Sound board memory handlers
 *
 *************************************/


static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x007f) AM_RAM		/* internal RAM */
	AM_RANGE(0x0080, 0x00ff) AM_RAM		/* MC6810 RAM */
	AM_RANGE(0x0400, 0x0403) AM_MIRROR(0x8000) AM_READWRITE(pia_2_r, pia_2_w)
	AM_RANGE(0xb000, 0xffff) AM_ROM		/* most games start at $F000, Sinistar starts at $B000 */
ADDRESS_MAP_END



/*************************************
 *
 *  Port definitions
 *
 *************************************/



INPUT_PORTS_START( stargate )
	PORT_START_TAG("IN0")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Fire")
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Thrust")
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Smart Bomb")
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Hyperspace")
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START1 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME(DEF_STR( Reverse ))
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY

	PORT_START_TAG("IN1")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Inviso")
	PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNKNOWN )

	PORT_START_TAG("IN2")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Auto Up") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Advance") PORT_CODE(KEYCODE_F2)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("High Score Reset") PORT_CODE(KEYCODE_9)
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_TILT )
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END


INPUT_PORTS_START( robotron )
	PORT_START_TAG("IN0")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP )
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN )
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT )
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP )
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN )

	PORT_START_TAG("IN1")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT )
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT )
	PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNKNOWN )

	PORT_START_TAG("IN2")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Auto Up") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Advance") PORT_CODE(KEYCODE_F2)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("High Score Reset") PORT_CODE(KEYCODE_9)
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_TILT )
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END


INPUT_PORTS_START( splat )
	PORT_START_TAG("IN0")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_8WAY PORT_PLAYER(2)

	PORT_START_TAG("IN1")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_8WAY PORT_PLAYER(2)
	PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNKNOWN )

	PORT_START_TAG("IN2")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Auto Up") PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Advance") PORT_CODE(KEYCODE_F2)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 )
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("High Score Reset") PORT_CODE(KEYCODE_9)
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_TILT )

	PORT_START_TAG("IN3")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 )
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_8WAY PORT_PLAYER(1)

	PORT_START_TAG("IN4")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_8WAY PORT_PLAYER(1)
	PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END



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

static MACHINE_DRIVER_START( williams )

	/* basic machine hardware */
	MDRV_CPU_ADD_TAG("main", M6809, MASTER_CLOCK/3/4)
	MDRV_CPU_PROGRAM_MAP(williams_map,0)

	MDRV_CPU_ADD_TAG("sound", M6808, SOUND_CLOCK/4)
	MDRV_CPU_PROGRAM_MAP(sound_map,0)

	MDRV_SCREEN_REFRESH_RATE(60)
	MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)

	MDRV_MACHINE_RESET(williams)
	MDRV_NVRAM_HANDLER(generic_0fill)

	/* video hardware */
	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
	MDRV_SCREEN_SIZE(384, 256)
	MDRV_SCREEN_VISIBLE_AREA(6, 298-1, 7, 247-1)
	MDRV_PALETTE_LENGTH(16)

	MDRV_VIDEO_START(williams)
	MDRV_VIDEO_UPDATE(williams)

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

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


/*************************************
 *
 *  Configuration macros
 *
 *************************************/

#define CONFIGURE_BLITTER(x,c) \
	williams_blitter_config = x; \
	williams_blitter_clip_address = c

#define CONFIGURE_PIAS(a,b,c) \
	pia_config(0, &a);\
	pia_config(1, &b);\
	pia_config(2, &c)



/*************************************
 *
 *  Standard hardware driver init
 *
 *************************************/

static DRIVER_INIT( stargate )
{
	CONFIGURE_BLITTER(WILLIAMS_BLITTER_NONE, 0x0000);
	CONFIGURE_PIAS(williams_pia_0_intf, williams_pia_1_intf, williams_snd_pia_intf);
}



static DRIVER_INIT( joust )
{
	CONFIGURE_BLITTER(WILLIAMS_BLITTER_SC01, 0xc000);
	CONFIGURE_PIAS(williams_muxed_pia_0_intf, williams_pia_1_intf, williams_snd_pia_intf);
}



/* MisfitMAME start */
ROM_START( defendr2 )
	ROM_REGION( 0x19000, REGION_CPU1, 0 )
	ROM_LOAD( "10",         0x0d000, 0x1000, CRC(4d82fc2f) SHA1(b11dc3f3f2100ab14ad5b26cd333b212c454cc8d) )
	ROM_LOAD( "11",         0x0e000, 0x1000, CRC(561fad3f) SHA1(597851e78423f30341f682f3fc62bf24cf9e8a91) )
	ROM_LOAD( "12",         0x0f000, 0x1000, CRC(836eacca) SHA1(f788fc2a25adffa21e02a3dfe2074e8719405200) )
	ROM_LOAD( "01",         0x10000, 0x1000, CRC(88824d18) SHA1(f003a5a9319c4eb8991fa2aae3f10c72d6b8e81a) )
	ROM_LOAD( "02",         0x11000, 0x1000, CRC(afc614c5) SHA1(087c6da93318e8dc922d3d22e0a2af7b9759701c) )
	ROM_LOAD( "03",         0x12000, 0x1000, CRC(6dd57970) SHA1(1fdee9180bfb835f35ac786116e0f8d7833f2c3f) )
	ROM_LOAD( "04",         0x13000, 0x1000, CRC(a8b4bf0f) SHA1(6b4d47c2899fe9f14f9dab5928499f12078c437d) )
	ROM_LOAD( "05",         0x14000, 0x1000, CRC(2d306074) SHA1(54f871983699113e31bb756d4ca885c26c2d66b4) )
	ROM_LOAD( "06",         0x15000, 0x1000, CRC(53598dde) SHA1(54b02d944caf95283c9b6f0160e75ea8c4ccc97b) )
	ROM_LOAD( "07",         0x16000, 0x1000, CRC(55b5b0d2) SHA1(dcf392a899fb6c225c4e31034e242e575c3dc94d) )
	ROM_LOAD( "08",         0x17000, 0x1000, CRC(b4f22d4d) SHA1(2486e895628df9ae1268d9eb2434f240dba99f70) )
	ROM_LOAD( "09",         0x18000, 0x1000, CRC(6df7463d) SHA1(b80c2872fc47b4b604967f176e3931cd992dd692) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )
	ROM_LOAD( "sg.snd",      0xf800, 0x0800, CRC(2fcf6c4d) SHA1(9c4334ac3ff15d94001b22fc367af40f9deb7d57) )

	ROM_REGION( 0x0400, REGION_PROMS, 0 )
	ROM_LOAD( "decoder.4",   0x0000, 0x0200, CRC(e6631c23) SHA1(9988723269367fb44ef83f627186a1c88cf7877e) )
	ROM_LOAD( "decoder.5",   0x0200, 0x0200, CRC(f921c5fe) SHA1(9cebb8bb935315101d248140d1b4503993ebdf8a) )
ROM_END

ROM_START( splatsc1 )
	ROM_REGION( 0x19000, REGION_CPU1, 0 )
	ROM_LOAD( "splatsc1.10", 0x0d000, 0x1000, CRC(6cc2988a) SHA1(bd0648185ab859afc981d4e8ab954ed1f39303e4) )
	ROM_LOAD( "splatsc1.11", 0x0e000, 0x1000, CRC(ee960115) SHA1(b3a03b14f7ee97d55b948ecc09c5e4006c31f0ce) )
	ROM_LOAD( "splatsc1.12", 0x0f000, 0x1000, CRC(21916fce) SHA1(6896afd10c30d90b807b60f90fced7114b1812e3) )
	ROM_LOAD( "splat.01",    0x10000, 0x1000, CRC(1cf26e48) SHA1(6ba4de6cc7d1359ed450da7bae1000552373f873) )
	ROM_LOAD( "splat.02",    0x11000, 0x1000, CRC(ac0d4276) SHA1(710aba98909d5d63c4b9b08579021f9c026b3111) )
	ROM_LOAD( "splat.03",    0x12000, 0x1000, CRC(74873e59) SHA1(727c9da682fd10353f3969ef02e9f1826d8cb77a) )
	ROM_LOAD( "splat.04",    0x13000, 0x1000, CRC(70a7064e) SHA1(7e6440585462b68b62d6d571d83635bf17149f1a) )
	ROM_LOAD( "splatsc1.05", 0x14000, 0x1000, CRC(6989e923) SHA1(383d831084cf79e3961125142d1e3bf4fad1ac66) )
	ROM_LOAD( "splatsc1.06", 0x15000, 0x1000, CRC(82b22e55) SHA1(d71c6598f6a43f47f6752c803069efeb877bf1f0) )
	ROM_LOAD( "splatsc1.07", 0x16000, 0x1000, CRC(e0c4230c) SHA1(2795732725f63e766ee23744147bf002373bc5f7) )
	ROM_LOAD( "splatsc1.08", 0x17000, 0x1000, CRC(42ff589f) SHA1(72c9b40c9291a6b97f637c6424265b30227d87c6) )
	ROM_LOAD( "splatsc1.09", 0x18000, 0x1000, CRC(f67564be) SHA1(3fda9032953e4f75df838616d1c7023a1f2e9861) )

	ROM_REGION( 0x10000, REGION_CPU2, 0 )
	ROM_LOAD( "splat.snd",   0xf000, 0x1000, CRC(a878d5f3) SHA1(f3347a354cb54ca228fe0971f0ae3bc778e2aecf) )

	ROM_REGION( 0x0400, REGION_PROMS, 0 )
	ROM_LOAD( "decoder.4",   0x0000, 0x0200, CRC(e6631c23) SHA1(9988723269367fb44ef83f627186a1c88cf7877e) )
	ROM_LOAD( "decoder.6",   0x0200, 0x0200, CRC(83faf25e) SHA1(30002643d08ed983a6701a7c4b5ee74a2f4a1adb) )
ROM_END

/* Williams MultiGame */

/* This game is not working. Rather, the menu is not working. Data can be seen to be written to the video ram,
   but nothing appears. After a few moments the watchdog kicks in.
	Game numbers:
	0 = The Menu
	1 = robotron
	2 = joustr
	3 = stargate
	4 = bubbles
	5 = defender
	6 = splat
	7 = spare position (duplicate of bubbles)

   If you enter the game number into the last line of the DRIVER_INIT below, that game will start up normally
   and run perfectly well. Exception is Defender which has a totally different memory map.

   Outstanding things to be done:
	1. Fix the menu
	2. Fix Defender
	3. Check the Inputs

  Some documents can be downloaded from http://www.multigame.com/williams.html */

/* switches the banks around when given a game number */
static void wmg_rombank_w( UINT8 banknum )
{
	UINT8 *RAM = memory_region(REGION_CPU1);
	memcpy( &RAM[0x10000], &RAM[(banknum << 16)+0x20000], 0x9000 );		/* Gfx etc */
	memory_set_bank(5, banknum);		/* Code */
	memory_set_bank(6, banknum);		/* Sound */
}

/* No idea what this does, or even if it's important */
static WRITE8_HANDLER( wmg_mystery_w )
{
	printf("Mystery:%X=%X\n",0xc400+offset,data);
}

static ADDRESS_MAP_START( wmg_cpu1, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x8fff) AM_READWRITE(MRA8_BANK1, MWA8_RAM) AM_BASE(&williams_videoram)
	AM_RANGE(0x9000, 0xbfff) AM_RAM
	AM_RANGE(0xc000, 0xc00f) AM_MIRROR(0x03f0) AM_WRITE(williams_paletteram_w) AM_BASE(&paletteram)
	AM_RANGE(0xc400, 0xc401) AM_WRITE(wmg_mystery_w)
	AM_RANGE(0xc804, 0xc807) AM_MIRROR(0x00f0) AM_READWRITE(pia_0_r, pia_0_w)
	AM_RANGE(0xc80c, 0xc80f) AM_MIRROR(0x00f0) AM_READWRITE(pia_1_r, pia_1_w)
	AM_RANGE(0xc900, 0xc9ff) AM_WRITE(williams_vram_select_w)
	AM_RANGE(0xca00, 0xca07) AM_MIRROR(0x00f8) AM_WRITE(williams_blitter_w)
	AM_RANGE(0xcb00, 0xcbff) AM_READ(williams_video_counter_r)
	AM_RANGE(0xcbff, 0xcbff) AM_WRITE(williams_watchdog_reset_w)
	AM_RANGE(0xcc00, 0xcfff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
	AM_RANGE(0xd000, 0xffff) AM_ROMBANK(5)
ADDRESS_MAP_END

static ADDRESS_MAP_START( wmg_cpu2, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x007f) AM_RAM		/* internal RAM */
	AM_RANGE(0x0080, 0x00ff) AM_RAM		/* MC6810 RAM */
	AM_RANGE(0x0400, 0x0403) AM_MIRROR(0x8000) AM_READWRITE(pia_2_r, pia_2_w)
	AM_RANGE(0xf000, 0xffff) AM_ROMBANK(6)
ADDRESS_MAP_END

static MACHINE_DRIVER_START( wmg )
	MDRV_IMPORT_FROM(williams)
	MDRV_CPU_MODIFY("main")
	MDRV_CPU_PROGRAM_MAP(wmg_cpu1,0)

	MDRV_CPU_MODIFY("sound")
	MDRV_CPU_PROGRAM_MAP(wmg_cpu2,0)
MACHINE_DRIVER_END

ROM_START( wmg )
	ROM_REGION( 0x100000, REGION_CPU1, 0 )
	ROM_LOAD( "rom_512k.bin",    0x20000, 0x80000, CRC(975516ec) SHA1(571aaf9bff8ebfc36448cd9394b47bcfae7d1b83) )

	ROM_REGION( 0x18000, REGION_CPU2, 0 )
	ROM_LOAD( "snd_32k.bin",     0x10000, 0x8000, CRC(1d08990e) SHA1(7bfb29426b3876f113e6ec3bc6c2fce9d2d1eb0c) )

	ROM_REGION( 0x0400, REGION_PROMS, 0 )
	ROM_LOAD( "decoder.4",       0x0000, 0x0200, CRC(e6631c23) SHA1(9988723269367fb44ef83f627186a1c88cf7877e) )
	ROM_LOAD( "decoder.6",       0x0200, 0x0200, CRC(83faf25e) SHA1(30002643d08ed983a6701a7c4b5ee74a2f4a1adb) )
ROM_END

static DRIVER_INIT( wmg )
{
	UINT8 *RAM = memory_region(REGION_CPU1);
	UINT8 *ROM = memory_region(REGION_CPU2);
	memory_configure_bank(5, 0, 8, &RAM[0x2d000], 0x10000);	/* Code */
	memory_configure_bank(6, 0, 8, &ROM[0x10000], 0x1000);	/* Sound */
	CONFIGURE_BLITTER(WILLIAMS_BLITTER_SC01, 0xc000);
	CONFIGURE_PIAS(williams_muxed_pia_0_intf, williams_pia_1_intf, williams_snd_pia_intf);
	wmg_rombank_w( 0 );			/* switch to the menu */
}

GAME( 1981, defendr2, 0, williams, stargate, stargate, ROT0, "Williams", "Defender II", GAME_SUPPORTS_SAVE )
GAME( 1982, splatsc1, 0, williams, splat,    joust,    ROT0, "Williams", "Splat! (sc1 hardware)", GAME_SUPPORTS_SAVE )
GAME( 2001, wmg,      0, wmg,      robotron, wmg,      ROT0, "Clay Cowgill", "Williams 6in1 Multigame", GAME_NOT_WORKING ) // www.multigame.com/williams.html

/* MisfitMAME end */
