예제 #1
0
파일: VPU1.cpp 프로젝트: RikoudoX/Play-
void CVPU1::Cmd_DIRECT(StreamType& stream, CODE nCommand)
{
	uint32 nSize = stream.GetAvailableReadBytes();
	nSize = std::min<uint32>(m_CODE.nIMM * 0x10, nSize);
	assert((nSize & 0x0F) == 0);

	if(nSize != 0)
	{
		uint8* packet = reinterpret_cast<uint8*>(alloca(nSize));
		stream.Read(packet, nSize);

		int32 remainingLength = nSize;
		while(remainingLength > 0)
		{
			uint32 processed = m_vif.GetGif().ProcessPacket(packet, 0, remainingLength, CGsPacketMetadata(2));
			packet += processed;
			remainingLength -= processed;
			assert(remainingLength >= 0);
		}
	}

	m_CODE.nIMM -= (nSize / 0x10);
	if((m_CODE.nIMM == 0) && (nSize != 0))
	{
		m_STAT.nVPS = 0;
	}
	else
	{
		m_STAT.nVPS = 1;
	}
}
예제 #2
0
파일: VPU.cpp 프로젝트: cmexp/Play-
bool CVPU::Unpack_V32(StreamType& stream, uint128& result, unsigned int fields)
{
	if(stream.GetAvailableReadBytes() < (fields * 4)) return false;

	stream.Read(&result, (fields * 4));

	return true;
}
예제 #3
0
파일: VPU.cpp 프로젝트: cmexp/Play-
bool CVPU::Unpack_V45(StreamType& stream, uint128& result)
{
	if(stream.GetAvailableReadBytes() < 2) return false;

	uint16 nColor = 0;
	stream.Read(&nColor, 2);

	result.nV0 = ((nColor >>  0) & 0x1F) << 3;
	result.nV1 = ((nColor >>  5) & 0x1F) << 3;
	result.nV2 = ((nColor >> 10) & 0x1F) << 3;
	result.nV3 = ((nColor >> 15) & 0x01) << 7;

	return true;
}
예제 #4
0
파일: VPU.cpp 프로젝트: cmexp/Play-
bool CVPU::Unpack_S32(StreamType& stream, uint128& result)
{
	if(stream.GetAvailableReadBytes() < 4) return false;

	uint32 word = 0;
	stream.Read(&word, 4);

	for(unsigned int i = 0; i < 4; i++)
	{
		result.nV[i] = word;
	}

	return true;
}
예제 #5
0
파일: VPU.cpp 프로젝트: cmexp/Play-
void CVPU::ProcessPacket(StreamType& stream)
{
	while(stream.GetAvailableReadBytes())
	{
		if(m_STAT.nVPS == 1)
		{
			//Command is waiting for more data...
			ExecuteCommand(stream, m_CODE);

			if((m_STAT.nVPS == 1) && (stream.GetAvailableReadBytes() != 0))
			{
				//We have data in our FIFO but we still need more than what's available
				break;
			}
			else
			{
				continue;
			}
		}
		if(m_STAT.nVEW == 1)
		{
			if(IsRunning()) break;
			m_STAT.nVEW = 0;
			//Command is waiting for micro-program to end.
			ExecuteCommand(stream, m_CODE);
			continue;
		}

#ifdef DELAYED_MSCAL
		m_previousCODE = m_CODE;
#endif
		stream.Read(&m_CODE, sizeof(CODE));

		assert(m_CODE.nI == 0);

		m_NUM = m_CODE.nNUM;

		ExecuteCommand(stream, m_CODE);
	}

#ifdef DELAYED_MSCAL
	if(stream.GetAvailableReadBytes() == 0)
	{
		ResumeDelayedMicroProgram();
	}
#endif
}
예제 #6
0
파일: VPU.cpp 프로젝트: cmexp/Play-
void CVPU::Cmd_MPG(StreamType& stream, CODE nCommand)
{
	uint32 nSize = stream.GetAvailableReadBytes();

	uint32 nNum			= (m_NUM == 0) ? (256) : (m_NUM);
	uint32 nCodeNum		= (m_CODE.nNUM == 0) ? (256) : (m_CODE.nNUM);
	uint32 nTransfered	= (nCodeNum - nNum) * 8;

	nCodeNum *= 8;
	nNum *= 8;

	nSize = std::min<uint32>(nNum, nSize);

	uint32 nDstAddr = (m_CODE.nIMM * 8) + nTransfered;

	//Check if microprogram is running
	if(IsRunning())
	{
		m_STAT.nVEW = 1;
		return;
	}

	if(nSize != 0)
	{
		uint8* microProgram = reinterpret_cast<uint8*>(alloca(nSize));
		stream.Read(microProgram, nSize);

		//Check if there's a change
		if(memcmp(m_microMem + nDstAddr, microProgram, nSize) != 0)
		{
			m_executor.ClearActiveBlocks();
			memcpy(m_microMem + nDstAddr, microProgram, nSize);
		}
	}

	m_NUM -= static_cast<uint8>(nSize / 8);
	if((m_NUM == 0) && (nSize != 0))
	{
		m_STAT.nVPS = 0;
	}
	else
	{
		m_STAT.nVPS = 1;
	}
}
예제 #7
0
파일: VPU.cpp 프로젝트: cmexp/Play-
bool CVPU::Unpack_V16(StreamType& stream, uint128& result, unsigned int fields, bool zeroExtend)
{
	if(stream.GetAvailableReadBytes() < (fields * 2)) return false;

	for(unsigned int i = 0; i < fields; i++)
	{
		uint32 temp = 0;
		stream.Read(&temp, 2);
		if(!zeroExtend)
		{
			temp = static_cast<int16>(temp);
		}

		result.nV[i] = temp;
	}

	return true;
}
예제 #8
0
파일: VPU.cpp 프로젝트: cmexp/Play-
bool CVPU::Unpack_S8(StreamType& stream, uint128& result, bool zeroExtend)
{
	if(stream.GetAvailableReadBytes() < 1) return false;

	uint32 temp = 0;
	stream.Read(&temp, 1);
	if(!zeroExtend)
	{
		temp = static_cast<int8>(temp);
	}

	for(unsigned int i = 0; i < 4; i++)
	{
		result.nV[i] = temp;
	}

	return true;
}
예제 #9
0
파일: VPU.cpp 프로젝트: cmexp/Play-
void CVPU::Cmd_STMASK(StreamType& stream, CODE command)
{
	if(m_NUM == 0)
	{
		m_NUM = 1;
	}

	while(m_NUM != 0 && stream.GetAvailableReadBytes())
	{
		stream.Read(&m_MASK, 4);
		m_NUM--;
	}

	if(m_NUM == 0)
	{
		m_STAT.nVPS = 0;
	}
	else
	{
		m_STAT.nVPS = 1;
	}
}
예제 #10
0
파일: VPU.cpp 프로젝트: cmexp/Play-
void CVPU::Cmd_STCOL(StreamType& stream, CODE nCommand)
{
	if(m_NUM == 0)
	{
		m_NUM = 4;
	}

	while(m_NUM != 0 && stream.GetAvailableReadBytes())
	{
		assert(m_NUM <= 4);
		stream.Read(&m_C[4 - m_NUM], 4);
		m_NUM--;
	}

	if(m_NUM == 0)
	{
		m_STAT.nVPS = 0;
	}
	else
	{
		m_STAT.nVPS = 1;
	}
}
예제 #11
0
파일: Vif1.cpp 프로젝트: unpeng/Play-
void CVif1::Cmd_DIRECT(StreamType& stream, CODE nCommand)
{
    uint32 nSize = stream.GetAvailableReadBytes();
    nSize = std::min<uint32>(m_CODE.nIMM * 0x10, nSize);
    assert((nSize & 0x0F) == 0);

    if(nSize != 0)
    {
        if(m_directBuffer.size() < nSize)
        {
            m_directBuffer.resize(nSize);
        }

        auto packet = m_directBuffer.data();
        stream.Read(packet, nSize);

        int32 remainingLength = nSize;
        while(remainingLength > 0)
        {
            uint32 processed = m_gif.ProcessPacket(packet, 0, remainingLength, CGsPacketMetadata(2));
            packet += processed;
            remainingLength -= processed;
            assert(remainingLength >= 0);
        }
    }

    m_CODE.nIMM -= (nSize / 0x10);
    if((m_CODE.nIMM == 0) && (nSize != 0))
    {
        m_STAT.nVPS = 0;
    }
    else
    {
        m_STAT.nVPS = 1;
    }
}