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

📄 dec8.c

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

Various Data East 8 bit games:

	Cobra Command               (c) 1988 Data East Corporation (6809)
	The Real Ghostbusters (2p)  (c) 1987 Data East USA (6809 + I8751)
	The Real Ghostbusters (3p)  (c) 1987 Data East USA (6809 + I8751)
	Mazehunter                  (c) 1987 Data East Corporation (6809 + I8751)
	Super Real Darwin           (c) 1987 Data East Corporation (6809 + I8751)
	Psycho-Nics Oscar           (c) 1988 Data East USA (2*6809 + I8751)
	Psycho-Nics Oscar (Japan)   (c) 1987 Data East Corporation (2*6809 + I8751)
	Gondomania					(c) 1987 Data East USA (6809 + I8751)
	Mekyo Sensi					(c) 1987 Data East Corporation (6809 + I8751)
	Last Mission (rev 6)        (c) 1986 Data East USA (2*6809 + I8751)
	Last Mission (rev 5)        (c) 1986 Data East USA (2*6809 + I8751)
	Shackled                    (c) 1986 Data East USA (2*6809 + I8751)
    Breywood                    (c) 1986 Data East Corporation (2*6809 + I8751)
    Captain Silver (Japan)      (c) 1987 Data East Corporation (2*6809 + I8751)

	All games use a 6502 for sound (some are encrypted), all games except Cobracom
	use an Intel 8751 for protection & coinage.  For these games the coinage dip
	switch is not currently supported, they are fixed at 1 coin 1 credit.

	Emulation by Bryan McPhail, mish@tendril.force9.net

Recent fixes:
	Ghostbusters kludge removed
	Priority added to Oscar
	Oscar speed fixed.
	SRD fixed
	New games added

To do:
	Slight graphics glitches in Captain Silver, Breywood, Shackled.
	Weird cpu race condition in Last Mission.
	Support coinage options for all i8751 emulations.
	Captain Silver/Cobra Command probably have some sprite/playfield priorities
	Wrong sprite colours in Super Real Darwin
	Cobra Command probably has missing graphics later on in the game.
	Dips needed to be worked on several games

Emulation Notes:

* Dip switches confirmed for Oscar, Ghostbusters & Gondomania, the others seem reasonable.
* Maze Hunter is using Ghostbusters colour proms for now...
* Breywood sprites are not currently dumped, a Breywood Rev 2 rom set is known
to exist..

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

#include "driver.h"
#include "vidhrdw/generic.h"
#include "M6809/m6809.h"
#include "M6502/m6502.h"

int dec8_video_r(int offset);
void dec8_video_w(int offset, int data);
void dec8_pf1_w(int offset, int data);
void dec8_pf2_w(int offset, int data);
void dec8_scroll1_w(int offset, int data);
void dec8_scroll2_w(int offset, int data);
void dec8_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
void ghostb_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
void srdarwin_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
void gondo_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
void lastmiss_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
void oscar_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh);
int dec8_vh_start(void);
void dec8_vh_stop(void);


void srdarwin_control_w(int offset, int data);

void gondo_scroll_w(int offset, int data);

void lastmiss_control_w(int offset, int data);
void lastmiss_scrollx_w(int offset, int data);
void lastmiss_scrolly_w(int offset, int data);


void dec8_bac06_0_w(int offset, int data);
void dec8_bac06_1_w(int offset, int data);

void ghostb_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);

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

static unsigned char *dec8_shared_ram,*dec8_shared2_ram;
extern unsigned char *dec8_row;

static int nmi_enable,int_enable;
static int i8751_return, i8751_value;

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

static int i8751_h_r(int offset)
{
	return i8751_return>>8; /* MSB */
}

static int i8751_l_r(int offset)
{
	return i8751_return&0xff; /* LSB */
}

static void i8751_reset_w(int offset, int data)
{
	i8751_return=0;
}

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

static int gondo_player_1_r(int offset)
{
	switch (offset) {
		case 0: /* Rotary low byte */
			return ~((1 << (readinputport(5) * 12 / 256))&0xff);
		case 1: /* Joystick = bottom 4 bits, rotary = top 4 */
			return ((~((1 << (readinputport(5) * 12 / 256))>>4))&0xf0) | (readinputport(0)&0xf);
	}
	return 0xff;
}

static int gondo_player_2_r(int offset)
{
	switch (offset) {
		case 0: /* Rotary low byte */
			return ~((1 << (readinputport(6) * 12 / 256))&0xff);
		case 1: /* Joystick = bottom 4 bits, rotary = top 4 */
			return ((~((1 << (readinputport(6) * 12 / 256))>>4))&0xf0) | (readinputport(1)&0xf);
	}
	return 0xff;
}

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

static void ghostb_i8751_w(int offset, int data)
{
	i8751_return=0;

	switch (offset) {
	case 0: /* High byte */
		i8751_value=(i8751_value&0xff) | (data<<8);
		break;
	case 1: /* Low byte */
		i8751_value=(i8751_value&0xff00) | data;
		break;
	}

	if (i8751_value==0x00aa) i8751_return=0x655;
	if (i8751_value==0x021a) i8751_return=0x6e5; /* Ghostbusters ID */
	if (i8751_value==0x021b) i8751_return=0x6e4; /* Mazehunter ID */
}

static void srdarwin_i8751_w(int offset, int data)
{
	static int coins,latch;
	i8751_return=0;

	switch (offset) {
	case 0: /* High byte */
		i8751_value=(i8751_value&0xff) | (data<<8);
		break;
	case 1: /* Low byte */
		i8751_value=(i8751_value&0xff00) | data;
		break;
	}

	if (i8751_value==0x0000) {i8751_return=0;coins=0;}
	if (i8751_value==0x3063) i8751_return=0x9c; /* Protection */
	if ((i8751_value&0xff00)==0x4000) i8751_return=i8751_value; /* Coinage settings */
 	if (i8751_value==0x5000) i8751_return=coins; /* Coin request */
 	if (i8751_value==0x6000) {i8751_value=-1; coins--; } /* Coin clear */

	/* Nb:  Command 0x4000 for setting coinage options is not supported */

 	if ((readinputport(1)&1)==1) latch=1;
 	if ((readinputport(1)&1)!=1 && latch) {coins++; latch=0;}

	/* This next value is the index to a series of tables,
	each table controls the end of level bad guy, wrong values crash the
	cpu right away via a bogus jump.

	Level number requested is in low byte, I'm assuming the
	table values are stored in sequential order (ie, level 1 is the
	first table, level 2 is the second, etc).

	See location 0xf580 in rom dy_01.rom

	A real board would be nice to check against :)

	*/
	if ((i8751_value&0xff00)==0x8000)
		i8751_return=0xf580 + ((i8751_value&0xff)*2);
}

static void gondo_i8751_w(int offset, int data)
{
	static int coin1,coin2,latch,snd;
	i8751_return=0;

	switch (offset) {
	case 0: /* High byte */
		i8751_value=(i8751_value&0xff) | (data<<8);
		if (int_enable) cpu_cause_interrupt (0, M6809_INT_IRQ); /* IRQ on *high* byte only */
		break;
	case 1: /* Low byte */
		i8751_value=(i8751_value&0xff00) | data;
		break;
	}

	/* Coins are controlled by the i8751 */
 	if ((readinputport(4)&3)==3) latch=1;
 	if ((readinputport(4)&1)!=1 && latch) {coin1++; snd=1; latch=0;}
 	if ((readinputport(4)&2)!=2 && latch) {coin2++; snd=1; latch=0;}

	/* Work out return values */
	if (i8751_value==0x0000) {i8751_return=0; coin1=coin2=snd=0;}
	if (i8751_value==0x038a)  i8751_return=0x375; /* Mekyo Sensi ID */
	if (i8751_value==0x038b)  i8751_return=0x374; /* Gondomania ID */
	if ((i8751_value>>8)==0x04)  i8751_return=0x40f; /* Coinage settings (Not supported) */
	if ((i8751_value>>8)==0x05) {i8751_return=0x500 | coin1;  } /* Coin 1 */
	if ((i8751_value>>8)==0x06 && coin1 && !offset) {i8751_return=0x600; coin1--; } /* Coin 1 clear */
	if ((i8751_value>>8)==0x07) {i8751_return=0x700 | coin2;  } /* Coin 2 */
	if ((i8751_value>>8)==0x08 && coin2 && !offset) {i8751_return=0x800; coin2--; } /* Coin 2 clear */
	/* Commands 0x9xx do nothing */
	if ((i8751_value>>8)==0x0a) {i8751_return=0xa00 | snd; if (snd) snd=0; }
}

static void shackled_i8751_w(int offset, int data)
{
	static int coin1,coin2,latch=0;
	i8751_return=0;

	switch (offset) {
	case 0: /* High byte */
		i8751_value=(i8751_value&0xff) | (data<<8);
		cpu_cause_interrupt (1, M6809_INT_FIRQ); /* Signal main cpu */
		break;
	case 1: /* Low byte */
		i8751_value=(i8751_value&0xff00) | data;
		break;
	}

	/* Coins are controlled by the i8751 */
 	if (/*(readinputport(2)&3)==3*/!latch) {latch=1;coin1=coin2=0;}
 	if ((readinputport(2)&1)!=1 && latch) {coin1=1; latch=0;}
 	if ((readinputport(2)&2)!=2 && latch) {coin2=1; latch=0;}

	if (i8751_value==0x0050) i8751_return=0; /* Breywood ID */
	if (i8751_value==0x0051) i8751_return=0; /* Shackled ID */
	if (i8751_value==0x0102) i8751_return=0; /* ?? */
	if (i8751_value==0x0101) i8751_return=0; /* ?? */
	if (i8751_value==0x8101) i8751_return=coin2 | (coin1<<8); /* Coins */
}

static void lastmiss_i8751_w(int offset, int data)
{
	static int coin,latch=0,snd;
	i8751_return=0;

	switch (offset) {
	case 0: /* High byte */
		i8751_value=(i8751_value&0xff) | (data<<8);
		cpu_cause_interrupt (0, M6809_INT_FIRQ); /* Signal main cpu */
		break;
	case 1: /* Low byte */
		i8751_value=(i8751_value&0xff00) | data;
		break;
	}

	/* Coins are controlled by the i8751 */
 	if ((readinputport(2)&3)==3 && !latch) latch=1;
 	if ((readinputport(2)&3)!=3 && latch) {coin++; latch=0;snd=0x400;}

	if (i8751_value==0x007b) i8751_return=0x0184; 
	if (i8751_value==0x0000) {i8751_return=0x0184; coin=snd=0;}
	if (i8751_value==0x0401) i8751_return=0x0184; 
	if ((i8751_value>>8)==0x01) i8751_return=0x0184; /* Coinage setup */
	if ((i8751_value>>8)==0x02) {i8751_return=snd | coin; snd=0;} /* Coin return */
	if ((i8751_value>>8)==0x03) {i8751_return=0; coin--; } /* Coin clear */
}

static void csilver_i8751_w(int offset, int data)
{
	static int coin,latch=0,snd;
	i8751_return=0;

	switch (offset) {
	case 0: /* High byte */
		i8751_value=(i8751_value&0xff) | (data<<8);
		cpu_cause_interrupt (0, M6809_INT_FIRQ); /* Signal main cpu */
		break;
	case 1: /* Low byte */
		i8751_value=(i8751_value&0xff00) | data;
		break;
	}

	/* Coins are controlled by the i8751 */
 	if ((readinputport(2)&3)==3 && !latch) latch=1;
 	if ((readinputport(2)&3)!=3 && latch) {coin++; latch=0;snd=0x1200;}

	if (i8751_value==0x054a) {i8751_return=~(0x4a); coin=0; snd=0;} /* Captain Silver ID */
	if ((i8751_value>>8)==0x01) i8751_return=0; /* Coinage - Not Supported */
	if ((i8751_value>>8)==0x02) {i8751_return=snd | coin; snd=0; } /* Coin Return */
	if (i8751_value==0x0003 && coin) {i8751_return=0; coin--;} /* Coin Clear */
/* Todo:  Coin insert sound doesn't seem to work...*/
}

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

static void dec8_bank_w(int offset, int data)
{
 	int bankaddress;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];

	bankaddress = 0x10000 + (data & 0x0f) * 0x4000;
	cpu_setbank(1,&RAM[bankaddress]);
}

/* Used by Ghostbusters, Mazehunter & Gondomania */
static void ghostb_bank_w(int offset, int data)
{
 	int bankaddress;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];

	/* Bit 0: Interrupt enable/disable (I think..)
	   Bit 1: NMI enable/disable
	   Bit 2: ??
	   Bit 3: Screen flip (not supported)
	   Bits 4-7: Bank switch
	*/

	bankaddress = 0x10000 + (data >> 4) * 0x4000;
	cpu_setbank(1,&RAM[bankaddress]);

	if (data&1) int_enable=1; else int_enable=0;
	if (data&2) nmi_enable=1; else nmi_enable=0;


}

void csilver_control_w(int offset, int data)
{
	int bankaddress;
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];

	/* Bottom 4 bits - bank switch */
	bankaddress = 0x10000 + (data & 0x0f) * 0x4000;
	cpu_setbank(1,&RAM[bankaddress]);

	/* There are unknown bits in the top half of the byte! */
 
}

static void dec8_sound_w(int offset, int data)
{
 	soundlatch_w(0,data);
	cpu_cause_interrupt(1,M6502_INT_NMI);
}

static void oscar_sound_w(int offset, int data)
{
 	soundlatch_w(0,data);
	cpu_cause_interrupt(2,M6502_INT_NMI);
}

static void csilver_adpcm_int(int data)
{
	static int toggle;

	toggle = 1 - toggle;
	if (toggle)
		cpu_cause_interrupt(2,M6502_INT_IRQ);
}

static int csilver_adpcm_reset_r(int offset)
{
	MSM5205_reset_w(0,0);
	return 0;
}

static void csilver_adpcm_data_w(int offset,int data)
{
	MSM5205_data_w(offset,data >> 4);
	MSM5205_data_w(offset,data);
}

static void csilver_sound_bank_w(int offset,int data)
{
	unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[2].memory_region];

	if (data&8) { cpu_setbank(3,&RAM[0x14000]); }

⌨️ 快捷键说明

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