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