📄 mpatrol.c
字号:
/***************************************************************************
Moon Patrol memory map (preliminary)
0000-3fff ROM
8000-83ff Video RAM
8400-87ff Color RAM
e000-e7ff RAM
read:
8800 protection
d000 IN0
d001 IN1
d002 IN2
d003 DSW1
d004 DSW2
write:
c820-c87f sprites
c8a0-c8ff sprites
d000 sound command
d001 flip screen
I/O ports
write:
10-1f scroll registers
40 background #1 x position
60 background #1 y position
80 background #2 x position
a0 background #2 y position
c0 background control?
There's an interesting problem with this game: it is designed to run on an
horizontal monitor, but the display in MAME is narrow and tall. The reason
is that the real board doesn't produce square pixels, but rectangular ones
whose width is almost twice their height.
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "Z80/Z80.h"
void mpatrol_scroll_w(int offset,int data);
void mpatrol_bg1xpos_w(int offset,int data);
void mpatrol_bg1ypos_w(int offset,int data);
void mpatrol_bg2xpos_w(int offset,int data);
void mpatrol_bg2ypos_w(int offset,int data);
void mpatrol_bgcontrol_w(int offset,int data);
void mpatrol_flipscreen_w(int offset,int data);
int mpatrol_vh_start(void);
void mpatrol_vh_stop(void);
void mpatrol_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void mpatrol_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
extern struct AY8910interface irem_ay8910_interface;
extern struct MSM5205interface irem_msm5205_interface;
void irem_io_w(int offset, int value);
int irem_io_r(int offset);
void irem_sound_cmd_w(int offset, int value);
int mpatrol_input_port_3_r(int offset);
/* this looks like some kind of protection. The game does strange things */
/* if a read from this address doesn't return the value it expects. */
int mpatrol_protection_r(int offset)
{
Z80_Regs regs;
Z80_GetRegs(®s);
#ifndef USE_DRZ80 /* FRANXIS 01-09-2005 */
return regs.DE.B.l;
#else
return (regs.regs.Z80DE>>16)&0x0F;
#endif
}
static struct MemoryReadAddress readmem[] =
{
{ 0x0000, 0x3fff, MRA_ROM },
{ 0x8000, 0x87ff, MRA_RAM },
{ 0x8800, 0x8800, mpatrol_protection_r },
{ 0xd000, 0xd000, input_port_0_r }, /* IN0 */
{ 0xd001, 0xd001, input_port_1_r }, /* IN1 */
{ 0xd002, 0xd002, input_port_2_r }, /* IN2 */
{ 0xd003, 0xd003, mpatrol_input_port_3_r }, /* DSW1 */
{ 0xd004, 0xd004, input_port_4_r }, /* DSW2 */
{ 0xe000, 0xe7ff, MRA_RAM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x8000, 0x83ff, videoram_w, &videoram, &videoram_size },
{ 0x8400, 0x87ff, colorram_w, &colorram },
{ 0xc820, 0xc87f, MWA_RAM, &spriteram, &spriteram_size },
{ 0xc8a0, 0xc8ff, MWA_RAM, &spriteram_2 },
{ 0xd000, 0xd000, irem_sound_cmd_w },
{ 0xd001, 0xd001, mpatrol_flipscreen_w },
{ 0xe000, 0xe7ff, MWA_RAM },
{ -1 } /* end of table */
};
static struct IOWritePort writeport[] =
{
{ 0x10, 0x1f, mpatrol_scroll_w },
{ 0x40, 0x40, mpatrol_bg1xpos_w },
{ 0x60, 0x60, mpatrol_bg1ypos_w },
{ 0x80, 0x80, mpatrol_bg2xpos_w },
{ 0xa0, 0xa0, mpatrol_bg2ypos_w },
{ 0xc0, 0xc0, mpatrol_bgcontrol_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0x001f, irem_io_r },
{ 0x0080, 0x00ff, MRA_RAM },
{ 0xf000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0x001f, irem_io_w },
{ 0x0080, 0x00ff, MWA_RAM },
{ 0x0801, 0x0802, MSM5205_data_w },
{ 0x9000, 0x9000, MWA_NOP }, /* IACK */
{ -1 } /* end of table */
};
INPUT_PORTS_START( mpatrol_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
/* coin input must be active for ? frames to be consistently recognized */
PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_COIN3 | IPF_IMPULSE, "Coin Aux", IP_KEY_DEFAULT, IP_JOY_DEFAULT, 17)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_START /* IN2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY | IPF_COCKTAIL )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY | IPF_COCKTAIL )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_COCKTAIL )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL )
PORT_START /* DSW0 */
PORT_DIPNAME( 0x03, 0x02, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPSETTING( 0x01, "2" )
PORT_DIPSETTING( 0x02, "3" )
PORT_DIPSETTING( 0x03, "5" )
PORT_DIPNAME( 0x0c, 0x0c, "Bonus Life", IP_KEY_NONE )
PORT_DIPSETTING( 0x0c, "10000 30000 50000" )
PORT_DIPSETTING( 0x08, "20000 40000 60000" )
PORT_DIPSETTING( 0x04, "10000" )
PORT_DIPSETTING( 0x00, "None" )
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) /* Gets filled in based on the coin mode */
PORT_START /* DSW1 */
PORT_DIPNAME( 0x01, 0x01, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x01, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x02, 0x00, "Cabinet", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Upright" )
PORT_DIPSETTING( 0x02, "Cocktail" )
PORT_DIPNAME( 0x04, 0x04, "Coin Mode", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "Mode 1" )
PORT_DIPSETTING( 0x00, "Mode 2" )
PORT_DIPNAME( 0x08, 0x08, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x08, "Off" )
PORT_DIPSETTING( 0x00, "On" )
/* In stop mode, press 2 to stop and 1 to restart */
PORT_BITX ( 0x10, 0x10, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Stop Mode", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x10, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x20, 0x20, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Sector Selection", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x20, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x40, 0x40, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Invulnerability", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x40, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x80, 0x80, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x80, "Off" )
PORT_DIPSETTING( 0x00, "On" )
/* Fake port to support the two different coin modes */
PORT_START
PORT_DIPNAME( 0x0f, 0x0f, "Coinage Mode 1", IP_KEY_NONE ) /* mapped on coin mode 1 */
PORT_DIPSETTING( 0x09, "7 Coins/1 Credit" )
PORT_DIPSETTING( 0x0a, "6 Coins/1 Credit" )
PORT_DIPSETTING( 0x0b, "5 Coins/1 Credit" )
PORT_DIPSETTING( 0x0c, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x0d, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x0e, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x0f, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x07, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x06, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x05, "1 Coin/4 Credits" )
PORT_DIPSETTING( 0x04, "1 Coin/5 Credits" )
PORT_DIPSETTING( 0x03, "1 Coin/6 Credits" )
PORT_DIPSETTING( 0x02, "1 Coin/7 Credits" )
PORT_DIPSETTING( 0x01, "1 Coin/8 Credits" )
PORT_DIPSETTING( 0x00, "Free Play" )
PORT_DIPNAME( 0x30, 0x30, "Coin A Mode 2", IP_KEY_NONE ) /* mapped on coin mode 2 */
PORT_DIPSETTING( 0x10, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x20, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x30, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x00, "Free Play" )
PORT_DIPNAME( 0xc0, 0xc0, "Coin B Mode 2", IP_KEY_NONE )
PORT_DIPSETTING( 0xc0, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x80, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x40, "1 Coin/5 Credits" )
PORT_DIPSETTING( 0x00, "1 Coin/6 Credits" )
INPUT_PORTS_END
/* Identical to mpatrol, the only difference is the number of lives */
INPUT_PORTS_START( mpatrolw_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
/* coin input must be active for ? frames to be consistently recognized */
PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_COIN3 | IPF_IMPULSE, "Coin Aux", IP_KEY_DEFAULT, IP_JOY_DEFAULT, 17)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_START /* IN2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY | IPF_COCKTAIL )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY | IPF_COCKTAIL )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_COCKTAIL )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL )
PORT_START /* DSW0 */
PORT_DIPNAME( 0x03, 0x01, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x01, "3" )
PORT_DIPSETTING( 0x02, "4" )
PORT_DIPSETTING( 0x03, "5" )
PORT_DIPNAME( 0x0c, 0x0c, "Bonus Life", IP_KEY_NONE )
PORT_DIPSETTING( 0x0c, "10000 30000 50000" )
PORT_DIPSETTING( 0x08, "20000 40000 60000" )
PORT_DIPSETTING( 0x04, "10000" )
PORT_DIPSETTING( 0x00, "None" )
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) /* Gets filled in based on the coin mode */
PORT_START /* DSW1 */
PORT_DIPNAME( 0x01, 0x01, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x01, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x02, 0x00, "Cabinet", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Upright" )
PORT_DIPSETTING( 0x02, "Cocktail" )
PORT_DIPNAME( 0x04, 0x04, "Coin Mode", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "Mode 1" )
PORT_DIPSETTING( 0x00, "Mode 2" )
PORT_DIPNAME( 0x08, 0x08, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x08, "Off" )
PORT_DIPSETTING( 0x00, "On" )
/* In stop mode, press 2 to stop and 1 to restart */
PORT_BITX ( 0x10, 0x10, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Stop Mode", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x10, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x20, 0x20, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Sector Selection", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x20, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x40, 0x40, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Invulnerability", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x40, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX( 0x80, 0x80, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x80, "Off" )
PORT_DIPSETTING( 0x00, "On" )
/* Fake port to support the two different coin modes */
PORT_START
PORT_DIPNAME( 0x0f, 0x0f, "Coinage Mode 1", IP_KEY_NONE ) /* mapped on coin mode 1 */
PORT_DIPSETTING( 0x09, "7 Coins/1 Credit" )
PORT_DIPSETTING( 0x0a, "6 Coins/1 Credit" )
PORT_DIPSETTING( 0x0b, "5 Coins/1 Credit" )
PORT_DIPSETTING( 0x0c, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x0d, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x0e, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x0f, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x07, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x06, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x05, "1 Coin/4 Credits" )
PORT_DIPSETTING( 0x04, "1 Coin/5 Credits" )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -