📄 gaiden.c
字号:
/***************************************************************************
Ninja Gaiden memory map (preliminary)
000000-03ffff ROM
060000-063fff RAM
070000-070fff Video RAM (text layer)
072000-075fff VRAM (backgrounds)
076000-077fff Sprite RAM
078000-079fff Palette RAM
07a100-07a1ff Unknown
memory mapped ports:
read:
07a001 IN0
07a002 IN2
07a003 IN1
07a004 DWSB
07a005 DSWA
see the input_ports definition below for details on the input bits
write:
07a104-07a105 text layer Y scroll
07a10c-07a10d text layer X scroll
07a204-07a205 front layer Y scroll
07a20c-07a20d front layer X scroll
07a304-07a305 back layer Y scroll
07a30c-07a30d back layer Xscroll
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "M68000/M68000.h"
#include "Z80/Z80.h"
extern unsigned char *gaiden_videoram;
extern unsigned char *gaiden_spriteram;
extern unsigned char *gaiden_videoram2;
extern unsigned char *gaiden_videoram3;
extern unsigned char *gaiden_txscrollx,*gaiden_txscrolly;
extern unsigned char *gaiden_fgscrollx,*gaiden_fgscrolly;
extern unsigned char *gaiden_bgscrollx,*gaiden_bgscrolly;
extern int gaiden_videoram_size;
extern int gaiden_videoram2_size;
extern int gaiden_videoram3_size;
extern int gaiden_spriteram_size;
void gaiden_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void gaiden_unknownram_w(int offset,int data);
int gaiden_unknownram_r(int offset);
void gaiden_videoram_w(int offset,int data);
int gaiden_videoram_r(int offset);
void gaiden_videoram2_w(int offset,int data);
int gaiden_videoram2_r(int offset);
void gaiden_videoram3_w(int offset,int data);
int gaiden_videoram3_r(int offset);
void gaiden_spriteram_w(int offset,int data);
int gaiden_spriteram_r(int offset);
void gaiden_txscrollx_w(int offset,int data);
void gaiden_txscrolly_w(int offset,int data);
void gaiden_fgscrollx_w(int offset,int data);
void gaiden_fgscrolly_w(int offset,int data);
void gaiden_bgscrollx_w(int offset,int data);
void gaiden_bgscrolly_w(int offset,int data);
void gaiden_background_w(int offset,int data);
void gaiden_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
int gaiden_vh_start(void);
void gaiden_vh_stop(void);
int gaiden_interrupt(void)
{
return 5; /*Interrupt vector 5*/
}
int gaiden_input_r(int offset)
{
switch (offset)
{
case 0:
return input_port_4_r (offset);
break;
case 2:
return (input_port_1_r (offset) << 8) + (input_port_0_r (offset));
break;
case 4:
return (input_port_3_r (offset) << 8) + (input_port_2_r (offset));
break;
}
return 0;
}
void gaiden_sound_command_w(int offset,int data)
{
if (data & 0xff000000) soundlatch_w(0,data & 0xff); /* Ninja Gaiden */
if (data & 0x00ff0000) soundlatch_w(0,(data >> 8) & 0xff); /* Tecmo Knight */
cpu_cause_interrupt(1,Z80_NMI_INT);
}
/* Tecmo Knight has a simple protection. It writes codes to 0x07a804, and reads */
/* the answer from 0x07a007. The returned values contain the address of a */
/* function to jump to. */
static int prot;
void tknight_protection_w(int offset,int data)
{
static int jumpcode;
static int jumppoints[] =
{
0x0c0c,0x0cac,0x0d42,0x0da2,0x0eea,0x112e,0x1300,0x13fa,
0x159a,0x1630,0x109a,0x1700,0x1750,0x1806,0x18d6,0x1a44,
0x1b52
};
data = (data >> 8) & 0xff;
switch (data & 0xf0)
{
case 0x00: /* init */
prot = 0x00;
break;
case 0x10: /* high 4 bits of jump code */
jumpcode = (data & 0x0f) << 4;
prot = 0x10;
break;
case 0x20: /* low 4 bits of jump code */
jumpcode |= data & 0x0f;
if (jumpcode > 16)
{
jumpcode = 0;
}
prot = 0x20;
break;
case 0x30: /* ask for bits 12-15 of function address */
prot = 0x40 | ((jumppoints[jumpcode] >> 12) & 0x0f);
break;
case 0x40: /* ask for bits 8-11 of function address */
prot = 0x50 | ((jumppoints[jumpcode] >> 8) & 0x0f);
break;
case 0x50: /* ask for bits 4-7 of function address */
prot = 0x60 | ((jumppoints[jumpcode] >> 4) & 0x0f);
break;
case 0x60: /* ask for bits 0-3 of function address */
prot = 0x70 | ((jumppoints[jumpcode] >> 0) & 0x0f);
break;
}
}
int tknight_protection_r(int offset)
{
return prot;
}
static struct MemoryReadAddress readmem[] =
{
{ 0x000000, 0x03ffff, MRA_ROM },
{ 0x060000, 0x063fff, MRA_BANK1 }, /* RAM */
{ 0x070000, 0x070fff, gaiden_videoram_r },
{ 0x072000, 0x073fff, gaiden_videoram2_r },
{ 0x074000, 0x075fff, gaiden_videoram3_r },
{ 0x076000, 0x077fff, gaiden_spriteram_r },
{ 0x078000, 0x0787ff, paletteram_word_r },
{ 0x078800, 0x079fff, MRA_NOP }, /* extra portion of palette RAM, not really used */
{ 0x07a000, 0x07a005, gaiden_input_r },
{ 0x07a006, 0x07a007, tknight_protection_r },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x000000, 0x03ffff, MWA_ROM },
{ 0x060000, 0x063fff, MWA_BANK1 },
{ 0x070000, 0x070fff, gaiden_videoram_w, &gaiden_videoram, &gaiden_videoram_size },
{ 0x072000, 0x073fff, gaiden_videoram2_w, &gaiden_videoram2, &gaiden_videoram2_size },
{ 0x074000, 0x075fff, gaiden_videoram3_w, &gaiden_videoram3, &gaiden_videoram3_size },
{ 0x076000, 0x077fff, gaiden_spriteram_w, &gaiden_spriteram, &gaiden_spriteram_size },
{ 0x078000, 0x0787ff, paletteram_xxxxBBBBGGGGRRRR_word_w, &paletteram },
{ 0x078800, 0x079fff, MWA_NOP }, /* extra portion of palette RAM, not really used */
{ 0x07a104, 0x07a105, gaiden_txscrolly_w, &gaiden_txscrolly },
{ 0x07a10c, 0x07a10d, gaiden_txscrollx_w, &gaiden_txscrollx },
{ 0x07a204, 0x07a205, gaiden_fgscrolly_w, &gaiden_fgscrolly },
{ 0x07a20c, 0x07a20d, gaiden_fgscrollx_w, &gaiden_fgscrollx },
{ 0x07a304, 0x07a305, gaiden_bgscrolly_w, &gaiden_bgscrolly },
{ 0x07a30c, 0x07a30d, gaiden_bgscrollx_w, &gaiden_bgscrollx },
{ 0x07a802, 0x07a803, gaiden_sound_command_w },
{ 0x07a804, 0x07a805, tknight_protection_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0xdfff, MRA_ROM },
{ 0xf000, 0xf7ff, MRA_RAM },
{ 0xf800, 0xf800, OKIM6295_status_r },
{ 0xfc00, 0xfc00, MRA_NOP }, /* ?? */
{ 0xfc20, 0xfc20, soundlatch_r },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0xdfff, MWA_ROM },
{ 0xf000, 0xf7ff, MWA_RAM },
{ 0xf800, 0xf800, OKIM6295_data_w },
{ 0xf810, 0xf810, YM2203_control_port_0_w },
{ 0xf811, 0xf811, YM2203_write_port_0_w },
{ 0xf820, 0xf820, YM2203_control_port_1_w },
{ 0xf821, 0xf821, YM2203_write_port_1_w },
{ 0xfc00, 0xfc00, MWA_NOP }, /* ?? */
{ -1 } /* end of table */
};
INPUT_PORTS_START( gaiden_input_ports )
PORT_START /* PLAYER 1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* PLAYER 2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* DSWA */
PORT_DIPNAME( 0x01, 0x01, "Demo Sounds", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x01, "On" )
PORT_DIPNAME( 0x02, 0x02, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x1c, 0x1c, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "5 Coins/1 Credit" )
PORT_DIPSETTING( 0x10, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x08, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x04, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x1c, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x0c, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x14, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x18, "1 Coin/4 Credits" )
PORT_DIPNAME( 0xe0, 0xe0, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "5 Coins/1 Credit" )
PORT_DIPSETTING( 0x80, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x40, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x20, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0xe0, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x60, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0xa0, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0xc0, "1 Coin/4 Credits" )
PORT_START /* DSWB */
PORT_DIPNAME( 0x01, 0x01, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x01, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x02, 0x02, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x04, 0x04, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x04, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x08, 0x08, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x08, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x30, 0x30, "Energy", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x30, "3" )
PORT_DIPSETTING( 0x10, "4" )
PORT_DIPSETTING( 0x20, "5" )
PORT_DIPNAME( 0xc0, 0xc0, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPSETTING( 0xc0, "2" )
PORT_DIPSETTING( 0x40, "3" )
PORT_DIPSETTING( 0x80, "4" )
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 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
INPUT_PORTS_END
INPUT_PORTS_START( tknight_input_ports )
PORT_START /* PLAYER 1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER1 | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* PLAYER 2 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER2 | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* DSWA */
PORT_DIPNAME( 0xe0, 0xe0, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "5 Coins/1 Credit" )
PORT_DIPSETTING( 0x80, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x40, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x20, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0xe0, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x60, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0xa0, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0xc0, "1 Coin/4 Credits" )
PORT_DIPNAME( 0x1c, 0x1c, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "5 Coins/1 Credit" )
PORT_DIPSETTING( 0x10, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x08, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x04, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x1c, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x0c, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x14, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x18, "1 Coin/4 Credits" )
PORT_DIPNAME( 0x02, 0x02, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x02, "Off" )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -