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; }
void WriteBuffer(u32 srcPtr, u32 len) { Memory::Memcpy(bufAddr + (bufSize - freeSize), srcPtr, len); freeSize -= len; if (transferredBytes.IsValid()) *transferredBytes += len; }
void ReadBuffer(u32 destPtr, u32 len) { Memory::Memcpy(destPtr, bufAddr + bufSize - freeSize, len); freeSize -= len; if (transferredBytes.IsValid()) *transferredBytes += len; }
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; }
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; }
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; }
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 {
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 {
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; }