public static void call() { int src1Addr = getGprA0(); int src2Addr = getGprA1(); int n = getGprA2(); if (n > 0) { IMemoryReader memoryReader1 = MemoryReader.getMemoryReader(src1Addr, n, 1); IMemoryReader memoryReader2 = MemoryReader.getMemoryReader(src2Addr, n, 1); if (memoryReader1 != null && memoryReader2 != null) { for (int i = 0; i < n; i++) { int c1 = memoryReader1.readNext(); int c2 = memoryReader2.readNext(); if (c1 != c2) { setGprV0(c1 - c2); return; } else if (c1 == 0) { // c1 == 0 and c2 == 0 break; } } } } setGprV0(0); }
private void readForCache(int numberOfVertex) { if (cachedIndices != null || cachedVertices != null) { return; } int vertexArraySize; if (ptr_index != 0 && index != 0) { IMemoryReader memoryReader = null; switch (index) { case 1: { // GU_INDEX_8BIT memoryReader = MemoryReader.getMemoryReader(ptr_index, 1 * numberOfVertex, 1); break; } case 2: { // GU_INDEX_16BIT memoryReader = MemoryReader.getMemoryReader(ptr_index, 2 * numberOfVertex, 2); break; } case 3: { // GU_INDEX_UNK3 (assume 32bit) memoryReader = MemoryReader.getMemoryReader(ptr_index, 4 * numberOfVertex, 4); break; } } // Remember the largest index int maxIndex = -1; if (memoryReader != null) { cachedIndices = new int[numberOfVertex]; for (int i = 0; i < numberOfVertex; i++) { int index = memoryReader.readNext(); cachedIndices[i] = index; if (index > maxIndex) { maxIndex = index; } } } // The vertex array extends only up to the largest index vertexArraySize = vertexSize * (maxIndex + 1); } else { vertexArraySize = vertexSize * numberOfVertex; } if (ptr_vertex != 0) { vertexArraySize = (vertexArraySize + 3) & ~3; cachedVertices = new int[vertexArraySize >> 2]; IMemoryReader verticesReader = MemoryReader.getMemoryReader(ptr_vertex, vertexArraySize, 4); for (int i = 0; i < cachedVertices.length; i++) { cachedVertices[i] = verticesReader.readNext(); } } }
private boolean isNativeCodeSequence( NativeCodeSequence nativeCodeSequence, CodeInstruction codeInstruction, CodeBlock codeBlock) { int address = codeInstruction.getAddress(); int numOpcodes = nativeCodeSequence.getNumOpcodes(); // Can this NativeCodeSequence only match a whole CodeBlock? if (nativeCodeSequence.isWholeCodeBlock()) { // Match only a whole CodeBlock: same StartAddress, same Length if (codeBlock.getStartAddress() != address) { return false; } if (codeBlock.getLength() != numOpcodes) { return false; } } IMemoryReader codeBlockReader = MemoryReader.getMemoryReader(address, 4); for (int i = 0; i < numOpcodes; i++) { int opcode = codeBlockReader.readNext(); if (!nativeCodeSequence.isMatching(i, opcode)) { return false; } } return true; }
public void atracAddStreamData(int address, int length) { if (checkMediaEngineState()) { if (atracChannel != null) { atracChannel.write(address, length); } return; } if (atracStream != null) { try { 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.error(e); } } }
public void write(OutputStream out) throws IOException { DataOutputStream data = new DataOutputStream(out); data.writeInt(packetSize); data.writeInt(address); data.writeInt(length); if (buffer instanceof ByteBuffer) { WritableByteChannel channel = Channels.newChannel(out); channel.write((ByteBuffer) buffer); } else { IMemoryReader reader = MemoryReader.getMemoryReader(address, length, 1); for (int i = 0; i < length; i++) { data.writeByte(reader.readNext()); } } VideoEngine.log.info( String.format("Saved memory %08x - %08x (len %08x)", address, address + length, length)); // VideoEngine.log.info("CaptureRAM write " + ((3 * 4) + length)); // data.flush(); // out.flush(); }
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(); } }