Пример #1
0
__fi void psxRcntWmode16( int index, u32 value )
{
	PSXCNT_LOG( "IOP Counter[%d] writeMode = 0x%04X", index, value );

	pxAssume( index >= 0 && index < 3 );
	psxCounter& counter = psxCounters[index];

	counter.mode  = value;
	counter.mode |= 0x0400;

	if( index == 2 )
	{
		switch(value & 0x200)
		{
		case 0x000: psxCounters[2].rate = 1; break;
		case 0x200: psxCounters[2].rate = 8; break;
			jNO_DEFAULT;
		}

		if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
		{
			counter.mode |= IOPCNT_STOPPED;
		}
	}
	else
	{
		// Counters 0 and 1 can select PIXEL or HSYNC as an alternate source:
		counter.rate = 1;

		if(value & IOPCNT_ALT_SOURCE)
			counter.rate = (index==0) ? PSXPIXEL : PSXHBLANK;

		if(counter.mode & IOPCNT_ENABLE_GATE)
		{
			// gated counters are added up as per the h/vblank timers.
			// (the PIXEL alt source becomes a vsync gate)
			counter.mode |= IOPCNT_STOPPED;
			PSXCNT_LOG( "IOP Counter[%d] Gate Check set, value = 0x%04X", index, value );
			if( index == 0 )
				psxhblankgate |= 1;		// fixme: these gate flags should be one var >_<
			else
				psxvblankgate |= 1<<1;
		}
		else
		{
			if( index == 0 )
				psxhblankgate &= ~1;
			else
				psxvblankgate &= ~(1<<1);
		}
	}

	counter.count = 0;
	counter.sCycleT = psxRegs.cycle;
	counter.target &= 0xffff;

	_rcntSet( index );
}
Пример #2
0
void _recFillRegister(EEINST& pinst, int type, int reg, int write)
{
	u32 i = 0;
	if (write ) {
		for(i = 0; i < ArraySize(pinst.writeType); ++i) {
			if( pinst.writeType[i] == XMMTYPE_TEMP ) {
				pinst.writeType[i] = type;
				pinst.writeReg[i] = reg;
				return;
			}
		}
		pxAssume( false );
	}
	else {
		for(i = 0; i < ArraySize(pinst.readType); ++i) {
			if( pinst.readType[i] == XMMTYPE_TEMP ) {
				pinst.readType[i] = type;
				pinst.readReg[i] = reg;
				return;
			}
		}
		pxAssume( false );
	}
}
Пример #3
0
__fi void psxRcntWmode32( int index, u32 value )
{
	PSXCNT_LOG( "IOP Counter[%d] writeMode = 0x%04x", index, value );

	pxAssume( index >= 3 && index < 6 );
	psxCounter& counter = psxCounters[index];

	counter.mode  = value;
	counter.mode |= 0x0400;

	if( index == 3 )
	{
		// Counter 3 has the HBlank as an alternate source.
		counter.rate  = 1;
		if(value & IOPCNT_ALT_SOURCE)
			counter.rate = PSXHBLANK;

		if(counter.mode & IOPCNT_ENABLE_GATE)
		{
			PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
			counter.mode |= IOPCNT_STOPPED;
			psxvblankgate |= 1<<3;
		}
		else psxvblankgate &= ~(1<<3);
	}
	else
	{
		switch(value & 0x6000)
		{
		case 0x0000: counter.rate = 1;   break;
		case 0x2000: counter.rate = 8;   break;
		case 0x4000: counter.rate = 16;  break;
		case 0x6000: counter.rate = 256; break;
		}

		// Need to set a rate and target
		if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
		{
			Console.WriteLn( "Gate set on IOP Counter %d, disabling", index );
			counter.mode |= IOPCNT_STOPPED;
		}
	}

	counter.count = 0;
	counter.sCycleT = psxRegs.cycle;
	counter.target &= 0xffffffff;
	_rcntSet( index );
}
Пример #4
0
    // Preps and invokes the _InternalCallback above.  This provides a cdecl-compliant
    // entry point for our C++ified object state. :)
    static void ExternalCallback(snd_async_handler_t *pcm_call)
    {
        fprintf(stderr, "* SPU2-X:Iz in your external callback.\n");
        AlsaMod *data = (AlsaMod *)snd_async_handler_get_callback_private(pcm_call);

        pxAssume(data != NULL);
        //pxAssume( data->handle == snd_async_handler_get_pcm(pcm_call) );

        // Not sure if we just need an assert, or something like this:
        if (data->handle != snd_async_handler_get_pcm(pcm_call)) {
            fprintf(stderr, "* SPU2-X: Failed to handle sound.\n");
            return;
        }

        data->_InternalCallback();
    }
Пример #5
0
// returns the length of the formatted string, in characters (wxChars).
static
#ifndef __linux__
    __ri
#endif
        uint
        format_that_unicode_mess(CharBufferType &buffer, uint writepos, const wxChar *fmt, va_list argptr)
{
    va_list args;
    while (true) {
        int size = buffer.GetLength() / sizeof(wxChar);

        va_copy(args, argptr);
        int len = wxVsnprintf((wxChar *)buffer.GetPtr(writepos * sizeof(wxChar)), size - writepos, fmt, args);
        va_end(args);

        // some implementations of vsnprintf() don't NUL terminate
        // the string if there is not enough space for it so
        // always do it manually
        ((wxChar *)buffer.GetPtr())[size - 1] = L'\0';

        if (size >= MaxFormattedStringLength)
            return size - 1;

        // vsnprintf() may return either -1 (traditional Unix behavior) or the
        // total number of characters which would have been written if the
        // buffer were large enough (newer standards such as Unix98)

        if (len < 0)
            len = size + (size / 4);

        len += writepos;
        if (len < size)
            return len;
        buffer.Resize((len + 128) * sizeof(wxChar));
    };

    // performing an assertion or log of a truncated string is unsafe, so let's not; even
    // though it'd be kinda nice if we did.

    pxAssume(false);
    return 0; // unreachable.
}
Пример #6
0
int _signExtendXMMtoM(u32 to, x86SSERegType from, int candestroy)
{
	int t0reg;
	g_xmmtypes[from] = XMMT_INT;
	if( candestroy ) {
		if( g_xmmtypes[from] == XMMT_FPS ) SSE_MOVSS_XMM_to_M32(to, from);
		else SSE2_MOVD_XMM_to_M32(to, from);

		SSE2_PSRAD_I8_to_XMM(from, 31);
		SSE2_MOVD_XMM_to_M32(to+4, from);
		return 1;
	}
	else {
		// can't destroy and type is int
		pxAssert( g_xmmtypes[from] == XMMT_INT );


		if( _hasFreeXMMreg() ) {
			xmmregs[from].needed = 1;
			t0reg = _allocTempXMMreg(XMMT_INT, -1);
			SSEX_MOVDQA_XMM_to_XMM(t0reg, from);
			SSE2_PSRAD_I8_to_XMM(from, 31);
			SSE2_MOVD_XMM_to_M32(to, t0reg);
			SSE2_MOVD_XMM_to_M32(to+4, from);

			// swap xmm regs.. don't ask
			xmmregs[t0reg] = xmmregs[from];
			xmmregs[from].inuse = 0;
		}
		else {
			SSE2_MOVD_XMM_to_M32(to+4, from);
			SSE2_MOVD_XMM_to_M32(to, from);
			SAR32ItoM(to+4, 31);
		}

		return 0;
	}

	pxAssume( false );
}
Пример #7
0
    s32 Init()
    {
        numBuffers = Config_WaveOut.NumBuffers;

        MMRESULT woores;

        if (Test())
            return -1;

// TODO : Use dsound to determine the speaker configuration, and expand audio from there.

#if 0
		int speakerConfig;

		//if( StereoExpansionEnabled )
			speakerConfig = 2;  // better not mess with this in wavout :p (rama)

		// Any windows driver should support stereo at the software level, I should think!
		pxAssume( speakerConfig > 1 );
		LPTHREAD_START_ROUTINE threadproc;

		switch( speakerConfig )
		{
		case 2:
			ConLog( "* SPU2 > Using normal 2 speaker stereo output.\n" );
			threadproc = (LPTHREAD_START_ROUTINE)&RThread<StereoOut16>;
			speakerConfig = 2;
		break;

		case 4:
			ConLog( "* SPU2 > 4 speaker expansion enabled [quadraphenia]\n" );
			threadproc = (LPTHREAD_START_ROUTINE)&RThread<StereoQuadOut16>;
			speakerConfig = 4;
		break;

		case 6:
		case 7:
			ConLog( "* SPU2 > 5.1 speaker expansion enabled.\n" );
			threadproc = (LPTHREAD_START_ROUTINE)&RThread<Stereo51Out16>;
			speakerConfig = 6;
		break;

		default:
			ConLog( "* SPU2 > 7.1 speaker expansion enabled.\n" );
			threadproc = (LPTHREAD_START_ROUTINE)&RThread<Stereo51Out16>;
			speakerConfig = 8;
		break;
		}
#endif

        wformat.wFormatTag = WAVE_FORMAT_PCM;
        wformat.nSamplesPerSec = SampleRate;
        wformat.wBitsPerSample = 16;
        wformat.nChannels = 2;
        wformat.nBlockAlign = ((wformat.wBitsPerSample * wformat.nChannels) / 8);
        wformat.nAvgBytesPerSec = (wformat.nSamplesPerSec * wformat.nBlockAlign);
        wformat.cbSize = 0;

        qbuffer = new StereoOut16[BufferSize * numBuffers];

        woores = waveOutOpen(&hwodevice, WAVE_MAPPER, &wformat, 0, 0, 0);
        if (woores != MMSYSERR_NOERROR) {
            waveOutGetErrorText(woores, (wchar_t *)&ErrText, 255);
            SysMessage("WaveOut Error: %s", ErrText);
            return -1;
        }

        const int BufferSizeBytes = wformat.nBlockAlign * BufferSize;

        for (u32 i = 0; i < numBuffers; i++) {
            whbuffer[i].dwBufferLength = BufferSizeBytes;
            whbuffer[i].dwBytesRecorded = BufferSizeBytes;
            whbuffer[i].dwFlags = 0;
            whbuffer[i].dwLoops = 0;
            whbuffer[i].dwUser = 0;
            whbuffer[i].lpData = (LPSTR)QBUFFER(i);
            whbuffer[i].lpNext = 0;
            whbuffer[i].reserved = 0;
            waveOutPrepareHeader(hwodevice, whbuffer + i, sizeof(WAVEHDR));
            whbuffer[i].dwFlags |= WHDR_DONE;  //avoid deadlock
        }

        // Start Thread
        // [Air]: The waveout code does not use wait objects, so setting a time critical
        // priority level is a bad idea.  Standard priority will do fine.  The buffer will get the
        // love it needs and won't suck resources idling pointlessly.  Just don't try to
        // run it in uber-low-latency mode.
        waveout_running = true;
        thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RThread<StereoOut16>, this, 0, &tid);

        return 0;
    }
Пример #8
0
__fi void psxRcntWmode32( int index, u32 value )
{
	PSXCNT_LOG("32bit IOP Counter[%d] writeMode = 0x%04x", index, value );
	int irqmode = 0;
	pxAssume( index >= 3 && index < 6 );
	psxCounter& counter = psxCounters[index];

	counter.mode  = value;
	counter.mode |= 0x0400; //IRQ enable

	if (value & (1 << 4)) {
		irqmode += 1;
	}
	if (value & (1 << 5)) {
		irqmode += 2;
	}
	if (value & (1 << 7)) {
		PSXCNT_LOG("32 Counter %d Toggle IRQ on %s", index, (irqmode & 3) == 1 ? "Target" : ((irqmode & 3) == 2 ? "Overflow" : "Target and Overflow"));
	}
	else
	{
		PSXCNT_LOG("32 Counter %d Pulsed IRQ on %s", index, (irqmode & 3) == 1 ? "Target" : ((irqmode & 3) == 2 ? "Overflow" : "Target and Overflow"));
	}
	if (!(value & (1 << 6))) {
		PSXCNT_LOG("32 Counter %d One Shot", index);
	}
	else {
		PSXCNT_LOG("32 Counter %d Repeat", index);
	}
	if( index == 3 )
	{
		// Counter 3 has the HBlank as an alternate source.
		counter.rate  = 1;
		if(value & IOPCNT_ALT_SOURCE)
			counter.rate = PSXHBLANK;

		if(counter.mode & IOPCNT_ENABLE_GATE)
		{
			PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
			counter.mode |= IOPCNT_STOPPED;
			psxvblankgate |= 1<<3;
		}
		else psxvblankgate &= ~(1<<3);
	}
	else
	{
		switch(value & 0x6000)
		{
		case 0x0000: counter.rate = 1;   break;
		case 0x2000: counter.rate = 8;   break;
		case 0x4000: counter.rate = 16;  break;
		case 0x6000: counter.rate = 256; break;
		}

		// Need to set a rate and target
		if((counter.mode & 0x7) == 0x7 || (counter.mode & 0x7) == 0x1)
		{
			Console.WriteLn( "Gate set on IOP Counter %d, disabling", index );
			counter.mode |= IOPCNT_STOPPED;
		}
	}

	counter.count = 0;
	counter.sCycleT = psxRegs.cycle;
	counter.target &= 0xffffffff;
	_rcntSet( index );
}