PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
acd.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 acd_softc Acdc;
14
15static void acd_done(struct acd *acd, struct acd_softc *arg, int ret)
16{
17 acInt32 tmout;
18 int thid;
19 int tmout_v2;
20 acd_done_t done;
21 acSpl state;
22
23 CpuSuspendIntr(&state);
24 tmout = arg->active;
25 arg->sense = ret;
26 tmout--;
27 arg->active = tmout;
28 if ( tmout < 0 )
29 arg->active = 0;
30 CpuResumeIntr(state);
31 thid = acd->c_thid;
32 tmout_v2 = acd->c_tmout;
33 done = acd->c_done;
34 acd->c_thid = ret;
35 if ( !tmout_v2 )
36 acd->c_tmout = 1;
37 if ( done )
38 done(acd, acd->c_arg, ret);
39 if ( thid )
40 WakeupThread(thid);
41}
42
43static void acd_atapi_done(acAtapiT atapi, void *arg, int ret)
44{
45 struct acd_softc *argt;
46
47 argt = (struct acd_softc *)arg;
48 acd_done((struct acd *)atapi, argt, ret);
49}
50
51static int
52acd_request_in(struct acd *acd, int flag, acAtapiPacketT packet, void *buffer, int size, acAtapiDone done, char *name)
53{
54 int status;
55 int ret;
56 int ret_v10;
57 int tmout;
58 int v16;
59 int ret_v13;
60 int ret_v15;
61 int state;
62 int state_2;
63
64 (void)name;
65 if ( (Acdc.status & 1) == 0 )
66 return -6;
67 ret = acd->c_tmout;
68 if ( ret <= 0 )
69 {
70 acd->c_thid = 0;
71 ret = -ret;
72 }
73 else
74 {
75 acd->c_thid = GetThreadId();
76 }
77 acAtapiSetup(&acd->c_atapi, done ? done : acd_atapi_done, &Acdc, ret);
78 CpuSuspendIntr(&state);
79 ret_v10 = Acdc.drive;
80 ++Acdc.active;
81 CpuResumeIntr(state);
82 status = ret_v10;
83 if ( status < 0 )
84 {
85 return status;
86 }
87 tmout = acd->c_tmout;
88 v16 = flag | ret_v10;
89 if ( tmout > 0 )
90 acd->c_tmout = 0;
91 status = acAtapiRequest(&acd->c_atapi, v16, packet, buffer, size);
92 ret_v13 = status;
93 if ( status < 0 )
94 {
95 CpuSuspendIntr(&state_2);
96 Acdc.active--;
97 if ( Acdc.active < 0 )
98 Acdc.active = 0;
99 CpuResumeIntr(state_2);
100 return ret_v13;
101 }
102 if ( tmout <= 0 )
103 {
104 return status;
105 }
106 while ( 1 )
107 {
108 int status_v14;
109
110 status_v14 = SleepThread();
111 if ( status_v14 == -418 )
112 {
113 ret_v15 = -116;
114 break;
115 }
116 if ( status_v14 )
117 {
118 ret_v15 = -5;
119 break;
120 }
121 if ( acd->c_tmout )
122 {
123 ret_v15 = acd->c_thid;
124 acd->c_tmout = tmout;
125 return ret_v15;
126 }
127 }
128 acd->c_tmout = tmout;
129 return ret_v15;
130}
131
132static void acd_read_done(acAtapiT atapi, struct acd_softc *arg, int ret)
133{
134 if ( ret >= 0 )
135 ret >>= 11;
136 acd_done((struct acd *)atapi, arg, ret);
137}
138
139int acd_read(struct acd *acd, acd_lsn_t lsn, void *buf, int sectors)
140{
141 int flag;
142 union
143 {
144 struct
145 {
146 acUint8 opcode;
147 acUint8 lun;
148 acUint8 lba[4];
149 // cppcheck-suppress unusedStructMember
150 acUint8 padding;
151 acUint8 len[2];
152 // cppcheck-suppress unusedStructMember
153 acUint8 padding2[3];
154 };
156 } u;
157
158 if ( !acd || !buf )
159 return -22;
160 if ( sectors == 0 )
161 {
162 return 0;
163 }
164 memset(&u, 0, sizeof(u));
165 flag = 2;
166 if ( Acdc.dma )
167 flag = 3;
168 u.opcode = 40;
169 u.lun = 0;
170 u.lba[0] = (lsn & 0xFF000000) >> 24;
171 u.lba[1] = (lsn & 0xFF0000) >> 16;
172 u.lba[2] = (lsn & 0xFF00) >> 8;
173 u.lba[3] = lsn;
174 u.len[0] = (sectors & 0xFF00) >> 8;
175 u.len[1] = sectors & 0xFF;
176 return acd_request_in(acd, flag, &u.pkt, buf, sectors << 11, (acAtapiDone)acd_read_done, "read");
177}
178
179int acd_readtoc(struct acd *acd, void *buf, int size)
180{
182
183 if ( !acd || !buf )
184 return -22;
185 if ( !size )
186 return 0;
187 memset(&v4, 0, sizeof(v4));
188 v4.u_h[2] = 0;
189 v4.u_w[0] = 579;
190 v4.u_b[7] = (size & 0xFF00) >> 8;
191 v4.u_b[6] = 0;
192 v4.u_w[2] = size & 0xFF;
193 return acd_request_in(acd, 2, &v4, buf, size, 0, "readtoc");
194}
195
196int acd_seek(struct acd *acd, acd_lsn_t lsn)
197{
199
200 if ( !acd )
201 return -22;
202 memset(&v3, 0, sizeof(v3));
203 v3.u_h[0] = 40;
204 v3.u_b[2] = (lsn & 0xFF000000) >> 24;
205 v3.u_b[3] = (lsn & 0xFF0000) >> 16;
206 v3.u_w[1] = (lsn & 0xFF00) >> 8;
207 v3.u_w[2] = 0;
208 v3.u_b[5] = lsn;
209 return acd_request_in(acd, 2, &v3, 0, 0, 0, "seek");
210}
211
212static void acd_opentray_done(acAtapiT atapi, struct acd_softc *arg, int ret)
213{
214 acSpl state;
215
216 if ( ret >= 0 )
217 {
218 CpuSuspendIntr(&state);
219 arg->status = (arg->status | 6) ^ 4;
220 CpuResumeIntr(state);
221 }
222 acd_done((struct acd *)atapi, arg, ret);
223}
224
225static void acd_closetray_done(acAtapiT atapi, struct acd_softc *arg, int ret)
226{
227 acSpl state;
228
229 if ( ret >= 0 )
230 {
231 CpuSuspendIntr(&state);
232 arg->status = (arg->status | 6) ^ 2;
233 CpuResumeIntr(state);
234 }
235 acd_done((struct acd *)atapi, arg, ret);
236}
237
238int acd_ioctl(struct acd *acd, int cmd)
239{
240 acAtapiDone done;
241 char *name;
242 union
243 {
244 struct
245 {
246 acUint8 opcode;
247 acUint8 imm;
248 // cppcheck-suppress unusedStructMember
249 acUint8 padding3[2];
250 acUint8 op;
251 // cppcheck-suppress unusedStructMember
252 acUint8 padding4[7];
253 };
255 } u;
256
257 if ( !acd )
258 return -22;
259 memset(&u, 0, sizeof(u));
260 done = 0;
261 if ( cmd == 17 )
262 {
263 u.opcode = 40;
264 name = "ioctl:seek+start";
265 }
266 else if ( (cmd & 5) != 0 )
267 {
268 u.opcode = 27;
269 u.imm = (cmd & 0x80) != 0;
270 u.op = cmd & 3;
271 if ( (cmd & 2) != 0 )
272 {
273 done = (acAtapiDone)acd_opentray_done;
274 if ( (cmd & 1) != 0 )
275 done = (acAtapiDone)acd_closetray_done;
276 }
277 name = "ioctl:startstop";
278 }
279 else
280 {
281 return -22;
282 }
283 return acd_request_in(acd, 2, &u.pkt, 0, 0, done, name);
284}
285
286static int acd_mode_sense(struct acd *acd, int pgcode, void *buffer, int size, acAtapiDone done, char *name)
287{
289
290 memset(&v7, 0, sizeof(v7));
291 v7.u_b[0] = 0x5A;
292 v7.u_b[2] = pgcode;
293 v7.u_b[7] = (size & 0xFF00) >> 8;
294 v7.u_w[2] = size & 0xFF;
295 return acd_request_in(acd, 2, &v7, buffer, size, done, name);
296}
297
298static int acd_mode_select(struct acd *acd, void *buffer, int size, acAtapiDone done, char *name)
299{
301
302 memset(&v6, 0, sizeof(v6));
303 v6.u_b[0] = 0x55;
304 v6.u_b[1] = 0x10;
305 v6.u_b[7] = (size & 0xFF00) >> 8;
306 v6.u_w[2] = size & 0xFF;
307 return acd_request_in(acd, 6, &v6, buffer, size, done, name);
308}
309
310static void acd_getmedium_done(acAtapiT atapi, struct acd_softc *arg, int ret)
311{
312 int h_mtype;
313 acSpl state;
314
315 h_mtype = ret;
316 if ( ret >= 0 )
317 {
318 acUint32 status;
319 int v7;
320
321 CpuSuspendIntr(&state);
322 h_mtype = arg->retry.me_h.h_mtype;
323 status = arg->status | 6;
324 arg->medium = h_mtype;
325 if ( h_mtype == 113 )
326 v7 = status ^ 4;
327 else
328 v7 = status ^ 2;
329 arg->status = v7 | 0xA00;
330 CpuResumeIntr(state);
331 }
332 acd_done((struct acd *)atapi, arg, h_mtype);
333}
334
335int acd_getmedium(struct acd *acd)
336{
337 int ret;
338 acSpl state;
339
340 if ( acd )
341 return acd_mode_sense(acd, 1, &Acdc.retry, 20, (acAtapiDone)acd_getmedium_done, "getmedium");
342 CpuSuspendIntr(&state);
343 ret = -61;
344 if ( (Acdc.status & 0x800) != 0 )
345 ret = Acdc.medium;
346 CpuResumeIntr(state);
347 return ret;
348}
349
350static void acd_retry_done(acAtapiT atapi, struct acd_softc *arg, int ret)
351{
352 int me_rretry;
353 acSpl state;
354
355 me_rretry = ret;
356 if ( ret >= 0 )
357 {
358 acCdvdsifId h_mtype;
359 acUint32 status;
360 int v8;
361
362 CpuSuspendIntr(&state);
363 h_mtype = arg->retry.me_h.h_mtype;
364 status = arg->status | 6;
365 arg->medium = h_mtype;
366 if ( h_mtype == 113 )
367 v8 = status ^ 4;
368 else
369 v8 = status ^ 2;
370 arg->status = v8 | 0xA00;
371 me_rretry = arg->retry.me_rretry;
372 CpuResumeIntr(state);
373 }
374 acd_done((struct acd *)atapi, arg, me_rretry);
375}
376
377int acd_getretry(struct acd *acd)
378{
379 if ( !acd )
380 return -22;
381 return acd_mode_sense(acd, 1, &Acdc.retry, 20, (acAtapiDone)acd_retry_done, "getretry");
382}
383
384int acd_setretry(struct acd *acd, int rretry)
385{
386 int size;
387 acSpl state;
388
389 if ( acd == 0 )
390 {
391 return -22;
392 }
393 if ( (Acdc.status & 0x200) == 0 )
394 {
395 return -61;
396 }
397 CpuSuspendIntr(&state);
398 size = 0;
399 if ( rretry != Acdc.retry.me_rretry )
400 {
401 Acdc.retry.me_rretry = rretry;
402 size = (Acdc.retry.me_h.h_len[0] << 8) + Acdc.retry.me_h.h_len[1] + 2;
403 }
404 CpuResumeIntr(state);
405 if ( !size )
406 return rretry;
407 return acd_mode_select(acd, &Acdc.retry, size, (acAtapiDone)acd_retry_done, "setretry");
408}
409
410static void acd_getspeed_done(acAtapiT atapi, struct acd_softc *arg, int ret)
411{
412 int v4;
413 acSpl state;
414
415 v4 = ret;
416 if ( ret >= 0 )
417 {
418 acCdvdsifId speed;
419 acUint32 status;
420 int v8;
421
422 CpuSuspendIntr(&state);
423 speed = arg->speed.mc_h.h_mtype;
424 v4 = (arg->speed.mc_speed[0] << 8) + arg->speed.mc_speed[1];
425 status = arg->status | 6;
426 arg->medium = speed;
427 if ( speed == 113 )
428 v8 = status ^ 4;
429 else
430 v8 = status ^ 2;
431 arg->status = v8 | 0xC00;
432 CpuResumeIntr(state);
433 }
434 acd_done((struct acd *)atapi, arg, v4);
435}
436
437static void acd_getmaxspeed_done(acAtapiT atapi, struct acd_softc *arg, int ret)
438{
439 int v4;
440 acSpl state;
441
442 v4 = ret;
443 if ( ret >= 0 )
444 {
445 acCdvdsifId speed;
446 acUint32 status;
447 int v8;
448
449 CpuSuspendIntr(&state);
450 speed = arg->speed.mc_h.h_mtype;
451 v4 = (arg->speed.mc_maxspeed[0] << 8) + arg->speed.mc_maxspeed[1];
452 status = arg->status | 6;
453 arg->medium = speed;
454 if ( speed == 113 )
455 v8 = status ^ 4;
456 else
457 v8 = status ^ 2;
458 arg->status = v8 | 0xC00;
459 CpuResumeIntr(state);
460 }
461 acd_done((struct acd *)atapi, arg, v4);
462}
463
464int acd_getspeed(struct acd *acd, int maxspeed)
465{
466 acAtapiDone done;
467
468 if ( acd == 0 )
469 {
470 return -22;
471 }
472 done = (acAtapiDone)acd_getspeed_done;
473 if ( maxspeed )
474 done = (acAtapiDone)acd_getmaxspeed_done;
475 return acd_mode_sense(acd, 42, &Acdc.speed, 28, done, "getspeed");
476}
477
478int acd_setspeed(struct acd *acd, int speed)
479{
480 int v3;
481 int ospeed;
482 union
483 {
484 struct
485 {
486 acUint8 opcode;
487 acUint8 lun;
488 acUint8 speed[2];
489 // cppcheck-suppress unusedStructMember
490 acUint8 padding[8];
491 };
493 } u;
494 acSpl state;
495
496 v3 = speed;
497 if ( speed < 0 )
498 return -22;
499 CpuSuspendIntr(&state);
500 if ( (Acdc.status & 0x400) != 0 )
501 ospeed = (Acdc.speed.mc_speed[0] << 8) + Acdc.speed.mc_speed[1];
502 else
503 ospeed = -1;
504 CpuResumeIntr(state);
505 if ( v3 > 0xFFFF )
506 v3 = 0xFFFF;
507 if ( v3 == ospeed )
508 return 0;
509 memset(&u, 0, sizeof(u));
510 u.opcode = 0xbb;
511 u.lun = 0;
512 u.speed[0] = (v3 & 0xFF00) >> 8;
513 u.speed[1] = v3;
514 return acd_request_in(acd, 2, &u.pkt, 0, 0, 0, "setspeed");
515}
516
517static void acd_timer_done(acAtapiT atapi, struct acd_softc *arg, int ret)
518{
519 int v4;
520 acSpl state;
521
522 v4 = ret;
523 if ( ret >= 0 )
524 {
525 acCdvdsifId h_mtype;
526 acUint32 status;
527 int status_v3;
528
529 CpuSuspendIntr(&state);
530 h_mtype = arg->timer.md_h.h_mtype;
531 status = arg->status | 6;
532 arg->medium = h_mtype;
533 if ( h_mtype == 113 )
534 status_v3 = status ^ 4;
535 else
536 status_v3 = status ^ 2;
537 arg->status = status_v3 | 0x900;
538 v4 = arg->timer.md_timer & 0xF;
539 CpuResumeIntr(state);
540 }
541 acd_done((struct acd *)atapi, arg, v4);
542}
543
544int acd_gettimer(struct acd *acd)
545{
546 if ( !acd )
547 return -22;
548 return acd_mode_sense(acd, 13, &Acdc.timer, 16, (acAtapiDone)acd_timer_done, "gettimer");
549}
550
551int acd_settimer(struct acd *acd, int time)
552{
553 char v3;
554 int acdc;
555 int state;
556
557 v3 = time;
558 if ( acd == 0 )
559 {
560 return -22;
561 }
562 if ( (Acdc.status & 0x100) == 0 )
563 {
564 return -61;
565 }
566 CpuSuspendIntr(&state);
567 Acdc.timer.md_timer = v3 & 0xF;
568 acdc = ((Acdc.timer.md_h.h_len[0] << 8) + Acdc.timer.md_h.h_len[1] + 2);
569 CpuResumeIntr(state);
570 return acd_mode_select(acd, &Acdc.timer, acdc, (acAtapiDone)acd_timer_done, "settimer");
571}
572
573int acd_ready(struct acd *acd)
574{
576
577 if ( !acd )
578 return -22;
579 memset(&v2, 0, sizeof(v2));
580 return acd_request_in(acd, 2, &v2, 0, 0, 0, "ready");
581}
582
583int acd_readcapacity()
584{
585 int ret;
586 struct acd acd_data;
587 struct atapi_read_capacity capacity;
588 union
589 {
590 struct
591 {
592 acUint8 opcode;
593 acUint8 lun;
594 // cppcheck-suppress unusedStructMember
595 acUint8 padding1[10];
596 };
598 } u;
599
600 acd_setup(&acd_data, 0, 0, 5000000);
601 memset(&u, 0, sizeof(u));
602 u.opcode = 0x25;
603 u.lun = 0;
604 ret = acd_request_in(&acd_data, 2, &u.pkt, &capacity, 8, 0, "readcapacity");
605 if ( ret >= 0 )
606 {
607 unsigned int val;
608
609 val = *(unsigned int *)capacity.lba;
610 return (val << 24) + ((val & 0xFF00) << 8) + ((val >> 8) & 0xFF00) + ((val >> 24) & 0xFF);
611 }
612 return ret;
613}
614
615int acd_delay()
616{
618 u32 s;
619 u32 us;
620
621 GetSystemTime(&t);
622 SysClock2USec(&t, &s, &us);
623 if ( s >= 0xD )
624 return 0;
625 return 1000000 * (13 - s) - us;
626}
627
628int acd_getsense()
629{
630 return Acdc.sense;
631}
632
633acCdvdsifId acd_gettray()
634{
635 if ( (Acdc.status & 8) != 0 )
636 return 3;
637 if ( (Acdc.status & 2) != 0 )
638 return 1;
639 return (Acdc.status >> 1) & 2;
640}
641
642struct acd *acd_setup(struct acd *acd, acd_done_t done, void *arg, int tmout)
643{
644 if ( acd )
645 {
646 acd->c_done = done;
647 acd->c_arg = arg;
648 acd->c_thid = 0;
649 acd->c_tmout = tmout;
650 if ( !tmout )
651 acd->c_tmout = 5000000;
652 }
653 return acd;
654}
655
656int acd_sync(struct acd *acd, int nblocking, int *resultp)
657{
658 int ret;
659 acSpl state;
660
661 CpuSuspendIntr(&state);
662 ret = -11;
663 if ( !acd->c_thid )
664 {
665 int v7;
666
667 v7 = acAtapiStatus(&acd->c_atapi);
668 ret = v7;
669 if ( v7 > 0 )
670 {
671 ret = 0;
672 acd->c_thid = GetThreadId();
673 }
674 else if ( v7 == 0 )
675 {
676 ret = 1;
677 }
678 }
679 CpuResumeIntr(state);
680 if ( !(ret | nblocking) )
681 {
682 ret = 1;
683 SleepThread();
684 }
685 if ( ret > 0 && resultp )
686 {
687 *resultp = acd->c_thid;
688 }
689 return ret;
690}
691
692static void acd_ata_done(acAtaT ata, void *arg, int ret)
693{
694 int thid;
695 struct acd_ata *acdata;
696
697 (void)arg;
698 acdata = (struct acd_ata *)ata;
699 thid = acdata->a_thid;
700 acdata->a_result = ret;
701 if ( thid )
702 WakeupThread(thid);
703}
704
705int acd_ata_request(int flag, acAtaCommandT cmd, int items, acAtaDone done, char *name)
706{
707 int ret;
708 struct acd_ata acdata;
709
710 (void)name;
711 acAtaSetup(&acdata.a_ata, done ? done : acd_ata_done, 0, 0x4C4B40u);
712 // cppcheck-suppress unreadVariable
713 acdata.a_thid = GetThreadId();
714 acdata.a_result = 0;
715 ret = acAtaRequest(&acdata.a_ata, flag, cmd, items, 0, 0);
716 if ( ret < 0 )
717 {
718 return ret;
719 }
720 SleepThread();
721 return acdata.a_result;
722}
723
724static void acd_getstatus_done(acAtaT ata, void *arg, int ret)
725{
726 int thid;
727 struct acd_ata *acdata;
728 (void)arg;
729 acdata = (struct acd_ata *)ata;
730 if ( ret >= 0 )
731 ret = *(acUint8 *)acAtaReply(&acdata->a_ata);
732 thid = acdata->a_thid;
733 acdata->a_result = ret;
734 if ( thid )
735 WakeupThread(thid);
736}
737
738int acd_getstatus()
739{
740 acAtaCommandData v1[4];
741
742 v1[1] = 2021;
743 v1[0] = (Acdc.drive & 0xFF) | 0x2600;
744 return acd_ata_request(Acdc.drive | 2, v1, 2, acd_getstatus_done, "getstatus");
745}
746
747static int acd_setfeatures(int feature, int value)
748{
749 acAtaCommandData v3[4];
750
751 v3[2] = (value & 0xFF) | 0x200;
752 v3[1] = (feature & 0xFF) | 0x100;
753 v3[3] = 2031;
754 v3[0] = (Acdc.drive & 0xFF) | 0x600;
755 return acd_ata_request(Acdc.drive | 2, v3, 4, 0, "setfeatures");
756}
757
758int acd_setdma(acCdvdsifId dma)
759{
760 acCdvdsifId v1;
761 int mode;
762 int ret;
763 int ret_v3;
764
765 v1 = dma;
766 mode = dma;
767 if ( !dma )
768 {
769 Acdc.dma = AC_CDVDSIF_ID_NOP;
770 return 0;
771 }
772 if ( dma == 32 )
773 {
774 mode = 18;
775 ret_v3 = 0x40000;
776 while ( mode >= 0 )
777 {
778 if ( (Acdc.dmamap & ret_v3) != 0 )
779 break;
780 mode--;
781 ret_v3 = 1 << mode;
782 }
783 v1 = mode;
784 if ( mode < 0 )
785 return -134;
786 }
787 if ( (Acdc.dmamap & (1 << v1)) == 0 )
788 {
789 return -134;
790 }
791 if ( (unsigned int)v1 < AC_CDVDSIF_ID_PAUSES )
792 {
793 if ( (unsigned int)v1 < AC_CDVDSIF_ID_STOP )
794 {
795 if ( (unsigned int)v1 >= AC_CDVDSIF_ID_PAUSE )
796 mode = v1 + 8;
797 }
798 else
799 {
800 mode = v1 + 16;
801 }
802 }
803 else
804 {
805 mode = v1 + 40;
806 }
807 ret = acd_setfeatures(3, mode);
808 if ( ret < 0 )
809 {
810 return ret;
811 }
812 ret = acd_setfeatures(102, 0);
813 if ( ret < 0 )
814 {
815 return ret;
816 }
817 Acdc.dma = v1;
818 return v1;
819}
820
821acCdvdsifId acd_getdma()
822{
823 return Acdc.dma;
824}
825
826static int acd_identify(int drive)
827{
828 int flag;
829 int ret;
830 acUint16 ident[256];
831 struct acd_ata acdata;
832 acAtaCommandData cmd[2];
833
834 flag = 16 * (drive != 0);
835 cmd[0] = flag | 0x600;
836 cmd[1] = 1953;
837 acAtaSetup(&acdata.a_ata, acd_ata_done, 0, 0x4C4B40u);
838 // cppcheck-suppress unreadVariable
839 acdata.a_thid = GetThreadId();
840 acdata.a_result = 0;
841 ret = acAtaRequest(&acdata.a_ata, flag | 2, cmd, 2, ident, 512);
842 if ( ret >= 0 )
843 {
844 SleepThread();
845 ret = acdata.a_result;
846 }
847 if ( ret < 0 )
848 {
849 return ret;
850 }
851 if ( (ident[0] & 0xFF00) != 0x8500 )
852 return -6;
853 return ((ident[62] & 0xFF) << 8) | ((ident[63] & 0xFF) << 16) | ((ident[88] & 0xFF) << 24);
854}
855
856static int acd_softreset(int drive)
857{
858 (void)drive;
859
860 return 0;
861}
862
863int acd_module_status()
864{
865 int ret;
866 int state;
867
868 CpuSuspendIntr(&state);
869 ret = 0;
870 if ( (Acdc.status & 1) != 0 )
871 {
872 ret = 1;
873 if ( Acdc.active > 0 )
874 ret = 2;
875 }
876 CpuResumeIntr(state);
877 return ret;
878}
879
880int acd_module_start(int argc, char **argv)
881{
882 int ret;
883 int drive;
884 int ret_v2;
885
886 (void)argc;
887 (void)argv;
888 ret = acd_module_status();
889 drive = 0;
890 if ( ret )
891 {
892 return ret;
893 }
894 while ( 1 )
895 {
896 acd_softreset(drive);
897 ret_v2 = acd_identify(drive);
898 if ( ret_v2 >= 0 )
899 break;
900 ++drive;
901 ret = -6;
902 if ( drive >= 2 )
903 return ret;
904 }
905 if ( drive )
906 Acdc.drive = 16;
907 else
908 Acdc.drive = 0;
909 Acdc.status = 1;
910 Acdc.medium = -1;
911 Acdc.dmamap = ret_v2;
912 acd_setdma((acCdvdsifId)32);
913 return 0;
914}
915
916int acd_module_stop()
917{
918 int ret;
919
920 ret = acd_module_status();
921 if ( ret )
922 {
923 return ret;
924 }
925 Acdc.status = 0;
926 return 0;
927}
928
929int acd_module_restart(int argc, char **argv)
930{
931 (void)argc;
932 (void)argv;
933
934 return -88;
935}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
Definition acata.h:46