⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pang.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************

	Pang (Mitchell Corp) / Buster Bros (Capcom)
	Super Pang (Mitchell Corp)
	Block Block (Capcom)

	Driver submitted by Paul Leaman

	Processor:
	1xZ80 (40006psc)

	Sound:
	1xOKIM6295 (9Z002 VI)   ADPCM chip
	1xYM2413                FM Chip

***************************************************************************/

#include "driver.h"
#include "vidhrdw/generic.h"

/* in machine/kabuki.c */
void bbros_decode(void);
void spang_decode(void);
void block_decode(void);


int  pang_vh_start(void);
void pang_vh_stop(void);
void pang_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);

void pang_video_bank_w(int offset, int data);
void pang_videoram_w(int offset, int data);
int  pang_videoram_r(int offset);
void pang_colorram_w(int offset, int data);
int  pang_colorram_r(int offset);
void pang_palette_bank_w(int offset, int data);
void pang_paletteram_w(int offset, int data);
int  pang_paletteram_r(int offset);

extern unsigned char *pang_videoram;
extern unsigned char *pang_colorram;

extern int pang_videoram_size;
extern int pang_colorram_size;



static int dial[2],dial_selected;

static void init_machine(void)
{
	/* start with the dial disabled, it will be enabled only for Block Block */
	dial_selected = 0;
}

int block_input_r(int offset)
{
	if (dial_selected)
	{
		static int dir[2];

		if (dial_selected == 1)
		{
			int delta;

			delta = (readinputport(4 + offset) - dial[offset]) & 0xff;
			if (delta & 0x80)
			{
				delta = (-delta) & 0xff;
				if (dir[offset])
				{
				/* don't report movement on a direction change,otherwise it will stutter */
					dir[offset] = 0;
					delta = 0;
				}
			}
			else if (delta > 0)
			{
				if (dir[offset] == 0)
				{
				/* don't report movement on a direction change,otherwise it will stutter */
					dir[offset] = 1;
					delta = 0;
				}
			}
			if (delta > 0x3f) delta = 0x3f;
			return delta << 2;
		}
		else
		{
			int res;

			res = readinputport(1 + offset) & 0xf7;
			if (dir[offset]) res |= 0x08;

			return res;
		}
	}
	else
		return readinputport(1 + offset);
}

void block_dial_control_w(int offset,int data)
{
	if (data == 0x08)
	{
		/* reset the dial counters */
		dial[0] = readinputport(4);
		dial[1] = readinputport(5);
	}
	else if (data == 0x80)
		dial_selected = -1;
	else
		dial_selected = 1;
}



/***************************************************************************

  EEPROM

***************************************************************************/

static int eeprom_serial_count,eeprom_serial_buffer[26];
static UINT16 eeprom_data[0x40],eeprom_data_bits;

static int pang_port_5_r(int offset)
{
	int bit;

	bit = (eeprom_data_bits & 0x8000) >> 8;
	eeprom_data_bits = (eeprom_data_bits << 1) | 1;
	return (input_port_3_r(0) & 0x7f) | bit;
}

static void pang_eeprom_start_w(int offset,int data)
{
	static int last;

	if (!data && last) eeprom_serial_count = 0;

	last = data;
}

static void pang_eeprom_serial_w(int offset,int data)
{
	if (eeprom_serial_count < 26)
	{
		eeprom_serial_buffer[eeprom_serial_count++] = data;
		if (eeprom_serial_count == 10)
		{
			if (eeprom_serial_buffer[0] == 0x00 &&
					eeprom_serial_buffer[1] == 0xff &&
					eeprom_serial_buffer[2] == 0xff &&
					eeprom_serial_buffer[3] == 0x00)
			{
				int i,address;

				address = 0;
				for (i = 4;i < 10;i++)
				{
					address <<= 1;
					if (eeprom_serial_buffer[i]) address |= 1;
				}
				eeprom_data_bits = eeprom_data[address];
			}
		}
		else if (eeprom_serial_count == 26)
		{
			if (eeprom_serial_buffer[0] == 0x00 &&
					eeprom_serial_buffer[1] == 0xff &&
					eeprom_serial_buffer[2] == 0x00 &&
					eeprom_serial_buffer[3] == 0xff)
			{
				int i,address,edata;

				address = 0;
				for (i = 4;i < 10;i++)
				{
					address <<= 1;
					if (eeprom_serial_buffer[i]) address |= 1;
				}
				edata = 0;
				for (i = 10;i < 26;i++)
				{
					edata <<= 1;
					if (eeprom_serial_buffer[i]) edata |= 1;
				}
				eeprom_data[address] = edata;
			}
		}
	}
}

static int nvram_load(void)
{
	void *f;


	/* Try loading static RAM */
	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,0)) != 0)
	{
		osd_fread_msbfirst(f,eeprom_data,0x80);	/* EEPROM */
		osd_fclose(f);
	}
	/* Invalidate the static RAM to force reset to factory settings */
	else memset(eeprom_data,0xff,0x80);

	return 1;
}

static void nvram_save(void)
{
	void *f;


	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,1)) != 0)
	{
		osd_fwrite_msbfirst(f,eeprom_data,0x80);	/* EEPROM */
		osd_fclose(f);
	}
}

static int spang_nvram_load(void)
{
	void *f;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];


	/* Try loading static RAM */
	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,0)) != 0)
	{
		osd_fread_msbfirst(f,eeprom_data,0x80);	/* EEPROM */
		osd_fread(f,&RAM[0xe000],0x80);			/* NVRAM */
		osd_fclose(f);
	}
	/* Invalidate the static RAM to force reset to factory settings */
	else memset(eeprom_data,0xff,0x80);

	return 1;
}

static void spang_nvram_save(void)
{
	void *f;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];


	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,1)) != 0)
	{
		osd_fwrite_msbfirst(f,eeprom_data,0x80);	/* EEPROM */
		osd_fwrite(f,&RAM[0xe000],0x80);			/* NVRAM */
		osd_fclose(f);
	}
}

static int block_nvram_load(void)
{
	void *f;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];


	/* Try loading static RAM */
	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,0)) != 0)
	{
		osd_fread_msbfirst(f,eeprom_data,0x80);	/* EEPROM */
		osd_fread(f,&RAM[0xff80],0x80);			/* NVRAM */
		osd_fclose(f);
	}
	/* Invalidate the static RAM to force reset to factory settings */
	else memset(eeprom_data,0xff,0x80);

	return 1;
}

static void block_nvram_save(void)
{
	void *f;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];


	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_HIGHSCORE,1)) != 0)
	{
		osd_fwrite_msbfirst(f,eeprom_data,0x80);	/* EEPROM */
		osd_fwrite(f,&RAM[0xff80],0x80);			/* NVRAM */
		osd_fclose(f);
	}
}




/***************************************************************************

 Horrible bankswitch routine. Need to be able to read decrypted opcodes
 from ROM. There must be a better way than this.

***************************************************************************/

static void pang_bankswitch_w(int offset,int data)
{
	static int olddata=-1;

	if (data != olddata)
	{
		int bankaddress;
		unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];

		bankaddress = 0x10000 + (data & 0x0f) * 0x4000;

		memcpy(ROM+0x8000, ROM+bankaddress, 0x4000);
		memcpy(RAM+0x8000, RAM+bankaddress, 0x4000);
		olddata=data;
	}
}



/***************************************************************************

  Memory handlers

***************************************************************************/

static struct MemoryReadAddress readmem[] =
{
	{ 0x0000, 0xbfff, MRA_ROM },
	{ 0xc000, 0xc7ff, pang_paletteram_r },	/* Banked palette RAM */
	{ 0xc800, 0xcfff, pang_colorram_r },	/* Attribute RAM */
	{ 0xd000, 0xdfff, pang_videoram_r },	/* Banked char / OBJ RAM */
	{ 0xe000, 0xffff, MRA_RAM },	/* Work RAM */
	{ -1 }  /* end of table */
};

static struct MemoryWriteAddress writemem[] =
{
	{ 0x0000, 0xbfff, MWA_ROM },
	{ 0xc000, 0xc7ff, pang_paletteram_w },
	{ 0xc800, 0xcfff, pang_colorram_w, &pang_colorram, &pang_colorram_size },
	{ 0xd000, 0xdfff, pang_videoram_w, &pang_videoram, &pang_videoram_size },
	{ 0xe000, 0xffff, MWA_RAMROM },
	{ -1 }  /* end of table */
};

static struct IOReadPort readport[] =
{
	{ 0x00, 0x00, input_port_0_r },
	{ 0x01, 0x02, block_input_r },
	{ 0x05, 0x05, pang_port_5_r },
	{ -1 }  /* end of table */
};

static struct IOWritePort writeport[] =
{
	{ 0x00, 0x00, pang_palette_bank_w },    /* Palette bank */
	{ 0x01, 0x01, block_dial_control_w },
	{ 0x02, 0x02, pang_bankswitch_w },      /* Code bank register */
	{ 0x03, 0x03, YM2413_data_port_0_w },
	{ 0x04, 0x04, YM2413_register_port_0_w },
	{ 0x05, 0x05, OKIM6295_data_w },
	{ 0x06, 0x06, MWA_NOP },                /* Watchdog ? */
	{ 0x07, 0x07, pang_video_bank_w },      /* Video RAM bank register */
	{ 0x08, 0x08, pang_eeprom_start_w },
	{ 0x10, 0x10, MWA_NOP },	/* clocks the EEPROM, I think */
	{ 0x18, 0x18, pang_eeprom_serial_w },
	{ -1 }  /* end of table */
};



INPUT_PORTS_START( pang_input_ports )
	PORT_START      /* IN0 */
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )    /* probably unused */
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )    /* probably unused */
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )    /* probably unused */
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )

	PORT_START      /* IN1 */
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -