Exemple #1
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;
  }
Exemple #2
0
  @HLEFunction(nid = 0x57C8945B, version = 150)
  public int sceGeGetMtx(int mtxType, TPointer mtxAddr) {
    if (mtxType < 0 || mtxType > PSP_GE_MATRIX_TEXGEN) {
      log.warn(String.format("sceGeGetMtx invalid type mtxType=%d", mtxType));
      return SceKernelErrors.ERROR_INVALID_INDEX;
    }

    float[] mtx;
    if (ExternalGE.isActive()) {
      mtx = ExternalGE.getMatrix(mtxType);
    } else {
      mtx = VideoEngine.getInstance().getMatrix(mtxType);
    }

    for (int i = 0; i < mtx.length; i++) {
      // Float value is returned in lower 24 bits.
      mtxAddr.setValue32(i << 2, Float.floatToRawIntBits(mtx[i]) >>> 8);
    }

    if (log.isInfoEnabled()) {
      log.info(String.format("sceGeGetMtx mtxType=%d, mtxAddr=%s, mtx=%s", mtxType, mtxAddr, mtx));
    }

    return 0;
  }
Exemple #3
0
  @HLEFunction(nid = 0xB448EC0D, version = 150)
  public int sceGeBreak(@CheckArgument("checkMode") int mode, TPointer brk_addr) {
    int result = 0;

    PspGeList list;
    if (ExternalGE.isActive()) {
      list = ExternalGE.getCurrentList();
    } else {
      list = VideoEngine.getInstance().getCurrentList();
    }

    if (mode == 0) { // Pause the current list only.
      if (list != null) {
        list.pauseList();
        result = list.id;
      }
    } else if (mode == 1) { // Pause the current list and cancel the rest of the queue.
      if (list != null) {
        list.pauseList();
        for (int i = 0; i < NUMBER_GE_LISTS; i++) {
          allGeLists[i].status = PSP_GE_LIST_CANCEL_DONE;
        }
        result = list.id;
      }
    }

    return result;
  }
Exemple #4
0
  @Override
  public void stop() {
    log.debug(String.format("Stopping %s", getName()));

    if (ExternalGE.isActive()) {
      ExternalGE.onGeUserStop();
    }
  }
Exemple #5
0
  @HLEFunction(nid = 0x0BF608FB, version = 150)
  public int sceGeRestoreContext(TPointer contextAddr) {
    if (ExternalGE.isActive()) {
      return ExternalGE.restoreContext(contextAddr.getAddress());
    }

    VideoEngine.getInstance().hleRestoreContext(contextAddr.getAddress());

    return 0;
  }
Exemple #6
0
  @HLEFunction(nid = 0x438A385A, version = 150)
  public int sceGeSaveContext(TPointer contextAddr) {
    if (ExternalGE.isActive()) {
      return ExternalGE.saveContext(contextAddr.getAddress());
    }

    VideoEngine.getInstance().hleSaveContext(contextAddr.getAddress());

    return 0;
  }
Exemple #7
0
  @HLEFunction(nid = 0xB287BD61, version = 150)
  public int sceGeDrawSync(@CheckArgument("checkMode") int mode) {
    if (mode == 0 && IntrManager.getInstance().isInsideInterrupt()) {
      log.debug("sceGeDrawSync (mode==0) cannot be called inside an interrupt handler!");
      return SceKernelErrors.ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT;
    }

    // no synchronization on "this" required because we are not accessing
    // local data, only list information from the VideoEngine.
    int result = 0;
    if (mode == 0) {
      PspGeList lastList;
      if (ExternalGE.isActive()) {
        lastList = ExternalGE.getLastDrawList();
      } else {
        lastList = VideoEngine.getInstance().getLastDrawList();
      }

      if (lastList != null) {
        blockCurrentThreadOnList(lastList, new HLEAfterDrawSyncAction());
      } else {
        if (log.isDebugEnabled()) {
          log.debug("sceGeDrawSync all lists completed, not waiting");
        }
        hleGeAfterDrawSyncAction();
        Modules.ThreadManForUserModule.hleRescheduleCurrentThread();
      }
    } else if (mode == 1) {
      PspGeList currentList;
      if (ExternalGE.isActive()) {
        currentList = ExternalGE.getFirstDrawList();
      } else {
        currentList = VideoEngine.getInstance().getFirstDrawList();
      }
      if (currentList != null) {
        result = currentList.status;
      }
      if (log.isDebugEnabled()) {
        log.debug(String.format("sceGeDrawSync mode=%d, returning %d", mode, result));
      }
    }

    return result;
  }
Exemple #8
0
  @HLEFunction(nid = 0xDC93CFEF, version = 150)
  public int sceGeGetCmd(int cmd) {
    VideoEngine ve = VideoEngine.getInstance();
    int value;
    if (ExternalGE.isActive()) {
      value = ExternalGE.getCmd(cmd);
    } else {
      value = ve.getCommandValue(cmd);
    }

    if (log.isInfoEnabled()) {
      log.info(
          String.format(
              "sceGeGetCmd %s: cmd=0x%X, value=0x%06X",
              ve.commandToString(cmd).toUpperCase(), cmd, value));
    }

    return value;
  }
Exemple #9
0
    @Override
    public boolean continueWaitState(SceKernelThreadInfo thread, ThreadWaitInfo wait) {
      // Continue the wait state until the list is done
      boolean contineWait = !list.isDone();

      if (!contineWait) {
        ExternalGE.onGeStopWaitList();
      }

      return contineWait;
    }
Exemple #10
0
  private void blockCurrentThreadOnList(PspGeList list, IAction action) {
    ThreadManForUser threadMan = Modules.ThreadManForUserModule;

    boolean blockCurrentThread = false;
    boolean executeAction = false;

    synchronized (this) {
      int currentThreadId = threadMan.getCurrentThreadID();
      if (list.isDone()) {
        // There has been some race condition: the list has just completed
        // do not block the thread
        if (log.isDebugEnabled()) {
          log.debug(
              "blockCurrentThreadOnList not blocking thread "
                  + Integer.toHexString(currentThreadId)
                  + ", list completed "
                  + list);
        }
        executeAction = true;
      } else {
        if (log.isDebugEnabled()) {
          log.debug(
              "blockCurrentThreadOnList blocking thread "
                  + Integer.toHexString(currentThreadId)
                  + " on list "
                  + list);
        }
        list.blockedThreadIds.add(currentThreadId);
        blockCurrentThread = true;
      }
    }

    // Execute the action outside of the synchronized block
    if (executeAction && action != null) {
      action.execute();
    }

    // Block the thread outside of the synchronized block
    if (blockCurrentThread) {
      // Block the thread, but do not execute callbacks.
      threadMan.hleBlockCurrentThread(
          SceKernelThreadInfo.JPCSP_WAIT_GE_LIST,
          list.id,
          false,
          action,
          new ListSyncWaitStateChecker(list));

      ExternalGE.onGeStartWaitList();
    }
  }
Exemple #11
0
  public void step() {
    ThreadManForUser threadMan = Modules.ThreadManForUserModule;

    for (Integer thid = deferredThreadWakeupQueue.poll();
        thid != null;
        thid = deferredThreadWakeupQueue.poll()) {
      if (log.isDebugEnabled()) {
        log.debug(
            "really waking thread "
                + Integer.toHexString(thid)
                + "("
                + threadMan.getThreadName(thid)
                + ")");
      }
      threadMan.hleUnblockThread(thid);

      ExternalGE.onGeStopWaitList();
    }
  }
Exemple #12
0
  public int hleGeListEnQueue(
      TPointer listAddr,
      @CanBeNull TPointer stallAddr,
      int cbid,
      @CanBeNull TPointer argAddr,
      int saveContextAddr,
      boolean enqueueHead) {
    pspGeListOptParam optParams = null;
    int stackAddr = 0;
    if (argAddr.isNotNull()) {
      optParams = new pspGeListOptParam();
      optParams.read(argAddr);
      stackAddr = optParams.stackAddr;
      if (log.isDebugEnabled()) {
        log.debug(String.format("hleGeListEnQueue optParams=%s", optParams));
      }
    }

    if (Modules.SysMemUserForUserModule.hleKernelGetCompiledSdkVersion() >= 0x02000000) {
      boolean isBusy;
      if (ExternalGE.isActive()) {
        isBusy = ExternalGE.hasDrawList(listAddr.getAddress(), stackAddr);
      } else {
        isBusy = VideoEngine.getInstance().hasDrawList(listAddr.getAddress(), stackAddr);
      }
      if (isBusy) {
        log.warn(
            String.format(
                "hleGeListEnQueue can't enqueue duplicate list address %s, stack 0x%08X",
                listAddr, stackAddr));
        return SceKernelErrors.ERROR_BUSY;
      }
    }

    int result;
    synchronized (this) {
      PspGeList list = listFreeQueue.poll();
      if (list == null) {
        log.warn("hleGeListEnQueue no more free list available!");
        if (log.isDebugEnabled()) {
          for (int i = 0; i < NUMBER_GE_LISTS; i++) {
            log.debug(String.format("List#%d: %s", i, allGeLists[i]));
          }
        }
        return SceKernelErrors.ERROR_OUT_OF_MEMORY;
      }

      list.init(listAddr.getAddress(), stallAddr.getAddress(), cbid, optParams);
      list.setSaveContextAddr(saveContextAddr);
      if (enqueueHead) {
        // Send the list to the VideoEngine at the head of the queue.
        list.startListHead();
      } else {
        // Send the list to the VideoEngine before triggering the display (setting GE dirty)
        list.startList();
      }
      Modules.sceDisplayModule.setGeDirty(true);
      result = list.id;
    }

    if (log.isDebugEnabled()) {
      log.debug(String.format("hleGeListEnQueue returning 0x%X", result));
    }

    return result;
  }