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);
  }
Example #2
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();
      }
    }
  }
Example #3
0
  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;
  }
Example #4
0
  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();
  }
Example #6
0
  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();
    }
  }