示例#1
0
static void jchan_mcu_run(running_machine *machine)
{
	UINT16 mcu_command = mcu_ram[0x0010/2];		/* command nb */
	UINT16 mcu_offset  = mcu_ram[0x0012/2] / 2;	/* offset in shared RAM where MCU will write */
	UINT16 mcu_subcmd  = mcu_ram[0x0014/2];		/* sub-command parameter, happens only for command #4 */

	logerror("%s : MCU executed command: %04X %04X %04X ",cpuexec_describe_context(machine),mcu_command,mcu_offset*2,mcu_subcmd);

/*
    the only MCU commands found in program code are:
    - 0x04: protection: provide data (see below) and code
    - 0x03: read DSW
    - 0x02: load game settings \ stored in ATMEL AT93C46 chip,
    - 0x42: save game settings / 128 bytes serial EEPROM
*/

	switch (mcu_command >> 8)
	{
		case 0x04: /* Protection: during self-test for mcu_subcmd = 0x3d, 0x3e, 0x3f */
		{
			 toxboy_handle_04_subcommand(machine,mcu_subcmd,mcu_ram);
		}
		break;

		case 0x03:	// DSW
		{
			mcu_ram[mcu_offset] = input_port_read(machine, "DSW");
			logerror("%s : MCU executed command: %04X %04X (read DSW)\n",cpuexec_describe_context(machine),mcu_command,mcu_offset*2);
		}
		break;

		case 0x02: /* load game settings from 93C46 EEPROM ($1090-$10dc) */
		{
			mame_file *f;
			if ((f = nvram_fopen(machine, OPEN_FLAG_READ)) != 0)
			{
				mame_fread(f,&mcu_ram[mcu_offset], 128);
				mame_fclose(f);
			}
			logerror("(load NVRAM settings)\n");
		}
		break;

		case 0x42: /* save game settings to 93C46 EEPROM ($50d4) */
		{
			mame_file *f;
			if ((f = nvram_fopen(machine, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)) != 0)
			{
				mame_fwrite(f,&mcu_ram[mcu_offset], 128);
				mame_fclose(f);
			}
			logerror("(save NVRAM settings)\n");
		}
		break;

		default:
			logerror("- UNKNOWN COMMAND!!!\n");
	}
}
示例#2
0
/* read status port */
static int I8741_status_r(const address_space *space, int num)
{
	I8741 *st = &taito8741[num];
	taito8741_update(space, num);
	LOG(("%s:8741-%d ST Read %02x\n",cpuexec_describe_context(space->machine),num,st->status));
	return st->status;
}
示例#3
0
/* Write command port */
static void I8741_command_w(const address_space *space, int num, int data)
{
	I8741 *st = &taito8741[num];
	LOG(("%s:8741-%d CMD Write %02x\n",cpuexec_describe_context(space->machine),num,data));
	st->fromCmd = data;
	st->status |= 0x04;
	/* update chip */
	taito8741_update(space,num);
}
示例#4
0
INLINE void update_irqstate(running_device *device)
{
    riot6532_state *riot = get_safe_token(device);
    int state = (riot->irqstate & riot->irqenable);

    if (riot->irq_func.write != NULL)
        devcb_call_write_line(&riot->irq_func, (state != 0) ? ASSERT_LINE : CLEAR_LINE);
    else
        logerror("%s:6532RIOT chip #%d: no irq callback function\n", cpuexec_describe_context(device->machine), riot->index);
}
示例#5
0
static READ8_DEVICE_HANDLER( dunhuang_dsw_r )
{
	if (!(dunhuang_input & 0x01))	return input_port_read(device->machine, "DSW1");
	if (!(dunhuang_input & 0x02))	return input_port_read(device->machine, "DSW2");
	if (!(dunhuang_input & 0x04))	return input_port_read(device->machine, "DSW3");
	if (!(dunhuang_input & 0x08))	return input_port_read(device->machine, "DSW4");
	if (!(dunhuang_input & 0x10))	return input_port_read(device->machine, "DSW5");
	logerror("%s: warning, unknown dsw bits read, dunhuang_input = %02x\n", cpuexec_describe_context(device->machine), dunhuang_input);
	return 0xff;
}
示例#6
0
static READ8_HANDLER( dunhuang_input_r )
{
	if (!(dunhuang_input & 0x01))	return input_port_read(space->machine, "IN0");
	if (!(dunhuang_input & 0x02))	return input_port_read(space->machine, "IN1");
	if (!(dunhuang_input & 0x04))	return input_port_read(space->machine, "IN2");
	if (!(dunhuang_input & 0x08))	return input_port_read(space->machine, "IN3");
	if (!(dunhuang_input & 0x10))	return input_port_read(space->machine, "IN4");
	logerror("%s: warning, unknown input bits read, dunhuang_input = %02x\n", cpuexec_describe_context(space->machine), dunhuang_input);
	return 0xff;
}
示例#7
0
INPUT_PORTS_END

static READ8_DEVICE_HANDLER(dips1_r)
{
	switch(bmc_input)
	{
			case 0x00:	return  input_port_read(device->machine, "IN1");
			case 0x40:	return  input_port_read(device->machine, "IN2");
	}
	logerror("%s:unknown input - %X\n",cpuexec_describe_context(device->machine),bmc_input);
	return 0xff;
}
示例#8
0
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... )
{
    if( VERBOSE_LEVEL >= n_level )
    {
        va_list v;
        char buf[ 32768 ];
        va_start( v, s_fmt );
        vsprintf( buf, s_fmt, v );
        va_end( v );
        logerror( "%s: %s", cpuexec_describe_context(machine), buf );
    }
}
示例#9
0
static INT8 josvolly_8741_r(const address_space *space,int num,int offset)
{
	JV8741 *mcu = &i8741[num];
	int ret;

	if(offset==1)
	{
		if(mcu->rst)
			mcu->rxd = input_port_read(space->machine, mcu->initReadPort); /* port in */
		ret = mcu->sts;
		LOG(("%s:8741[%d]       SR %02X\n",cpuexec_describe_context(space->machine),num,ret));
	}
	else
	{
		/* clear status port */
		mcu->sts &= ~0x01; /* RD ready */
		ret = mcu->rxd;
		LOG(("%s:8741[%d]       DR %02X\n",cpuexec_describe_context(space->machine),num,ret));
		mcu->rst = 0;
	}
	return ret;
}
示例#10
0
static CUSTOM_INPUT( pc3092_r )
{
	UINT32 ret;

	/* enable coin & start input? Wild guess!!! */
	if (pc3092_data[1] & 0x02)
		ret = input_port_read(field->port->machine, "PC3092");
	else
		ret = 0x00;

	if (LOG_PC3092) logerror("%s:  read  PC3092 = 0x%02x\n", cpuexec_describe_context(field->port->machine), ret);

	return ret;
}
示例#11
0
void via6522_device::set_int(int data)
{
	m_ifr |= data;
	if (TRACE_VIA)
    {
		logerror("%s:6522VIA chip %s: IFR = %02X\n", cpuexec_describe_context(&m_machine), tag(), m_ifr);
    }

	if (m_ier & m_ifr)
    {
		m_ifr |= INT_ANY;
		devcb_call_write_line(&m_irq_func, ASSERT_LINE);
    }
}
示例#12
0
static void scsidev_write_data( SCSIInstance *scsiInstance, UINT8 *data, int dataLength )
{
	UINT8 *command;
	int commandLength;
//  SCSIDev *our_this = (SCSIDev *)SCSIThis( &SCSIClassDevice, scsiInstance );
	SCSIGetCommand( scsiInstance, &command, &commandLength );

	switch( command[ 0 ] )
	{
		default:
			logerror( "%s: SCSIDEV unknown write %02x\n", cpuexec_describe_context(scsiInstance->machine), command[ 0 ] );
			break;
	}
}
示例#13
0
static READ8_DEVICE_HANDLER( scramble_protection_r )
{
	switch (cpu_get_pc(devtag_get_device(device->machine, "maincpu")))
	{
	case 0x00a8: return 0xf0;
	case 0x00be: return 0xb0;
	case 0x0c1d: return 0xf0;
	case 0x0c6a: return 0xb0;
	case 0x0ceb: return 0x40;
	case 0x0d37: return 0x60;
	case 0x1ca2: return 0x00;  /* I don't think it's checked */
	case 0x1d7e: return 0xb0;
	default:
		logerror("%s: read protection\n",cpuexec_describe_context(device->machine));
		return 0;
	}
}
示例#14
0
static int scsidev_exec_command( SCSIInstance *scsiInstance, UINT8 *statusCode )
{
	UINT8 *command;
	int commandLength;
//  SCSIDev *our_this = (SCSIDev *)SCSIThis( &SCSIClassDevice, scsiInstance );
	SCSIGetCommand( scsiInstance, &command, &commandLength );

	switch( command[ 0 ] )
	{
		case 0x00: // TEST UNIT READY
			SCSISetPhase( scsiInstance, SCSI_PHASE_STATUS );
			return 0;

		default:
			logerror( "%s: SCSIDEV unknown command %02x\n", cpuexec_describe_context(scsiInstance->machine), command[ 0 ] );
			return 0;
	}
}
示例#15
0
void via6522_device::clear_int(int data)
{
	m_ifr = (m_ifr & ~data) & 0x7f;

	if (TRACE_VIA)
    {
		logerror("%s:6522VIA chip %s: IFR = %02X\n", cpuexec_describe_context(&m_machine), tag(), m_ifr);
    }

	if (m_ifr & m_ier)
    {
		m_ifr |= INT_ANY;
    }
	else
	{
		devcb_call_write_line(&m_irq_func, CLEAR_LINE);
	}
}
示例#16
0
/* read data port */
static int I8741_data_r(const address_space *space, int num)
{
	I8741 *st = &taito8741[num];
	int ret = st->toData;
	st->status &= 0xfe;
	LOG(("%s:8741-%d DATA Read %02x\n",cpuexec_describe_context(space->machine),num,ret));

	/* update chip */
	taito8741_update(space, num);

	switch( st->mode )
	{
	case TAITO8741_PORT: /* parallel data */
		taito8741_hostdata_w(st,st->portHandler ? st->portHandler(space, st->parallelselect) : st->portName ? input_port_read(space->machine, st->portName) : 0);
		break;
	}
	return ret;
}
示例#17
0
static WRITE8_DEVICE_HANDLER( zaccaria_dsw_sel_w )
{
	switch (data & 0xf0)
	{
		case 0xe0:
			dsw = 0;
			break;

		case 0xd0:
			dsw = 1;
			break;

		case 0xb0:
			dsw = 2;
			break;

		default:
			logerror("%s: portsel = %02x\n", cpuexec_describe_context(device->machine), data);
			break;
	}
}
示例#18
0
文件: dc.c 项目: nitrologic/emu
// this accepts only 32-bit accesses
INLINE int decode_reg32_64(running_machine *machine, UINT32 offset, UINT64 mem_mask, UINT64 *shift)
{
	int reg = offset * 2;

	*shift = 0;

	// non 32-bit accesses have not yet been seen here, we need to know when they are
	if ((mem_mask != U64(0xffffffff00000000)) && (mem_mask != U64(0x00000000ffffffff)))
	{
		mame_printf_verbose("%s:Wrong mask!\n", cpuexec_describe_context(machine));
//      debugger_break(machine);
	}

	if (mem_mask == U64(0xffffffff00000000))
	{
		reg++;
		*shift = 32;
 	}

	return reg;
}
示例#19
0
static READ8_DEVICE_HANDLER( r6532_porta_r )
{
	if (has_tms5220)
	{
		running_device *tms = devtag_get_device(device->machine, "tms");
		logerror("(%f)%s:TMS5220 status read = %02X\n", attotime_to_double(timer_get_time(device->machine)), cpuexec_describe_context(device->machine), tms5220_status_r(tms, 0));
		return tms5220_status_r(tms, 0);
	}
	else
		return 0xff;
}
示例#20
0
static WRITE8_DEVICE_HANDLER( paradise_okibank_w )
{
	if (data & ~0x02)	logerror("%s: unknown oki bank bits %02X\n",cpuexec_describe_context(device->machine),data);

	okim6295_set_bank_base(device, (data & 0x02) ? 0x40000 : 0);
}
示例#21
0
static WRITE8_DEVICE_HANDLER( galpani2_oki2_bank_w )
{
		okim6295_device *oki = downcast<okim6295_device *>(device);
		oki->set_bank_base(0x40000 * (data & 0xf) );
		logerror("%s : %s bank %08X\n",cpuexec_describe_context(device->machine),device->tag(),data);
}
示例#22
0
static WRITE8_DEVICE_HANDLER( galpani2_oki1_bank_w )
{
		UINT8 *ROM = memory_region(device->machine, "oki1");
		logerror("%s : %s bank %08X\n",cpuexec_describe_context(device->machine),device->tag(),data);
		memcpy(ROM + 0x30000, ROM + 0x40000 + 0x10000 * (~data & 0xf), 0x10000);
}
示例#23
0
static void galpani2_mcu_nmi1(running_machine *machine)
{
	const address_space *srcspace = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
	const address_space *dstspace = cputag_get_address_space(machine, "sub", ADDRESS_SPACE_PROGRAM);
	UINT32 mcu_list, mcu_command, mcu_address, mcu_extra, mcu_src, mcu_dst, mcu_size;

	for ( mcu_list = 0x100021; mcu_list < (0x100021 + 0x40); mcu_list += 4 )
	{
		mcu_command		=	memory_read_byte(srcspace, mcu_list);

		mcu_address		=	0x100000 +
							(memory_read_byte(srcspace, mcu_list + 1)<<8) +
							(memory_read_byte(srcspace, mcu_list + 2)<<0) ;

		mcu_extra		=	memory_read_byte(srcspace, mcu_list + 3); //0xff for command $A and $2, 0x02 for others

		if (mcu_command != 0)
		{
			logerror("%s : MCU [$%06X] endidx = $%02X / command = $%02X addr = $%04X ? = $%02X.\n",
			cpuexec_describe_context(machine),
			mcu_list,
			memory_read_byte(srcspace, 0x100020),
			mcu_command,
			mcu_address,
			mcu_extra
			);
		}

		switch (mcu_command)
		{
		case 0x00:
			break;

		case 0x02: //Copy N bytes from RAM2 to RAM1?, gp2se is the only one to use it, often!
			mcu_src		=	(memory_read_byte(srcspace, mcu_address + 2)<<8) +
							(memory_read_byte(srcspace, mcu_address + 3)<<0) ;

			mcu_dst		=	(memory_read_byte(srcspace, mcu_address + 6)<<8) +
							(memory_read_byte(srcspace, mcu_address + 7)<<0) ;

			mcu_size	=	(memory_read_byte(srcspace, mcu_address + 8)<<8) +
							(memory_read_byte(srcspace, mcu_address + 9)<<0) ;
			logerror("%s : MCU executes command $%02X, %04X %02X-> %04x\n",cpuexec_describe_context(machine),mcu_command,mcu_src,mcu_size,mcu_dst);

			for( ; mcu_size > 0 ; mcu_size-- )
			{
				mcu_src &= 0xffff;	mcu_dst &= 0xffff;
				memory_write_byte(srcspace,0x100000 + mcu_dst,memory_read_byte(dstspace,0x100000 + mcu_src));
				mcu_src ++;			mcu_dst ++;
			}

			/* Raise a "job done" flag */
			memory_write_byte(srcspace,mcu_address+0,0xff);
			memory_write_byte(srcspace,mcu_address+1,0xff);

			break;

		case 0x0a:	// Copy N bytes from RAM1 to RAM2
			mcu_src		=	(memory_read_byte(srcspace, mcu_address + 2)<<8) +
							(memory_read_byte(srcspace, mcu_address + 3)<<0) ;

			mcu_dst		=	(memory_read_byte(srcspace, mcu_address + 6)<<8) +
							(memory_read_byte(srcspace, mcu_address + 7)<<0) ;

			mcu_size	=	(memory_read_byte(srcspace, mcu_address + 8)<<8) +
							(memory_read_byte(srcspace, mcu_address + 9)<<0) ;

			logerror("%s : MCU executes command $%02X, %04X %02X-> %04x\n",cpuexec_describe_context(machine),mcu_command,mcu_src,mcu_size,mcu_dst);

			for( ; mcu_size > 0 ; mcu_size-- )
			{
				mcu_src &= 0xffff;	mcu_dst &= 0xffff;
				memory_write_byte(dstspace,0x100000 + mcu_dst,memory_read_byte(srcspace,0x100000 + mcu_src));
				mcu_src ++;			mcu_dst ++;
			}

			/* Raise a "job done" flag */
			memory_write_byte(srcspace,mcu_address+0,0xff);
			memory_write_byte(srcspace,mcu_address+1,0xff);

			break;

		//case 0x10: //? Clear gal?
		//case 0x14: //? Display gal?
		//until
		//case 0x50: //? Display gal?
		//case 0x68: //? Display "Changed" monster?
		//until
		//case 0x6E: //? Display "Changed" monster?
		//case 0x85: //? Do what?
		default:
			/* Raise a "job done" flag */
			memory_write_byte(srcspace,mcu_address+0,0xff);
			memory_write_byte(srcspace,mcu_address+1,0xff);

			logerror("%s : MCU ERROR, unknown command $%02X\n",cpuexec_describe_context(machine),mcu_command);
		}

		/* Erase command (so that it won't be processed again)? */
		memory_write_byte(srcspace,mcu_list,0x00);
	}
}
示例#24
0
static WRITE16_DEVICE_HANDLER( sslam_snd_w )
{
	if (ACCESSING_BITS_0_7)
	{
		logerror("%s Writing %04x to Sound CPU\n",cpuexec_describe_context(device->machine),data);
		if (data >= 0x40) {
			if (data == 0xfe) {
				/* This should reset the sound MCU and stop audio playback, but here, it */
				/* chops the first coin insert. So let's only stop any playing melodies. */
				sslam_play(device, 1, (0x80 | 0x40));		/* Stop playing the melody */
			}
			else {
				logerror("Unknown command (%02x) sent to the Sound controller\n",data);
				popmessage("Unknown command (%02x) sent to the Sound controller",data);
			}
		}
		else if (data == 0) {
			sslam_bar = 0;		/* Complete any current bars then stop sequencing */
			sslam_melody = 0;
		}
		else {
			sslam_sound = sslam_snd_cmd[data];

			if (sslam_sound == 0xff) {
				popmessage("Unmapped sound command %02x on Bank %02x",data,sslam_snd_bank);
			}
			else if (sslam_sound >= 0x70) {
				/* These vocals are in bank 1, but a bug in the actual MCU doesn't set the bank */
//              if (sslam_snd_bank != 1)
//                  okim6295_set_bank_base(device, (1 * 0x40000));
//              sslam_snd_bank = 1;
				sslam_play(device, 0, sslam_sound);
			}
			else if (sslam_sound >= 0x69) {
				if (sslam_snd_bank != 2)
					okim6295_set_bank_base(device, (2 * 0x40000));
				sslam_snd_bank = 2;
				switch (sslam_sound)
				{
					case 0x69:	sslam_melody = 5; break;
					case 0x6b:	sslam_melody = 6; break;
					case 0x6c:	sslam_melody = 7; break;
					default:	sslam_melody = 0; sslam_bar = 0; break;	/* Invalid */
				}
				sslam_play(device, sslam_melody, sslam_sound);
			}
			else if (sslam_sound >= 0x65) {
				if (sslam_snd_bank != 1)
					okim6295_set_bank_base(device, (1 * 0x40000));
				sslam_snd_bank = 1;
				sslam_melody = 4;
				sslam_play(device, sslam_melody, sslam_sound);
			}
			else if (sslam_sound >= 0x60) {
				if (sslam_snd_bank != 0)
					okim6295_set_bank_base(device, (0 * 0x40000));
				sslam_snd_bank = 0;
				switch (sslam_sound)
				{
					case 0x60:	sslam_melody = 1; break;
					case 0x63:	sslam_melody = 2; break;
					case 0x64:	sslam_melody = 3; break;
					default:	sslam_melody = 0; sslam_bar = 0; break;	/* Invalid */
				}
				sslam_play(device, sslam_melody, sslam_sound);
			}
			else {
				sslam_play(device, 0, sslam_sound);
			}
		}
	}
}
示例#25
0
static WRITE8_DEVICE_HANDLER( r6532_porta_w )
{
	if (has_mc3417)
		cputag_set_input_line(device->machine, "cvsdcpu", INPUT_LINE_RESET, (data & 0x10) ? CLEAR_LINE : ASSERT_LINE);

	if (has_tms5220)
	{
		running_device *tms = devtag_get_device(device->machine, "tms");
		logerror("(%f)%s:TMS5220 data write = %02X\n", attotime_to_double(timer_get_time(device->machine)), cpuexec_describe_context(device->machine), riot6532_porta_out_get(riot));
		tms5220_data_w(tms, 0, data);
	}
}
示例#26
0
static void execute_blit(running_machine *machine)
{
	UINT16 *dest = blitter_page ? artmagic_vram0 : artmagic_vram1;
	int offset = ((blitter_data[1] & 0xff) << 16) | blitter_data[0];
	int color = (blitter_data[1] >> 4) & 0xf0;
	int x = (INT16)blitter_data[2];
	int y = (INT16)blitter_data[3];
	int maskx = blitter_data[6] & 0xff;
	int masky = blitter_data[6] >> 8;
	int w = ((blitter_data[7] & 0xff) + 1) * 4;
	int h = (blitter_data[7] >> 8) + 1;
	int i, j, sx, sy, last;

#if 0
{
	static UINT32 hit_list[50000];
	static int hit_index;
	static FILE *f;

	logerror("%s:Blit from %06X to (%d,%d) %dx%d -- %04X %04X %04X %04X %04X %04X %04X %04X\n",
				cpuexec_describe_context(machine), offset, x, y, w, h,
				blitter_data[0], blitter_data[1],
				blitter_data[2], blitter_data[3],
				blitter_data[4], blitter_data[5],
				blitter_data[6], blitter_data[7]);

	if (!f) f = fopen("artmagic.log", "w");

	for (i = 0; i < hit_index; i++)
		if (hit_list[i] == offset)
			break;
	if (i == hit_index)
	{
		int tempoffs = offset;
		hit_list[hit_index++] = offset;

		fprintf(f, "----------------------\n"
				   "%s:Blit from %06X to (%d,%d) %dx%d -- %04X %04X %04X %04X %04X %04X %04X %04X\n",
					cpuexec_describe_context(machine), offset, x, y, w, h,
					blitter_data[0], blitter_data[1],
					blitter_data[2], blitter_data[3],
					blitter_data[4], blitter_data[5],
					blitter_data[6], blitter_data[7]);

		fprintf(f, "\t");
		for (i = 0; i < h; i++)
		{
			for (j = 0; j < w; j += 4)
				fprintf(f, "%04X ", blitter_base[tempoffs++]);
			fprintf(f, "\n\t");
		}
		fprintf(f, "\n\t");
		tempoffs = offset;
		for (i = 0; i < h; i++)
		{
			last = 0;
			if (i == 0)	/* first line */
			{
				/* ultennis, stonebal */
				last ^= (blitter_data[7] & 0x0001);
				if (artmagic_is_stoneball)
					last ^= ((blitter_data[0] & 0x0020) >> 3);
				else	/* ultennis */
					last ^= ((blitter_data[0] & 0x0040) >> 4);

				/* cheesech */
				last ^= ((blitter_data[7] & 0x0400) >> 9);
				last ^= ((blitter_data[0] & 0x2000) >> 10);
			}
			else	/* following lines */
			{
示例#27
0
static WRITE8_DEVICE_HANDLER( aquarium_oki_w )
{
	logerror("%s:Writing %04x to the OKI M6295\n",cpuexec_describe_context(device->machine),aquarium_snd_bitswap(data));
	okim6295_w( device, 0, (aquarium_snd_bitswap(data)) );
}
示例#28
0
static void josvolly_8741_w(const address_space *space, int num, int offset, int data)
{
	JV8741 *mcu = &i8741[num];

	if(offset==1)
	{
		LOG(("%s:8741[%d] CW %02X\n", cpuexec_describe_context(space->machine), num, data));

		/* read pointer */
		mcu->cmd = data;
		/* CMD */
		switch(data)
		{
		case 0:
			mcu->txd = data ^ 0x40;
			mcu->sts |= 0x02;
			break;
		case 1:
			mcu->txd = data ^ 0x40;
			mcu->sts |= 0x02;
#if 1
			/* ?? */
			mcu->rxd = 0;  /* SBSTS ( DIAG ) , killed */
			mcu->sts |= 0x01; /* RD ready */
#endif
			break;
		case 2:
#if 1
			mcu->rxd = input_port_read(space->machine, "DSW2");
			mcu->sts |= 0x01; /* RD ready */
#endif
			break;
		case 3: /* normal mode ? */
			break;

		case 0xf0: /* clear main sts ? */
			mcu->txd = data ^ 0x40;
			mcu->sts |= 0x02;
			break;
		}
	}
	else
	{
		/* data */
		LOG(("%s:8741[%d] DW %02X\n", cpuexec_describe_context(space->machine), num, data));

		mcu->txd = data ^ 0x40; /* parity reverce ? */
		mcu->sts |= 0x02;     /* TXD busy         */
#if 1
		/* interrupt ? */
		if(num == 0)
		{
			if(josvolly_nmi_enable)
			{
				cputag_set_input_line(space->machine, "audiocpu", INPUT_LINE_NMI, PULSE_LINE);
				josvolly_nmi_enable = 0;
			}
		}
#endif
	}
	josvolly_8741_do(space->machine, num);
}