Пример #1
0
blargg_err_t Sap_Emu::run_clocks( blip_time_t& duration, int )
{
	set_time( 0 );
	while ( time() < duration )
	{
		if ( cpu::run( duration ) || r.pc > idle_addr )
			return "Emulation error (illegal instruction)";
		
		if ( r.pc == idle_addr )
		{
			if ( next_play <= duration )
			{
				set_time( next_play );
				next_play += play_period();
				call_play();
				GME_FRAME_HOOK( this );
			}
			else
			{
				set_time( duration );
			}
		}
	}
	
	duration = time();
	next_play -= duration;
	check( next_play >= 0 );
	if ( next_play < 0 )
		next_play = 0;
	apu.end_frame( duration );
	if ( info.stereo )
		apu2.end_frame( duration );
	
	return 0;
}
Пример #2
0
int Hes_Emu::cpu_done()
{
	check( time() >= end_time() ||
			(!(r.status & i_flag_mask) && time() >= irq_time()) );
	
	if ( !(r.status & i_flag_mask) )
	{
		hes_time_t present = time();
		
		if ( irq.timer <= present && !(irq.disables & timer_mask) )
		{
			timer.fired = true;
			irq.timer = future_hes_time;
			irq_changed(); // overkill, but not worth writing custom code
			#if GME_FRAME_HOOK_DEFINED
			{
				unsigned const threshold = period_60hz / 30;
				unsigned long elapsed = present - last_frame_hook;
				if ( elapsed - period_60hz + threshold / 2 < threshold )
				{
					last_frame_hook = present;
					GME_FRAME_HOOK( this );
				}
			}
			#endif
			return 0x0A;
		}
		
		if ( irq.vdp <= present && !(irq.disables & vdp_mask) )
		{
			// work around for bugs with music not acknowledging VDP
			//run_until( present );
			//irq.vdp = future_hes_time;
			//irq_changed();
			#if GME_FRAME_HOOK_DEFINED
				last_frame_hook = present;
				GME_FRAME_HOOK( this );
			#endif
			return 0x08;
		}
	}
	return 0;
}
Пример #3
0
blargg_err_t Nsf_Emu::run_clocks( blip_time_t& duration, int )
{
	set_time( 0 );
	while ( time() < duration )
	{
		nes_time_t end = min( next_play, duration );
		end = min( end, time() + 32767 ); // allows CPU to use 16-bit time delta
		if ( cpu::run( end ) )
		{
			if ( r.pc != badop_addr )
			{
				set_warning( "Emulation error (illegal instruction)" );
				r.pc++;
			}
			else
			{
				play_ready = 1;
				if ( saved_state.pc != badop_addr )
				{
					cpu::r = saved_state;
					saved_state.pc = badop_addr;
				}
				else
				{
					set_time( end );
				}
			}
		}
		
		if ( time() >= next_play )
		{
			nes_time_t period = (play_period + play_extra) / clock_divisor;
			play_extra = play_period - period * clock_divisor;
			next_play += period;
			if ( play_ready && !--play_ready )
			{
				check( saved_state.pc == badop_addr );
				if ( r.pc != badop_addr )
					saved_state = cpu::r;
				
				r.pc = play_addr;
				low_mem [0x100 + r.sp--] = (badop_addr - 1) >> 8;
				low_mem [0x100 + r.sp--] = (badop_addr - 1) & 0xFF;
				GME_FRAME_HOOK( this );
			}
		}