2 Copyright 2009-2010, Ifcaro, jimmikaelkael & Polo
3 Copyright 2006-2008 Polo
4 Licenced under Academic Free License version 3.0
5 Review Open PS2 Loader README & LICENSE files for further details.
7 Some parts of the code are taken from HD Project by Polo
14 extern void *cdvdman_irx
;
15 extern int size_cdvdman_irx
;
17 extern void *cdvdfsv_irx
;
18 extern int size_cdvdfsv_irx
;
21 /* Do not link to strcpy() from libc */
22 inline void _strcpy(char *dst
, const char *src
)
24 strncpy(dst
, src
, strlen(src
)+1);
27 /* Do not link to strcat() from libc */
28 inline void _strcat(char *dst
, const char *src
)
30 _strcpy(&dst
[strlen(dst
)], src
);
33 /* Do not link to strncmp() from libc */
34 int _strncmp(const char *s1
, const char *s2
, int length
)
40 if ((*a
== 0) || (*b
== 0))
50 /* Do not link to strcmp() from libc */
51 int _strcmp(const char *s1
, const char *s2
)
55 while ((s1
[i
] != 0) && (s1
[i
] == s2
[i
]))
60 else if (s1
[i
] < s2
[i
])
66 /* Do not link to strchr() from libc */
67 char *_strchr(const char *string
, int c
)
71 return (char *)string
;
76 return (char *)string
;
81 /* Do not link to strrchr() from libc */
82 char *_strrchr(const char * string
, int c
)
84 /* use the asm strchr to do strrchr */
88 /* if char is never found then this will return 0 */
89 /* if char is found then this will return the last matched location
90 before strchr returned 0 */
93 result
= _strchr(string
,c
);
95 while ((int)result
!= 0) {
97 result
= _strchr(lastmatch
+1,c
);
103 /* Do not link to strtok() from libc */
104 char *_strtok(char *strToken
, const char *strDelimit
)
109 if (strToken
!= NULL
)
121 // Strip out any leading delimiters
122 while (_strchr(strDelimit
, *start
)) {
123 // If a character from the delimiting string
138 if (_strchr(strDelimit
, *end
)) {
139 // if we find a delimiting character
140 // before the end of the string, then
141 // terminate the token and move the end
142 // pointer to the next character
150 // reached the end of the string before finding a delimiter
151 // so dont move on to the next character
155 /* Do not link to strstr() from libc */
156 char *_strstr(const char *string
, const char *substring
)
163 if (strlen(substring
)==0)
164 return (char*)string
;
166 strpos
= (char*)string
;
168 while (*strpos
!= 0) {
169 if (_strncmp(strpos
, substring
, strlen(substring
)) == 0)
178 /* Do not link to islower() from libc */
179 inline int _islower(int c
)
181 if ((c
< 'a') || (c
> 'z'))
184 // passed both criteria, so it
185 // is a lower case alpha char
189 /* Do not link to toupper() from libc */
190 inline int _toupper(int c
)
198 /* Do not link to memcmp() from libc */
199 int _memcmp(const void *s1
, const void *s2
, unsigned int length
)
212 /*----------------------------------------------------------------------------------------*/
213 /* This function converts string to unsigned integer. Stops on illegal characters. */
214 /* Put here because including atoi rises the size of loader.elf by another kilobyte */
215 /* and that causes some games to stop working. */
216 /*----------------------------------------------------------------------------------------*/
217 unsigned int _strtoui(const char* p
)
226 if ((*p
< '0') || (*p
> '9'))
229 r
= r
* 10 + (*p
++ - '0');
235 /*----------------------------------------------------------------------------------------*/
236 /* This function format g_ipconfig with ip, netmask, and gateway */
237 /*----------------------------------------------------------------------------------------*/
238 void set_ipconfig(void)
240 memset(g_ipconfig
, 0, IPCONFIG_MAX_LEN
);
243 // add ip to g_ipconfig buf
244 strncpy(&g_ipconfig
[g_ipconfig_len
], g_ps2_ip
, 16);
245 g_ipconfig_len
+= strlen(g_ps2_ip
) + 1;
247 // add netmask to g_ipconfig buf
248 strncpy(&g_ipconfig
[g_ipconfig_len
], g_ps2_netmask
, 16);
249 g_ipconfig_len
+= strlen(g_ps2_netmask
) + 1;
251 // add gateway to g_ipconfig buf
252 strncpy(&g_ipconfig
[g_ipconfig_len
], g_ps2_gateway
, 16);
253 g_ipconfig_len
+= strlen(g_ps2_gateway
) + 1;
256 /*----------------------------------------------------------------------------------------*/
257 /* This function retrieve a pattern in a buffer, using a mask */
258 /*----------------------------------------------------------------------------------------*/
259 u32
*find_pattern_with_mask(u32
*buf
, u32 bufsize
, u32
*pattern
, u32
*mask
, u32 len
)
264 bufsize
/= sizeof(u32
);
266 for (i
= 0; i
< bufsize
- len
; i
++) {
267 for (j
= 0; j
< len
; j
++) {
268 if ((buf
[i
+ j
] & mask
[j
]) != pattern
[j
])
278 /*----------------------------------------------------------------------------------------*/
279 /* Copy 'size' bytes of 'eedata' from EE to 'iopptr' in IOP. */
280 /*----------------------------------------------------------------------------------------*/
281 void CopyToIop(void *eedata
, unsigned int size
, void *iopptr
)
283 SifDmaTransfer_t dmadata
;
286 dmadata
.src
= eedata
;
287 dmadata
.dest
= iopptr
;
293 id
= SifSetDma(&dmadata
, 1);
296 while (SifDmaStat(id
) >= 0) {;}
299 /*----------------------------------------------------------------------------------------*/
300 /* Replace a module in a IOPRP image. */
301 /*----------------------------------------------------------------------------------------*/
302 int Patch_Mod(ioprp_t
*ioprp_img
, const char *name
, void *modptr
, int modsize
)
304 int i
, offset_in
, bytes_to_move
, next_mod_offset
, diff
;
306 u8
*p
= (u8
*)ioprp_img
->data_in
;
308 // arrange modsize to next 16 bytes align
310 modsize
= (modsize
+ 0x10) & 0xfffffff0;
313 romdir_in
= (romdir_t
*)ioprp_img
->data_in
;
315 // scan for module offset & size
316 while(strlen(romdir_in
->fileName
) > 0)
318 //scr_printf("%s:%d ", romdir_in->fileName, romdir_in->fileSize);
319 if (!_strcmp(romdir_in
->fileName
, name
))
322 if ((romdir_in
->fileSize
% 0x10)==0)
323 offset_in
+= romdir_in
->fileSize
;
325 offset_in
+= (romdir_in
->fileSize
+ 0x10) & 0xfffffff0;
332 if ((romdir_in
->fileSize
% 0x10)==0)
333 next_mod_offset
= offset_in
+ romdir_in
->fileSize
;
335 next_mod_offset
= offset_in
+ ((romdir_in
->fileSize
+ 0x10) & 0xfffffff0);
337 bytes_to_move
= ioprp_img
->size_in
- next_mod_offset
;
339 // and greater than one in IOPRP img
340 if (modsize
>= romdir_in
->fileSize
) {
341 diff
= modsize
- romdir_in
->fileSize
;
343 if (bytes_to_move
> 0) {
344 for (i
= ioprp_img
->size_in
; i
>= next_mod_offset
; i
--)
347 ioprp_img
->size_in
+= diff
;
351 // or smaller than one in IOPRP
353 diff
= romdir_in
->fileSize
- modsize
;
355 if (bytes_to_move
> 0) {
356 for (i
= 0; i
< bytes_to_move
; i
++)
357 p
[offset_in
+ modsize
+ i
] = p
[next_mod_offset
+ i
];
359 ioprp_img
->size_in
-= diff
;
364 // finally replace module
367 memcpy((void *)(ioprp_img
->data_in
+offset_in
), modptr
, modsize
);
371 // correct filesize in romdir
372 romdir_in
->fileSize
= modsize
;
375 ioprp_img
->size_out
= ioprp_img
->size_in
;
380 /*----------------------------------------------------------------------------------------*/
381 /* Build an EELOAD Config file */
382 /*----------------------------------------------------------------------------------------*/
383 int Build_EELOADCNF_Img(ioprp_t
*ioprp_img
, int have_xloadfile
)
385 int romdir_size
, extinfo_size
, iopbtconf_size
, cdvdman_size
, cdvdfsv_size
;
388 romdir_in
= (romdir_t
*)ioprp_img
->data_in
;
389 memset((void *)romdir_in
, 0, 7 * sizeof(romdir_t
));
392 _strcpy(romdir_in
->fileName
, "RESET");
393 romdir_in
->extinfo_size
= 8;
396 _strcpy(romdir_in
->fileName
, "ROMDIR");
397 romdir_size
= 7 * sizeof(romdir_t
);
398 romdir_in
->fileSize
= romdir_size
;
401 _strcpy(romdir_in
->fileName
, "EXTINFO");
402 extinfo_size
= 8 + 8 + 24 + 24;
403 romdir_in
->fileSize
= extinfo_size
;
406 _strcpy(romdir_in
->fileName
, "IOPBTCONF");
407 romdir_in
->extinfo_size
= 8;
410 u8
*ptr
= (u8
*)(ioprp_img
->data_in
+ romdir_size
);
411 memcpy(&ptr
[0], "\0\0\x04\x01\x07\x02\x02\x20", 8);
412 memcpy(&ptr
[8], "\0\0\x04\x01\x07\x02\x02\x20", 8);
413 memcpy(&ptr
[8+8], "\0\0\x04\x01\x12\x04\x88\x19\x99\x99\0\x02\0\0\x08\x03""CDVDMAN\0", 24);
414 memcpy(&ptr
[8+8+24], "\0\0\x04\x01\x12\x04\x88\x19\x99\x99\0\x02\0\0\x08\x03""CDVDFSV\0", 24);
418 char *iopbtconf_str0
= "@800\nSYSMEM\nLOADCORE\nEXCEPMAN\nINTRMANP\nINTRMANI\nSSBUSC\nDMACMAN\nTIMEMANP\nTIMEMANI\n";
419 char *iopbtconf_str1
= "SYSCLIB\nHEAPLIB\nEECONF\nTHREADMAN\nVBLANK\nIOMAN\nMODLOAD\nROMDRV\nSTDIO\nSIFMAN\n";
420 char *iopbtconf_str2
= "IGREETING\nSIFCMD\nREBOOT\nLOADFILE\nCDVDMAN\nCDVDFSV\nSIFINIT\nFILEIO\nSECRMAN\nEESYNC\n";
422 iopbtconf_str2
= "IGREETING\nSIFCMD\nREBOOT\nXLOADFILE\nCDVDMAN\nCDVDFSV\nSIFINIT\nFILEIO\nSECRMAN\nEESYNC\n";
424 memcpy(&ptr
[0], iopbtconf_str0
, strlen(iopbtconf_str0
));
425 memcpy(&ptr
[strlen(iopbtconf_str0
)], iopbtconf_str1
, strlen(iopbtconf_str1
));
426 memcpy(&ptr
[strlen(iopbtconf_str0
)+strlen(iopbtconf_str1
)], iopbtconf_str2
, strlen(iopbtconf_str2
));
428 // Fill IOPBTCONF filesize
429 iopbtconf_size
= strlen(iopbtconf_str0
)+strlen(iopbtconf_str1
)+strlen(iopbtconf_str2
);
430 romdir_in
->fileSize
= iopbtconf_size
;
431 // arrange size to next 16 bytes multiple
432 if (iopbtconf_size
% 0x10)
433 iopbtconf_size
= (iopbtconf_size
+ 0x10) & 0xfffffff0;
435 ptr
+= iopbtconf_size
;
438 _strcpy(romdir_in
->fileName
, "CDVDMAN");
439 romdir_in
->extinfo_size
= 24;
440 cdvdman_size
= size_cdvdman_irx
;
441 romdir_in
->fileSize
= cdvdman_size
;
442 // arrange size to next 16 bytes multiple
443 if (cdvdman_size
% 0x10)
444 cdvdman_size
= (cdvdman_size
+ 0x10) & 0xfffffff0;
447 memcpy(&ptr
[0], cdvdman_irx
, size_cdvdman_irx
);
454 _strcpy(romdir_in
->fileName
, "CDVDFSV");
455 romdir_in
->extinfo_size
= 24;
456 cdvdfsv_size
= size_cdvdfsv_irx
;
457 romdir_in
->fileSize
= cdvdfsv_size
;
458 // arrange size to next 16 bytes multiple
459 if (cdvdfsv_size
% 0x10)
460 cdvdfsv_size
= (cdvdfsv_size
+ 0x10) & 0xfffffff0;
463 memcpy(&ptr
[0], cdvdfsv_irx
, size_cdvdfsv_irx
);
469 // Fill mini image size
470 ioprp_img
->data_out
= ioprp_img
->data_in
;
471 ioprp_img
->size_out
= ioprp_img
->size_in
= romdir_size
+ extinfo_size
+ iopbtconf_size
+ cdvdman_size
+ cdvdfsv_size
;
476 /*----------------------------------------------------------------------------------------*/
478 /*----------------------------------------------------------------------------------------*/
479 inline int XLoadfileCheck(void)
483 fd
= open("rom0:XLOADFILE", O_RDONLY
);
492 /*----------------------------------------------------------------------------------------*/
494 /*----------------------------------------------------------------------------------------*/
495 inline void delay(int count
)
499 for (i
= 0; i
< count
; i
++) {
501 while(ret
--) asm("nop\nnop\nnop\nnop");
505 /*----------------------------------------------------------------------------------------*/
506 /* Apply SBV patchs. */
507 /*----------------------------------------------------------------------------------------*/
508 inline void Sbv_Patch(void)
510 sbv_patch_enable_lmb();
511 sbv_patch_disable_prefix_check();