1 /*
2 * OpenBOR - http://www.LavaLit.com
3 * -----------------------------------------------------------------------
4 * Licensed under the BSD license, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2011 OpenBOR Team
7 */
8
9 #include <pspsdk.h>
10 #include <pspctrl.h>
11 #include <psppower.h>
12 #include <psptypes.h>
13 #include <psploadexec_kernel.h>
14 #include <unistd.h>
15 #include "menu.h"
16 #include "utils.h"
17 #include "control.h"
18 #include "openbor.h"
19 #include "packfile.h"
20 #include "graphics.h"
21 #include "kernel/kernel.h"
22 #include "control/control.h"
23
24 /* Define the module info section */
25 PSP_MODULE_INFO(VERSION_NAME, PSP_MODULE_USER, 3, 0);
26 PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
27 PSP_HEAP_SIZE_MAX();
28
29 typedef void (*WriteToIO)(const char *msg, ...);
30 static WriteToIO pWriteToIO;
31
32 PspDebugRegBlock exception_regs;
33 char packfile[256] = {"bor.pak"};
34 char eboot[256];
35
borExit(int reset)36 void borExit(int reset)
37 {
38 disableGraphics();
39 scePowerSetClockFrequency(222, 222, 111);
40 if(reset < 0)
41 {
42 struct SceKernelLoadExecVSHParam param;
43 memset(¶m, 0, sizeof(param));
44 param.size = sizeof(param);
45 param.argp = eboot;
46 param.args = strlen(eboot)+1;
47 param.key = "game";
48 loadexec(eboot, ¶m);
49 }
50 else
51 {
52 sceKernelExitGame();
53 }
54 }
55
56 static const char *codeTxt[32] =
57 {
58 "Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store",
59 "Address load/inst fetch", "Address store", "Bus error (instr)",
60 "Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction",
61 "Coprocessor unusable", "Arithmetic overflow", "Unknown 14",
62 "Unknown 15", "Unknown 16", "Unknown 17", "Unknown 18", "Unknown 19",
63 "Unknown 20", "Unknown 21", "Unknown 22", "Unknown 23", "Unknown 24",
64 "Unknown 25", "Unknown 26", "Unknown 27", "Unknown 28", "Unknown 29",
65 "Unknown 31"
66 };
67
68 static const unsigned char regName[32][5] =
69 {
70 "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
71 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
72 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
73 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
74 };
75
ExceptionHandler(PspDebugRegBlock * regs)76 void ExceptionHandler(PspDebugRegBlock * regs)
77 {
78 int i;
79 int loop = 0;
80 extern unsigned long _ftext;
81
82 pspDebugScreenInit();
83 pspDebugScreenSetBackColor(0x00FF0000);
84 pspDebugScreenSetTextColor(0xFFFFFFFF);
85 pspDebugScreenClear();
86
87 WRITE_EXCEPTION:
88 if(!loop) pWriteToIO = pspDebugScreenPrintf;
89 else pWriteToIO = writeToLogFile;
90
91 pWriteToIO("\n I'm sorry to inform your PSP has crashed. The exception has\n");
92 pWriteToIO(" been logged to a file. Please include OpenBOR.ELF within the\n");
93 pWriteToIO(" Modules directory and the log file generated to www.LavaLit.com\n\n\n\n");
94 pWriteToIO(" Exception Details:\n\n\n");
95 pWriteToIO(" Exception - %s / %s.text + %X\n", codeTxt[(regs->cause >> 2) & 31], module_info.modname, regs->epc-(int)&_ftext);
96 pWriteToIO(" EPC - %08X\n", (int)regs->epc);
97 pWriteToIO(" REPC - %08X\n", (int)regs->epc-(int)&_ftext);
98 pWriteToIO(" Cause - %08X\n", (int)regs->cause);
99 pWriteToIO(" Status - %08X\n", (int)regs->status);
100 pWriteToIO(" BadVAddr - %08X\n\n\n", (int)regs->badvaddr);
101
102 for(i=0; i<32; i+=4) pWriteToIO(" %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]);
103
104 loop++;
105 if(loop < 2) goto WRITE_EXCEPTION;
106
107 pspDebugScreenPrintf("\n\n\n\n\n");
108 pspDebugScreenPrintf(" Press Home key to exit.\n");
109 pspDebugScreenPrintf(" Press Select key to capture screen.");
110 while(1)
111 {
112 SceCtrlData data;
113 getCtrlData(&data);
114 if(data.Buttons & PSP_CTRL_HOME) sceKernelExitGame();
115 if(data.Buttons & PSP_CTRL_SELECT) screenshot(NULL, NULL, 0);
116 }
117 }
118
initExceptionHandler()119 void initExceptionHandler()
120 {
121 SceKernelLMOption option;
122 int args[2], fd, modid;
123
124 memset(&option, 0, sizeof(option));
125 option.size = sizeof(option);
126 option.mpidtext = PSP_MEMORY_PARTITION_KERNEL;
127 option.mpiddata = PSP_MEMORY_PARTITION_KERNEL;
128 option.position = 0;
129 option.access = 1;
130
131 if((modid = sceKernelLoadModule("/Modules/exception.prx", 0, &option)) >= 0)
132 {
133 args[0] = (int)ExceptionHandler;
134 args[1] = (int)&exception_regs;
135 sceKernelStartModule(modid, 8, args, &fd, NULL);
136 }
137 }
138
main(int argc,char * argv[])139 int main(int argc, char *argv[])
140 {
141 char cwd[256];
142 int status = 0;
143
144 scePowerSetClockFrequency(333, 333, 166);
145 initExceptionHandler();
146 strncpy(eboot, argv[0], strlen(argv[0]));
147
148 if((status = pspSdkLoadStartModule("/Modules/kernel.prx", PSP_MEMORY_PARTITION_KERNEL)) < 0) goto error_loading_prx_modules;
149 if((status = pspSdkLoadStartModule("/Modules/control.prx", PSP_MEMORY_PARTITION_KERNEL)) < 0) goto error_loading_prx_modules;
150 if(getHardwareModel()==1 && (status = pspSdkLoadStartModule("/Modules/dvemgr.prx", PSP_MEMORY_PARTITION_KERNEL)) < 0) goto error_loading_prx_modules;
151
152 setSystemRam();
153 packfile_mode(0);
154 loadsettings();
155 setGraphicsTVOverScan(savedata.overscan[0], savedata.overscan[1], savedata.overscan[2], savedata.overscan[3]);
156 initGraphics(savedata.usetv, PIXEL_32);
157
158 dirExists("Saves", 1);
159 dirExists("Paks", 1);
160 dirExists("Images", 1);
161 dirExists("Logs", 1);
162
163 getcwd(cwd, 256);
164 menu(cwd);
165 openborMain(argc, argv);
166 borExit(0);
167 return 0;
168
169 error_loading_prx_modules:
170 writeToLogFile("PRX Modules failed with %x\n", status);
171 sceKernelDelayThread(5*1000000);
172 return 0;
173 }
174