Skip to content

Commit

Permalink
sceKernelRegisterIntrHandler, sceKernelRegisterSubIntrHandler: set $gp
Browse files Browse the repository at this point in the history
register when callling the interrupt handler.
Implemented sceKernelGetModuleGPByAddressForKernel()
  • Loading branch information
gid15 committed Oct 6, 2020
1 parent 9ca7097 commit 5bbc2ad
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 14 deletions.
9 changes: 6 additions & 3 deletions src/jpcsp/HLE/kernel/managers/IntrManager.java
Expand Up @@ -26,6 +26,7 @@
import jpcsp.HLE.Modules;
import jpcsp.HLE.TPointer;
import jpcsp.HLE.TPointer32;
import jpcsp.HLE.kernel.Managers;
import jpcsp.HLE.kernel.types.IAction;
import jpcsp.HLE.kernel.types.SceKernelErrors;
import jpcsp.HLE.kernel.types.interrupts.AbstractAllegrexInterruptHandler;
Expand Down Expand Up @@ -262,7 +263,7 @@ public void continueCallAllegrexInterruptHandler(InterruptState interruptState,
log.debug("Calling InterruptHandler " + allegrexInterruptHandler.toString());
}
allegrexInterruptHandler.copyArgumentsToCpu(Emulator.getProcessor().cpu);
Modules.ThreadManForUserModule.callAddress(allegrexInterruptHandler.getAddress(), continueAction, true);
Modules.ThreadManForUserModule.callAddress(allegrexInterruptHandler.getAddress(), continueAction, true, allegrexInterruptHandler.getGp());
somethingExecuted = true;
}
} else {
Expand Down Expand Up @@ -367,7 +368,8 @@ public int sceKernelRegisterSubIntrHandler(int intrNumber, int subIntrNumber, TP
return SceKernelErrors.ERROR_KERNEL_SUBINTR_ALREADY_REGISTERED;
}

SubIntrHandler subIntrHandler = new SubIntrHandler(handlerAddress.getAddress(), subIntrNumber, handlerArgument);
int gp = Managers.modules.getModuleGpByAddress(handlerAddress.getAddress());
SubIntrHandler subIntrHandler = new SubIntrHandler(handlerAddress.getAddress(), gp, subIntrNumber, handlerArgument);
subIntrHandler.setEnabled(false);
intrHandlers[intrNumber].addSubIntrHandler(subIntrNumber, subIntrHandler);

Expand Down Expand Up @@ -430,7 +432,8 @@ public int sceKernelRegisterIntrHandler(int intrNumber, int unknown, TPointer fu
return -1;
}

AbstractInterruptHandler interruptHandler = new InterruptHandler(func, funcArg);
int gp = Managers.modules.getModuleGpByAddress(func.getAddress());
AbstractInterruptHandler interruptHandler = new InterruptHandler(func, gp, funcArg);
addInterruptHandler(intrNumber, interruptHandler);

return 0;
Expand Down
9 changes: 9 additions & 0 deletions src/jpcsp/HLE/kernel/managers/ModuleManager.java
Expand Up @@ -72,6 +72,15 @@ public SceModule getModuleByAddress(int address) {
return null;
}

public int getModuleGpByAddress(int address) {
SceModule module = getModuleByAddress(address);
if (module == null) {
return 0;
}

return module.gp_value;
}

public static final ModuleManager singleton;

static {
Expand Down
Expand Up @@ -22,6 +22,7 @@ public class AbstractAllegrexInterruptHandler {
private int address;
private int[] arguments = new int[4];
private int numberArguments;
private int gp;

public AbstractAllegrexInterruptHandler(int address) {
this.address = address;
Expand Down Expand Up @@ -82,6 +83,14 @@ public int getNumberArguments() {
return numberArguments;
}

public int getGp() {
return gp;
}

public void setGp(int gp) {
this.gp = gp;
}

public void copyArgumentsToCpu(CpuState cpu) {
switch (numberArguments) {
case 4: cpu._a3 = arguments[3];
Expand Down
6 changes: 4 additions & 2 deletions src/jpcsp/HLE/kernel/types/interrupts/InterruptHandler.java
Expand Up @@ -21,15 +21,17 @@

public class InterruptHandler extends AbstractInterruptHandler {
private TPointer func;
private int gp;
private int funcArg;

public InterruptHandler(TPointer func, int funcArg) {
public InterruptHandler(TPointer func, int gp, int funcArg) {
this.func = func;
this.gp = gp;
this.funcArg = funcArg;
}

@Override
protected void executeInterrupt() {
Modules.ThreadManForUserModule.executeCallback(null, func.getAddress(), null, true, funcArg);
Modules.ThreadManForUserModule.executeCallback(func.getAddress(), gp, null, funcArg);
}
}
3 changes: 2 additions & 1 deletion src/jpcsp/HLE/kernel/types/interrupts/SubIntrHandler.java
Expand Up @@ -19,11 +19,12 @@
public class SubIntrHandler extends AbstractAllegrexInterruptHandler {
private boolean enabled;

public SubIntrHandler(int address, int id, int argument) {
public SubIntrHandler(int address, int gp, int id, int argument) {
// call: handler(int id, void* argument)
// -> argumentA0 = id
// -> argumentA1 = argument
super(address, id, argument);
setGp(gp);
}

public int getId() {
Expand Down
3 changes: 1 addition & 2 deletions src/jpcsp/HLE/modules/LoadCoreForKernel.java
Expand Up @@ -1138,10 +1138,9 @@ public int sceKernelGetModuleListWithAlloc(TPointer32 modCount) {
*
* @return The global pointer value (greater than 0) of the found module on success.
*/
@HLEUnimplemented
@HLEFunction(nid = 0x410084F9, version = 660)
public int sceKernelGetModuleGPByAddressForKernel(int addr) {
return 0;
return Managers.modules.getModuleGpByAddress(addr);
}

/**
Expand Down
48 changes: 42 additions & 6 deletions src/jpcsp/HLE/modules/ThreadManForUser.java
Expand Up @@ -342,20 +342,23 @@ public static class Callback {
private int id;
private int address;
private int[] parameters;
private int gp;
private int savedIdRegister;
private int savedRa;
private int savedPc;
private int savedGp;
private int savedV0;
private int savedV1;
private IAction afterAction;
private boolean returnVoid;
private boolean preserveCpuState;
private CpuState savedCpuState;

public Callback(int id, int address, int[] parameters, IAction afterAction, boolean returnVoid, boolean preserveCpuState) {
public Callback(int id, int address, int[] parameters, int gp, IAction afterAction, boolean returnVoid, boolean preserveCpuState) {
this.id = id;
this.address = address;
this.parameters = parameters;
this.gp = gp;
this.afterAction = afterAction;
this.returnVoid = returnVoid;
this.preserveCpuState = preserveCpuState;
Expand All @@ -371,6 +374,7 @@ public void execute(SceKernelThreadInfo thread) {
savedIdRegister = cpu.getRegister(CALLBACKID_REGISTER);
savedRa = cpu._ra;
savedPc = cpu.pc;
savedGp = cpu._gp;
savedV0 = cpu._v0;
savedV1 = cpu._v1;
if (preserveCpuState) {
Expand All @@ -384,6 +388,7 @@ public void execute(SceKernelThreadInfo thread) {
}
}

cpu._gp = gp;
cpu.setRegister(CALLBACKID_REGISTER, id);
cpu._ra = CALLBACK_EXIT_HANDLER_ADDRESS;
cpu.pc = address;
Expand All @@ -393,6 +398,7 @@ public void execute(SceKernelThreadInfo thread) {

public void executeExit(CpuState cpu) {
cpu.setRegister(CALLBACKID_REGISTER, savedIdRegister);
cpu._gp = savedGp;
cpu._ra = savedRa;
cpu.pc = savedPc;

Expand Down Expand Up @@ -1978,12 +1984,42 @@ public void hleKernelExitCallback(Processor processor) {
* @param address the address to be called
* @param afterAction the action to be executed after the completion of the code
* @param returnVoid the code has a void return value, i.e. $v0/$v1 have to be restored
* @param gp the value of the $gp register to be set
*/
public void callAddress(int address, IAction afterAction, boolean returnVoid) {
callAddress(null, address, afterAction, returnVoid, false, null);
public void callAddress(int address, IAction afterAction, boolean returnVoid, int gp) {
callAddress(null, address, afterAction, returnVoid, false, null, gp);
}

/**
* Execute the code at the given address.
* The code is executed in the context of the currentThread.
* This call can return before the completion of the callback. Use the
* "afterAction" parameter to trigger some actions that need to be executed
* after the callback (e.g. to evaluate a return value in cpu.gpr[2]).
*
* @param address address of the callback
* @param gp value of the $gp register
* @param afterAction action to be executed after the completion of the callback
* @param registerA0 first parameter of the callback ($a0)
*/
public void executeCallback(int address, int gp, IAction afterAction, int registerA0) {
if (log.isDebugEnabled()) {
log.debug(String.format("Execute callback 0x%08X($a0=0x%08X), afterAction=%s", address, registerA0, afterAction));
}

callAddress(null, address, afterAction, true, true, new int[]{registerA0}, gp);
}

private void callAddress(SceKernelThreadInfo thread, int address, IAction afterAction, boolean returnVoid, boolean preserveCpuState, int[] parameters) {
int gp = 0;
if (thread != null) {
gp = thread.gpReg_addr;
}

callAddress(thread, address, afterAction, returnVoid, preserveCpuState, parameters, gp);
}

private void callAddress(SceKernelThreadInfo thread, int address, IAction afterAction, boolean returnVoid, boolean preserveCpuState, int[] parameters, int gp) {
if (thread != null) {
// Save the wait state of the thread to restore it after the call
afterAction = new AfterCallAction(thread, afterAction);
Expand All @@ -1996,7 +2032,7 @@ private void callAddress(SceKernelThreadInfo thread, int address, IAction afterA
}

int callbackId = callbackManager.getNewCallbackId();
Callback callback = new Callback(callbackId, address, parameters, afterAction, returnVoid, preserveCpuState);
Callback callback = new Callback(callbackId, address, parameters, gp, afterAction, returnVoid, preserveCpuState);

callbackManager.addCallback(callback);

Expand Down Expand Up @@ -4533,7 +4569,7 @@ public int sceKernelExtendThreadStack(CpuState cpu, @CheckArgument("checkStackSi
AfterSceKernelExtendThreadStackAction afterAction = new AfterSceKernelExtendThreadStackAction(thread, cpu.pc, cpu._sp, cpu._ra, extendedStackSysMemInfo);
cpu._a0 = entryParameter;
cpu._sp = extendedStackSysMemInfo.addr + size;
callAddress(entryAddr.getAddress(), afterAction, false);
callAddress(entryAddr.getAddress(), afterAction, false, cpu._gp);

return afterAction.getReturnValue();
}
Expand All @@ -4553,7 +4589,7 @@ public int sceKernelExtendKernelStack(CpuState cpu, @CheckArgument("checkStackSi
AfterSceKernelExtendThreadStackAction afterAction = new AfterSceKernelExtendThreadStackAction(thread, cpu.pc, cpu._sp, cpu._ra, extendedStackSysMemInfo);
cpu._a0 = entryParameter;
cpu._sp = extendedStackSysMemInfo.addr + size;
callAddress(entryAddr.getAddress(), afterAction, false);
callAddress(entryAddr.getAddress(), afterAction, false, cpu._gp);

return afterAction.getReturnValue();
}
Expand Down

2 comments on commit 5bbc2ad

@sum2012
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Break Final Fantasy Tactics: Shishi Sensou - ULJM05194
http://www.emunewz.net/forum/showthread.php?tid=5892&pid=365513#pid365513

@sum2012
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in bf86e36

Please sign in to comment.