Exemple #1
0
void psxRcntUpdate()
{
	int i;
	//u32 change = 0;

	g_iopNextEventCycle = psxRegs.cycle + 32;

	psxNextCounter = 0x7fffffff;
	psxNextsCounter = psxRegs.cycle;

	for (i=0; i<=5; i++)
	{
		s32 change = psxRegs.cycle - psxCounters[i].sCycleT;

		// don't count disabled or hblank counters...
		// We can't check the ALTSOURCE flag because the PSXCLOCK source *should*
		// be counted here.
		
		if( psxCounters[i].mode & IOPCNT_STOPPED ) continue;

		if ((psxCounters[i].mode & 0x40) && !(psxCounters[i].mode & 0x80)) { //Repeat IRQ mode Pulsed, resets a few cycles after the interrupt, this should do.
			psxCounters[i].mode |= 0x400;
		}

		if( psxCounters[i].rate == PSXHBLANK ) continue;
		
		if( change <= 0 ) continue;

		psxCounters[i].count += change / psxCounters[i].rate;
		if(psxCounters[i].rate != 1)
		{
			change -= (change / psxCounters[i].rate) * psxCounters[i].rate;
			psxCounters[i].sCycleT = psxRegs.cycle - change;
		}
		else
			psxCounters[i].sCycleT = psxRegs.cycle;
	}

	// Do target/overflow testing
	// Optimization Note: This approach is very sound.  Please do not try to unroll it
	// as the size of the Test functions will cause code cache clutter and slowness.

	for( i=0; i<6; i++ )
	{
		// don't do target/oveflow checks for hblankers.  Those
		// checks are done when the counters are updated.
		if( psxCounters[i].rate == PSXHBLANK ) continue;
		if( psxCounters[i].mode & IOPCNT_STOPPED ) continue;

		_rcntTestTarget( i );
		_rcntTestOverflow( i );

		// perform second target test because if we overflowed above it's possible we
		// already shot past our target if it was very near zero.

		//if( psxCounters[i].count >= psxCounters[i].target ) _rcntTestTarget( i );
	}


	if(SPU2async)
	{
		const s32 difference = psxRegs.cycle - psxCounters[6].sCycleT;
		s32 c = psxCounters[6].CycleT;

		if(difference >= psxCounters[6].CycleT)
		{
			SPU2async(difference);
			psxCounters[6].sCycleT = psxRegs.cycle;
			psxCounters[6].CycleT = psxCounters[6].rate;
		}
		else c -= difference;
		psxNextCounter = c;
	}
	if (DEV9async)
	{
		DEV9async(1);
	}
	if(USBasync)
	{
		const s32 difference = psxRegs.cycle - psxCounters[7].sCycleT;
		s32 c = psxCounters[7].CycleT;

		if(difference >= psxCounters[7].CycleT)
		{
			USBasync(difference);
			psxCounters[7].sCycleT = psxRegs.cycle;
			psxCounters[7].CycleT = psxCounters[7].rate;
		}
		else c -= difference;
		if (c < psxNextCounter) psxNextCounter = c;
	}

#ifdef ENABLE_NEW_IOPDMA

	// New Iop DMA handler WIP
	{
		const s32 difference = psxRegs.cycle - psxCounters[8].sCycleT;
		s32 c = psxCounters[8].CycleT;

		if(difference >= psxCounters[8].CycleT)
		{
			psxCounters[8].sCycleT = psxRegs.cycle;
			psxCounters[8].CycleT = psxCounters[8].rate;
			IopDmaUpdate(difference);
		}
		else c -= difference;
		if (c < psxNextCounter) psxNextCounter = c;
	}
#endif

	for (i=0; i<6; i++) _rcntSet( i );
}
Exemple #2
0
void psxRcntUpdate()
{
	int i;
	//u32 change = 0;

	for (i=0; i<=5; i++)
	{
		s32 change = psxRegs.cycle - psxCounters[i].sCycleT;

		// don't count disabled, gated, or hblank counters...
		// We can't check the ALTSOURCE flag because the PSXCLOCK source *should*
		// be counted here.

		if( psxCounters[i].mode & (IOPCNT_STOPPED | IOPCNT_ENABLE_GATE) ) continue;
		if( psxCounters[i].rate == PSXHBLANK ) continue;
		if( change <= 0 ) continue;

		psxCounters[i].count += change / psxCounters[i].rate;
		if(psxCounters[i].rate != 1)
		{
			change -= (change / psxCounters[i].rate) * psxCounters[i].rate;
			psxCounters[i].sCycleT = psxRegs.cycle - change;
		}
		else
			psxCounters[i].sCycleT = psxRegs.cycle;
	}

	// Do target/overflow testing
	// Optimization Note: This approach is very sound.  Please do not try to unroll it
	// as the size of the Test functions will cause code cache clutter and slowness.
	
	for( i=0; i<6; i++ )
	{
		// don't do target/oveflow checks for hblankers.  Those
		// checks are done when the counters are updated.
		if( psxCounters[i].rate == PSXHBLANK ) continue;
		if( psxCounters[i].mode & IOPCNT_STOPPED ) continue;

		_rcntTestTarget( i );
		_rcntTestOverflow( i );
		
		// perform second target test because if we overflowed above it's possible we
		// already shot past our target if it was very near zero.

		//if( psxCounters[i].count >= psxCounters[i].target ) _rcntTestTarget( i );
	}

	psxNextCounter = 0xffffff;
	psxNextsCounter = psxRegs.cycle;

	if(SPU2async)
	{	
		const s32 difference = psxRegs.cycle - psxCounters[6].sCycleT;
		s32 c = psxCounters[6].CycleT;

		if(difference >= psxCounters[6].CycleT)
		{
			SPU2async(difference);
			psxCounters[6].sCycleT = psxRegs.cycle;
			psxCounters[6].CycleT = psxCounters[6].rate;
		}
		else c -= difference;
		psxNextCounter = c;
	}

	if(USBasync)
	{
		const s32 difference = psxRegs.cycle - psxCounters[7].sCycleT;
		s32 c = psxCounters[7].CycleT;

		if(difference >= psxCounters[7].CycleT)
		{
			USBasync(difference);
			psxCounters[7].sCycleT = psxRegs.cycle;
			psxCounters[7].CycleT = psxCounters[7].rate;
		}
		else c -= difference;
		if (c < psxNextCounter) psxNextCounter = c;
	}

	for (i=0; i<6; i++) _rcntSet( i );
}
Exemple #3
0
EXPORT_C_(void) s2r_replay(HWND hwnd, HINSTANCE hinst, LPSTR filename, int nCmdShow)
{
#ifndef ENABLE_NEW_IOPDMA_SPU2
	int events=0;

	Running = true;

#ifdef WIN32
	AllocConsole();
	SetConsoleCtrlHandler(HandlerRoutine, TRUE);
	
	conprintf("Playing %s file on %x...",filename,hwnd);

#endif

	// load file
	FILE *file=fopen(filename,"rb");

	if(!file)
	{
		conprintf("Could not open the replay file.");
		return;
	}
	// if successful, init the plugin

#define TryRead(dest,size,count,file) if(fread(dest,size,count,file)<count) { conprintf("Error reading from file.");  goto Finish;  /* Need to exit the while() loop and maybe also the switch */ }

	TryRead(&CurrentIOPCycle,4,1,file);
	
	replay_mode=true;

	InitWaitSync(); // Initialize the WaitSync stuff

	SPU2init();
	SPU2irqCallback(dummy1,dummy4,dummy7);
	SPU2setClockPtr(&CurrentIOPCycle);
	SPU2open(&hwnd);

	CurrentIOPCycle=0;

	SPU2async(0);

	while(!feof(file) && Running)
	{
		u32 ccycle=0;
		u32 evid=0;
		u32 sval=0;
		u32 tval=0;

		TryRead(&ccycle,4,1,file);
		TryRead(&sval,4,1,file);

		evid=sval>>29;
		sval&=0x1FFFFFFF;

		u32 TargetCycle = ccycle * 768;

		while(TargetCycle > CurrentIOPCycle)
		{
			u32 delta = WaitSync(TargetCycle);
			SPU2async(delta);
		}
		
		switch(evid)
		{
		case 0:
			SPU2read(sval);
			break;
		case 1:
			TryRead(&tval,2,1,file);
			SPU2write(sval,tval);
			break;
		case 2:
			TryRead(dmabuffer,sval,2,file);
			SPU2writeDMA4Mem(dmabuffer,sval);
			break;
		case 3:
			TryRead(dmabuffer,sval,2,file);
			SPU2writeDMA7Mem(dmabuffer,sval);
			break;
		default:
			// not implemented
			return;
			break;
		}
		events++;
	}

Finish:

	//shutdown
	SPU2close();
	SPU2shutdown();
	fclose(file);

	conprintf("Finished playing %s file (%d cycles, %d events).",filename,CurrentIOPCycle,events);

#ifdef WIN32
	FreeConsole();
#endif

	replay_mode=false;
#endif
}