[wrap]
MAME source file: / src / mame / drivers / metro.c [download] (view on mamedev.org)
/***************************************************************************

                              -= Metro Games =-

                    driver by   Luca Elia (l.elia@tin.it)


Main  CPU    :  MC68000 Or H8/3007

Video Chips  :  Imagetek 14100 052 9227KK701    Or
                Imagetek 14220 071 9338EK707    Or
                Imagetek 14300 095

Sound CPU    :  NEC78C10 [Optional]

Sound Chips  :  OKIM6295 + YM2413  or
                YRW801-M + YMF278B (YM2610 compatible)

Other        :  Memory Blitter

---------------------------------------------------------------------------
Year + Game                     PCB         Video Chip  Issues / Notes
---------------------------------------------------------------------------
92  Last Fortress - Toride      VG420       14100
92  Last Fortress - Toride (Ger)VG460-(A)   14100
92  Pang Pom's                  VG420       14100
92  Sky Alert                   VG420       14100
92  The Karate Tournament       VG460-B     14100
93? Lady Killer / Moeyo Gonta!! VG460-B     14100
93  Poitto!                     MTR5260-A   14100
94  Dharma Doujou               MTR5260-A   14220
94  Gun Master                  MTR5260-A   14220
94  Toride II Adauchi Gaiden    MTR5260-A   14220
94  Blazing Tornado             ?           14220       Also has Konami 053936 gfx chip
96  Grand Striker 2             HUM-003(A)  14220       Also has Konami 053936 gfx chip
95  Daitoride                   MTR5260-A   14220
95  Pururun                     MTR5260-A   14220
95  Puzzli                      MTR5260-A   14220
96  Sankokushi                  MTR5260-A   14220
96  Bal Cube                    ?           14220       No sound CPU
96  Bang Bang Ball              ?           14220       No sound CPU
95  Mahjong Doukyuhsei          VG330-B     14300       No sound CPU
95  Mahjong Doukyuusei Special  VG340-A     14300       No sound CPU
97  Mahjong Gakuensai           VG340-A     14300       No sound CPU
98  Mahjong Gakuensai 2         VG340-A     14300       No sound CPU
96  Mouja                       VG410-B     14300       No sound CPU
99  Battle Bubble v2.00         LM2D-Y      14220       No sound CPU
00  Puzzlet                     VG2200-(B)  14300       PIC? Protection?
---------------------------------------------------------------------------

Not dumped yet:
94  Toride II

To Do:

-   1 pixel granularity in the window's placement (8 pixels now, see daitorid title)
-   Coin lockout
-   Some gfx problems in ladykill, 3kokushi, puzzli, gakusai
-   Are the 16x16 tiles used by Mouja a Imagetek 14300-only feature?
-   Flip screen doesn't work correctly in Mouja due to asymmetrical visible area

Notes:

-   To enter service mode in Lady Killer, toggle the dip switch and reset
    keeping  start 2 pressed.
-   Sprite zoom in Mouja at the end of a match looks wrong, but it's been verified
    to be the same on the original board

lastfort info from guru
---
Master clock = 24.00MHz
D7810 clock : 12.00MHz (24 / 2)
M6295 clock: 1.200MHz (24 / 20), sample rate =  M6295 clock /165
YM2413 clock: 3.579545MHz
Vsync: 58Hz
HSync: 15.16kHz

Compared to the real PCB, MAME is too fast, so 60fps needs to be changed to 58fps (i.e 58Hz).
--
driver modified by Eisuke Watanabe
***************************************************************************/

#include "driver.h"
#include "deprecat.h"
#include "cpu/h83002/h8.h"
#include "cpu/upd7810/upd7810.h"
#include "machine/eeprom.h"
#include "video/konamiic.h"
#include "sound/2610intf.h"
#include "sound/2151intf.h"
#include "sound/2413intf.h"
#include "sound/okim6295.h"
#include "sound/ymf278b.h"

/* Variables defined in video: */

extern UINT16 *metro_videoregs;
extern UINT16 *metro_screenctrl;
extern UINT16 *metro_scroll;
extern UINT16 *metro_tiletable;
extern size_t metro_tiletable_size;
extern UINT16 *metro_vram_0, *metro_vram_1, *metro_vram_2;
extern UINT16 *metro_window;
extern UINT16 *metro_K053936_ram;
WRITE16_HANDLER( metro_K053936_w );


/* Functions defined in video: */

WRITE16_HANDLER( metro_window_w );

WRITE16_HANDLER( metro_vram_0_w );
WRITE16_HANDLER( metro_vram_1_w );
WRITE16_HANDLER( metro_vram_2_w );


VIDEO_START( metro_14100 );
VIDEO_START( metro_14220 );
VIDEO_START( metro_14300 );
VIDEO_START( blzntrnd );
VIDEO_START( gstrik2 );

VIDEO_UPDATE( metro );


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


                                Interrupts


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

static int irq_line, blitter_bit;

static UINT8 requested_int[8];

static UINT16 *metro_irq_levels, *metro_irq_vectors, *metro_irq_enable;

static READ16_HANDLER( metro_irq_cause_r )
{
	return	requested_int[0] * 0x01 +	// vblank
			requested_int[1] * 0x02 +
			requested_int[2] * 0x04 +	// blitter
			requested_int[3] * 0x08 +
			requested_int[4] * 0x10 +
			requested_int[5] * 0x20 +
			requested_int[6] * 0x40 +	// unused
			requested_int[7] * 0x80 ;	// unused
}


/* Update the IRQ state based on all possible causes */
static void update_irq_state(running_machine *machine)
{
	const address_space *space = cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_PROGRAM);

	/*  Get the pending IRQs (only the enabled ones, e.g. where
        irq_enable is *0*)  */
	UINT16 irq = metro_irq_cause_r(space, 0, 0xffff) & ~*metro_irq_enable;

	if (irq_line == -1)	/* mouja, gakusai, gakusai2, dokyusei, dokyusp */
	{
		/*  This is for games that supply an *IRQ Vector* on the data bus
            together with an IRQ level for each possible IRQ source */

		UINT8 irq_level[8] = { 0 };
		int i = 0;
		for (i = 0; i < 8; i++)
			if (irq & (1 << i))
				irq_level[metro_irq_levels[i]&7] = 1;
		for (i = 0; i < 8; i++)
			cpu_set_input_line(machine->cpu[0], i, irq_level[i] ? ASSERT_LINE : CLEAR_LINE);
	}
	else
	{
		/*  This is for games where every IRQ source generates the same
            IRQ level. The interrupt service routine then reads the actual
            source by peeking a register (metro_irq_cause_r) */

		int state =	(irq ? ASSERT_LINE : CLEAR_LINE);
		cpu_set_input_line(machine->cpu[0], irq_line, state);
	}
}


/* For games that supply an *IRQ Vector* on the data bus */
static IRQ_CALLBACK(metro_irq_callback)
{
//  logerror("CPU #0 PC %06X: irq callback returns %04X\n",cpu_get_pc(machine->activecpu),metro_irq_vectors[int_level]);
	return metro_irq_vectors[irqline]&0xff;
}

static MACHINE_RESET( metro )
{
	if (irq_line == -1)
		cpu_set_irq_callback(machine->cpu[0], metro_irq_callback);
}


static WRITE16_HANDLER( metro_irq_cause_w )
{
//if (data & ~0x15) logerror("CPU #0 PC %06X : unknown bits of irqcause written: %04X\n",cpu_get_pc(space->cpu),data);

	if (ACCESSING_BITS_0_7)
	{
		data &= ~*metro_irq_enable;

		if (data & 0x01)	requested_int[0] = 0;
		if (data & 0x02)	requested_int[1] = 0;	// DAITORIDE, BALCUBE, KARATOUR, MOUJA
		if (data & 0x04)	requested_int[2] = 0;
		if (data & 0x08)	requested_int[3] = 0;	// KARATOUR
		if (data & 0x10)	requested_int[4] = 0;
		if (data & 0x20)	requested_int[5] = 0;	// KARATOUR, BLZNTRND
		if (data & 0x40)	requested_int[6] = 0;
		if (data & 0x80)	requested_int[7] = 0;
	}

	update_irq_state(space->machine);
}


static INTERRUPT_GEN( metro_interrupt )
{
	switch ( cpu_getiloops(device) )
	{
		case 0:
			requested_int[0] = 1;
			update_irq_state(device->machine);
			break;

		default:
			requested_int[4] = 1;
			update_irq_state(device->machine);
			break;
	}
}

/* Lev 1. Lev 2 seems sound related */
static INTERRUPT_GEN( bangball_interrupt )
{
	requested_int[0] = 1;	// set scroll regs if a flag is set
	requested_int[4] = 1;	// clear that flag
	update_irq_state(device->machine);
}


static TIMER_CALLBACK( vblank_end_callback )
{
	requested_int[5] = param;
}

/* lev 2-7 (lev 1 seems sound related) */
static INTERRUPT_GEN( karatour_interrupt )
{
	switch ( cpu_getiloops(device) )
	{
		case 0:
			requested_int[0] = 1;
			requested_int[5] = 1;	// write the scroll registers
			/* the duration is a guess */
			timer_set(ATTOTIME_IN_USEC(2500), NULL, 0, vblank_end_callback);
			update_irq_state(device->machine);
			break;

		default:
			requested_int[4] = 1;
			update_irq_state(device->machine);
			break;
	}
}

static emu_timer *mouja_irq_timer;

static TIMER_CALLBACK( mouja_irq_callback )
{
	requested_int[0] = 1;
	update_irq_state(machine);
}

static WRITE16_HANDLER( mouja_irq_timer_ctrl_w )
{
	double freq = 58.0 + (0xff - (data & 0xff)) / 2.2;					/* 0xff=58Hz, 0x80=116Hz? */
	timer_adjust_periodic(mouja_irq_timer, attotime_zero, 0, ATTOTIME_IN_HZ(freq));
}

static INTERRUPT_GEN( mouja_interrupt )
{
	requested_int[1] = 1;
	update_irq_state(device->machine);
}


static INTERRUPT_GEN( gakusai_interrupt )
{
	switch ( cpu_getiloops(device) )
	{
		case 0:
			requested_int[1] = 1;
			update_irq_state(device->machine);
			break;
	}
}

static INTERRUPT_GEN( dokyusei_interrupt )
{
	switch ( cpu_getiloops(device) )
	{
		case 0:
			requested_int[1] = 1;
			update_irq_state(device->machine);
			break;
		case 1:	// needed?
			requested_int[5] = 1;
			update_irq_state(device->machine);
			break;
	}
}

static void ymf278b_interrupt(running_machine *machine, int active)
{
	cpu_set_input_line(machine->cpu[0], 2, active);
}

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


                            Sound Communication


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

static UINT16 metro_soundstatus;
static int porta, portb, busy_sndcpu;

static int metro_io_callback(int ioline, int state)
{
	const address_space *space = cpu_get_address_space(Machine->cpu[0], ADDRESS_SPACE_PROGRAM);

	UINT8 data = 0;

    switch ( ioline )
	{
		case UPD7810_RXD:	/* read the RxD line */
			data = soundlatch_r(space,0);
			state = data & 1;
			soundlatch_w(space, 0, data >> 1);
			break;
		default:
			logerror("upd7810 ioline %d not handled\n", ioline);
    }

	return state;
}

static WRITE16_HANDLER( metro_soundlatch_w )
{
	if (ACCESSING_BITS_0_7)
	{
		soundlatch_w(space,0,data & 0xff);
		cpu_set_input_line(space->machine->cpu[1], INPUT_LINE_NMI, PULSE_LINE);
		cpu_spinuntil_int(space->cpu);
		busy_sndcpu = 1;
	}
}


static READ16_HANDLER( metro_soundstatus_r )
{
	return (busy_sndcpu ? 0x00 : 0x01);
}

static CUSTOM_INPUT( custom_soundstatus_r )
{
	return (busy_sndcpu ? 0x01 : 0x00);
}

static WRITE16_HANDLER( metro_soundstatus_w )
{
	if (ACCESSING_BITS_0_7)
		metro_soundstatus = data & 0x01;
}


static WRITE8_HANDLER( metro_sound_rombank_w )
{
	int bankaddress;
	UINT8 *ROM = memory_region(space->machine, "audio");

	bankaddress = 0x10000-0x4000 + ((data >> 4) & 0x03) * 0x4000;
	if (bankaddress < 0x10000) bankaddress = 0x0000;

	memory_set_bankptr(space->machine, 1, &ROM[bankaddress]);
}

static WRITE8_HANDLER( daitorid_sound_rombank_w )
{
	int bankaddress;
	UINT8 *ROM = memory_region(space->machine, "audio");

	bankaddress = 0x10000-0x4000 + ((data >> 4) & 0x07) * 0x4000;
	if (bankaddress < 0x10000) bankaddress = 0x10000;

	memory_set_bankptr(space->machine, 1, &ROM[bankaddress]);
}


static READ8_HANDLER( metro_porta_r )
{
	return porta;
}

static WRITE8_HANDLER( metro_porta_w )
{
	porta = data;
}

static WRITE8_HANDLER( metro_portb_w )
{
	/* port B layout:
       7 !clock latch for message to main CPU
       6
       5 !clock YM2413 I/O
       4 !clock MSM6295 I/O
       3
       2 !enable write to YM2413/6295
       1 select YM2151 register or data port
       0
    */

	if (BIT(portb,7) && !BIT(data,7))	/* clock 1->0 */
	{
		busy_sndcpu = 0;
		portb = data;
		return;
	}

	if (BIT(portb,5) && !BIT(data,5))	/* clock 1->0 */
	{
		if (!BIT(data,2))
		{
			/* write */
			if (BIT(data,1))
				ym2413_data_port_0_w(space,0,porta);
			else
				ym2413_register_port_0_w(space,0,porta);
		}
		portb = data;
		return;
	}

	if (BIT(portb,2) && !BIT(data,2))	/* clock 1->0 */
	{
		/* write */
		if (!BIT(data,4))
			okim6295_data_0_w(space,0,porta);
	}
	portb = data;
}


static WRITE8_HANDLER( daitorid_portb_w )
{
	/* port B layout:
       7 !clock latch for message to main CPU
       6 !clock YM2151 I/O
       5
       4 !clock MSM6295 I/O
       3 !enable read from YM2151/6295
       2 !enable write to YM2151/6295
       1 select YM2151 register or data port
       0
    */

	if (BIT(portb,7) && !BIT(data,7))	/* clock 1->0 */
	{
		busy_sndcpu = 0;
		portb = data;
		return;
	}

	if (BIT(portb,6) && !BIT(data,6))	/* clock 1->0 */
	{
		if (!BIT(data,2))
		{
			/* write */
			if (BIT(data,1))
				ym2151_data_port_0_w(space,0,porta);
			else
				ym2151_register_port_0_w(space,0,porta);
		}
		if (!BIT(data,3))
		{
			/* read */
			if (BIT(data,1))
				porta = ym2151_status_port_0_r(space,0);
		}
		portb = data;
		return;
	}

	if (BIT(portb,2) && !BIT(data,2))	/* clock 1->0 */
	{
		/* write */
		if (!BIT(data,4))
			okim6295_data_0_w(space,0,porta);
	}
	if (BIT(portb,3) && !BIT(data,3))	/* clock 1->0 */
	{
		/* read */
		if (!BIT(data,4))
			porta = okim6295_status_0_r(space,0);
	}
	portb = data;
}

static void metro_sound_irq_handler(running_machine *machine, int state)
{
	cpu_set_input_line(machine->cpu[1], UPD7810_INTF2, state ? ASSERT_LINE : CLEAR_LINE);
}

static const ym2151_interface ym2151_config =
{
	metro_sound_irq_handler	/* irq handler */
};


static READ16_HANDLER( ymf278b_r )
{
	return ymf278b_status_port_0_r(space, 0);
}

static WRITE16_HANDLER( ymf278b_w )
{
	if(ACCESSING_BITS_0_7)
		switch(offset)
		{
			case 0:
				ymf278b_control_port_0_a_w(space, 0, data);
				break;
			case 1:
				ymf278b_data_port_0_a_w(space, 0, data);
				break;
			case 2:
				ymf278b_control_port_0_b_w(space, 0, data);
				break;
			case 3:
				ymf278b_data_port_0_b_w(space, 0, data);
				break;
			case 4:
				ymf278b_control_port_0_c_w(space, 0, data);
				break;
			case 5:
				ymf278b_data_port_0_c_w(space, 0, data);
				break;
		}
}


static const ymf278b_interface ymf278b_config =
{
	ymf278b_interrupt
};


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


                                Coin Lockout


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

/* IT DOESN'T WORK PROPERLY */

static WRITE16_HANDLER( metro_coin_lockout_1word_w )
{
	if (ACCESSING_BITS_0_7)
	{
//      coin_lockout_w(0, data & 1);
//      coin_lockout_w(1, data & 2);
	}
	if (data & ~3)	logerror("CPU #0 PC %06X : unknown bits of coin lockout written: %04X\n",cpu_get_pc(space->cpu),data);
}


static WRITE16_HANDLER( metro_coin_lockout_4words_w )
{
//  coin_lockout_w( (offset >> 1) & 1, offset & 1 );
	if (data & ~1)	logerror("CPU #0 PC %06X : unknown bits of coin lockout written: %04X\n",cpu_get_pc(space->cpu),data);
}




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


                                Banked ROM access


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

/*
    The main CPU has access to the ROMs that hold the graphics through
    a banked window of 64k. Those ROMs also usually store the tables for
    the virtual tiles set. The tile codes to be written to the tilemap
    memory to render the backgrounds are also stored here, in a format
    that the blitter can readily use (which is a form of compression)
*/

static UINT16 *metro_rombank;

static READ16_HANDLER( metro_bankedrom_r )
{
	UINT8 *ROM = memory_region( space->machine, "gfx1" );
	size_t  len  = memory_region_length( space->machine, "gfx1" );

	offset = offset * 2 + 0x10000 * (*metro_rombank);

	if ( offset < len )	return ((ROM[offset+0]<<8)+ROM[offset+1]);
	else				return 0xffff;
}




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


                                    Blitter

    [ Registers ]

        Offset:     Value:

        0.l         Destination Tilemap      (1,2,3)
        4.l         Blitter Data Address     (byte offset into the gfx ROMs)
        8.l         Destination Address << 7 (byte offset into the tilemap)

        The Blitter reads a byte and looks at the most significative
        bits for the opcode, while the remaining bits define a value
        (usually how many bytes to write). The opcode byte may be
        followed by a number of other bytes:

            76------            Opcode
            --543210            N
            (at most N+1 bytes follow)


        The blitter is designed to write every other byte (e.g. it
        writes a byte and skips the next). Hence 2 blits are needed
        to fill a tilemap (first even, then odd addresses)

    [ Opcodes ]

            0       Copy the following N+1 bytes. If the whole byte
                    is $00: stop and generate an IRQ

            1       Fill N+1 bytes with a sequence, starting with
                    the  value in the following byte

            2       Fill N+1 bytes with the value in the following
                    byte

            3       Skip N+1 bytes. If the whole byte is $C0:
                    skip to the next row of the tilemap (+0x200 bytes)
                    but preserve the column passed at the start of the
                    blit (destination address % 0x200)


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

static UINT16 *metro_blitter_regs;

static TIMER_CALLBACK( metro_blit_done )
{
	requested_int[blitter_bit] = 1;
	update_irq_state(machine);
}

INLINE int blt_read(const UINT8 *ROM, const int offs)
{
	return ROM[offs];
}

INLINE void blt_write(const address_space *space, const int tmap, const offs_t offs, const UINT16 data, const UINT16 mask)
{
	switch( tmap )
	{
		case 1:	metro_vram_0_w(space,offs,data,mask);	break;
		case 2:	metro_vram_1_w(space,offs,data,mask);	break;
		case 3:	metro_vram_2_w(space,offs,data,mask);	break;
	}
//  logerror("CPU #0 PC %06X : Blitter %X] %04X <- %04X & %04X\n",cpu_get_pc(machine->activecpu),tmap,offs,data,mask);
}


static WRITE16_HANDLER( metro_blitter_w )
{
	COMBINE_DATA( &metro_blitter_regs[offset] );

	if (offset == 0xC/2)
	{
		UINT8 *src	=	memory_region(space->machine, "gfx1");
		size_t  src_len	=	memory_region_length(space->machine, "gfx1");

		UINT32 tmap		=	(metro_blitter_regs[ 0x00 / 2 ] << 16 ) +
							 metro_blitter_regs[ 0x02 / 2 ];
		UINT32 src_offs	=	(metro_blitter_regs[ 0x04 / 2 ] << 16 ) +
							 metro_blitter_regs[ 0x06 / 2 ];
		UINT32 dst_offs	=	(metro_blitter_regs[ 0x08 / 2 ] << 16 ) +
							 metro_blitter_regs[ 0x0a / 2 ];

		int shift			=	(dst_offs & 0x80) ? 0 : 8;
		UINT16 mask		=	(dst_offs & 0x80) ? 0x00ff : 0xff00;

//      logerror("CPU #0 PC %06X : Blitter regs %08X, %08X, %08X\n",cpu_get_pc(space->cpu),tmap,src_offs,dst_offs);

		dst_offs >>= 7+1;
		switch( tmap )
		{
			case 1:
			case 2:
			case 3:
				break;
			default:
				logerror("CPU #0 PC %06X : Blitter unknown destination: %08X\n",cpu_get_pc(space->cpu),tmap);
				return;
		}

		while (1)
		{
			UINT16 b1,b2,count;

			src_offs %= src_len;
			b1 = blt_read(src,src_offs);
//          logerror("CPU #0 PC %06X : Blitter opcode %02X at %06X\n",cpu_get_pc(space->cpu),b1,src_offs);
			src_offs++;

			count = ((~b1) & 0x3f) + 1;

			switch( (b1 & 0xc0) >> 6 )
			{
				case 0:

					/* Stop and Generate an IRQ. We can't generate it now
                       both because it's unlikely that the blitter is so
                       fast and because some games (e.g. lastfort) need to
                       complete the blitter irq service routine before doing
                       another blit. */
					if (b1 == 0)
					{
						timer_set(ATTOTIME_IN_USEC(500), NULL,0,metro_blit_done);
						return;
					}

					/* Copy */
					while (count--)
					{
						src_offs %= src_len;
						b2 = blt_read(src,src_offs) << shift;
						src_offs++;

						dst_offs &= 0xffff;
						blt_write(space,tmap,dst_offs,b2,mask);
						dst_offs = ((dst_offs+1) & (0x100-1)) | (dst_offs & (~(0x100-1)));
					}
					break;


				case 1:

					/* Fill with an increasing value */
					src_offs %= src_len;
					b2 = blt_read(src,src_offs);
					src_offs++;

					while (count--)
					{
						dst_offs &= 0xffff;
						blt_write(space,tmap,dst_offs,b2<<shift,mask);
						dst_offs = ((dst_offs+1) & (0x100-1)) | (dst_offs & (~(0x100-1)));
						b2++;
					}
					break;


				case 2:

					/* Fill with a fixed value */
					src_offs %= src_len;
					b2 = blt_read(src,src_offs) << shift;
					src_offs++;

					while (count--)
					{
						dst_offs &= 0xffff;
						blt_write(space,tmap,dst_offs,b2,mask);
						dst_offs = ((dst_offs+1) & (0x100-1)) | (dst_offs & (~(0x100-1)));
					}
					break;


				case 3:

					/* Skip to the next line ?? */
					if (b1 == 0xC0)
					{
						dst_offs +=   0x100;
						dst_offs &= ~(0x100-1);
						dst_offs |=  (0x100-1) & (metro_blitter_regs[ 0x0a / 2 ] >> (7+1));
					}
					else
					{
						dst_offs += count;
					}
					break;


				default:
					logerror("CPU #0 PC %06X : Blitter unknown opcode %02X at %06X\n",cpu_get_pc(space->cpu),b1,src_offs-1);
					return;
			}

		}
	}

}


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


                                Memory Maps


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

/*
 Lines starting with an empty comment in the following MemoryReadAddress
 arrays are there for debug (e.g. the game does not read from those ranges
 AFAIK)
*/


static ADDRESS_MAP_START( metro_snd_readmem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x3fff) AM_READ(SMH_ROM)	/* External ROM */
	AM_RANGE(0x4000, 0x7fff) AM_READ(SMH_BANK1)	/* External ROM (Banked) */
	AM_RANGE(0x8000, 0x87ff) AM_READ(SMH_RAM)	/* External RAM */
	AM_RANGE(0xff00, 0xffff) AM_READ(SMH_RAM)	/* Internal RAM */
ADDRESS_MAP_END

static ADDRESS_MAP_START( metro_snd_writemem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x3fff) AM_WRITE(SMH_ROM)	/* External ROM */
	AM_RANGE(0x4000, 0x7fff) AM_WRITE(SMH_BANK1)	/* External ROM (Banked) */
	AM_RANGE(0x8000, 0x87ff) AM_WRITE(SMH_RAM)	/* External RAM */
	AM_RANGE(0xff00, 0xffff) AM_WRITE(SMH_RAM)	/* Internal RAM */
ADDRESS_MAP_END

static ADDRESS_MAP_START( metro_snd_readport, ADDRESS_SPACE_IO, 8 )
	AM_RANGE(UPD7810_PORTA, UPD7810_PORTA) AM_READ(metro_porta_r)
ADDRESS_MAP_END

static ADDRESS_MAP_START( metro_snd_writeport, ADDRESS_SPACE_IO, 8 )
	AM_RANGE(UPD7810_PORTA, UPD7810_PORTA) AM_WRITE(metro_porta_w)
	AM_RANGE(UPD7810_PORTB, UPD7810_PORTB) AM_WRITE(metro_portb_w)
	AM_RANGE(UPD7810_PORTC, UPD7810_PORTC) AM_WRITE(metro_sound_rombank_w)
ADDRESS_MAP_END

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

static ADDRESS_MAP_START( daitorid_snd_readmem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x3fff) AM_READ(SMH_ROM)	/* External ROM */
	AM_RANGE(0x4000, 0x7fff) AM_READ(SMH_BANK1)	/* External ROM (Banked) */
	AM_RANGE(0x8000, 0x87ff) AM_READ(SMH_RAM)	/* External RAM */
	AM_RANGE(0xff00, 0xffff) AM_READ(SMH_RAM)	/* Internal RAM */
ADDRESS_MAP_END

static ADDRESS_MAP_START( daitorid_snd_writemem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x3fff) AM_WRITE(SMH_ROM)	/* External ROM */
	AM_RANGE(0x4000, 0x7fff) AM_WRITE(SMH_BANK1)	/* External ROM (Banked) */
	AM_RANGE(0x8000, 0x87ff) AM_WRITE(SMH_RAM)	/* External RAM */
	AM_RANGE(0xff00, 0xffff) AM_WRITE(SMH_RAM)	/* Internal RAM */
ADDRESS_MAP_END

static ADDRESS_MAP_START( daitorid_snd_readport, ADDRESS_SPACE_IO, 8 )
	AM_RANGE(UPD7810_PORTA, UPD7810_PORTA) AM_READ(metro_porta_r)
ADDRESS_MAP_END

static ADDRESS_MAP_START( daitorid_snd_writeport, ADDRESS_SPACE_IO, 8 )
	AM_RANGE(UPD7810_PORTA, UPD7810_PORTA) AM_WRITE(metro_porta_w)
	AM_RANGE(UPD7810_PORTB, UPD7810_PORTB) AM_WRITE(daitorid_portb_w)
	AM_RANGE(UPD7810_PORTC, UPD7810_PORTC) AM_WRITE(daitorid_sound_rombank_w)
ADDRESS_MAP_END

/***************************************************************************
                                    Bal Cube
***************************************************************************/

/* Really weird way of mapping 3 DSWs */
static READ16_HANDLER( balcube_dsw_r )
{
	UINT16 dsw1 = input_port_read(space->machine, "DSW0") >> 0;
	UINT16 dsw2 = input_port_read(space->machine, "DSW0") >> 8;
	UINT16 dsw3 = input_port_read(space->machine, "IN2");

	switch (offset*2)
	{
		case 0x1FFFC:	return ((dsw1 & 0x01) ? 0x40 : 0) | ((dsw3 & 0x01) ? 0x80 : 0);
		case 0x1FFFA:	return ((dsw1 & 0x02) ? 0x40 : 0) | ((dsw3 & 0x02) ? 0x80 : 0);
		case 0x1FFF6:	return ((dsw1 & 0x04) ? 0x40 : 0) | ((dsw3 & 0x04) ? 0x80 : 0);
		case 0x1FFEE:	return ((dsw1 & 0x08) ? 0x40 : 0) | ((dsw3 & 0x08) ? 0x80 : 0);
		case 0x1FFDE:	return ((dsw1 & 0x10) ? 0x40 : 0) | ((dsw3 & 0x10) ? 0x80 : 0);
		case 0x1FFBE:	return ((dsw1 & 0x20) ? 0x40 : 0) | ((dsw3 & 0x20) ? 0x80 : 0);
		case 0x1FF7E:	return ((dsw1 & 0x40) ? 0x40 : 0) | ((dsw3 & 0x40) ? 0x80 : 0);
		case 0x1FEFE:	return ((dsw1 & 0x80) ? 0x40 : 0) | ((dsw3 & 0x80) ? 0x80 : 0);

		case 0x1FDFE:	return (dsw2 & 0x01) ? 0x40 : 0;
		case 0x1FBFE:	return (dsw2 & 0x02) ? 0x40 : 0;
		case 0x1F7FE:	return (dsw2 & 0x04) ? 0x40 : 0;
		case 0x1EFFE:	return (dsw2 & 0x08) ? 0x40 : 0;
		case 0x1DFFE:	return (dsw2 & 0x10) ? 0x40 : 0;
		case 0x1BFFE:	return (dsw2 & 0x20) ? 0x40 : 0;
		case 0x17FFE:	return (dsw2 & 0x40) ? 0x40 : 0;
		case 0x0FFFE:	return (dsw2 & 0x80) ? 0x40 : 0;
	}
	logerror("CPU #0 PC %06X : unknown dsw address read: %04X\n",cpu_get_pc(space->cpu),offset);
	return 0xffff;
}


static ADDRESS_MAP_START( balcube_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x300000, 0x300001) AM_READ(ymf278b_r				)	// Sound
	AM_RANGE(0x400000, 0x41ffff) AM_READ(balcube_dsw_r			)	// DSW x 3
	AM_RANGE(0x600000, 0x61ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x620000, 0x63ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x640000, 0x65ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x660000, 0x66ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x670000, 0x673fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x674000, 0x674fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x678000, 0x6787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x6788a2, 0x6788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x500000, 0x500001) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x500002, 0x500003) AM_READ_PORT("IN1")				//
	AM_RANGE(0x500006, 0x500007) AM_READ(SMH_NOP				)	//
ADDRESS_MAP_END

static ADDRESS_MAP_START( balcube_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x300000, 0x30000b) AM_WRITE(ymf278b_w						)	// Sound
	AM_RANGE(0x500002, 0x500009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
	AM_RANGE(0x670000, 0x673fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x674000, 0x674fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x600000, 0x61ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x620000, 0x63ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x640000, 0x65ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x678000, 0x6787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size		)	// Tiles Set
	AM_RANGE(0x678840, 0x67884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs		)	// Tiles Blitter
	AM_RANGE(0x678860, 0x67886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window				)	// Tilemap Window
	AM_RANGE(0x678870, 0x67887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x678880, 0x678881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x678890, 0x678891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x6788a2, 0x6788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x6788a4, 0x6788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x6788aa, 0x6788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x6788ac, 0x6788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x679700, 0x679713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
ADDRESS_MAP_END

/***************************************************************************
                                    Daitoride (alt hardware)
***************************************************************************/


static ADDRESS_MAP_START( daitoa_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x400000, 0x400001) AM_READ(ymf278b_r				)	// Sound
	AM_RANGE(0x300000, 0x31ffff) AM_READ(balcube_dsw_r			)	// DSW x 3
	AM_RANGE(0x100000, 0x11ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x120000, 0x13ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x140000, 0x15ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x160000, 0x16ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x170000, 0x173fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x174000, 0x174fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x178000, 0x1787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x1788a2, 0x1788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x200000, 0x200001) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x200002, 0x200003) AM_READ_PORT("IN1")				//
	AM_RANGE(0x200006, 0x200007) AM_READ(SMH_NOP				)	//
ADDRESS_MAP_END

static ADDRESS_MAP_START( daitoa_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x400000, 0x40000b) AM_WRITE(ymf278b_w						)	// Sound
	AM_RANGE(0x200002, 0x200009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
	AM_RANGE(0x170000, 0x173fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x174000, 0x174fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x100000, 0x11ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x120000, 0x13ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x140000, 0x15ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x178000, 0x1787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size		)	// Tiles Set
	AM_RANGE(0x178840, 0x17884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs		)	// Tiles Blitter
	AM_RANGE(0x178860, 0x17886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window				)	// Tilemap Window
	AM_RANGE(0x178870, 0x17887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x178880, 0x178881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x178890, 0x178891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x1788a2, 0x1788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x1788a4, 0x1788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x1788aa, 0x1788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x1788ac, 0x1788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x179700, 0x179713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
ADDRESS_MAP_END


/***************************************************************************
                                Bang Bang Ball
***************************************************************************/

static ADDRESS_MAP_START( bangball_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0xf10000, 0xf10fff) AM_READ(SMH_RAM				)	// RAM (bug in the ram test routine)
	AM_RANGE(0xb00000, 0xb00001) AM_READ(ymf278b_r				)	// Sound
	AM_RANGE(0xc00000, 0xc1ffff) AM_READ(balcube_dsw_r			)	// DSW x 3
	AM_RANGE(0xd00000, 0xd00001) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0xd00002, 0xd00003) AM_READ_PORT("IN1")				//
	AM_RANGE(0xd00006, 0xd00007) AM_READ(SMH_NOP				)	//
	AM_RANGE(0xe00000, 0xe1ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0xe20000, 0xe3ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0xe40000, 0xe5ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0xe60000, 0xe6ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0xe70000, 0xe73fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0xe74000, 0xe74fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0xe78000, 0xe787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0xe788a2, 0xe788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
ADDRESS_MAP_END

static ADDRESS_MAP_START( bangball_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0xf10000, 0xf10fff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0xb00000, 0xb0000b) AM_WRITE(ymf278b_w						)	// Sound
	AM_RANGE(0xd00002, 0xd00009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
	AM_RANGE(0xe00000, 0xe1ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0xe20000, 0xe3ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0xe40000, 0xe5ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0xe70000, 0xe73fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0xe74000, 0xe74fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0xe78000, 0xe787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size		)	// Tiles Set
	AM_RANGE(0xe78840, 0xe7884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs		)	// Tiles Blitter
	AM_RANGE(0xe78860, 0xe7886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window				)	// Tilemap Window
	AM_RANGE(0xe78870, 0xe7887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0xe78880, 0xe78881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xe78890, 0xe78891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xe788a2, 0xe788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0xe788a4, 0xe788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0xe788aa, 0xe788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0xe788ac, 0xe788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0xe79700, 0xe79713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
ADDRESS_MAP_END

/***************************************************************************
                                Battle Bubble
***************************************************************************/

static ADDRESS_MAP_START( batlbubl_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x0fffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x100000, 0x11ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x120000, 0x13ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x140000, 0x15ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x160000, 0x16ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x170000, 0x173fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x174000, 0x174fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x178000, 0x1787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x1788a2, 0x1788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x200000, 0x200001) AM_READ_PORT("IN1")
	AM_RANGE(0x200002, 0x200003) AM_READ_PORT("DSW0")
	AM_RANGE(0x200004, 0x200005) AM_READ_PORT("IN0")
	AM_RANGE(0x200006, 0x200007) AM_READ_PORT("IN2")
	AM_RANGE(0x300000, 0x31ffff) AM_READ(balcube_dsw_r			)	// read but ignored?
	AM_RANGE(0x400000, 0x400001) AM_READ(ymf278b_r				)	// Sound
	AM_RANGE(0xf00000, 0xf0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0xf10000, 0xf10fff) AM_READ(SMH_RAM				)	// RAM (bug in the ram test routine)
ADDRESS_MAP_END

static ADDRESS_MAP_START( batlbubl_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x0fffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x100000, 0x11ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x120000, 0x13ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x140000, 0x15ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x170000, 0x173fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x174000, 0x174fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x178000, 0x1787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size		)	// Tiles Set
	AM_RANGE(0x178840, 0x17884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs		)	// Tiles Blitter
	AM_RANGE(0x178860, 0x17886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window				)	// Tilemap Window
	AM_RANGE(0x178870, 0x17887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x178880, 0x178881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x178890, 0x178891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x1788a2, 0x1788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x1788a4, 0x1788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x1788aa, 0x1788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x1788ac, 0x1788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x179700, 0x179713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x200002, 0x200009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
	AM_RANGE(0x400000, 0x40000b) AM_WRITE(ymf278b_w						)	// Sound
	AM_RANGE(0xf00000, 0xf0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0xf10000, 0xf10fff) AM_WRITE(SMH_RAM						)	// RAM
ADDRESS_MAP_END


/***************************************************************************
                                Dai Toride
***************************************************************************/

static ADDRESS_MAP_START( daitorid_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x800000, 0x80ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x470000, 0x473fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x4788a2, 0x4788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0xc00000, 0xc00001) AM_READ_PORT("IN0")
	AM_RANGE(0xc00002, 0xc00003) AM_READ_PORT("IN1")
	AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("DSW0")
	AM_RANGE(0xc00006, 0xc00007) AM_READ_PORT("IN2")
ADDRESS_MAP_END

static ADDRESS_MAP_START( daitorid_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x800000, 0x80ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x470000, 0x473fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window			)	// Tilemap Window
	AM_RANGE(0x478870, 0x47887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x478880, 0x478881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x478890, 0x478891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x4788a2, 0x4788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x4788a4, 0x4788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x4788a8, 0x4788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x4788aa, 0x4788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x4788ac, 0x4788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x479700, 0x479713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0xc00002, 0xc00009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                                Dharma Doujou
***************************************************************************/

static ADDRESS_MAP_START( dharma_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x400000, 0x40ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x800000, 0x81ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x820000, 0x83ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x840000, 0x85ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x870000, 0x873fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x878000, 0x8787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x8788a2, 0x8788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0xc00000, 0xc00001) AM_READ_PORT("IN0")
	AM_RANGE(0xc00002, 0xc00003) AM_READ_PORT("IN1")
	AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("DSW0")
	AM_RANGE(0xc00006, 0xc00007) AM_READ_PORT("IN2")
ADDRESS_MAP_END

static ADDRESS_MAP_START( dharma_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x400000, 0x40ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x800000, 0x81ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x820000, 0x83ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x840000, 0x85ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x870000, 0x873fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x878000, 0x8787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x878870, 0x87887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x878880, 0x878881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x878890, 0x878891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8788a2, 0x8788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x8788a4, 0x8788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x8788aa, 0x8788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x8788ac, 0x8788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x879700, 0x879713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0xc00002, 0xc00009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                                Karate Tournament
***************************************************************************/

/* This game uses almost only the blitter to write to the tilemaps.
   The CPU can only access a "window" of 512x256 pixels in the upper
   left corner of the big tilemap */

#define KARATOUR_OFFS( _x_ ) ((_x_) & (0x3f)) + (((_x_) & ~(0x3f)) * (0x100 / 0x40))

#define KARATOUR_VRAM( _n_ ) \
static READ16_HANDLER( karatour_vram_##_n_##_r ) \
{ \
	return metro_vram_##_n_[KARATOUR_OFFS(offset)]; \
} \
static WRITE16_HANDLER( karatour_vram_##_n_##_w ) \
{ \
	metro_vram_##_n_##_w(space,KARATOUR_OFFS(offset),data,mem_mask); \
}

KARATOUR_VRAM( 0 )
KARATOUR_VRAM( 1 )
KARATOUR_VRAM( 2 )

static ADDRESS_MAP_START( karatour_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xffc000, 0xffffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x400000, 0x400001) AM_READ(metro_soundstatus_r	)	// From Sound CPU
	AM_RANGE(0x400002, 0x400003) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x400004, 0x400005) AM_READ_PORT("IN1")				//
	AM_RANGE(0x400006, 0x400007) AM_READ_PORT("DSW0")				//
	AM_RANGE(0x40000a, 0x40000b) AM_READ_PORT("DSW1")				//
	AM_RANGE(0x40000c, 0x40000d) AM_READ_PORT("IN2")				//
	AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x870000, 0x873fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x875000, 0x875fff) AM_READ(karatour_vram_0_r		)	// Layer 0 (Part of)
	AM_RANGE(0x876000, 0x876fff) AM_READ(karatour_vram_1_r		)	// Layer 1 (Part of)
	AM_RANGE(0x877000, 0x877fff) AM_READ(karatour_vram_2_r		)	// Layer 2 (Part of)
	AM_RANGE(0x878000, 0x8787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x8788a2, 0x8788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
ADDRESS_MAP_END

static ADDRESS_MAP_START( karatour_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xffc000, 0xffffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x400000, 0x400001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x400002, 0x400003) AM_WRITE(metro_coin_lockout_1word_w	)	// Coin Lockout
	AM_RANGE(0x870000, 0x873fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x875000, 0x875fff) AM_WRITE(karatour_vram_0_w				)	// Layer 0 (Part of)
	AM_RANGE(0x876000, 0x876fff) AM_WRITE(karatour_vram_1_w				)	// Layer 1 (Part of)
	AM_RANGE(0x877000, 0x877fff) AM_WRITE(karatour_vram_2_w				)	// Layer 2 (Part of)
	AM_RANGE(0x878000, 0x8787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x878800, 0x878813) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x878870, 0x87887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x878880, 0x878881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x878890, 0x878891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8788a2, 0x8788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x8788a4, 0x8788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x8788aa, 0x8788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x8788ac, 0x8788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
ADDRESS_MAP_END


/***************************************************************************
                                Sankokushi
***************************************************************************/

/* same limited tilemap access as karatour */

static ADDRESS_MAP_START( kokushi_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x7fc000, 0x7fffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x870000, 0x873fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x875000, 0x875fff) AM_READ(karatour_vram_0_r		)	// Layer 0 (Part of)
	AM_RANGE(0x876000, 0x876fff) AM_READ(karatour_vram_1_r		)	// Layer 1 (Part of)
	AM_RANGE(0x877000, 0x877fff) AM_READ(karatour_vram_2_r		)	// Layer 2 (Part of)
	AM_RANGE(0x878000, 0x8787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x8788a2, 0x8788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0xc00000, 0xc00001) AM_READ_PORT("IN0")				// From Sound CPU
	AM_RANGE(0xc00002, 0xc00003) AM_READ_PORT("IN1")				// Inputs
	AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("DSW0")
ADDRESS_MAP_END

static ADDRESS_MAP_START( kokushi_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x7fc000, 0x7fffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x870000, 0x873fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x875000, 0x875fff) AM_WRITE(karatour_vram_0_w				)	// Layer 0 (Part of)
	AM_RANGE(0x876000, 0x876fff) AM_WRITE(karatour_vram_1_w				)	// Layer 1 (Part of)
	AM_RANGE(0x877000, 0x877fff) AM_WRITE(karatour_vram_2_w				)	// Layer 2 (Part of)
	AM_RANGE(0x878000, 0x8787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x878870, 0x87887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs - WRONG
//  AM_RANGE(0x878880, 0x878881) AM_WRITE(SMH_NOP                     )   // ? increasing
	AM_RANGE(0x878890, 0x878891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8788a2, 0x8788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x8788a4, 0x8788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x8788aa, 0x8788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x8788ac, 0x8788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x879700, 0x879713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0xc00002, 0xc00009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
ADDRESS_MAP_END



/***************************************************************************
                                Last Fortress
***************************************************************************/

static ADDRESS_MAP_START( lastfort_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x400000, 0x40ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x800000, 0x81ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x820000, 0x83ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x840000, 0x85ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x870000, 0x873fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x878000, 0x8787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x8788a2, 0x8788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0xc00000, 0xc00001) AM_READ(metro_soundstatus_r	)	// From Sound CPU
	AM_RANGE(0xc00002, 0xc00003) AM_READ(SMH_NOP				)	//
	AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0xc00006, 0xc00007) AM_READ_PORT("IN1")				//
	AM_RANGE(0xc00008, 0xc00009) AM_READ_PORT("IN2")				//
	AM_RANGE(0xc0000a, 0xc0000b) AM_READ_PORT("DSW0")				//
	AM_RANGE(0xc0000c, 0xc0000d) AM_READ_PORT("DSW1")				//
	AM_RANGE(0xc0000e, 0xc0000f) AM_READ_PORT("IN3")				//
ADDRESS_MAP_END

static ADDRESS_MAP_START( lastfort_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x400000, 0x40ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x800000, 0x81ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x820000, 0x83ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x840000, 0x85ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x870000, 0x873fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x878000, 0x8787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x878800, 0x878813) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x878870, 0x87887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x878880, 0x878881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x878890, 0x878891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8788a2, 0x8788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x8788a4, 0x8788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x8788aa, 0x8788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x8788ac, 0x8788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0xc00002, 0xc00003) AM_WRITE(metro_coin_lockout_1word_w	)	// Coin Lockout
ADDRESS_MAP_END

/* the German version is halfway between lastfort and ladykill (karatour) memory maps */

/* todo: clean up input reads etc. */
static ADDRESS_MAP_START( lastforg_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x400000, 0x400001) AM_READ(metro_soundstatus_r	)	// From Sound CPU
	AM_RANGE(0x400002, 0x400003) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x400004, 0x400005) AM_READ_PORT("IN1")				//
	AM_RANGE(0x400006, 0x400007) AM_READ_PORT("DSW0")				//
	AM_RANGE(0x40000a, 0x40000b) AM_READ_PORT("DSW1")				//
	AM_RANGE(0x40000c, 0x40000d) AM_READ_PORT("IN2")				//
	AM_RANGE(0x880000, 0x89ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x8a0000, 0x8bffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x8c0000, 0x8dffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x8e0000, 0x8effff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x8f0000, 0x8f3fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x8f4000, 0x8f4fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x8f8000, 0x8f87ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x8f88a2, 0x8f88a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0xc00000, 0xc0ffff) AM_READ(SMH_RAM				)	// RAM
ADDRESS_MAP_END

static ADDRESS_MAP_START( lastforg_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x400000, 0x400001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x400002, 0x400003) AM_WRITE(metro_coin_lockout_1word_w	)	// Coin Lockout
	AM_RANGE(0x880000, 0x89ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x8a0000, 0x8bffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x8c0000, 0x8dffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x8f0000, 0x8f3fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x8f4000, 0x8f4fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x8f8000, 0x8f87ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x8f8800, 0x8f8813) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x8f8840, 0x8f884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x8f8860, 0x8f886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x8f8870, 0x8f887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x8f8880, 0x8f8881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8f8890, 0x8f8891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8f88a2, 0x8f88a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x8f88a4, 0x8f88a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x8f88a8, 0x8f88a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x8f88aa, 0x8f88ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x8f88ac, 0x8f88ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0xc00000, 0xc0ffff) AM_WRITE(SMH_RAM						)	// RAM
ADDRESS_MAP_END


/***************************************************************************
                                Mahjong Gakuensai
***************************************************************************/

static int gakusai_oki_bank_lo, gakusai_oki_bank_hi;

static void gakusai_oki_bank_set(void)
{
	int bank = (gakusai_oki_bank_lo & 7) + (gakusai_oki_bank_hi & 1) * 8;
	okim6295_set_bank_base(0, bank * 0x40000);
}

static WRITE16_HANDLER( gakusai_oki_bank_hi_w )
{
	if (ACCESSING_BITS_0_7)
	{
		gakusai_oki_bank_hi = data & 0xff;
		gakusai_oki_bank_set();
	}
}

static WRITE16_HANDLER( gakusai_oki_bank_lo_w )
{
	if (ACCESSING_BITS_0_7)
	{
		gakusai_oki_bank_lo = data & 0xff;
		gakusai_oki_bank_set();
	}
}

static UINT16 *gakusai_input_sel;

static READ16_HANDLER( gakusai_input_r )
{
	UINT16 input_sel = (*gakusai_input_sel) ^ 0x3e;
	// Bit 0 ??
	if (input_sel & 0x0002)	return input_port_read(space->machine, "KEY0");
	if (input_sel & 0x0004)	return input_port_read(space->machine, "KEY1");
	if (input_sel & 0x0008)	return input_port_read(space->machine, "KEY2");
	if (input_sel & 0x0010)	return input_port_read(space->machine, "KEY3");
	if (input_sel & 0x0020)	return input_port_read(space->machine, "KEY4");
	return 0xffff;
}

static READ16_HANDLER( gakusai_eeprom_r )
{
	return eeprom_read_bit() & 1;
}

static WRITE16_HANDLER( gakusai_eeprom_w )
{
	if (ACCESSING_BITS_0_7)
	{
		// latch the bit
		eeprom_write_bit(data & 0x01);

		// reset line asserted: reset.
		eeprom_set_cs_line((data & 0x04) ? CLEAR_LINE : ASSERT_LINE );

		// clock line asserted: write latch or select next bit to read
		eeprom_set_clock_line((data & 0x02) ? ASSERT_LINE : CLEAR_LINE );
	}
}

static ADDRESS_MAP_START( gakusai_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM					)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_READ(SMH_RAM					)	// RAM
	AM_RANGE(0x200000, 0x21ffff) AM_READ(SMH_RAM					)	// Layer 0
	AM_RANGE(0x220000, 0x23ffff) AM_READ(SMH_RAM					)	// Layer 1
	AM_RANGE(0x240000, 0x25ffff) AM_READ(SMH_RAM					)	// Layer 2
	AM_RANGE(0x260000, 0x26ffff) AM_READ(metro_bankedrom_r			)	// Banked ROM
	AM_RANGE(0x270000, 0x273fff) AM_READ(SMH_RAM					)	// Palette
	AM_RANGE(0x274000, 0x274fff) AM_READ(SMH_RAM					)	// Sprites
	AM_RANGE(0x278000, 0x2787ff) AM_READ(SMH_RAM					)	// Tiles Set
	AM_RANGE(0x278832, 0x278833) AM_READ(metro_irq_cause_r			)	// IRQ Cause
	AM_RANGE(0x278880, 0x278881) AM_READ(gakusai_input_r			)	// Inputs
	AM_RANGE(0x278882, 0x278883) AM_READ_PORT("IN0")					//
	AM_RANGE(0x27880e, 0x27880f) AM_READ(SMH_RAM					)	// Screen Control
	AM_RANGE(0x700000, 0x700001) AM_READ(okim6295_status_0_lsb_r	)	// Sound
	AM_RANGE(0xc00000, 0xc00001) AM_READ(gakusai_eeprom_r			)	// EEPROM
ADDRESS_MAP_END

static ADDRESS_MAP_START( gakusai_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x200000, 0x21ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x220000, 0x23ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x240000, 0x25ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x270000, 0x273fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x274000, 0x274fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x278000, 0x2787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x27880e, 0x27880f) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x278810, 0x27881f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_levels	)	// IRQ Levels
	AM_RANGE(0x278820, 0x27882f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_vectors	)	// IRQ Vectors
	AM_RANGE(0x278830, 0x278831) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x278832, 0x278833) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x278836, 0x278837) AM_WRITE(watchdog_reset16_w			)	// Watchdog
	AM_RANGE(0x278840, 0x27884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x278860, 0x27886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x278850, 0x27885b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x278870, 0x278871) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x278888, 0x278889) AM_WRITE(SMH_RAM) AM_BASE(&gakusai_input_sel	)	// Inputs
	AM_RANGE(0x279700, 0x279713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x400000, 0x400001) AM_WRITE(SMH_NOP						)	// ? 5
	AM_RANGE(0x500000, 0x500001) AM_WRITE(gakusai_oki_bank_lo_w			)	// Sound
	AM_RANGE(0x600000, 0x600001) AM_WRITE(ym2413_register_port_0_lsb_w	)
	AM_RANGE(0x600002, 0x600003) AM_WRITE(ym2413_data_port_0_lsb_w		)
	AM_RANGE(0x700000, 0x700001) AM_WRITE(okim6295_data_0_lsb_w 		)
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(gakusai_eeprom_w				)	// EEPROM
	AM_RANGE(0xd00000, 0xd00001) AM_WRITE(gakusai_oki_bank_hi_w			)
ADDRESS_MAP_END


/***************************************************************************
                                Mahjong Gakuensai 2
***************************************************************************/

static ADDRESS_MAP_START( gakusai2_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM					)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_READ(SMH_RAM					)	// RAM
	AM_RANGE(0x600000, 0x61ffff) AM_READ(SMH_RAM					)	// Layer 0
	AM_RANGE(0x620000, 0x63ffff) AM_READ(SMH_RAM					)	// Layer 1
	AM_RANGE(0x640000, 0x65ffff) AM_READ(SMH_RAM					)	// Layer 2
	AM_RANGE(0x660000, 0x66ffff) AM_READ(metro_bankedrom_r			)	// Banked ROM
	AM_RANGE(0x670000, 0x673fff) AM_READ(SMH_RAM					)	// Palette
	AM_RANGE(0x674000, 0x674fff) AM_READ(SMH_RAM					)	// Sprites
	AM_RANGE(0x675000, 0x675fff) AM_READ(SMH_RAM					)	// Sprites?
	AM_RANGE(0x678000, 0x6787ff) AM_READ(SMH_RAM					)	// Tiles Set
	AM_RANGE(0x678832, 0x678833) AM_READ(metro_irq_cause_r			)	// IRQ Cause
	AM_RANGE(0x678880, 0x678881) AM_READ(gakusai_input_r			)	// Inputs
	AM_RANGE(0x678882, 0x678883) AM_READ_PORT("IN0")					//
	AM_RANGE(0x67880e, 0x67880f) AM_READ(SMH_RAM					)	// Screen Control
	AM_RANGE(0xb00000, 0xb00001) AM_READ(okim6295_status_0_lsb_r	)	// Sound
	AM_RANGE(0xe00000, 0xe00001) AM_READ(gakusai_eeprom_r			)	// EEPROM
ADDRESS_MAP_END

static ADDRESS_MAP_START( gakusai2_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x600000, 0x61ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x620000, 0x63ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x640000, 0x65ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x670000, 0x673fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x674000, 0x674fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x675000, 0x675fff) AM_WRITE(SMH_RAM						)	// Sprites?
	AM_RANGE(0x678000, 0x6787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x67880e, 0x67880f) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x678810, 0x67881f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_levels	)	// IRQ Levels
	AM_RANGE(0x678820, 0x67882f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_vectors	)	// IRQ Vectors
	AM_RANGE(0x678830, 0x678831) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x678832, 0x678833) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x678836, 0x678837) AM_WRITE(watchdog_reset16_w			)	// Watchdog
	AM_RANGE(0x678840, 0x67884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x678860, 0x67886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x678850, 0x67885b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x678870, 0x678871) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x678888, 0x678889) AM_WRITE(SMH_RAM) AM_BASE(&gakusai_input_sel	)	// Inputs
	AM_RANGE(0x679700, 0x679713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x800000, 0x800001) AM_WRITE(SMH_NOP						)	// ? 5
	AM_RANGE(0x900000, 0x900001) AM_WRITE(gakusai_oki_bank_lo_w			)	// Sound
	AM_RANGE(0xa00000, 0xa00001) AM_WRITE(gakusai_oki_bank_hi_w			)
	AM_RANGE(0xb00000, 0xb00001) AM_WRITE(okim6295_data_0_lsb_w 		)
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(ym2413_register_port_0_lsb_w	)
	AM_RANGE(0xc00002, 0xc00003) AM_WRITE(ym2413_data_port_0_lsb_w		)
	AM_RANGE(0xe00000, 0xe00001) AM_WRITE(gakusai_eeprom_w				)	// EEPROM
ADDRESS_MAP_END


/***************************************************************************
                        Mahjong Doukyuusei Special
***************************************************************************/

static READ16_HANDLER( dokyusp_eeprom_r )
{
	// clock line asserted: write latch or select next bit to read
	eeprom_set_clock_line(CLEAR_LINE);
	eeprom_set_clock_line(ASSERT_LINE);

	return eeprom_read_bit() & 1;
}

static WRITE16_HANDLER( dokyusp_eeprom_bit_w )
{
	if (ACCESSING_BITS_0_7)
	{
		// latch the bit
		eeprom_write_bit(data & 0x01);

		// clock line asserted: write latch or select next bit to read
		eeprom_set_clock_line(CLEAR_LINE);
		eeprom_set_clock_line(ASSERT_LINE);
	}
}

static WRITE16_HANDLER( dokyusp_eeprom_reset_w )
{
	if (ACCESSING_BITS_0_7)
	{
		// reset line asserted: reset.
		eeprom_set_cs_line((data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
	}
}

static ADDRESS_MAP_START( dokyusp_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM					)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_READ(SMH_RAM					)	// RAM
	AM_RANGE(0x200000, 0x21ffff) AM_READ(SMH_RAM					)	// Layer 0
	AM_RANGE(0x220000, 0x23ffff) AM_READ(SMH_RAM					)	// Layer 1
	AM_RANGE(0x240000, 0x25ffff) AM_READ(SMH_RAM					)	// Layer 2
	AM_RANGE(0x260000, 0x26ffff) AM_READ(metro_bankedrom_r			)	// Banked ROM
	AM_RANGE(0x270000, 0x273fff) AM_READ(SMH_RAM					)	// Palette
	AM_RANGE(0x274000, 0x274fff) AM_READ(SMH_RAM					)	// Sprites
	AM_RANGE(0x278000, 0x2787ff) AM_READ(SMH_RAM					)	// Tiles Set
	AM_RANGE(0x278832, 0x278833) AM_READ(metro_irq_cause_r			)	// IRQ Cause
	AM_RANGE(0x278880, 0x278881) AM_READ(gakusai_input_r			)	// Inputs
	AM_RANGE(0x278882, 0x278883) AM_READ_PORT("IN0")					//
	AM_RANGE(0x27880e, 0x27880f) AM_READ(SMH_RAM					)	// Screen Control
	AM_RANGE(0x700000, 0x700001) AM_READ(okim6295_status_0_lsb_r	)	// Sound
	AM_RANGE(0xd00000, 0xd00001) AM_READ(dokyusp_eeprom_r			)	// EEPROM
ADDRESS_MAP_END

static ADDRESS_MAP_START( dokyusp_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x200000, 0x21ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x220000, 0x23ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x240000, 0x25ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x270000, 0x273fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x274000, 0x274fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x278000, 0x2787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x27880e, 0x27880f) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x278810, 0x27881f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_levels	)	// IRQ Levels
	AM_RANGE(0x278820, 0x27882f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_vectors	)	// IRQ Vectors
	AM_RANGE(0x278830, 0x278831) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x278832, 0x278833) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x278836, 0x278837) AM_WRITE(watchdog_reset16_w			)	// Watchdog
	AM_RANGE(0x278840, 0x27884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x278860, 0x27886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x278850, 0x27885b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x278870, 0x278871) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x278888, 0x278889) AM_WRITE(SMH_RAM) AM_BASE(&gakusai_input_sel	)	// Inputs
	AM_RANGE(0x279700, 0x279713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x400000, 0x400001) AM_WRITE(SMH_NOP						)	// ? 5
	AM_RANGE(0x500000, 0x500001) AM_WRITE(gakusai_oki_bank_lo_w			)	// Sound
	AM_RANGE(0x600000, 0x600001) AM_WRITE(ym2413_register_port_0_lsb_w	)
	AM_RANGE(0x600002, 0x600003) AM_WRITE(ym2413_data_port_0_lsb_w		)
	AM_RANGE(0x700000, 0x700001) AM_WRITE(okim6295_data_0_lsb_w 		)
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(dokyusp_eeprom_reset_w		)	// EEPROM
	AM_RANGE(0xd00000, 0xd00001) AM_WRITE(dokyusp_eeprom_bit_w			)	// EEPROM
ADDRESS_MAP_END


/***************************************************************************
                            Mahjong Doukyuusei
***************************************************************************/

static ADDRESS_MAP_START( dokyusei_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM					)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_READ(SMH_RAM					)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_READ(SMH_RAM					)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_READ(SMH_RAM					)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_READ(SMH_RAM					)	// Layer 2
	AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r			)	// Banked ROM
	AM_RANGE(0x470000, 0x473fff) AM_READ(SMH_RAM					)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_READ(SMH_RAM					)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_READ(SMH_RAM					)	// Tiles Set
//  AM_RANGE(0x478832, 0x478833) AM_READ(metro_irq_cause_r          )   // IRQ Cause
	AM_RANGE(0x478880, 0x478881) AM_READ(gakusai_input_r			)	// Inputs
	AM_RANGE(0x478882, 0x478883) AM_READ_PORT("IN0")					//
	AM_RANGE(0x478884, 0x478885) AM_READ_PORT("DSW0")					// 2 x DSW
	AM_RANGE(0x478886, 0x478887) AM_READ_PORT("DSW1")					//
	AM_RANGE(0xd00000, 0xd00001) AM_READ(okim6295_status_0_lsb_r	)	// Sound
ADDRESS_MAP_END

static ADDRESS_MAP_START( dokyusei_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x460000, 0x46ffff) AM_WRITE(SMH_NOP						)	// DSW Selection
	AM_RANGE(0x470000, 0x473fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x47880e, 0x47880f) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x478810, 0x47881f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_levels	)	// IRQ Levels
	AM_RANGE(0x478820, 0x47882f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_vectors	)	// IRQ Vectors
	AM_RANGE(0x478830, 0x478831) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x478832, 0x478833) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x478836, 0x478837) AM_WRITE(SMH_NOP						)	// ? watchdog ?
	AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x478850, 0x47885b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x478870, 0x478871) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x479700, 0x479713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x478888, 0x478889) AM_WRITE(SMH_RAM) AM_BASE(&gakusai_input_sel	)	// Inputs
	AM_RANGE(0x800000, 0x800001) AM_WRITE(gakusai_oki_bank_hi_w			)	// Samples Bank?
	AM_RANGE(0x900000, 0x900001) AM_WRITE(SMH_NOP						)	// ? 4
	AM_RANGE(0xa00000, 0xa00001) AM_WRITE(gakusai_oki_bank_lo_w			)	// Samples Bank
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(ym2413_register_port_0_lsb_w	)	// Sound
	AM_RANGE(0xc00002, 0xc00003) AM_WRITE(ym2413_data_port_0_lsb_w		)	//
	AM_RANGE(0xd00000, 0xd00001) AM_WRITE(okim6295_data_0_lsb_w			)	//
ADDRESS_MAP_END


/***************************************************************************
                                Pang Pom's
***************************************************************************/

static ADDRESS_MAP_START( pangpoms_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xc00000, 0xc0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x470000, 0x473fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x4788a2, 0x4788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x800000, 0x800001) AM_READ(metro_soundstatus_r	)	// From Sound CPU
	AM_RANGE(0x800002, 0x800003) AM_READ(SMH_NOP				)	//
	AM_RANGE(0x800004, 0x800005) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x800006, 0x800007) AM_READ_PORT("IN1")				//
	AM_RANGE(0x800008, 0x800009) AM_READ_PORT("IN2")				//
	AM_RANGE(0x80000a, 0x80000b) AM_READ_PORT("DSW0")				//
	AM_RANGE(0x80000c, 0x80000d) AM_READ_PORT("DSW1")				//
	AM_RANGE(0x80000e, 0x80000f) AM_READ_PORT("IN3")				//
ADDRESS_MAP_END

static ADDRESS_MAP_START( pangpoms_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xc00000, 0xc0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x470000, 0x473fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x478800, 0x478813) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x478870, 0x47887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x478880, 0x478881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x478890, 0x478891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x4788a2, 0x4788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x4788a4, 0x4788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x4788a8, 0x4788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x4788aa, 0x4788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x4788ac, 0x4788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x800000, 0x800001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x800002, 0x800003) AM_WRITE(metro_coin_lockout_1word_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                                Poitto!
***************************************************************************/

static ADDRESS_MAP_START( poitto_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x400000, 0x40ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0xc00000, 0xc1ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0xc20000, 0xc3ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0xc40000, 0xc5ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0xc60000, 0xc6ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0xc70000, 0xc73fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0xc74000, 0xc74fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0xc78000, 0xc787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0xc788a2, 0xc788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x800000, 0x800001) AM_READ_PORT("IN0")
	AM_RANGE(0x800002, 0x800003) AM_READ_PORT("IN1")
	AM_RANGE(0x800004, 0x800005) AM_READ_PORT("DSW0")
	AM_RANGE(0x800006, 0x800007) AM_READ_PORT("IN2")
ADDRESS_MAP_END

static ADDRESS_MAP_START( poitto_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x400000, 0x40ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0xc00000, 0xc1ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0xc20000, 0xc3ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0xc40000, 0xc5ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0xc70000, 0xc73fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0xc74000, 0xc74fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0xc78000, 0xc787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0xc78800, 0xc78813) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0xc78840, 0xc7884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0xc78860, 0xc7886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0xc78870, 0xc7887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0xc78880, 0xc78881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xc78890, 0xc78891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xc788a2, 0xc788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0xc788a4, 0xc788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0xc788a8, 0xc788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0xc788aa, 0xc788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0xc788ac, 0xc788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x800000, 0x800001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x800002, 0x800009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                                Sky Alert
***************************************************************************/

static ADDRESS_MAP_START( skyalert_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xc00000, 0xc0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x800000, 0x81ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x820000, 0x83ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x840000, 0x85ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x870000, 0x873fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x878000, 0x8787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x8788a2, 0x8788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x400000, 0x400001) AM_READ(metro_soundstatus_r	)	// From Sound CPU
	AM_RANGE(0x400002, 0x400003) AM_READ(SMH_NOP				)	//
	AM_RANGE(0x400004, 0x400005) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x400006, 0x400007) AM_READ_PORT("IN1")				//
	AM_RANGE(0x400008, 0x400009) AM_READ_PORT("IN2")				//
	AM_RANGE(0x40000a, 0x40000b) AM_READ_PORT("DSW0")				//
	AM_RANGE(0x40000c, 0x40000d) AM_READ_PORT("DSW1")				//
	AM_RANGE(0x40000e, 0x40000f) AM_READ_PORT("IN3")				//
ADDRESS_MAP_END

static ADDRESS_MAP_START( skyalert_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x03ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xc00000, 0xc0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x800000, 0x81ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x820000, 0x83ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x840000, 0x85ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x870000, 0x873fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x874000, 0x874fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x878000, 0x8787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x878800, 0x878813) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x878870, 0x87887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x878880, 0x878881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x878890, 0x878891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x8788a2, 0x8788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x8788a4, 0x8788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0x8788aa, 0x8788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x8788ac, 0x8788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x400000, 0x400001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x400002, 0x400003) AM_WRITE(metro_coin_lockout_1word_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                                Pururun
***************************************************************************/

static ADDRESS_MAP_START( pururun_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x800000, 0x80ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0xc00000, 0xc1ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0xc20000, 0xc3ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0xc40000, 0xc5ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0xc60000, 0xc6ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0xc70000, 0xc73fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0xc74000, 0xc74fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0xc78000, 0xc787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0xc788a2, 0xc788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x400000, 0x400001) AM_READ_PORT("IN0")
	AM_RANGE(0x400002, 0x400003) AM_READ_PORT("IN1")
	AM_RANGE(0x400004, 0x400005) AM_READ_PORT("DSW0")
	AM_RANGE(0x400006, 0x400007) AM_READ_PORT("IN2")
ADDRESS_MAP_END

static ADDRESS_MAP_START( pururun_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x800000, 0x80ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0xc00000, 0xc1ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0xc20000, 0xc3ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0xc40000, 0xc5ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0xc70000, 0xc73fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0xc74000, 0xc74fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0xc78000, 0xc787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0xc78840, 0xc7884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0xc78860, 0xc7886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0xc78870, 0xc7887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0xc78880, 0xc78881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xc78890, 0xc78891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xc788a2, 0xc788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0xc788a4, 0xc788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0xc788a8, 0xc788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0xc788aa, 0xc788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0xc788ac, 0xc788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0xc79700, 0xc79713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x400000, 0x400001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x400002, 0x400009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                            Toride II Adauchi Gaiden
***************************************************************************/

static ADDRESS_MAP_START( toride2g_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0x400000, 0x4cffff) AM_READ(SMH_RAM				)	// RAM (4xc000-4xffff mirrored?)
	AM_RANGE(0xc00000, 0xc1ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0xc20000, 0xc3ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0xc40000, 0xc5ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0xc60000, 0xc6ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0xc70000, 0xc73fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0xc74000, 0xc74fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0xc78000, 0xc787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0xc788a2, 0xc788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x800000, 0x800001) AM_READ_PORT("IN0")
	AM_RANGE(0x800002, 0x800003) AM_READ_PORT("IN1")
	AM_RANGE(0x800004, 0x800005) AM_READ_PORT("DSW0")
	AM_RANGE(0x800006, 0x800007) AM_READ_PORT("IN2")
ADDRESS_MAP_END

static ADDRESS_MAP_START( toride2g_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x400000, 0x4cffff) AM_WRITE(SMH_RAM						)	// RAM (4xc000-4xffff mirrored?)
	AM_RANGE(0xc00000, 0xc1ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0xc20000, 0xc3ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0xc40000, 0xc5ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0xc70000, 0xc73fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0xc74000, 0xc74fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0xc78000, 0xc787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0xc78840, 0xc7884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0xc78860, 0xc7886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0xc78870, 0xc7887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0xc78880, 0xc78881) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xc78890, 0xc78891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0xc788a2, 0xc788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0xc788a4, 0xc788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0xc788a8, 0xc788a9) AM_WRITE(metro_soundlatch_w			)	// To Sound CPU
	AM_RANGE(0xc788aa, 0xc788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0xc788ac, 0xc788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0xc79700, 0xc79713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x800000, 0x800001) AM_WRITE(metro_soundstatus_w			)	// To Sound CPU
	AM_RANGE(0x800002, 0x800009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
ADDRESS_MAP_END


/***************************************************************************
                            Blazing Tornado
***************************************************************************/

static WRITE16_HANDLER( blzntrnd_sound_w )
{
	soundlatch_w(space, offset, data>>8);
	cpu_set_input_line(space->machine->cpu[1], INPUT_LINE_NMI, PULSE_LINE);
}

static WRITE8_HANDLER( blzntrnd_sh_bankswitch_w )
{
	UINT8 *RAM = memory_region(space->machine, "audio");
	int bankaddress;

	bankaddress = 0x10000 + (data & 0x03) * 0x4000;
	memory_set_bankptr(space->machine, 1, &RAM[bankaddress]);
}

static void blzntrnd_irqhandler(running_machine *machine, int irq)
{
	cpu_set_input_line(machine->cpu[1], 0, irq ? ASSERT_LINE : CLEAR_LINE);
}

static const ym2610_interface blzntrnd_ym2610_interface =
{
	blzntrnd_irqhandler
};

static ADDRESS_MAP_START( blzntrnd_sound_readmem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x7fff) AM_READ(SMH_ROM)
	AM_RANGE(0x8000, 0xbfff) AM_READ(SMH_BANK1)
	AM_RANGE(0xe000, 0xffff) AM_READ(SMH_RAM)
ADDRESS_MAP_END

static ADDRESS_MAP_START( blzntrnd_sound_writemem, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x7fff) AM_WRITE(SMH_ROM)
	AM_RANGE(0x8000, 0xbfff) AM_WRITE(SMH_ROM)
	AM_RANGE(0xe000, 0xffff) AM_WRITE(SMH_RAM)
ADDRESS_MAP_END

static ADDRESS_MAP_START( blzntrnd_sound_readport, ADDRESS_SPACE_IO, 8 )
	ADDRESS_MAP_GLOBAL_MASK(0xff)
	AM_RANGE(0x40, 0x40) AM_READ(soundlatch_r)
	AM_RANGE(0x80, 0x80) AM_READ(ym2610_status_port_0_a_r)
	AM_RANGE(0x82, 0x82) AM_READ(ym2610_status_port_0_b_r)
ADDRESS_MAP_END

static ADDRESS_MAP_START( blzntrnd_sound_writeport, ADDRESS_SPACE_IO, 8 )
	ADDRESS_MAP_GLOBAL_MASK(0xff)
	AM_RANGE(0x00, 0x00) AM_WRITE(blzntrnd_sh_bankswitch_w)
	AM_RANGE(0x40, 0x40) AM_WRITE(SMH_NOP)
	AM_RANGE(0x80, 0x80) AM_WRITE(ym2610_control_port_0_a_w)
	AM_RANGE(0x81, 0x81) AM_WRITE(ym2610_data_port_0_a_w)
	AM_RANGE(0x82, 0x82) AM_WRITE(ym2610_control_port_0_b_w)
	AM_RANGE(0x83, 0x83) AM_WRITE(ym2610_data_port_0_b_w)
ADDRESS_MAP_END

static ADDRESS_MAP_START( blzntrnd_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x1fffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xff0000, 0xffffff) AM_READ(SMH_RAM				)	// RAM
//  AM_RANGE(0x300000, 0x300001) AM_READ(SMH_NOP              )   // Sound
	AM_RANGE(0x200000, 0x21ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x220000, 0x23ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x240000, 0x25ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x260000, 0x26ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
	AM_RANGE(0x270000, 0x273fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x274000, 0x274fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x278000, 0x2787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x2788a2, 0x2788a3) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0xe00000, 0xe00001) AM_READ_PORT("DSW0")				// Inputs
	AM_RANGE(0xe00002, 0xe00003) AM_READ_PORT("DSW1")				//
	AM_RANGE(0xe00004, 0xe00005) AM_READ_PORT("IN0")				//
	AM_RANGE(0xe00006, 0xe00007) AM_READ_PORT("IN1")				//
	AM_RANGE(0xe00008, 0xe00009) AM_READ_PORT("IN2")				//
	AM_RANGE(0x400000, 0x43ffff) AM_READ(SMH_RAM				)	// 053936
ADDRESS_MAP_END

static ADDRESS_MAP_START( blzntrnd_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x1fffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0x200000, 0x21ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x220000, 0x23ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x240000, 0x25ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x260000, 0x26ffff) AM_WRITE(SMH_NOP				)	// ??????
	AM_RANGE(0x270000, 0x273fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x274000, 0x274fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x278000, 0x2787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size		)	// Tiles Set
	AM_RANGE(0x278860, 0x27886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window				)	// Tilemap Window
	AM_RANGE(0x278870, 0x27887b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll
	AM_RANGE(0x278890, 0x278891) AM_WRITE(SMH_NOP						)	// ? increasing
	AM_RANGE(0x2788a2, 0x2788a3) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x2788a4, 0x2788a5) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x2788aa, 0x2788ab) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x2788ac, 0x2788ad) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x279700, 0x279713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0x400000, 0x43ffff) AM_WRITE(metro_K053936_w) AM_BASE(&metro_K053936_ram	)	// 053936
	AM_RANGE(0x500000, 0x500fff) AM_WRITE(SMH_RAM) AM_BASE(&K053936_0_linectrl)	// 053936 line control
	AM_RANGE(0x600000, 0x60001f) AM_WRITE(SMH_RAM) AM_BASE(&K053936_0_ctrl	)	// 053936 control
	AM_RANGE(0xe00000, 0xe00001) AM_WRITE(SMH_NOP)
	AM_RANGE(0xe00002, 0xe00003) AM_WRITE(blzntrnd_sound_w)
	AM_RANGE(0xff0000, 0xffffff) AM_WRITE(SMH_RAM						)	// RAM
ADDRESS_MAP_END


/***************************************************************************
                                    Mouja
***************************************************************************/

static WRITE16_HANDLER( mouja_sound_rombank_w )
{
	if (ACCESSING_BITS_0_7)
		okim6295_set_bank_base(0, ((data >> 3) & 0x07) * 0x40000);
}

static ADDRESS_MAP_START( mouja_readmem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM				)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_READ(SMH_RAM				)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_READ(SMH_RAM				)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_READ(SMH_RAM				)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_READ(SMH_RAM				)	// Layer 2
	AM_RANGE(0x470000, 0x473fff) AM_READ(SMH_RAM				)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_READ(SMH_RAM				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_READ(SMH_RAM				)	// Tiles Set
	AM_RANGE(0x478832, 0x478833) AM_READ(metro_irq_cause_r		)	// IRQ Cause
	AM_RANGE(0x478880, 0x478881) AM_READ_PORT("IN0")				// Inputs
	AM_RANGE(0x478882, 0x478883) AM_READ_PORT("IN1")				//
	AM_RANGE(0x478884, 0x478885) AM_READ_PORT("DSW0")				//
	AM_RANGE(0x478886, 0x478887) AM_READ_PORT("IN2")				//
	AM_RANGE(0xd00000, 0xd00001) AM_READ(okim6295_status_0_lsb_r)
#if 0
	AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r		)	// Banked ROM
#endif
ADDRESS_MAP_END

static ADDRESS_MAP_START( mouja_writemem, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM						)	// ROM
	AM_RANGE(0xf00000, 0xf0ffff) AM_WRITE(SMH_RAM						)	// RAM
	AM_RANGE(0x400000, 0x41ffff) AM_WRITE(metro_vram_0_w) AM_BASE(&metro_vram_0	)	// Layer 0
	AM_RANGE(0x420000, 0x43ffff) AM_WRITE(metro_vram_1_w) AM_BASE(&metro_vram_1	)	// Layer 1
	AM_RANGE(0x440000, 0x45ffff) AM_WRITE(metro_vram_2_w) AM_BASE(&metro_vram_2	)	// Layer 2
	AM_RANGE(0x470000, 0x473fff) AM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w  ) AM_BASE(&paletteram16	)	// Palette
	AM_RANGE(0x474000, 0x474fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16) AM_SIZE(&spriteram_size				)	// Sprites
	AM_RANGE(0x478000, 0x4787ff) AM_WRITE(SMH_RAM) AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size	)	// Tiles Set
	AM_RANGE(0x47880e, 0x47880f) AM_WRITE(SMH_RAM) AM_BASE(&metro_screenctrl	)	// Screen Control
	AM_RANGE(0x478810, 0x47881f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_levels	)	// IRQ Levels
	AM_RANGE(0x478820, 0x47882f) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_vectors	)	// IRQ Vectors
	AM_RANGE(0x478830, 0x478831) AM_WRITE(SMH_RAM) AM_BASE(&metro_irq_enable	)	// IRQ Enable
	AM_RANGE(0x478832, 0x478833) AM_WRITE(metro_irq_cause_w				)	// IRQ Acknowledge
	AM_RANGE(0x478834, 0x478835) AM_WRITE(mouja_irq_timer_ctrl_w		)	// IRQ set timer count
	AM_RANGE(0x478836, 0x478837) AM_WRITE(watchdog_reset16_w			)	// Watchdog
	AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_BASE(&metro_window	)	// Tilemap Window
	AM_RANGE(0x478850, 0x47885b) AM_WRITE(SMH_RAM) AM_BASE(&metro_scroll		)	// Scroll Regs
	AM_RANGE(0x478888, 0x478889) AM_WRITE(SMH_NOP)								// ??
	AM_RANGE(0x479700, 0x479713) AM_WRITE(SMH_RAM) AM_BASE(&metro_videoregs	)	// Video Registers
	AM_RANGE(0xc00000, 0xc00001) AM_WRITE(ym2413_register_port_0_lsb_w	)
	AM_RANGE(0xc00002, 0xc00003) AM_WRITE(ym2413_data_port_0_lsb_w		)
	AM_RANGE(0x800000, 0x800001) AM_WRITE(mouja_sound_rombank_w			)
	AM_RANGE(0xd00000, 0xd00001) AM_WRITE(okim6295_data_0_msb_w  		)

#if 0
	AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_BASE(&metro_blitter_regs	)	// Tiles Blitter
	AM_RANGE(0x47883a, 0x47883b) AM_WRITE(SMH_RAM) AM_BASE(&metro_rombank		)	// Rom Bank
	AM_RANGE(0x800002, 0x800009) AM_WRITE(metro_coin_lockout_4words_w	)	// Coin Lockout
#endif
ADDRESS_MAP_END


/***************************************************************************
                                Puzzlet
***************************************************************************/

static WRITE16_HANDLER( puzzlet_irq_enable_w )
{
	if (ACCESSING_BITS_0_7)
		*metro_irq_enable = data^0xffff;
}

// H8/3007 CPU
static ADDRESS_MAP_START( puzzlet_map, ADDRESS_SPACE_PROGRAM, 16 )
	AM_RANGE( 0x000000, 0x1fffff ) AM_ROM
	AM_RANGE( 0x430000, 0x433fff ) AM_RAM
	AM_RANGE( 0x470000, 0x47dfff ) AM_RAM

	AM_RANGE( 0x500000, 0x500001 ) AM_READWRITE( okim6295_status_0_msb_r, okim6295_data_0_msb_w )
	AM_RANGE( 0x580000, 0x580001 ) AM_WRITE( ym2413_register_port_0_msb_w )
	AM_RANGE( 0x580002, 0x580003 ) AM_WRITE( ym2413_data_port_0_msb_w )

	AM_RANGE( 0x700000, 0x71ffff ) AM_READWRITE( SMH_RAM, metro_vram_0_w ) AM_BASE( &metro_vram_0 )	// Layer 0
	AM_RANGE( 0x720000, 0x73ffff ) AM_READWRITE( SMH_RAM, metro_vram_1_w ) AM_BASE( &metro_vram_1 )	// Layer 1
	AM_RANGE( 0x740000, 0x75ffff ) AM_READWRITE( SMH_RAM, metro_vram_2_w ) AM_BASE( &metro_vram_2 )	// Layer 2
	AM_RANGE( 0x774000, 0x774fff ) AM_RAM	AM_BASE( &spriteram16 )	AM_SIZE( &spriteram_size )			// Sprites

	AM_RANGE( 0x760000, 0x76ffff ) AM_READ( metro_bankedrom_r )	// Banked ROM

//  AM_RANGE( 0x772000, 0x773fff ) AM_RAM
	AM_RANGE( 0x770000, 0x773fff ) AM_READWRITE( SMH_RAM, paletteram16_GGGGGRRRRRBBBBBx_word_w   ) AM_BASE( &paletteram16 )	// Palette

	AM_RANGE( 0x775000, 0x777fff ) AM_RAM

	AM_RANGE( 0x778000, 0x7787ff ) AM_READWRITE( SMH_RAM, SMH_RAM )	AM_BASE(&metro_tiletable) AM_SIZE(&metro_tiletable_size		)	// Tiles Set
	AM_RANGE( 0x778800, 0x778813 ) AM_WRITE( SMH_RAM )		AM_BASE( &metro_videoregs )	// Video Registers
	AM_RANGE( 0x778840, 0x77884f ) AM_WRITE( metro_blitter_w )	AM_BASE( &metro_blitter_regs )	// Tiles Blitter
	AM_RANGE( 0x778860, 0x77886b ) AM_WRITE( metro_window_w )	AM_BASE( &metro_window )	// Tilemap Window
	AM_RANGE( 0x778870, 0x77887b ) AM_WRITE( SMH_RAM )		AM_BASE( &metro_scroll )	// Scroll
	AM_RANGE( 0x778890, 0x778891 ) AM_WRITE( SMH_NOP )	// ? increasing
	AM_RANGE( 0x7788a2, 0x7788a3 ) AM_WRITE( metro_irq_cause_w )	// IRQ Cause
	AM_RANGE( 0x7788a4, 0x7788a5 ) AM_WRITE( puzzlet_irq_enable_w ) AM_BASE( &metro_irq_enable )	// IRQ Enable

	AM_RANGE( 0x7788aa, 0x7788ab ) AM_WRITE( SMH_RAM )		AM_BASE( &metro_rombank	)		// Rom Bank
	AM_RANGE( 0x7788ac, 0x7788ad ) AM_WRITE( SMH_RAM )		AM_BASE( &metro_screenctrl )	// Screen Control

	AM_RANGE( 0x7f2000, 0x7f3fff ) AM_RAM

	AM_RANGE( 0x7f8880, 0x7f8881 ) AM_READ_PORT("IN1")
	AM_RANGE( 0x7f8884, 0x7f8885 ) AM_READ_PORT("DSW0")
	AM_RANGE( 0x7f8886, 0x7f8887 ) AM_READ_PORT("DSW0")

	AM_RANGE( 0x7f88a2, 0x7f88a3 ) AM_READ( metro_irq_cause_r )	// IRQ Cause
ADDRESS_MAP_END


static WRITE8_HANDLER( puzzlet_portb_w )
{
//  popmessage("PORTB %02x",data);
}

static ADDRESS_MAP_START( puzzlet_io_map, ADDRESS_SPACE_IO, 8 )
	AM_RANGE( H8_PORT_7,		H8_PORT_7	)	AM_READ_PORT("IN2")
	AM_RANGE( H8_SERIAL_1,	H8_SERIAL_1	)	AM_READ_PORT("IN0")		// coin
	AM_RANGE( H8_PORT_B,		H8_PORT_B	)	AM_READ_PORT("DSW0") AM_WRITE( puzzlet_portb_w )
ADDRESS_MAP_END


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


                                Input Ports


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


#define JOY_LSB(_n_, _b1_, _b2_, _b3_, _b4_) \
	PORT_BIT(  0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0010, IP_ACTIVE_LOW, IPT_##_b1_         ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0020, IP_ACTIVE_LOW, IPT_##_b2_         ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0040, IP_ACTIVE_LOW, IPT_##_b3_         ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_##_b4_         ) PORT_PLAYER(_n_) \


#define JOY_MSB(_n_, _b1_, _b2_, _b3_, _b4_) \
	PORT_BIT(  0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP    ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x1000, IP_ACTIVE_LOW, IPT_##_b1_         ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x2000, IP_ACTIVE_LOW, IPT_##_b2_         ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x4000, IP_ACTIVE_LOW, IPT_##_b3_         ) PORT_PLAYER(_n_) \
	PORT_BIT(  0x8000, IP_ACTIVE_LOW, IPT_##_b4_         ) PORT_PLAYER(_n_) \


#define COINS \
	PORT_BIT(  0x0001, IP_ACTIVE_LOW,  IPT_SERVICE1 ) \
	PORT_BIT(  0x0002, IP_ACTIVE_LOW,  IPT_TILT     ) \
	PORT_BIT(  0x0004, IP_ACTIVE_LOW,  IPT_COIN1 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0008, IP_ACTIVE_LOW,  IPT_COIN2 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0010, IP_ACTIVE_LOW,  IPT_START1   ) \
	PORT_BIT(  0x0020, IP_ACTIVE_LOW,  IPT_START2   ) \
	PORT_BIT(  0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN  ) \
	PORT_BIT(  0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN  )

#define COINS_SOUND \
	PORT_BIT(  0x0001, IP_ACTIVE_LOW,  IPT_SERVICE1 ) \
	PORT_BIT(  0x0002, IP_ACTIVE_LOW,  IPT_TILT     ) \
	PORT_BIT(  0x0004, IP_ACTIVE_LOW,  IPT_COIN1 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0008, IP_ACTIVE_LOW,  IPT_COIN2 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0010, IP_ACTIVE_LOW,  IPT_START1   ) \
	PORT_BIT(  0x0020, IP_ACTIVE_LOW,  IPT_START2   ) \
	PORT_BIT(  0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN  ) \
	PORT_BIT(  0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL  ) PORT_CUSTOM(custom_soundstatus_r, NULL)	/* From Sound CPU */


#define COINAGE_DSW \
	PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) ) \
	PORT_DIPSETTING(      0x0001, DEF_STR( 4C_1C ) ) \
	PORT_DIPSETTING(      0x0002, DEF_STR( 3C_1C ) ) \
	PORT_DIPSETTING(      0x0003, DEF_STR( 2C_1C ) ) \
	PORT_DIPSETTING(      0x0007, DEF_STR( 1C_1C ) ) \
	PORT_DIPSETTING(      0x0006, DEF_STR( 1C_2C ) ) \
	PORT_DIPSETTING(      0x0005, DEF_STR( 1C_3C ) ) \
	PORT_DIPSETTING(      0x0004, DEF_STR( 1C_4C ) ) \
	PORT_DIPSETTING(      0x0000, DEF_STR( Free_Play ) ) \
	PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) ) \
	PORT_DIPSETTING(      0x0008, DEF_STR( 4C_1C ) ) \
	PORT_DIPSETTING(      0x0010, DEF_STR( 3C_1C ) ) \
	PORT_DIPSETTING(      0x0018, DEF_STR( 2C_1C ) ) \
	PORT_DIPSETTING(      0x0038, DEF_STR( 1C_1C ) ) \
	PORT_DIPSETTING(      0x0030, DEF_STR( 1C_2C ) ) \
	PORT_DIPSETTING(      0x0028, DEF_STR( 1C_3C ) ) \
	PORT_DIPSETTING(      0x0020, DEF_STR( 1C_4C ) ) \
	PORT_DIPSETTING(      0x0000, DEF_STR( Free_Play ) ) \
	PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) ) \
	PORT_DIPSETTING(      0x0040, DEF_STR( Off ) ) \
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) ) \
	PORT_SERVICE( 0x0080, IP_ACTIVE_LOW )



/***************************************************************************
                                    Bal Cube
***************************************************************************/

static INPUT_PORTS_START( balcube )
	PORT_START("IN0")	// $500000
	COINS

	PORT_START("IN1")	// $500002
	JOY_LSB(1, BUTTON1, UNKNOWN, UNKNOWN, UNKNOWN)
	JOY_MSB(2, BUTTON1, UNKNOWN, UNKNOWN, UNKNOWN)

	PORT_START("DSW0")	// Strangely mapped in the 0x400000-0x41ffff range
	COINAGE_DSW
	PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(      0x0200, DEF_STR( Easy )    )
	PORT_DIPSETTING(      0x0300, DEF_STR( Normal )  )
	PORT_DIPSETTING(      0x0100, DEF_STR( Hard )    )
	PORT_DIPSETTING(      0x0000, DEF_STR( Very_Hard ) )
	PORT_DIPNAME( 0x0400, 0x0400, "2 Players Game" )
	PORT_DIPSETTING(      0x0000, "1 Credit" )
	PORT_DIPSETTING(      0x0400, "2 Credits" )
	PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Lives ) )
	PORT_DIPSETTING(      0x0800, "2" )
	PORT_DIPSETTING(      0x0000, "3" )
	PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Allow_Continue ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( No ) )
	PORT_DIPSETTING(      0x1000, DEF_STR( Yes ) )
	PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x8000, DEF_STR( On ) )

	PORT_START("IN2")	// Strangely mapped in the 0x400000-0x41ffff range
	PORT_BIT(  0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN )	// unused
INPUT_PORTS_END


/***************************************************************************
                                Bang Bang Ball
***************************************************************************/

static INPUT_PORTS_START( bangball )
	PORT_START("IN0")	// $d00000
	COINS

	PORT_START("IN1")	// $d00002
	JOY_LSB(1, BUTTON1, UNKNOWN, UNKNOWN, UNKNOWN)
	JOY_MSB(2, BUTTON1, UNKNOWN, UNKNOWN, UNKNOWN)

	PORT_START("DSW0")	// Strangely mapped in the 0xc00000-0xc1ffff range
	COINAGE_DSW
	PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(      0x0200, DEF_STR( Easy )    )
	PORT_DIPSETTING(      0x0300, DEF_STR( Normal )  )
	PORT_DIPSETTING(      0x0100, DEF_STR( Hard )    )
	PORT_DIPSETTING(      0x0000, DEF_STR( Hardest ) )
	PORT_DIPNAME( 0x0c00, 0x0c00, DEF_STR( Lives ) )
	PORT_DIPSETTING(      0x0800, "2" )
	PORT_DIPSETTING(      0x0400, "3" )
	PORT_DIPSETTING(      0x0c00, "4" )
	PORT_DIPSETTING(      0x0000, "5" )
	PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Allow_Continue ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( No ) )
	PORT_DIPSETTING(      0x1000, DEF_STR( Yes ) )
	PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x2000, DEF_STR( On ) )
	PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Language ) )
	PORT_DIPSETTING(      0x8000, DEF_STR( Japanese ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( English ) )

	PORT_START("IN2")	// Strangely mapped in the 0xc00000-0xc1ffff range
	PORT_BIT(  0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN )	// used for debug
INPUT_PORTS_END

/***************************************************************************
                                Battle Bubble
***************************************************************************/

static INPUT_PORTS_START( batlbubl )
	PORT_START("IN1")
	JOY_LSB(1, BUTTON1, UNKNOWN, UNKNOWN, UNKNOWN)
	JOY_MSB(2, BUTTON1, UNKNOWN, UNKNOWN, UNKNOWN)

	PORT_START("DSW0")	// Strangely mapped in the 0xc00000-0xc1ffff range
	PORT_DIPNAME( 0x0003, 0x0003, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(      0x0002, DEF_STR( Easy )    )
	PORT_DIPSETTING(      0x0003, DEF_STR( Normal )  )
	PORT_DIPSETTING(      0x0001, DEF_STR( Hard )    )
	PORT_DIPSETTING(      0x0000, DEF_STR( Hardest ) )
	PORT_DIPNAME( 0x000c, 0x000c, DEF_STR( Lives ) )
	PORT_DIPSETTING(      0x0008, "2" )
	PORT_DIPSETTING(      0x0004, "3" )
	PORT_DIPSETTING(      0x000c, "4" )
	PORT_DIPSETTING(      0x0000, "5" )
	PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Allow_Continue ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( No ) )
	PORT_DIPSETTING(      0x0010, DEF_STR( Yes ) )
	PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0020, DEF_STR( On ) )
	PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0700, 0x0700, DEF_STR( Coin_A ) )
	PORT_DIPSETTING(      0x0100, DEF_STR( 4C_1C ) )
	PORT_DIPSETTING(      0x0200, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(      0x0300, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(      0x0700, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(      0x0600, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(      0x0500, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(      0x0400, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Free_Play ) )
	PORT_DIPNAME( 0x3800, 0x3800, DEF_STR( Coin_B ) )
	PORT_DIPSETTING(      0x0800, DEF_STR( 4C_1C ) )
	PORT_DIPSETTING(      0x1000, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(      0x1800, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(      0x3800, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(      0x3000, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(      0x2800, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(      0x2000, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Free_Play ) )
	PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Flip_Screen ) )
	PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_SERVICE( 0x8000, IP_ACTIVE_LOW )

	PORT_START("IN0")	// $d00000
	COINS

	PORT_START("IN2")	// Strangely mapped in the 0xc00000-0xc1ffff range
    PORT_DIPNAME( 0x0001, 0x0001, "0" )
    PORT_DIPSETTING(      0x0001, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0002, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0004, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0008, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0010, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0020, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0080, 0x0080, "Debug Mode?" )
	PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0100, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0200, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0400, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x0800, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
    PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
    PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
INPUT_PORTS_END

/***************************************************************************
                            Blazing Tornado
***************************************************************************/

static INPUT_PORTS_START( blzntrnd )
	PORT_START("DSW0")
	PORT_DIPNAME( 0x0007, 0x0004, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(      0x0007, "Beginner" )
	PORT_DIPSETTING(      0x0006, DEF_STR( Easiest ) )
	PORT_DIPSETTING(      0x0005, DEF_STR( Easy ) )
	PORT_DIPSETTING(      0x0004, DEF_STR( Normal ) )
	PORT_DIPSETTING(      0x0003, DEF_STR( Hard ) )
	PORT_DIPSETTING(      0x0002, DEF_STR( Hardest ) )
	PORT_DIPSETTING(      0x0001, "Expert" )
	PORT_DIPSETTING(      0x0000, "Master" )
	PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Flip_Screen ) )
	PORT_DIPSETTING(      0x0008, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0010, 0x0000, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(      0x0010, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0020, 0x0000, DEF_STR( Allow_Continue ) )
	PORT_DIPSETTING(      0x0020, DEF_STR( No ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Yes ) )
	PORT_DIPNAME( 0x00c0, 0x0000, "Control Panel" )
	PORT_DIPSETTING(      0x0000, "4 Players" )
//  PORT_DIPSETTING(      0x0040, "4 Players" )
	PORT_DIPSETTING(      0x0080, "1P & 2P Tag only" )
	PORT_DIPSETTING(      0x00c0, "1P & 2P vs only" )
	PORT_DIPNAME( 0x0300, 0x0300, "Half Continue" )
	PORT_DIPSETTING(      0x0000, "6C to start, 3C to continue" )
	PORT_DIPSETTING(      0x0100, "4C to start, 2C to continue" )
	PORT_DIPSETTING(      0x0200, "2C to start, 1C to continue" )
	PORT_DIPSETTING(      0x0300, "Disabled" )
	PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x0400, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x0800, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unused ) )
	PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )

	PORT_START("DSW1")
	PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
	PORT_DIPSETTING(      0x0004, DEF_STR( 4C_1C ) )
	PORT_DIPSETTING(      0x0005, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(      0x0006, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(      0x0007, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(      0x0003, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(      0x0002, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(      0x0001, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( 1C_5C ) )
	PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) )
	PORT_DIPSETTING(      0x0020, DEF_STR( 4C_1C ) )
	PORT_DIPSETTING(      0x0028, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(      0x0030, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(      0x0038, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(      0x0018, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(      0x0010, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(      0x0008, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( 1C_5C ) )
	PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Free_Play ) )
	PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_SERVICE_NO_TOGGLE(0x0080, IP_ACTIVE_LOW)
	PORT_DIPNAME( 0x0300, 0x0300, "CP Single" )
	PORT_DIPSETTING(      0x0300, "2:00" )
	PORT_DIPSETTING(      0x0200, "2:30" )
	PORT_DIPSETTING(      0x0100, "3:00" )
	PORT_DIPSETTING(      0x0000, "3:30" )
	PORT_DIPNAME( 0x0c00, 0x0c00, "CP Tag" )
	PORT_DIPSETTING(      0x0c00, "2:00" )
	PORT_DIPSETTING(      0x0800, "2:30" )
	PORT_DIPSETTING(      0x0400, "3:00" )
	PORT_DIPSETTING(      0x0000, "3:30" )
	PORT_DIPNAME( 0x3000, 0x3000, "Vs Single" )
	PORT_DIPSETTING(      0x3000, "2:30" )
	PORT_DIPSETTING(      0x2000, "3:00" )
	PORT_DIPSETTING(      0x1000, "4:00" )
	PORT_DIPSETTING(      0x0000, "5:00" )
	PORT_DIPNAME( 0xc000, 0xc000, "Vs Tag" )
	PORT_DIPSETTING(      0xc000, "2:30" )
	PORT_DIPSETTING(      0x8000, "3:00" )
	PORT_DIPSETTING(      0x4000, "4:00" )
	PORT_DIPSETTING(      0x0000, "5:00" )

	PORT_START("IN0")
	JOY_LSB(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4)
	JOY_MSB(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4)

	PORT_START("IN1")
	JOY_LSB(3, BUTTON1, BUTTON2, BUTTON3, BUTTON4)
	JOY_MSB(4, BUTTON1, BUTTON2, BUTTON3, BUTTON4)

	PORT_START("IN2")
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 )
	PORT_SERVICE_NO_TOGGLE(0x0002, IP_ACTIVE_LOW)
	PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
	PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2)
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_START1 )
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START2 )
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START3 )
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START4 )
INPUT_PORTS_END


/***************************************************************************
                            Grand Striker 2
***************************************************************************/

static INPUT_PORTS_START( gstrik2 )
	PORT_START("DSW0")
	PORT_DIPNAME( 0x0003, 0x0003, "Player Vs Com" )
	PORT_DIPSETTING(      0x0003, "1:00" )
	PORT_DIPSETTING(      0x0002, "1:30" )
	PORT_DIPSETTING(      0x0001, "2:00" )
	PORT_DIPSETTING(      0x0000, "2:30" )
	PORT_DIPNAME( 0x000c, 0x000c, "1P Vs 2P" )
	PORT_DIPSETTING(      0x000c, "0:45" )
	PORT_DIPSETTING(      0x0008, "1:00" )
	PORT_DIPSETTING(      0x0004, "1:30" )
	PORT_DIPSETTING(      0x0000, "2:00" )
	PORT_DIPNAME( 0x0030, 0x0030, "Extra Time" )
	PORT_DIPSETTING(      0x0030, "0:30" )
	PORT_DIPSETTING(      0x0020, "0:45" )
	PORT_DIPSETTING(      0x0010, "1:00" )
	PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
	PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x0080, 0x0080, "Extra Time" )
	PORT_DIPSETTING(      0x0080, "Sudden Death" )
	PORT_DIPSETTING(      0x0000, "Full" )
	PORT_DIPNAME( 0x0700, 0x0400, DEF_STR( Difficulty ) )
	PORT_DIPSETTING(      0x0700, DEF_STR( Very_Easy) )
	PORT_DIPSETTING(      0x0600, DEF_STR( Easier ) )
	PORT_DIPSETTING(      0x0500, DEF_STR( Easy ) )
	PORT_DIPSETTING(      0x0400, DEF_STR( Normal ) )
	PORT_DIPSETTING(      0x0300, DEF_STR( Medium ) )
	PORT_DIPSETTING(      0x0200, DEF_STR( Hard ) )
	PORT_DIPSETTING(      0x0100, DEF_STR( Hardest ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Very_Hard ) )
	PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Demo_Sounds ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0800, DEF_STR( On ) )
	PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Flip_Screen ) )
	PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )

	PORT_START("DSW1")
	PORT_DIPNAME( 0x001f, 0x001f, DEF_STR( Coin_A ) )
	PORT_DIPSETTING(      0x001c, DEF_STR( 4C_1C ) )
	PORT_DIPSETTING(      0x001d, DEF_STR( 3C_1C ) )
	PORT_DIPSETTING(      0x0018, DEF_STR( 4C_2C ) )
	PORT_DIPSETTING(      0x001e, DEF_STR( 2C_1C ) )
	PORT_DIPSETTING(      0x0019, DEF_STR( 3C_2C ) )
	PORT_DIPSETTING(      0x0014, DEF_STR( 4C_3C ) )
	PORT_DIPSETTING(      0x0010, DEF_STR( 4C_4C ) )
	PORT_DIPSETTING(      0x0015, DEF_STR( 3C_3C ) )
	PORT_DIPSETTING(      0x001a, DEF_STR( 2C_2C ) )
	PORT_DIPSETTING(      0x001f, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(      0x000c, DEF_STR( 4C_5C ) )
	PORT_DIPSETTING(      0x0011, DEF_STR( 3C_4C ) )
	PORT_DIPSETTING(      0x0008, "4 Coins/6 Credits" )
	PORT_DIPSETTING(      0x0016, DEF_STR( 2C_3C ) )
	PORT_DIPSETTING(      0x000d, "3 Coins/5 Credits" )
	PORT_DIPSETTING(      0x0004, DEF_STR( 4C_7C ) )
	PORT_DIPSETTING(      0x0000, "4 Coins/8 Credits" )
	PORT_DIPSETTING(      0x0009, "3 Coins/6 Credits" )
	PORT_DIPSETTING(      0x0012, DEF_STR( 2C_4C ) )
	PORT_DIPSETTING(      0x001b, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(      0x0005, "3 Coins/7 Credits" )
	PORT_DIPSETTING(      0x000e, DEF_STR( 2C_5C ) )
	PORT_DIPSETTING(      0x0001, "3 Coins/8 Credits" )
	PORT_DIPSETTING(      0x000a, DEF_STR( 2C_6C ) )
	PORT_DIPSETTING(      0x0017, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(      0x0006, DEF_STR( 2C_7C ) )
	PORT_DIPSETTING(      0x0002, DEF_STR( 2C_8C ) )
	PORT_DIPSETTING(      0x0013, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(      0x000f, DEF_STR( 1C_5C ) )
	PORT_DIPSETTING(      0x000b, DEF_STR( 1C_6C ) )
	PORT_DIPSETTING(      0x0007, DEF_STR( 1C_7C ) )
	PORT_DIPSETTING(      0x0003, DEF_STR( 1C_8C ) )
	PORT_DIPNAME( 0x00e0, 0x0000, DEF_STR( Coin_B ) )
	PORT_DIPSETTING(      0x00c0, DEF_STR( 1C_1C ) )
	PORT_DIPSETTING(      0x00a0, DEF_STR( 1C_2C ) )
	PORT_DIPSETTING(      0x0080, DEF_STR( 1C_3C ) )
	PORT_DIPSETTING(      0x0060, DEF_STR( 1C_4C ) )
	PORT_DIPSETTING(      0x0040, DEF_STR( 1C_5C ) )
	PORT_DIPSETTING(      0x0020, DEF_STR( 1C_6C ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( 1C_7C ) )
	PORT_DIPSETTING(      0x00e0, "Same as Coin A" )
	PORT_DIPNAME( 0x0300, 0x0300, "Credits to Start" )
	PORT_DIPSETTING(      0x0300, "1" )
	PORT_DIPSETTING(      0x0200, "2" )
	PORT_DIPSETTING(      0x0100, "3" )
	PORT_DIPSETTING(      0x0000, "4" )
	PORT_DIPNAME( 0x0c00, 0x0c00, "Credits to Continue" )
	PORT_DIPSETTING(      0x0c00, "1" )
	PORT_DIPSETTING(      0x0800, "2" )
	PORT_DIPSETTING(      0x0400, "3" )
	PORT_DIPSETTING(      0x0000, "4" )
	PORT_DIPNAME( 0x1000, 0x1000, "Continue" )
	PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x1000, DEF_STR( On ) )
	PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
	PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
	PORT_DIPNAME( 0x4000, 0x4000, "Playmode" )
	PORT_DIPSETTING(      0x4000, "1 Credit for 1 Player" )
	PORT_DIPSETTING(      0x0000, "1 Credit for 2 Players" )
	PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Free_Play ) )
	PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
	PORT_DIPSETTING(      0x0000, DEF_STR( On ) )

	PORT_START("IN0")
	JOY_LSB(1, BUTTON1, BUTTON2, BUTTON3, UNUSED)
	JOY_MSB(2, BUTTON1, BUTTON2, BUTTON3, UNUSED)

	PORT_START("IN1")
	/* Not Used */

	PORT_START("IN2")
	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 )
	PORT_SERVICE_NO_TOGGLE(0x0002, IP_ACTIVE_LOW )
	PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
	PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2)
	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_START1 )
	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START2 )
	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END

/***************************************************************************
                                Dai Toride
***************************************************************************/

/* If only ONE of the "Coinage" is set to "Free Play", it is in fact "5C_1C".

   IN2 bits 12 and 13 are in fact "merged" :

     12  13