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.
140
JGE/src/main.cpp
140
JGE/src/main.cpp
@@ -13,6 +13,10 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pspctrl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//#include <mikmod.h>
|
||||
|
||||
@@ -21,13 +25,13 @@
|
||||
#include "../../JGE/include/JGameLauncher.h"
|
||||
#include "../../JGE/include/JRenderer.h"
|
||||
|
||||
|
||||
#ifndef JGEApp_Title
|
||||
#define JGEApp_Title "JGE++"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEVHOOK
|
||||
|
||||
PSP_MODULE_INFO(JGEApp_Title, 0, 1, 1);
|
||||
PSP_MAIN_THREAD_ATTR(0);
|
||||
PSP_HEAP_SIZE_KB(-256);
|
||||
@@ -161,7 +165,107 @@ int SetupCallbacks(void)
|
||||
|
||||
|
||||
#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
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Custom exception handler
|
||||
@@ -202,21 +306,14 @@ int SetupCallbacks(void)
|
||||
// The main loop
|
||||
int main()
|
||||
{
|
||||
//scePowerSetClockFrequency(333, 333, 166);
|
||||
|
||||
SetupCallbacks();
|
||||
|
||||
// pspDebugScreenInit();
|
||||
|
||||
// if ((mikModThreadID = sceKernelCreateThread("MikMod" , AudioChannelThread, 0x12,0x10000,0,0)) > 0)
|
||||
// {
|
||||
// sceKernelStartThread(mikModThreadID, 0 , 0);
|
||||
// }
|
||||
|
||||
#ifdef DEVHOOK
|
||||
initExceptionHandler();
|
||||
#endif
|
||||
engine = NULL;
|
||||
|
||||
//engine->Init(0);
|
||||
//
|
||||
|
||||
JGameLauncher* launcher = new JGameLauncher();
|
||||
|
||||
u32 flags = launcher->GetInitFlags();
|
||||
@@ -232,9 +329,6 @@ int main()
|
||||
engine->SetApp(game);
|
||||
engine->Run();
|
||||
|
||||
//pspDebugScreenSetXY(10,10);
|
||||
//pspDebugScreenPrintf("Hello world!");
|
||||
|
||||
game->Destroy();
|
||||
delete game;
|
||||
game = NULL;
|
||||
@@ -243,28 +337,12 @@ int main()
|
||||
|
||||
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;
|
||||
|
||||
JGE::Destroy();
|
||||
engine = NULL;
|
||||
|
||||
|
||||
// sceKernelSleepThread();
|
||||
|
||||
sceKernelExitGame();
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user