📄 sf1.c
字号:
/***************************************************************************
Street Fighter 1
TODO:
- hook up the second Z80 (which plays samples through two MSM5205)
- properly support palette shrinking in the video driver
- clean up and optimize the video driver (it's currently redrawing the
whole screen every frame)
***************************************************************************/
#include "driver.h"
#include "cpuintrf.h"
#include "vidhrdw/generic.h"
#include "Z80/z80.h"
extern unsigned char *sf1_video_ram;
extern unsigned char *sf1_object_ram;
extern int sf1_deltaxb;
extern int sf1_deltaxm;
extern int sf1_active;
void sf1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
static int sf1_interrupt(void)
{
return 1;
}
/* Dips */
static int control4_r(int offset)
{
return (input_port_1_r(0)<<8)|input_port_0_r(0);
}
/* Dips again */
/* No, the 7 is not a bug */
static int control5_r(int offset)
{
return (input_port_3_r(0)<<7)|input_port_2_r(0);
}
/* Start */
static int control6_r(int offset)
{
return input_port_5_r(0)|0xff00;
}
static int control7_r(int offset)
{
return 0xffff;
}
static void control10_w(int offset, int data)
{
sf1_deltaxm = data;
}
static void control12_w(int offset, int data)
{
sf1_deltaxb = data;
}
/* b0 = reset, or maybe "set anyway" */
/* b1 = pulsed when control6.b6==0 until it's 1 */
/* b2 = active when dip 8 (flip) on */
/* b3 = active character plane */
/* b4 = unused */
/* b5 = active background plane */
/* b6 = active middle plane */
/* b7 = active sprites */
static void control13_w(int offset, int data)
{
if((data&0xff)!=0)
sf1_active = data;
}
/* The protection of the japanese version */
static void control15_w(int offset, int data)
{
static int maplist[4][10] = {
{ 1, 0, 3, 2, 4, 5, 6, 7, 8, 9 },
{ 4, 5, 6, 7, 1, 0, 3, 2, 8, 9 },
{ 3, 2, 1, 0, 6, 7, 4, 5, 8, 9 },
{ 6, 7, 4, 5, 3, 2, 1, 0, 8, 9 }
};
int map;
map = maplist
[cpu_readmem24(0xffc006)]
[(cpu_readmem24(0xffc003)<<1) + (cpu_readmem24_word(0xffc004)>>8)];
switch(cpu_readmem24(0xffc684)) {
case 1:
{
int base;
int j;
base = 0x1b6e8+0x300e*map;
cpu_writemem24_dword(0xffc01c, 0x16bfc+0x270*map);
cpu_writemem24_dword(0xffc020, base+0x80);
cpu_writemem24_dword(0xffc024, base);
cpu_writemem24_dword(0xffc028, base+0x86);
cpu_writemem24_dword(0xffc02c, base+0x8e);
cpu_writemem24_dword(0xffc030, base+0x20e);
cpu_writemem24_dword(0xffc034, base+0x30e);
cpu_writemem24_dword(0xffc038, base+0x38e);
cpu_writemem24_dword(0xffc03c, base+0x40e);
cpu_writemem24_dword(0xffc040, base+0x80e);
cpu_writemem24_dword(0xffc044, base+0xc0e);
cpu_writemem24_dword(0xffc048, base+0x180e);
cpu_writemem24_dword(0xffc04c, base+0x240e);
cpu_writemem24_dword(0xffc050, 0x19548+0x60*map);
cpu_writemem24_dword(0xffc054, 0x19578+0x60*map);
break;
}
case 2:
{
static int delta1[10] = {
0x1f80, 0x1c80, 0x2700, 0x2400, 0x2b80, 0x2e80, 0x3300, 0x3600, 0x3a80, 0x3d80
};
static int delta2[10] = {
0x2180, 0x1800, 0x3480, 0x2b00, 0x3e00, 0x4780, 0x5100, 0x5a80, 0x6400, 0x6d80
};
int d1 = delta1[map] + 0xc0;
int d2 = delta2[map];
cpu_writemem24_word(0xffc680, d1);
cpu_writemem24_word(0xffc682, d2);
cpu_writemem24_word(0xffc00c, 0xc0);
control10_w(0, d1);
control12_w(0, d2);
break;
}
case 4:
{
int pos = cpu_readmem24(0xffc010);
pos = (pos+1) & 3;
cpu_writemem24(0xffc010, pos);
if(!pos) {
int d1 = cpu_readmem24_word(0xffc682);
int off = cpu_readmem24_word(0xffc00e);
if(off!=512) {
off++;
d1++;
} else {
off = 0;
d1 -= 512;
}
cpu_writemem24_word(0xffc682, d1);
cpu_writemem24_word(0xffc00e, off);
control12_w(0, d1);
}
break;
}
default:
{
break;
}
}
}
/* Players actions, world version */
/* That one has analog buttons */
/* We simulate them with 3 buttons the same way the other versions
internally do */
/* Coins */
static int control0_r(int offset)
{
return input_port_4_r(0)|0xff00;
}
/* Moves */
static int control1_r(int offset)
{
return (input_port_7_r(0)<<8)|input_port_6_r(0);
}
static int scale[8] = { 0x00, 0x40, 0xe0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe };
/* Buttons punch */
static int control2_r(int offset)
{
return (scale[input_port_10_r(0)]<<8)|scale[input_port_8_r(0)];
}
static int control3_r(int offset)
{
return (scale[input_port_11_r(0)]<<8)|scale[input_port_9_r(0)];
}
/* Players actions, japanese version */
/* That one has three buttons per attack */
/* Coins */
static int control0jp_r(int offset)
{
return input_port_4_r(0)|0xff00;
}
/* player 1 buttons & moves */
static int control1jp_r(int offset)
{
return (input_port_7_r(0)<<8)|input_port_6_r(0);
}
/* Player 2 buttons & moves */
static int control2jp_r(int offset)
{
return (input_port_9_r(0)<<8)|input_port_8_r(0);
}
static int control3jp_r(int offset)
{
return 0xffff;
}
/* Players actions, US version */
/* That one has three buttons per attack */
/* Coins and buttons */
static int control0us_r(int offset)
{
return (input_port_8_r(0)<<8)|input_port_4_r(0);
}
/* Moves & Buttons */
static int control1us_r(int offset)
{
return (input_port_7_r(0)<<8)|input_port_6_r(0);
}
static int control2us_r(int offset)
{
return 0xffff;
}
static int control3us_r(int offset)
{
return 0xffff;
}
static void sf1_soundcmd_w(int offset,int data)
{
if (data != 0xffff)
{
soundlatch_w(offset,data);
cpu_cause_interrupt(1,Z80_NMI_INT);
}
}
static struct MemoryReadAddress readmem[] =
{
{ 0x000000, 0x04ffff, MRA_ROM },
{ 0x800000, 0x800fff, MRA_BANK3 },
{ 0xc00000, 0xc00001, control0_r },
{ 0xc00002, 0xc00003, control1_r },
{ 0xc00004, 0xc00005, control2_r },
{ 0xc00006, 0xc00007, control3_r },
{ 0xc00008, 0xc00009, control4_r },
{ 0xc0000a, 0xc0000b, control5_r },
{ 0xc0000c, 0xc0000d, control6_r },
{ 0xc0000e, 0xc0000f, control7_r },
{ 0xff8000, 0xffdfff, MRA_BANK1 },
{ 0xffe000, 0xffffff, MRA_BANK2 },
{ -1 }
};
static struct MemoryReadAddress readmemus[] =
{
{ 0x000000, 0x04ffff, MRA_ROM },
{ 0x800000, 0x800fff, MRA_BANK3 },
{ 0xc00000, 0xc00001, control0us_r },
{ 0xc00002, 0xc00003, control1us_r },
{ 0xc00004, 0xc00005, control2us_r },
{ 0xc00006, 0xc00007, control3us_r },
{ 0xc00008, 0xc00009, control4_r },
{ 0xc0000a, 0xc0000b, control5_r },
{ 0xc0000c, 0xc0000d, control6_r },
{ 0xc0000e, 0xc0000f, control7_r },
{ 0xff8000, 0xffdfff, MRA_BANK1 },
{ 0xffe000, 0xffffff, MRA_BANK2 },
{ -1 }
};
static struct MemoryReadAddress readmemjp[] =
{
{ 0x000000, 0x04ffff, MRA_ROM },
{ 0x800000, 0x800fff, MRA_BANK3 },
{ 0xc00000, 0xc00001, control0jp_r },
{ 0xc00002, 0xc00003, control1jp_r },
{ 0xc00004, 0xc00005, control2jp_r },
{ 0xc00006, 0xc00007, control3jp_r },
{ 0xc00008, 0xc00009, control4_r },
{ 0xc0000a, 0xc0000b, control5_r },
{ 0xc0000c, 0xc0000d, control6_r },
{ 0xc0000e, 0xc0000f, control7_r },
{ 0xff8000, 0xffdfff, MRA_BANK1 },
{ 0xffe000, 0xffffff, MRA_BANK2 },
{ -1 }
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x800000, 0x800fff, MWA_BANK3, &sf1_video_ram },
{ 0xb00000, 0xb007ff, paletteram_xxxxRRRRGGGGBBBB_word_w, &paletteram },
{ 0xc00014, 0xc00015, control10_w },
{ 0xc00017, 0xc00018, control12_w },
{ 0xc0001a, 0xc0001b, control13_w },
{ 0xc0001c, 0xc0001d, sf1_soundcmd_w },
{ 0xc0001e, 0xc0001f, control15_w },
{ 0xff8000, 0xffdfff, MWA_BANK1 },
{ 0xffe000, 0xffffff, MWA_BANK2, &sf1_object_ram },
{ -1 }
};
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0x7fff, MRA_ROM },
{ 0xc000, 0xc7ff, MRA_RAM },
{ 0xc800, 0xc800, soundlatch_r },
{ 0xe001, 0xe001, YM2151_status_port_0_r },
{ -1 }
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0x7fff, MWA_ROM },
{ 0xc000, 0xc7ff, MWA_RAM },
{ 0xe000, 0xe000, YM2151_register_port_0_w },
{ 0xe001, 0xe001, YM2151_data_port_0_w },
{ -1 }
};
INPUT_PORTS_START(sf1jp_input_ports)
PORT_START
PORT_DIPNAME( 0x07, 0x07, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x07, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x06, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x05, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x04, "1 Coin/4 Credits" )
PORT_DIPSETTING( 0x03, "1 Coin/6 Credits" )
PORT_DIPSETTING( 0x02, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x01, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x00, "4 Coins/1 Credit" )
PORT_DIPNAME( 0x38, 0x38, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x38, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x30, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x28, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x20, "1 Coin/4 Credits" )
PORT_DIPSETTING( 0x18, "1 Coin/6 Credits" )
PORT_DIPSETTING( 0x10, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x08, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x00, "4 Coins/1 Credit" )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START
PORT_DIPNAME( 0x01, 0x01, "Screen orientation", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Flip" )
PORT_DIPSETTING( 0x01, "Normal" )
PORT_DIPNAME( 0x02, 0x02, "Attract music", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPSETTING( 0x02, "Off" )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_DIPNAME( 0x10, 0x10, "Speed", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Slow" )
PORT_DIPSETTING( 0x10, "Normal" )
PORT_DIPNAME( 0x20, 0x20, "Attract sound?", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPSETTING( 0x20, "Off" )
PORT_DIPNAME( 0x40, 0x40, "Freeze", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPSETTING( 0x40, "Off" )
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" )
PORT_START
PORT_DIPNAME( 0x07, 0x07, "Continuation max stage", IP_KEY_NONE )
PORT_DIPSETTING( 0x07, "5th" )
PORT_DIPSETTING( 0x06, "4th" )
PORT_DIPSETTING( 0x05, "3rd" )
PORT_DIPSETTING( 0x04, "2nd" )
PORT_DIPSETTING( 0x03, "1st" )
PORT_DIPSETTING( 0x02, "No continuation" )
PORT_DIPNAME( 0x18, 0x18, "Round time", IP_KEY_NONE )
PORT_DIPSETTING( 0x18, "100" )
PORT_DIPSETTING( 0x10, "150" )
PORT_DIPSETTING( 0x08, "200" )
PORT_DIPSETTING( 0x00, "250" )
PORT_DIPNAME( 0x60, 0x60, "Difficulty", IP_KEY_NONE )
PORT_DIPSETTING( 0x60, "Normal" )
PORT_DIPSETTING( 0x40, "Easy" )
PORT_DIPSETTING( 0x20, "Difficult" )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -