Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / iopcore / cdvdfsv / cdvdfsv.c
blobb30e50204ea0c7cca7eca49273919ab7696ff7c1
1 /*
2 Copyright 2009, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review open-ps2-loader README & LICENSE files for further details.
5 */
7 #include <intrman.h>
8 #include <loadcore.h>
9 #include <stdio.h>
10 #include <sifcmd.h>
11 #include <sifman.h>
12 #include <sysmem.h>
13 #include <sysclib.h>
14 #include <thbase.h>
15 #include <thsemap.h>
17 #include "smsutils.h"
19 #define MODNAME "cdvd_ee_driver"
20 IRX_ID(MODNAME, 2, 2);
22 typedef struct {
23 u8 stat;
24 u8 second;
25 u8 minute;
26 u8 hour;
27 u8 week;
28 u8 day;
29 u8 month;
30 u8 year;
31 } cd_clock_t;
33 typedef struct {
34 u32 lsn;
35 u32 size;
36 char name[16];
37 u8 date[8];
38 } cd_file_t;
40 typedef struct {
41 u32 lsn;
42 u32 size;
43 char name[16];
44 u8 date[8];
45 u32 flag;
46 } cdl_file_t;
48 typedef struct {
49 u8 trycount;
50 u8 spindlctrl;
51 u8 datapattern;
52 u8 pad;
53 } cd_read_mode_t;
55 // cdGetError() return values
56 #define CDVD_ERR_FAIL -1 // error in cdGetError()
57 #define CDVD_ERR_NO 0x00 // no error occurred
58 #define CDVD_ERR_ABRT 0x01 // command was aborted due to cdBreak() call
59 #define CDVD_ERR_CMD 0x10 // unsupported command
60 #define CDVD_ERR_OPENS 0x11 // tray is open
61 #define CDVD_ERR_NODISC 0x12 // no disk inserted
62 #define CDVD_ERR_NORDY 0x13 // drive is busy processing another command
63 #define CDVD_ERR_CUD 0x14 // command unsupported for disc currently in drive
64 #define CDVD_ERR_IPI 0x20 // sector address error
65 #define CDVD_ERR_ILI 0x21 // num sectors error
66 #define CDVD_ERR_PRM 0x22 // command parameter error
67 #define CDVD_ERR_READ 0x30 // error while reading
68 #define CDVD_ERR_TRMOPN 0x31 // tray was opened
69 #define CDVD_ERR_EOM 0x32 // outermost error
70 #define CDVD_ERR_READCF 0xFD // error setting command
71 #define CDVD_ERR_READCFR 0xFE // error setting command
73 // cdvdman imports
74 int sceCdInit(int init_mode); // #4
75 int sceCdStandby(void); // #5
76 int sceCdRead(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode); // #6
77 int sceCdSeek(u32 lsn); // #7
78 int sceCdGetError(void); // #8
79 int sceCdSearchFile(cd_file_t *fp, const char *name); // #10
80 int sceCdSync(int mode); // #11
81 int sceCdGetDiskType(void); // #12
82 int sceCdDiskReady(int mode); // #13
83 int sceCdTrayReq(int mode, u32 *traycnt); // #14
84 int sceCdStop(void); // #15
85 int sceCdReadClock(cd_clock_t *rtc); // #24
86 int sceCdStatus(void); // #28
87 int sceCdApplySCmd(int cmd, void *in, u32 in_size, void *out); // #29
88 int sceCdPause(void); // #38
89 int sceCdBreak(void); // #39
90 int sceCdStInit(u32 bufmax, u32 bankmax, void *iop_bufaddr); // #56
91 int sceCdStRead(u32 sectors, void *buf, u32 mode, u32 *err); // #57
92 int sceCdStSeek(u32 lsn); // #58
93 int sceCdStStart(u32 lsn, cd_read_mode_t *mode); // #59
94 int sceCdStStat(void); // #60
95 int sceCdStStop(void); // #61
96 int sceCdRead0(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode); // #62
97 int sceCdStPause(void); // #67
98 int sceCdStResume(void); // #68
99 int sceCdMmode(int mode); // #75
100 int sceCdStSeekF(u32 lsn); // #77
101 int sceCdReadDiskID(void *DiskID); // #79
102 int sceCdReadGUID(void *GUID); // #80
103 int sceCdSetTimeout(int param, int timeout); // #81
104 int sceCdReadModelID(void *ModelID); // #82
105 int sceCdReadDvdDualInfo(int *on_dual, u32 *layer1_start); // #83
106 int sceCdLayerSearchFile(cdl_file_t *fp, const char *name, int layer); // #84
108 typedef struct {
109 int func_ret;
110 int cdvdfsv_ver;
111 int cdvdman_ver;
112 int debug_mode;
113 } cdvdinit_res_t;
115 typedef struct {
116 int result;
117 cd_clock_t rtc;
118 } cdvdreadclock_res_t;
120 typedef struct {
121 int result;
122 u32 param1;
123 u32 param2;
124 } cdvdSCmd_res_t;
126 typedef struct {
127 u16 cmd;
128 u16 in_size;
129 void *in;
130 } cdapplySCmd_t __attribute__((aligned(64)));
132 typedef struct { // size =0x124
133 cd_file_t cdfile; // 0x000
134 char name[256]; // 0x020
135 void *dest; // 0x120
136 } SearchFilePkt_t;
138 typedef struct { // size =0x128
139 cdl_file_t cdfile; // 0x000
140 char name[256]; // 0x024
141 void *dest; // 0x124
142 } SearchFilePkt2_t;
144 typedef struct { // size =0x12c
145 cdl_file_t cdfile; // 0x000
146 char name[256]; // 0x024
147 void *dest; // 0x124
148 int layer; // 0x128
149 } SearchFilePktl_t;
151 typedef struct {
152 u32 lsn;
153 u32 sectors;
154 void *buf;
155 cd_read_mode_t mode;
156 void *eeaddr1;
157 void *eeaddr2;
158 } RpcCdvd_t;
160 typedef struct {
161 u32 lsn;
162 u32 sectors;
163 void *buf;
164 int cmd;
165 cd_read_mode_t mode;
166 u32 pad;
167 } RpcCdvdStream_t;
169 typedef struct {
170 u32 bufmax;
171 u32 bankmax;
172 void *buf;
173 u32 pad;
174 } RpcCdvdStInit_t;
176 typedef struct {
177 u32 lsn; // sector location to start reading from
178 u32 sectors; // number of sectors to read
179 void *buf; // buffer address to read to ( bit0: 0=EE, 1=IOP )
180 } RpcCdvdchain_t; // (EE addresses must be on 64byte alignment)
182 typedef struct { // size = 144
183 u32 b1len;
184 u32 b2len;
185 void *pdst1;
186 void *pdst2;
187 u8 buf1[64];
188 u8 buf2[64];
189 } cdvdfsv_readee_t;
191 // internal prototypes
192 void init_thread(void *args);
193 void cdvdfsv_startrpcthreads(void);
194 void cdvdfsv_rpc0_th(void *args);
195 void cdvdfsv_rpc1_th(void *args);
196 void cdvdfsv_rpc2_th(void *args);
197 void *cbrpc_cdinit(u32 fno, void *buf, int size);
198 void *cbrpc_cdvdScmds(u32 fno, void *buf, int size);
199 void *(*rpcSCmd_fn)(u32 fno, void *buf, int size);
200 void *rpcSCmd_cdapplySCmd(u32 fno, void *buf, int size);
201 void *rpcSCmd_cdreadclock(u32 fno, void *buf, int size);
202 void *rpcSCmd_cdgetdisktype(u32 fno, void *buf, int size);
203 void *rpcSCmd_cdgeterror(u32 fno, void *buf, int size);
204 void *rpcSCmd_cdtrayreq(u32 fno, void *buf, int size);
205 void *rpcSCmd_cdstatus(u32 fno, void *buf, int size);
206 void *rpcSCmd_cdabort(u32 fno, void *buf, int size);
207 void *rpcSCmd_cdpoweroff(u32 fno, void *buf, int size);
208 void *rpcSCmd_cdmmode(u32 fno, void *buf, int size);
209 void *rpcSCmd_cdreadGUID(u32 fno, void *buf, int size);
210 void *rpcSCmd_cdsettimeout(u32 fno, void *buf, int size);
211 void *rpcSCmd_cdreadModelID(u32 fno, void *buf, int size);
212 void *rpcSCmd_cdreaddvddualinfo(u32 fno, void *buf, int size);
213 void *rpcSCmd_dummy(u32 fno, void *buf, int size);
214 void *cbrpc_cddiskready(u32 fno, void *buf, int size);
215 void *cbrpc_cddiskready2(u32 fno, void *buf, int size);
216 void *cbrpc_cdvdNcmds(u32 fno, void *buf, int size);
217 void *(*rpcNCmd_fn)(u32 fno, void *buf, int size);
218 void *rpcNCmd_cdread(u32 fno, void *buf, int size);
219 void *rpcNCmd_cdgettoc(u32 fno, void *buf, int size);
220 void *rpcNCmd_cdseek(u32 fno, void *buf, int size);
221 void *rpcNCmd_cdstandby(u32 fno, void *buf, int size);
222 void *rpcNCmd_cdstop(u32 fno, void *buf, int size);
223 void *rpcNCmd_cdpause(u32 fno, void *buf, int size);
224 void *rpcNCmd_cdstream(u32 fno, void *buf, int size);
225 void *rpcNCmd_iopmread(u32 fno, void *buf, int size);
226 void *rpcNCmd_cddiskready(u32 fno, void *buf, int size);
227 void *rpcNCmd_cdreadchain(u32 fno, void *buf, int size);
228 void *rpcNCmd_cdreadDiskID(u32 fno, void *buf, int size);
229 void *rpcNCmd_cdgetdisktype(u32 fno, void *buf, int size);
230 void *rpcNCmd_dummy(u32 fno, void *buf, int size);
231 void *cbrpc_S596(u32 fno, void *buf, int size);
232 void *cbrpc_cdsearchfile(u32 fno, void *buf, int size);
233 void cdvd_Stsubcmdcall(void *buf);
234 void (*cdvd_Stsubcall_fn)(void *buf);
235 void cdvdSt_dummy(void *buf);
236 void cdvdSt_start(void *buf);
237 void cdvdSt_read(void *buf);
238 void cdvdSt_stop(void *buf);
239 void cdvdSt_seek(void *buf);
240 void cdvdSt_init(void *buf);
241 void cdvdSt_stat(void *buf);
242 void cdvdSt_pause(void *buf);
243 void cdvdSt_resume(void *buf);
244 void cdvdSt_seekF(void *buf);
245 void cdvd_iopmread(void *buf);
246 void cdvd_readchain(void *buf);
247 void cdvd_readee(void *buf);
248 void sendcurlsnEE(void *eeaddr, u32 lsn);
250 // rpcSCmd funcs array
251 void *rpcSCmd_tab[40] = {
252 (void *)rpcSCmd_dummy,
253 (void *)rpcSCmd_cdreadclock,
254 (void *)rpcSCmd_dummy, // cdwriteclock
255 (void *)rpcSCmd_cdgetdisktype,
256 (void *)rpcSCmd_cdgeterror,
257 (void *)rpcSCmd_cdtrayreq,
258 (void *)rpcSCmd_dummy,
259 (void *)rpcSCmd_dummy,
260 (void *)rpcSCmd_dummy,
261 (void *)rpcSCmd_dummy,
262 (void *)rpcSCmd_dummy,
263 (void *)rpcSCmd_cdapplySCmd, // ApplySCmd
264 (void *)rpcSCmd_cdstatus,
265 (void *)rpcSCmd_dummy,
266 (void *)rpcSCmd_dummy,
267 (void *)rpcSCmd_dummy,
268 (void *)rpcSCmd_dummy,
269 (void *)rpcSCmd_dummy,
270 (void *)rpcSCmd_dummy,
271 (void *)rpcSCmd_dummy,
272 (void *)rpcSCmd_dummy,
273 (void *)rpcSCmd_dummy,
274 (void *)rpcSCmd_cdabort,
275 (void *)rpcSCmd_dummy,
276 (void *)rpcSCmd_dummy,
277 (void *)rpcSCmd_dummy,
278 (void *)rpcSCmd_dummy,
279 (void *)rpcSCmd_dummy,
280 (void *)rpcSCmd_dummy,
281 (void *)rpcSCmd_dummy,
282 (void *)rpcSCmd_dummy,
283 (void *)rpcSCmd_dummy, // CancelPowerOff
284 (void *)rpcSCmd_dummy, // BlueLedCtrl
285 (void *)rpcSCmd_cdpoweroff,
286 (void *)rpcSCmd_cdmmode,
287 (void *)rpcSCmd_dummy, // SetThreadPriority
288 (void *)rpcSCmd_cdreadGUID,
289 (void *)rpcSCmd_cdsettimeout,
290 (void *)rpcSCmd_cdreadModelID,
291 (void *)rpcSCmd_cdreaddvddualinfo
294 // rpcNCmd funcs array
295 void *rpcNCmd_tab[24] = {
296 (void *)rpcNCmd_dummy,
297 (void *)rpcNCmd_cdread,
298 (void *)rpcNCmd_cdread, // Cdda Read
299 (void *)rpcNCmd_cdread, // Dvd Read
300 (void *)rpcNCmd_cdgettoc,
301 (void *)rpcNCmd_cdseek,
302 (void *)rpcNCmd_cdstandby,
303 (void *)rpcNCmd_cdstop,
304 (void *)rpcNCmd_cdpause,
305 (void *)rpcNCmd_cdstream,
306 (void *)rpcNCmd_dummy, // CDDA Stream
307 (void *)rpcNCmd_dummy,
308 (void *)rpcNCmd_dummy, // Apply NCMD
309 (void *)rpcNCmd_iopmread,
310 (void *)rpcNCmd_cddiskready,
311 (void *)rpcNCmd_cdreadchain,
312 (void *)rpcNCmd_dummy,
313 (void *)rpcNCmd_cdreadDiskID,
314 (void *)rpcNCmd_dummy,
315 (void *)rpcNCmd_dummy, // ???
316 (void *)rpcNCmd_dummy,
317 (void *)rpcNCmd_dummy,
318 (void *)rpcNCmd_dummy,
319 (void *)rpcNCmd_cdgetdisktype
322 // cdvdStsubcall funcs array
323 void *cdvdStsubcall_tab[10] = {
324 (void *)cdvdSt_dummy,
325 (void *)cdvdSt_start,
326 (void *)cdvdSt_read,
327 (void *)cdvdSt_stop,
328 (void *)cdvdSt_seek,
329 (void *)cdvdSt_init,
330 (void *)cdvdSt_stat,
331 (void *)cdvdSt_pause,
332 (void *)cdvdSt_resume,
333 (void *)cdvdSt_seekF
336 cd_read_mode_t cdvdfsv_Stmode;
337 static u8 *cdvdfsv_buf;
339 u32 cbrpcS596_oldfno;
340 u32 cbrpcS596_fno;
342 SifRpcDataQueue_t rpc0_DQ __attribute__((aligned(16)));
343 SifRpcDataQueue_t rpc1_DQ __attribute__((aligned(16)));
344 SifRpcDataQueue_t rpc2_DQ __attribute__((aligned(16)));
345 SifRpcServerData_t cdinit_rpcSD, cddiskready_rpcSD, cddiskready2_rpcSD, cdvdScmds_rpcSD __attribute__((aligned(16)));
346 SifRpcServerData_t cdsearchfile_rpcSD, cdvdNcmds_rpcSD __attribute__((aligned(16)));
347 SifRpcServerData_t S596_rpcSD __attribute__((aligned(16)));
349 static u8 cdinit_rpcbuf[16] __attribute__((aligned(16)));
350 static u8 cddiskready_rpcbuf[16] __attribute__((aligned(16)));
351 static u8 cddiskready2_rpcbuf[16] __attribute__((aligned(16)));
352 static u8 cdvdScmds_rpcbuf[1024] __attribute__((aligned(16)));
353 static u8 cdsearchfile_rpcbuf[304] __attribute__((aligned(16)));
354 static u8 cdvdNcmds_rpcbuf[1024] __attribute__((aligned(16)));
355 static u8 S596_rpcbuf[16] __attribute__((aligned(16)));
356 static u8 curlsn_buf[16] __attribute__ ((aligned(64)));
358 //static int g_reduced_iopmemusage = 0xC0DEC0DE;
360 #define CDVDFSV_BUF_SECTORS 2
362 int init_thread_id;
363 int rpc0_thread_id, rpc1_thread_id, rpc2_thread_id;
365 struct irx_export_table _exp_cdvdfsv;
367 //-------------------------------------------------------------------------
368 int _start(int argc, char** argv)
370 iop_thread_t thread_param;
372 RegisterLibraryEntries(&_exp_cdvdfsv);
374 FlushDcache();
375 CpuEnableIntr();
377 thread_param.attr = TH_C;
378 thread_param.option = 0;
379 thread_param.thread = (void *)init_thread;
380 thread_param.stacksize = 0x800;
381 thread_param.priority = 0x50;
383 init_thread_id = CreateThread(&thread_param);
384 StartThread(init_thread_id, 0);
386 return MODULE_RESIDENT_END;
389 //-------------------------------------------------------------------------
390 void init_thread(void *args)
392 if (!sceSifCheckInit())
393 sceSifInit();
395 sceSifInitRpc(0);
397 cdvdfsv_buf = AllocSysMemory(ALLOC_FIRST, (CDVDFSV_BUF_SECTORS << 11)+2048, NULL);
398 if (!cdvdfsv_buf)
399 SleepThread();
401 cdvdfsv_startrpcthreads();
404 //-------------------------------------------------------------------------
405 void cdvdfsv_startrpcthreads(void)
407 iop_thread_t thread_param;
409 thread_param.attr = TH_C;
410 thread_param.option = 0;
411 thread_param.thread = (void *)cdvdfsv_rpc1_th;
412 thread_param.stacksize = 0x1900;
413 thread_param.priority = 0x51;
415 rpc1_thread_id = CreateThread(&thread_param);
416 StartThread(rpc1_thread_id, 0);
418 thread_param.attr = TH_C;
419 thread_param.option = 0;
420 thread_param.thread = (void *)cdvdfsv_rpc2_th;
421 thread_param.stacksize = 0x1900;
422 thread_param.priority = 0x51;
424 rpc2_thread_id = CreateThread(&thread_param);
425 StartThread(rpc2_thread_id, 0);
427 thread_param.attr = TH_C;
428 thread_param.option = 0;
429 thread_param.thread = (void *)cdvdfsv_rpc0_th;
430 thread_param.stacksize = 0x800;
431 thread_param.priority = 0x51;
433 rpc0_thread_id = CreateThread(&thread_param);
434 StartThread(rpc0_thread_id, 0);
437 //-------------------------------------------------------------------------
438 void cdvdfsv_rpc0_th(void *args)
440 sceSifSetRpcQueue(&rpc0_DQ, GetThreadId());
442 sceSifRegisterRpc(&S596_rpcSD, 0x80000596, (void *)cbrpc_S596, S596_rpcbuf, NULL, NULL, &rpc0_DQ);
443 sceSifRegisterRpc(&cddiskready2_rpcSD, 0x8000059c, (void *)cbrpc_cddiskready2, cddiskready2_rpcbuf, NULL, NULL, &rpc0_DQ);
445 sceSifRpcLoop(&rpc0_DQ);
448 //-------------------------------------------------------------------------
449 void cdvdfsv_rpc1_th(void *args)
451 // Starts cd Init rpc Server
452 // Starts cd Disk ready rpc server
453 // Starts SCMD rpc server;
455 sceSifSetRpcQueue(&rpc1_DQ, GetThreadId());
457 sceSifRegisterRpc(&cdinit_rpcSD, 0x80000592, (void *)cbrpc_cdinit, cdinit_rpcbuf, NULL, NULL, &rpc1_DQ);
458 sceSifRegisterRpc(&cdvdScmds_rpcSD, 0x80000593, (void *)cbrpc_cdvdScmds, cdvdScmds_rpcbuf, NULL, NULL, &rpc1_DQ);
459 sceSifRegisterRpc(&cddiskready_rpcSD, 0x8000059a, (void *)cbrpc_cddiskready, cddiskready_rpcbuf, NULL, NULL, &rpc1_DQ);
461 sceSifRpcLoop(&rpc1_DQ);
464 //-------------------------------------------------------------------------
465 void cdvdfsv_rpc2_th(void *args)
467 // Starts NCMD rpc server
468 // Starts Search file rpc server
470 sceSifSetRpcQueue(&rpc2_DQ, GetThreadId());
472 sceSifRegisterRpc(&cdvdNcmds_rpcSD, 0x80000595, (void *)cbrpc_cdvdNcmds, cdvdNcmds_rpcbuf, NULL, NULL, &rpc2_DQ);
473 sceSifRegisterRpc(&cdsearchfile_rpcSD, 0x80000597, (void *)cbrpc_cdsearchfile, cdsearchfile_rpcbuf, NULL, NULL, &rpc2_DQ);
475 sceSifRpcLoop(&rpc2_DQ);
478 //-------------------------------------------------------------------------
479 void *cbrpc_cdinit(u32 fno, void *buf, int size)
480 { // CD Init RPC callback
482 cdvdinit_res_t *r = (cdvdinit_res_t *)buf;
484 r->func_ret = sceCdInit(*(int *)buf);
486 r->cdvdfsv_ver = 0x223;
487 r->cdvdman_ver = 0x223;
488 //r->debug_mode = 0xff;
490 return buf;
493 //-------------------------------------------------------------------------
494 void *cbrpc_cdvdScmds(u32 fno, void *buf, int size)
495 { // CD SCMD RPC callback
497 if ((u32)(fno >= 40))
498 return rpcSCmd_dummy(fno, buf, size);
500 // Call SCMD RPC sub function
501 rpcSCmd_fn = (void *)rpcSCmd_tab[fno];
503 return rpcSCmd_fn(fno, buf, size);
506 //--------------------------------------------------------------
507 void *rpcSCmd_cdapplySCmd(u32 fno, void *buf, int size)
508 { // CD ApplySCMD RPC SCMD
510 cdapplySCmd_t *SCmd = (cdapplySCmd_t *)buf;
512 sceCdApplySCmd(SCmd->cmd, SCmd->in, SCmd->in_size, buf);
513 return buf;
516 //-------------------------------------------------------------------------
517 void *rpcSCmd_cdreadclock(u32 fno, void *buf, int size)
518 { // CD Read Clock RPC SCMD
519 cdvdreadclock_res_t *r = (cdvdreadclock_res_t *)buf;
521 r->result = sceCdReadClock(&r->rtc);
522 return buf;
525 //-------------------------------------------------------------------------
526 void *rpcSCmd_cdgetdisktype(u32 fno, void *buf, int size)
527 { // CD Get Disc Type RPC SCMD
529 *(int *)buf = sceCdGetDiskType();
530 return buf;
533 //-------------------------------------------------------------------------
534 void *rpcSCmd_cdgeterror(u32 fno, void *buf, int size)
535 { // CD Get Error RPC SCMD
537 *(int *)buf = sceCdGetError();
538 return buf;
541 //-------------------------------------------------------------------------
542 void *rpcSCmd_cdtrayreq(u32 fno, void *buf, int size)
543 { // CD Tray Req RPC SCMD
545 cdvdSCmd_res_t *r = (cdvdSCmd_res_t *)buf;
547 r->result = sceCdTrayReq(*((int *)buf), &r->param1);
548 return buf;
551 //-------------------------------------------------------------------------
552 void *rpcSCmd_cdstatus(u32 fno, void *buf, int size)
553 { // CD Status RPC SCMD
555 *(int *)buf = sceCdStatus();
556 return buf;
559 //-------------------------------------------------------------------------
560 void *rpcSCmd_cdabort(u32 fno, void *buf, int size)
561 { // CD Abort RPC SCMD
563 *(int *)buf = sceCdBreak();
564 return buf;
567 //-------------------------------------------------------------------------
568 void *rpcSCmd_cdpoweroff(u32 fno, void *buf, int size)
569 { // CD Power Off RPC SCMD
571 *(int *)buf = 1;
572 return buf;
575 //-------------------------------------------------------------------------
576 void *rpcSCmd_cdmmode(u32 fno, void *buf, int size)
577 { // CD Media Mode RPC SCMD
579 *(int *)buf = sceCdMmode(*(int *)buf);
580 return buf;
583 //-------------------------------------------------------------------------
584 void *rpcSCmd_cdreadGUID(u32 fno, void *buf, int size)
585 { // CD Read GUID RPC SCMD
587 cdvdSCmd_res_t *r = (cdvdSCmd_res_t *)buf;
589 r->result = sceCdReadGUID(&r->param1);
590 return buf;
593 //-------------------------------------------------------------------------
594 void *rpcSCmd_cdsettimeout(u32 fno, void *buf, int size)
595 { // CD Set TimeOut RPC SCMD
597 cdvdSCmd_res_t *r = (cdvdSCmd_res_t *)buf;
599 r->result = sceCdSetTimeout(*(int *)buf, r->param1);
600 return buf;
603 //-------------------------------------------------------------------------
604 void *rpcSCmd_cdreadModelID(u32 fno, void *buf, int size)
605 { // CD Read Disk ID RPC SCMD
607 cdvdSCmd_res_t *r = (cdvdSCmd_res_t *)buf;
609 r->result = sceCdReadModelID(&r->param1);
610 return buf;
613 //-------------------------------------------------------------------------
614 void *rpcSCmd_cdreaddvddualinfo(u32 fno, void *buf, int size)
615 { // CD Read Dvd DualLayer Info RPC SCMD
617 cdvdSCmd_res_t *r = (cdvdSCmd_res_t *)buf;
619 r->result = sceCdReadDvdDualInfo((int *)&r->param1, &r->param2);
620 return buf;
623 //-------------------------------------------------------------------------
624 void *rpcSCmd_dummy(u32 fno, void *buf, int size)
626 *(int *)buf = 0;
627 return buf;
630 //-------------------------------------------------------------------------
631 void *cbrpc_cddiskready(u32 fno, void *buf, int size)
632 { // CD Disk Ready RPC callback
634 if (*(int *)buf == 0)
635 *(int *)buf = sceCdDiskReady(0);
636 else
637 *(int *)buf = sceCdDiskReady(1);
639 return buf;
642 //-------------------------------------------------------------------------
643 void *cbrpc_cddiskready2(u32 fno, void *buf, int size)
644 { // CD Disk Ready2 RPC callback
646 *(int *)buf = sceCdDiskReady(0);
648 return buf;
651 //-------------------------------------------------------------------------
652 void *cbrpc_cdvdNcmds(u32 fno, void *buf, int size)
653 { // CD NCMD RPC callback
655 if ((u32)(fno >= 24))
656 return rpcNCmd_dummy(fno, buf, size);
658 // Call NCMD RPC sub function
659 rpcNCmd_fn = (void *)rpcNCmd_tab[fno];
661 return rpcNCmd_fn(fno, buf, size);
664 //-------------------------------------------------------------------------
665 void *rpcNCmd_cdread(u32 fno, void *buf, int size)
666 { // CD Read RPC NCMD
668 cdvd_readee(buf);
669 return buf;
672 //-------------------------------------------------------------------------
673 void *rpcNCmd_cdgettoc(u32 fno, void *buf, int size)
674 { // CD Get TOC RPC NCMD
676 *(int *)buf = 1;
677 return buf;
680 //-------------------------------------------------------------------------
681 void *rpcNCmd_cdseek(u32 fno, void *buf, int size)
682 { // CD Seek RPC NCMD
684 *(int *)buf = sceCdSeek(*(u32 *)buf);
685 return buf;
688 //-------------------------------------------------------------------------
689 void *rpcNCmd_cdstandby(u32 fno, void *buf, int size)
690 { // CD Standby RPC NCMD
692 *(int *)buf = sceCdStandby();
693 return buf;
696 //-------------------------------------------------------------------------
697 void *rpcNCmd_cdstop(u32 fno, void *buf, int size)
698 { // CD Stop RPC NCMD
700 *(int *)buf = sceCdStop();
701 return buf;
704 //-------------------------------------------------------------------------
705 void *rpcNCmd_cdpause(u32 fno, void *buf, int size)
706 { // CD Pause RPC NCMD
708 *(int *)buf = sceCdPause();
709 return buf;
712 //-------------------------------------------------------------------------
713 void *rpcNCmd_cdstream(u32 fno, void *buf, int size)
714 { // CD Stream RPC NCMD
716 cdvd_Stsubcmdcall(buf);
717 return buf;
720 //-------------------------------------------------------------------------
721 void *rpcNCmd_iopmread(u32 fno, void *buf, int size)
722 { // CD IOP Mem Read RPC NCMD
724 cdvd_iopmread(buf);
725 return buf;
728 //-------------------------------------------------------------------------
729 void *rpcNCmd_cddiskready(u32 fno, void *buf, int size)
730 { // CD Disk Ready RPC NCMD
732 *(int *)buf = sceCdDiskReady(0);
733 return buf;
736 //-------------------------------------------------------------------------
737 void *rpcNCmd_cdreadchain(u32 fno, void *buf, int size)
738 { // CD ReadChain RPC NCMD
740 cdvd_readchain(buf);
741 return buf;
744 //-------------------------------------------------------------------------
745 void *rpcNCmd_cdreadDiskID(u32 fno, void *buf, int size)
747 u8 *p = (u8 *)buf;
749 mips_memset(p, 0, 10);
750 *(int *)buf = sceCdReadDiskID(&p[4]);
752 return buf;
755 //-------------------------------------------------------------------------
756 void *rpcNCmd_cdgetdisktype(u32 fno, void *buf, int size)
758 u8 *p = (u8 *)buf;
759 *(int *)&p[4] = sceCdGetDiskType();
760 *(int *)&p[0] = 1;
762 return buf;
765 //-------------------------------------------------------------------------
766 void *rpcNCmd_dummy(u32 fno, void *buf, int size)
768 *(int *)buf = 0;
769 return buf;
772 //--------------------------------------------------------------
773 void *cbrpc_S596(u32 fno, void *buf, int size)
775 if (fno != 1)
776 return (void *)NULL;
778 if (*(u32 *)buf == fno)
779 return (void *)&cbrpcS596_oldfno;
781 cbrpcS596_oldfno = cbrpcS596_fno;
783 cbrpcS596_fno = fno;
785 return (void *)&cbrpcS596_oldfno;
788 //-------------------------------------------------------------------------
789 void *cbrpc_cdsearchfile(u32 fno, void *buf, int size)
790 { // CD Search File RPC callback
792 SifDmaTransfer_t dmat;
793 int r, oldstate;
794 void *ee_addr;
795 char *p;
796 SearchFilePkt_t *pkt = (SearchFilePkt_t *)buf;
797 SearchFilePkt2_t *pkt2 = (SearchFilePkt2_t *)buf;
798 SearchFilePktl_t *pktl = (SearchFilePktl_t *)buf;
799 int pktsize = 0;
801 if (size == sizeof(SearchFilePkt2_t)) {
802 ee_addr = (void *)pkt2->dest; // Search File: Called from Not Dual_layer Version
803 p = (void *)&pkt2->name[0];
804 pktsize = sizeof(cdl_file_t);
805 r = sceCdSearchFile((cd_file_t *)buf, p);
806 pkt2->cdfile.flag = 0;
808 else {
809 if (size > sizeof(SearchFilePkt2_t)) { // Search File: Called from Dual_layer Version
810 ee_addr = (void *)pktl->dest;
811 p = (char *)&pktl->name[0];
812 pktsize = sizeof(cdl_file_t);
813 r = sceCdLayerSearchFile((cdl_file_t *)buf, p, pktl->layer);
814 pktl->cdfile.flag = 0;
816 else { // Search File: Called from Old Library
817 ee_addr = (void *)pkt->dest;
818 p = (char *)&pkt->name[0];
819 pktsize = sizeof(cd_file_t);
820 r = sceCdSearchFile((cd_file_t *)buf, p);
824 dmat.dest = (void *)ee_addr;
825 dmat.size = pktsize;
826 dmat.src = (void *)buf;
827 dmat.attr = 0;
829 CpuSuspendIntr(&oldstate);
830 while (!sceSifSetDma(&dmat, 1));
831 CpuResumeIntr(oldstate);
832 //while (sceSifDmaStat >= 0);
834 *(int *)buf = r;
836 return buf;
839 //-------------------------------------------------------------------------
840 void cdvd_Stsubcmdcall(void *buf)
841 { // call a Stream Sub function (below) depending on stream cmd sent
843 RpcCdvdStream_t *St = (RpcCdvdStream_t *)buf;
845 if ((u32)(St->cmd >= 10)) {
846 cdvdSt_dummy(buf);
847 return;
850 cdvd_Stsubcall_fn = cdvdStsubcall_tab[St->cmd];
851 cdvd_Stsubcall_fn(buf);
854 //-------------------------------------------------------------------------
855 void cdvdSt_dummy(void *buf)
857 *(int *)buf = 0;
860 //-------------------------------------------------------------------------
861 void cdvdSt_start(void *buf)
863 RpcCdvdStream_t *St = (RpcCdvdStream_t *)buf;
865 *(int *)buf = sceCdStStart(St->lsn, &cdvdfsv_Stmode);
868 //--------------------------------------------------------------
869 void sysmemSendEE(void *buf, void *EE_addr, int size)
871 SifDmaTransfer_t dmat;
872 int oldstate, id;
874 size += 3;
875 size &= 0xfffffffc;
877 dmat.dest = (void *)EE_addr;
878 dmat.size = size;
879 dmat.src = (void *)buf;
880 dmat.attr = 0;
882 id = 0;
883 while (!id) {
884 CpuSuspendIntr(&oldstate);
885 id = sceSifSetDma(&dmat, 1);
886 CpuResumeIntr(oldstate);
889 while (sceSifDmaStat(id) >= 0);
892 //-------------------------------------------------------------------------
893 void cdvdSt_read(void *buf)
895 RpcCdvdStream_t *St = (RpcCdvdStream_t *)buf;
896 u32 nsectors, err;
897 int r;
898 int rpos = 0;
899 void *ee_addr = (void *)St->buf;
901 while (St->sectors > 0) {
902 if (St->sectors > CDVDFSV_BUF_SECTORS)
903 nsectors = CDVDFSV_BUF_SECTORS;
904 else
905 nsectors = St->sectors;
907 r = sceCdStRead(nsectors, cdvdfsv_buf, 0, &err);
909 sysmemSendEE(cdvdfsv_buf, ee_addr, nsectors << 11);
911 ee_addr += nsectors << 11;
912 rpos += r;
913 St->sectors -= r;
916 *(int *)buf = rpos;
919 //-------------------------------------------------------------------------
920 void cdvdSt_stop(void *buf)
922 *(int *)buf = sceCdStStop();
925 //-------------------------------------------------------------------------
926 void cdvdSt_seek(void *buf)
928 RpcCdvdStream_t *St = (RpcCdvdStream_t *)buf;
930 *(int *)buf = sceCdStSeek(St->lsn);
933 //-------------------------------------------------------------------------
934 void cdvdSt_init(void *buf)
936 RpcCdvdStInit_t *r = (RpcCdvdStInit_t *)buf;
938 *(int *)buf = sceCdStInit(r->bufmax, r->bankmax, r->buf);
941 //-------------------------------------------------------------------------
942 void cdvdSt_stat(void *buf)
944 *(int *)buf = sceCdStStat();
947 //-------------------------------------------------------------------------
948 void cdvdSt_pause(void *buf)
950 *(int *)buf = sceCdStPause();
953 //-------------------------------------------------------------------------
954 void cdvdSt_resume(void *buf)
956 *(int *)buf = sceCdStResume();
959 //-------------------------------------------------------------------------
960 void cdvdSt_seekF(void *buf)
962 RpcCdvdStream_t *St = (RpcCdvdStream_t *)buf;
964 *(int *)buf = sceCdStSeekF(St->lsn);
967 //-------------------------------------------------------------------------
968 void cdvd_iopmread(void *buf)
970 RpcCdvd_t *r = (RpcCdvd_t *)buf;
972 sceCdRead0(r->lsn, r->sectors, r->buf, NULL);
974 *(int *)buf = 1;
977 //-------------------------------------------------------------------------
978 void cdvd_readchain(void *buf)
980 int i;
981 u32 nsectors, tsectors, lsn, addr;
983 RpcCdvdchain_t *ch = (RpcCdvdchain_t *)buf;
985 for (i=0; i<64; i++) {
987 if ((ch->lsn == -1) || (ch->sectors == -1) || ((u32)ch->buf == -1))
988 break;
990 lsn = ch->lsn;
991 tsectors = ch->sectors;
992 addr = (u32)ch->buf & 0xfffffffc;
994 while (tsectors != 0) {
996 if (tsectors > CDVDFSV_BUF_SECTORS)
997 nsectors = CDVDFSV_BUF_SECTORS;
998 else
999 nsectors = tsectors;
1001 if ((u32)ch->buf & 1) { // IOP addr
1002 sceCdRead0(lsn, nsectors, (void *)addr, NULL);
1004 else { // EE addr
1005 sceCdRead0(lsn, nsectors, cdvdfsv_buf, NULL);
1006 sysmemSendEE(cdvdfsv_buf, (void *)addr, nsectors << 11);
1009 lsn += nsectors;
1010 tsectors -= nsectors;
1011 addr += nsectors << 11;
1013 ch++;
1016 *(int *)buf = 1;
1019 //--------------------------------------------------------------
1020 void cdvd_readee(void *buf)
1021 { // Read Disc datas to EE mem buffer
1022 u32 nbytes, nsectors, sectors_to_read, size_64b, size_64bb, bytesent, temp;
1023 int sector_size, flag_64b;
1024 void *fsvRbuf = (void *)cdvdfsv_buf;
1025 void *eeaddr_64b, *eeaddr2_64b;
1026 cdvdfsv_readee_t readee;
1027 RpcCdvd_t *r = (RpcCdvd_t *)buf;
1029 if (r->sectors == 0) {
1030 *(int *)buf = 0;
1031 return;
1034 sector_size = 2328;
1036 if ((r->mode.datapattern & 0xff) != 1) {
1037 sector_size = 2340;
1038 if ((r->mode.datapattern & 0xff) != 2)
1039 sector_size = 2048;
1042 r->eeaddr1 = (void *)((u32)r->eeaddr1 & 0x1fffffff);
1043 r->eeaddr2 = (void *)((u32)r->eeaddr2 & 0x1fffffff);
1044 r->buf = (void *)((u32)r->buf & 0x1fffffff);
1046 sceCdDiskReady(0);
1048 sectors_to_read = r->sectors;
1049 bytesent = 0;
1051 if (r->eeaddr2)
1052 mips_memset((void *)curlsn_buf, 0, 16);
1054 readee.pdst1 = (void *)r->buf;
1055 eeaddr_64b = (void *)(((u32)r->buf + 0x3f) & 0xffffffc0); // get the next 64-bytes aligned address
1057 if ((u32)r->buf & 0x3f)
1058 readee.b1len = (((u32)r->buf & 0xffffffc0) - (u32)r->buf) + 64; // get how many bytes needed to get a 64 bytes alignment
1059 else
1060 readee.b1len = 0;
1062 nbytes = r->sectors * sector_size;
1064 temp = (u32)r->buf + nbytes;
1065 eeaddr2_64b = (void *)(temp & 0xffffffc0);
1066 temp -= (u32)eeaddr2_64b;
1067 readee.pdst2 = eeaddr2_64b; // get the end address on a 64 bytes align
1068 readee.b2len = temp; // get bytes remainder at end of 64 bytes align
1069 fsvRbuf += temp;
1071 if (readee.b1len)
1072 flag_64b = 0; // 64 bytes alignment flag
1073 else {
1074 if (temp)
1075 flag_64b = 0;
1076 else
1077 flag_64b = 1;
1080 while (1) {
1081 do {
1082 if ((sectors_to_read == 0) || (sceCdGetError() == CDVD_ERR_ABRT)) {
1084 if (r->eeaddr1)
1085 sysmemSendEE((void *)&readee, (void *)r->eeaddr1, sizeof(cdvdfsv_readee_t));
1087 if (r->eeaddr2) {
1088 *((u32 *)&curlsn_buf[0]) = nbytes;
1089 sysmemSendEE((void *)curlsn_buf, (void *)r->eeaddr2, 16);
1092 *(int *)buf = 1;
1093 return;
1096 if (flag_64b == 0) { // not 64 bytes aligned buf
1097 if (sectors_to_read < CDVDFSV_BUF_SECTORS)
1098 nsectors = sectors_to_read;
1099 else
1100 nsectors = CDVDFSV_BUF_SECTORS-1;
1101 temp = nsectors + 1;
1103 else { // 64 bytes aligned buf
1104 if (sectors_to_read < (CDVDFSV_BUF_SECTORS+1))
1105 nsectors = sectors_to_read;
1106 else
1107 nsectors = CDVDFSV_BUF_SECTORS;
1108 temp = nsectors;
1111 sceCdRead0(r->lsn, temp, (void *)fsvRbuf, NULL);
1113 size_64b = nsectors * sector_size;
1114 size_64bb = size_64b;
1116 if (!flag_64b) {
1117 if (sectors_to_read == r->sectors) // check that was the first read
1118 mips_memcpy((void *)readee.buf1, (void *)fsvRbuf, readee.b1len);
1120 if ((!flag_64b) && (sectors_to_read == nsectors) && (readee.b1len))
1121 size_64bb = size_64b - 64;
1124 if (size_64bb > 0) {
1125 sysmemSendEE((void *)(fsvRbuf + readee.b1len), (void *)eeaddr_64b, size_64bb);
1126 bytesent += size_64bb;
1129 if (r->eeaddr2) {
1130 temp = bytesent;
1131 if (temp < 0)
1132 temp += 2047;
1133 temp = temp >> 11;
1134 *((u32 *)&curlsn_buf[0]) = temp;
1135 sysmemSendEE((void *)curlsn_buf, (void *)r->eeaddr2, 16);
1138 sectors_to_read -= nsectors;
1139 r->lsn += nsectors;
1140 eeaddr_64b += size_64b;
1142 } while ((flag_64b) || (sectors_to_read));
1144 mips_memcpy((void *)readee.buf2, (void *)(fsvRbuf + size_64b - readee.b2len), readee.b2len);
1147 *(int *)buf = 0;
1150 //-------------------------------------------------------------------------
1151 int sceCdChangeThreadPriority(int priority)
1153 iop_thread_info_t th_info;
1155 if ((u32)(priority - 9) < 0x73) {
1156 if (priority == 9)
1157 priority = 10;
1159 ReferThreadStatus(0, &th_info);
1161 ChangeThreadPriority(0, 0x08);
1162 ChangeThreadPriority(init_thread_id, priority-1);
1163 ChangeThreadPriority(rpc0_thread_id, priority);
1164 ChangeThreadPriority(rpc2_thread_id, priority);
1165 ChangeThreadPriority(rpc1_thread_id, priority);
1167 return 0;
1170 return -403;
1173 //-------------------------------------------------------------------------
1174 DECLARE_IMPORT_TABLE(cdvdman, 1, 1)
1175 DECLARE_IMPORT(4, sceCdInit)
1176 DECLARE_IMPORT(5, sceCdStandby)
1177 DECLARE_IMPORT(6, sceCdRead)
1178 DECLARE_IMPORT(7, sceCdSeek)
1179 DECLARE_IMPORT(8, sceCdGetError)
1180 DECLARE_IMPORT(10, sceCdSearchFile)
1181 DECLARE_IMPORT(11, sceCdSync)
1182 DECLARE_IMPORT(12, sceCdGetDiskType)
1183 DECLARE_IMPORT(13, sceCdDiskReady)
1184 DECLARE_IMPORT(14, sceCdTrayReq)
1185 DECLARE_IMPORT(15, sceCdStop)
1186 DECLARE_IMPORT(24, sceCdReadClock)
1187 DECLARE_IMPORT(28, sceCdStatus)
1188 DECLARE_IMPORT(29, sceCdApplySCmd)
1189 DECLARE_IMPORT(38, sceCdPause)
1190 DECLARE_IMPORT(39, sceCdBreak)
1191 DECLARE_IMPORT(56, sceCdStInit)
1192 DECLARE_IMPORT(57, sceCdStRead)
1193 DECLARE_IMPORT(58, sceCdStSeek)
1194 DECLARE_IMPORT(59, sceCdStStart)
1195 DECLARE_IMPORT(60, sceCdStStat)
1196 DECLARE_IMPORT(61, sceCdStStop)
1197 DECLARE_IMPORT(62, sceCdRead0)
1198 DECLARE_IMPORT(67, sceCdStPause)
1199 DECLARE_IMPORT(68, sceCdStResume)
1200 DECLARE_IMPORT(75, sceCdMmode)
1201 DECLARE_IMPORT(77, sceCdStSeekF)
1202 DECLARE_IMPORT(79, sceCdReadDiskID)
1203 DECLARE_IMPORT(80, sceCdReadGUID)
1204 DECLARE_IMPORT(81, sceCdSetTimeout)
1205 DECLARE_IMPORT(82, sceCdReadModelID)
1206 DECLARE_IMPORT(83, sceCdReadDvdDualInfo)
1207 DECLARE_IMPORT(84, sceCdLayerSearchFile)
1208 END_IMPORT_TABLE