Ejemplo n.º 1
0
int Hes_Emu::cpu_read_( hes_addr_t addr )
{
	hes_time_t time = this->time();
	addr &= page_size - 1;
	switch ( addr )
	{
	case 0x0000:
		if ( irq.vdp > time )
			return 0;
		irq.vdp = future_hes_time;
		run_until( time );
		irq_changed();
		return 0x20;
		
	case 0x0002:
	case 0x0003:
		debug_printf( "VDP read not supported: %d\n", addr );
		return 0;
	
	case 0x0C01:
		//return timer.enabled; // TODO: remove?
	case 0x0C00:
		run_until( time );
		debug_printf( "Timer count read\n" );
		return (unsigned) (timer.count - 1) / timer_base;
	
	case 0x1402:
		return irq.disables;
	
	case 0x1403:
		{
			int status = 0;
			if ( irq.timer <= time ) status |= timer_mask;
			if ( irq.vdp   <= time ) status |= vdp_mask;
			return status;
		}
		
	#ifndef NDEBUG
		case 0x1000: // I/O port
		case 0x180C: // CD-ROM
		case 0x180D:
			break;
		
		default:
			debug_printf( "unmapped read  $%04X\n", addr );
	#endif
	}
	
	return unmapped;
}
Ejemplo n.º 2
0
int Opl_Apu::read( blip_time_t time, int port )
{
	run_until( time );
	switch (type_)
	{
	case type_opll:
	case type_msxmusic:
	case type_smsfmunit:
	case type_vrc7:
		return ym2413_read( opl, port );

	case type_opl:
		return ym3526_read( opl, port );

	case type_msxaudio:
		{
			int ret = y8950_read( opl, port );
			/*unsigned char temp [2] = { port + 0x80, ret };
			fwrite( &temp, 1, 2, logfile );*/
			return ret;
		}

	case type_opl2:
		return ym3812_read( opl, port );
	}

	return 0;
}
Ejemplo n.º 3
0
void Opl_Apu::write_data( blip_time_t time, int data )
{
	run_until( time );
	switch (type_)
	{
	case type_opll:
	case type_msxmusic:
	case type_smsfmunit:
	case type_vrc7:
		ym2413_write( opl, 0, addr );
		ym2413_write( opl, 1, data );
		break;

	case type_opl:
		ym3526_write( opl, 0, addr );
		ym3526_write( opl, 1, data );
		break;

	case type_msxaudio:
		/*if ( addr >= 7 && addr <= 7 + 11 )
		{
			unsigned char temp [2] = { addr - 7, data };
			fwrite( &temp, 1, 2, logfile );
		}*/
		y8950_write( opl, 0, addr );
		y8950_write( opl, 1, data );
		break;

	case type_opl2:
		ym3812_write( opl, 0, addr );
		ym3812_write( opl, 1, data );
		break;
	}
}
Ejemplo n.º 4
0
blargg_err_t Hes_Emu::run_clocks( blip_time_t& duration_, int )
{
	blip_time_t const duration = duration_; // cache
	
	if ( cpu::run( duration ) )
		set_warning( "Emulation error (illegal instruction)" );
	
	check( time() >= duration );
	//check( time() - duration < 20 ); // Txx instruction could cause going way over
	
	run_until( duration );
	
	// end time frame
	timer.last_time -= duration;
	vdp.next_vbl    -= duration;
	#if GME_FRAME_HOOK_DEFINED
		last_frame_hook -= duration;
	#endif
	cpu::end_frame( duration );
	::adjust_time( irq.timer, duration );
	::adjust_time( irq.vdp,   duration );
	apu.end_frame( duration );
	
	return 0;
}
Ejemplo n.º 5
0
void Sms_Fm_Apu::write_data( blip_time_t time, int data )
{
	if ( time > next_time )
		run_until( time );
	
	apu.write( addr, data );
}
Ejemplo n.º 6
0
int Hes_Apu_Adpcm::read_data( blip_time_t time, int addr )
{
	if ( time > last_time ) run_until( time );

	switch ( addr & 15 )
	{
	case 10:
		return state.pcmbuf [state.readptr++];
	case 11:
		return state.port [11] & ~1;
	case 12:
		if (!state.playflag)
		{
			state.port [12] |= 1;
			state.port [12] &= ~8;
		}
		else
		{
			state.port [12] &= ~1;
			state.port [12] |= 8;
		}
		return state.port [12];
	case 13:
		return state.port [13];
	}

	return 0xFF;
}
Ejemplo n.º 7
0
void Hes_Emu::cpu_write_vdp( int addr, int data )
{
	switch ( addr )
	{
	case 0:
		vdp.latch = data & 0x1F;
		break;
	
	case 2:
		if ( vdp.latch == 5 )
		{
			if ( data & 0x04 )
				set_warning( "Scanline interrupt unsupported" );
			run_until( time() );
			vdp.control = data;
			irq_changed();
		}
		else
		{
			debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
		}
		break;
	
	case 3:
		debug_printf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
		break;
	}
}
Ejemplo n.º 8
0
void Nes_Vrc6_Apu::end_frame( nes_time_t time )
{
	if ( time > last_time )
		run_until( time );
	
	assert( last_time >= time );
	last_time -= time;
}
Ejemplo n.º 9
0
void Nes_Vrc6_Apu::write_osc( nes_time_t time, int osc_index, int reg, int data )
{
	require( (unsigned) osc_index < osc_count );
	require( (unsigned) reg < reg_count );
	
	run_until( time );
	oscs [osc_index].regs [reg] = data;
}
Ejemplo n.º 10
0
void Opl_Apu::end_frame( blip_time_t time )
{
	run_until( time );
	next_time -= time;

	if ( output_ )
		output_->set_modified();
}
Ejemplo n.º 11
0
	virtual void end_frame( nes_time_t end_time )
	{
		if ( end_time > last_time )
			run_until( end_time );
		
		last_time -= end_time;
		
		sound.end_frame( end_time );
	}
Ejemplo n.º 12
0
void Hes_Apu_Adpcm::end_frame( blip_time_t end_time )
{
	run_until( end_time );
	last_time -= end_time;
	next_timer -= (double)end_time;
	check( last_time >= 0 );
	if ( output )
		output->set_modified();
}
Ejemplo n.º 13
0
void Sms_Fm_Apu::end_frame( blip_time_t time )
{
	if ( time > next_time )
		run_until( time );
	
	next_time -= time;
	assert( next_time >= 0 );
	
	if ( output_ )
		output_->set_modified();
}
Ejemplo n.º 14
0
void Nes_Vrc7_Apu::write_data( blip_time_t time, int data )
{
    int type = (addr >> 4) - 1;
    int chan = addr & 15;
    if ( (unsigned) type < 3 && chan < osc_count )
        oscs [chan].regs [type] = data;

    if ( time > next_time )
        run_until( time );
    ym2413_write( opll, 0, addr );
    ym2413_write( opll, 1, data );
}
Ejemplo n.º 15
0
void Nes_Vrc7_Apu::write_data( blip_time_t time, int data )
{
	int type = (addr >> 4) - 1;
	int chan = addr & 15;
	if ( (unsigned) type < 3 && chan < osc_count )
		oscs [chan].regs [type] = data;
	if ( addr < 0x08 )
	  inst [addr] = data;

	if ( time > next_time )
		run_until( time );
	OPLL_writeIO( (OPLL *) opll, 0, addr );
	OPLL_writeIO( (OPLL *) opll, 1, data );
}
Ejemplo n.º 16
0
void Nsf_Impl::end_frame( time_t end )
{
	if ( time() < end )
		run_until( end );
	cpu.adjust_time( -end );
	
	// Localize to new time frame
	next_play -= end;
	check( next_play >= 0 );
	if ( next_play < 0 )
		next_play = 0;
	
	apu.end_frame( end );
}
Ejemplo n.º 17
0
void Nes_Vrc7_Apu::end_frame( blip_time_t time )
{
    if ( time > next_time )
        run_until( time );

    next_time -= time;
    assert( next_time >= 0 );

    for ( int i = osc_count; --i >= 0; )
    {
        Blip_Buffer* output = oscs [i].output;
        if ( output )
            output->set_modified();
    }
}
Ejemplo n.º 18
0
void Mapper_Fme7::write_irq( nes_time_t time, int index, int data )
{
	run_until( time );
	switch ( index )
	{
	case 0x0D:
		irq_mode = data;
      irq_pending = false;
      irq_changed();
		break;

	case 0x0E:
		irq_count = (irq_count & 0xFF00) | data;
		break;

	case 0x0F:
		irq_count = data << 8 | (irq_count & 0xFF);
		break;
	}
}
Ejemplo n.º 19
0
void Hes_Apu_Adpcm::write_data( blip_time_t time, int addr, int data )
{
	if ( time > last_time ) run_until( time );

	data &= 0xFF;
	state.port[ addr & 15 ] = data;
	switch ( addr & 15 )
	{
	case 8:
		state.addr &= 0xFF00;
		state.addr |= data;
		break;
	case 9:
		state.addr &= 0xFF;
		state.addr |= data << 8;
		break;
	case 10:
		state.pcmbuf[ state.writeptr++ ] = data;
		state.playlength ++;
		break;
	case 11:
		dprintf("ADPCM DMA 0x%02X", data);
		break;
	case 13:
		if ( data & 0x80 )
		{
			state.addr = 0;
			state.freq = 0;
			state.writeptr = 0;
			state.readptr = 0;
			state.playflag = 0;
			state.repeatflag = 0;
			state.length = 0;
			state.volume = 0xFF;
		}
		if ( ( data & 3 ) == 3 )
		{
			state.writeptr = state.addr;
		}
		if ( data & 8 )
		{
			state.readptr = state.addr ? state.addr - 1 : state.addr;
		}
		if ( data & 0x10 )
		{
			state.length = state.addr;
		}
		state.repeatflag = data & 0x20;
		state.playflag = data & 0x40;
		if ( state.playflag )
		{
			state.playptr = state.readptr;
			state.playlength = state.length + 1;
			state.playedsamplecount = 0;
			state.ad_sample = 0;
			state.ad_low_nibble = false;
		}
		break;
	case 14:
        state.freq = 7159091 / ( 32000 / ( 16 - ( data & 15 ) ) );
		break;
	case 15:
		switch ( data & 15 )
		{
		case 0:
		case 8:
		case 12:
			state.fadetimer = -100;
			state.fadecount = state.fadetimer;
			break;
		case 10:
			state.fadetimer = 5000;
			state.fadecount = state.fadetimer;
			break;
		case 14:
			state.fadetimer = 1500;
			state.fadecount = state.fadetimer;
			break;
		}
		break;
	}
}
Ejemplo n.º 20
0
void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
{
	if ( unsigned (addr - apu.start_addr) <= apu.end_addr - apu.start_addr )
	{
		GME_APU_HOOK( this, addr - apu.start_addr, data );
		// avoid going way past end when a long block xfer is writing to I/O space
		hes_time_t t = min( time(), end_time() + 8 );
		apu.write_data( t, addr, data );
		return;
	}
	
	hes_time_t time = this->time();
	switch ( addr )
	{
	case 0x0000:
	case 0x0002:
	case 0x0003:
		cpu_write_vdp( addr, data );
		return;
	
	case 0x0C00: {
		run_until( time );
		timer.raw_load = (data & 0x7F) + 1;
		recalc_timer_load();
		timer.count = timer.load;
		break;
	}
	
	case 0x0C01:
		data &= 1;
		if ( timer.enabled == data )
			return;
		run_until( time );
		timer.enabled = data;
		if ( data )
			timer.count = timer.load;
		break;
	
	case 0x1402:
		run_until( time );
		irq.disables = data;
		if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
			debug_printf( "Int mask: $%02X\n", data );
		break;
	
	case 0x1403:
		run_until( time );
		if ( timer.enabled )
			timer.count = timer.load;
		timer.fired = false;
		break;
	
#ifndef NDEBUG
	case 0x1000: // I/O port
	case 0x0402: // palette
	case 0x0403:
	case 0x0404:
	case 0x0405:
		return;
		
	default:
		debug_printf( "unmapped write $%04X <- $%02X\n", addr, data );
		return;
#endif
	}
	
	irq_changed();
}