Beispiel #1
0
int GPUCommon::GetStack(int index, u32 stackPtr) {
	easy_guard guard(listLock);
	if (currentList == NULL) {
		// Seems like it doesn't return an error code?
		return 0;
	}

	if (currentList->stackptr <= index) {
		return SCE_KERNEL_ERROR_INVALID_INDEX;
	}

	if (index >= 0) {
		PSPPointer<u32> stack;
		stack = stackPtr;
		if (stack.IsValid()) {
			auto entry = currentList->stack[index];
			// Not really sure what most of these values are.
			stack[0] = 0;
			stack[1] = entry.pc + 4;
			stack[2] = entry.offsetAddr;
			stack[7] = entry.baseAddr;
		}
	}

	return currentList->stackptr;
}
Beispiel #2
0
	void WriteBuffer(u32 srcPtr, u32 len)
	{
		Memory::Memcpy(bufAddr + (bufSize - freeSize), srcPtr, len);
		freeSize -= len;
		if (transferredBytes.IsValid())
			*transferredBytes += len;
	}
Beispiel #3
0
	void ReadBuffer(u32 destPtr, u32 len)
	{
		Memory::Memcpy(destPtr, bufAddr + bufSize - freeSize, len);
		freeSize -= len;
		if (transferredBytes.IsValid())
			*transferredBytes += len;
	}
Beispiel #4
0
Psmf *getPsmf(u32 psmf)
{
	PSPPointer<PsmfData> psmfstruct;
	psmfstruct = psmf;
	if (!psmfstruct.IsValid())
		return 0;
	auto iter = psmfMap.find(psmfstruct->headerOffset);
	if (iter != psmfMap.end())
		return iter->second;
	else
		return 0;
}
Beispiel #5
0
static int __CtrlReadSingleBuffer(PSPPointer<_ctrl_data> data, bool negative)
{
	if (data.IsValid())
	{
		*data = ctrlBufs[ctrlBufRead];
		ctrlBufRead = (ctrlBufRead + 1) % NUM_CTRL_BUFFERS;

		if (negative)
			data->buttons = ~data->buttons;

		return 1;
	}

	return 0;
}
Beispiel #6
0
int sceMpegRingbufferAvailableSize(u32 ringbufferAddr)
{
	PSPPointer<SceMpegRingBuffer> ringbuffer;
	ringbuffer = ringbufferAddr;

	if (!ringbuffer.IsValid()) {
		ERROR_LOG(HLE, "sceMpegRingbufferAvailableSize(%08x) - bad address", ringbufferAddr);
		return -1;
	}

	MpegContext *ctx = getMpegCtx(ringbuffer->mpeg);
	if (!ctx) {
		ERROR_LOG(HLE, "sceMpegRingbufferAvailableSize(%08x) - bad mpeg", ringbufferAddr);
		return -1;
	}

	hleEatCycles(2020);
	DEBUG_LOG(HLE, "%i=sceMpegRingbufferAvailableSize(%08x)", ringbuffer->packetsFree, ringbufferAddr);
	return ringbuffer->packetsFree;
}
Beispiel #7
0
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le> em_address)
{
	if (!em_address.IsValid())
	{
		_string = "";
		return;
	}

	char stringBuffer[2048];
	char *string = stringBuffer;

	auto input = em_address;
	int c;
	while ((c = *input++) != 0)
	{
		if (c < 0x80)
			*string++ = c;
		else if (c < 0x800) {
			*string++ = 0xC0 | (c >> 6);
			*string++ = 0x80 | (c & 0x3F);
		} else {
Beispiel #8
0
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le>& em_address)
{
	if (!em_address.IsValid())
	{
		_string = "";
		return;
	}

	const size_t maxLength = 2047;
	char stringBuffer[maxLength + 1];
	char *string = stringBuffer;

	u16_le *input = &em_address[0];
	int c;
	while ((c = *input++) != 0 && string < stringBuffer + maxLength)
	{
		if (c < 0x80)
			*string++ = c;
		else if (c < 0x800) {
			*string++ = 0xC0 | (c >> 6);
			*string++ = 0x80 | (c & 0x3F);
		} else {
Beispiel #9
0
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<PspGeListArgs> args, bool head) {
	easy_guard guard(listLock);
	// TODO Check the stack values in missing arg and ajust the stack depth

	// Check alignment
	// TODO Check the context and stack alignement too
	if (((listpc | stall) & 3) != 0)
		return SCE_KERNEL_ERROR_INVALID_POINTER;

	int id = -1;
	bool oldCompatibility = true;
	if (sceKernelGetCompiledSdkVersion() > 0x01FFFFFF) {
		//numStacks = 0;
		//stack = NULL;
		oldCompatibility = false;
	}

	u64 currentTicks = CoreTiming::GetTicks();
	for (int i = 0; i < DisplayListMaxCount; ++i) {
		if (dls[i].state != PSP_GE_DL_STATE_NONE && dls[i].state != PSP_GE_DL_STATE_COMPLETED) {
			if (dls[i].pc == listpc && !oldCompatibility) {
				ERROR_LOG(G3D, "sceGeListEnqueue: can't enqueue, list address %08X already used", listpc);
				return 0x80000021;
			}
			//if(dls[i].stack == stack) {
			//	ERROR_LOG(G3D, "sceGeListEnqueue: can't enqueue, list stack %08X already used", context);
			//	return 0x80000021;
			//}
		}
	}
	for (int i = 0; i < DisplayListMaxCount; ++i) {
		int possibleID = (i + nextListID) % DisplayListMaxCount;
		auto possibleList = dls[possibleID];
		if (possibleList.pendingInterrupt) {
			continue;
		}

		if (possibleList.state == PSP_GE_DL_STATE_NONE) {
			id = possibleID;
			break;
		}
		if (possibleList.state == PSP_GE_DL_STATE_COMPLETED && possibleList.waitTicks < currentTicks) {
			id = possibleID;
		}
	}
	if (id < 0) {
		ERROR_LOG_REPORT(G3D, "No DL ID available to enqueue");
		for (auto it = dlQueue.begin(); it != dlQueue.end(); ++it) {
			DisplayList &dl = dls[*it];
			DEBUG_LOG(G3D, "DisplayList %d status %d pc %08x stall %08x", *it, dl.state, dl.pc, dl.stall);
		}
		return SCE_KERNEL_ERROR_OUT_OF_MEMORY;
	}
	nextListID = id + 1;

	DisplayList &dl = dls[id];
	dl.id = id;
	dl.startpc = listpc & 0x0FFFFFFF;
	dl.pc = listpc & 0x0FFFFFFF;
	dl.stall = stall & 0x0FFFFFFF;
	dl.subIntrBase = std::max(subIntrBase, -1);
	dl.stackptr = 0;
	dl.signal = PSP_GE_SIGNAL_NONE;
	dl.interrupted = false;
	dl.waitTicks = (u64)-1;
	dl.interruptsEnabled = interruptsEnabled_;
	dl.started = false;
	dl.offsetAddr = 0;
	dl.bboxResult = false;

	if (args.IsValid() && args->context.IsValid())
		dl.context = args->context;
	else
		dl.context = NULL;

	if (head) {
		if (currentList) {
			if (currentList->state != PSP_GE_DL_STATE_PAUSED)
				return SCE_KERNEL_ERROR_INVALID_VALUE;
			currentList->state = PSP_GE_DL_STATE_QUEUED;
		}

		dl.state = PSP_GE_DL_STATE_PAUSED;

		currentList = &dl;
		dlQueue.push_front(id);
	} else if (currentList) {
		dl.state = PSP_GE_DL_STATE_QUEUED;
		dlQueue.push_back(id);
	} else {
		dl.state = PSP_GE_DL_STATE_RUNNING;
		currentList = &dl;
		dlQueue.push_front(id);

		drawCompleteTicks = (u64)-1;

		// TODO save context when starting the list if param is set
		guard.unlock();
		ProcessDLQueue();
	}

	return id;
}