📄 punchout.c
字号:
/***************************************************************************
Punch Out memory map (preliminary)
Arm Wrestling runs on about the same hardware, but the video board is different.
main CPU:
0000-bfff ROM
c000-c3ff NVRAM
d000-d7ff RAM
d800-dfff Video RAM (info screen)
e000-e7ff Video RAM (opponent)
e800-efff Video RAM (player)
f000-f03f Background row scroll (low/high couples)
f000-ffff Video RAM (background)
memory mapped ports:
write:
dfe0-dfef ??
dff0 big sprite #1 zoom low 8 bits
dff1 big sprite #1 zoom high 4 bits
dff2 big sprite #1 x pos low 8 bits
dff3 big sprite #1 x pos high 4 bits
dff4 big sprite #1 y pos low 8 bits
dff5 big sprite #1 y pos high bit
dff6 big sprite #1 x flip (bit 0)
dff7 big sprite #1 bit 0: show on top monitor; bit 1: show on bottom monitor
dff8 big sprite #2 x pos low 8 bits
dff9 big sprite #2 x pos high bit
dffa big sprite #2 y pos low 8 bits
dffb big sprite #2 y pos high bit
dffc big sprite #2 x flip (bit 0)
dffd palette bank (bit 0 = bottom monitor bit 1 = top monitor)
I/O
read:
00 IN0
01 IN1
02 DSW0
03 DSW1 (bit 4: VLM5030 busy signal)
write:
00 to 2A03 #1 IN0 (unpopulated)
01 to 2A03 #1 IN1 (unpopulated)
02 to 2A03 #2 IN0
03 to 2A03 #2 IN1
04 to VLM5030
08 NMI enable + watchdog reset
09 watchdog reset
0a ? latched into Z80 BUS RQ
0b to 2A03 #1 and #2 RESET
0c to VLM5030 RESET
0d to VLM5030 START
0e to VLM5030 VCU
0f enable NVRAM ?
sound CPU:
the sound CPU is a 2A03, which is a modified 6502 with built-in input ports
and two (analog?) outputs. The input ports are memory mapped at 4016-4017;
the outputs are more complicated. The only thing I have found is that 4011
goes straight into a DAC and produces the crowd sounds, but several addresses
in the range 4000-4017 are written to. There are probably three tone generators.
0000-07ff RAM
e000-ffff ROM
read:
4016 IN0
4017 IN1
write:
4000 ? is usually ORed with 90 or 50
4001 ? usually 7f, could be associated with 4000
4002-4003 ? tone #1 freq? (bit 3 of 4003 is always 1, bits 4-7 always 0)
4004 ? is usually ORed with 90 or 50
4005 ? usually 7f, could be associated with 4004
4006-4007 ? tone #2 freq? (bit 3 of 4007 is always 1, bits 4-7 always 0)
4008 ? at one point the max value is cut at 38
400a-400b ? tone #3 freq? (bit 3 of 400b is always 1, bits 4-7 always 0)
400c ?
400e-400f ?
4011 DAC crowd noise
4015 ?? 00 or 0f
4017 ?? always c0
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
extern unsigned char *punchout_videoram2;
extern int punchout_videoram2_size;
extern unsigned char *punchout_bigsprite1ram;
extern int punchout_bigsprite1ram_size;
extern unsigned char *punchout_bigsprite2ram;
extern int punchout_bigsprite2ram_size;
extern unsigned char *punchout_scroll;
extern unsigned char *punchout_bigsprite1;
extern unsigned char *punchout_bigsprite2;
extern unsigned char *punchout_palettebank;
void punchout_videoram2_w(int offset,int data);
void punchout_bigsprite1ram_w(int offset,int data);
void punchout_bigsprite2ram_w(int offset,int data);
void punchout_palettebank_w(int offset,int data);
int punchout_vh_start(void);
int armwrest_vh_start(void);
void punchout_vh_stop(void);
void punchout_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void armwrest_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void punchout_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void armwrest_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
int punchout_input_3_r(int offset);
void punchout_speech_reset(int offset,int data);
void punchout_speech_st(int offset,int data);
void punchout_speech_vcu(int offset,int data);
void punchout_dac_w(int offset,int data)
{
DAC_data_w(0,data);
}
void punchout_2a03_reset_w(int offset,int data)
{
if (data & 1)
{
/* suspend execution */
cpu_halt(1,0);
}
else
{
/* reset and resume execution */
cpu_reset(1);
cpu_halt(1,1);
}
}
static int prot[7];
static int spunchout_prot_0_r( int offset ) {
return prot[0];
}
static void spunchout_prot_0_w( int offset, int data ) {
prot[0] = data;
}
static int spunchout_prot_2_r( int offset )
{
if( cpu_getpc() == 0x0615 ) return 0x09; /*write "JMP (HL)"code to 0d79fh*/
else return prot[2];
}
static void spunchout_prot_2_w( int offset, int data ) {
prot[2] = data;
}
static int spunchout_prot_3_r( int offset ) {
return prot[3];
}
static void spunchout_prot_3_w( int offset, int data ) {
prot[3] = data;
}
static int spunchout_prot_4_r( int offset ) {
return prot[4];
}
static void spunchout_prot_4_w( int offset, int data ) {
prot[4] = data;
}
static int spunchout_prot_5_r( int offset ) {
return prot[5];
}
static void spunchout_prot_5_w( int offset, int data ) {
prot[5] = data;
}
static int spunchout_prot_6_r( int offset ) {
return prot[6];
}
static void spunchout_prot_6_w( int offset, int data ) {
prot[6] = data;
}
/* test handlers */
static int punchout_prot_t;
static int spunchout_prot_t_r( int offset ) {
return punchout_prot_t;
}
static void spunchout_prot_t_w( int offset, int data ) {
punchout_prot_t = data;
}
static struct MemoryReadAddress readmem[] =
{
{ 0x0000, 0xbfff, MRA_ROM },
{ 0xc000, 0xc3ff, MRA_RAM },
{ 0xd000, 0xffff, MRA_RAM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress writemem[] =
{
{ 0x0000, 0xbfff, MWA_ROM },
{ 0xc000, 0xc3ff, MWA_RAM },
{ 0xd000, 0xd7ff, MWA_RAM },
{ 0xdff0, 0xdff7, MWA_RAM, &punchout_bigsprite1 },
{ 0xdff8, 0xdffc, MWA_RAM, &punchout_bigsprite2 },
{ 0xdffd, 0xdffd, punchout_palettebank_w, &punchout_palettebank },
{ 0xd800, 0xdfff, videoram_w, &videoram, &videoram_size },
{ 0xe000, 0xe7ff, punchout_bigsprite1ram_w, &punchout_bigsprite1ram, &punchout_bigsprite1ram_size },
{ 0xe800, 0xefff, punchout_bigsprite2ram_w, &punchout_bigsprite2ram, &punchout_bigsprite2ram_size },
{ 0xf000, 0xf03f, MWA_RAM, &punchout_scroll },
{ 0xf000, 0xffff, punchout_videoram2_w, &punchout_videoram2, &punchout_videoram2_size },
{ -1 } /* end of table */
};
static struct IOReadPort readport[] =
{
{ 0x00, 0x00, input_port_0_r },
{ 0x01, 0x01, input_port_1_r },
{ 0x02, 0x02, input_port_2_r },
{ 0x03, 0x03, punchout_input_3_r },
{ 0x27, 0x27, spunchout_prot_2_r },
{ 0x37, 0x37, spunchout_prot_3_r },
{ 0x67, 0x67, spunchout_prot_4_r },
{ 0x97, 0x97, spunchout_prot_5_r }, /* $d7*/
{ 0xa7, 0xa7, spunchout_prot_6_r },
{ -1 } /* end of table */
};
static struct IOWritePort writeport[] =
{
{ 0x00, 0x01, IOWP_NOP }, /* the 2A03 #1 is not present */
{ 0x02, 0x02, soundlatch_w },
{ 0x03, 0x03, soundlatch2_w },
{ 0x04, 0x04, VLM5030_data_w }, /* VLM5030 */
{ 0x05, 0x05, IOWP_NOP }, /* unused */
{ 0x08, 0x08, interrupt_enable_w },
{ 0x09, 0x09, IOWP_NOP }, /* watchdog reset, seldom used because 08 clears the watchdog as well */
{ 0x0a, 0x0a, IOWP_NOP }, /* ?? */
{ 0x0b, 0x0b, punchout_2a03_reset_w },
{ 0x0c, 0x0c, punchout_speech_reset }, /* VLM5030 */
{ 0x0d, 0x0d, punchout_speech_st }, /* VLM5030 */
{ 0x0e, 0x0e, punchout_speech_vcu }, /* VLM5030 */
{ 0x0f, 0x0f, IOWP_NOP }, /* enable NVRAM ? */
{ 0x27, 0x27, spunchout_prot_2_w }, /* 1:1 */
{ 0x37, 0x37, spunchout_prot_3_w }, /* 1:1 */
{ 0x67, 0x67, spunchout_prot_4_w }, /* 1:1 */
{ 0xa7, 0xa7, spunchout_prot_6_w }, /* 1:1 */
{ 0xd7, 0xd7, spunchout_prot_5_w }, /* $97 */
{ -1 } /* end of table */
};
static struct MemoryReadAddress sound_readmem[] =
{
{ 0x0000, 0x07ff, MRA_RAM },
{ 0x4016, 0x4016, soundlatch_r },
{ 0x4017, 0x4017, soundlatch2_r },
{ 0x4000, 0x4017, NESPSG_0_r },
{ 0xe000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress sound_writemem[] =
{
{ 0x0000, 0x07ff, MWA_RAM },
{ 0x4011, 0x4011, punchout_dac_w },
{ 0x4000, 0x4017, NESPSG_0_w },
{ 0xe000, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
INPUT_PORTS_START( punchout_input_ports )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON3 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT | IPF_8WAY )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT | IPF_8WAY )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP | IPF_8WAY )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN | IPF_8WAY )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_START /* DSW0 */
PORT_DIPNAME( 0x03, 0x00, "Difficulty", IP_KEY_NONE )
PORT_DIPSETTING( 0x00, "Easy" )
PORT_DIPSETTING( 0x01, "Medium" )
PORT_DIPSETTING( 0x02, "Hard" )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -