11#include "accdvd_internal.h"
32 tmout_v2 =
acd->c_tmout;
38 done(
acd,
acd->c_arg, ret);
43static void acd_atapi_done(
acAtapiT atapi,
void *arg,
int ret)
48 acd_done((
struct acd *)atapi, argt, ret);
52acd_request_in(
struct acd *
acd,
int flag,
acAtapiPacketT packet,
void *buffer,
int size, acAtapiDone done,
char *name)
65 if ( (Acdc.status & 1) == 0 )
75 acd->c_thid = GetThreadId();
77 acAtapiSetup(&
acd->c_atapi, done ? done : acd_atapi_done, &Acdc, ret);
91 status = acAtapiRequest(&
acd->c_atapi, v16, packet, buffer, size);
97 if ( Acdc.active < 0 )
110 status_v14 = SleepThread();
111 if ( status_v14 == -418 )
123 ret_v15 =
acd->c_thid;
124 acd->c_tmout = tmout;
128 acd->c_tmout = tmout;
136 acd_done((
struct acd *)atapi, arg, ret);
139int acd_read(
struct acd *
acd, acd_lsn_t lsn,
void *buf,
int sectors)
164 memset(&u, 0,
sizeof(u));
170 u.lba[0] = (lsn & 0xFF000000) >> 24;
171 u.lba[1] = (lsn & 0xFF0000) >> 16;
172 u.lba[2] = (lsn & 0xFF00) >> 8;
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");
179int acd_readtoc(
struct acd *
acd,
void *buf,
int size)
187 memset(&v4, 0,
sizeof(v4));
190 v4.u_b[7] = (size & 0xFF00) >> 8;
192 v4.u_w[2] = size & 0xFF;
193 return acd_request_in(
acd, 2, &v4, buf, size, 0,
"readtoc");
196int acd_seek(
struct acd *
acd, acd_lsn_t lsn)
202 memset(&v3, 0,
sizeof(v3));
204 v3.u_b[2] = (lsn & 0xFF000000) >> 24;
205 v3.u_b[3] = (lsn & 0xFF0000) >> 16;
206 v3.u_w[1] = (lsn & 0xFF00) >> 8;
209 return acd_request_in(
acd, 2, &v3, 0, 0, 0,
"seek");
219 arg->status = (arg->status | 6) ^ 4;
222 acd_done((
struct acd *)atapi, arg, ret);
232 arg->status = (arg->status | 6) ^ 2;
235 acd_done((
struct acd *)atapi, arg, ret);
238int acd_ioctl(
struct acd *
acd,
int cmd)
259 memset(&u, 0,
sizeof(u));
264 name =
"ioctl:seek+start";
266 else if ( (cmd & 5) != 0 )
269 u.imm = (cmd & 0x80) != 0;
271 if ( (cmd & 2) != 0 )
273 done = (acAtapiDone)acd_opentray_done;
274 if ( (cmd & 1) != 0 )
275 done = (acAtapiDone)acd_closetray_done;
277 name =
"ioctl:startstop";
283 return acd_request_in(
acd, 2, &u.pkt, 0, 0, done, name);
286static int acd_mode_sense(
struct acd *
acd,
int pgcode,
void *buffer,
int size, acAtapiDone done,
char *name)
290 memset(&v7, 0,
sizeof(v7));
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);
298static int acd_mode_select(
struct acd *
acd,
void *buffer,
int size, acAtapiDone done,
char *name)
302 memset(&v6, 0,
sizeof(v6));
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);
322 h_mtype = arg->retry.me_h.h_mtype;
323 status = arg->status | 6;
324 arg->medium = h_mtype;
325 if ( h_mtype == 113 )
329 arg->status = v7 | 0xA00;
332 acd_done((
struct acd *)atapi, arg, h_mtype);
335int acd_getmedium(
struct acd *
acd)
341 return acd_mode_sense(
acd, 1, &Acdc.retry, 20, (acAtapiDone)acd_getmedium_done,
"getmedium");
344 if ( (Acdc.status & 0x800) != 0 )
363 h_mtype = arg->retry.me_h.h_mtype;
364 status = arg->status | 6;
365 arg->medium = h_mtype;
366 if ( h_mtype == 113 )
370 arg->status = v8 | 0xA00;
371 me_rretry = arg->retry.me_rretry;
374 acd_done((
struct acd *)atapi, arg, me_rretry);
377int acd_getretry(
struct acd *
acd)
381 return acd_mode_sense(
acd, 1, &Acdc.retry, 20, (acAtapiDone)acd_retry_done,
"getretry");
384int acd_setretry(
struct acd *
acd,
int rretry)
393 if ( (Acdc.status & 0x200) == 0 )
399 if ( rretry != Acdc.retry.me_rretry )
401 Acdc.retry.me_rretry = rretry;
402 size = (Acdc.retry.me_h.h_len[0] << 8) + Acdc.retry.me_h.h_len[1] + 2;
407 return acd_mode_select(
acd, &Acdc.retry, size, (acAtapiDone)acd_retry_done,
"setretry");
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;
431 arg->status = v8 | 0xC00;
434 acd_done((
struct acd *)atapi, arg, v4);
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;
458 arg->status = v8 | 0xC00;
461 acd_done((
struct acd *)atapi, arg, v4);
464int acd_getspeed(
struct acd *
acd,
int maxspeed)
472 done = (acAtapiDone)acd_getspeed_done;
474 done = (acAtapiDone)acd_getmaxspeed_done;
475 return acd_mode_sense(
acd, 42, &Acdc.speed, 28, done,
"getspeed");
478int acd_setspeed(
struct acd *
acd,
int speed)
500 if ( (Acdc.status & 0x400) != 0 )
501 ospeed = (Acdc.speed.mc_speed[0] << 8) + Acdc.speed.mc_speed[1];
509 memset(&u, 0,
sizeof(u));
512 u.speed[0] = (v3 & 0xFF00) >> 8;
514 return acd_request_in(
acd, 2, &u.pkt, 0, 0, 0,
"setspeed");
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;
536 status_v3 = status ^ 2;
537 arg->status = status_v3 | 0x900;
538 v4 = arg->timer.md_timer & 0xF;
541 acd_done((
struct acd *)atapi, arg, v4);
544int acd_gettimer(
struct acd *
acd)
548 return acd_mode_sense(
acd, 13, &Acdc.timer, 16, (acAtapiDone)acd_timer_done,
"gettimer");
551int acd_settimer(
struct acd *
acd,
int time)
562 if ( (Acdc.status & 0x100) == 0 )
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);
570 return acd_mode_select(
acd, &Acdc.timer, acdc, (acAtapiDone)acd_timer_done,
"settimer");
573int acd_ready(
struct acd *
acd)
579 memset(&v2, 0,
sizeof(v2));
580 return acd_request_in(
acd, 2, &v2, 0, 0, 0,
"ready");
583int acd_readcapacity()
595 acUint8 padding1[10];
600 acd_setup(&acd_data, 0, 0, 5000000);
601 memset(&u, 0,
sizeof(u));
604 ret = acd_request_in(&acd_data, 2, &u.pkt, &capacity, 8, 0,
"readcapacity");
609 val = *(
unsigned int *)capacity.lba;
610 return (val << 24) + ((val & 0xFF00) << 8) + ((val >> 8) & 0xFF00) + ((val >> 24) & 0xFF);
622 SysClock2USec(&t, &s, &us);
625 return 1000000 * (13 - s) - us;
633acCdvdsifId acd_gettray()
635 if ( (Acdc.status & 8) != 0 )
637 if ( (Acdc.status & 2) != 0 )
639 return (Acdc.status >> 1) & 2;
642struct acd *acd_setup(
struct acd *
acd, acd_done_t done,
void *arg,
int tmout)
649 acd->c_tmout = tmout;
651 acd->c_tmout = 5000000;
656int acd_sync(
struct acd *
acd,
int nblocking,
int *resultp)
667 v7 = acAtapiStatus(&
acd->c_atapi);
672 acd->c_thid = GetThreadId();
680 if ( !(ret | nblocking) )
685 if ( ret > 0 && resultp )
687 *resultp =
acd->c_thid;
692static void acd_ata_done(
acAtaT ata,
void *arg,
int ret)
698 acdata = (
struct acd_ata *)ata;
699 thid = acdata->a_thid;
700 acdata->a_result = ret;
705int acd_ata_request(
int flag, acAtaCommandT cmd,
int items, acAtaDone done,
char *name)
711 acAtaSetup(&acdata.a_ata, done ? done : acd_ata_done, 0, 0x4C4B40u);
713 acdata.a_thid = GetThreadId();
715 ret = acAtaRequest(&acdata.a_ata, flag, cmd, items, 0, 0);
721 return acdata.a_result;
724static void acd_getstatus_done(
acAtaT ata,
void *arg,
int ret)
729 acdata = (
struct acd_ata *)ata;
731 ret = *(acUint8 *)acAtaReply(&acdata->a_ata);
732 thid = acdata->a_thid;
733 acdata->a_result = ret;
740 acAtaCommandData v1[4];
743 v1[0] = (Acdc.drive & 0xFF) | 0x2600;
744 return acd_ata_request(Acdc.drive | 2, v1, 2, acd_getstatus_done,
"getstatus");
747static int acd_setfeatures(
int feature,
int value)
749 acAtaCommandData v3[4];
751 v3[2] = (value & 0xFF) | 0x200;
752 v3[1] = (feature & 0xFF) | 0x100;
754 v3[0] = (Acdc.drive & 0xFF) | 0x600;
755 return acd_ata_request(Acdc.drive | 2, v3, 4, 0,
"setfeatures");
758int acd_setdma(acCdvdsifId dma)
769 Acdc.dma = AC_CDVDSIF_ID_NOP;
778 if ( (Acdc.dmamap & ret_v3) != 0 )
787 if ( (Acdc.dmamap & (1 << v1)) == 0 )
791 if ( (
unsigned int)v1 < AC_CDVDSIF_ID_PAUSES )
793 if ( (
unsigned int)v1 < AC_CDVDSIF_ID_STOP )
795 if ( (
unsigned int)v1 >= AC_CDVDSIF_ID_PAUSE )
807 ret = acd_setfeatures(3, mode);
812 ret = acd_setfeatures(102, 0);
821acCdvdsifId acd_getdma()
826static int acd_identify(
int drive)
832 acAtaCommandData cmd[2];
834 flag = 16 * (drive != 0);
835 cmd[0] = flag | 0x600;
837 acAtaSetup(&acdata.a_ata, acd_ata_done, 0, 0x4C4B40u);
839 acdata.a_thid = GetThreadId();
841 ret = acAtaRequest(&acdata.a_ata, flag | 2, cmd, 2, ident, 512);
845 ret = acdata.a_result;
851 if ( (ident[0] & 0xFF00) != 0x8500 )
853 return ((ident[62] & 0xFF) << 8) | ((ident[63] & 0xFF) << 16) | ((ident[88] & 0xFF) << 24);
856static int acd_softreset(
int drive)
863int acd_module_status()
870 if ( (Acdc.status & 1) != 0 )
873 if ( Acdc.active > 0 )
880int acd_module_start(
int argc,
char **argv)
888 ret = acd_module_status();
896 acd_softreset(drive);
897 ret_v2 = acd_identify(drive);
911 Acdc.dmamap = ret_v2;
912 acd_setdma((acCdvdsifId)32);
920 ret = acd_module_status();
929int acd_module_restart(
int argc,
char **argv)
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)