Erwan
-adding exception handler to JGE. Copy the exception.prx file to the same directory as the EBOOT from now on
This commit is contained in:
34
JGE/exceptionHandler/README.txt
Normal file
34
JGE/exceptionHandler/README.txt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
Exception Handler for Kernel 3.71
|
||||||
|
---------------------------------
|
||||||
|
All credits goes to crazyc (for the prx code) and SamuraiX (sample usage code)
|
||||||
|
|
||||||
|
What is it?
|
||||||
|
-----------
|
||||||
|
exception.prx is a prx that handle exception and can be used
|
||||||
|
to show usefull information abuot a crash.
|
||||||
|
|
||||||
|
|
||||||
|
How to build:
|
||||||
|
-------------
|
||||||
|
To build exception.prx
|
||||||
|
|
||||||
|
$cd prx
|
||||||
|
$make
|
||||||
|
|
||||||
|
To build the test program:
|
||||||
|
$cd test
|
||||||
|
$make
|
||||||
|
|
||||||
|
|
||||||
|
How to use it:
|
||||||
|
--------------
|
||||||
|
Include utility/exception.h in your main.c and init the handler with:
|
||||||
|
|
||||||
|
initExceptionHandler();
|
||||||
|
|
||||||
|
Copy exception.prx in the same directory your EBOOT is.
|
||||||
|
|
||||||
|
Please check the test program. ;)
|
||||||
|
|
||||||
|
Note:
|
||||||
|
--> For Wagic, the code is already included in JGE's main.cpp. You just need to copy the prx with the EBOOT
|
||||||
BIN
JGE/exceptionHandler/prx/exception.prx
Normal file
BIN
JGE/exceptionHandler/prx/exception.prx
Normal file
Binary file not shown.
214
JGE/exceptionHandler/prx/exception_asm.S
Normal file
214
JGE/exceptionHandler/prx/exception_asm.S
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
#include "as_reg_compat.h"
|
||||||
|
.set noreorder
|
||||||
|
.set noat
|
||||||
|
|
||||||
|
#define BadVAddr $8 // Address for the most recent address-related exception
|
||||||
|
#define Status $12 // Processor status and control
|
||||||
|
#define Cause $13 // Cause of last general exception
|
||||||
|
#define EPC $14 // Program counter at last exception
|
||||||
|
#define PRId $15 // Processor identification and revision
|
||||||
|
|
||||||
|
#define FSR $31
|
||||||
|
#define FIR $0
|
||||||
|
|
||||||
|
#define REG_GPR_0 (6*4)
|
||||||
|
#define REG_GPR_1 (REG_GPR_0 + 4)
|
||||||
|
#define REG_GPR_2 (REG_GPR_1 + 4)
|
||||||
|
#define REG_GPR_3 (REG_GPR_2 + 4)
|
||||||
|
#define REG_GPR_4 (REG_GPR_3 + 4)
|
||||||
|
#define REG_GPR_5 (REG_GPR_4 + 4)
|
||||||
|
#define REG_GPR_6 (REG_GPR_5 + 4)
|
||||||
|
#define REG_GPR_7 (REG_GPR_6 + 4)
|
||||||
|
#define REG_GPR_8 (REG_GPR_7 + 4)
|
||||||
|
#define REG_GPR_9 (REG_GPR_8 + 4)
|
||||||
|
#define REG_GPR_10 (REG_GPR_9 + 4)
|
||||||
|
#define REG_GPR_11 (REG_GPR_10 + 4)
|
||||||
|
#define REG_GPR_12 (REG_GPR_11 + 4)
|
||||||
|
#define REG_GPR_13 (REG_GPR_12 + 4)
|
||||||
|
#define REG_GPR_14 (REG_GPR_13 + 4)
|
||||||
|
#define REG_GPR_15 (REG_GPR_14 + 4)
|
||||||
|
#define REG_GPR_16 (REG_GPR_15 + 4)
|
||||||
|
#define REG_GPR_17 (REG_GPR_16 + 4)
|
||||||
|
#define REG_GPR_18 (REG_GPR_17 + 4)
|
||||||
|
#define REG_GPR_19 (REG_GPR_18 + 4)
|
||||||
|
#define REG_GPR_20 (REG_GPR_19 + 4)
|
||||||
|
#define REG_GPR_21 (REG_GPR_20 + 4)
|
||||||
|
#define REG_GPR_22 (REG_GPR_21 + 4)
|
||||||
|
#define REG_GPR_23 (REG_GPR_22 + 4)
|
||||||
|
#define REG_GPR_24 (REG_GPR_23 + 4)
|
||||||
|
#define REG_GPR_25 (REG_GPR_24 + 4)
|
||||||
|
#define REG_GPR_26 (REG_GPR_25 + 4)
|
||||||
|
#define REG_GPR_27 (REG_GPR_26 + 4)
|
||||||
|
#define REG_GPR_28 (REG_GPR_27 + 4)
|
||||||
|
#define REG_GPR_29 (REG_GPR_28 + 4)
|
||||||
|
#define REG_GPR_30 (REG_GPR_29 + 4)
|
||||||
|
#define REG_GPR_31 (REG_GPR_30 + 4)
|
||||||
|
|
||||||
|
#define REG_STATUS (REG_GPR_31 + 4)
|
||||||
|
#define REG_LO (REG_STATUS + 4)
|
||||||
|
#define REG_HI (REG_LO + 4)
|
||||||
|
#define REG_BADVADDR (REG_HI + 4)
|
||||||
|
#define REG_CAUSE (REG_BADVADDR + 4)
|
||||||
|
#define REG_EPC (REG_CAUSE + 4)
|
||||||
|
|
||||||
|
#define REG_FPR_0 (REG_EPC + 4)
|
||||||
|
#define REG_FPR_1 (REG_FPR_0 + 4)
|
||||||
|
#define REG_FPR_2 (REG_FPR_1 + 4)
|
||||||
|
#define REG_FPR_3 (REG_FPR_2 + 4)
|
||||||
|
#define REG_FPR_4 (REG_FPR_3 + 4)
|
||||||
|
#define REG_FPR_5 (REG_FPR_4 + 4)
|
||||||
|
#define REG_FPR_6 (REG_FPR_5 + 4)
|
||||||
|
#define REG_FPR_7 (REG_FPR_6 + 4)
|
||||||
|
#define REG_FPR_8 (REG_FPR_7 + 4)
|
||||||
|
#define REG_FPR_9 (REG_FPR_8 + 4)
|
||||||
|
#define REG_FPR_10 (REG_FPR_9 + 4)
|
||||||
|
#define REG_FPR_11 (REG_FPR_10 + 4)
|
||||||
|
#define REG_FPR_12 (REG_FPR_11 + 4)
|
||||||
|
#define REG_FPR_13 (REG_FPR_12 + 4)
|
||||||
|
#define REG_FPR_14 (REG_FPR_13 + 4)
|
||||||
|
#define REG_FPR_15 (REG_FPR_14 + 4)
|
||||||
|
#define REG_FPR_16 (REG_FPR_15 + 4)
|
||||||
|
#define REG_FPR_17 (REG_FPR_16 + 4)
|
||||||
|
#define REG_FPR_18 (REG_FPR_17 + 4)
|
||||||
|
#define REG_FPR_19 (REG_FPR_18 + 4)
|
||||||
|
#define REG_FPR_20 (REG_FPR_19 + 4)
|
||||||
|
#define REG_FPR_21 (REG_FPR_20 + 4)
|
||||||
|
#define REG_FPR_22 (REG_FPR_21 + 4)
|
||||||
|
#define REG_FPR_23 (REG_FPR_22 + 4)
|
||||||
|
#define REG_FPR_24 (REG_FPR_23 + 4)
|
||||||
|
#define REG_FPR_25 (REG_FPR_24 + 4)
|
||||||
|
#define REG_FPR_26 (REG_FPR_25 + 4)
|
||||||
|
#define REG_FPR_27 (REG_FPR_26 + 4)
|
||||||
|
#define REG_FPR_28 (REG_FPR_27 + 4)
|
||||||
|
#define REG_FPR_29 (REG_FPR_28 + 4)
|
||||||
|
#define REG_FPR_30 (REG_FPR_29 + 4)
|
||||||
|
#define REG_FPR_31 (REG_FPR_30 + 4)
|
||||||
|
|
||||||
|
#define REG_FSR (REG_FPR_31 + 4)
|
||||||
|
#define REG_FIR (REG_FSR + 4)
|
||||||
|
#define REG_FP (REG_FIR + 4)
|
||||||
|
|
||||||
|
.extern exception_regs
|
||||||
|
.extern curr_handler
|
||||||
|
|
||||||
|
.global _pspDebugExceptionHandler
|
||||||
|
.ent _pspDebugExceptionHandler
|
||||||
|
_pspDebugExceptionHandler:
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
lw $v0, exception_regs
|
||||||
|
sw $0, REG_GPR_0($v0)
|
||||||
|
sw $1, REG_GPR_1($v0)
|
||||||
|
|
||||||
|
cfc0 $1, $4 # Get original v0
|
||||||
|
sw $1, REG_GPR_2($v0)
|
||||||
|
cfc0 $1, $5 # Get original v1
|
||||||
|
sw $1, REG_GPR_3($v0)
|
||||||
|
sw $4, REG_GPR_4($v0)
|
||||||
|
sw $5, REG_GPR_5($v0)
|
||||||
|
sw $6, REG_GPR_6($v0)
|
||||||
|
sw $7, REG_GPR_7($v0)
|
||||||
|
sw $8, REG_GPR_8($v0)
|
||||||
|
sw $9, REG_GPR_9($v0)
|
||||||
|
sw $10, REG_GPR_10($v0)
|
||||||
|
sw $11, REG_GPR_11($v0)
|
||||||
|
sw $12, REG_GPR_12($v0)
|
||||||
|
sw $13, REG_GPR_13($v0)
|
||||||
|
sw $14, REG_GPR_14($v0)
|
||||||
|
sw $15, REG_GPR_15($v0)
|
||||||
|
sw $16, REG_GPR_16($v0)
|
||||||
|
sw $17, REG_GPR_17($v0)
|
||||||
|
sw $18, REG_GPR_18($v0)
|
||||||
|
sw $19, REG_GPR_19($v0)
|
||||||
|
sw $20, REG_GPR_20($v0)
|
||||||
|
sw $21, REG_GPR_21($v0)
|
||||||
|
sw $22, REG_GPR_22($v0)
|
||||||
|
sw $23, REG_GPR_23($v0)
|
||||||
|
sw $24, REG_GPR_24($v0)
|
||||||
|
sw $25, REG_GPR_25($v0)
|
||||||
|
sw $26, REG_GPR_26($v0)
|
||||||
|
sw $27, REG_GPR_27($v0)
|
||||||
|
sw $28, REG_GPR_28($v0)
|
||||||
|
sw $29, REG_GPR_29($v0)
|
||||||
|
sw $30, REG_GPR_30($v0)
|
||||||
|
sw $31, REG_GPR_31($v0)
|
||||||
|
|
||||||
|
mflo $v1
|
||||||
|
sw $v1, REG_LO($v0)
|
||||||
|
mfhi $v1
|
||||||
|
sw $v1, REG_HI($v0)
|
||||||
|
mfc0 $v1, BadVAddr
|
||||||
|
sw $v1, REG_BADVADDR($v0)
|
||||||
|
mfc0 $v1, Cause
|
||||||
|
sw $v1, REG_CAUSE($v0)
|
||||||
|
mfc0 $v1, EPC
|
||||||
|
sw $v1, REG_EPC($v0)
|
||||||
|
mfc0 $v1, Status
|
||||||
|
sw $v1, REG_STATUS($v0)
|
||||||
|
|
||||||
|
# Check if cop1 is enable and skip if not
|
||||||
|
lui $a0, 0x2000
|
||||||
|
and $a0, $a0, $v1
|
||||||
|
beq $a0, $0, 1f
|
||||||
|
nop
|
||||||
|
|
||||||
|
swc1 $0, REG_FPR_0($v0)
|
||||||
|
swc1 $1, REG_FPR_1($v0)
|
||||||
|
swc1 $2, REG_FPR_2($v0)
|
||||||
|
swc1 $3, REG_FPR_3($v0)
|
||||||
|
swc1 $4, REG_FPR_4($v0)
|
||||||
|
swc1 $5, REG_FPR_5($v0)
|
||||||
|
swc1 $6, REG_FPR_6($v0)
|
||||||
|
swc1 $7, REG_FPR_7($v0)
|
||||||
|
swc1 $8, REG_FPR_8($v0)
|
||||||
|
swc1 $9, REG_FPR_9($v0)
|
||||||
|
swc1 $10, REG_FPR_10($v0)
|
||||||
|
swc1 $11, REG_FPR_11($v0)
|
||||||
|
swc1 $12, REG_FPR_12($v0)
|
||||||
|
swc1 $13, REG_FPR_13($v0)
|
||||||
|
swc1 $14, REG_FPR_14($v0)
|
||||||
|
swc1 $15, REG_FPR_15($v0)
|
||||||
|
swc1 $16, REG_FPR_16($v0)
|
||||||
|
swc1 $17, REG_FPR_17($v0)
|
||||||
|
swc1 $18, REG_FPR_18($v0)
|
||||||
|
swc1 $19, REG_FPR_19($v0)
|
||||||
|
swc1 $20, REG_FPR_20($v0)
|
||||||
|
swc1 $21, REG_FPR_21($v0)
|
||||||
|
swc1 $22, REG_FPR_22($v0)
|
||||||
|
swc1 $23, REG_FPR_23($v0)
|
||||||
|
swc1 $24, REG_FPR_24($v0)
|
||||||
|
swc1 $25, REG_FPR_25($v0)
|
||||||
|
swc1 $26, REG_FPR_26($v0)
|
||||||
|
swc1 $27, REG_FPR_27($v0)
|
||||||
|
swc1 $28, REG_FPR_28($v0)
|
||||||
|
swc1 $29, REG_FPR_29($v0)
|
||||||
|
swc1 $30, REG_FPR_30($v0)
|
||||||
|
swc1 $31, REG_FPR_31($v0)
|
||||||
|
|
||||||
|
cfc1 $t0, FSR
|
||||||
|
sw $t0, REG_FSR($v0)
|
||||||
|
cfc1 $t0, FIR
|
||||||
|
sw $t0, REG_FIR($v0)
|
||||||
|
ctc1 $0, FSR # Clear any cause flags
|
||||||
|
|
||||||
|
# Jump target for ignore cop1
|
||||||
|
1:
|
||||||
|
|
||||||
|
sw $sp, REG_FP($v0)
|
||||||
|
move $a0, $v0
|
||||||
|
|
||||||
|
lw $2, curr_handler
|
||||||
|
mtc0 $2, $14
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
eret
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
.end _pspDebugExceptionHandler
|
||||||
|
|
||||||
|
#include "pspimport.s"
|
||||||
|
|
||||||
|
IMPORT_START "ExceptionManagerForKernel",0x00010011
|
||||||
|
IMPORT_FUNC "ExceptionManagerForKernel",0x565C0B0E,sceKernelRegisterDefaultExceptionHandler371
|
||||||
7
JGE/exceptionHandler/prx/exports.exp
Normal file
7
JGE/exceptionHandler/prx/exports.exp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
PSP_BEGIN_EXPORTS
|
||||||
|
PSP_EXPORT_START(syslib, 0, 0x8000)
|
||||||
|
PSP_EXPORT_FUNC_HASH(module_start)
|
||||||
|
PSP_EXPORT_VAR_HASH(module_info)
|
||||||
|
PSP_EXPORT_END
|
||||||
|
|
||||||
|
PSP_END_EXPORTS
|
||||||
25
JGE/exceptionHandler/prx/main.c
Normal file
25
JGE/exceptionHandler/prx/main.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <pspkernel.h>
|
||||||
|
#include <psppower.h>
|
||||||
|
#include <pspdebug.h>
|
||||||
|
|
||||||
|
PSP_MODULE_INFO("exception", 0x1007, 1, 1); // better not unload
|
||||||
|
|
||||||
|
PspDebugErrorHandler curr_handler;
|
||||||
|
PspDebugRegBlock *exception_regs;
|
||||||
|
|
||||||
|
void _pspDebugExceptionHandler(void);
|
||||||
|
int sceKernelRegisterDefaultExceptionHandler(void *func);
|
||||||
|
int sceKernelRegisterDefaultExceptionHandler371(void *func);
|
||||||
|
|
||||||
|
int module_start(SceSize args, void *argp)
|
||||||
|
{
|
||||||
|
if(args != 8) return -1;
|
||||||
|
curr_handler = (PspDebugErrorHandler)((int *)argp)[0];
|
||||||
|
exception_regs = (PspDebugRegBlock *)((int *)argp)[1];
|
||||||
|
if(!curr_handler || !exception_regs) return -1;
|
||||||
|
|
||||||
|
if(sceKernelDevkitVersion() < 0x03070110)
|
||||||
|
return sceKernelRegisterDefaultExceptionHandler((void *)_pspDebugExceptionHandler);
|
||||||
|
else
|
||||||
|
return sceKernelRegisterDefaultExceptionHandler371((void *)_pspDebugExceptionHandler);
|
||||||
|
}
|
||||||
20
JGE/exceptionHandler/prx/makefile
Normal file
20
JGE/exceptionHandler/prx/makefile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
TARGET = exception
|
||||||
|
OBJS = main.o exception_asm.o
|
||||||
|
|
||||||
|
# Define to build this as a prx (instead of a static elf)
|
||||||
|
BUILD_PRX=1
|
||||||
|
# Define the name of our custom exports (minus the .exp extension)
|
||||||
|
PRX_EXPORTS=exports.exp
|
||||||
|
|
||||||
|
USE_KERNEL_LIBC = 1
|
||||||
|
USE_KERNEL_LIBS = 1
|
||||||
|
|
||||||
|
INCDIR =
|
||||||
|
CFLAGS = -Os -G0 -Wall -nostartfiles
|
||||||
|
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
ASFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
|
LIBDIR =
|
||||||
|
|
||||||
|
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||||
|
include $(PSPSDK)/lib/build.mak
|
||||||
73
JGE/exceptionHandler/test/main.c
Normal file
73
JGE/exceptionHandler/test/main.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#include <pspkernel.h>
|
||||||
|
#include <pspctrl.h>
|
||||||
|
#include <pspdebug.h>
|
||||||
|
#include <pspsdk.h>
|
||||||
|
|
||||||
|
#include "../utility/exception.h"
|
||||||
|
PSP_MODULE_INFO("Exception Handler Test", 0, 1, 0);
|
||||||
|
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
|
||||||
|
//PSP_HEAP_SIZE_KB(22000);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Globals:
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int runningFlag = 1;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Callbacks:
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* Exit callback */
|
||||||
|
int exit_callback(int arg1, int arg2, void *common) {
|
||||||
|
runningFlag = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback thread */
|
||||||
|
int CallbackThread(SceSize args, void *argp) {
|
||||||
|
int cbid;
|
||||||
|
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
|
||||||
|
sceKernelRegisterExitCallback(cbid);
|
||||||
|
sceKernelSleepThreadCB();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets up the callback thread and returns its thread id */
|
||||||
|
int SetupCallbacks(void) {
|
||||||
|
int thid = 0;
|
||||||
|
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
|
||||||
|
if(thid >= 0)
|
||||||
|
sceKernelStartThread(thid, 0, 0);
|
||||||
|
return thid;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Main:
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int main(){
|
||||||
|
pspDebugScreenInit();
|
||||||
|
SetupCallbacks();
|
||||||
|
|
||||||
|
pspDebugScreenPrintf("Expcetion Handler Test\n");
|
||||||
|
|
||||||
|
initExceptionHandler();
|
||||||
|
|
||||||
|
pspDebugScreenPrintf("Press X for a breakpoint\n");
|
||||||
|
pspDebugScreenPrintf("Press O for a bus error\n");
|
||||||
|
|
||||||
|
SceCtrlData pad;
|
||||||
|
while(runningFlag){
|
||||||
|
sceCtrlReadBufferPositive(&pad, 1);
|
||||||
|
if (pad.Buttons & PSP_CTRL_CROSS){
|
||||||
|
/* Cause a break exception */
|
||||||
|
asm(
|
||||||
|
"break\r\n"
|
||||||
|
);
|
||||||
|
}else if (pad.Buttons & PSP_CTRL_CIRCLE){
|
||||||
|
/* Cause a bus error */
|
||||||
|
_sw(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sceKernelExitGame();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
19
JGE/exceptionHandler/test/makefile
Normal file
19
JGE/exceptionHandler/test/makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
TARGET = exception_handler_test
|
||||||
|
OBJS = ../utility/exception.o main.o
|
||||||
|
|
||||||
|
#To build for custom firmware:
|
||||||
|
BUILD_PRX = 1
|
||||||
|
|
||||||
|
#CFLAGS = -O3 -G0 -Wall
|
||||||
|
CFLAGS = -O3 -frename-registers -G0 -Wall
|
||||||
|
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
ASFLAGS = $(CFLAGS)
|
||||||
|
LIBDIR =
|
||||||
|
|
||||||
|
LIBS =
|
||||||
|
LDFLAGS =
|
||||||
|
EXTRA_TARGETS = EBOOT.PBP
|
||||||
|
PSP_EBOOT_TITLE = Exception Handler Test
|
||||||
|
#PSP_EBOOT_ICON = ICON0.PNG
|
||||||
|
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||||
|
include $(PSPSDK)/lib/build.mak
|
||||||
107
JGE/exceptionHandler/utility/exception.c
Normal file
107
JGE/exceptionHandler/utility/exception.c
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#include <pspkernel.h>
|
||||||
|
#include <pspsdk.h>
|
||||||
|
#include <pspctrl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
PspDebugRegBlock exception_regs;
|
||||||
|
|
||||||
|
extern SceModule module_info;
|
||||||
|
extern int _ftext;
|
||||||
|
|
||||||
|
static const char *codeTxt[32] =
|
||||||
|
{
|
||||||
|
"Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store",
|
||||||
|
"Address load/inst fetch", "Address store", "Bus error (instr)",
|
||||||
|
"Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction",
|
||||||
|
"Coprocessor unusable", "Arithmetic overflow", "Unknown 14",
|
||||||
|
"Unknown 15", "Unknown 16", "Unknown 17", "Unknown 18", "Unknown 19",
|
||||||
|
"Unknown 20", "Unknown 21", "Unknown 22", "Unknown 23", "Unknown 24",
|
||||||
|
"Unknown 25", "Unknown 26", "Unknown 27", "Unknown 28", "Unknown 29",
|
||||||
|
"Unknown 31"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char regName[32][5] =
|
||||||
|
{
|
||||||
|
"zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||||
|
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||||
|
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||||
|
"t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
|
||||||
|
};
|
||||||
|
|
||||||
|
void ExceptionHandler(PspDebugRegBlock * regs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
SceCtrlData pad;
|
||||||
|
|
||||||
|
pspDebugScreenInit();
|
||||||
|
pspDebugScreenSetBackColor(0x00FF0000);
|
||||||
|
pspDebugScreenSetTextColor(0xFFFFFFFF);
|
||||||
|
pspDebugScreenClear();
|
||||||
|
pspDebugScreenPrintf("Your PSP has just crashed!\n");
|
||||||
|
pspDebugScreenPrintf("Exception details:\n\n");
|
||||||
|
|
||||||
|
pspDebugScreenPrintf("Exception - %s\n", codeTxt[(regs->cause >> 2) & 31]);
|
||||||
|
pspDebugScreenPrintf("EPC - %08X / %s.text + %08X\n", (int)regs->epc, module_info.modname, (unsigned int)(regs->epc-(int)&_ftext));
|
||||||
|
pspDebugScreenPrintf("Cause - %08X\n", (int)regs->cause);
|
||||||
|
pspDebugScreenPrintf("Status - %08X\n", (int)regs->status);
|
||||||
|
pspDebugScreenPrintf("BadVAddr - %08X\n", (int)regs->badvaddr);
|
||||||
|
for(i=0; i<32; i+=4) pspDebugScreenPrintf("%s:%08X %s:%08X %s:%08X %s:%08X\n", regName[i], (int)regs->r[i], regName[i+1], (int)regs->r[i+1], regName[i+2], (int)regs->r[i+2], regName[i+3], (int)regs->r[i+3]);
|
||||||
|
|
||||||
|
sceKernelDelayThread(1000000);
|
||||||
|
pspDebugScreenPrintf("\n\nPress X to dump information on file exception.log and quit");
|
||||||
|
pspDebugScreenPrintf("\nPress O to quit");
|
||||||
|
|
||||||
|
for (;;){
|
||||||
|
sceCtrlReadBufferPositive(&pad, 1);
|
||||||
|
if (pad.Buttons & PSP_CTRL_CROSS){
|
||||||
|
FILE *log = fopen("exception.log", "w");
|
||||||
|
if (log != NULL){
|
||||||
|
char testo[512];
|
||||||
|
sprintf(testo, "Exception details:\n\n");
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "Exception - %s\n", codeTxt[(regs->cause >> 2) & 31]);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "EPC - %08X / %s.text + %08X\n", (int)regs->epc, module_info.modname, (unsigned int)(regs->epc-(int)&_ftext));
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "Cause - %08X\n", (int)regs->cause);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "Status - %08X\n", (int)regs->status);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "BadVAddr - %08X\n", (int)regs->badvaddr);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
for(i=0; i<32; i+=4){
|
||||||
|
sprintf(testo, "%s:%08X %s:%08X %s:%08X %s:%08X\n", regName[i], (int)regs->r[i], regName[i+1], (int)regs->r[i+1], regName[i+2], (int)regs->r[i+2], regName[i+3], (int)regs->r[i+3]);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
}
|
||||||
|
fclose(log);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}else if (pad.Buttons & PSP_CTRL_CIRCLE){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sceKernelDelayThread(100000);
|
||||||
|
}
|
||||||
|
sceKernelExitGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initExceptionHandler()
|
||||||
|
{
|
||||||
|
SceKernelLMOption option;
|
||||||
|
int args[2], fd, modid;
|
||||||
|
|
||||||
|
memset(&option, 0, sizeof(option));
|
||||||
|
option.size = sizeof(option);
|
||||||
|
option.mpidtext = PSP_MEMORY_PARTITION_KERNEL;
|
||||||
|
option.mpiddata = PSP_MEMORY_PARTITION_KERNEL;
|
||||||
|
option.position = 0;
|
||||||
|
option.access = 1;
|
||||||
|
|
||||||
|
if((modid = sceKernelLoadModule("exception.prx", 0, &option)) >= 0)
|
||||||
|
{
|
||||||
|
args[0] = (int)ExceptionHandler;
|
||||||
|
args[1] = (int)&exception_regs;
|
||||||
|
sceKernelStartModule(modid, 8, args, &fd, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
JGE/exceptionHandler/utility/exception.h
Normal file
3
JGE/exceptionHandler/utility/exception.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
void initExceptionHandler();
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
142
JGE/src/main.cpp
142
JGE/src/main.cpp
@@ -13,6 +13,10 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <pspctrl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
//#include <mikmod.h>
|
//#include <mikmod.h>
|
||||||
|
|
||||||
@@ -21,13 +25,13 @@
|
|||||||
#include "../../JGE/include/JGameLauncher.h"
|
#include "../../JGE/include/JGameLauncher.h"
|
||||||
#include "../../JGE/include/JRenderer.h"
|
#include "../../JGE/include/JRenderer.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef JGEApp_Title
|
#ifndef JGEApp_Title
|
||||||
#define JGEApp_Title "JGE++"
|
#define JGEApp_Title "JGE++"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEVHOOK
|
#ifdef DEVHOOK
|
||||||
|
|
||||||
PSP_MODULE_INFO(JGEApp_Title, 0, 1, 1);
|
PSP_MODULE_INFO(JGEApp_Title, 0, 1, 1);
|
||||||
PSP_MAIN_THREAD_ATTR(0);
|
PSP_MAIN_THREAD_ATTR(0);
|
||||||
PSP_HEAP_SIZE_KB(-256);
|
PSP_HEAP_SIZE_KB(-256);
|
||||||
@@ -161,7 +165,107 @@ int SetupCallbacks(void)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEVHOOK
|
#ifdef DEVHOOK
|
||||||
|
//code by sakya, crazyc, samuraiX
|
||||||
|
//http://forums.ps2dev.org/viewtopic.php?t=9591&sid=2056889f6b9531194cab9b2d487df844
|
||||||
|
PspDebugRegBlock exception_regs;
|
||||||
|
|
||||||
|
extern int _ftext;
|
||||||
|
|
||||||
|
static const char *codeTxt[32] =
|
||||||
|
{
|
||||||
|
"Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store",
|
||||||
|
"Address load/inst fetch", "Address store", "Bus error (instr)",
|
||||||
|
"Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction",
|
||||||
|
"Coprocessor unusable", "Arithmetic overflow", "Unknown 14",
|
||||||
|
"Unknown 15", "Unknown 16", "Unknown 17", "Unknown 18", "Unknown 19",
|
||||||
|
"Unknown 20", "Unknown 21", "Unknown 22", "Unknown 23", "Unknown 24",
|
||||||
|
"Unknown 25", "Unknown 26", "Unknown 27", "Unknown 28", "Unknown 29",
|
||||||
|
"Unknown 31"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char regName[32][5] =
|
||||||
|
{
|
||||||
|
"zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||||
|
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||||
|
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||||
|
"t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
|
||||||
|
};
|
||||||
|
|
||||||
|
void ExceptionHandler(PspDebugRegBlock * regs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
SceCtrlData pad;
|
||||||
|
|
||||||
|
pspDebugScreenInit();
|
||||||
|
pspDebugScreenSetBackColor(0x00FF0000);
|
||||||
|
pspDebugScreenSetTextColor(0xFFFFFFFF);
|
||||||
|
pspDebugScreenClear();
|
||||||
|
pspDebugScreenPrintf("Your PSP has just crashed!\n");
|
||||||
|
pspDebugScreenPrintf("Exception details:\n\n");
|
||||||
|
|
||||||
|
pspDebugScreenPrintf("Exception - %s\n", codeTxt[(regs->cause >> 2) & 31]);
|
||||||
|
pspDebugScreenPrintf("EPC - %08X / %s.text + %08X\n", (int)regs->epc, module_info.modname, (unsigned int)(regs->epc-(int)&_ftext));
|
||||||
|
pspDebugScreenPrintf("Cause - %08X\n", (int)regs->cause);
|
||||||
|
pspDebugScreenPrintf("Status - %08X\n", (int)regs->status);
|
||||||
|
pspDebugScreenPrintf("BadVAddr - %08X\n", (int)regs->badvaddr);
|
||||||
|
for(i=0; i<32; i+=4) pspDebugScreenPrintf("%s:%08X %s:%08X %s:%08X %s:%08X\n", regName[i], (int)regs->r[i], regName[i+1], (int)regs->r[i+1], regName[i+2], (int)regs->r[i+2], regName[i+3], (int)regs->r[i+3]);
|
||||||
|
|
||||||
|
sceKernelDelayThread(1000000);
|
||||||
|
pspDebugScreenPrintf("\n\nPress X to dump information on file exception.log and quit");
|
||||||
|
pspDebugScreenPrintf("\nPress O to quit");
|
||||||
|
|
||||||
|
for (;;){
|
||||||
|
sceCtrlReadBufferPositive(&pad, 1);
|
||||||
|
if (pad.Buttons & PSP_CTRL_CROSS){
|
||||||
|
FILE *log = fopen("exception.log", "w");
|
||||||
|
if (log != NULL){
|
||||||
|
char testo[512];
|
||||||
|
sprintf(testo, "Exception details:\n\n");
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "Exception - %s\n", codeTxt[(regs->cause >> 2) & 31]);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "EPC - %08X / %s.text + %08X\n", (int)regs->epc, module_info.modname, (unsigned int)(regs->epc-(int)&_ftext));
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "Cause - %08X\n", (int)regs->cause);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "Status - %08X\n", (int)regs->status);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
sprintf(testo, "BadVAddr - %08X\n", (int)regs->badvaddr);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
for(i=0; i<32; i+=4){
|
||||||
|
sprintf(testo, "%s:%08X %s:%08X %s:%08X %s:%08X\n", regName[i], (int)regs->r[i], regName[i+1], (int)regs->r[i+1], regName[i+2], (int)regs->r[i+2], regName[i+3], (int)regs->r[i+3]);
|
||||||
|
fwrite(testo, 1, strlen(testo), log);
|
||||||
|
}
|
||||||
|
fclose(log);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}else if (pad.Buttons & PSP_CTRL_CIRCLE){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sceKernelDelayThread(100000);
|
||||||
|
}
|
||||||
|
sceKernelExitGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initExceptionHandler()
|
||||||
|
{
|
||||||
|
SceKernelLMOption option;
|
||||||
|
int args[2], fd, modid;
|
||||||
|
|
||||||
|
memset(&option, 0, sizeof(option));
|
||||||
|
option.size = sizeof(option);
|
||||||
|
option.mpidtext = PSP_MEMORY_PARTITION_KERNEL;
|
||||||
|
option.mpiddata = PSP_MEMORY_PARTITION_KERNEL;
|
||||||
|
option.position = 0;
|
||||||
|
option.access = 1;
|
||||||
|
|
||||||
|
if((modid = sceKernelLoadModule("exception.prx", 0, &option)) >= 0)
|
||||||
|
{
|
||||||
|
args[0] = (int)ExceptionHandler;
|
||||||
|
args[1] = (int)&exception_regs;
|
||||||
|
sceKernelStartModule(modid, 8, args, &fd, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
// Custom exception handler
|
// Custom exception handler
|
||||||
@@ -201,22 +305,15 @@ int SetupCallbacks(void)
|
|||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
// The main loop
|
// The main loop
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
//scePowerSetClockFrequency(333, 333, 166);
|
|
||||||
|
|
||||||
SetupCallbacks();
|
SetupCallbacks();
|
||||||
|
#ifdef DEVHOOK
|
||||||
// pspDebugScreenInit();
|
initExceptionHandler();
|
||||||
|
#endif
|
||||||
// if ((mikModThreadID = sceKernelCreateThread("MikMod" , AudioChannelThread, 0x12,0x10000,0,0)) > 0)
|
|
||||||
// {
|
|
||||||
// sceKernelStartThread(mikModThreadID, 0 , 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
engine = NULL;
|
engine = NULL;
|
||||||
|
|
||||||
//engine->Init(0);
|
|
||||||
//
|
|
||||||
JGameLauncher* launcher = new JGameLauncher();
|
JGameLauncher* launcher = new JGameLauncher();
|
||||||
|
|
||||||
u32 flags = launcher->GetInitFlags();
|
u32 flags = launcher->GetInitFlags();
|
||||||
@@ -232,9 +329,6 @@ int main()
|
|||||||
engine->SetApp(game);
|
engine->SetApp(game);
|
||||||
engine->Run();
|
engine->Run();
|
||||||
|
|
||||||
//pspDebugScreenSetXY(10,10);
|
|
||||||
//pspDebugScreenPrintf("Hello world!");
|
|
||||||
|
|
||||||
game->Destroy();
|
game->Destroy();
|
||||||
delete game;
|
delete game;
|
||||||
game = NULL;
|
game = NULL;
|
||||||
@@ -243,28 +337,12 @@ int main()
|
|||||||
|
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
// if (mikModThreadID > 0)
|
|
||||||
// {
|
|
||||||
// ////SceUInt timeout = 100000;
|
|
||||||
// ////sceKernelWaitThreadEnd(mikModThreadID, &timeout);
|
|
||||||
// // not 100% sure if this is necessary after a clean exit, but just to make sure any resources are freed:
|
|
||||||
// sceKernelDeleteThread(mikModThreadID);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// JFileSystem::Destroy();
|
|
||||||
// JParticleSystem::Destroy();
|
|
||||||
// JMotionSystem::Destroy();
|
|
||||||
|
|
||||||
// launcher->CleanUp();
|
|
||||||
delete launcher;
|
delete launcher;
|
||||||
|
|
||||||
JGE::Destroy();
|
JGE::Destroy();
|
||||||
engine = NULL;
|
engine = NULL;
|
||||||
|
|
||||||
|
|
||||||
// sceKernelSleepThread();
|
|
||||||
|
|
||||||
sceKernelExitGame();
|
sceKernelExitGame();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user