public int sceKernelUnlockLwMutex(int workAreaAddr, int count) { Memory mem = Processor.memory; int uid = mem.read32(workAreaAddr); if (log.isDebugEnabled()) { log.debug( "sceKernelUnlockLwMutex (workAreaAddr=0x" + Integer.toHexString(workAreaAddr) + ", count=" + count + ")"); } SceKernelLwMutexInfo info = lwMutexMap.get(uid); if (info == null) { log.warn("sceKernelUnlockLwMutex unknown uid"); return ERROR_KERNEL_LWMUTEX_NOT_FOUND; } if (info.lockedCount == 0) { log.debug("sceKernelUnlockLwMutex not locked"); return ERROR_KERNEL_LWMUTEX_UNLOCKED; } if (info.lockedCount < 0) { log.warn("sceKernelUnlockLwMutex underflow"); return ERROR_KERNEL_LWMUTEX_UNLOCK_UNDERFLOW; } info.lockedCount -= count; if (info.lockedCount == 0) { onLwMutexModified(info); } return 0; }
public int sceKernelReferLwMutexStatus(int workAreaAddr, int addr) { Memory mem = Processor.memory; int uid = mem.read32(workAreaAddr); if (log.isDebugEnabled()) { log.debug( "sceKernelReferLwMutexStatus (workAreaAddr=0x" + Integer.toHexString(workAreaAddr) + ", addr=0x" + addr + ")"); } SceKernelLwMutexInfo info = lwMutexMap.get(uid); if (info == null) { log.warn("sceKernelReferLwMutexStatus unknown UID " + Integer.toHexString(uid)); return ERROR_KERNEL_LWMUTEX_NOT_FOUND; } if (!Memory.isAddressGood(addr)) { log.warn("sceKernelReferLwMutexStatus bad address 0x" + Integer.toHexString(addr)); return -1; } info.write(mem, addr); return 0; }
@HLEFunction(nid = 0x4C06E472, version = 150) public int sceGeContinue() { PspGeList list; if (ExternalGE.isActive()) { list = ExternalGE.getCurrentList(); } else { list = VideoEngine.getInstance().getCurrentList(); } if (list != null) { synchronized (this) { if (list.status == PSP_GE_LIST_END_REACHED) { Memory mem = Memory.getInstance(); if (mem.read32(list.getPc()) == (GeCommands.FINISH << 24) && mem.read32(list.getPc() + 4) == (GeCommands.END << 24)) { list.readNextInstruction(); list.readNextInstruction(); } } list.restartList(); } } return 0; }
public int sceKernelTryLockLwMutex(int workAreaAddr, int count) { Memory mem = Processor.memory; int uid = mem.read32(workAreaAddr); if (log.isDebugEnabled()) { log.debug("sceKernelTryLockLwMutex redirecting to hleKernelLockLwMutex"); } return hleKernelLockLwMutex(uid, count, 0, false, false); }
public int sceKernelLockLwMutexCB(int workAreaAddr, int count, int timeout_addr) { Memory mem = Processor.memory; int uid = mem.read32(workAreaAddr); if (log.isDebugEnabled()) { log.debug("sceKernelLockLwMutexCB redirecting to hleKernelLockLwMutex"); } return hleKernelLockLwMutex(uid, count, timeout_addr, true, true); }
protected int copySamplesToMem(int address) { Memory mem = Memory.getInstance(); int bytes = me.getCurrentAudioSamples(samplesBuffer); if (bytes > 0) { atracEndSample += bytes; mem.copyToMemory(address, ByteBuffer.wrap(samplesBuffer, 0, bytes), bytes); } return bytes / bytesPerSample; }
public static void init() { if (!isInitialized) { List<String> libraries = new LinkedList<String>(); if (NativeCpuInfo.isAvailable()) { NativeCpuInfo.init(); if (NativeCpuInfo.hasAVX2()) { libraries.add("software-ge-renderer-AVX2"); } if (NativeCpuInfo.hasAVX()) { libraries.add("software-ge-renderer-AVX"); } if (NativeCpuInfo.hasSSE41()) { libraries.add("software-ge-renderer-SSE41"); } if (NativeCpuInfo.hasSSE3()) { libraries.add("software-ge-renderer-SSE3"); } if (NativeCpuInfo.hasSSE2()) { libraries.add("software-ge-renderer-SSE2"); } } libraries.add("software-ge-renderer"); boolean libraryExisting = false; // Search for an available library in preference order for (String library : libraries) { if (Utilities.isSystemLibraryExisting(library)) { libraryExisting = true; try { System.loadLibrary(library); if (Memory.getInstance() instanceof FastMemory) { memoryInt = ((FastMemory) Memory.getInstance()).getAll(); } initNative(); log.info(String.format("Loaded %s library", library)); isAvailable = true; } catch (UnsatisfiedLinkError e) { log.error(String.format("Could not load external software library %s: %s", library, e)); isAvailable = false; } break; } } if (!libraryExisting) { log.error(String.format("Missing external software library")); } isInitialized = true; } }
public CaptureRAM(int address, int length) throws IOException { packetSize = 8 + length; this.address = address; this.length = length; Memory mem = Memory.getInstance(); if (Memory.isAddressGood(address)) { buffer = mem.getBuffer(address, length); } if (buffer == null) { throw new IOException( String.format( "CaptureRAM: Unable to read buffer %08x - %08x", address, address + length)); } }
public int getAddress(Memory mem, int i) { if (ptr_index != 0 && index != 0) { int addr = ptr_index + i * index; switch (index) { case 1: i = mem.read8(addr); break; // GU_INDEX_8BIT case 2: i = mem.read16(addr); break; // GU_INDEX_16BIT case 3: i = mem.read32(addr); break; // GU_INDEX_UNK3 (assume 32bit) } } return ptr_vertex + i * vertexSize; }
@Override public void resolve(Memory mem, int address) { if (!hasSavedValue) { savedValue = mem.read32(getImportAddress()); hasSavedValue = true; } // Perform a R_MIPS_32 relocation // Retrieve the current 32bit value int value = mem.read32(getImportAddress()); // Relocate the value value += address; // Write back the relocated 32bit value mem.write32(getImportAddress(), value); }
public static Memory getInstance() { if (instance == null) { // // The following memory implementations are available: // - StandardMemory: low memory requirements, performs address checking, slow // - SafeFastMemory: high memory requirements, performs address checking, fast // - FastMemory : high memory requirements, no address checking, very fast // // Best choices are currently // 1) SafeFastMemory (address check is useful when debugging programs) // 2) StandardMemory when available memory is not sufficient for 1st choice // if (useSafeMemory) { instance = new SafeFastMemory(); } else { instance = new FastMemory(); } if (instance != null) { if (!instance.allocate()) { instance = null; } } if (instance == null) { instance = new StandardMemory(); if (!instance.allocate()) { instance = null; } } if (instance == null) { throw new OutOfMemoryError("Cannot allocate memory"); } if (useDebuggerMemory || new File(DebuggerMemory.mBrkFilePath).exists()) { DebuggerMemory.install(); } log.debug("Using " + instance.getClass().getName()); } return instance; }
public int sceKernelDeleteLwMutex(int workAreaAddr) { Memory mem = Processor.memory; int uid = mem.read32(workAreaAddr); if (log.isDebugEnabled()) { log.debug("sceKernelDeleteLwMutex (workAreaAddr='" + Integer.toHexString(workAreaAddr) + ")"); } SceKernelLwMutexInfo info = lwMutexMap.remove(uid); if (info == null) { log.warn("sceKernelDeleteLwMutex unknown UID " + Integer.toHexString(uid)); return ERROR_KERNEL_LWMUTEX_NOT_FOUND; } mem.write32(workAreaAddr, 0); // Clear uid. onLwMutexDeleted(uid); return 0; }
@Override public void unresolve(Memory mem) { if (hasSavedValue) { mem.write32(getImportAddress(), savedValue); } if (sourceModule != null) { // Add this stub back to the list of unresolved imports from the source module sourceModule.unresolvedImports.add(this); } }
/** * @return the UID assigned to the module or negative on error TODO need to figure out how the * uids work when 1 prx contains several modules. */ public int LoadFlash0Module(String prxname) { if (prxname != null) { List<HLEModule> modules = flash0prxMap.get(prxname.toLowerCase()); if (modules != null) { for (HLEModule module : modules) { installModuleWithAnnotations(module, firmwareVersion); } } } SceModule fakeModule = new SceModule(true); fakeModule.modname = prxname; fakeModule.write(Memory.getInstance(), fakeModule.address); Managers.modules.addModule(fakeModule); return fakeModule.modid; }
public void setMemorySize(int memorySize) { if (MemoryMap.SIZE_RAM != memorySize) { int previousMemorySize = MemoryMap.SIZE_RAM; MemoryMap.END_RAM = MemoryMap.START_RAM + memorySize - 1; MemoryMap.END_USERSPACE = MemoryMap.END_RAM; MemoryMap.SIZE_RAM = MemoryMap.END_RAM - MemoryMap.START_RAM + 1; if (!Memory.getInstance().allocate()) { log.error( String.format( "Failed to resize the PSP memory from 0x%X to 0x%X", previousMemorySize, memorySize)); Emulator.PauseEmuWithStatus(Emulator.EMU_STATUS_MEM_ANY); } reset(); } }
public void commit() { Memory.getInstance().copyToMemory(address, (ByteBuffer) buffer, length); }
public int atracDecodeData(int atracID, int address, int channels) { int samples = 0; boolean isEnded = false; if (checkMediaEngineState()) { if (me.getContainer() == null && atracChannel != null) { if (requireAllAtracData) { if (atracChannel.length() >= atracFileSize) { requireAllAtracData = false; if (checkMediaEngineState() && ExternalDecoder.isEnabled()) { String decodedFile = externalDecoder.decodeAtrac( atracChannel, atracBufferAddress, atracFileSize, atracHash); if (decodedFile != null) { Modules.log.info( "AT3+ data decoded by the external decoder (all AT3+ data retrieved)."); me.finish(); atracChannel = null; me.init(new FileProtocolHandler(decodedFile), false, true, 0, 0); atracEndSample = -1; } else { Modules.log.info( "AT3+ data could not be decoded by the external decoder, even after retrieving all AT3+ data."); me = null; } } else { Modules.log.info( "AT3+ data could not be decoded by the external decoder, even after retrieving all AT3+ data."); me = null; } if (me == null) { return atracDecodeData(atracID, address, channels); } } else { // Fake returning 1 sample with remainFrames == 0 // to force a call to sceAtracAddStreamData. samples = 1; Memory.getInstance().memset(address, (byte) 0, samples * bytesPerSample); } } else if (atracChannel.length() >= getAtracChannelStartLength() || atracChannel.length() >= atracFileSize) { me.init(atracChannel, false, true, 0, 0); } else { // Fake returning 1 sample with remainFrames == 0 // to force a call to sceAtracAddStreamData. samples = 1; Memory.getInstance().memset(address, (byte) 0, samples * bytesPerSample); } } setChannels(channels); if (me.stepAudio(atracMaxSamples * bytesPerSample, channels)) { samples = copySamplesToMem(address); } if (samples == 0) { isEnded = true; } } else if (decodedStream != null) { try { int length = decodedStream.read(atracDecodeBuffer); if (length > 0) { samples = length / 4; Memory.getInstance() .copyToMemory(address, ByteBuffer.wrap(atracDecodeBuffer, 0, length), length); long restLength = decodedStream.length() - decodedStream.getFilePointer(); if (restLength <= 0) { isEnded = true; } } else { isEnded = true; } } catch (IOException e) { Modules.log.warn(e); } } else { samples = -1; isEnded = true; } if (isEnded) { atracEnd = 1; } else { atracEnd = 0; } return samples; }
public void atracSetData( int atracID, int codecType, int address, int length, int atracFileSize, int atracHash) { this.atracFileSize = atracFileSize; this.atracBufferAddress = address; this.atracHash = atracHash; id = generateID(address, length, atracFileSize); closeStreams(); atracEndSample = -1; requireAllAtracData = false; int memoryCodecType = sceAtrac3plus.getCodecType(address); if (memoryCodecType != codecType && memoryCodecType != 0) { Modules.log.info( String.format( "Different CodecType received %d != %d, assuming %d", codecType, memoryCodecType, memoryCodecType)); codecType = memoryCodecType; } if (codecType == 0x00001001) { Modules.log.info("Decodable AT3 data detected."); if (checkMediaEngineState()) { me.finish(); atracChannel = new PacketChannel(); atracChannel.setTotalStreamSize(atracFileSize); atracChannel.setFarRewindAllowed(true); atracChannel.write(address, length); // Defer the initialization of the MediaEngine until atracDecodeData() // to ensure we have enough data into the channel. atracEndSample = 0; return; } } else if (codecType == 0x00001000) { if (checkMediaEngineState() && ExternalDecoder.isEnabled()) { String decodedFile = externalDecoder.decodeAtrac(address, length, atracFileSize, atracHash, this); if (decodedFile != null) { Modules.log.info("AT3+ data decoded by the external decoder."); me.finish(); atracChannel = null; me.init(new FileProtocolHandler(decodedFile), false, true, 0, 0); atracEndSample = -1; return; } else if (requireAllAtracData) { // The external decoder requires all the atrac data // before it can try to decode the atrac. me.finish(); atracChannel = new PacketChannel(); atracChannel.setTotalStreamSize(atracFileSize); atracChannel.write(address, length); return; } Modules.log.info("AT3+ data could not be decoded by the external decoder."); } else { Modules.log.info("Undecodable AT3+ data detected."); } } me = null; File decodedFile = new File(getCompleteFileName(decodedAtracSuffix)); if (!decodedFile.canRead()) { // Try to read the decoded file using an alternate file name, // without HashCode. These files can be generated by external tools // decoding the Atrac3+ files. These tools can't generate the HashCode. // // Use the following alternate file name scheme: // Atrac-SSSSSSSS-NNNNNNNN-DDDDDDDD.at3.decoded // where SSSSSSSS is the file size in Hex // NNNNNNNN is the number of samples in Hex found in the "fact" Chunk // DDDDDDDD are the first 32-bit in Hex found in the "data" Chunk int numberOfSamples = 0; int data = 0; // Scan the Atrac data for NNNNNNNN and DDDDDDDD values Memory mem = Memory.getInstance(); int scanAddress = address + 12; int endScanAddress = address + length; while (scanAddress < endScanAddress) { int chunkHeader = mem.read32(scanAddress); int chunkSize = mem.read32(scanAddress + 4); if (chunkHeader == waveFactChunkHeader) { numberOfSamples = mem.read32(scanAddress + 8); } else if (chunkHeader == waveDataChunkHeader) { data = mem.read32(scanAddress + 8); break; } // Go to the next Chunk scanAddress += chunkSize + 8; } File alternateDecodedFile = new File( String.format( "%sAtrac-%08X-%08X-%08X%s", getBaseDirectory(), atracFileSize, numberOfSamples, data, decodedAtracSuffix)); if (alternateDecodedFile.canRead()) { decodedFile = alternateDecodedFile; } } File atracFile = new File(getCompleteFileName(atracSuffix)); if (decodedFile.canRead()) { try { decodedStream = new RandomAccessFile(decodedFile, "r"); atracEndSample = (int) (decodedFile.length() / 4); } catch (FileNotFoundException e) { // Decoded file should already be present Modules.log.warn(e); } } else if (atracFile.canRead() && atracFile.length() == atracFileSize) { // Atrac file is already written, no need to write it again } else if (sceAtrac3plus.isEnableConnector()) { commandFileDirty = true; displayInstructions(); new File(getBaseDirectory()).mkdirs(); try { atracStream = new FileOutputStream(getCompleteFileName(atracSuffix)); byte[] buffer = new byte[length]; IMemoryReader memoryReader = MemoryReader.getMemoryReader(address, length, 1); for (int i = 0; i < length; i++) { buffer[i] = (byte) memoryReader.readNext(); } atracStream.write(buffer); } catch (IOException e) { Modules.log.warn(e); } generateCommandFile(); } }