PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
cde.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "accdvde_internal.h"
12
13static int cde_op_ready(void *arg);
14static int cde_op_type(void *arg);
15static int cde_op_error(void *arg);
16static int cde_op_getpos(void *arg);
17static int cde_op_init(void *arg);
18static int cde_op_pause(void *arg);
19static int cde_op_read(void *arg);
20static int cde_op_readtoc(void *arg);
21static int cde_op_readi(void *arg);
22static int cde_op_sync(void *arg);
23static int cde_op_lookup(void *arg);
24static int cde_op_seek(void *arg);
25static int cde_op_standby(void *arg);
26static int cde_op_stat(void *arg);
27static int cde_op_stop(void *arg);
28static int cde_op_tray(void *arg);
29static int cde_op_inits(void *arg);
30static int cde_op_reads(void *arg);
31static int cde_op_seeks(void *arg);
32static int cde_op_starts(void *arg);
33static int cde_op_stats(void *arg);
34static int cde_op_stops(void *arg);
35static int cde_op_pauses(void *arg);
36static int cde_op_resumes(void *arg);
37static int cde_op_readrtc(void *arg);
38
39static cde_ops_t Cde_ops[27] = {
40 NULL,
41 NULL,
42 &cde_op_ready,
43 &cde_op_type,
44 &cde_op_error,
45 &cde_op_getpos,
46 &cde_op_readtoc,
47 &cde_op_init,
48 &cde_op_pause,
49 &cde_op_read,
50 &cde_op_readi,
51 &cde_op_sync,
52 &cde_op_lookup,
53 &cde_op_seek,
54 &cde_op_standby,
55 &cde_op_stat,
56 &cde_op_stop,
57 &cde_op_tray,
58 &cde_op_inits,
59 &cde_op_reads,
60 &cde_op_seeks,
61 &cde_op_starts,
62 &cde_op_stats,
63 &cde_op_stops,
64 &cde_op_pauses,
65 &cde_op_resumes,
66 &cde_op_readrtc};
67static struct cde_softc Cdec;
68
69static int cde_op_ready(void *arg)
70{
71 const struct ac_cdvdsif_ready *argt;
72 struct ac_cdvdsif_reply *argr;
73
74 argt = (struct ac_cdvdsif_ready *)arg;
75 argr = (struct ac_cdvdsif_reply *)arg;
76 argr->result = cdc_ready(argt->mode);
77 return 1;
78}
79
80static int cde_op_type(void *arg)
81{
82 struct ac_cdvdsif_reply *argr;
83
84 argr = (struct ac_cdvdsif_reply *)arg;
85 argr->result = cdc_medium();
86 return 1;
87}
88
89static int cde_op_error(void *arg)
90{
91 struct ac_cdvdsif_reply *argr;
92
93 argr = (struct ac_cdvdsif_reply *)arg;
94 argr->result = cdc_error();
95 return 1;
96}
97
98static int cde_op_getpos(void *arg)
99{
100 struct ac_cdvdsif_reply *argr;
101
102 argr = (struct ac_cdvdsif_reply *)arg;
103 argr->result = cdc_getpos();
104 return 0;
105}
106
107static int cde_op_init(void *arg)
108{
109 int mode;
110 int ret;
111 const struct ac_cdvdsif_init *argt;
112 struct ac_cdvdsif_reply *argr;
113
114 argt = (struct ac_cdvdsif_init *)arg;
115 argr = (struct ac_cdvdsif_reply *)arg;
116 mode = argt->mode;
117 if ( mode < 0 )
118 {
119 ret = 0;
120 }
121 else if ( mode < 2 )
122 {
123 int ret_v2;
124
125 if ( cdc_module_status() > 0 )
126 cdc_module_stop();
127 ret_v2 = cdc_module_start(0, 0);
128 if ( ret_v2 >= 0 )
129 {
130 ret = 1;
131 if ( !mode )
132 {
133 cdc_ready(0);
134 ret = 1;
135 }
136 }
137 else
138 {
139 printf("cde:init: START error %d\n", ret_v2);
140 ret = 0;
141 }
142 }
143 else
144 {
145 ret = mode == 5 && cdc_module_stop() >= 0;
146 }
147 argr->result = ret;
148 return ret;
149}
150
151static int cde_op_pause(void *arg)
152{
153 int result;
154 struct ac_cdvdsif_reply *argr;
155
156 argr = (struct ac_cdvdsif_reply *)arg;
157 result = cdc_pause(0);
158 argr->result = result;
159 return result;
160}
161
162static int cde_read_xfer(void *dst, void *src, int len, enum cdc_xfer_dir dir)
163{
164 if ( dir == CDC_XFER_SYNC )
165 return len;
166 if ( acMemWait(&Cdec.rd_mem, 100, 120) < 0 )
167 return -116;
168 acMemSetup(&Cdec.rd_mem, src, len);
169 return acMemSend(&Cdec.rd_mem, (acMemEEaddr)dst, len, 10);
170}
171
172static int cde_op_read(void *arg)
173{
174 int result;
175 struct ac_cdvdsif_read *argt;
176 struct ac_cdvdsif_reply *argr;
177
178 argt = (struct ac_cdvdsif_read *)arg;
179 argr = (struct ac_cdvdsif_reply *)arg;
180 acMemSetup(&Cdec.rd_mem, 0, 0);
181 result = cdc_read(argt->lsn, argt->buf, argt->sectors, &argt->rmode, (cdc_xfer_t)cde_read_xfer, 0);
182 argr->result = result;
183 return result;
184}
185
186static int cde_op_readtoc(void *arg)
187{
188 int result;
189 struct ac_cdvdsif_readtoc *argt;
190 struct ac_cdvdsif_reply *argr;
191
192 argt = (struct ac_cdvdsif_readtoc *)arg;
193 argr = (struct ac_cdvdsif_reply *)arg;
194 acMemSetup(&Cdec.rd_mem, 0, 0);
195 result = cdc_readtoc(argt->toc, (cdc_xfer_t)cde_read_xfer);
196 argr->result = result;
197 return result;
198}
199
200static void cde_read_acram_cb(acRamT ram, void *arg, int result)
201{
202 int thid;
203
204 (void)ram;
205 (void)result;
206 thid = *(int *)arg;
207 *(int *)arg = 0;
208 // cppcheck-suppress knownConditionTrueFalse
209 if ( thid )
210 WakeupThread(thid);
211}
212
213static int cde_read_acram(void *dst, void *src, int len, enum cdc_xfer_dir dir)
214{
215 acRamData *v7;
216 int ret;
217 acRamData ram_data;
218 int thid;
219
220 (void)dir;
221 thid = GetThreadId();
222 v7 = acRamSetup(&ram_data, cde_read_acram_cb, &thid, 0);
223 ret = acRamWrite(v7, (acRamAddr)dst, src, len);
224 if ( ret < 0 )
225 {
226 return ret;
227 }
228 while ( thid )
229 {
230 SleepThread();
231 }
232 return ret;
233}
234
235static int cde_op_readi(void *arg)
236{
237 unsigned int v2;
238 int result;
239 struct ac_cdvdsif_read *argt;
240 struct ac_cdvdsif_reply *argr;
241 int flg;
242
243 argt = (struct ac_cdvdsif_read *)arg;
244 argr = (struct ac_cdvdsif_reply *)arg;
245 flg = 0;
246 v2 = (unsigned int)argt->buf;
247 if ( (v2 & 0xF0000001) == 0x40000000 )
248 {
249 v2 &= 0xFFFFFFEu;
250 flg = 1;
251 }
252 result = cdc_read(argt->lsn, (void *)v2, argt->sectors, &argt->rmode, flg ? cde_read_acram : 0, 0);
253 argr->result = result;
254 return result;
255}
256
257static int cde_op_sync(void *arg)
258{
259 int mode;
260 int v3;
261 const struct ac_cdvdsif_sync *argt;
262 struct ac_cdvdsif_sync_rpl *argr;
263
264 argt = (struct ac_cdvdsif_sync *)arg;
265 argr = (struct ac_cdvdsif_sync_rpl *)arg;
266 mode = argt->mode;
267 argr->fno = cdc_getfno();
268 v3 = cdc_sync(mode);
269 argr->result = v3;
270 if ( mode < 0 && v3 )
271 argr->rpos = cdc_getpos();
272 else
273 argr->rpos = 0;
274 return 0;
275}
276
277static int cde_lookup_xfer(void *dst, void *src, int len, enum cdc_xfer_dir dir)
278{
279 int v5;
280 acMemData mem_data;
281
282 v5 = len;
283 if ( !dir )
284 {
285 return v5;
286 }
287 acMemSetup(&mem_data, dst, len);
288 return acMemReceive(&mem_data, (acMemEEaddr)src, v5);
289}
290
291static int cde_op_lookup(void *arg)
292{
293 int result;
294 const struct ac_cdvdsif_lookup *argt;
295 struct ac_cdvdsif_lookup_rpl *argr;
296
297 argt = (struct ac_cdvdsif_lookup *)arg;
298 argr = (struct ac_cdvdsif_lookup_rpl *)arg;
299 result = cdc_lookup(&argr->file, (char *)argt->name, argt->namlen, (cdc_xfer_t)cde_lookup_xfer);
300 argr->result = result;
301 return result;
302}
303
304static int cde_op_seek(void *arg)
305{
306 int result;
307 const struct ac_cdvdsif_seek *argt;
308 struct ac_cdvdsif_reply *argr;
309
310 argt = (struct ac_cdvdsif_seek *)arg;
311 argr = (struct ac_cdvdsif_reply *)arg;
312 result = cdc_seek(argt->lsn, 0);
313 argr->result = result;
314 return result;
315}
316
317static int cde_op_standby(void *arg)
318{
319 int result;
320 struct ac_cdvdsif_reply *argr;
321
322 argr = (struct ac_cdvdsif_reply *)arg;
323 result = cdc_standby(0);
324 argr->result = result;
325 return result;
326}
327
328static int cde_op_stat(void *arg)
329{
330 struct ac_cdvdsif_reply *argr;
331
332 argr = (struct ac_cdvdsif_reply *)arg;
333 argr->result = cdc_stat();
334 return 1;
335}
336
337static int cde_op_stop(void *arg)
338{
339 int result;
340 struct ac_cdvdsif_reply *argr;
341
342 argr = (struct ac_cdvdsif_reply *)arg;
343 result = cdc_stop(0);
344 argr->result = result;
345 return result;
346}
347
348static int cde_op_tray(void *arg)
349{
350 int result;
351 const struct ac_cdvdsif_tray *argt;
352 struct ac_cdvdsif_tray_rpl *argr;
353
354 argt = (struct ac_cdvdsif_tray *)arg;
355 argr = (struct ac_cdvdsif_tray_rpl *)arg;
356 result = cdc_tray(argt->mode, &argr->status);
357 argr->result = result;
358 return result;
359}
360
361static int cde_op_inits(void *arg)
362{
363 int result;
364 struct ac_cdvdsif_inits *argt;
365 struct ac_cdvdsif_reply *argr;
366
367 argt = (struct ac_cdvdsif_inits *)arg;
368 argr = (struct ac_cdvdsif_reply *)arg;
369 result = cdc_inits(argt->buf, argt->size, argt->bsize);
370 argr->result = result;
371 return result;
372}
373
374static int cde_reads_xfer(void *dst, void *src, int len, enum cdc_xfer_dir dir)
375{
376 int index;
377 acMemT mem;
378 int index_v2;
379
380 if ( !dir )
381 {
382 int index_v3;
383
384 index_v3 = Cdec.st_index - 1;
385 if ( Cdec.st_index - 1 < 0 )
386 index_v3 = 1;
387 if ( acMemWait(&Cdec.st_mem[index_v3], 100, 120) < 0 )
388 return -116;
389 return 9;
390 }
391 index = Cdec.st_index;
392 mem = &Cdec.st_mem[Cdec.st_index];
393 if ( acMemWait(mem, 100, 120) < 0 )
394 return -116;
395 acMemSetup(mem, src, len);
396 index_v2 = index + 1;
397 if ( acMemSend(mem, (acMemEEaddr)dst, len, 10) < 0 )
398 {
399 return -116;
400 }
401 if ( (unsigned int)index_v2 >= 2 )
402 index_v2 = 0;
403 Cdec.st_index = index_v2;
404 return len;
405}
406
407static int cde_op_reads(void *arg)
408{
409 int result;
410 struct ac_cdvdsif_reads *argt;
411 struct ac_cdvdsif_reads_rpl *argr;
412
413 argt = (struct ac_cdvdsif_reads *)arg;
414 argr = (struct ac_cdvdsif_reads_rpl *)arg;
415 result = cdc_reads(argt->buf, argt->sectors, argt->mode, (int *)&argr->error, (cdc_xfer_t)cde_reads_xfer);
416 argr->result = result;
417 return result;
418}
419
420static int cde_op_seeks(void *arg)
421{
422 int result;
423 const struct ac_cdvdsif_seeks *argt;
424 struct ac_cdvdsif_reply *argr;
425
426 argt = (struct ac_cdvdsif_seeks *)arg;
427 argr = (struct ac_cdvdsif_reply *)arg;
428 result = cdc_seeks(argt->lsn);
429 argr->result = result;
430 return result;
431}
432
433static int cde_op_starts(void *arg)
434{
435 int result;
436 struct ac_cdvdsif_starts *argt;
437 struct ac_cdvdsif_reply *argr;
438
439 argt = (struct ac_cdvdsif_starts *)arg;
440 argr = (struct ac_cdvdsif_reply *)arg;
441 result = cdc_starts(argt->lsn, &argt->rmode);
442 argr->result = result;
443 return result;
444}
445
446static int cde_op_stats(void *arg)
447{
448 int result;
449 struct ac_cdvdsif_reply *argr;
450
451 argr = (struct ac_cdvdsif_reply *)arg;
452 result = cdc_stats();
453 argr->result = result;
454 return result;
455}
456
457static int cde_op_stops(void *arg)
458{
459 int result;
460 struct ac_cdvdsif_reply *argr;
461
462 argr = (struct ac_cdvdsif_reply *)arg;
463 result = cdc_stops();
464 argr->result = result;
465 return result;
466}
467
468static int cde_op_pauses(void *arg)
469{
470 int result;
471 struct ac_cdvdsif_reply *argr;
472
473 argr = (struct ac_cdvdsif_reply *)arg;
474 result = cdc_pauses();
475 argr->result = result;
476 return result;
477}
478
479static int cde_op_resumes(void *arg)
480{
481 int result;
482 struct ac_cdvdsif_reply *argr;
483
484 argr = (struct ac_cdvdsif_reply *)arg;
485 result = cdc_resumes();
486 argr->result = result;
487 return result;
488}
489
490static int cde_op_readrtc(void *arg)
491{
492 int result;
493 struct ac_cdvdsif_readrtc_rpl *argr;
494
495 argr = (struct ac_cdvdsif_readrtc_rpl *)arg;
496 result = sceCdReadClock(&argr->rtc);
497 argr->result = result;
498 return result;
499}
500
501static void *cde_request(unsigned int fno, struct cde_softc *data, int size)
502{
503 struct ac_cdvdsif_reply *rpl;
504 cde_ops_t func;
505 int ret;
506 int v11;
507 acSpl state;
508
509 rpl = (struct ac_cdvdsif_reply *)data->rpl;
510 if ( size != 16 )
511 {
512 rpl->error = 33;
513 rpl->result = -1;
514 return rpl;
515 }
516 if ( fno >= (sizeof(Cde_ops) / sizeof(Cde_ops[0])) || (func = Cde_ops[fno]) == 0 )
517 {
518 rpl->error = 16;
519 rpl->result = -1;
520 return rpl;
521 }
522 CpuSuspendIntr(&state);
523 if ( data->fno )
524 {
525 ret = 1;
526 }
527 else
528 {
529 data->fno = fno;
530 ret = 0;
531 }
532 CpuResumeIntr(state);
533 if ( ret )
534 {
535 rpl->error = 19;
536 rpl->result = -1;
537 return rpl;
538 }
539 rpl->error = *(acUint32 *)data->cal;
540 rpl->result = *(acUint32 *)&data->cal[4];
541 rpl->padding[0] = *(acUint32 *)&data->cal[8];
542 rpl->padding[1] = *(acUint32 *)&data->cal[12];
543 v11 = func(rpl);
544 if ( v11 >= 0 )
545 {
546 if ( v11 )
547 rpl->error = 0;
548 else
549 rpl->error = cdc_error();
550 }
551 data->fno = AC_CDVDSIF_ID_NOP;
552 return rpl;
553}
554
555static void cde_thread(void *arg)
556{
557 int thid;
558 SifRpcDataQueue_t queue_data;
559 SifRpcServerData_t serv_data;
560 struct cde_softc *argt;
561
562 argt = (struct cde_softc *)arg;
563 thid = GetThreadId();
564 sceSifSetRpcQueue(&queue_data, thid);
565 sceSifRegisterRpc(&serv_data, 0x76500002, (SifRpcFunc_t)cde_request, argt, 0, 0, &queue_data);
566 argt->thid = thid;
567 while ( 1 )
568 {
570
571 s = sceSifGetNextRequest(&queue_data);
572 if ( s )
573 {
574 sceSifExecRequest(s);
575 }
576 else
577 {
578 SleepThread();
579 if ( thid != argt->thid )
580 ExitThread();
581 }
582 }
583}
584
585static void cde_term_thread(struct cde_softc *cdec)
586{
587 int thid;
588
589 thid = cdec->thid;
590 if ( thid > 0 )
591 {
592 int retry;
593 int ret;
594
595 cdec->thid = 0;
596 WakeupThread(thid);
597 DelayThread(1000);
598 for ( retry = 9; retry >= 0; --retry )
599 {
600 ret = DeleteThread(thid);
601 if ( !ret )
602 break;
603 DelayThread(1000000);
604 }
605 if ( retry < 0 )
606 printf("accdvde:term_thread: TIMEDOUT %d\n", ret);
607 }
608}
609
610static int cde_init_thread(struct cde_softc *cdec, int prio)
611{
612 int th;
613 iop_thread_t param;
614
615 param.attr = 0x2000000;
616 param.thread = cde_thread;
617 param.priority = prio;
618 param.stacksize = 4096;
619 param.option = 0;
620 th = CreateThread(&param);
621 if ( th > 0 )
622 StartThread(th, cdec);
623 return th;
624}
625
626int acCdvdeModuleStatus()
627{
628 int ret;
629 int state;
630
631 CpuSuspendIntr(&state);
632 if ( Cdec.fno )
633 ret = 2;
634 else
635 ret = Cdec.thid != 0;
636 CpuResumeIntr(state);
637 return ret;
638}
639
640int acCdvdeModuleStart(int argc, char **argv)
641{
642 int index;
643 int prio;
644 char **v8;
645 char *opt;
646 int v10;
647 const char *opt_v7;
648 int value;
649 int inited;
650 char *next;
651
652 if ( acCdvdeModuleStatus() != 0 )
653 {
654 return -16;
655 }
656 index = 1;
657 prio = 80;
658 v8 = argv + 1;
659 while ( index < argc )
660 {
661 opt = *v8;
662 if ( **v8 == 45 )
663 {
664 v10 = opt[1];
665 opt_v7 = opt + 2;
666 if ( v10 == 112 )
667 {
668 value = strtol(opt_v7, &next, 0);
669 if ( next != opt_v7 )
670 prio = value;
671 }
672 }
673 ++index;
674 ++v8;
675 }
676 memset(&Cdec, 0, sizeof(Cdec));
677 inited = cde_init_thread(&Cdec, prio);
678 if ( inited <= 0 )
679 return -6;
680 return 0;
681}
682
683int acCdvdeModuleStop()
684{
685 if ( acCdvdeModuleStatus() != 0 )
686 {
687 cde_term_thread(&Cdec);
688 }
689 return 0;
690}
691
692int acCdvdeModuleRestart(int argc, char **argv)
693{
694 (void)argc;
695 (void)argv;
696
697 return -88;
698}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
int sceCdReadClock(sceCdCLOCK *clock)
Definition cdvdman.c:5821
Definition acmem.h:17
Definition acram.h:23