Exemplo n.º 1
0
void USB_PortCtl_Worker(void *Unused)
{
	Threads_SetName("USB PortCtl Worker");
	for(;;)
	{
		tUSBHubPort *port;
		tUSBHub	*hub;
	       
		port = Workqueue_GetWork(&gUSB_PortCtl_WorkQueue);
		if( !port ) {
			Log_Warning("USB", "PortCtl Workqueue returned NULL");
			break;
		}
	       	hub = (tUSBHub*)(port - port->PortNum) - 1;

		LOG("port = %p, hub = %p", port, hub);

		switch(port->Status)
		{
		case 1:
			// Assert reset
			USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_RESET);
			LOG("Port reset starting");
			// Wait 50 ms
			Time_Delay(50);
			USB_PortCtl_ClearPortFeature(hub, port->PortNum, PORT_RESET);
			Time_Delay(10);	// May take up to 2ms for reset to clear
			// Enable port
			LOG("Port enabling");
			USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_ENABLE);
			// Begin connect processing
			port->Status = 2;
			USB_DeviceConnected(hub, port->PortNum);
			break;
		}
	}
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: jsdf/previous
/**
 * This function waits on each emulated VBL to synchronize the real time
 * with the emulated ST.
 * Unfortunately SDL_Delay and other sleep functions like usleep or nanosleep
 * are very inaccurate on some systems like Linux 2.4 or Mac OS X (they can only
 * wait for a multiple of 10ms due to the scheduler on these systems), so we have
 * to "busy wait" there to get an accurate timing.
 * All times are expressed as micro seconds, to avoid too much rounding error.
 */
void Main_WaitOnVbl(void)
{
	Sint64 CurrentTicks;
	static Sint64 DestTicks = 0;
	Sint64 FrameDuration_micro;
	Sint64 nDelay;

	nVBLCount++;
	if (nRunVBLs &&	nVBLCount >= nRunVBLs)
	{
		/* show VBLs/s */
		Main_PauseEmulation(true);
		exit(0);
	}

//	FrameDuration_micro = (Sint64) ( 1000000.0 / nScreenRefreshRate + 0.5 );	/* round to closest integer */
	FrameDuration_micro = ClocksTimings_GetVBLDuration_micro ( ConfigureParams.System.nMachineType , 68 );
//      FrameDuration_micro = 1000000/50;
	CurrentTicks = Time_GetTicks();

	if ( DestTicks == 0 )					/* first call, init DestTicks */
    {
		DestTicks = CurrentTicks + FrameDuration_micro;
    }

	nDelay = DestTicks - CurrentTicks;

	/* Do not wait if we are in fast forward mode or if we are totally out of sync */
	if (ConfigureParams.System.bFastForward == true
	        || nDelay < -4*FrameDuration_micro || nDelay > 50*FrameDuration_micro)
	{
		if (ConfigureParams.System.bFastForward == true)
		{
			if (!nFirstMilliTick)
				nFirstMilliTick = Main_GetTicks();
		}
		if (nFrameSkips < ConfigureParams.Screen.nFrameSkips)
		{
			nFrameSkips += 1;
			Log_Printf(LOG_DEBUG, "Increased frameskip to %d\n", nFrameSkips);
		}
		/* Only update DestTicks for next VBL */
		DestTicks = CurrentTicks + FrameDuration_micro;
		return;
	}
	/* If automatic frameskip is enabled and delay's more than twice
	 * the effect of single frameskip, decrease frameskip
	 */
	if (nFrameSkips > 0
	    && ConfigureParams.Screen.nFrameSkips >= AUTO_FRAMESKIP_LIMIT
	    && 2*nDelay > FrameDuration_micro/nFrameSkips)
	{
		nFrameSkips -= 1;
		Log_Printf(LOG_DEBUG, "Decreased frameskip to %d\n", nFrameSkips);
	}

	if (bAccurateDelays)
	{
		/* Accurate sleeping is possible -> use SDL_Delay to free the CPU */
		if (nDelay > 1000)
			Time_Delay(nDelay - 1000);
	}
	else
	{
		/* No accurate SDL_Delay -> only wait if more than 5ms to go... */
		if (nDelay > 5000)
			Time_Delay(nDelay<10000 ? nDelay-1000 : 9000);
	}

	/* Now busy-wait for the right tick: */
	while (nDelay > 0)
	{
		CurrentTicks = Time_GetTicks();
		nDelay = DestTicks - CurrentTicks;
        /* If the delay is still bigger than one frame, somebody
         * played tricks with the system clock and we have to abort */
        if (nDelay > FrameDuration_micro)
            break;
	}

//printf ( "tick %lld\n" , CurrentTicks );
	/* Update DestTicks for next VBL */
	DestTicks += FrameDuration_micro;
}