ArdSCSino.ino 15 KB

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