PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
cdc.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 "accdvd_internal.h"
12
13static struct cdc_module mods_120[3] = {
14 {&acAtaModuleStart, &acAtaModuleStop, &acAtaModuleStatus},
15 {&acd_module_start, &acd_module_stop, &acd_module_status},
16 {&cdfs_module_start, &cdfs_module_stop, &cdfs_module_status}};
17static struct cdc_softc Cdcc;
18
19static int cdc_errno_set(struct cdc_softc *cdcc, int ret)
20{
21 if ( ret )
22 {
23 if ( ret >= 256 )
24 {
25 if ( ret >> 16 == 6 )
26 {
27 cdfs_umount();
28 ret = 49;
29 }
30 else
31 {
32 int asc;
33
34 asc = ret & 0xFFFF;
35 ret = 48;
36 if ( asc == 8448 )
37 ret = 50;
38 }
39 }
40 else
41 {
42 switch ( ret )
43 {
44 case 14:
45 ret = 32;
46 break;
47 case 16:
48 ret = 19;
49 break;
50 case 22:
51 ret = 33;
52 break;
53 case 34:
54 ret = 50;
55 break;
56 default:
57 ret = 48;
58 break;
59 }
60 }
61 }
62 cdcc->error = ret;
63 return ret;
64}
65
66static int cdc_eve_alloc()
67{
68 int ret;
69 iop_event_t param;
70
71 param.attr = 2;
72 param.bits = 0;
73 param.option = 0;
74 ret = CreateEventFlag(&param);
75 if ( ret <= 0 )
76 {
77 printf("accdvd:cdc:eve_alloc: error %d\n", ret);
78 }
79 return ret;
80}
81
82static int cdc_sem_alloc()
83{
84 int ret;
85 iop_sema_t param;
86
87 param.attr = 0;
88 param.initial = 1;
89 param.max = 1;
90 param.option = 0;
91 ret = CreateSema(&param);
92 if ( ret <= 0 )
93 {
94 printf("accdvd:cdc:sem_alloc: error %d\n", ret);
95 }
96 return ret;
97}
98
99static int cdc_unlock(struct cdc_softc *cdcc, int ret, acCdvdsifId fno)
100{
101 int lockid;
102 unsigned int v8;
103
104 lockid = cdcc->lockid;
105 if ( fno )
106 {
107 int v6;
108 int eveid;
109
110 v6 = 0;
111 if ( ret < 0 )
112 v6 = -ret;
113 cdc_errno_set(cdcc, v6);
114 eveid = cdcc->syncid;
115 cdcc->stat = 0;
116 cdcc->fno = AC_CDVDSIF_ID_NOP;
117 if ( eveid > 0 )
118 SetEventFlag(eveid, 3u);
119 }
120 if ( lockid > 0 )
121 {
122 SignalSema(lockid);
123 }
124 v8 = ~ret;
125 return v8 >> 31;
126}
127
128int cdc_getfno()
129{
130 return Cdcc.fno;
131}
132
133int cdc_geterrno()
134{
135 return Cdcc.error;
136}
137
138int cdc_seterrno(int ret)
139{
140 Cdcc.error = ret;
141 return 0;
142}
143
144static void cdc_done(struct acd *acd, struct cdc_softc *arg, int ret)
145{
146 int v3;
147 cdc_done_t done;
148 int eveid;
149
150 (void)acd;
151 v3 = 0;
152 if ( ret < 0 )
153 v3 = -ret;
154 cdc_errno_set(arg, v3);
155 done = arg->done;
156 arg->done = 0;
157 if ( done )
158 {
159 int type;
160
161 switch ( arg->fno )
162 {
163 case AC_CDVDSIF_ID_PAUSE:
164 type = 7;
165 break;
166 case AC_CDVDSIF_ID_READ:
167 type = 1;
168 break;
169 case AC_CDVDSIF_ID_SEEK:
170 type = 4;
171 break;
172 case AC_CDVDSIF_ID_STANDBY:
173 type = 5;
174 break;
175 case AC_CDVDSIF_ID_STOP:
176 type = 6;
177 break;
178 default:
179 type = 0;
180 break;
181 }
182 done(type);
183 }
184 eveid = arg->syncid;
185 arg->stat = 0;
186 arg->fno = AC_CDVDSIF_ID_NOP;
187 if ( eveid > 0 )
188 SetEventFlag(eveid, 3u);
189}
190
191int cdc_sync(int nonblocking)
192{
193 u32 bits;
194
195 if ( !Cdcc.fno )
196 {
197 return 0;
198 }
199 if ( nonblocking > 0 )
200 {
201 return 1;
202 }
203 bits = 1;
204 if ( nonblocking < 0 )
205 bits = 3;
206 if ( Cdcc.syncid > 0 )
207 WaitEventFlag(Cdcc.syncid, bits, 1, &bits);
208 return ((bits & 0xFF) ^ 1) & 1;
209}
210
211int cdc_ready(int nonblocking)
212{
213 struct acd *acd;
214 int ret;
215 int v4;
216 int asc;
217 struct acd acd_data;
218 struct acd acd_data_v8;
219
220 acd = acd_setup(&acd_data, 0, 0, 5000000);
221 Cdcc.error = 0;
222 ret = -1;
223 while ( ret < 0 )
224 {
225 int delay;
226
227 ret = acd_ready(acd);
228 delay = -1;
229 if ( ret >= 0 )
230 {
231 v4 = acd_readcapacity();
232 if ( v4 < 0 )
233 v4 = 0;
234 Cdcc.cdsize = v4;
235 ret = 2;
236 }
237 else if ( ret < -255 )
238 {
239 asc = (acUint16) - (ret & 0xFFFF);
240 if ( -ret >> 16 != 6 )
241 {
242 if ( asc != 0x401 )
243 {
244 if ( asc == 0x3A00 )
245 {
246 Cdcc.cdsize = 0;
247 ret = 2;
248 }
249 }
250 else
251 {
252 delay = 1000000;
253 }
254 }
255 else
256 {
257 delay = 0;
258 if ( asc == 10496 )
259 delay = acd_delay();
260 }
261 }
262 else
263 {
264 if ( ret == -116 )
265 {
266 delay = 1000000;
267 }
268 else
269 {
270 ret = 6;
271 }
272 }
273 if ( nonblocking )
274 break;
275 if ( delay > 0 )
276 DelayThread(delay);
277 }
278 if ( ret == 2 )
279 {
280 acd_getmedium(acd_setup(&acd_data_v8, 0, 0, 5000000));
281 Cdcc.tray = acd_gettray();
282 }
283 return ret;
284}
285
286int cdc_medium()
287{
288 struct acd *v0;
289 int v1;
290 int ret;
291 int v3;
292 struct acd acd_data;
293
294 v0 = acd_setup(&acd_data, 0, 0, 5000000);
295 v1 = acd_getmedium(v0);
296 ret = v1;
297 v3 = 0;
298 if ( v1 < 0 )
299 v3 = -v1;
300 cdc_errno_set(&Cdcc, v3);
301 switch ( ret )
302 {
303 case 1:
304 case 5:
305 case 33:
306 case 37:
307 return 18;
308 case 2:
309 case 6:
310 case 34:
311 case 38:
312 return 253;
313 case 3:
314 case 7:
315 case 35:
316 case 39:
317 return 19;
318 case 65:
319 case 69:
320 return 20;
321 case 112:
322 case 113:
323 return 0;
324 default:
325 return 255;
326 }
327}
328
329int cdc_error()
330{
331 return Cdcc.error;
332}
333
334int cdc_stat()
335{
336 int ret;
337 int v2;
338 struct acd acd_data;
339
340 ret = acd_getmedium(0);
341 acd_setup(&acd_data, 0, 0, 5000000);
342 if ( ret == -61 )
343 ret = acd_getmedium(&acd_data);
344 if ( ret == 113 )
345 {
346 return 1;
347 }
348 if ( Cdcc.stat )
349 {
350 return Cdcc.stat;
351 }
352 v2 = acd_getstatus();
353 if ( v2 < 0 )
354 return 32;
355 return (v2 != 0) ? 2 : 0;
356}
357
358int cdc_readtoc(unsigned char *toc, cdc_xfer_t xfer)
359{
360 acInt32 ret;
361 int v7;
362 int ret_v3;
363
364 if ( Cdcc.lockid )
365 {
366 ret = 0;
367 if ( WaitSema(Cdcc.lockid) )
368 ret = 19;
369 }
370 else
371 {
372 ret = 17;
373 }
374 if ( ret )
375 {
376 Cdcc.error = ret;
377 return 0;
378 }
379 v7 = -16;
380 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
381 {
382 v7 = 6;
383 Cdcc.fno = AC_CDVDSIF_ID_READTOC;
384 Cdcc.stat = 6;
385 if ( Cdcc.syncid > 0 )
386 ClearEventFlag(Cdcc.syncid, 0);
387 }
388 ret_v3 = v7;
389 if ( v7 > 0 )
390 {
391 ret_v3 = acd_readtoc(acd_setup(&Cdcc.acd, 0, 0, 5000000), Cdcc.buf, 1024);
392 if ( ret_v3 > 0 )
393 {
394 if ( ret_v3 < 1024 )
395 memset(&Cdcc.buf[ret_v3], 0, 1024 - ret_v3);
396 ret_v3 = xfer(toc, Cdcc.buf, 1024, CDC_XFER_OUT);
397 }
398 }
399 return cdc_unlock(&Cdcc, ret_v3, AC_CDVDSIF_ID_READTOC);
400}
401
402int cdc_lookup(sceCdlFILE *fp, const char *name, int namlen, cdc_xfer_t xfer)
403{
404 acInt32 ret;
405 int ret_v2;
406 int ret_v3;
407 struct cdfs_dirent dirent;
408
409 if ( Cdcc.lockid )
410 {
411 ret = 0;
412 if ( WaitSema(Cdcc.lockid) )
413 ret = 19;
414 }
415 else
416 {
417 ret = 17;
418 }
419 if ( ret )
420 {
421 Cdcc.error = ret;
422 return 0;
423 }
424 ret_v2 = -16;
425 if ( Cdcc.fno )
426 {
427 ret_v3 = ret_v2;
428 }
429 else
430 {
431 ret_v2 = 12;
432 ret_v3 = 12;
433 Cdcc.fno = AC_CDVDSIF_ID_LOOKUP;
434 Cdcc.stat = 0;
435 if ( Cdcc.syncid > 0 )
436 {
437 ClearEventFlag(Cdcc.syncid, 0);
438 ret_v3 = ret_v2;
439 }
440 }
441 if ( ret_v3 > 0 )
442 {
443 ret_v3 = 0;
444 if ( xfer )
445 {
446 ret_v3 = xfer(
447 Cdcc.buf,
448 (void *)((uiptr)name - ((uiptr)name & 0xF)),
449 (((uiptr)name & 0xF) + namlen + 0xF) & 0xFFFFFFF0,
450 CDC_XFER_IN);
451 name = (char *)&Cdcc.buf[(uiptr)name & 0xF];
452 }
453 while ( ret_v3 > 0 )
454 {
455 int ret_v4;
456
457 ret_v4 = cdfs_lookup(&dirent, name, namlen);
458 if ( ret_v4 >= 0 )
459 {
460 int d_namlen;
461
462 *(acUint32 *)fp->date = *(acUint32 *)&dirent.d_time.t_padding;
463 *(acUint32 *)&fp->date[4] = *(acUint32 *)&dirent.d_time.t_day;
464 d_namlen = dirent.d_namlen;
465 fp->lsn = dirent.d_lsn;
466 fp->size = dirent.d_size;
467 fp->name[d_namlen] = 59;
468 fp->name[d_namlen + 1] = (dirent.d_vol & 0xFF) + 48;
469 fp->name[d_namlen + 2] = 0;
470 memcpy(fp->name, dirent.d_name, d_namlen);
471 ret_v3 = 0;
472 }
473 else
474 {
475 ret_v3 = cdfs_recover(ret_v4);
476 }
477 }
478 }
479 return cdc_unlock(&Cdcc, ret_v3, AC_CDVDSIF_ID_LOOKUP);
480}
481
482int cdc_seek(unsigned int lsn, cdc_done_t done)
483{
484 acCdvdsifId fno;
485 acInt32 v5;
486 int v8;
487 int ret_v4;
488
489 fno = AC_CDVDSIF_ID_SEEK;
490 if ( Cdcc.lockid )
491 {
492 v5 = 0;
493 if ( WaitSema(Cdcc.lockid) )
494 v5 = 19;
495 }
496 else
497 {
498 v5 = 17;
499 }
500 if ( v5 )
501 {
502 Cdcc.error = v5;
503 return 0;
504 }
505 v8 = -16;
506 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
507 {
508 v8 = 13;
509 Cdcc.fno = AC_CDVDSIF_ID_SEEK;
510 Cdcc.stat = 18;
511 if ( Cdcc.syncid > 0 )
512 ClearEventFlag(Cdcc.syncid, 0);
513 }
514 ret_v4 = v8;
515 if ( v8 <= 0 )
516 {
517 fno = AC_CDVDSIF_ID_NOP;
518 }
519 else if ( lsn < Cdcc.cdsize )
520 {
521 Cdcc.done = done;
522 ret_v4 = acd_seek(acd_setup(&Cdcc.acd, (acd_done_t)cdc_done, &Cdcc, -5000000), lsn);
523 if ( ret_v4 >= 0 )
524 fno = AC_CDVDSIF_ID_NOP;
525 }
526 else
527 {
528 ret_v4 = 0;
529 }
530 return cdc_unlock(&Cdcc, ret_v4, fno);
531}
532
533static int cdc_ioctl(acCdvdsifId fno, int state, int tmout, cdc_done_t done)
534{
535 acInt32 ret;
536 int ret_v2;
537 acCdvdsifId v12;
538 int ret_v4;
539
540 if ( Cdcc.lockid )
541 {
542 ret = 0;
543 if ( WaitSema(Cdcc.lockid) )
544 ret = 19;
545 }
546 else
547 {
548 ret = 17;
549 }
550 if ( ret )
551 {
552 Cdcc.error = ret;
553 return 0;
554 }
555 if ( state == 4 )
556 {
557 ret_v2 = 0;
558 }
559 else if ( state >= 5 )
560 {
561 if ( state == 6 )
562 {
563 ret_v2 = 1;
564 }
565 else
566 {
567 ret_v2 = 10;
568 if ( state == 16 )
569 ret_v2 = 18;
570 }
571 }
572 else
573 {
574 ret_v2 = 10;
575 if ( state == 1 )
576 ret_v2 = 2;
577 }
578 if ( fno )
579 {
580 v12 = -16;
581 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
582 {
583 v12 = fno;
584 Cdcc.fno = fno;
585 Cdcc.stat = ret_v2;
586 if ( Cdcc.syncid > 0 )
587 ClearEventFlag(Cdcc.syncid, 0);
588 }
589 }
590 else
591 {
592 Cdcc.stat = 0;
593 Cdcc.fno = AC_CDVDSIF_ID_NOP;
594 if ( Cdcc.syncid > 0 )
595 SetEventFlag(Cdcc.syncid, 3u);
596 v12 = AC_CDVDSIF_ID_NOP;
597 }
598 ret_v4 = v12;
599 if ( v12 < AC_CDVDSIF_ID_NOP )
600 {
601 fno = AC_CDVDSIF_ID_NOP;
602 }
603 else
604 {
605 Cdcc.done = done;
606 ret_v4 = acd_ioctl(acd_setup(&Cdcc.acd, (acd_done_t)cdc_done, &Cdcc, tmout), state);
607 if ( ret_v4 >= 0 )
608 {
609 fno = AC_CDVDSIF_ID_NOP;
610 }
611 }
612 return cdc_unlock(&Cdcc, ret_v4, fno);
613}
614
615int cdc_pause(cdc_done_t done)
616{
617 return cdc_ioctl(AC_CDVDSIF_ID_PAUSE, 1, -5000000, done);
618}
619
620int cdc_standby(cdc_done_t done)
621{
622 return cdc_ioctl(AC_CDVDSIF_ID_STANDBY, 17, -5000000, done);
623}
624
625int cdc_stop(cdc_done_t done)
626{
627 return cdc_ioctl(AC_CDVDSIF_ID_STOP, 4, -5000000, done);
628}
629
630int cdc_tray(int mode, u32 *traycnt)
631{
632 acCdvdsifId tray;
633 int v5;
634 acCdvdsifId v8;
635 struct acd v10;
636
637 tray = Cdcc.tray;
638 v5 = 1;
639 if ( mode == 2 )
640 {
641 acd_getmedium(acd_setup(&v10, 0, 0, 5000000));
642 }
643 else
644 {
645 int ret;
646
647 ret = 134;
648 if ( mode )
649 ret = 131;
650 v5 = cdc_ioctl(AC_CDVDSIF_ID_TRAY, ret, 5000000, 0);
651 }
652 v8 = acd_gettray();
653 Cdcc.tray = v8;
654 *traycnt = tray != v8;
655 return v5;
656}
657
658int cdc_getpos()
659{
660 acInt32 v0;
661 int ret;
662
663 v0 = 17;
664 if ( Cdcc.lockid )
665 {
666 v0 = 0;
667 if ( WaitSema(Cdcc.lockid) )
668 v0 = 19;
669 }
670 if ( v0 )
671 {
672 Cdcc.error = v0;
673 return 0;
674 }
675 if ( Cdcc.fno )
676 {
677 if ( Cdcc.fno == AC_CDVDSIF_ID_READ )
678 {
679 ret = Cdcc.rd.pos << 11;
680 }
681 else
682 {
683 Cdcc.error = 19;
684 ret = 0;
685 }
686 }
687 else
688 {
689 ret = 0;
690 }
691 if ( Cdcc.lockid > 0 )
692 {
693 SignalSema(Cdcc.lockid);
694 }
695 return ret;
696}
697
698static int cdc_rmode(struct cdc_softc *cdcc, const sceCdRMode *mode)
699{
700 int spindlctrl;
701 struct acd *v5;
702 int speed;
703 struct acd *acd;
704 int v8;
705 int trycount;
706 struct acd *acd_v7;
707
708 spindlctrl = mode->spindlctrl;
709 v5 = acd_setup(&cdcc->acd, 0, 0, 5000000);
710 speed = cdcc->rd.maxspeed;
711 acd = v5;
712 v8 = 0;
713 if ( !cdcc->rd.maxspeed )
714 {
715 v8 = acd_getspeed(v5, 1);
716 speed = v8;
717 }
718 if ( v8 >= 0 )
719 {
720 cdcc->rd.maxspeed = v8;
721 if ( spindlctrl == 1 )
722 {
723 int v9;
724
725 v9 = 3 * (speed - 1);
726 speed = v9 >> 2;
727 if ( v9 < 0 )
728 speed = (v9 + 3) >> 2;
729 }
730 if ( acd_setspeed(acd, speed) >= 0 )
731 cdcc->rd.spindle = spindlctrl;
732 }
733 trycount = mode->trycount - 1;
734 acd_v7 = acd_setup(&cdcc->acd, 0, 0, 5000000);
735 if ( trycount < 0 )
736 trycount = 254;
737 while ( acd_setretry(acd_v7, trycount) == -61 && acd_getretry(acd_v7) >= 0 )
738 ;
739 return 0;
740}
741
742static void cdc_read_done(struct acd *acd, struct cdc_softc *arg, int ret)
743{
744 cdc_xfer_t xfer;
745 acInt32 npos;
746 unsigned char *buf;
747 int rlen;
748 unsigned char *buf_v9;
749 unsigned char *src;
750
751 if ( ret >= 0 )
752 {
753 acInt32 cpos;
754 acInt32 size;
755 acInt32 xlen;
756 acInt32 bsize;
757
758 cpos = arg->rd.pos;
759 size = arg->rd.size;
760 xfer = arg->rd.xfer;
761 npos = cpos + ret;
762 xlen = size - cpos;
763 buf = &arg->rd.buf[2048 * cpos];
764 bsize = arg->rd.bsize;
765 rlen = size - (cpos + ret);
766 if ( size < cpos + ret )
767 npos = arg->rd.size;
768 if ( bsize < rlen )
769 rlen = arg->rd.bsize;
770 if ( bsize < xlen )
771 xlen = arg->rd.bsize;
772 arg->rd.pos = npos;
773 if ( xfer )
774 {
775 unsigned char *size_v10;
776 acInt32 cpos_v11;
777 acInt32 bsize_v13;
778
779 size_v10 = buf;
780 cpos_v11 = bsize << 11;
781 src = arg->buf;
782 bsize_v13 = arg->rd.bank;
783 buf_v9 = &src[cpos_v11];
784 if ( bsize_v13 )
785 {
786 src += cpos_v11;
787 buf_v9 = arg->buf;
788 }
789 arg->rd.bank = bsize_v13 ^ 1;
790 ret = xfer(size_v10, src, xlen << 11, CDC_XFER_OUT);
791 }
792 else
793 {
794 buf_v9 = &buf[2048 * ret];
795 }
796 }
797 if ( ret >= 0 )
798 {
799 ret = npos;
800 if ( rlen )
801 {
802 int size_v14;
803
804 size_v14 = arg->syncid;
805 if ( size_v14 > 0 )
806 SetEventFlag(size_v14, 2u);
807 ret = acd_read(acd, arg->rd.lsn + npos, buf_v9, rlen);
808 }
809 }
810 if ( ret >= 0 )
811 {
812 if ( rlen )
813 {
814 int size_v15;
815
816 size_v15 = arg->syncid;
817 if ( size_v15 > 0 )
818 ClearEventFlag(size_v15, 0xFFFFFFFD);
819 return;
820 }
821 }
822 cdc_done(acd, arg, ret);
823}
824
825int cdc_read(unsigned int lsn, void *buf, int sectors, const sceCdRMode *mode, cdc_xfer_t xfer, cdc_done_t done)
826{
827 acCdvdsifId fno;
828 acInt32 v11;
829 int v14;
830 int ret_v4;
831 unsigned int n;
832
833 fno = AC_CDVDSIF_ID_READ;
834 if ( Cdcc.lockid )
835 {
836 v11 = 0;
837 if ( WaitSema(Cdcc.lockid) )
838 v11 = 19;
839 }
840 else
841 {
842 v11 = 17;
843 }
844 if ( v11 )
845 {
846 Cdcc.error = v11;
847 return 0;
848 }
849 v14 = -16;
850 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
851 {
852 v14 = 9;
853 Cdcc.fno = AC_CDVDSIF_ID_READ;
854 Cdcc.stat = 6;
855 if ( Cdcc.syncid > 0 )
856 ClearEventFlag(Cdcc.syncid, 0);
857 }
858 ret_v4 = v14;
859 if ( v14 <= 0 )
860 {
861 fno = AC_CDVDSIF_ID_NOP;
862 return cdc_unlock(&Cdcc, ret_v4, fno);
863 }
864 n = 16;
865 if ( lsn >= Cdcc.cdsize )
866 {
867 ret_v4 = -34;
868 }
869 else
870 {
871 if ( lsn + sectors >= Cdcc.cdsize )
872 sectors = Cdcc.cdsize - lsn;
873 Cdcc.rd.buf = (acUint8 *)buf;
874 Cdcc.done = done;
875 Cdcc.rd.size = sectors;
876 Cdcc.rd.bsize = 16;
877 Cdcc.rd.lsn = lsn;
878 Cdcc.rd.xfer = xfer;
879 Cdcc.rd.pos = 0;
880 Cdcc.rd.bank = 0;
881 if ( xfer )
882 buf = Cdcc.buf;
883 if ( (unsigned int)sectors < 0x10 )
884 n = sectors;
885 ret_v4 = cdc_rmode(&Cdcc, mode);
886 // cppcheck-suppress knownConditionTrueFalse
887 if ( ret_v4 < 0 )
888 return cdc_unlock(&Cdcc, ret_v4, fno);
889 ret_v4 = acd_read(acd_setup(&Cdcc.acd, (acd_done_t)cdc_read_done, &Cdcc, -5000000), lsn, buf, n);
890 if ( ret_v4 >= 0 )
891 {
892 fno = AC_CDVDSIF_ID_NOP;
893 }
894 }
895 return cdc_unlock(&Cdcc, ret_v4, fno);
896}
897
898int cdc_xfer(void *dst, void *src, int len, enum cdc_xfer_dir dir)
899{
900 if ( dir )
901 memcpy(dst, src, len);
902 return len;
903}
904
905static int cdc_unlocks(struct cdc_softc *cdcc, int ret, acCdvdsifId fno)
906{
907 int lockid;
908
909 lockid = cdcc->lockid;
910 if ( ret < 0 )
911 cdc_errno_set(cdcc, -ret);
912 if ( cdcc->fno == fno )
913 {
914 int eveid;
915
916 eveid = cdcc->syncid;
917 cdcc->fno = AC_CDVDSIF_ID_NOP;
918 if ( eveid > 0 )
919 SetEventFlag(eveid, 3u);
920 }
921 if ( lockid > 0 )
922 {
923 SignalSema(lockid);
924 }
925 return ret >= 0;
926}
927
928static void cdc_stream_done(struct acd *acd, struct cdc_softc *arg, int ret)
929{
930 int v4;
931 int v21;
932 acSpl state;
933 int flg;
934
935 flg = 0;
936 v4 = ret;
937 if ( ret <= 0 )
938 {
939 arg->st.flag = 0;
940 arg->fno = AC_CDVDSIF_ID_NOP;
941 v21 = 0;
942 flg = 1;
943 }
944 else
945 {
946 unsigned int flag;
947 acInt32 tail;
948 acInt32 size;
949 acInt32 bsize;
950 unsigned int cdsize;
951 acInt32 head;
952 unsigned int lsn;
953 int xlen;
954 unsigned int v15;
955 unsigned char *buf;
956 unsigned int size_v12;
957
958 CpuSuspendIntr(&state);
959 flag = arg->st.flag;
960 tail = arg->st.tail;
961 size = arg->st.size;
962 bsize = arg->st.bsize;
963 cdsize = arg->cdsize;
964 head = arg->st.head + v4;
965 if ( head >= size )
966 head = 0;
967 lsn = arg->st.lsn + v4;
968 if ( (flag & 0x10) != 0 )
969 {
970 head = 0;
971 tail = 0;
972 lsn = arg->st.reqlsn;
973 flag = (flag | 0x14) ^ 0x14;
974 arg->st.tail = 0;
975 }
976 else
977 {
978 if ( head == tail )
979 {
980 flag = (flag | 6) ^ 2;
981 }
982 }
983 xlen = tail - head;
984 if ( head >= tail )
985 xlen = size - head;
986 v15 = lsn + xlen;
987 if ( bsize < xlen )
988 {
989 xlen = bsize;
990 v15 = lsn + bsize;
991 }
992 if ( v15 >= cdsize )
993 xlen = cdsize - lsn;
994 buf = &arg->st.buf[2048 * head];
995 size_v12 = flag & 0x28;
996 if ( size_v12 == 32 )
997 {
998 arg->st.flag = flag & 0xFFFFFFFD;
999 }
1000 else
1001 {
1002 if ( ((flag & 0x28) >= 0x21) ? (size_v12 != 40) : (size_v12 != 8) )
1003 {
1004 arg->st.flag = flag;
1005 }
1006 else
1007 {
1008 arg->st.flag = flag & 4;
1009 }
1010 }
1011 arg->st.head = head;
1012 arg->st.lsn = lsn;
1013 CpuResumeIntr(state);
1014 if ( (flag & 8) != 0 )
1015 {
1016 arg->fno = AC_CDVDSIF_ID_NOP;
1017 v4 = 0;
1018 v21 = 0;
1019 flg = 1;
1020 }
1021 else
1022 {
1023 v4 = 0;
1024 if ( (flag & 0x20) != 0 )
1025 {
1026 v21 = 0;
1027 flg = 1;
1028 }
1029 else
1030 {
1031 v4 = -34;
1032 if ( !xlen )
1033 {
1034 v21 = 0;
1035 flg = 1;
1036 }
1037 else
1038 {
1039 int eveid;
1040 eveid = arg->syncid;
1041 if ( eveid > 0 )
1042 SetEventFlag(arg->syncid, 3u);
1043 if ( (flag & 4) == 0 )
1044 {
1045 if ( eveid > 0 )
1046 ClearEventFlag(eveid, 0);
1047 v4 = acd_read(acd, lsn, buf, xlen);
1048 if ( v4 < 0 )
1049 {
1050 v21 = 0;
1051 flg = 1;
1052 }
1053 }
1054 }
1055 }
1056 }
1057 }
1058 if ( flg )
1059 {
1060 int eveid_v17;
1061
1062 if ( v4 < 0 )
1063 v21 = -v4;
1064 cdc_errno_set(arg, v21);
1065 eveid_v17 = arg->syncid;
1066 if ( eveid_v17 > 0 )
1067 SetEventFlag(eveid_v17, 3u);
1068 }
1069}
1070
1071static int cdc_stream(struct cdc_softc *cdcc)
1072{
1073 int ret;
1074 int head;
1075 int tail;
1076 int xlen;
1077 int flag;
1078 unsigned char *buf;
1079 unsigned int lsn;
1080 int tail_v9;
1081 struct acd *ret_v10;
1082 acSpl state;
1083
1084 if ( cdcc->fno != AC_CDVDSIF_ID_STREAM )
1085 {
1086 return -16;
1087 }
1088 CpuSuspendIntr(&state);
1089 head = cdcc->st.head;
1090 tail = cdcc->st.tail;
1091 xlen = tail - head;
1092 if ( head >= tail )
1093 xlen = cdcc->st.size - head;
1094 flag = cdcc->st.flag;
1095 if ( cdcc->st.bsize < xlen )
1096 xlen = cdcc->st.bsize;
1097 buf = &cdcc->st.buf[2048 * head];
1098 if ( (flag & 6) != 0 || (flag & 0x28) != 0 || (flag & 1) == 0 )
1099 xlen = 0;
1100 lsn = 0;
1101 if ( xlen )
1102 {
1103 unsigned int head_v7;
1104
1105 flag |= 2u;
1106 head_v7 = cdcc->cdsize;
1107 if ( (flag & 0x10) != 0 )
1108 {
1109 lsn = cdcc->st.reqlsn;
1110 flag ^= 0x10u;
1111 cdcc->st.tail = 0;
1112 cdcc->st.head = 0;
1113 cdcc->st.lsn = lsn;
1114 }
1115 else
1116 {
1117 lsn = cdcc->st.lsn;
1118 }
1119 if ( lsn + xlen >= head_v7 )
1120 {
1121 xlen = head_v7 - lsn;
1122 if ( head_v7 == lsn )
1123 flag ^= 2u;
1124 }
1125 }
1126 cdcc->st.flag = flag;
1127 CpuResumeIntr(state);
1128 if ( !xlen )
1129 {
1130 return 0;
1131 }
1132 tail_v9 = cdcc->syncid;
1133 if ( tail_v9 > 0 )
1134 ClearEventFlag(tail_v9, 0);
1135 ret_v10 = acd_setup(&cdcc->acd, (acd_done_t)cdc_stream_done, cdcc, -5000000);
1136 ret = acd_read(ret_v10, lsn, buf, xlen);
1137 if ( ret < 0 )
1138 cdcc->st.flag = 0;
1139 return ret;
1140}
1141
1142int cdc_reads(void *buf, int sectors, int mode, int *errp, cdc_xfer_t xfer)
1143{
1144 int v5;
1145 int v7;
1146 unsigned char *v11;
1147 acInt32 rlen;
1148 int ret_v8;
1149 acInt32 head;
1150 int rlen_v10;
1151 int v17;
1152 int rlen_v13;
1153 int xlen;
1154 unsigned char *tmp;
1155 int v21;
1156 acInt32 ret_v17;
1157 int xlen_v20;
1158 int ret_v21;
1159 int rlen_v22;
1160 int rlen_v23;
1161 acSpl state;
1162 int state_2;
1163 int state_3;
1164 int v33;
1165 unsigned char *dst;
1166 u32 *resbits;
1167
1168 v5 = sectors;
1169 dst = (unsigned char *)buf;
1170 resbits = (u32 *)&v33;
1171 while ( v5 > 0 )
1172 {
1173 acInt32 v6;
1174 acInt32 ret;
1175 int len;
1176
1177 v6 = 17;
1178 if ( Cdcc.lockid )
1179 {
1180 v7 = WaitSema(Cdcc.lockid);
1181 v6 = 0;
1182 if ( v7 )
1183 v6 = 19;
1184 }
1185 if ( v6 )
1186 {
1187 Cdcc.error = v6;
1188 break;
1189 }
1190 ret = 27;
1191 if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1192 {
1193 ret = -16;
1194 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1195 {
1196 ret = 19;
1197 Cdcc.fno = AC_CDVDSIF_ID_READS;
1198 if ( Cdcc.syncid > 0 )
1199 ClearEventFlag(Cdcc.syncid, 0);
1200 }
1201 }
1202 len = v5;
1203 if ( ret <= 0 )
1204 {
1205 rlen_v23 = 0;
1206 printf("accdvd:cdc:reads: ACTIVE\n");
1207 }
1208 else
1209 {
1210 v11 = dst;
1211 CpuSuspendIntr(&state);
1212 rlen = Cdcc.st.tail;
1213 ret_v8 = Cdcc.st.flag;
1214 head = Cdcc.st.head;
1215 rlen_v10 = Cdcc.st.lsn >= Cdcc.cdsize;
1216 CpuResumeIntr(state);
1217 if ( (ret_v8 & 0x10) != 0 )
1218 {
1219 ret = 0;
1220 }
1221 if ( ((ret_v8 & 4) == 0) && (head == rlen) )
1222 {
1223 v17 = 0;
1224 if ( rlen_v10 )
1225 v17 = -34;
1226 ret = v17;
1227 }
1228 else
1229 {
1230 int flg;
1231
1232 flg = 1;
1233 rlen_v13 = 0;
1234 if ( rlen >= head )
1235 {
1236 xlen = Cdcc.st.size - rlen;
1237 tmp = v11;
1238 if ( v5 < Cdcc.st.size - rlen )
1239 xlen = v5;
1240 len = v5 - xlen;
1241 v11 += 2048 * xlen;
1242 rlen_v13 = xlen;
1243 v21 = xlen;
1244 if ( xlen )
1245 {
1246 v21 = xfer(tmp, &Cdcc.st.buf[2048 * rlen], xlen * 2048, CDC_XFER_OUT);
1247 if ( v21 >= 0 )
1248 {
1249 CpuSuspendIntr(&state_2);
1250 ret_v17 = rlen + rlen_v13;
1251 if ( rlen + rlen_v13 >= Cdcc.st.size )
1252 ret_v17 = 0;
1253 Cdcc.st.tail = ret_v17;
1254 Cdcc.st.flag &= ~4u;
1255 CpuResumeIntr(state_2);
1256 v21 = ret_v17;
1257 }
1258 }
1259 rlen = v21;
1260 if ( rlen < 0 )
1261 {
1262 ret = rlen;
1263 flg = 0;
1264 }
1265 }
1266 if ( rlen < head )
1267 {
1268 xlen_v20 = head - rlen;
1269 ret = head - rlen;
1270 if ( len < head - rlen )
1271 {
1272 xlen_v20 = len;
1273 ret = len;
1274 }
1275 rlen_v13 += xlen_v20;
1276 rlen_v22 = 0;
1277 if ( ret )
1278 {
1279 ret_v21 = xfer(v11, &Cdcc.st.buf[2048 * rlen], ret << 11, CDC_XFER_OUT);
1280 if ( ret_v21 >= 0 )
1281 {
1282 CpuSuspendIntr(&state_3);
1283 ret += rlen;
1284 if ( ret >= Cdcc.st.size )
1285 ret = 0;
1286 Cdcc.st.tail = ret;
1287 Cdcc.st.flag &= ~4u;
1288 CpuResumeIntr(state_3);
1289 rlen_v22 = ret;
1290 }
1291 ret = ret_v21;
1292 }
1293 else
1294 {
1295 rlen_v22 = ret;
1296 }
1297 if ( rlen_v22 < 0 )
1298 flg = 0;
1299 }
1300 if ( flg )
1301 {
1302 ret = rlen_v13;
1303 if ( rlen_v13 > 0 && xfer )
1304 {
1305 xfer(0, 0, 0, CDC_XFER_SYNC);
1306 }
1307 }
1308 }
1309 rlen_v23 = ret;
1310 if ( ret < 0 )
1311 {
1312 rlen_v23 = 0;
1313 printf("accdvd:cdc:reads: READ\n");
1314 }
1315 else
1316 {
1317 v5 -= ret;
1318 dst += 2048 * ret;
1319 ret = cdc_stream(&Cdcc);
1320 }
1321 }
1322 cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_READS);
1323 if ( ret < 0 )
1324 break;
1325 if ( rlen_v23 <= 0 )
1326 {
1327 if ( !mode )
1328 break;
1329 v33 = 1;
1330 if ( Cdcc.syncid > 0 )
1331 WaitEventFlag(Cdcc.syncid, 1u, 1, resbits);
1332 }
1333 }
1334 *errp = Cdcc.error;
1335 return sectors - v5;
1336}
1337
1338int cdc_starts(unsigned int lsn, const sceCdRMode *mode)
1339{
1340 acInt32 v4;
1341 int v7;
1342 int ret;
1343 acSpl state;
1344
1345 if ( Cdcc.lockid )
1346 {
1347 v4 = 0;
1348 if ( WaitSema(Cdcc.lockid) )
1349 v4 = 19;
1350 }
1351 else
1352 {
1353 v4 = 17;
1354 }
1355 if ( v4 )
1356 {
1357 Cdcc.error = v4;
1358 return 0;
1359 }
1360 v7 = 27;
1361 if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1362 {
1363 v7 = -16;
1364 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1365 {
1366 v7 = 21;
1367 Cdcc.fno = AC_CDVDSIF_ID_STARTS;
1368 if ( Cdcc.syncid > 0 )
1369 ClearEventFlag(Cdcc.syncid, 0);
1370 }
1371 }
1372 ret = v7;
1373 if ( v7 > 0 )
1374 {
1375 acInt32 flag;
1376
1377 CpuSuspendIntr(&state);
1378 flag = Cdcc.st.flag;
1379 if ( (Cdcc.st.flag & 2) != 0 )
1380 {
1381 Cdcc.st.reqlsn = lsn;
1382 Cdcc.st.flag |= 0x10u;
1383 }
1384 else
1385 {
1386 flag = 0;
1387 Cdcc.st.flag = 1;
1388 Cdcc.st.lsn = lsn;
1389 }
1390 CpuResumeIntr(state);
1391 if ( !flag )
1392 {
1393 acCdvdsifId flag_v5;
1394
1395 flag_v5 = Cdcc.fno;
1396 Cdcc.fno = AC_CDVDSIF_ID_STREAM;
1397 ret = cdc_rmode(&Cdcc, mode);
1398 // cppcheck-suppress knownConditionTrueFalse
1399 if ( ret < 0 || (ret = cdc_stream(&Cdcc), ret < 0) )
1400 Cdcc.fno = flag_v5;
1401 }
1402 }
1403 return cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_STARTS);
1404}
1405
1406int cdc_stops()
1407{
1408 acInt32 v0;
1409 int sync;
1410 int ret;
1411 int sync_v5;
1412 int ret_v6;
1413 int state;
1414 u32 pattern;
1415
1416 v0 = 17;
1417 if ( Cdcc.lockid )
1418 {
1419 v0 = 0;
1420 if ( WaitSema(Cdcc.lockid) )
1421 v0 = 19;
1422 }
1423 if ( v0 )
1424 {
1425 Cdcc.error = v0;
1426 return 0;
1427 }
1428 sync = 27;
1429 if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1430 {
1431 sync = -16;
1432 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1433 {
1434 sync = 23;
1435 Cdcc.fno = AC_CDVDSIF_ID_STOPS;
1436 if ( Cdcc.syncid > 0 )
1437 ClearEventFlag(Cdcc.syncid, 0);
1438 }
1439 }
1440 ret = sync;
1441 sync_v5 = 0;
1442 if ( sync > 0 )
1443 {
1444 CpuSuspendIntr(&state);
1445 sync_v5 = Cdcc.st.flag | 8;
1446 if ( (Cdcc.st.flag & 2) == 0 )
1447 {
1448 Cdcc.fno = AC_CDVDSIF_ID_STOPS;
1449 sync_v5 = 0;
1450 }
1451 Cdcc.st.flag = sync_v5;
1452 CpuResumeIntr(state);
1453 }
1454 ret_v6 = cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_STOPS);
1455 if ( sync_v5 )
1456 {
1457 pattern = 1;
1458 if ( Cdcc.syncid > 0 )
1459 WaitEventFlag(Cdcc.syncid, 1u, 1, &pattern);
1460 }
1461 return ret_v6;
1462}
1463
1464int cdc_pauses()
1465{
1466 acInt32 v0;
1467 int sync;
1468 int ret;
1469 int sync_v5;
1470 int ret_v7;
1471 int state;
1472 u32 pattern;
1473
1474 v0 = 17;
1475 if ( Cdcc.lockid )
1476 {
1477 v0 = 0;
1478 if ( WaitSema(Cdcc.lockid) )
1479 v0 = 19;
1480 }
1481 if ( v0 )
1482 {
1483 Cdcc.error = v0;
1484 return 0;
1485 }
1486 sync = 27;
1487 if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1488 {
1489 sync = -16;
1490 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1491 {
1492 sync = 24;
1493 Cdcc.fno = AC_CDVDSIF_ID_PAUSES;
1494 if ( Cdcc.syncid > 0 )
1495 ClearEventFlag(Cdcc.syncid, 0);
1496 }
1497 }
1498 ret = sync;
1499 sync_v5 = 0;
1500 if ( sync > 0 )
1501 {
1502 int sync_v6;
1503
1504 CpuSuspendIntr(&state);
1505 sync_v6 = Cdcc.st.flag;
1506 if ( (Cdcc.st.flag & 2) != 0 )
1507 {
1508 sync_v6 = Cdcc.st.flag | 0x20;
1509 Cdcc.st.flag |= 0x20u;
1510 }
1511 sync_v5 = sync_v6 & 2;
1512 CpuResumeIntr(state);
1513 }
1514 ret_v7 = cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_PAUSES);
1515 if ( sync_v5 )
1516 {
1517 pattern = 1;
1518 if ( Cdcc.syncid > 0 )
1519 WaitEventFlag(Cdcc.syncid, 1u, 1, &pattern);
1520 }
1521 return ret_v7;
1522}
1523
1524int cdc_resumes()
1525{
1526 acInt32 v0;
1527 int ret_v2;
1528 int ret_v3;
1529 acSpl state;
1530
1531 v0 = 17;
1532 if ( Cdcc.lockid )
1533 {
1534 v0 = 0;
1535 if ( WaitSema(Cdcc.lockid) )
1536 v0 = 19;
1537 }
1538 if ( v0 )
1539 {
1540 Cdcc.error = v0;
1541 return 0;
1542 }
1543 ret_v2 = 27;
1544 if ( Cdcc.fno == AC_CDVDSIF_ID_STREAM )
1545 {
1546 ret_v3 = ret_v2;
1547 }
1548 else
1549 {
1550 ret_v2 = -16;
1551 if ( Cdcc.fno )
1552 {
1553 ret_v3 = ret_v2;
1554 }
1555 else
1556 {
1557 ret_v2 = 25;
1558 ret_v3 = 25;
1559 Cdcc.fno = AC_CDVDSIF_ID_RESUMES;
1560 if ( Cdcc.syncid > 0 )
1561 {
1562 ClearEventFlag(Cdcc.syncid, 0);
1563 ret_v3 = ret_v2;
1564 }
1565 }
1566 }
1567 if ( ret_v3 > 0 )
1568 {
1569 int flag;
1570
1571 CpuSuspendIntr(&state);
1572 flag = Cdcc.st.flag;
1573 if ( (Cdcc.st.flag & 2) == 0 && (Cdcc.st.flag & 0x20) != 0 )
1574 Cdcc.st.flag ^= 0x20u;
1575 CpuResumeIntr(state);
1576 ret_v3 = 0;
1577 if ( (flag & 0x20) != 0 )
1578 ret_v3 = cdc_stream(&Cdcc);
1579 }
1580 return cdc_unlocks(&Cdcc, ret_v3, AC_CDVDSIF_ID_RESUMES);
1581}
1582
1583int cdc_inits(void *buf, unsigned int size, unsigned int bsize)
1584{
1585 acInt32 ret;
1586 int v9;
1587 int ret_v3;
1588
1589 if ( Cdcc.lockid )
1590 {
1591 ret = 0;
1592 if ( WaitSema(Cdcc.lockid) )
1593 ret = 19;
1594 }
1595 else
1596 {
1597 ret = 17;
1598 }
1599 if ( ret )
1600 {
1601 Cdcc.error = ret;
1602 return 0;
1603 }
1604 v9 = -16;
1605 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1606 {
1607 v9 = 18;
1608 Cdcc.fno = AC_CDVDSIF_ID_INITS;
1609 Cdcc.stat = 0;
1610 if ( Cdcc.syncid > 0 )
1611 ClearEventFlag(Cdcc.syncid, 0);
1612 }
1613 ret_v3 = v9;
1614 if ( v9 > 0 )
1615 {
1616 ret_v3 = 1;
1617 Cdcc.st.buf = (acUint8 *)buf;
1618 Cdcc.st.size = size;
1619 Cdcc.st.bsize = bsize;
1620 Cdcc.st.head = 0;
1621 Cdcc.st.tail = 0;
1622 Cdcc.st.lsn = 0;
1623 Cdcc.st.reqlsn = 0;
1624 Cdcc.st.flag = 0;
1625 }
1626 return cdc_unlock(&Cdcc, ret_v3, AC_CDVDSIF_ID_INITS);
1627}
1628
1629int cdc_seeks(unsigned int lsn)
1630{
1631 acInt32 v2;
1632 int v5;
1633 int ret;
1634 acSpl state;
1635
1636 v2 = 17;
1637 if ( Cdcc.lockid )
1638 {
1639 v2 = 0;
1640 if ( WaitSema(Cdcc.lockid) )
1641 v2 = 19;
1642 }
1643 if ( v2 )
1644 {
1645 Cdcc.error = v2;
1646 return 0;
1647 }
1648 v5 = 27;
1649 if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1650 {
1651 v5 = -16;
1652 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1653 {
1654 v5 = 20;
1655 Cdcc.fno = AC_CDVDSIF_ID_SEEKS;
1656 if ( Cdcc.syncid > 0 )
1657 ClearEventFlag(Cdcc.syncid, 0);
1658 }
1659 }
1660 ret = v5;
1661 if ( v5 > 0 )
1662 {
1663 CpuSuspendIntr(&state);
1664 Cdcc.st.reqlsn = lsn;
1665 Cdcc.st.flag |= 0x10u;
1666 CpuResumeIntr(state);
1667 ret = 1;
1668 }
1669 return cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_SEEKS);
1670}
1671
1672int cdc_stats()
1673{
1674 acInt32 v0;
1675 int ret;
1676 acSpl state;
1677
1678 v0 = 17;
1679 if ( Cdcc.lockid )
1680 {
1681 v0 = 0;
1682 if ( WaitSema(Cdcc.lockid) )
1683 v0 = 19;
1684 }
1685 if ( v0 )
1686 {
1687 Cdcc.error = v0;
1688 return 0;
1689 }
1690 ret = 27;
1691 if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1692 {
1693 ret = -16;
1694 if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1695 {
1696 ret = 22;
1697 Cdcc.fno = AC_CDVDSIF_ID_STATS;
1698 if ( Cdcc.syncid > 0 )
1699 ClearEventFlag(Cdcc.syncid, 0);
1700 }
1701 }
1702 if ( ret > 0 )
1703 {
1704 CpuSuspendIntr(&state);
1705 ret = Cdcc.st.size;
1706 if ( Cdcc.st.head == Cdcc.st.tail )
1707 {
1708 if ( (Cdcc.st.flag & 4) == 0 )
1709 ret = 0;
1710 }
1711 else if ( Cdcc.st.head < Cdcc.st.tail )
1712 {
1713 ret = Cdcc.st.size + Cdcc.st.head - Cdcc.st.tail;
1714 }
1715 else
1716 {
1717 ret = Cdcc.st.head - Cdcc.st.tail;
1718 }
1719 CpuResumeIntr(state);
1720 }
1721 if ( Cdcc.fno == AC_CDVDSIF_ID_STATS )
1722 {
1723 Cdcc.fno = AC_CDVDSIF_ID_NOP;
1724 if ( Cdcc.syncid > 0 )
1725 SetEventFlag(Cdcc.syncid, 3u);
1726 }
1727 if ( Cdcc.lockid > 0 )
1728 {
1729 SignalSema(Cdcc.lockid);
1730 }
1731 if ( ret < 0 )
1732 return 0;
1733 return ret;
1734}
1735
1736int cdc_module_status()
1737{
1738 int ret;
1739 int state;
1740
1741 CpuSuspendIntr(&state);
1742 if ( Cdcc.fno )
1743 ret = 2;
1744 else
1745 ret = Cdcc.lockid > 0;
1746 CpuResumeIntr(state);
1747 return ret;
1748}
1749
1750int cdc_module_start(int argc, char **argv)
1751{
1752 int ret;
1753 int index;
1754 int v6;
1755 int ret_v4;
1756 int ret_v5;
1757 int lockid;
1758 acUint8 *buf_v7;
1759 int syncid;
1760 acUint8 *buf;
1761
1762 (void)argc;
1763 (void)argv;
1764 ret = cdc_module_status();
1765 index = 0;
1766 if ( ret )
1767 {
1768 return ret;
1769 }
1770 v6 = 0;
1771 ret_v4 = 0;
1772 while ( (unsigned int)index < 3 )
1773 {
1774 int ret_v3;
1775
1776 ret_v3 = mods_120[v6].status();
1777 ret_v4 = ret_v3;
1778 if ( ret_v3 <= 0 )
1779 {
1780 if ( !ret_v3 )
1781 ret_v4 = mods_120[v6].start(argc, argv);
1782 }
1783 else
1784 {
1785 ret_v4 = 0;
1786 }
1787 if ( ret_v4 < 0 )
1788 {
1789 printf("cdc:init_modules:S:%d: error %d\n", index, ret_v4);
1790 break;
1791 }
1792 ++index;
1793 ++v6;
1794 }
1795 ret_v5 = ret_v4;
1796 if ( ret_v5 <= 0 )
1797 {
1798 return ret_v5;
1799 }
1800 lockid = cdc_sem_alloc();
1801 syncid = cdc_eve_alloc();
1802 buf_v7 = (acUint8 *)AllocSysMemory(0, 0x10000, 0);
1803 buf = buf_v7;
1804 if ( lockid > 0 )
1805 {
1806 if ( buf_v7 )
1807 {
1808 memset(&Cdcc, 0, sizeof(Cdcc));
1809 Cdcc.syncid = syncid;
1810 Cdcc.lockid = lockid;
1811 Cdcc.buf = buf;
1812 Cdcc.cdsize = 0;
1813 Cdcc.rd.spindle = -1;
1814 Cdcc.rd.maxspeed = 0;
1815 if ( syncid > 0 )
1816 SetEventFlag(syncid, 3u);
1817 return ret_v5;
1818 }
1819 DeleteSema(lockid);
1820 }
1821 if ( syncid > 0 )
1822 DeleteEventFlag(syncid);
1823 if ( buf )
1824 {
1825 FreeSysMemory(buf);
1826 }
1827 return -6;
1828}
1829
1830int cdc_module_stop()
1831{
1832 int ret;
1833 int lockid;
1834 int i;
1835 int lockid_v6;
1836 u32 pattern;
1837
1838 ret = cdc_module_status();
1839 if ( ret == 0 )
1840 {
1841 return 0;
1842 }
1843 lockid = Cdcc.lockid;
1844 if ( Cdcc.lockid <= 0 )
1845 return 0;
1846 cdc_stops();
1847 WaitSema(lockid);
1848 pattern = 1;
1849 if ( Cdcc.syncid > 0 )
1850 WaitEventFlag(Cdcc.syncid, 1u, 1, &pattern);
1851 if ( Cdcc.syncid > 0 )
1852 DeleteEventFlag(Cdcc.syncid);
1853 if ( Cdcc.buf )
1854 FreeSysMemory(Cdcc.buf);
1855 memset(&Cdcc, 0, sizeof(Cdcc));
1856 SignalSema(lockid);
1857 DeleteSema(lockid);
1858 for ( i = 2;; --i )
1859 {
1860 int ret_v5;
1861
1862 ret_v5 = mods_120[i].status();
1863 lockid_v6 = ret_v5;
1864 if ( ret_v5 < 0 )
1865 {
1866 lockid_v6 = 0;
1867 }
1868 if ( ret_v5 > 0 )
1869 {
1870 lockid_v6 = mods_120[i].stop();
1871 if ( lockid_v6 < 0 )
1872 {
1873 printf("cdc:init_modules:E:%d: error %d\n", i, lockid_v6);
1874 return lockid_v6;
1875 }
1876 }
1877 }
1878 return lockid_v6;
1879}
1880
1881int cdc_module_restart(int argc, char **argv)
1882{
1883 (void)argc;
1884 (void)argv;
1885
1886 return -88;
1887}
static cdda_toc toc
Definition cdrom.c:52
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205