ArdSCSino.ino 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. /*
  2. * SCSI-HDデバイスエミュレータ
  3. */
  4. #include <SPI.h>
  5. #include "SdFat.h"
  6. //ENABLE_EXTENDED_TRANSFER_CLASSを1に設定する
  7. //libraries/SdFat/SdFatConfig.h
  8. SPIClass SPI_1(1);
  9. SdFatEX SD(&SPI_1);
  10. #define LOG(XX) //Serial.print(XX)
  11. #define LOGHEX(XX) //Serial.print(XX, HEX)
  12. #define LOGN(XX) //Serial.println(XX)
  13. #define LOGHEXN(XX) //Serial.println(XX, HEX)
  14. #define high 0
  15. #define low 1
  16. #define isHigh(XX) ((XX) == high)
  17. #define isLow(XX) ((XX) != high)
  18. #define gpio_mode(pin,val) gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, val);
  19. #define gpio_write(pin,val) gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, val)
  20. #define gpio_read(pin) gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit)
  21. //#define DB0 PB8 // SCSI:DB0
  22. //#define DB1 PB9 // SCSI:DB1
  23. //#define DB2 PB10 // SCSI:DB2
  24. //#define DB3 PB11 // SCSI:DB3
  25. //#define DB4 PB12 // SCSI:DB4
  26. //#define DB5 PB13 // SCSI:DB5
  27. //#define DB6 PB14 // SCSI:DB6
  28. //#define DB7 PB15 // SCSI:DB7
  29. //#define DBP PB0 // SCSI:DBP
  30. #define ATN PA8 // SCSI:ATN
  31. #define BSY PA9 // SCSI:BSY
  32. #define ACK PA10 // SCSI:ACK
  33. #define RST PA15 // SCSI:RST
  34. #define MSG PB3 // SCSI:MSG
  35. #define SEL PB4 // SCSI:SEL
  36. #define CD PB5 // SCSI:C/D
  37. #define REQ PB6 // SCSI:REQ
  38. #define IO PB7 // SCSI:I/O
  39. #define SD_CS PA4 // SDCARD:CS
  40. #define LED PC13 // LED
  41. #define SCSIID 0 // SCSI-ID
  42. #define BLOCKSIZE 512 // 1BLOCKサイズ
  43. uint8_t m_senseKey = 0; //センスキー
  44. volatile bool m_isBusReset = false; //バスリセット
  45. #define HDIMG_FILE "HD.HDS" // HDイメージファイル名
  46. File m_file; // ファイルオブジェクト
  47. uint32_t m_fileSize; // ファイルサイズ
  48. byte m_buf[BLOCKSIZE]; // 汎用バッファ
  49. int m_msc;
  50. bool m_msb[256];
  51. /*
  52. * IO読み込み.
  53. */
  54. inline byte readIO(void)
  55. {
  56. //GPIO(SCSI BUS)初期化
  57. //ポート設定レジスタ(下位)
  58. // GPIOB->regs->CRL |= 0x000000008; // SET INPUT W/ PUPD on PAB-PB0
  59. //ポート設定レジスタ(上位)
  60. GPIOB->regs->CRH = 0x88888888; // SET INPUT W/ PUPD on PB15-PB8
  61. // GPIOB->regs->ODR = 0x0000FF00; // SET PULL-UPs on PB15-PB8
  62. //ポート入力データレジスタ
  63. uint32 ret = GPIOB->regs->IDR;
  64. byte bret = 0x00;
  65. bret |= (!(ret & (1<<15))) << 7;
  66. bret |= (!(ret & (1<<14))) << 6;
  67. bret |= (!(ret & (1<<13))) << 5;
  68. bret |= (!(ret & (1<<12))) << 4;
  69. bret |= (!(ret & (1<<11))) << 3;
  70. bret |= (!(ret & (1<<10))) << 2;
  71. bret |= (!(ret & (1<<9))) << 1;
  72. bret |= (!(ret & (1<<8))) << 0;
  73. return bret;
  74. }
  75. /*
  76. * IO書き込み.
  77. */
  78. inline void writeIO(byte v)
  79. {
  80. //GPIO(SCSI BUS)初期化
  81. //ポート設定レジスタ(下位)
  82. GPIOB->regs->CRL |= 0x00000003; // SET OUTPUT W/ PUPD on PA7-PB0 50MHz
  83. //ポート設定レジスタ(上位)
  84. GPIOB->regs->CRH = 0x33333333; // SET OUTPUT W/ PUPD on PB15-PB8 50MHz
  85. // GPIOB->regs->ODR != 0x0000FF00; // SET PULL-UPs on PB15-PB8
  86. uint32 retL = 0x00;
  87. uint32 retH = 0x00;
  88. if(!parity(v)) {
  89. retL |= (1<<0);
  90. } else {
  91. retH |= (1<<0);
  92. }
  93. if(v & ( 1 << 7 )) {
  94. retL |= (1<<15);
  95. } else {
  96. retH |= (1<<15);
  97. }
  98. if(v & ( 1 << 6 )) {
  99. retL |= (1<<14);
  100. } else {
  101. retH |= (1<<14);
  102. }
  103. if(v & ( 1 << 5 )) {
  104. retL |= (1<<13);
  105. } else {
  106. retH |= (1<<13);
  107. }
  108. if(v & ( 1 << 4 )) {
  109. retL |= (1<<12);
  110. } else {
  111. retH |= (1<<12);
  112. }
  113. if(v & ( 1 << 3 )) {
  114. retL |= (1<<11);
  115. } else {
  116. retH |= (1<<11);
  117. }
  118. if(v & ( 1 << 2 )) {
  119. retL |= (1<<10);
  120. } else {
  121. retH |= (1<<10);
  122. }
  123. if(v & ( 1 << 1 )) {
  124. retL |= (1<<9);
  125. } else {
  126. retH |= (1<<9);
  127. }
  128. if(v & ( 1 << 0 )) {
  129. retL |= (1<<8);
  130. } else {
  131. retH |= (1<<8);
  132. }
  133. //ビットがLOWに設定される
  134. GPIOB->regs->BRR = retL ;
  135. // ビットがHIGHに設定される
  136. GPIOB->regs->BSRR = retH ;
  137. }
  138. /*
  139. * 初期化.
  140. * パリティチェック
  141. */
  142. inline int parity(byte val) {
  143. val ^= val >> 16;
  144. val ^= val >> 8;
  145. val ^= val >> 4;
  146. val ^= val >> 2;
  147. val ^= val >> 1;
  148. return val & 0x00000001;
  149. }
  150. /*
  151. * 初期化.
  152. * バスの初期化、PINの向きの設定を行う
  153. */
  154. void setup()
  155. {
  156. // PA15 / PB3 / PB4 が使えない
  157. // JTAG デバッグ用に使われているからです。
  158. disableDebugPorts();
  159. //シリアル初期化
  160. //Serial.begin(9600);
  161. //while (!Serial);
  162. //PINの初期化
  163. gpio_mode(LED, GPIO_OUTPUT_OD);
  164. gpio_write(LED, low);
  165. //GPIO(SCSI BUS)初期化
  166. //ポート設定レジスタ(下位)
  167. // GPIOB->regs->CRL |= 0x000000008; // SET INPUT W/ PUPD on PAB-PB0
  168. //ポート設定レジスタ(上位)
  169. GPIOB->regs->CRH = 0x88888888; // SET INPUT W/ PUPD on PB15-PB8
  170. // GPIOB->regs->ODR = 0x0000FF00; // SET PULL-UPs on PB15-PB8
  171. gpio_mode(ATN, GPIO_INPUT_PU);
  172. gpio_mode(BSY, GPIO_INPUT_PU);
  173. gpio_mode(ACK, GPIO_INPUT_PU);
  174. gpio_mode(RST, GPIO_INPUT_PU);
  175. gpio_mode(SEL, GPIO_INPUT_PU);
  176. gpio_mode(MSG, GPIO_OUTPUT_PP);
  177. gpio_mode(CD, GPIO_OUTPUT_PP);
  178. gpio_mode(REQ, GPIO_OUTPUT_PP);
  179. gpio_mode(IO, GPIO_OUTPUT_PP);
  180. gpio_write(MSG, low);
  181. gpio_write(CD, low);
  182. gpio_write(REQ, low);
  183. gpio_write(IO, low);
  184. //RSTピンの状態がHIGHからLOWに変わったときに発生
  185. attachInterrupt(PIN_MAP[RST].gpio_bit, onBusReset, FALLING);
  186. if(!SD.begin(SD_CS,SPI_FULL_SPEED)) {
  187. Serial.println("SD initialization failed!");
  188. onFalseInit();
  189. }
  190. //HDイメージファイル
  191. m_file = SD.open(HDIMG_FILE, O_RDWR);
  192. if(!m_file) {
  193. Serial.println("Error: open hdimg");
  194. onFalseInit();
  195. }
  196. m_fileSize = m_file.size();
  197. Serial.println("Found Valid HD Image File.");
  198. Serial.print(m_fileSize);
  199. Serial.println("byte");
  200. Serial.print(m_fileSize / 1024);
  201. Serial.println("KB");
  202. Serial.print(m_fileSize / 1024 / 1024);
  203. Serial.println("MB");
  204. }
  205. /*
  206. * 初期化失敗.
  207. */
  208. void onFalseInit(void)
  209. {
  210. while(true) {
  211. gpio_write(LED, high);
  212. delay(500);
  213. gpio_write(LED, low);
  214. delay(500);
  215. }
  216. }
  217. /*
  218. * バスリセット割り込み.
  219. */
  220. void onBusReset(void)
  221. {
  222. if(isHigh(gpio_read(RST))) {
  223. delayMicroseconds(20);
  224. if(isHigh(gpio_read(RST))) {
  225. LOGN("BusReset!");
  226. m_isBusReset = true;
  227. }
  228. }
  229. }
  230. /*
  231. * ハンドシェイクで読み込む.
  232. */
  233. byte readHandshake(void)
  234. {
  235. gpio_write(REQ, high);
  236. while(isLow(gpio_read(ACK))) {
  237. if(m_isBusReset) {
  238. return 0;
  239. }
  240. }
  241. byte r = readIO();
  242. gpio_write(REQ, low);
  243. while(isHigh(gpio_read(ACK))) {
  244. if(m_isBusReset) {
  245. return 0;
  246. }
  247. }
  248. return r;
  249. }
  250. /*
  251. * ハンドシェイクで書込み.
  252. */
  253. void writeHandshake(byte d)
  254. {
  255. writeIO(d);
  256. gpio_write(REQ, high);
  257. while(isLow(gpio_read(ACK))) {
  258. if(m_isBusReset) {
  259. return;
  260. }
  261. }
  262. gpio_write(REQ, low);
  263. while(isHigh(gpio_read(ACK))) {
  264. if(m_isBusReset) {
  265. return;
  266. }
  267. }
  268. }
  269. /*
  270. * データインフェーズ.
  271. * データ配列 p を len バイト送信する。
  272. */
  273. void writeDataPhase(int len, byte* p)
  274. {
  275. LOGN("DATAIN PHASE");
  276. gpio_write(MSG, low);
  277. gpio_write(CD, low);
  278. gpio_write(IO, high);
  279. for (int i = 0; i < len; i++) {
  280. if(m_isBusReset) {
  281. return;
  282. }
  283. writeHandshake(p[i]);
  284. }
  285. }
  286. /*
  287. * データインフェーズ.
  288. * SDカードからの読み込みながら len ブロック送信する。
  289. */
  290. void writeDataPhaseSD(uint32_t adds, uint32_t len)
  291. {
  292. LOGN("DATAIN PHASE(SD)");
  293. uint32_t pos = adds * BLOCKSIZE;
  294. m_file.seek(pos);
  295. gpio_write(MSG, low);
  296. gpio_write(CD, low);
  297. gpio_write(IO, high);
  298. for(uint32_t i = 0; i < len; i++) {
  299. m_file.read(m_buf, BLOCKSIZE);
  300. for(int j = 0; j < BLOCKSIZE; j++) {
  301. if(m_isBusReset) {
  302. return;
  303. }
  304. writeHandshake(m_buf[j]);
  305. }
  306. }
  307. }
  308. /*
  309. * データアウトフェーズ.
  310. * len ブロック読み込みながら SDカードへ書き込む。
  311. */
  312. void readDataPhaseSD(uint32_t adds, uint32_t len)
  313. {
  314. LOGN("DATAOUT PHASE(SD)");
  315. uint32_t pos = adds * BLOCKSIZE;
  316. m_file.seek(pos);
  317. gpio_write(MSG, low);
  318. gpio_write(CD, low);
  319. gpio_write(IO, low);
  320. for(uint32_t i = 0; i < len; i++) {
  321. for(int j = 0; j < BLOCKSIZE; j++) {
  322. if(m_isBusReset) {
  323. return;
  324. }
  325. m_buf[j] = readHandshake();
  326. }
  327. m_file.write(m_buf, BLOCKSIZE);
  328. }
  329. m_file.flush();
  330. }
  331. /*
  332. * INQUIRY コマンド処理.
  333. */
  334. void onInquiryCommand(byte len)
  335. {
  336. byte buf[36] = {
  337. 0x00, //デバイスタイプ
  338. 0x00, //RMB = 0
  339. 0x01, //ISO,ECMA,ANSIバージョン
  340. 0x01, //レスポンスデータ形式
  341. 35 - 4, //追加データ長
  342. 0, 0, //Reserve
  343. 0x00, //サポート機能
  344. 'T', 'N', 'B', ' ', ' ', ' ', ' ', ' ',
  345. 'A', 'r', 'd', 'S', 'C', 'S', 'i', 'n', 'o', ' ', ' ',' ', ' ', ' ', ' ', ' ',
  346. '0', '0', '1', '0',
  347. };
  348. writeDataPhase(len < 36 ? len : 36, buf);
  349. }
  350. /*
  351. * REQUEST SENSE コマンド処理.
  352. */
  353. void onRequestSenseCommand(byte len)
  354. {
  355. byte buf[18] = {
  356. 0x70, //CheckCondition
  357. 0, //セグメント番号
  358. 0x00, //センスキー
  359. 0, 0, 0, 0, //インフォメーション
  360. 17 - 7 , //追加データ長
  361. 0,
  362. };
  363. buf[2] = m_senseKey;
  364. m_senseKey = 0;
  365. writeDataPhase(len < 18 ? len : 18, buf);
  366. }
  367. /*
  368. * READ CAPACITY コマンド処理.
  369. */
  370. void onReadCapacityCommand(byte pmi)
  371. {
  372. uint32_t bc = m_fileSize / BLOCKSIZE;
  373. uint32_t bl = BLOCKSIZE;
  374. uint8_t buf[8] = {
  375. bc >> 24, bc >> 16, bc >> 8, bc,
  376. bl >> 24, bl >> 16, bl >> 8, bl
  377. };
  378. writeDataPhase(8, buf);
  379. }
  380. /*
  381. * READ6/10 コマンド処理.
  382. */
  383. byte onReadCommand(uint32_t adds, uint32_t len)
  384. {
  385. LOGN("-R");
  386. LOGHEXN(adds);
  387. LOGHEXN(len);
  388. gpio_write(LED, high);
  389. writeDataPhaseSD(adds, len);
  390. gpio_write(LED, low);
  391. return 0; //sts
  392. }
  393. /*
  394. * WRITE6/10 コマンド処理.
  395. */
  396. byte onWriteCommand(uint32_t adds, uint32_t len)
  397. {
  398. LOGN("-W");
  399. LOGHEXN(adds);
  400. LOGHEXN(len);
  401. gpio_write(LED, high);
  402. readDataPhaseSD(adds, len);
  403. gpio_write(LED, low);
  404. return 0; //sts
  405. }
  406. /*
  407. * MODE SENSE コマンド処理.
  408. */
  409. void onModeSenseCommand(byte dbd, int pageCode, uint32_t len)
  410. {
  411. memset(m_buf, 0, sizeof(m_buf));
  412. int a = 4;
  413. if(dbd == 0) {
  414. uint32_t bc = m_fileSize / BLOCKSIZE;
  415. uint32_t bl = BLOCKSIZE;
  416. byte c[8] = {
  417. 0,//デンシティコード
  418. bc >> 16, bc >> 8, bc,
  419. 0, //Reserve
  420. bl >> 16, bl >> 8, bl
  421. };
  422. memcpy(&m_buf[4], c, 8);
  423. a += 8;
  424. m_buf[3] = 0x08;
  425. }
  426. switch(pageCode) {
  427. case 0x3F:
  428. case 0x03: //ドライブパラメータ
  429. m_buf[a + 0] = 0x03; //ページコード
  430. m_buf[a + 1] = 0x16; // ページ長
  431. m_buf[a + 11] = 0x3F;//セクタ数/トラック
  432. a += 24;
  433. if(pageCode != 0x3F) {
  434. break;
  435. }
  436. case 0x04: //ドライブパラメータ
  437. {
  438. uint32_t bc = m_fileSize / BLOCKSIZE;
  439. m_buf[a + 0] = 0x04; //ページコード
  440. m_buf[a + 1] = 0x16; // ページ長
  441. m_buf[a + 2] = bc >> 16;// シリンダ長
  442. m_buf[a + 3] = bc >> 8;
  443. m_buf[a + 4] = bc;
  444. m_buf[a + 5] = 1; //ヘッド数
  445. a += 24;
  446. }
  447. if(pageCode != 0x3F) {
  448. break;
  449. }
  450. default:
  451. break;
  452. }
  453. m_buf[0] = a - 1;
  454. writeDataPhase(len < a ? len : a, m_buf);
  455. }
  456. /*
  457. * MsgIn2.
  458. */
  459. void MsgIn2(int msg)
  460. {
  461. LOGN("MsgIn2");
  462. gpio_write(MSG, high);
  463. gpio_write(CD, high);
  464. gpio_write(IO, high);
  465. writeHandshake(msg);
  466. }
  467. /*
  468. * MsgOut2.
  469. */
  470. void MsgOut2()
  471. {
  472. LOGN("MsgOut2");
  473. gpio_write(MSG, high);
  474. gpio_write(CD, high);
  475. gpio_write(IO, low);
  476. m_msb[m_msc] = readHandshake();
  477. m_msc++;
  478. m_msc %= 256;
  479. }
  480. /*
  481. * メインループ.
  482. */
  483. void loop()
  484. {
  485. int sts = 0;
  486. int msg = 0;
  487. //BSY,SELが+はバスフリー
  488. // セレクションチェック
  489. // BSYが-の間ループ
  490. if(isHigh(gpio_read(BSY))) {
  491. return;
  492. }
  493. // SELが+の間ループ
  494. if(isLow(gpio_read(SEL))) {
  495. return;
  496. }
  497. // BSY+ SEL-
  498. byte db = readIO();
  499. if((db & (1 << SCSIID)) == 0) {
  500. return;
  501. }
  502. LOGN("Selection");
  503. m_isBusReset = false;
  504. // セレクトされたらBSYを-にする
  505. gpio_mode(BSY, GPIO_OUTPUT_PP);
  506. gpio_write(BSY, high);
  507. while(isHigh(gpio_read(SEL))) {
  508. if(m_isBusReset) {
  509. goto BusFree;
  510. }
  511. }
  512. if(isHigh(gpio_read(ATN))) {
  513. bool syncenable = false;
  514. int syncperiod = 50;
  515. int syncoffset = 0;
  516. m_msc = 0;
  517. memset(m_msb, 0x00, sizeof(m_msb));
  518. while(isHigh(gpio_read(ATN))) {
  519. MsgOut2();
  520. }
  521. for(int i = 0; i < m_msc; i++) {
  522. // ABORT
  523. if (m_msb[i] == 0x06) {
  524. goto BusFree;
  525. }
  526. // BUS DEVICE RESET
  527. if (m_msb[i] == 0x0C) {
  528. syncoffset = 0;
  529. goto BusFree;
  530. }
  531. // IDENTIFY
  532. if (m_msb[i] >= 0x80) {
  533. }
  534. // 拡張メッセージ
  535. if (m_msb[i] == 0x01) {
  536. // 同期転送が可能な時だけチェック
  537. if (!syncenable || m_msb[i + 2] != 0x01) {
  538. MsgIn2(0x07);
  539. break;
  540. }
  541. // Transfer period factor(50 x 4 = 200nsに制限)
  542. syncperiod = m_msb[i + 3];
  543. if (syncperiod > 50) {
  544. syncoffset = 50;
  545. }
  546. // REQ/ACK offset(16に制限)
  547. syncoffset = m_msb[i + 4];
  548. if (syncoffset > 16) {
  549. syncoffset = 16;
  550. }
  551. // STDR応答メッセージ生成
  552. MsgIn2(0x01);
  553. MsgIn2(0x03);
  554. MsgIn2(0x01);
  555. MsgIn2(syncperiod);
  556. MsgIn2(syncoffset);
  557. break;
  558. }
  559. }
  560. }
  561. LOGN("Command");
  562. gpio_write(MSG, low);
  563. gpio_write(CD, high);
  564. gpio_write(IO, low);
  565. int len;
  566. byte cmd[12];
  567. cmd[0] = readHandshake();
  568. LOGHEX(cmd[0]);
  569. len = 1;
  570. switch(cmd[0] >> 5) {
  571. case 0b000:
  572. len = 6;
  573. break;
  574. case 0b001:
  575. len = 10;
  576. break;
  577. case 0b010:
  578. len = 10;
  579. break;
  580. case 0b101:
  581. len = 12;
  582. break;
  583. default:
  584. break;
  585. }
  586. for(int i = 1; i < len; i++ ) {
  587. cmd[i] = readHandshake();
  588. LOGHEX(cmd[i]);
  589. }
  590. LOGN("");
  591. switch(cmd[0]) {
  592. case 0x00:
  593. LOGN("[Test Unit]");
  594. break;
  595. case 0x01:
  596. LOGN("[Rezero Unit]");
  597. break;
  598. case 0x03:
  599. LOGN("[RequestSense]");
  600. onRequestSenseCommand(cmd[4]);
  601. break;
  602. case 0x04:
  603. LOGN("[FormatUnit]");
  604. break;
  605. case 0x06:
  606. LOGN("[FormatUnit]");
  607. break;
  608. case 0x07:
  609. LOGN("[ReassignBlocks]");
  610. break;
  611. case 0x08:
  612. LOGN("[Read6]");
  613. sts = onReadCommand((((uint32_t)cmd[1] & 0x1F) << 16) | ((uint32_t)cmd[2] << 8) | cmd[3], (cmd[4] == 0) ? 0x100 : cmd[4]);
  614. break;
  615. case 0x0A:
  616. LOGN("[Write6]");
  617. sts = onWriteCommand((((uint32_t)cmd[1] & 0x1F) << 16) | ((uint32_t)cmd[2] << 8) | cmd[3], (cmd[4] == 0) ? 0x100 : cmd[4]);
  618. break;
  619. case 0x0B:
  620. LOGN("[Seek6]");
  621. break;
  622. case 0x12:
  623. LOGN("[Inquiry]");
  624. onInquiryCommand(cmd[4]);
  625. break;
  626. case 0x1A:
  627. LOGN("[ModeSense6]");
  628. onModeSenseCommand(cmd[1]&0x80, cmd[2] & 0x3F, cmd[4]);
  629. break;
  630. case 0x1B:
  631. LOGN("[StartStopUnit]");
  632. break;
  633. case 0x1E:
  634. LOGN("[PreAllowMed.Removal]");
  635. break;
  636. case 0x25:
  637. LOGN("[ReadCapacity]");
  638. onReadCapacityCommand(cmd[8]);
  639. break;
  640. case 0x28:
  641. LOGN("[Read10]");
  642. sts = onReadCommand(((uint32_t)cmd[2] << 24) | ((uint32_t)cmd[3] << 16) | ((uint32_t)cmd[4] << 8) | cmd[5], ((uint32_t)cmd[7] << 8) | cmd[8]);
  643. break;
  644. case 0x2A:
  645. LOGN("[Write10]");
  646. sts = onWriteCommand(((uint32_t)cmd[2] << 24) | ((uint32_t)cmd[3] << 16) | ((uint32_t)cmd[4] << 8) | cmd[5], ((uint32_t)cmd[7] << 8) | cmd[8]);
  647. break;
  648. case 0x2B:
  649. LOGN("[Seek10]");
  650. break;
  651. case 0x5A:
  652. LOGN("[ModeSense10]");
  653. onModeSenseCommand(cmd[1] & 0x80, cmd[2] & 0x3F, ((uint32_t)cmd[7] << 8) | cmd[8]);
  654. break;
  655. default:
  656. LOGN("[*Unknown]");
  657. sts = 2;
  658. m_senseKey = 5;
  659. break;
  660. }
  661. if(m_isBusReset) {
  662. goto BusFree;
  663. }
  664. LOGN("Sts");
  665. gpio_write(MSG, low);
  666. gpio_write(CD, high);
  667. gpio_write(IO, high);
  668. writeHandshake(sts);
  669. if(m_isBusReset) {
  670. goto BusFree;
  671. }
  672. LOGN("MsgIn");
  673. gpio_write(MSG, high);
  674. gpio_write(CD, high);
  675. gpio_write(IO, high);
  676. writeHandshake(msg);
  677. BusFree:
  678. LOGN("BusFree");
  679. m_isBusReset = false;
  680. gpio_write(REQ, low);
  681. gpio_write(MSG, low);
  682. gpio_write(CD, low);
  683. gpio_write(IO, low);
  684. // gpio_write(BSY, low);
  685. gpio_mode(BSY, GPIO_INPUT_PU);
  686. }