📄 vicdual.c
字号:
/***************************************************************************
VIC Dual Game board memory map (preliminary)
0000-3fff ROM
4000-7fff ROM mirror image (used in most games)
8000-87ff looks like extra work RAM in Safari
e000-e3ff Video RAM + work RAM
e400-e7ff RAM
e800-efff Character generator RAM
I/O ports:
The memory map is the same for many games, but the I/O ports change. The
following ones are for Carnival, and apply to many other games as well.
read:
00 IN0
bit 0 = connector
bit 1 = connector
bit 2 = dsw
bit 3 = dsw
bit 4 = connector
bit 5 = connector
bit 6 = seems unused
bit 7 = seems unused
01 IN1
bit 0 = connector
bit 1 = connector
bit 2 = dsw
bit 3 = vblank
bit 4 = connector
bit 5 = connector
bit 6 = seems unused
bit 7 = seems unused
02 IN2
bit 0 = connector
bit 1 = connector
bit 2 = dsw
bit 3 = timer? is this used?
bit 4 = connector
bit 5 = connector
bit 6 = seems unused
bit 7 = seems unused
03 IN3
bit 0 = connector
bit 1 = connector
bit 2 = dsw
bit 3 = COIN (must reset the CPU to make the game acknowledge it)
bit 4 = connector
bit 5 = connector
bit 6 = seems unused
bit 7 = seems unused
write:
(ports 1 and 2: see definitions in sound driver)
08 ?
40 palette bank
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "I8039/I8039.h"
#define PSG_CLOCK_CARNIVAL ( 3579545 / 3 ) /* Hz */
extern unsigned char *vicdual_characterram;
void vicdual_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void vicdual_characterram_w(int offset,int data);
void vicdual_palette_bank_w(int offset, int data);
void vicdual_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void carnival_sh_port1_w(int offset, int data);
void carnival_sh_port2_w(int offset, int data);
int carnival_music_port_t1_r( int offset );
void carnival_music_port_1_w( int offset, int data );
void carnival_music_port_2_w( int offset, int data );
static int protection_data;
void samurai_protection_w(int offset,int data)
{
protection_data = data;
}
int samurai_input_r(int offset)
{
int answer = 0;
if (protection_data == 0xab) answer = 0x02;
else if (protection_data == 0x1d) answer = 0x0c;
return (readinputport(1 + offset) & 0xfd) | ((answer >> offset) & 0x02);
}
static struct MemoryReadAddress vicdual_readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0xe000, 0xefff, MRA_RAM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress vicdual_writemem[] =
{
{ 0x7f00, 0x7f00, samurai_protection_w }, /* Samurai only */
{ 0x0000, 0x7fff, MWA_ROM },
{ 0xe000, 0xe3ff, videoram_w, &videoram, &videoram_size },
{ 0xe400, 0xe7ff, MWA_RAM },
{ 0xe800, 0xefff, vicdual_characterram_w, &vicdual_characterram },
{ -1 } /* end of table */
};
static struct MemoryReadAddress samurai_readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0xe000, 0xefff, MRA_RAM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress samurai_writemem[] =
{
{ 0x7f00, 0x7f00, samurai_protection_w },
{ 0x0000, 0x7fff, MWA_ROM },
{ 0xe000, 0xe3ff, videoram_w, &videoram, &videoram_size },
{ 0xe400, 0xe7ff, MWA_RAM },
{ 0xe800, 0xefff, vicdual_characterram_w, &vicdual_characterram },
{ -1 } /* end of table */
};
static struct MemoryReadAddress heiankyo_readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0x8000, 0x8fff, MRA_RAM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress heiankyo_writemem[] =
{
{ 0x0000, 0x7fff, MWA_ROM },
{ 0x8000, 0x83ff, videoram_w, &videoram, &videoram_size },
{ 0x8400, 0x87ff, MWA_RAM },
{ 0x8800, 0x8fff, vicdual_characterram_w, &vicdual_characterram },
{ -1 } /* end of table */
};
static struct IOReadPort readport_2Aports[] =
{
{ 0x01, 0x01, input_port_0_r },
{ 0x08, 0x08, input_port_1_r },
{ -1 } /* end of table */
};
static struct IOReadPort readport_2Bports[] =
{
{ 0x03, 0x03, input_port_0_r },
{ 0x08, 0x08, input_port_1_r },
{ -1 } /* end of table */
};
static struct IOReadPort readport_3ports[] =
{
{ 0x01, 0x01, input_port_0_r },
{ 0x04, 0x04, input_port_1_r },
{ 0x08, 0x08, input_port_2_r },
{ -1 } /* end of table */
};
static struct IOReadPort readport_4ports[] =
{
{ 0x00, 0x00, input_port_0_r },
{ 0x01, 0x01, input_port_1_r },
{ 0x02, 0x02, input_port_2_r },
{ 0x03, 0x03, input_port_3_r },
{ -1 } /* end of table */
};
static struct IOReadPort readport_samuraiports[] =
{
{ 0x00, 0x00, input_port_0_r },
{ 0x01, 0x03, samurai_input_r }, /* bit 1 of these ports returns a protection code */
{ -1 } /* end of table */
};
static struct IOWritePort writeport[] =
{
{ 0x01, 0x01, carnival_sh_port1_w },
{ 0x02, 0x02, carnival_sh_port2_w },
{ 0x40, 0x40, vicdual_palette_bank_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress i8039_readmem[] =
{
{ 0x0000, 0x07ff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress i8039_writemem[] =
{
{ 0x0000, 0x07ff, MWA_ROM },
{ -1 } /* end of table */
};
static struct IOReadPort i8039_readport[] =
{
{ I8039_t1, I8039_t1, carnival_music_port_t1_r },
{ -1 }
};
static struct IOWritePort i8039_writeport[] =
{
{ I8039_p1, I8039_p1, carnival_music_port_1_w },
{ I8039_p2, I8039_p2, carnival_music_port_2_w },
{ -1 } /* end of table */
};
INPUT_PORTS_START( depthch_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY )
PORT_DIPNAME (0x30, 0x30, "Coinage", IP_KEY_NONE )
PORT_DIPSETTING ( 0x00, "4 Coins/1 Credit" )
PORT_DIPSETTING ( 0x10, "3 Coins/1 Credit" )
PORT_DIPSETTING ( 0x20, "2 Coins/1 Credit" )
PORT_DIPSETTING ( 0x30, "1 Coin/1 Credit" )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_BIT( 0x7e, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE | IPF_RESETCPU, IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 30 )
INPUT_PORTS_END
INPUT_PORTS_START( safari_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY )
PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_BUTTON2, "Aim Up", OSD_KEY_A, 0, 0)
PORT_BITX(0x20, IP_ACTIVE_LOW, IPT_BUTTON3, "Aim Down", OSD_KEY_Z, 0, 0)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_DIPNAME (0x30, 0x30, "Coinage", IP_KEY_NONE )
PORT_DIPSETTING ( 0x00, "4 Coins/1 Credit" )
PORT_DIPSETTING ( 0x10, "3 Coins/1 Credit" )
PORT_DIPSETTING ( 0x20, "2 Coins/1 Credit" )
PORT_DIPSETTING ( 0x30, "1 Coin/1 Credit" )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE | IPF_RESETCPU, IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 30 )
INPUT_PORTS_END
INPUT_PORTS_START( frogs_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY )
PORT_DIPNAME( 0x08, 0x00, "Unknown", IP_KEY_NONE ) /* maybe Demo Sounds */
PORT_DIPSETTING( 0x08, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x10, 0x10, "Allow Free Game", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "No" )
PORT_DIPSETTING( 0x10, "Yes" )
PORT_DIPNAME( 0x20, 0x20, "Time", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "60" )
PORT_DIPSETTING( 0x20, "90" )
PORT_DIPNAME( 0x40, 0x40, "Coinage", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x40, "1 Coin/1 Credit" )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_BIT( 0x7e, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE | IPF_RESETCPU, IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 30 )
INPUT_PORTS_END
INPUT_PORTS_START( sspaceat_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_2WAY | IPF_COCKTAIL )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY | IPF_COCKTAIL )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_2WAY )
PORT_START /* IN1 */
PORT_DIPNAME( 0x01, 0x00, "Unknown", IP_KEY_NONE ) /* unknown, but used */
PORT_DIPSETTING( 0x01, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x0e, 0x0e, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x0e, "3" )
PORT_DIPSETTING( 0x0c, "4" )
PORT_DIPSETTING( 0x0a, "5" )
PORT_DIPSETTING( 0x06, "6" )
/* the following are duplicates
PORT_DIPSETTING( 0x00, "4" )
PORT_DIPSETTING( 0x04, "4" )
PORT_DIPSETTING( 0x08, "4" )
PORT_DIPSETTING( 0x02, "5" ) */
PORT_DIPNAME( 0x10, 0x00, "Unknown", IP_KEY_NONE ) /* unknown, but used */
PORT_DIPSETTING( 0x10, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_DIPNAME( 0x80, 0x00, "Show Credits", IP_KEY_NONE )
PORT_DIPSETTING( 0x80, "No" )
PORT_DIPSETTING( 0x00, "Yes" )
PORT_START /* IN2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_BIT( 0x7e, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE | IPF_RESETCPU, IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 30 )
INPUT_PORTS_END
INPUT_PORTS_START( headon_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* unknown, but used (sound related?) */
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_BIT( 0x7e, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE | IPF_RESETCPU, IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 30 )
INPUT_PORTS_END
INPUT_PORTS_START ( invho2_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_DIPNAME( 0x04, 0x04, "Head On Lives (1/2)", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "+0" )
PORT_DIPSETTING( 0x00, "+1" )
PORT_DIPNAME( 0x08, 0x00, "Unused", IP_KEY_NONE )
PORT_DIPSETTING( 0x08, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_DIPNAME( 0x04, 0x00, "Head On Lives (2/2)", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "+0" )
PORT_DIPSETTING( 0x00, "+1" )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START /* IN2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_DIPNAME( 0x04, 0x00, "Invinco Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "5" )
PORT_DIPSETTING( 0x04, "6" )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* timer - unused */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) /* probably unused */
PORT_START /* IN3 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
/* There's probably a bug in the code: this would likely be the second */
/* bit of the Invinco Lives setting, but the game reads bit 3 instead */
/* of bit 2. */
PORT_DIPNAME( 0x04, 0x00, "Unused", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BITX(0x08, IP_ACTIVE_LOW, IPT_COIN1 | IPF_IMPULSE | IPF_RESETCPU, IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 30 )
PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_TOGGLE, "Game Select", IP_KEY_DEFAULT, IP_JOY_DEFAULT, 0 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
INPUT_PORTS_START ( samurai_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_DIPNAME( 0x04, 0x04, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "3" )
PORT_DIPSETTING( 0x00, "4" )
PORT_BITX( 0x08, 0x08, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Infinite Lives", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x08, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* protection, see samurai_input_r() */
PORT_DIPNAME( 0x04, 0x00, "Unknown", IP_KEY_NONE ) /* unknown, but used */
PORT_DIPSETTING( 0x04, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_VBLANK ) /* seems to be on port 2 instead */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START /* IN2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* protection, see samurai_input_r() */
PORT_DIPNAME( 0x04, 0x00, "Unused", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_VBLANK ) /* either vblank, or a timer. In the */
/* Carnival schematics, it's a timer. */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -