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

📄 dec0.c

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

Data East machine functions - Bryan McPhail, mish@tendril.force9.net

* Control reads, protection chip emulations & cycle skipping patches

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

#include "driver.h"
#include "M6502/m6502.h"

extern unsigned char *dec0_ram;
static int GAME,i8751_return;

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

int dec0_controls_read(int offset)
{
	switch (offset)
	{
		case 0: /* Player 1 & 2 joystick & buttons */
			return (readinputport(0) + (readinputport(1) << 8));

		case 2: /* Credits, start buttons */
			return readinputport(2);

		case 4: /* Byte 4: Dipswitch bank 2, Byte 5: Dipswitch Bank 1 */
			return (readinputport(3) + (readinputport(4) << 8));

		case 8: /* Intel 8751 mc, Bad Dudes & Heavy Barrel only */
			return i8751_return;
	}

	return 0xffff;
}

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

int dec0_rotary_read(int offset)
{
	switch (offset)
	{
		case 0: /* Player 1 rotary */
			return ~(1 << (readinputport(5) * 12 / 256));

		case 8: /* Player 2 rotary */
			return ~(1 << (readinputport(6) * 12 / 256));

		default:
			break;
	}

	return 0;
}

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

int midres_controls_read(int offset)
{
	switch (offset)
	{
		case 0: /* Player 1 Joystick + start, Player 2 Joystick + start */
			return (readinputport(0) + (readinputport(1) << 8));

		case 2: /* Dipswitches */
			return (readinputport(3) + (readinputport(4) << 8));

		case 4: /* Player 1 rotary */
			return ~(1 << (readinputport(5) * 12 / 256));

		case 6: /* Player 2 rotary */
			return ~(1 << (readinputport(6) * 12 / 256));

		case 8: /* Credits, start buttons */
			return readinputport(2);

		case 12:
			return 0;	/* ?? watchdog ?? */
	}

	return 0xffff;
}

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

int slyspy_controls_read(int offset)
{
	switch (offset)
	{
		case 0: /* Dip Switches */
			return (readinputport(3) + (readinputport(4) << 8));

		case 2: /* Player 1 & Player 2 joysticks & fire buttons */
			return (readinputport(0) + (readinputport(1) << 8));

		case 4: /* Credits */
			return readinputport(2);
	}

	return 0xffff;
}

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

#if 0
static int share[10];

int hippo_6510_intf_r(int offset)
{

	return share[offset];

	switch (offset) {
		case 4:
			return share[0];
		case 8:
			return 3;
		case 12:
			return share[12];	


	}

return 0;
}


void hippo_6510_intf_w(int offset,int data)
{
	share[offset]=data;

}
#endif

static int hippodrm_protection(int offset)
{
	switch (offset) {
    case 8: return 4;
    case 0x14: return 0; /* Unknown.. */
  	case 0x1c: return 4;
  }

  return 0; /* Keep zero */
}

extern void dec0_pf3_control_1_w(int offset,int data);
extern void dec0_pf3_control_0_w(int offset,int data);

extern void dec0_pf3_data_w(int offset,int data);
extern void dec0_pf2_data_w(int offset,int data);
extern void dec0_priority_w(int offset,int data);

void hippodrm_prot_w(int offset,int data)
{
	static int scroll,position,posdata;

	switch (offset) {

		case 0:
		case 0x14:
			return;

		case 0x2: /* Position of floating data window */
			position=data&0xf;
			return;

		case 0x4: /* Byte 5 is MSB of window data */
			posdata=((data&0xff)<<8)+(posdata&0xff);

			if (position<4)
				dec0_pf3_control_0_w(position<<1,posdata);
			else
				dec0_pf3_control_1_w((position-4)<<1,posdata);

			break;

		case 0x6: /* Byte 7 is LSB of window data */
			posdata=(posdata&0xff00)+(data&0xff);

			if (position<4)
				dec0_pf3_control_0_w(position<<1,posdata);
			else
				dec0_pf3_control_1_w((position-4)<<1,posdata);

			return;

		case 0x8:
		case 0x16:
		return;

		case 0x18: /* Scroll MSB, byte 0x19 */
			scroll=((data&0xff)<<8)+(scroll&0xff);
			dec0_pf3_control_1_w(0,scroll);
			return;

		case 0x1a: /* Scroll LSB, byte 0x1b */
			scroll=(scroll&0xff00)+(data&0xff);
			dec0_pf3_control_1_w(0,scroll);
			return;

	}

}

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

static void hbarrel_i8751_write(int data)
{
  static int level,state;

  int title[]={  1, 2, 5, 6, 9,10,13,14,17,18,21,22,25,26,29,30,33,34,37,38,41,42,0,
                 3, 4, 7, 8,11,12,15,16,19,20,23,24,27,28,31,32,35,36,39,40,43,44,0,
                45,46,49,50,53,54,57,58,61,62,65,66,69,70,73,74,77,78,81,82,0,
                47,48,51,52,55,56,59,60,63,64,67,68,71,72,75,76,79,80,83,84,0,
                85,86,89,90,93,94,97,98,101,102,105,106,109,110,113,114,117,118,121,122,125,126,0,
                87,88,91,92,95,96,99,100,103,104,107,108,111,112,115,116,119,120,123,124,127,128,0,
                129,130,133,134,137,138,141,142,145,146,149,150,153,154,157,158,161,162,165,166,169,170,173,174,0,
                131,132,135,136,139,140,143,144,147,148,151,152,155,156,159,160,163,164,167,168,171,172,175,176,0,
                177,178,0,179,180,-1
                };

	/* Unknown, initialise the variables? */
	if (data==0xb3b || data==0x500) i8751_return=level=0;

	/* Command 0x301 is written at end of each level */
	if (data==0x301) {level++;i8751_return=level;}

	/* 0x200 selects level */
	if (data==0x200) i8751_return=level;

	/* Protection */
	if (data==7) i8751_return=0xc000; /* Stack pointer */
	if (data==0x175) i8751_return=0x68b; /* Protection - USA version */
	if (data==0x174) i8751_return=0x68c; /* Protection - Japan version */

	/* Related to appearance & placement of special weapons */
	if (data>0x5ff && data<0x700) i8751_return=rand()%0xfff;

	/* All commands in range 4xx are related to title screen.. */
	if (data==0x4ff) state=0;
	if (data>0x3ff && data<0x4ff) {
		state++;

		if (title[state-1]==0) i8751_return=0xfffe;
		else if (title[state-1]==-1) i8751_return=0xffff;
		else i8751_return=title[state-1]+128+15+0x2000;

		/* We have to use a state as the microcontroller remembers previous commands */
	}

}

static void baddudes_i8751_write(int data)
{
	i8751_return=0;

	switch (data&0xffff) {
		case 0x714: i8751_return=0x700; break;
		case 0x73b: i8751_return=0x701; break;
		case 0x72c: i8751_return=0x702; break;
		case 0x73f: i8751_return=0x703; break;
		case 0x755: i8751_return=0x704; break;
		case 0x722: i8751_return=0x705; break;
		case 0x72b: i8751_return=0x706; break;
		case 0x724: i8751_return=0x707; break;
		case 0x728: i8751_return=0x708; break;
		case 0x735: i8751_return=0x709; break;
		case 0x71d: i8751_return=0x70a; break;
		case 0x721: i8751_return=0x70b; break;
		case 0x73e: i8751_return=0x70c; break;
		case 0x761: i8751_return=0x70d; break;
		case 0x753: i8751_return=0x70e; break;
		case 0x75b: i8751_return=0x70f; break;
	}

}

static void *i8751_timer;

static void i8751_callback(int param)
{
	/* Signal main cpu microcontroller task is complete */
	cpu_cause_interrupt(0,5);

	timer_remove(i8751_timer);
	i8751_timer=NULL;



}

void dec0_i8751_write(int data)
{
	/* Writes to this address cause an IRQ to the i8751 microcontroller */
	if (GAME==1) hbarrel_i8751_write(data);
	if (GAME==2) baddudes_i8751_write(data);

	cpu_cause_interrupt(0,5);


/* There is a timing problem in Heavy Barrel if the processing time is not
simulated - if the interrupt is triggered straight away then HB will reset
at the end of level one, the processing time needs to be at least the cycles
of a TST.W + BMI.S (ie, not very much at all).

See the code about 0xb60 (USA version)

*/

}

void dec0_i8751_reset(void)
{
	i8751_return=0;
}

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

static int hbarrel_cycle_r(int offset)
{
	if (cpu_getpc()==0x131a0) {cpu_spinuntil_int(); return 0;} return READ_WORD(&dec0_ram[0x10]);
}

static int hbarrelj_cycle_r(int offset)
{
	if (cpu_getpc()==0x130ca) {cpu_spinuntil_int(); return 0;} return READ_WORD(&dec0_ram[0x10]);
}

static int dude_skip(int offset)
{
	cpu_spinuntil_int();
	return READ_WORD(&dec0_ram[0x212]);
}

static int robocop_skip(int offset)
{
	int p=cpu_getpc();
	int result=READ_WORD(&dec0_ram[0x4]);

	if (p==0x17c8 || p==0x17f6) { cpu_spinuntil_int(); return result+1; }

	return result;
}

static int slyspy_skip(int offset)
{
	int result=READ_WORD(&dec0_ram[0x2018]);

	if (cpu_getpc()==0xe04 && !(result&0x100)) { cpu_spinuntil_int(); return (READ_WORD(&dec0_ram[0x2018]) | 0x0100); }
	return result;
}

static int midres_skip(int offset)
{
	if (cpu_getpc()==0x3a9c) cpu_spinuntil_int();
	return READ_WORD(&dec0_ram[0x207c]);
}

static void sprite_mirror(int offset, int data)
{
	extern unsigned char *spriteram;
	WRITE_WORD (&spriteram[offset], data);
}

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

static void hbarrel_custom_memory(void)
{
	install_mem_read_handler(0, 0xff8010, 0xff8011, hbarrel_cycle_r);
	GAME=1;

{ /* Remove this patch once processing time of i8751 is simulated */
unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];
WRITE_WORD (&RAM[0xb68],0x8008);
}
}

static void hbarrelj_custom_memory(void)
{
	install_mem_read_handler(0, 0xff8010, 0xff8011, hbarrelj_cycle_r);
	GAME=1;
{ /* Remove this patch once processing time of i8751 is simulated */
unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];
WRITE_WORD (&RAM[0xb3e],0x8008);
}
}

static void baddudes_custom_memory(void)
{
	install_mem_read_handler(0, 0xff8212, 0xff8213, dude_skip);
	GAME=2;
}

static void robocop_custom_memory(void)
{
	install_mem_read_handler(0, 0xff8004, 0xff8005, robocop_skip);
	install_mem_read_handler (0, 0x242800, 0x243fff, MRA_BANK3); /* Extra ram bank */
	install_mem_write_handler(0, 0x242800, 0x243fff, MWA_BANK3);
}

static void hippodrm_custom_memory(void)
{
	install_mem_read_handler(0, 0x180000, 0x180fff, hippodrm_protection);
	install_mem_write_handler(0, 0x180000, 0x180fff, hippodrm_prot_w);
	install_mem_write_handler(0, 0xffc800, 0xffcfff, sprite_mirror);
}

static void midres_custom_memory(void)
{
	install_mem_read_handler(0, 0x10207c, 0x10207d, midres_skip);
}

static void slyspy_custom_memory(void)
{
	install_mem_read_handler(0, 0x306018, 0x306019, slyspy_skip);
}

void dec0_custom_memory(void)
{
	GAME=0;
	i8751_timer=NULL;

	if (!strcmp(Machine->gamedrv->name,"hbarrel")) hbarrel_custom_memory();
	if (!strcmp(Machine->gamedrv->name,"hbarrelj")) hbarrelj_custom_memory();
	if (!strcmp(Machine->gamedrv->name,"baddudes")) baddudes_custom_memory();
	if (!strcmp(Machine->gamedrv->name,"drgninja")) baddudes_custom_memory();
	if (!strcmp(Machine->gamedrv->name,"robocopp")) robocop_custom_memory();
	if (!strcmp(Machine->gamedrv->name,"hippodrm")) hippodrm_custom_memory();
	if (!strcmp(Machine->gamedrv->name,"ffantasy")) hippodrm_custom_memory();
}

⌨️ 快捷键说明

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