ArdSCSino.ino 16 KB

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