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

📄 rthunder.c

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

To Do:
-----
Further optimize video (skip transparent/obscured tiles)
Add voice (see note below)
Add flipped and cocktail cabinet mode


Notes:
-----
PCM roms sample tables:
At the beggining of each PCM sound ROM you can find a 2 byte
offset to the beggining of each sample in the rom. Since the
table is not in sequential order, it is possible that the order
of the table is actually the sound number. Each sample ends in
a 0xff mark.

We MIGHT be missing a 512 bytes sound prom for the PSG. Im using
a generic one. Maybe 'rt1-5.bin' is the one but it has been incorrectly
dumped?. The game uses more than 1 wave for sure.

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

#include "driver.h"
#include "m6809/m6809.h"
#include "m6808/m6808.h"

extern unsigned char *videoram, *spriteram, *dirtybuffer;

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

extern void rthunder_vh_convert_color_prom(	unsigned char *palette, unsigned short *colortable,
	const unsigned char *color_prom);
extern int rthunder_vh_start( void );
extern void rthunder_vh_stop( void );
extern void rthunder_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh );
extern void rthunder_scroll_w( int layer, int offset, int data );
extern void rthunder_tilebank_w( int offset, int data );

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

#define MEM_CPU1		0
#define MEM_DATA1		1

#define MEM_CPU2		2
#define MEM_DATA2		3

#define MEM_GFX_TILES	4
#define MEM_GFX_SPRITES	5
#define MEM_COLOR		6
#define MEM_MCU			7

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

/* You can turn on/off cycle skipping in the next line */
#define CYCLE_SKIP 1

#if CYCLE_SKIP
static int cpu0_skip_r( int offs ) {

	if ( spriteram[0x126f] == spriteram[0x126e] && cpu_getpc() == 0xd64c ) {
		if ( spriteram[0x12b4] == spriteram[0x12b3] ) {
			cpu_spinuntil_int();
		}
	}

	return spriteram[0x126f];
}

static int cpu1_skip_r( int offs ) {

	if ( spriteram[0x1268] == spriteram[0x1267] && cpu_getpc() == 0xb0c1 )
		cpu_spinuntil_int();

	return spriteram[0x1268];
}
#endif

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

/* play voice sample */
static int voice[2];

static void namco_voice0_play_w( int offset, int data ) {
}

static void namco_voice0_select_w( int offset, int data ) {
}

static void namco_voice1_play_w( int offset, int data ) {
}

static void namco_voice1_select_w( int offset, int data ) {
}

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

/* shared memory area with the mcu */
static unsigned char *shared;
static int shared_r( int offs ) { return shared[offs]; }
static void shared_w( int offs, int data ) { shared[offs] = data; }

/*
	each layer has its own pair of scroll registers, but in practice
	layers 0,1,2 scroll together, while layer3 is fixed
*/
static void scroll0_w( int offset, int data ){ rthunder_scroll_w( 0, offset, data ); }
static void scroll1_w( int offset, int data ){ rthunder_scroll_w( 1, offset, data ); }
static void scroll2_w( int offset, int data ){ rthunder_scroll_w( 2, offset, data ); }
static void scroll3_w( int offset, int data ){ rthunder_scroll_w( 3, offset, data ); }

static void videoram_w( int offset, int data ){
	videoram[offset] = data;
	dirtybuffer[offset/2] = 1;
}
static int videoram_r( int offset ){
	return videoram[offset];
}
static void spriteram_w( int offset, int data ){
	spriteram[offset] = data;
}
static int spriteram_r( int offset ){
	return spriteram[offset];
}

static void bankswitch1_w( int offset, int data ){
	unsigned char *base = Machine->memory_region[MEM_DATA1];
	cpu_setbank( 1, base + ((data&0x1f)*0x2000) );
}

static void bankswitch2_w( int offset, int data ){
	unsigned char *base = Machine->memory_region[MEM_DATA2];
	cpu_setbank( 2, base + ((data&0x03)*0x2000) );
}

/* Stubs to pass the correct Dip Switch setup to the MCU */
static int dsw_r0( int offset ) {
	int rhi, rlo;

	rhi = ( readinputport( 2 ) & 0x01 ) << 4;
	rhi |= ( readinputport( 2 ) & 0x04 ) << 3;
	rhi |= ( readinputport( 2 ) & 0x10 ) << 2;
	rhi |= ( readinputport( 2 ) & 0x40 ) << 1;

	rlo = ( readinputport( 3 ) & 0x01 );
	rlo |= ( readinputport( 3 ) & 0x04 ) >> 1;
	rlo |= ( readinputport( 3 ) & 0x10 ) >> 2;
	rlo |= ( readinputport( 3 ) & 0x40 ) >> 3;

	return ~( rhi | rlo ); /* Active Low */
}

static int dsw_r1( int offset ) {
	int rhi, rlo;

	rhi = ( readinputport( 2 ) & 0x02 ) << 3;
	rhi |= ( readinputport( 2 ) & 0x08 ) << 2;
	rhi |= ( readinputport( 2 ) & 0x20 ) << 1;
	rhi |= ( readinputport( 2 ) & 0x80 );

	rlo = ( readinputport( 3 ) & 0x02 ) >> 1;
	rlo |= ( readinputport( 3 ) & 0x08 ) >> 2;
	rlo |= ( readinputport( 3 ) & 0x20 ) >> 3;
	rlo |= ( readinputport( 3 ) & 0x80 ) >> 4;

	return ~( rhi | rlo ); /* Active Low */
}

static int int_enabled[2];

static void int_enable_w( int offs, int data ) {
	int cpu = cpu_getactivecpu();

	int_enabled[cpu] = 1;
}

static void *rt_timer = 0;
static unsigned char *hd_regs;

static void rt_timer_proc( int param )
{
	rt_timer = 0;

	/* update current time with compare time */
	hd_regs[0x09] = hd_regs[0x0b];
	hd_regs[0x0a] = hd_regs[0x0c];

	if ( hd_regs[0x08] & 8 )
		cpu_cause_interrupt( 2, M6808_INT_OCI );
}

void rt_stop_mcu_timer( void ) {
	if ( rt_timer ) {
		timer_remove( rt_timer );
		rt_timer = 0;
	}
}

static void rt_start_mcu_timer( void )
{
	int total_time, current_time;

	current_time = ( hd_regs[0x09] << 8 ) | hd_regs[0x0a];
	total_time = ( hd_regs[0x0b] << 8 ) | hd_regs[0x0c];

	total_time = ( total_time - current_time );

	total_time &= 0xffff;

	if ( rt_timer )
		timer_remove( rt_timer );

	rt_timer = timer_set( TIME_IN_USEC( total_time ), 0, rt_timer_proc );
}

static int hd_regs_r( int offset )
{
	if ( offset == 0x02 ) 
		return readinputport( 4 );
	return hd_regs[offset];
}

static void hd_regs_w( int offset, int data )
{
	hd_regs[offset] = data;

	if ( offset == 0x0c || offset == 0x0a )	
		rt_start_mcu_timer();
}

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

static struct MemoryReadAddress readmem1[] = {
	{ 0x0000, 0x3fff, MRA_RAM, &videoram },
	{ 0x4000, 0x43ff, shared_r, &shared },

#if CYCLE_SKIP
	{ 0x566f, 0x566f, cpu0_skip_r },
#endif

	{ 0x4400, 0x5fff, spriteram_r, &spriteram },
	{ 0x6000, 0x7fff, MRA_BANK1 },
	{ 0x8000, 0xffff, MRA_ROM },
	{ -1 }
};

static struct MemoryWriteAddress writemem1[] = {
	{ 0x0000, 0x3fff, videoram_w },
	{ 0x4000, 0x43ff, shared_w },
	{ 0x4400, 0x5fff, spriteram_w },

	{ 0x6000, 0x6000, namco_voice0_play_w },
	{ 0x6200, 0x6200, namco_voice0_select_w },
	{ 0x6400, 0x6400, namco_voice1_play_w },
	{ 0x6600, 0x6600, namco_voice1_select_w },
	{ 0x6800, 0x6800, bankswitch1_w },

	{ 0x6c00, 0x6c00, MWA_NOP }, /* written once on startup */
	{ 0x6e00, 0x6e00, MWA_NOP }, /* written once on startup */

	{ 0x8000, 0x8000, watchdog_reset_w }, /* watchdog */
	{ 0x8400, 0x8400, int_enable_w }, /* written when CPU1 is done its interrupt routine */

	{ 0x8800, 0x8800, rthunder_tilebank_w },
	{ 0x8c00, 0x8c00, rthunder_tilebank_w },

	{ 0x9000, 0x9002, scroll0_w },
	{ 0x9004, 0x9006, scroll1_w },
	{ 0x9400, 0x9402, scroll2_w },
	{ 0x9404, 0x9406, scroll3_w },

	{ 0xa000, 0xa000, MWA_NOP }, /* Looks like IRQ trigger on MCU */
								 /* but that fucks up entering test mode */
	{ 0x8000, 0xffff, MWA_ROM },
	{ -1 }
};

static struct MemoryReadAddress readmem2[] = {
	{ 0x0000, 0x03ff, MRA_RAM },

#if CYCLE_SKIP
	{ 0x1668, 0x1668, cpu1_skip_r },
#endif

	{ 0x0400, 0x1fff, spriteram_r },
	{ 0x2000, 0x5fff, videoram_r },
	{ 0x6000, 0x7fff, MRA_BANK2 },
	{ 0x8000, 0xffff, MRA_ROM },
	{ -1 }
};

static struct MemoryWriteAddress writemem2[] = {
	{ 0x0000, 0x03ff, MWA_RAM },
	{ 0x0400, 0x1fff, spriteram_w },
	{ 0x2000, 0x5fff, videoram_w },
	{ 0xd803, 0xd803, bankswitch2_w },
	{ 0x8000, 0x8000, watchdog_reset_w }, /* watchdog */
	{ 0x8800, 0x8800, int_enable_w },	/* written when CPU2 is done its interrupt */
	{ 0x8000, 0xffff, MWA_ROM },
	{ -1 }
};

static struct MemoryReadAddress mcu_readmem[] =
{
	{ 0x0000, 0x0027, hd_regs_r },
	{ 0x0028, 0x013f, MRA_RAM },
	{ 0x12c8, 0x1307, namcos1_sound_r }, /* PSG device */
	{ 0x1000, 0x13ff, shared_r },
	{ 0x1400, 0x1fff, MRA_RAM },
	{ 0x2000, 0x2001, YM2151_status_port_0_r },
	{ 0x2020, 0x2020, input_port_0_r },
	{ 0x2021, 0x2021, input_port_1_r },
	{ 0x2030, 0x2030, dsw_r0 },
	{ 0x2031, 0x2031, dsw_r1 },
	{ 0x4000, 0xbfff, MRA_ROM },
	{ 0xf000, 0xffff, MRA_ROM },
	{ -1 }	/* end of table */
};

static struct MemoryWriteAddress mcu_writemem[] =
{
	{ 0x0000, 0x0027, hd_regs_w, &hd_regs },
	{ 0x0028, 0x013f, MWA_RAM },
	{ 0x12c8, 0x1307, namcos1_sound_w }, /* PSG device */

⌨️ 快捷键说明

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