Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanKensa/common/cmd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Sat Jan 14 15:42:25 2006 UTC (18 years, 2 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +10 -6 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * 円盤複写屋 - EnbanKensa
3 * Copyright (C) 2005 Kagetani Hideto
4 * cmd.c - MMCコマンド送信関数群
5 * $Date: 2005/12/11 15:25:30 $
6 * $Revision: 1.5 $
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #if !defined(WIN32)
12 # include <unistd.h>
13 #endif
14 #include "struct.h"
15 #include "cmd.h"
16 #include "ui.h"
17 #include "text.h"
18
19 WORD Get2bytes(BYTE *buf)
20 {
21 return (WORD)buf[0]<<8 | buf[1];
22 }
23
24 DWORD Get3bytes(BYTE *buf)
25 {
26 return (DWORD)buf[0]<<16 | (DWORD)buf[1]<<8 | buf[2];
27 }
28
29 DWORD Get4bytes(BYTE *buf)
30 {
31 return (DWORD)buf[0]<<24 | (DWORD)buf[1]<<16 | (DWORD)buf[2]<<8 | buf[3];
32 }
33
34 void Set2bytes(BYTE *buf, WORD value)
35 {
36 buf[0] = (BYTE)(value>>8);
37 buf[1] = (BYTE)value;
38 }
39
40 void Set3bytes(BYTE *buf, DWORD value)
41 {
42 buf[0] = (BYTE)(value>>16);
43 buf[1] = (BYTE)(value>>8);
44 buf[2] = (BYTE)value;
45 }
46
47 void Set4bytes(BYTE *buf, DWORD value)
48 {
49 buf[0] = (BYTE)(value>>24);
50 buf[1] = (BYTE)(value>>16);
51 buf[2] = (BYTE)(value>>8);
52 buf[3] = (BYTE)value;
53 }
54
55
56 DWORD MSF2LBA(BYTE min, BYTE sec, BYTE frame, BOOL force_positive)
57 {
58 DWORD ret = min*60 + sec;
59 ret *= 75;
60 ret += frame;
61 if(min < 90 || force_positive)
62 ret -= 150;
63 else
64 ret -= 450150;
65 return ret;
66 }
67
68 BOOL LBA2MSF(DWORD lba, BYTE *min, BYTE *sec, BYTE *frame)
69 {
70 BYTE m, s, f;
71
72 if(lba >= (DWORD)-150 || lba < 405000){
73 m = (BYTE)((lba+150)/60/75);
74 s = (BYTE)((lba+150 - m*60*75)/75);
75 f = (BYTE)(lba+150 - m*60*75 - s*75);
76 }
77 else if(lba>=(DWORD)-45150 && lba<=(DWORD)-151){
78 m = (BYTE)((lba+450150)/60/75);
79 s = (BYTE)((lba+450150 - m*60*75)/75);
80 f = (BYTE)(lba+450150 - m*60*75 - s*75);
81 }
82 else{
83 *min = 0xff;
84 *sec = 0xff;
85 *frame = 0xff;
86 return FALSE;
87 }
88
89 *min = m;
90 *sec = s;
91 *frame = f;
92
93 if(lba>404849)
94 return FALSE;
95 return TRUE;
96 }
97
98
99
100 int SendTestUnitReady(CMDDRIVE *drive)
101 {
102 BYTE cdb[12];
103
104 memset(cdb, 0, sizeof(cdb));
105 return SendCmd(drive, cdb, 0, REQ_NODATA);
106 }
107
108 int SendStartStop(CMDDRIVE *drive, BYTE immed, BYTE load_eject, BYTE start_or_load)
109 {
110 BYTE cdb[12];
111
112 memset(cdb, 0, sizeof(cdb));
113 cdb[0] = CMD_START_STOP;
114 cdb[1] = (BYTE)(immed ? 1:0);
115 cdb[4] = (BYTE)((load_eject ? 2:0)|(start_or_load ? 1:0));
116 return SendCmd(drive, cdb, 0, REQ_NODATA);
117 }
118
119 int SendPreventAllow(CMDDRIVE *drive, BYTE prevent)
120 {
121 BYTE cdb[12];
122
123 memset(cdb, 0, sizeof(cdb));
124 cdb[0] = CMD_PREVENT_ALLOW;
125 cdb[4] = (BYTE)(prevent ? 1:0);
126 return SendCmd(drive, cdb, 0, REQ_NODATA);
127 }
128
129 int SendModeSense(CMDDRIVE *drive, BYTE page_control, BYTE page_code)
130 {
131 BYTE cdb[12];
132 WORD len;
133 int ret;
134
135 len = drive->cmd_type==CMDDRVCTYPE_ATAPI ? 8:16;
136
137 memset(cdb, 0, sizeof(cdb));
138 cdb[0] = CMD_MODE_SENSE10;
139 cdb[2] = (BYTE)(page_control<<6 | page_code);
140 Set2bytes(cdb+7, len);
141 ret = SendCmd(drive, cdb, len, REQ_DATAIN);
142 if(ret!=RET_OK){
143 return ret;
144 }
145 len = Get2bytes(drive->data_buf) + 2;
146 Set2bytes(cdb+7, len);
147 return SendCmd(drive, cdb, len, REQ_DATAIN);
148 }
149
150 int SendModeSelect(CMDDRIVE *drive, BYTE pf)
151 {
152 BYTE cdb[12];
153 WORD len;
154 struct _MODEPAGE_HEADER *mph;
155
156 mph = (struct _MODEPAGE_HEADER *)
157 (drive->data_buf+(drive->cmd_type==CMDDRVCTYPE_ATAPI ? 8:16));
158 len = mph->p_len + (drive->cmd_type==CMDDRVCTYPE_ATAPI ? 8:16) + 2;
159 memset(drive->data_buf, 0, drive->cmd_type==CMDDRVCTYPE_ATAPI ? 8:16);
160
161 memset(cdb, 0, sizeof(cdb));
162 cdb[0] = CMD_MODE_SELECT10;
163 cdb[1] = (BYTE)(pf ? 0x10:0);
164 Set2bytes(cdb+7, len);
165 return SendCmd(drive, cdb, len, REQ_DATAOUT);
166 }
167
168 int SendReadToc(CMDDRIVE *drive, WORD track_sess_num, BYTE msf, BYTE format)
169 {
170 BYTE cdb[12];
171 WORD len = 4;
172 int ret;
173
174 memset(cdb, 0, sizeof(cdb));
175 cdb[0] = CMD_READ_TOC;
176 cdb[1] = (BYTE)(msf ? 2:0);
177 cdb[2] = (BYTE)(format & 0x0f);
178 cdb[6] = (BYTE)(track_sess_num);
179 Set2bytes(cdb+7, len);
180 ret = SendCmd(drive, cdb, len, REQ_DATAIN);
181 if(ret!=RET_OK){
182 return ret;
183 }
184 len = Get2bytes(drive->data_buf);
185 len += 2;
186 Set2bytes(cdb+7, len);
187 return SendCmd(drive, cdb, len, REQ_DATAIN);
188 }
189
190
191 int SendReadDiscInfo(CMDDRIVE *drive)
192 {
193 BYTE cdb[12];
194 WORD len;
195 int ret;
196
197 memset(cdb, 0, sizeof(cdb));
198 cdb[0] = CMD_READ_DISC_INFO;
199 Set2bytes(cdb+7, 2);
200 ret = SendCmd(drive, cdb, 2, REQ_DATAIN);
201 if(ret!=RET_OK){
202 return ret;
203 }
204 len = Get2bytes(drive->data_buf) + 2;
205 Set2bytes(cdb+7, len);
206 memset(drive->data_buf, 0, sizeof(struct _DISCINFO));
207 return SendCmd(drive, cdb, len, REQ_DATAIN);
208 }
209
210
211 int SendReadTrackInfo(CMDDRIVE *drive, WORD track_num)
212 {
213 BYTE cdb[12];
214 WORD len = sizeof(struct _TRACKINFO);
215
216 memset(cdb, 0, sizeof(cdb));
217 cdb[0] = CMD_READ_TRACK_INFO;
218 cdb[1] = 0x01;
219 Set2bytes(cdb+4, track_num);
220 Set2bytes(cdb+7, len);
221 return SendCmd(drive, cdb, len, REQ_DATAIN);
222 }
223
224
225 int SendCloseTrackSession(CMDDRIVE *drive, BYTE immed, BYTE type, WORD track_num)
226 {
227 BYTE cdb[12];
228
229 memset(cdb, 0, sizeof(cdb));
230 cdb[0] = CMD_CLOSE_TRACK_SESSION;
231 cdb[1] = (BYTE)(immed ? 1:0);
232 cdb[2] = (BYTE)(type & 7);
233 Set2bytes(cdb+4, track_num);
234 return SendCmd(drive, cdb, 0, REQ_NODATA);
235 }
236
237 int SendReadSubchannel(CMDDRIVE *drive, BYTE track_num, BYTE msf, BYTE subq, BYTE format)
238 {
239 BYTE cdb[12];
240 WORD len=4;
241 int ret;
242
243 memset(cdb, 0, sizeof(cdb));
244 cdb[0] = CMD_READ_SUBCHANNEL;
245 cdb[1] = (BYTE)(msf ? 2:0);
246 cdb[2] = (BYTE)(subq ? 0x40:0);
247 cdb[3] = format;
248 cdb[6] = track_num;
249 Set2bytes(cdb+7, len);
250 ret = SendCmd(drive, cdb, len, REQ_DATAIN);
251 if(ret!=RET_OK)
252 return ret;
253 len = Get2bytes(drive->data_buf+2) + 4;
254 Set2bytes(cdb+7, len);
255 return SendCmd(drive, cdb, len, REQ_DATAIN);
256 }
257
258 int SendReadCD(CMDDRIVE *drive, DWORD addr, DWORD len)
259 {
260 BYTE cdb[12];
261
262 memset(cdb, 0, sizeof(cdb));
263 cdb[0] = CMD_READ_CD;
264 Set4bytes(cdb+2, addr);
265 Set3bytes(cdb+6, len);
266 cdb[9] = 0xf8;
267 return SendCmd(drive, cdb, len*2352, REQ_DATAIN);
268 }
269
270 int SendReadFormatCapacities(CMDDRIVE *drive)
271 {
272 BYTE cdb[12];
273 WORD len=4;
274 int ret;
275
276 memset(cdb, 0, sizeof(cdb));
277 cdb[0] = CMD_READ_FORMAT_CAPACITIES;
278 Set2bytes(cdb+7, len);
279 ret = SendCmd(drive, cdb, len, REQ_DATAIN);
280 if(ret!=RET_OK)
281 return ret;
282 len = drive->data_buf[3] + sizeof(struct _FORMATCAPA_HEADER) +
283 sizeof(struct _FORMATCURMAXDESC);
284 Set2bytes(cdb+7, len);
285 return SendCmd(drive, cdb, len, REQ_DATAIN);
286 }
287
288
289
290 int SendFormatUnit(CMDDRIVE *drive, BYTE fmtdata, BYTE cmplist, BYTE format_code, WORD len)
291 {
292 BYTE cdb[12];
293
294 memset(cdb, 0, sizeof(cdb));
295 cdb[0] = CMD_FORMAT_UNIT;
296 cdb[1] = (BYTE)((fmtdata ? 0x10:0)|(cmplist ? 8:0)|(format_code & 7));
297 return SendCmd(drive, cdb, len, REQ_DATAOUT);
298 }
299
300 int SendSetCdSpeed(CMDDRIVE *drive, WORD read_speed, WORD write_speed, BYTE rotctl)
301 {
302 BYTE cdb[12];
303
304 memset(cdb, 0, sizeof(cdb));
305 cdb[0] = CMD_SET_CD_SPEED;
306 cdb[1] = (BYTE)(rotctl & 3);
307 Set2bytes(cdb+2, read_speed);
308 Set2bytes(cdb+4, write_speed);
309 return SendCmd(drive, cdb, 0, REQ_NODATA);
310 }
311
312 int SendSetStreaming(CMDDRIVE *drive)
313 {
314 BYTE cdb[12];
315 WORD len = sizeof(struct _PERFORMANCEDESC);
316
317 memset(cdb, 0, sizeof(cdb));
318 cdb[0] = CMD_SET_STREAMING;
319 Set2bytes(cdb+9, len);
320 return SendCmd(drive, cdb, len, REQ_DATAOUT);
321 }
322
323
324 int SendSynchronizeCache(CMDDRIVE *drive, BYTE immed)
325 {
326 BYTE cdb[12];
327
328 memset(cdb, 0, sizeof(cdb));
329 cdb[0] = CMD_SYNCHRONIZE_CACHE;
330 cdb[1] = (BYTE)(immed ? 2:0);
331 return SendCmd(drive, cdb, 0, REQ_NODATA);
332 }
333
334 int SendReserveTrack(CMDDRIVE *drive, DWORD size)
335 {
336 BYTE cdb[12];
337
338 memset(cdb, 0, sizeof(cdb));
339 cdb[0] = CMD_RESERVE_TRACK;
340 Set4bytes(cdb+5, size);
341 return SendCmd(drive, cdb, 0, REQ_NODATA);
342 }
343
344 int SendRead10(CMDDRIVE *drive, DWORD lba, WORD len, DWORD buflen)
345 {
346 BYTE cdb[12];
347
348 memset(cdb, 0, sizeof(cdb));
349 cdb[0] = CMD_READ10;
350 Set4bytes(cdb+2, lba);
351 Set2bytes(cdb+7, len);
352 return SendCmd(drive, cdb, buflen, REQ_DATAIN);
353 }
354
355 int SendWrite10(CMDDRIVE *drive, DWORD lba, WORD len, DWORD buflen)
356 {
357 BYTE cdb[12];
358 int ret;
359
360 memset(cdb, 0, sizeof(cdb));
361 cdb[0] = CMD_WRITE10;
362 Set4bytes(cdb+2, lba);
363 Set2bytes(cdb+7, len);
364 while(TRUE){
365 ret = SendCmd(drive, cdb, buflen, REQ_DATAOUT);
366 if(ret!=RET_CMDERR)
367 break;
368 if(!(SD_ASC(drive)==0x04 && SD_ASCQ(drive)==0x08))
369 break;
370 }
371 return ret;
372 }
373
374 int SendSeek10(CMDDRIVE *drive, DWORD lba)
375 {
376 BYTE cdb[12];
377
378 memset(cdb, 0, sizeof(cdb));
379 cdb[0] = CMD_SEEK10;
380 Set4bytes(cdb+2, lba);
381 return SendCmd(drive, cdb, 0, REQ_NODATA);
382 }
383
384 int SendSendCueSheet(CMDDRIVE *drive, void *cuesheet, DWORD len)
385 {
386 BYTE cdb[12];
387
388 if(len >= (DWORD)drive->bufsize)
389 return RET_NG;
390
391 if(cuesheet!=NULL)
392 memcpy(drive->data_buf, cuesheet, len);
393
394 memset(cdb, 0, sizeof(cdb));
395 cdb[0] = CMD_SEND_CUE_SHEET;
396 Set3bytes(cdb+6, len);
397 return SendCmd(drive, cdb, len, REQ_DATAOUT);
398 }
399
400
401
402 int OpenTray(CMDDRIVE *drive)
403 {
404 SendPreventAllow(drive, 0);
405 return SendStartStop(drive, 1, 1, 0);
406 }
407
408 int CloseTray(CMDDRIVE *drive)
409 {
410 return SendStartStop(drive, 1, 1, 1);
411 }
412
413
414 int GetDiscType(CMDDRIVE *drive, int *disc_type_ret, BOOL bWaitDisc)
415 {
416 BYTE cdb[12];
417 int ret;
418 struct _FEATURE_HEADER *fh;
419 struct _DISCINFO *di;
420 int disc_type;
421
422 *disc_type_ret = DT_UNKNOWN;
423
424 ret = CheckReady(drive, bWaitDisc);
425 if(ret!=RET_OK){
426 return ret;
427 }
428
429 memset(cdb, 0, sizeof(cdb));
430 cdb[0] = CMD_GET_CONFIGURATION;
431 cdb[8] = 8;
432 ret = SendCmd(drive, cdb, 8, REQ_DATAIN);
433 if(ret==RET_OK){
434 fh = (struct _FEATURE_HEADER *)drive->data_buf;
435 disc_type = Get2bytes(fh->cur_profile);
436 *disc_type_ret = disc_type;
437 return RET_OK;
438 }
439 if(SD_SENSEKEY(drive)==5 && SD_ASC(drive)==0x20){
440 /* GET CONFIG コマンド未サポート */
441 ret = SendReadDiscInfo(drive);
442 if(ret!=RET_OK){
443 return ret;
444 }
445 di = (struct _DISCINFO *)drive->data_buf;
446 *disc_type_ret = di->erasable ? DT_CDRW : DT_CDR;
447 return RET_OK;
448 }
449
450 return ret;
451 }
452
453 int CheckReady(CMDDRIVE *drive, BOOL bWaitDisc)
454 {
455 int ret;
456 BOOL bGood=FALSE;
457 BOOL bEjected=FALSE;
458
459 while(bGood==FALSE){
460 if(UICheckAbort()){
461 return RET_ABORT;
462 }
463 ret = SendTestUnitReady(drive);
464 if(ret==RET_OK){
465 bGood=TRUE;
466 }
467 else{
468 if(SD_SENSEKEY(drive)==0x02 &&
469 SD_ASC(drive)==0x04 &&
470 SD_ASCQ(drive)==0x01){
471 /* becoming ready */
472 UIDispInfo(MSG_WAITING_READY
473 /*"準備ができるのを待っています"*/);
474 }
475 else if(SD_SENSEKEY(drive)==0x06 &&
476 SD_ASC(drive)==0x28 &&
477 SD_ASCQ(drive)==0x00){
478 /* medium change */
479 }
480 else if(SD_SENSEKEY(drive)==0x06 &&
481 SD_ASC(drive)==0x29 &&
482 SD_ASCQ(drive)==0x00){
483 /* power on, reset */
484 }
485 #if 0
486 else if(SD_SENSEKEY(drive)==0x02 &&
487 SD_ASC(drive)==0x3a &&
488 SD_ASCQ(drive)==0x00){
489 /* medium not present */
490 }
491 #endif
492 else{
493 if(bWaitDisc){
494 /* Ejectする */
495 if(bEjected==FALSE){
496 OpenTray(drive);
497 bEjected=TRUE;
498 UIDispInfo(MSG_INSERT_DISC
499 /*"ディスクを挿入してください"*/);
500 }
501 }
502 else{
503 return RET_NG;
504 }
505 }
506 #ifdef WIN32
507 Sleep(1000);
508 #else
509 sleep(1);
510 #endif
511 }
512 }
513 UIDispInfo("");
514
515 return RET_OK;
516 }
517
518 int BlankDisc(CMDDRIVE *drive, BYTE type)
519 {
520 BYTE cdb[12];
521 int ret;
522
523 memset(cdb, 0, sizeof(cdb));
524 cdb[0] = CMD_BLANK;
525 cdb[1] = (BYTE)(0x10|type);
526 ret = SendCmd(drive, cdb, 0, REQ_NODATA);
527 if(ret!=RET_OK){
528 return ret;
529 }
530
531 ret = WaitProgress(drive, MSG_QUICK_BLANK/*"高速消去"*/, FALSE);
532 return ret;
533 }
534
535
536 int WaitProgress(CMDDRIVE *drive, const char *message, BOOL meter1)
537 {
538 WORD indicator=0;
539 BOOL bGood=FALSE;
540 int ret;
541
542 #if 0
543 if(message!=NULL){
544 if(meter1)
545 UIMeter1Initialize(message);
546 else
547 UIMeter2Initialize(message);
548 }
549 #endif
550
551 while(bGood==FALSE){
552 if(UICheckAbort()){
553 return RET_ABORT;
554 }
555 //ret = SendTestUnitReady(drive);
556 ret = SendReadDiscInfo(drive);
557 if(ret==RET_OK){
558 bGood=TRUE;
559 }
560 else{
561 if(SD_SENSEKEY(drive)!=0x02){
562 return RET_CMDERR;
563 }
564 /* 消去中 */
565 if(drive->sense_data[15] & 0x80){
566 indicator = Get2bytes(drive->sense_data+16);
567 #if 0
568 if(message!=NULL){
569 if(meter1)
570 UIMeter1Update((int)((indicator*100+0x7fff)/0xffff));
571 else
572 UIMeter2Update((int)((indicator*100+0x7fff)/0xffff));
573 }
574 #endif
575 }
576 #if defined(WIN32)
577 Sleep(100);
578 #else
579 usleep(100*1000);
580 #endif
581 }
582 }
583
584 return RET_OK;
585 }
586
587 void DispCommandError(CMDDRIVE *drive)
588 {
589 char buf[80];
590
591 if(SD_SENSEKEY(drive)!=0){
592 sprintf(buf, MSG_COMMAND_ERROR
593 /*"コマンド実行エラー(%02Xh : %X/%02X/%02X)"*/,
594 drive->cmdcode,
595 SD_SENSEKEY(drive), SD_ASC(drive), SD_ASCQ(drive));
596 UIDispMessage(buf, UIDMT_ERROR);
597 }
598 }
599
600 /*
601 * READ CD コマンドで SUB-Q データを取得
602 */
603 int GetSubQ(CMDDRIVE *drive, DWORD lba, DWORD len)
604 {
605 BYTE cdb[12];
606
607 memset(cdb, 0, sizeof(cdb));
608 cdb[0] = CMD_READ_CD;
609 Set4bytes(cdb+2, lba);
610 Set3bytes(cdb+6, len);
611 cdb[10] = 2;
612 return SendCmd(drive, cdb, len*16, REQ_DATAIN);
613 }
614
615

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26