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(&param, 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, &param);
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