📄 pow.c
字号:
/***************************************************************************
POW - Prisoners Of War, SNK 1988
Emulation by Bryan McPhail, mish@tendril.force9.net
Issues:
Wrong ADPCM samples are sometimes played.
Priority is sometimes wrong, eg, end of first level - player goes behind
ladder instead of in front...
Title screen is wrong (view bottom layer with TRANSPARENCY_NONE to see).
Japanese text is wrong (I can't find bank select).
A bit slow...
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "z80/z80.h"
void pow_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
static unsigned char *pow_ram;
/******************************************************************************/
static int control_1_r(int offset)
{
return (readinputport(0) + (readinputport(1) << 8));
}
static int control_2_r(int offset)
{
return readinputport(2);
}
static int dip_1_r(int offset)
{
return (readinputport(3) << 8);
}
static int dip_2_r(int offset)
{
return (readinputport(4) << 8);
}
static void pow_sound_w(int offset, int data)
{
int mybyte=(data>>8)&0xff;
if (mybyte>0xbf) {
ADPCM_trigger(0,mybyte);
}
else {
soundlatch_w(0,mybyte);
cpu_cause_interrupt(1,Z80_NMI_INT);
}
}
static int high_ret(int offset) { return 0xffff; }
/* Idle cpu detection for POW */
static int cycle_r(int offset)
{
int c=READ_WORD(&pow_ram[0x3e7c]);
if ((c&0xff)!=0xf) cpu_spinuntil_int();
return c;
}
static struct MemoryReadAddress pow_readmem[] =
{
{ 0x000000, 0x03ffff, MRA_ROM },
{ 0x043e7c, 0x043e7d, cycle_r },
{ 0x040000, 0x043fff, MRA_BANK1 },
{ 0x080000, 0x080001, control_1_r },
{ 0x0c0000, 0x0c0001, control_2_r },
{ 0x0e0000, 0x0e0001, high_ret }, /* Not sure */
{ 0x0e8000, 0x0e8001, high_ret }, /* Not sure */
{ 0x0f0000, 0x0f0001, dip_1_r },
{ 0x0f0008, 0x0f0009, dip_2_r },
{ 0x100000, 0x100fff, MRA_BANK2 },
{ 0x200000, 0x207fff, MRA_BANK3 },
{ 0x400000, 0x400fff, paletteram_word_r },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress pow_writemem[] =
{
{ 0x000000, 0x03ffff, MWA_ROM },
{ 0x040000, 0x043fff, MWA_BANK1, &pow_ram },
{ 0x080000, 0x080001, pow_sound_w },
{ 0x0f0008, 0x0f0009, MWA_NOP },
{ 0x100000, 0x100fff, MWA_BANK2, &videoram },
{ 0x200000, 0x207fff, MWA_BANK3, &spriteram },
{ 0x400000, 0x400fff, paletteram_xxxxRRRRGGGGBBBB_word_w, &paletteram },
{ -1 } /* end of table */
};
/******************************************************************************/
static struct MemoryReadAddress pow_sound_readmem[] =
{
{ 0x0000, 0xefff, MRA_ROM },
{ 0xf000, 0xf7ff, MRA_RAM },
{ 0xf800, 0xf800, soundlatch_r },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress pow_sound_writemem[] =
{
{ 0x0000, 0xefff, MWA_ROM },
{ 0xf000, 0xf7ff, MWA_RAM },
{ -1 } /* end of table */
};
static struct IOReadPort pow_sound_readport[] =
{
{ 0x00, 0x00, YM3812_status_port_0_r },
{ -1 }
};
static struct IOWritePort pow_sound_writeport[] =
{
{ 0x00, 0x00, YM3812_control_port_0_w },
{ 0x20, 0x20, YM3812_write_port_0_w },
/* 0x40 & 0x80 - adpcm ports, an unknown chip */
{ -1 }
};
/******************************************************************************/
INPUT_PORTS_START( pow_input_ports )
PORT_START /* Player 1 controls */
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_LEFT | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
PORT_START /* Player 2 controls */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
PORT_START
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN3 ) /* Service button */
/* there's a service mode dip switch as well
PORT_BITX( 0x02, 0x02, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
*/ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* Dip switch bank 1, all active high */
PORT_DIPNAME( 0x03, 0x00, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x02, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x01, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x03, "1 Coin/4 Credits" )
PORT_DIPNAME( 0x0c, 0x00, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x0c, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x04, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x08, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x00, "1 Coin/1 Credit" )
PORT_DIPNAME( 0x10, 0x10, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x10, "3" )
PORT_DIPNAME( 0x20, 0x00, "Bonus Occurence", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Second Bonus" )
PORT_DIPSETTING( 0x20, "Every Bonus" )
PORT_DIPNAME( 0x40, 0x00, "Language", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "English" )
PORT_DIPSETTING( 0x40, "Japanese" )
PORT_DIPNAME( 0x80, 0x00, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x80, "On" )
PORT_START /* Dip switch bank 2, all active high */
PORT_BITX( 0x01, 0x00, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x01, "On" )
PORT_DIPNAME( 0x02, 0x00, "Allow Continue", IP_KEY_NONE )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
PORT_DIPNAME( 0x0c, 0x00, "Bonus Life", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "20000 50000" )
PORT_DIPSETTING( 0x08, "40000 100000" )
PORT_DIPSETTING( 0x04, "60000 150000" )
PORT_DIPSETTING( 0x0c, "None" )
PORT_DIPNAME( 0x30, 0x00, "Game Mode", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Demo Sounds On" )
PORT_DIPSETTING( 0x20, "Demo Sounds Off" )
PORT_DIPSETTING( 0x30, "Freeze Game" )
PORT_BITX( 0, 0x10, IPT_DIPSWITCH_SETTING | IPF_CHEAT, "Infinite Lives", IP_KEY_NONE, IP_JOY_NONE, 0 )
PORT_DIPNAME( 0xc0, 0x00, "Difficulty", IP_KEY_NONE )
PORT_DIPSETTING( 0x80, "Easy" )
PORT_DIPSETTING( 0x00, "Normal" )
PORT_DIPSETTING( 0x40, "Hard" )
PORT_DIPSETTING( 0xc0, "Hardest" )
INPUT_PORTS_END
/* Identical to pow, but the Language dip switch has no effect */
INPUT_PORTS_START( powj_input_ports )
PORT_START /* Player 1 controls */
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_LEFT | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
PORT_START /* Player 2 controls */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
PORT_START
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN3 ) /* Service button */
/* there's a service mode dip switch as well
PORT_BITX( 0x02, 0x02, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x02, "Off" )
PORT_DIPSETTING( 0x00, "On" )
*/ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* Dip switch bank 1, all active high */
PORT_DIPNAME( 0x03, 0x00, "Coin B", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "1 Coin/1 Credit" )
PORT_DIPSETTING( 0x02, "1 Coin/2 Credits" )
PORT_DIPSETTING( 0x01, "1 Coin/3 Credits" )
PORT_DIPSETTING( 0x03, "1 Coin/4 Credits" )
PORT_DIPNAME( 0x0c, 0x00, "Coin A", IP_KEY_NONE )
PORT_DIPSETTING( 0x0c, "4 Coins/1 Credit" )
PORT_DIPSETTING( 0x04, "3 Coins/1 Credit" )
PORT_DIPSETTING( 0x08, "2 Coins/1 Credit" )
PORT_DIPSETTING( 0x00, "1 Coin/1 Credit" )
PORT_DIPNAME( 0x10, 0x10, "Lives", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x10, "3" )
PORT_DIPNAME( 0x20, 0x00, "Bonus Occurence", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Second Bonus" )
PORT_DIPSETTING( 0x20, "Every Bonus" )
PORT_DIPNAME( 0x40, 0x00, "Unknown", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x40, "On" )
PORT_DIPNAME( 0x80, 0x00, "Flip Screen", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Off" )
PORT_DIPSETTING( 0x80, "On" )
PORT_START /* Dip switch bank 2, all active high */
PORT_BITX( 0x01, 0x00, IPT_DIPSWITCH_NAME | IPF_TOGGLE, "Service Mode", OSD_KEY_F2, IP_JOY_NONE, 0 )
PORT_DIPSETTING( 0x00, "Off" )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -