BlueSCSI.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043
  1. /*
  2. * BlueSCSI
  3. * Copyright (c) 2021 Eric Helgeson, Androda
  4. *
  5. * This file is free software: you may copy, redistribute and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation, either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This file is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see https://github.com/erichelgeson/bluescsi.
  17. *
  18. * This file incorporates work covered by the following copyright and
  19. * permission notice:
  20. *
  21. * Copyright (c) 2019 komatsu
  22. *
  23. * Permission to use, copy, modify, and/or distribute this software
  24. * for any purpose with or without fee is hereby granted, provided
  25. * that the above copyright notice and this permission notice appear
  26. * in all copies.
  27. *
  28. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  29. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  30. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  31. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  32. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  33. * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  34. * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  35. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  36. */
  37. #include <Arduino.h> // For Platform.IO
  38. #include <SdFat.h>
  39. #include <setjmp.h>
  40. #define DEBUG 0 // 0:No debug information output
  41. // 1: Debug information output to USB Serial
  42. // 2: Debug information output to LOG.txt (slow)
  43. // Log File
  44. #define VERSION "1.1-20220918-SNAPSHOT"
  45. #define LOG_FILENAME "LOG.txt"
  46. #include "BlueSCSI.h"
  47. #include "scsi_cmds.h"
  48. #include "scsi_sense.h"
  49. #include "scsi_status.h"
  50. #include "scsi_mode.h"
  51. #ifdef USE_STM32_DMA
  52. #warning "warning USE_STM32_DMA"
  53. #endif
  54. // SDFAT
  55. SdFs SD;
  56. FsFile LOG_FILE;
  57. volatile bool m_isBusReset = false; // Bus reset
  58. volatile bool m_resetJmp = false; // Call longjmp on reset
  59. jmp_buf m_resetJmpBuf;
  60. byte scsi_id_mask; // Mask list of responding SCSI IDs
  61. byte m_id; // Currently responding SCSI-ID
  62. byte m_lun; // Logical unit number currently responding
  63. byte m_sts; // Status byte
  64. byte m_msg; // Message bytes
  65. byte m_buf[MAX_BLOCKSIZE]; // General purpose buffer
  66. byte m_scsi_buf[SCSI_BUF_SIZE]; // Buffer for SCSI READ/WRITE Buffer
  67. unsigned m_scsi_buf_size = 0;
  68. byte m_msb[256]; // Command storage bytes
  69. SCSI_DEVICE scsi_device_list[NUM_SCSIID][NUM_SCSILUN]; // Maximum number
  70. SCSI_INQUIRY_DATA default_hdd, default_optical;
  71. // function table
  72. byte (*scsi_command_table[MAX_SCSI_COMMAND])(SCSI_DEVICE *dev, const byte *cdb);
  73. // scsi command functions
  74. SCSI_COMMAND_HANDLER(onUnimplemented);
  75. SCSI_COMMAND_HANDLER(onNOP);
  76. SCSI_COMMAND_HANDLER(onRequestSense);
  77. SCSI_COMMAND_HANDLER(onRead6);
  78. SCSI_COMMAND_HANDLER(onRead10);
  79. SCSI_COMMAND_HANDLER(onWrite6);
  80. SCSI_COMMAND_HANDLER(onWrite10);
  81. SCSI_COMMAND_HANDLER(onInquiry);
  82. SCSI_COMMAND_HANDLER(onReadCapacity);
  83. SCSI_COMMAND_HANDLER(onModeSense);
  84. SCSI_COMMAND_HANDLER(onModeSelect);
  85. SCSI_COMMAND_HANDLER(onVerify);
  86. SCSI_COMMAND_HANDLER(onReadBuffer);
  87. SCSI_COMMAND_HANDLER(onWriteBuffer);
  88. SCSI_COMMAND_HANDLER(onReZeroUnit);
  89. SCSI_COMMAND_HANDLER(onSendDiagnostic);
  90. SCSI_COMMAND_HANDLER(onReadDefectData);
  91. SCSI_COMMAND_HANDLER(onReadTOC);
  92. SCSI_COMMAND_HANDLER(onReadDVDStructure);
  93. SCSI_COMMAND_HANDLER(onReadDiscInformation);
  94. static uint32_t MSFtoLBA(const byte *msf);
  95. static void LBAtoMSF(const uint32_t lba, byte *msf);
  96. static void flashError(const unsigned error);
  97. void onBusReset(void);
  98. void initFileLog(int);
  99. void finalizeFileLog(void);
  100. void findDriveImages(FsFile root);
  101. /*
  102. * IO read.
  103. */
  104. inline byte readIO(void)
  105. {
  106. // Port input data register
  107. uint32_t ret = GPIOB->regs->IDR;
  108. byte bret = (byte)(~(ret>>8));
  109. #if READ_PARITY_CHECK
  110. if((db_bsrr[bret]^ret)&1)
  111. m_sts |= 0x01; // parity error
  112. #endif
  113. return bret;
  114. }
  115. // If config file exists, read the first three lines and copy the contents.
  116. // File must be well formed or you will get junk in the SCSI Vendor fields.
  117. void readSCSIDeviceConfig(SCSI_DEVICE *dev) {
  118. FsFile config_file = SD.open("scsi-config.txt", O_RDONLY);
  119. if (!config_file.isOpen()) {
  120. return;
  121. }
  122. SCSI_INQUIRY_DATA *iq = dev->inquiry_block;
  123. char vendor[9];
  124. memset(vendor, 0, sizeof(vendor));
  125. config_file.readBytes(vendor, sizeof(vendor));
  126. LOG_FILE.print("SCSI VENDOR: ");
  127. LOG_FILE.println(vendor);
  128. memcpy(&iq->vendor, vendor, 8);
  129. char product[17];
  130. memset(product, 0, sizeof(product));
  131. config_file.readBytes(product, sizeof(product));
  132. LOG_FILE.print("SCSI PRODUCT: ");
  133. LOG_FILE.println(product);
  134. memcpy(&iq->product, product, 16);
  135. char version[5];
  136. memset(version, 0, sizeof(version));
  137. config_file.readBytes(version, sizeof(version));
  138. LOG_FILE.print("SCSI VERSION: ");
  139. LOG_FILE.println(version);
  140. memcpy(&iq->revision, version, 4);
  141. config_file.close();
  142. }
  143. // read SD information and print to logfile
  144. void readSDCardInfo()
  145. {
  146. cid_t sd_cid;
  147. if(SD.card()->readCID(&sd_cid))
  148. {
  149. LOG_FILE.print("Sd MID:");
  150. LOG_FILE.print(sd_cid.mid, 16);
  151. LOG_FILE.print(" OID:");
  152. LOG_FILE.print(sd_cid.oid[0]);
  153. LOG_FILE.println(sd_cid.oid[1]);
  154. LOG_FILE.print("Sd Name:");
  155. LOG_FILE.print(sd_cid.pnm[0]);
  156. LOG_FILE.print(sd_cid.pnm[1]);
  157. LOG_FILE.print(sd_cid.pnm[2]);
  158. LOG_FILE.print(sd_cid.pnm[3]);
  159. LOG_FILE.println(sd_cid.pnm[4]);
  160. LOG_FILE.print("Sd Date:");
  161. LOG_FILE.print(sd_cid.mdtMonth());
  162. LOG_FILE.print("/");
  163. LOG_FILE.println(sd_cid.mdtYear());
  164. LOG_FILE.print("Sd Serial:");
  165. LOG_FILE.println(sd_cid.psn());
  166. LOG_FILE.sync();
  167. }
  168. }
  169. bool VerifyISOPVD(SCSI_DEVICE *dev, unsigned sector_size, bool mode2)
  170. {
  171. int seek = 16 * sector_size;
  172. if(sector_size > CDROM_COMMON_SECTORSIZE) seek += 16;
  173. if(mode2) seek += 8;
  174. bool ret = false;
  175. dev->m_file->seekSet(seek);
  176. dev->m_file->read(m_buf, 2048);
  177. ret = ((m_buf[0] == 1 && !strncmp((char *)&m_buf[1], "CD001", 5) && m_buf[6] == 1) ||
  178. (m_buf[8] == 1 && !strncmp((char *)&m_buf[9], "CDROM", 5) && m_buf[14] == 1));
  179. dev->m_file->rewind();
  180. return ret;
  181. }
  182. /*
  183. * Open HDD image file
  184. */
  185. bool hddimageOpen(SCSI_DEVICE *dev, FsFile *file,int id,int lun,int blocksize)
  186. {
  187. dev->m_fileSize= 0;
  188. dev->m_sector_offset = 0;
  189. dev->m_blocksize = blocksize;
  190. dev->m_rawblocksize = blocksize;
  191. dev->m_file = file;
  192. if(!dev->m_file->isOpen()) { goto failed; }
  193. dev->m_fileSize = dev->m_file->size();
  194. if(dev->m_fileSize < 1) {
  195. LOG_FILE.println(" - file is 0 bytes, can not use.");
  196. goto failed;
  197. }
  198. if(dev->m_type == SCSI_DEVICE_OPTICAL) {
  199. LOG_FILE.print(" CDROM");
  200. dev->m_blocksize = CDROM_COMMON_SECTORSIZE;
  201. // Borrowed from PCEM
  202. if(VerifyISOPVD(dev, CDROM_COMMON_SECTORSIZE, false)) {
  203. dev->m_rawblocksize = CDROM_COMMON_SECTORSIZE;
  204. dev->m_mode2 = false;
  205. } else if(VerifyISOPVD(dev, CDROM_RAW_SECTORSIZE, false)) {
  206. dev->m_rawblocksize = CDROM_RAW_SECTORSIZE;
  207. dev->m_mode2 = false;
  208. dev->m_raw = true;
  209. dev->m_sector_offset = 16;
  210. } else if(VerifyISOPVD(dev, 2336, true)) {
  211. dev->m_rawblocksize = 2336;
  212. dev->m_mode2 = true;
  213. } else if(VerifyISOPVD(dev, CDROM_RAW_SECTORSIZE, true)) {
  214. dev->m_rawblocksize = CDROM_RAW_SECTORSIZE;
  215. dev->m_mode2 = true;
  216. dev->m_raw = true;
  217. dev->m_sector_offset = 24;
  218. } else {
  219. // Last ditch effort
  220. // size must be less than 700MB
  221. if(dev->m_fileSize > 912579600) {
  222. goto failed;
  223. }
  224. dev->m_raw = true;
  225. if(!(dev->m_fileSize % CDROM_COMMON_SECTORSIZE)) {
  226. // try a multiple of 2048
  227. dev->m_blocksize = CDROM_COMMON_SECTORSIZE;
  228. dev->m_rawblocksize = CDROM_COMMON_SECTORSIZE;
  229. } else {
  230. // I give up!
  231. LOG_FILE.println(" InvalidISO");
  232. goto failed;
  233. }
  234. }
  235. } else {
  236. LOG_FILE.print(" HDD");
  237. }
  238. dev->m_blockcount = dev->m_fileSize / dev->m_blocksize;
  239. // check blocksize dummy file
  240. LOG_FILE.print(" / ");
  241. LOG_FILE.print(dev->m_fileSize);
  242. LOG_FILE.print("bytes / ");
  243. LOG_FILE.print(dev->m_fileSize / 1024);
  244. LOG_FILE.print("KiB / ");
  245. LOG_FILE.print(dev->m_fileSize / 1024 / 1024);
  246. LOG_FILE.println("MiB");
  247. if(dev->m_type == SCSI_DEVICE_OPTICAL) {
  248. LOG_FILE.print(" MODE2:");LOG_FILE.print(dev->m_mode2);
  249. LOG_FILE.print(" BlockSize:");LOG_FILE.println(dev->m_rawblocksize);
  250. }
  251. return true; // File opened
  252. failed:
  253. dev->m_file->close();
  254. dev->m_fileSize = dev->m_blocksize = 0; // no file
  255. delete dev->m_file;
  256. dev->m_file = NULL;
  257. return false;
  258. }
  259. /*
  260. * Initialization.
  261. * Initialize the bus and set the PIN orientation
  262. */
  263. void setup()
  264. {
  265. // PA15 / PB3 / PB4 Cannot be used
  266. // JTAG Because it is used for debugging.
  267. enableDebugPorts();
  268. // Setup BSRR table
  269. for (unsigned i = 0; i <= 255; i++) {
  270. db_bsrr[i] = DBP(i);
  271. }
  272. // Default all SCSI command handlers to onUnimplemented
  273. for(unsigned i = 0; i < MAX_SCSI_COMMAND; i++)
  274. {
  275. scsi_command_table[i] = onUnimplemented;
  276. }
  277. // SCSI commands that just need to return ok
  278. scsi_command_table[SCSI_FORMAT_UNIT4] = onNOP;
  279. scsi_command_table[SCSI_FORMAT_UNIT6] = onNOP;
  280. scsi_command_table[SCSI_REASSIGN_BLOCKS] = onNOP;
  281. scsi_command_table[SCSI_SEEK6] = onNOP;
  282. scsi_command_table[SCSI_SEEK10] = onNOP;
  283. scsi_command_table[SCSI_START_STOP_UNIT] = onNOP;
  284. scsi_command_table[SCSI_PREVENT_ALLOW_REMOVAL] = onNOP;
  285. scsi_command_table[SCSI_RELEASE] = onNOP;
  286. scsi_command_table[SCSI_RESERVE] = onNOP;
  287. scsi_command_table[SCSI_TEST_UNIT_READY] = onNOP;
  288. // SCSI commands that have handlers
  289. scsi_command_table[SCSI_REZERO_UNIT] = onReZeroUnit;
  290. scsi_command_table[SCSI_REQUEST_SENSE] = onRequestSense;
  291. scsi_command_table[SCSI_READ6] = onRead6;
  292. scsi_command_table[SCSI_READ10] = onRead10;
  293. scsi_command_table[SCSI_WRITE6] = onWrite6;
  294. scsi_command_table[SCSI_WRITE10] = onWrite10;
  295. scsi_command_table[SCSI_INQUIRY] = onInquiry;
  296. scsi_command_table[SCSI_READ_CAPACITY] = onReadCapacity;
  297. scsi_command_table[SCSI_MODE_SENSE6] = onModeSense;
  298. scsi_command_table[SCSI_MODE_SENSE10] = onModeSense;
  299. scsi_command_table[SCSI_MODE_SELECT6] = onModeSelect;
  300. scsi_command_table[SCSI_MODE_SELECT10] = onModeSelect;
  301. scsi_command_table[SCSI_VERIFY10] = onVerify;
  302. scsi_command_table[SCSI_READ_BUFFER] = onReadBuffer;
  303. scsi_command_table[SCSI_WRITE_BUFFER] = onWriteBuffer;
  304. scsi_command_table[SCSI_SEND_DIAG] = onSendDiagnostic;
  305. scsi_command_table[SCSI_READ_DEFECT_DATA] = onReadDefectData;
  306. scsi_command_table[SCSI_READ_TOC] = onReadTOC;
  307. scsi_command_table[SCSI_READ_DVD_STRUCTURE] = onReadDVDStructure;
  308. scsi_command_table[SCSI_READ_DISC_INFORMATION] = onReadDiscInformation;
  309. // clear and initialize default inquiry blocks
  310. // default SCSI HDD
  311. memset(&default_hdd, 0, sizeof(default_hdd));
  312. default_hdd.ansi_version = 1;
  313. default_hdd.response_format = 1;
  314. default_hdd.additional_length = 31;
  315. memcpy(&default_hdd.vendor, "QUANTUM", 7);
  316. memcpy(&default_hdd.product, "BLUESCSI F1", 11);
  317. memcpy(&default_hdd.revision, "1.0", 3);
  318. // default SCSI CDROM
  319. memset(&default_optical, 0, sizeof(default_optical));
  320. default_optical.peripheral_device_type = 5;
  321. default_optical.rmb = 1;
  322. default_optical.ansi_version = 1;
  323. default_optical.response_format = 1;
  324. default_optical.additional_length = 42;
  325. default_optical.sync = 1;
  326. memcpy(&default_optical.vendor, "BLUESCSI", 8);
  327. memcpy(&default_optical.product, "CD-ROM CDU-55S", 14);
  328. memcpy(&default_optical.revision, "1.9a", 4);
  329. default_optical.release = 0x20;
  330. memcpy(&default_optical.revision_date, "1995", 4);
  331. // Serial initialization
  332. #if DEBUG > 0
  333. Serial.begin(9600);
  334. // If using a USB->TTL monitor instead of USB serial monitor - you can uncomment this.
  335. //while (!Serial);
  336. #endif
  337. // PIN initialization
  338. gpio_mode(LED2, GPIO_OUTPUT_PP);
  339. gpio_mode(LED, GPIO_OUTPUT_OD);
  340. // Image Set Select Init
  341. gpio_mode(IMAGE_SELECT1, GPIO_INPUT_PU);
  342. gpio_mode(IMAGE_SELECT2, GPIO_INPUT_PU);
  343. pinMode(IMAGE_SELECT1, INPUT);
  344. pinMode(IMAGE_SELECT2, INPUT);
  345. int image_file_set = ((digitalRead(IMAGE_SELECT1) == LOW) ? 1 : 0) | ((digitalRead(IMAGE_SELECT2) == LOW) ? 2 : 0);
  346. LED_OFF();
  347. #ifdef XCVR
  348. // Transceiver Pin Initialization
  349. pinMode(TR_TARGET, OUTPUT);
  350. pinMode(TR_INITIATOR, OUTPUT);
  351. pinMode(TR_DBP, OUTPUT);
  352. TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT);
  353. #endif
  354. //GPIO(SCSI BUS)Initialization
  355. //Port setting register (lower)
  356. // GPIOB->regs->CRL |= 0x000000008; // SET INPUT W/ PUPD on PAB-PB0
  357. //Port setting register (upper)
  358. //GPIOB->regs->CRH = 0x88888888; // SET INPUT W/ PUPD on PB15-PB8
  359. // GPIOB->regs->ODR = 0x0000FF00; // SET PULL-UPs on PB15-PB8
  360. // DB and DP are input modes
  361. SCSI_DB_INPUT()
  362. #ifdef XCVR
  363. TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT);
  364. // Initiator port
  365. pinMode(ATN, INPUT);
  366. pinMode(BSY, INPUT);
  367. pinMode(ACK, INPUT);
  368. pinMode(RST, INPUT);
  369. pinMode(SEL, INPUT);
  370. TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT);
  371. // Target port
  372. pinMode(MSG, INPUT);
  373. pinMode(CD, INPUT);
  374. pinMode(REQ, INPUT);
  375. pinMode(IO, INPUT);
  376. TRANSCEIVER_IO_SET(vTR_TARGET,TR_INPUT);
  377. #else
  378. // Input port
  379. gpio_mode(ATN, GPIO_INPUT_PU);
  380. gpio_mode(BSY, GPIO_INPUT_PU);
  381. gpio_mode(ACK, GPIO_INPUT_PU);
  382. gpio_mode(RST, GPIO_INPUT_PU);
  383. gpio_mode(SEL, GPIO_INPUT_PU);
  384. // Output port
  385. gpio_mode(MSG, GPIO_OUTPUT_OD);
  386. gpio_mode(CD, GPIO_OUTPUT_OD);
  387. gpio_mode(REQ, GPIO_OUTPUT_OD);
  388. gpio_mode(IO, GPIO_OUTPUT_OD);
  389. // Turn off the output port
  390. SCSI_TARGET_INACTIVE()
  391. #endif
  392. //Occurs when the RST pin state changes from HIGH to LOW
  393. //attachInterrupt(RST, onBusReset, FALLING);
  394. // Try Full and half clock speeds.
  395. LED_ON();
  396. int mhz = 0;
  397. if (SD.begin(SdSpiConfig(PA4, DEDICATED_SPI, SD_SCK_MHZ(50), &SPI)))
  398. {
  399. mhz = 50;
  400. }
  401. else if (SD.begin(SdSpiConfig(PA4, DEDICATED_SPI, SD_SCK_MHZ(25), &SPI)))
  402. {
  403. mhz = 25;
  404. }
  405. LED_OFF();
  406. if(mhz == 0) {
  407. #if DEBUG > 0
  408. Serial.println("SD initialization failed!");
  409. #endif
  410. flashError(ERROR_NO_SDCARD);
  411. }
  412. initFileLog(mhz);
  413. readSDCardInfo();
  414. //HD image file open
  415. scsi_id_mask = 0x00;
  416. // Iterate over the root path in the SD card looking for candidate image files.
  417. FsFile root;
  418. char image_set_dir_name[] = "/ImageSetX/";
  419. image_set_dir_name[9] = char(image_file_set) + 0x30;
  420. root.open(image_set_dir_name);
  421. if (root.isDirectory()) {
  422. LOG_FILE.print("Looking for images in: ");
  423. LOG_FILE.println(image_set_dir_name);
  424. LOG_FILE.sync();
  425. } else {
  426. root.close();
  427. root.open("/");
  428. }
  429. findDriveImages(root);
  430. root.close();
  431. FsFile images_all_dir;
  432. images_all_dir.open("/ImageSetAll/");
  433. if (images_all_dir.isDirectory()) {
  434. LOG_FILE.println("Looking for images in: /ImageSetAll/");
  435. LOG_FILE.sync();
  436. findDriveImages(images_all_dir);
  437. }
  438. images_all_dir.close();
  439. // Error if there are 0 image files
  440. if(scsi_id_mask==0) {
  441. LOG_FILE.println("ERROR: No valid images found!");
  442. flashError(ERROR_FALSE_INIT);
  443. }
  444. finalizeFileLog();
  445. LED_OFF();
  446. //Occurs when the RST pin state changes from HIGH to LOW
  447. attachInterrupt(RST, onBusReset, FALLING);
  448. }
  449. void findDriveImages(FsFile root) {
  450. bool image_ready;
  451. FsFile *file = NULL;
  452. char path_name[MAX_FILE_PATH+1];
  453. root.getName(path_name, sizeof(path_name));
  454. SD.chdir(path_name);
  455. SCSI_DEVICE *dev = NULL;
  456. while (1) {
  457. // Directories can not be opened RDWR, so it will fail, but fails the same way with no file/dir, so we need to peek at the file first.
  458. FsFile file_test = root.openNextFile(O_RDONLY);
  459. char name[MAX_FILE_PATH+1];
  460. file_test.getName(name, MAX_FILE_PATH+1);
  461. // Skip directories and already open files.
  462. if(file_test.isDir() || strncmp(name, "LOG.txt", 7) == 0) {
  463. file_test.close();
  464. continue;
  465. }
  466. // If error there is no next file to open.
  467. if(file_test.getError() > 0) {
  468. file_test.close();
  469. break;
  470. }
  471. // Valid file, open for reading/writing.
  472. file = new FsFile(SD.open(name, O_RDWR));
  473. if(file && file->isFile()) {
  474. SCSI_DEVICE_TYPE device_type;
  475. if(tolower(name[1]) != 'd') {
  476. file->close();
  477. delete file;
  478. LOG_FILE.print("Not an image: ");
  479. LOG_FILE.println(name);
  480. continue;
  481. }
  482. switch (tolower(name[0])) {
  483. case 'h': device_type = SCSI_DEVICE_HDD;
  484. break;
  485. case 'c': device_type = SCSI_DEVICE_OPTICAL;
  486. break;
  487. default:
  488. file->close();
  489. delete file;
  490. LOG_FILE.print("Not an image: ");
  491. LOG_FILE.println(name);
  492. continue;
  493. }
  494. // Defaults for Hard Disks
  495. int id = 1; // 0 and 3 are common in Macs for physical HD and CD, so avoid them.
  496. int lun = 0;
  497. int blk = 512;
  498. // Positionally read in and coerase the chars to integers.
  499. // We only require the minimum and read in the next if provided.
  500. int file_name_length = strlen(name);
  501. if(file_name_length > 2) { // HD[N]
  502. int tmp_id = name[HDIMG_ID_POS] - '0';
  503. // If valid id, set it, else use default
  504. if(tmp_id > -1 && tmp_id < 8) {
  505. id = tmp_id;
  506. } else {
  507. LOG_FILE.print(name);
  508. LOG_FILE.println(" - bad SCSI id in filename, Using default ID 1");
  509. }
  510. }
  511. if(file_name_length > 3) { // HDN[N]
  512. int tmp_lun = name[HDIMG_LUN_POS] - '0';
  513. // If valid lun, set it, else use default
  514. if(tmp_lun == 0 || tmp_lun == 1) {
  515. lun = tmp_lun;
  516. } else {
  517. LOG_FILE.print(name);
  518. LOG_FILE.println(" - bad SCSI LUN in filename, Using default LUN ID 0");
  519. }
  520. }
  521. int blk1 = 0, blk2, blk3, blk4 = 0;
  522. if(file_name_length > 8) { // HD00_[111]
  523. blk1 = name[HDIMG_BLK_POS] - '0';
  524. blk2 = name[HDIMG_BLK_POS+1] - '0';
  525. blk3 = name[HDIMG_BLK_POS+2] - '0';
  526. if(file_name_length > 9) // HD00_NNN[1]
  527. blk4 = name[HDIMG_BLK_POS+3] - '0';
  528. }
  529. if(blk1 == 2 && blk2 == 5 && blk3 == 6) {
  530. blk = 256;
  531. } else if(blk1 == 1 && blk2 == 0 && blk3 == 2 && blk4 == 4) {
  532. blk = 1024;
  533. } else if(blk1 == 2 && blk2 == 0 && blk3 == 4 && blk4 == 8) {
  534. blk = 2048;
  535. }
  536. if(id < NUM_SCSIID && lun < NUM_SCSILUN) {
  537. dev = &scsi_device_list[id][lun];
  538. LOG_FILE.print(" - ");
  539. LOG_FILE.print(name);
  540. dev->m_type = device_type;
  541. image_ready = hddimageOpen(dev, file, id, lun, blk);
  542. if(image_ready) { // Marked as a responsive ID
  543. scsi_id_mask |= 1<<id;
  544. switch(dev->m_type)
  545. {
  546. case SCSI_DEVICE_HDD:
  547. // default SCSI HDD
  548. dev->inquiry_block = &default_hdd;
  549. break;
  550. case SCSI_DEVICE_OPTICAL:
  551. // default SCSI CDROM
  552. dev->inquiry_block = &default_optical;
  553. break;
  554. }
  555. readSCSIDeviceConfig(dev);
  556. }
  557. }
  558. }
  559. LOG_FILE.sync();
  560. }
  561. // cd .. before going back.
  562. SD.chdir("/");
  563. }
  564. /*
  565. * Setup initialization logfile
  566. */
  567. void initFileLog(int success_mhz) {
  568. LOG_FILE = SD.open(LOG_FILENAME, O_WRONLY | O_CREAT | O_TRUNC);
  569. LOG_FILE.println("BlueSCSI <-> SD - https://github.com/erichelgeson/BlueSCSI");
  570. LOG_FILE.print("VER: ");
  571. LOG_FILE.print(VERSION);
  572. LOG_FILE.println(BUILD_TAGS);
  573. LOG_FILE.print("DEBUG:");
  574. LOG_FILE.print(DEBUG);
  575. LOG_FILE.print(" SDFAT_FILE_TYPE:");
  576. LOG_FILE.println(SDFAT_FILE_TYPE);
  577. LOG_FILE.print("SdFat version: ");
  578. LOG_FILE.println(SD_FAT_VERSION_STR);
  579. LOG_FILE.print("Sd Format: ");
  580. switch(SD.vol()->fatType()) {
  581. case FAT_TYPE_EXFAT:
  582. LOG_FILE.println("exFAT");
  583. break;
  584. default:
  585. LOG_FILE.print("FAT 32/16/12 - Consider formatting the SD Card with exFAT for improved performance.");
  586. }
  587. LOG_FILE.print("SPI speed: ");
  588. LOG_FILE.print(success_mhz);
  589. LOG_FILE.println("Mhz");
  590. if(success_mhz == 25) {
  591. LOG_FILE.println("SPI running at half speed - read https://github.com/erichelgeson/BlueSCSI/wiki/Slow-SPI");
  592. }
  593. LOG_FILE.print("SdFat Max FileName Length: ");
  594. LOG_FILE.println(MAX_FILE_PATH);
  595. LOG_FILE.println("Initialized SD Card - let's go!");
  596. LOG_FILE.sync();
  597. }
  598. /*
  599. * Finalize initialization logfile
  600. */
  601. void finalizeFileLog() {
  602. // View support drive map
  603. LOG_FILE.print("ID");
  604. for(int lun=0;lun<NUM_SCSILUN;lun++)
  605. {
  606. LOG_FILE.print(":LUN");
  607. LOG_FILE.print(lun);
  608. }
  609. LOG_FILE.println(":");
  610. //
  611. for(int id=0;id<NUM_SCSIID;id++)
  612. {
  613. LOG_FILE.print(" ");
  614. LOG_FILE.print(id);
  615. for(int lun=0;lun<NUM_SCSILUN;lun++)
  616. {
  617. SCSI_DEVICE *dev = &scsi_device_list[id][lun];
  618. if( (lun<NUM_SCSILUN) && (dev->m_file))
  619. {
  620. LOG_FILE.print((dev->m_blocksize<1000) ? ": " : ":");
  621. LOG_FILE.print(dev->m_blocksize);
  622. }
  623. else
  624. LOG_FILE.print(":----");
  625. }
  626. LOG_FILE.println(":");
  627. }
  628. LOG_FILE.println("Finished initialization of SCSI Devices - Entering main loop.");
  629. LOG_FILE.sync();
  630. #if DEBUG < 2
  631. LOG_FILE.close();
  632. #endif
  633. }
  634. static void flashError(const unsigned error)
  635. {
  636. while(true) {
  637. for(uint8_t i = 0; i < error; i++) {
  638. LED_ON();
  639. delay(250);
  640. LED_OFF();
  641. delay(250);
  642. }
  643. delay(3000);
  644. }
  645. }
  646. /*
  647. * Return from exception and call longjmp
  648. */
  649. void __attribute__ ((noinline)) longjmpFromInterrupt(jmp_buf jmpb, int retval) __attribute__ ((noreturn));
  650. void longjmpFromInterrupt(jmp_buf jmpb, int retval) {
  651. // Address of longjmp with the thumb bit cleared
  652. const uint32_t longjmpaddr = ((uint32_t)longjmp) & 0xfffffffe;
  653. const uint32_t zero = 0;
  654. // Default PSR value, function calls don't require any particular value
  655. const uint32_t PSR = 0x01000000;
  656. // For documentation on what this is doing, see:
  657. // https://developer.arm.com/documentation/dui0552/a/the-cortex-m3-processor/exception-model/exception-entry-and-return
  658. // Stack frame needs to have R0-R3, R12, LR, PC, PSR (from bottom to top)
  659. // This is being set up to have R0 and R1 contain the parameters passed to longjmp, and PC is the address of the longjmp function.
  660. // This is using existing stack space, rather than allocating more, as longjmp is just going to unroll the stack even further.
  661. // 0xfffffff9 is the EXC_RETURN value to return to thread mode.
  662. asm (
  663. "str %0, [sp];\
  664. str %1, [sp, #4];\
  665. str %2, [sp, #8];\
  666. str %2, [sp, #12];\
  667. str %2, [sp, #16];\
  668. str %2, [sp, #20];\
  669. str %3, [sp, #24];\
  670. str %4, [sp, #28];\
  671. ldr lr, =0xfffffff9;\
  672. bx lr"
  673. :: "r"(jmpb),"r"(retval),"r"(zero), "r"(longjmpaddr), "r"(PSR)
  674. );
  675. }
  676. /*
  677. * Bus reset interrupt.
  678. */
  679. void onBusReset(void)
  680. {
  681. if(isHigh(gpio_read(RST))) {
  682. delayMicroseconds(20);
  683. if(isHigh(gpio_read(RST))) {
  684. // BUS FREE is done in the main process
  685. // gpio_mode(MSG, GPIO_OUTPUT_OD);
  686. // gpio_mode(CD, GPIO_OUTPUT_OD);
  687. // gpio_mode(REQ, GPIO_OUTPUT_OD);
  688. // gpio_mode(IO, GPIO_OUTPUT_OD);
  689. // Should I enter DB and DBP once?
  690. SCSI_DB_INPUT()
  691. LOGN("BusReset!");
  692. if (m_resetJmp) {
  693. m_resetJmp = false;
  694. // Jumping out of the interrupt handler, so need to clear the interupt source.
  695. uint8 exti = PIN_MAP[RST].gpio_bit;
  696. EXTI_BASE->PR = (1U << exti);
  697. longjmpFromInterrupt(m_resetJmpBuf, 1);
  698. } else {
  699. m_isBusReset = true;
  700. }
  701. }
  702. }
  703. }
  704. /*
  705. * Enable the reset longjmp, and check if reset fired while it was disabled.
  706. */
  707. void enableResetJmp(void) {
  708. m_resetJmp = true;
  709. if (m_isBusReset) {
  710. longjmp(m_resetJmpBuf, 1);
  711. }
  712. }
  713. /*
  714. * Read by handshake.
  715. */
  716. inline byte readHandshake(void)
  717. {
  718. SCSI_OUT(vREQ,active)
  719. //SCSI_DB_INPUT()
  720. while( ! SCSI_IN(vACK));
  721. byte r = readIO();
  722. SCSI_OUT(vREQ,inactive)
  723. while( SCSI_IN(vACK));
  724. return r;
  725. }
  726. /*
  727. * Write with a handshake.
  728. */
  729. inline void writeHandshake(byte d)
  730. {
  731. // This has a 400ns bus settle delay built in. Not optimal for multi-byte transfers.
  732. GPIOB->regs->BSRR = db_bsrr[d]; // setup DB,DBP (160ns)
  733. #ifdef XCVR
  734. TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT)
  735. #endif
  736. SCSI_DB_OUTPUT() // (180ns)
  737. // ACK.Fall to DB output delay 100ns(MAX) (DTC-510B)
  738. SCSI_OUT(vREQ,inactive) // setup wait (30ns)
  739. SCSI_OUT(vREQ,inactive) // setup wait (30ns)
  740. SCSI_OUT(vREQ,inactive) // setup wait (30ns)
  741. SCSI_OUT(vREQ,active) // (30ns)
  742. //while(!SCSI_IN(vACK)) { if(m_isBusReset){ SCSI_DB_INPUT() return; }}
  743. while(!SCSI_IN(vACK));
  744. // ACK.Fall to REQ.Raise delay 500ns(typ.) (DTC-510B)
  745. GPIOB->regs->BSRR = DBP(0xff); // DB=0xFF , SCSI_OUT(vREQ,inactive)
  746. // REQ.Raise to DB hold time 0ns
  747. SCSI_DB_INPUT() // (150ns)
  748. #ifdef XCVR
  749. TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT)
  750. #endif
  751. while( SCSI_IN(vACK));
  752. }
  753. #pragma GCC push_options
  754. #pragma GCC optimize ("-Os")
  755. /*
  756. * This loop is tuned to repeat the following pattern:
  757. * 1) Set REQ
  758. * 2) 5 cycles of work/delay
  759. * 3) Wait for ACK
  760. * Cycle time tunings are for 72MHz STM32F103
  761. * Alignment matters. For the 3 instruction wait loops,it looks like crossing
  762. * an 8 byte prefetch buffer can add 2 cycles of wait every branch taken.
  763. */
  764. void writeDataLoop(uint32_t blocksize, const byte* srcptr) __attribute__ ((aligned(8)));
  765. void writeDataLoop(uint32_t blocksize, const byte* srcptr)
  766. {
  767. #define REQ_ON() (port_b->BRR = req_bit);
  768. #define FETCH_BSRR_DB() (bsrr_val = bsrr_tbl[*srcptr++])
  769. #define REQ_OFF_DB_SET(BSRR_VAL) port_b->BSRR = BSRR_VAL;
  770. #define WAIT_ACK_ACTIVE() while((*port_a_idr>>(vACK&15)&1))
  771. #define WAIT_ACK_INACTIVE() while(!(*port_a_idr>>(vACK&15)&1))
  772. register const byte *endptr= srcptr + blocksize; // End pointer
  773. register const uint32_t *bsrr_tbl = db_bsrr; // Table to convert to BSRR
  774. register uint32_t bsrr_val; // BSRR value to output (DB, DBP, REQ = ACTIVE)
  775. register uint32_t req_bit = BITMASK(vREQ);
  776. register gpio_reg_map *port_b = PBREG;
  777. register volatile uint32_t *port_a_idr = &(GPIOA->regs->IDR);
  778. // Start the first bus cycle.
  779. FETCH_BSRR_DB();
  780. REQ_OFF_DB_SET(bsrr_val);
  781. REQ_ON();
  782. FETCH_BSRR_DB();
  783. WAIT_ACK_ACTIVE();
  784. REQ_OFF_DB_SET(bsrr_val);
  785. // Align the starts of the do/while and WAIT loops to an 8 byte prefetch.
  786. asm("nop.w;nop");
  787. do{
  788. WAIT_ACK_INACTIVE();
  789. REQ_ON();
  790. // 4 cycles of work
  791. FETCH_BSRR_DB();
  792. // Extra 1 cycle delay while keeping the loop within an 8 byte prefetch.
  793. asm("nop");
  794. WAIT_ACK_ACTIVE();
  795. REQ_OFF_DB_SET(bsrr_val);
  796. // Extra 1 cycle delay, plus 4 cycles for the branch taken with prefetch.
  797. asm("nop");
  798. }while(srcptr < endptr);
  799. WAIT_ACK_INACTIVE();
  800. // Finish the last bus cycle, byte is already on DB.
  801. REQ_ON();
  802. WAIT_ACK_ACTIVE();
  803. REQ_OFF_DB_SET(bsrr_val);
  804. WAIT_ACK_INACTIVE();
  805. }
  806. #pragma GCC pop_options
  807. /*
  808. * Data in phase.
  809. * Send len bytes of data array p.
  810. */
  811. void writeDataPhase(int len, const byte* p)
  812. {
  813. LOG(" DI ");
  814. SCSI_PHASE_CHANGE(SCSI_PHASE_DATAIN);
  815. // Bus settle delay 400ns. Following code was measured at 800ns before REQ asserted. STM32F103.
  816. #ifdef XCVR
  817. TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT)
  818. #endif
  819. SCSI_DB_OUTPUT()
  820. writeDataLoop(len, p);
  821. }
  822. /*
  823. * Data in phase.
  824. * Send len block while reading from SD card.
  825. */
  826. void writeDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
  827. {
  828. LOG (" DI(SD) ");
  829. SCSI_PHASE_CHANGE(SCSI_PHASE_DATAIN);
  830. //Bus settle delay 400ns, file.seek() measured at over 1000ns.
  831. uint64_t pos = (uint64_t)adds * dev->m_rawblocksize;
  832. dev->m_file->seekSet(pos);
  833. #ifdef XCVR
  834. TRANSCEIVER_IO_SET(vTR_DBP,TR_OUTPUT)
  835. #endif
  836. SCSI_DB_OUTPUT()
  837. for(uint32_t i = 0; i < len; i++) {
  838. // Asynchronous reads will make it faster ...
  839. m_resetJmp = false;
  840. dev->m_file->read(m_buf, dev->m_rawblocksize);
  841. enableResetJmp();
  842. writeDataLoop(dev->m_blocksize, &m_buf[dev->m_sector_offset]);
  843. }
  844. }
  845. #pragma GCC push_options
  846. #pragma GCC optimize ("-Os")
  847. /*
  848. * See writeDataLoop for optimization info.
  849. */
  850. void readDataLoop(uint32_t blockSize, byte* dstptr) __attribute__ ((aligned(16)));
  851. void readDataLoop(uint32_t blockSize, byte* dstptr)
  852. {
  853. register byte *endptr= dstptr + blockSize - 1;
  854. #define REQ_ON() (port_b->BRR = req_bit);
  855. #define REQ_OFF() (port_b->BSRR = req_bit);
  856. #define WAIT_ACK_ACTIVE() while((*port_a_idr>>(vACK&15)&1))
  857. #define WAIT_ACK_INACTIVE() while(!(*port_a_idr>>(vACK&15)&1))
  858. register uint32_t req_bit = BITMASK(vREQ);
  859. register gpio_reg_map *port_b = PBREG;
  860. register volatile uint32_t *port_a_idr = &(GPIOA->regs->IDR);
  861. REQ_ON();
  862. // Fastest alignment obtained by trial and error.
  863. // Wait loop is within an 8 byte prefetch buffer.
  864. asm("nop");
  865. do {
  866. WAIT_ACK_ACTIVE();
  867. uint32_t ret = port_b->IDR;
  868. REQ_OFF();
  869. *dstptr++ = ~(ret >> 8);
  870. // Move wait loop in to a single 8 byte prefetch buffer
  871. asm("nop;nop;nop");
  872. WAIT_ACK_INACTIVE();
  873. REQ_ON();
  874. // Extra 1 cycle delay
  875. asm("nop");
  876. } while(dstptr<endptr);
  877. WAIT_ACK_ACTIVE();
  878. uint32_t ret = GPIOB->regs->IDR;
  879. REQ_OFF();
  880. *dstptr = ~(ret >> 8);
  881. WAIT_ACK_INACTIVE();
  882. }
  883. #pragma GCC pop_options
  884. /*
  885. * Data out phase.
  886. * len block read
  887. */
  888. void readDataPhase(int len, byte* p)
  889. {
  890. LOG(" DO ");
  891. SCSI_PHASE_CHANGE(SCSI_PHASE_DATAOUT);
  892. // Bus settle delay 400ns. The following code was measured at 450ns before REQ asserted. STM32F103.
  893. readDataLoop(len, p);
  894. }
  895. /*
  896. * Data out phase.
  897. * Write to SD card while reading len block.
  898. */
  899. void readDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
  900. {
  901. LOG(" DO(SD) ");
  902. SCSI_PHASE_CHANGE(SCSI_PHASE_DATAOUT);
  903. //Bus settle delay 400ns, file.seek() measured at over 1000ns.
  904. uint64_t pos = (uint64_t)adds * dev->m_blocksize;
  905. dev->m_file->seekSet(pos);
  906. for(uint32_t i = 0; i < len; i++) {
  907. m_resetJmp = true;
  908. readDataLoop(dev->m_blocksize, m_buf);
  909. m_resetJmp = false;
  910. dev->m_file->write(m_buf, dev->m_blocksize);
  911. // If a reset happened while writing, break and let the flush happen before it is handled.
  912. if (m_isBusReset) {
  913. break;
  914. }
  915. }
  916. dev->m_file->flush();
  917. enableResetJmp();
  918. }
  919. /*
  920. * Data out phase.
  921. * Compare to SD card while reading len block.
  922. */
  923. void verifyDataPhaseSD(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
  924. {
  925. LOG(" DO(SD) ");
  926. SCSI_PHASE_CHANGE(SCSI_PHASE_DATAOUT);
  927. //Bus settle delay 400ns, file.seek() measured at over 1000ns.
  928. uint64_t pos = (uint64_t)adds * dev->m_blocksize;
  929. dev->m_file->seekSet(pos);
  930. for(uint32_t i = 0; i < len; i++) {
  931. readDataLoop(dev->m_blocksize, m_buf);
  932. // This has just gone through the transfer to make things work, a compare would go here.
  933. }
  934. }
  935. /*
  936. * MsgIn2.
  937. */
  938. void MsgIn2(int msg)
  939. {
  940. LOG(" MI:"); LOGHEX(msg); LOG(" ");
  941. SCSI_PHASE_CHANGE(SCSI_PHASE_MESSAGEIN);
  942. // Bus settle delay 400ns built in to writeHandshake
  943. writeHandshake(msg);
  944. }
  945. /*
  946. * Main loop.
  947. */
  948. void loop()
  949. {
  950. #ifdef XCVR
  951. // Reset all DB and Target pins, switch transceivers to input
  952. // Precaution against bugs or jumps which don't clean up properly
  953. SCSI_DB_INPUT();
  954. TRANSCEIVER_IO_SET(vTR_DBP,TR_INPUT)
  955. SCSI_TARGET_INACTIVE();
  956. TRANSCEIVER_IO_SET(vTR_INITIATOR,TR_INPUT)
  957. #endif
  958. //int msg = 0;
  959. m_msg = 0;
  960. m_lun = 0xff;
  961. SCSI_DEVICE *dev = (SCSI_DEVICE *)0; // HDD image for current SCSI-ID, LUN
  962. do {} while( SCSI_IN(vBSY) || !SCSI_IN(vSEL) || SCSI_IN(vRST));
  963. //do {} while( !SCSI_IN(vBSY) || SCSI_IN(vRST));
  964. // We're in ARBITRATION
  965. //LOG(" A:"); LOGHEX(readIO()); LOG(" ");
  966. //do {} while( SCSI_IN(vBSY) || !SCSI_IN(vSEL) || SCSI_IN(vRST));
  967. //LOG(" S:"); LOGHEX(readIO()); LOG(" ");
  968. // We're in SELECTION
  969. byte scsiid = readIO() & scsi_id_mask;
  970. if(SCSI_IN(vIO) || (scsiid) == 0) {
  971. delayMicroseconds(1);
  972. return;
  973. }
  974. // We've been selected
  975. #ifdef XCVR
  976. // Reconfigure target pins to output mode, after resetting their values
  977. GPIOB->regs->BSRR = 0x000000E8; // MSG, CD, REQ, IO
  978. // GPIOA->regs->BSRR = 0x00000200; // BSY
  979. #endif
  980. SCSI_TARGET_ACTIVE() // (BSY), REQ, MSG, CD, IO output turned on
  981. // Set BSY to-when selected
  982. SCSI_BSY_ACTIVE(); // Turn only BSY output ON, ACTIVE
  983. // Wait until SEL becomes inactive
  984. while(isHigh(gpio_read(SEL))) {}
  985. // Ask for a TARGET-ID to respond
  986. m_id = 31 - __builtin_clz(scsiid);
  987. m_isBusReset = false;
  988. if (setjmp(m_resetJmpBuf) == 1) {
  989. LOGN("Reset, going to BusFree");
  990. goto BusFree;
  991. }
  992. enableResetJmp();
  993. // In SCSI-2 this is mandatory, but in SCSI-1 it's optional
  994. if(isHigh(gpio_read(ATN))) {
  995. SCSI_PHASE_CHANGE(SCSI_PHASE_MESSAGEOUT);
  996. // Bus settle delay 400ns. Following code was measured at 350ns before REQ asserted. Added another 50ns. STM32F103.
  997. SCSI_PHASE_CHANGE(SCSI_PHASE_MESSAGEOUT);// 28ns delay STM32F103
  998. SCSI_PHASE_CHANGE(SCSI_PHASE_MESSAGEOUT);// 28ns delay STM32F103
  999. bool syncenable = false;
  1000. int syncperiod = 50;
  1001. int syncoffset = 0;
  1002. int msc = 0;
  1003. while(isHigh(gpio_read(ATN)) && msc < 255) {
  1004. m_msb[msc++] = readHandshake();
  1005. }
  1006. for(int i = 0; i < msc; i++) {
  1007. // ABORT
  1008. if (m_msb[i] == 0x06) {
  1009. goto BusFree;
  1010. }
  1011. // BUS DEVICE RESET
  1012. if (m_msb[i] == 0x0C) {
  1013. syncoffset = 0;
  1014. goto BusFree;
  1015. }
  1016. // IDENTIFY
  1017. if (m_msb[i] >= 0x80) {
  1018. m_lun = m_msb[i] & 0x1f;
  1019. }
  1020. // Extended message
  1021. if (m_msb[i] == 0x01) {
  1022. // Check only when synchronous transfer is possible
  1023. if (!syncenable || m_msb[i + 2] != 0x01) {
  1024. MsgIn2(0x07);
  1025. break;
  1026. }
  1027. // Transfer period factor(50 x 4 = Limited to 200ns)
  1028. syncperiod = m_msb[i + 3];
  1029. if (syncperiod > 50) {
  1030. syncperiod = 50;
  1031. }
  1032. // REQ/ACK offset(Limited to 16)
  1033. syncoffset = m_msb[i + 4];
  1034. if (syncoffset > 16) {
  1035. syncoffset = 16;
  1036. }
  1037. // STDR response message generation
  1038. MsgIn2(0x01);
  1039. MsgIn2(0x03);
  1040. MsgIn2(0x01);
  1041. MsgIn2(syncperiod);
  1042. MsgIn2(syncoffset);
  1043. break;
  1044. }
  1045. }
  1046. }
  1047. LOG("CMD:");
  1048. SCSI_PHASE_CHANGE(SCSI_PHASE_COMMAND);
  1049. // Bus settle delay 400ns. The following code was measured at 20ns before REQ asserted. Added another 380ns. STM32F103.
  1050. asm("nop;nop;nop;nop;nop;nop;nop;nop");// This asm causes some code reodering, which adds 270ns, plus 8 nop cycles for an additional 110ns. STM32F103
  1051. int len;
  1052. byte cmd[20];
  1053. cmd[0] = readHandshake();
  1054. // Atari ST ICD extension support
  1055. // It sends a 0x1F as a indicator there is a
  1056. // proper full size SCSI command byte to follow
  1057. // so just read it and re-read it again to get the
  1058. // real command byte
  1059. if(cmd[0] == SCSI_ICD_EXTENDED_CMD) { cmd[0] = readHandshake(); }
  1060. LOGHEX(cmd[0]);
  1061. // Command length selection, reception
  1062. static const int cmd_class_len[8]={6,10,10,6,6,12,6,6};
  1063. len = cmd_class_len[cmd[0] >> 5];
  1064. cmd[1] = readHandshake(); LOG(":");LOGHEX(cmd[1]);
  1065. cmd[2] = readHandshake(); LOG(":");LOGHEX(cmd[2]);
  1066. cmd[3] = readHandshake(); LOG(":");LOGHEX(cmd[3]);
  1067. cmd[4] = readHandshake(); LOG(":");LOGHEX(cmd[4]);
  1068. cmd[5] = readHandshake(); LOG(":");LOGHEX(cmd[5]);
  1069. // Receive the remaining commands
  1070. for(int i = 6; i < len; i++ ) {
  1071. cmd[i] = readHandshake();
  1072. LOG(":");
  1073. LOGHEX(cmd[i]);
  1074. }
  1075. // LUN confirmation
  1076. // if it wasn't set in the IDENTIFY then grab it from the CDB
  1077. if(m_lun > MAX_SCSILUN)
  1078. {
  1079. m_lun = (cmd[1] & 0xe0) >> 5;
  1080. }
  1081. LOG(":ID ");
  1082. LOG(m_id);
  1083. LOG(":LUN ");
  1084. LOG(m_lun);
  1085. LOG(" ");
  1086. // HDD Image selection
  1087. if(m_lun >= NUM_SCSILUN)
  1088. {
  1089. m_sts = SCSI_STATUS_GOOD;
  1090. // REQUEST SENSE and INQUIRY are handled different with invalid LUNs
  1091. if(cmd[0] == SCSI_INQUIRY)
  1092. {
  1093. // Special INQUIRY handling for invalid LUNs
  1094. LOGN("onInquiry - InvalidLUN");
  1095. dev = &(scsi_device_list[m_id][0]);
  1096. byte temp = dev->inquiry_block->raw[0];
  1097. // If the LUN is invalid byte 0 of inquiry block needs to be 7fh
  1098. dev->inquiry_block->raw[0] = 0x7f;
  1099. // only write back what was asked for
  1100. writeDataPhase(cmd[4], dev->inquiry_block->raw);
  1101. // return it back to normal if it was altered
  1102. dev->inquiry_block->raw[0] = temp;
  1103. }
  1104. else if(cmd[0] == SCSI_REQUEST_SENSE)
  1105. {
  1106. byte buf[18] = {
  1107. 0x70, //CheckCondition
  1108. 0, //Segment number
  1109. SCSI_SENSE_ILLEGAL_REQUEST, //Sense key
  1110. 0, 0, 0, 0, //information
  1111. 10, //Additional data length
  1112. 0, 0, 0, 0, // command specific information bytes
  1113. (byte)(SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED >> 8),
  1114. (byte)SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
  1115. 0, 0, 0, 0,
  1116. };
  1117. writeDataPhase(cmd[4] < 18 ? cmd[4] : 18, buf);
  1118. }
  1119. else
  1120. {
  1121. m_sts = SCSI_STATUS_CHECK_CONDITION;
  1122. }
  1123. goto Status;
  1124. }
  1125. dev = &(scsi_device_list[m_id][m_lun]);
  1126. if(!dev->m_file)
  1127. {
  1128. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1129. dev->m_additional_sense_code = SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED;
  1130. m_sts = SCSI_STATUS_CHECK_CONDITION;
  1131. goto Status;
  1132. }
  1133. LED_ON();
  1134. m_sts = scsi_command_table[cmd[0]](dev, cmd);
  1135. LED_OFF();
  1136. Status:
  1137. LOG(" STS:"); LOGHEX(m_sts);
  1138. SCSI_PHASE_CHANGE(SCSI_PHASE_STATUS);
  1139. // Bus settle delay 400ns built in to writeHandshake
  1140. writeHandshake(m_sts);
  1141. LOG(" MI:"); LOGHEX(m_msg);
  1142. SCSI_PHASE_CHANGE(SCSI_PHASE_MESSAGEIN);
  1143. // Bus settle delay 400ns built in to writeHandshake
  1144. writeHandshake(m_msg);
  1145. BusFree:
  1146. LOGN(" BF ");
  1147. m_isBusReset = false;
  1148. //SCSI_OUT(vREQ,inactive) // gpio_write(REQ, low);
  1149. //SCSI_OUT(vMSG,inactive) // gpio_write(MSG, low);
  1150. //SCSI_OUT(vCD ,inactive) // gpio_write(CD, low);
  1151. //SCSI_OUT(vIO ,inactive) // gpio_write(IO, low);
  1152. //SCSI_OUT(vBSY,inactive)
  1153. SCSI_TARGET_INACTIVE() // Turn off BSY, REQ, MSG, CD, IO output
  1154. #ifdef XCVR
  1155. TRANSCEIVER_IO_SET(vTR_TARGET,TR_INPUT);
  1156. // Something in code linked after this function is performing better with a +4 alignment.
  1157. // Adding this nop is causing the next function (_GLOBAL__sub_I_SD) to have an address with a last digit of 0x4.
  1158. // Last digit of 0xc also works.
  1159. // This affects both with and without XCVR, currently without XCVR doesn't need any padding.
  1160. // Until the culprit can be tracked down and fixed, it may be necessary to do manual adjustment.
  1161. asm("nop.w");
  1162. #endif
  1163. }
  1164. static byte onUnimplemented(SCSI_DEVICE *dev, const byte *cdb)
  1165. {
  1166. // does nothing!
  1167. if(Serial)
  1168. {
  1169. Serial.print("Unimplemented SCSI command: ");
  1170. Serial.println(cdb[0], 16);
  1171. }
  1172. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1173. dev->m_additional_sense_code = SCSI_ASC_INVALID_OPERATION_CODE;
  1174. return SCSI_STATUS_CHECK_CONDITION;
  1175. }
  1176. static byte onNOP(SCSI_DEVICE *dev, const byte *cdb)
  1177. {
  1178. dev->m_senseKey = 0;
  1179. dev->m_additional_sense_code = 0;
  1180. return SCSI_STATUS_GOOD;
  1181. }
  1182. /*
  1183. * INQUIRY command processing.
  1184. */
  1185. byte onInquiry(SCSI_DEVICE *dev, const byte *cdb)
  1186. {
  1187. writeDataPhase(cdb[4] < 47 ? cdb[4] : 47, dev->inquiry_block->raw);
  1188. return SCSI_STATUS_GOOD;
  1189. }
  1190. /*
  1191. * REQUEST SENSE command processing.
  1192. */
  1193. byte onRequestSense(SCSI_DEVICE *dev, const byte *cdb)
  1194. {
  1195. byte buf[18] = {
  1196. 0x70, //CheckCondition
  1197. 0, //Segment number
  1198. dev->m_senseKey, //Sense key
  1199. 0, 0, 0, 0, //information
  1200. 10, //Additional data length
  1201. 0, 0, 0, 0, // command specific information bytes
  1202. (byte)(dev->m_additional_sense_code >> 8),
  1203. (byte)dev->m_additional_sense_code,
  1204. 0, 0, 0, 0,
  1205. };
  1206. dev->m_senseKey = 0;
  1207. dev->m_additional_sense_code = 0;
  1208. writeDataPhase(cdb[4] < 18 ? cdb[4] : 18, buf);
  1209. return SCSI_STATUS_GOOD;
  1210. }
  1211. /*
  1212. * READ CAPACITY command processing.
  1213. */
  1214. byte onReadCapacity(SCSI_DEVICE *dev, const byte *cdb)
  1215. {
  1216. uint32_t lastlba = dev->m_blockcount - 1; // Points to last LBA
  1217. uint8_t buf[8] = {
  1218. (byte)(lastlba >> 24),
  1219. (byte)(lastlba >> 16),
  1220. (byte)(lastlba >> 8),
  1221. (byte)(lastlba),
  1222. (byte)(dev->m_blocksize >> 24),
  1223. (byte)(dev->m_blocksize >> 16),
  1224. (byte)(dev->m_blocksize >> 8),
  1225. (byte)(dev->m_blocksize)
  1226. };
  1227. writeDataPhase(sizeof(buf), buf);
  1228. return SCSI_STATUS_GOOD;
  1229. }
  1230. /*
  1231. * Check that the image file is present and the block range is valid.
  1232. */
  1233. byte checkBlockCommand(SCSI_DEVICE *dev, uint32_t adds, uint32_t len)
  1234. {
  1235. // Check block range is valid
  1236. if (adds >= dev->m_blockcount || (adds + len) > dev->m_blockcount) {
  1237. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1238. dev->m_additional_sense_code = SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
  1239. return SCSI_STATUS_CHECK_CONDITION;
  1240. }
  1241. return SCSI_STATUS_GOOD;
  1242. }
  1243. /*
  1244. * READ6 / 10 Command processing.
  1245. */
  1246. static byte onRead6(SCSI_DEVICE *dev, const byte *cdb)
  1247. {
  1248. unsigned adds = (((uint32_t)cdb[1] & 0x1F) << 16) | ((uint32_t)cdb[2] << 8) | cdb[3];
  1249. unsigned len = (cdb[4] == 0) ? 0x100 : cdb[4];
  1250. /*
  1251. LOGN("onRead6");
  1252. LOG("-R ");
  1253. LOGHEX(adds);
  1254. LOG(":");
  1255. LOGHEXN(len);
  1256. */
  1257. byte sts = checkBlockCommand(dev, adds, len);
  1258. if (sts) {
  1259. return sts;
  1260. }
  1261. writeDataPhaseSD(dev, adds, len);
  1262. return SCSI_STATUS_GOOD;
  1263. }
  1264. static byte onRead10(SCSI_DEVICE *dev, const byte *cdb)
  1265. {
  1266. unsigned adds = ((uint32_t)cdb[2] << 24) | ((uint32_t)cdb[3] << 16) | ((uint32_t)cdb[4] << 8) | cdb[5];
  1267. unsigned len = ((uint32_t)cdb[7] << 8) | cdb[8];
  1268. LOG (" Read10 ");
  1269. LOG("A:");
  1270. LOGHEX(adds);
  1271. LOG(":");
  1272. LOGHEX(len);
  1273. LOG(" ");
  1274. byte sts = checkBlockCommand(dev, adds, len);
  1275. if (sts) {
  1276. return sts;
  1277. }
  1278. writeDataPhaseSD(dev, adds, len);
  1279. return SCSI_STATUS_GOOD;
  1280. }
  1281. /*
  1282. * WRITE6 / 10 Command processing.
  1283. */
  1284. static byte onWrite6(SCSI_DEVICE *dev, const byte *cdb)
  1285. {
  1286. unsigned adds = (((uint32_t)cdb[1] & 0x1F) << 16) | ((uint32_t)cdb[2] << 8) | cdb[3];
  1287. unsigned len = (cdb[4] == 0) ? 0x100 : cdb[4];
  1288. /*
  1289. LOGN("onWrite6");
  1290. LOG("-W ");
  1291. LOGHEX(adds);
  1292. LOG(":");
  1293. LOGHEXN(len);
  1294. */
  1295. if(dev->m_type == SCSI_DEVICE_OPTICAL)
  1296. {
  1297. dev->m_senseKey = SCSI_SENSE_HARDWARE_ERROR;
  1298. dev->m_additional_sense_code = SCSI_ASC_WRITE_PROTECTED; // Write Protect
  1299. return SCSI_STATUS_CHECK_CONDITION;
  1300. }
  1301. byte sts = checkBlockCommand(dev, adds, len);
  1302. if (sts) {
  1303. return sts;
  1304. }
  1305. readDataPhaseSD(dev, adds, len);
  1306. return SCSI_STATUS_GOOD;
  1307. }
  1308. static byte onWrite10(SCSI_DEVICE *dev, const byte *cdb)
  1309. {
  1310. unsigned adds = ((uint32_t)cdb[2] << 24) | ((uint32_t)cdb[3] << 16) | ((uint32_t)cdb[4] << 8) | cdb[5];
  1311. unsigned len = ((uint32_t)cdb[7] << 8) | cdb[8];
  1312. /*
  1313. LOGN("onWrite10");
  1314. LOG("-W ");
  1315. LOGHEX(adds);
  1316. LOG(":");
  1317. LOGHEXN(len);
  1318. */
  1319. if(dev->m_type == SCSI_DEVICE_OPTICAL)
  1320. {
  1321. dev->m_senseKey = SCSI_SENSE_HARDWARE_ERROR;
  1322. dev->m_additional_sense_code = SCSI_ASC_WRITE_PROTECTED; // Write Protect
  1323. return SCSI_STATUS_CHECK_CONDITION;
  1324. }
  1325. byte sts = checkBlockCommand(dev, adds, len);
  1326. if (sts) {
  1327. return sts;
  1328. }
  1329. readDataPhaseSD(dev, adds, len);
  1330. return SCSI_STATUS_GOOD;
  1331. }
  1332. /*
  1333. * VERIFY10 Command processing.
  1334. */
  1335. byte onVerify(SCSI_DEVICE *dev, const byte *cdb)
  1336. {
  1337. unsigned adds = ((uint32_t)cdb[2] << 24) | ((uint32_t)cdb[3] << 16) | ((uint32_t)cdb[4] << 8) | cdb[5];
  1338. unsigned len = ((uint32_t)cdb[7] << 8) | cdb[8];
  1339. byte sts = checkBlockCommand(dev, adds, len);
  1340. if (sts) {
  1341. return sts;
  1342. }
  1343. int bytchk = (cdb[1] >> 1) & 0x03;
  1344. if (bytchk != 0) {
  1345. if (bytchk == 3) {
  1346. // Data-Out buffer is single logical block for repeated verification.
  1347. len = dev->m_blocksize;
  1348. }
  1349. verifyDataPhaseSD(dev, adds, len);
  1350. }
  1351. return SCSI_STATUS_GOOD;
  1352. }
  1353. /*
  1354. * MODE SENSE command processing.
  1355. */
  1356. byte onModeSense(SCSI_DEVICE *dev, const byte *cdb)
  1357. {
  1358. const byte apple_magic[] = "APPLE COMPUTER, INC ";
  1359. int pageCode = cdb[2] & 0x3F;
  1360. int pageControl = cdb[2] >> 6;
  1361. byte dbd = cdb[1] & 0x8;
  1362. byte block_descriptor_length = 8;
  1363. // saving parameters is not allowed...yet!
  1364. if(pageControl == 3)
  1365. {
  1366. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1367. dev->m_additional_sense_code = SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED;
  1368. return SCSI_STATUS_CHECK_CONDITION;
  1369. }
  1370. // SCSI_MODE_SENSE6
  1371. int a = 4;
  1372. int length = cdb[4];
  1373. if(cdb[0] == SCSI_MODE_SENSE10) {
  1374. a = 8;
  1375. length = cdb[7];
  1376. length <<= 8;
  1377. length |= cdb[8];
  1378. if(length > 0x800) { length = 0x800; };
  1379. }
  1380. memset(m_buf, 0, length);
  1381. if(!dbd) {
  1382. byte c[8] = {
  1383. 0,//Density code
  1384. (byte)(dev->m_blockcount >> 16),
  1385. (byte)(dev->m_blockcount >> 8),
  1386. (byte)(dev->m_blockcount),
  1387. 0, //Reserve
  1388. (byte)(dev->m_blocksize >> 16),
  1389. (byte)(dev->m_blocksize >> 8),
  1390. (byte)(dev->m_blocksize),
  1391. };
  1392. memcpy(&m_buf[a], c, 8);
  1393. a += 8;
  1394. }
  1395. // HDD supports page codes 0x1 (Read/Write), 0x2, 0x3, 0x4
  1396. // CDROM supports page codes 0x1 (Read Only), 0x2, 0xD, 0xE, 0x30
  1397. if(dev->m_type == SCSI_DEVICE_HDD) {
  1398. switch(pageCode) {
  1399. case SCSI_SENSE_MODE_ALL:
  1400. case SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY:
  1401. m_buf[a + 0] = SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY;
  1402. m_buf[a + 1] = 0x0A;
  1403. a += 0x0C;
  1404. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1405. case SCSI_SENSE_MODE_DISCONNECT_RECONNECT:
  1406. m_buf[a + 0] = SCSI_SENSE_MODE_DISCONNECT_RECONNECT;
  1407. m_buf[a + 1] = 0x0A;
  1408. a += 0x0C;
  1409. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1410. case SCSI_SENSE_MODE_FORMAT_DEVICE: //Drive parameters
  1411. m_buf[a + 0] = SCSI_SENSE_MODE_FORMAT_DEVICE; //Page code
  1412. m_buf[a + 1] = 0x16; // Page length
  1413. if(pageControl != 1) {
  1414. m_buf[a + 11] = 0x3F;//Number of sectors / track
  1415. m_buf[a + 12] = (byte)(dev->m_blocksize >> 8);
  1416. m_buf[a + 13] = (byte)dev->m_blocksize;
  1417. m_buf[a + 15] = 0x1; // Interleave
  1418. }
  1419. a += 0x18;
  1420. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1421. case SCSI_SENSE_MODE_DISK_GEOMETRY: //Drive parameters
  1422. m_buf[a + 0] = SCSI_SENSE_MODE_DISK_GEOMETRY; //Page code
  1423. m_buf[a + 1] = 0x16; // Page length
  1424. if(pageControl != 1) {
  1425. unsigned cylinders = dev->m_blockcount / (16 * 63);
  1426. m_buf[a + 2] = (byte)(cylinders >> 16); // Cylinders
  1427. m_buf[a + 3] = (byte)(cylinders >> 8);
  1428. m_buf[a + 4] = (byte)cylinders;
  1429. m_buf[a + 5] = 16; //Number of heads
  1430. } else {
  1431. m_buf[a + 2] = 0xFF; // Cylinder length
  1432. m_buf[a + 3] = 0xFF;
  1433. m_buf[a + 4] = 0xFF;
  1434. m_buf[a + 5] = 16; //Number of heads
  1435. }
  1436. a += 0x18;
  1437. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1438. case SCSI_SENSE_MODE_FLEXABLE_GEOMETRY:
  1439. m_buf[a + 0] = SCSI_SENSE_MODE_FLEXABLE_GEOMETRY;
  1440. m_buf[a + 1] = 0x1E; // Page length
  1441. if(pageControl != 1) {
  1442. m_buf[a + 2] = 0x03;
  1443. m_buf[a + 3] = 0xE8; // Transfer rate 1 mbit/s
  1444. m_buf[a + 4] = 16; // Number of heads
  1445. m_buf[a + 5] = 63; // Sectors per track
  1446. m_buf[a + 6] = (byte)dev->m_blocksize >> 8;
  1447. m_buf[a + 7] = (byte)dev->m_blocksize & 0xff; // Data bytes per sector
  1448. }
  1449. a += 0x20;
  1450. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1451. case SCSI_SENSE_MODE_CACHING:
  1452. m_buf[a + 0] = SCSI_SENSE_MODE_CACHING;
  1453. m_buf[a + 1] = 0x0A; // Page length
  1454. if(pageControl != 1) {
  1455. m_buf[a + 2] = 0x01; // Disalbe Read Cache so no one asks for Cache Stats page.
  1456. }
  1457. a += 0x0C;
  1458. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1459. case SCSI_SENSE_MODE_VENDOR_APPLE:
  1460. {
  1461. if(pageControl != 1) {
  1462. m_buf[a + 0] = SCSI_SENSE_MODE_VENDOR_APPLE;
  1463. m_buf[a + 1] = sizeof(apple_magic); // Page length
  1464. memcpy(&m_buf[a + 2], apple_magic, sizeof(apple_magic));
  1465. a += sizeof(apple_magic) + 2;
  1466. }
  1467. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1468. }
  1469. break; // Don't want SCSI_SENSE_MODE_ALL falling through to error condition
  1470. default:
  1471. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1472. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1473. return SCSI_STATUS_CHECK_CONDITION;
  1474. break;
  1475. }
  1476. } else {
  1477. // OPTICAL
  1478. if(cdb[0] == SCSI_MODE_SENSE6) {
  1479. m_buf[2] = 1 << 7; // WP bit
  1480. } else {
  1481. m_buf[3] = 1 << 7; // WP bit
  1482. }
  1483. switch(pageCode) {
  1484. case SCSI_SENSE_MODE_ALL:
  1485. case SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY:
  1486. m_buf[a + 0] = SCSI_SENSE_MODE_READ_WRITE_ERROR_RECOVERY;
  1487. m_buf[a + 1] = 0x06;
  1488. m_buf[a + 3] = 0x01; // Retry Count
  1489. a += 0x08;
  1490. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1491. case SCSI_SENSE_MODE_DISCONNECT_RECONNECT:
  1492. m_buf[a + 0] = SCSI_SENSE_MODE_DISCONNECT_RECONNECT;
  1493. m_buf[a + 1] = 0x0A;
  1494. a += 0x0C;
  1495. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1496. case SCSI_SENSE_MODE_CDROM:
  1497. m_buf[a + 0] = SCSI_SENSE_MODE_CDROM;
  1498. m_buf[a + 1] = 0x06;
  1499. if(pageControl != 1)
  1500. {
  1501. // 2 seconds for inactive timer
  1502. m_buf[a + 3] = 0x05;
  1503. // MSF multiples are 60 and 75
  1504. m_buf[a + 5] = 60;
  1505. m_buf[a + 7] = 75;
  1506. }
  1507. a += 0x8;
  1508. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1509. case SCSI_SENSE_MODE_CDROM_AUDIO_CONTROL:
  1510. m_buf[a + 0] = SCSI_SENSE_MODE_CDROM_AUDIO_CONTROL;
  1511. m_buf[a + 1] = 0x0E;
  1512. a += 0x10;
  1513. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1514. case SCSI_SENSE_MODE_VENDOR_APPLE:
  1515. {
  1516. if(pageControl != 1) {
  1517. m_buf[a + 0] = SCSI_SENSE_MODE_VENDOR_APPLE;
  1518. m_buf[a + 1] = sizeof(apple_magic); // Page length
  1519. memcpy(&m_buf[a + 2], apple_magic, sizeof(apple_magic));
  1520. a += sizeof(apple_magic) + 2;
  1521. }
  1522. if(pageCode != SCSI_SENSE_MODE_ALL) break;
  1523. }
  1524. break; // Don't want SCSI_SENSE_MODE_ALL falling through to error condition
  1525. default:
  1526. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1527. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1528. return SCSI_STATUS_CHECK_CONDITION;
  1529. break;
  1530. }
  1531. }
  1532. if(cdb[0] == SCSI_MODE_SENSE10)
  1533. {
  1534. m_buf[1] = a - 2;
  1535. m_buf[7] = block_descriptor_length; // block descriptor length
  1536. }
  1537. else
  1538. {
  1539. m_buf[0] = a - 1;
  1540. m_buf[3] = block_descriptor_length; // block descriptor length
  1541. }
  1542. writeDataPhase(length < a ? length : a, m_buf);
  1543. return SCSI_STATUS_GOOD;
  1544. }
  1545. void setBlockLength(SCSI_DEVICE *dev, uint32_t length)
  1546. {
  1547. dev->m_blocksize = dev->m_rawblocksize = length;
  1548. dev->m_blockcount = dev->m_fileSize / dev->m_blocksize;
  1549. }
  1550. byte onModeSelect(SCSI_DEVICE *dev, const byte *cdb)
  1551. {
  1552. unsigned length = 0;
  1553. LOGN("onModeSelect");
  1554. // saving mode pages isn't supported yet
  1555. if(cdb[1] & 0x01)
  1556. {
  1557. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1558. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1559. return SCSI_STATUS_CHECK_CONDITION;
  1560. }
  1561. if(cdb[0] == SCSI_MODE_SELECT6)
  1562. {
  1563. length = cdb[4];
  1564. }
  1565. else /* SCSI_MODE_SELECT10 */
  1566. {
  1567. length = cdb[7] << 8;
  1568. length |= cdb[8];
  1569. if(length > 0x800) { length = 0x800; }
  1570. }
  1571. if(length == 0)
  1572. {
  1573. return SCSI_STATUS_GOOD;
  1574. }
  1575. memset(m_buf, 0, length);
  1576. readDataPhase(length, m_buf);
  1577. //Apple HD SC Setup sends:
  1578. //0 0 0 8 0 0 0 0 0 0 2 0 0 2 10 0 1 6 24 10 8 0 0 0
  1579. //I believe mode page 0 set to 10 00 is Disable Unit Attention
  1580. //Mode page 1 set to 24 10 08 00 00 00 is TB and PER set, read retry count 16, correction span 8
  1581. if(dev->m_type == SCSI_DEVICE_OPTICAL)
  1582. {
  1583. // check for a block descriptor
  1584. if(m_buf[3] == 8)
  1585. {
  1586. // Requested change of blocksize
  1587. // Only supporting 512 or 2048 for optical devices
  1588. uint32_t new_block_size = ((uint32_t)m_buf[8] << 16) | ((uint32_t)m_buf[10] << 8) | m_buf[9];
  1589. switch(new_block_size)
  1590. {
  1591. case 512: setBlockLength(dev, 512);
  1592. break;
  1593. case 2048: setBlockLength(dev, 2048);
  1594. break;
  1595. default: LOG("Err BlockSize:"); LOG(new_block_size); LOG(" ");
  1596. }
  1597. }
  1598. }
  1599. #if DEBUG > 0
  1600. for (unsigned i = 0; i < length; i++) {
  1601. LOGHEX(m_buf[i]);LOG(" ");
  1602. }
  1603. LOGN("");
  1604. #endif
  1605. return SCSI_STATUS_GOOD;
  1606. }
  1607. /*
  1608. * ReZero Unit - Move to Logical Block Zero in file.
  1609. */
  1610. byte onReZeroUnit(SCSI_DEVICE *dev, const byte *cdb) {
  1611. LOGN("-ReZeroUnit");
  1612. // Make sure we have an image with atleast a first byte.
  1613. // Actually seeking to the position wont do anything, so dont.
  1614. return checkBlockCommand(dev, 0, 0);
  1615. }
  1616. /*
  1617. * WriteBuffer - Used for testing buffer, no change to medium
  1618. */
  1619. byte onWriteBuffer(SCSI_DEVICE *dev, const byte *cdb)
  1620. {
  1621. byte mode = cdb[1] & 7;
  1622. uint32_t allocLength = ((uint32_t)cdb[6] << 16) | ((uint32_t)cdb[7] << 8) | cdb[8];
  1623. LOGN("-WriteBuffer");
  1624. LOGHEXN(mode);
  1625. LOGHEXN(allocLength);
  1626. if (mode == MODE_COMBINED_HEADER_DATA && (allocLength - 4) <= SCSI_BUF_SIZE)
  1627. {
  1628. byte tmp[allocLength];
  1629. readDataPhase(allocLength, tmp);
  1630. // Drop header
  1631. memcpy(m_scsi_buf, (&tmp[4]), allocLength - 4);
  1632. #if DEBUG > 0
  1633. for (unsigned i = 0; i < allocLength; i++) {
  1634. LOGHEX(tmp[i]);LOG(" ");
  1635. }
  1636. LOGN("");
  1637. #endif
  1638. return SCSI_STATUS_GOOD;
  1639. }
  1640. else if ( mode == MODE_DATA && allocLength <= SCSI_BUF_SIZE)
  1641. {
  1642. readDataPhase(allocLength, m_scsi_buf);
  1643. #if DEBUG > 0
  1644. for (unsigned i = 0; i < allocLength; i++) {
  1645. LOGHEX(m_scsi_buf[i]);LOG(" ");
  1646. }
  1647. LOGN("");
  1648. #endif
  1649. return SCSI_STATUS_GOOD;
  1650. }
  1651. else
  1652. {
  1653. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1654. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1655. return SCSI_STATUS_CHECK_CONDITION;
  1656. }
  1657. }
  1658. /*
  1659. * ReadBuffer - Used for testing buffer, no change to medium
  1660. */
  1661. byte onReadBuffer(SCSI_DEVICE *dev, const byte *cdb)
  1662. {
  1663. byte mode = cdb[1] & 7;
  1664. uint32_t allocLength = ((uint32_t)cdb[6] << 16) | ((uint32_t)cdb[7] << 8) | cdb[8];
  1665. LOGN("-ReadBuffer");
  1666. LOGHEXN(mode);
  1667. LOGHEXN(allocLength);
  1668. if (mode == MODE_COMBINED_HEADER_DATA)
  1669. {
  1670. memset(m_buf, 0, 4 + m_scsi_buf_size);
  1671. // four byte read buffer header
  1672. m_buf[0] = 0;
  1673. m_buf[1] = (SCSI_BUF_SIZE >> 16) & 0xff;
  1674. m_buf[2] = (SCSI_BUF_SIZE >> 8) & 0xff;
  1675. m_buf[3] = SCSI_BUF_SIZE & 0xff;
  1676. // actual data
  1677. memcpy((&m_buf[4]), m_scsi_buf, m_scsi_buf_size);
  1678. writeDataPhase(4 + m_scsi_buf_size, m_buf);
  1679. #if DEBUG > 0
  1680. for (unsigned i = 0; i < allocLength; i++) {
  1681. LOGHEX(m_scsi_buf[i]);LOG(" ");
  1682. }
  1683. LOGN("");
  1684. #endif
  1685. return SCSI_STATUS_GOOD;
  1686. }
  1687. else if (mode == MODE_DATA)
  1688. {
  1689. writeDataPhase(m_scsi_buf_size, m_scsi_buf);
  1690. #if DEBUG > 0
  1691. for (unsigned i = 0; i < allocLength; i++) {
  1692. LOGHEX(m_scsi_buf[i]);LOG(" ");
  1693. }
  1694. LOGN("");
  1695. #endif
  1696. return SCSI_STATUS_GOOD;
  1697. }
  1698. else
  1699. {
  1700. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1701. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1702. return SCSI_STATUS_CHECK_CONDITION;
  1703. }
  1704. }
  1705. /*
  1706. * On Send Diagnostic
  1707. */
  1708. byte onSendDiagnostic(SCSI_DEVICE *dev, const byte *cdb)
  1709. {
  1710. int self_test = cdb[1] & 0x4;
  1711. LOGN("-SendDiagnostic");
  1712. LOGHEXN(cdb[1]);
  1713. if(self_test)
  1714. {
  1715. // Don't actually do a test, we're good.
  1716. return SCSI_STATUS_GOOD;
  1717. }
  1718. else
  1719. {
  1720. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1721. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1722. return SCSI_STATUS_CHECK_CONDITION;
  1723. }
  1724. }
  1725. /*
  1726. * Read Defect Data
  1727. */
  1728. byte onReadDefectData(SCSI_DEVICE *dev, const byte *cdb)
  1729. {
  1730. byte response[4] = {
  1731. 0x0, // Reserved
  1732. cdb[2], // echo back Reserved, Plist, Glist, Defect list format
  1733. cdb[7], cdb[8] // echo back defect list length
  1734. };
  1735. writeDataPhase(4, response);
  1736. return SCSI_STATUS_GOOD;
  1737. }
  1738. static byte onReadTOC(SCSI_DEVICE *dev, const byte *cdb)
  1739. {
  1740. uint8_t msf = cdb[1] & 0x02;
  1741. uint8_t track = cdb[6];
  1742. unsigned len = ((uint32_t)cdb[7] << 8) | cdb[8];
  1743. memset(m_buf, 0, len);
  1744. // Doing just the error seemed to make MacOS unhappy
  1745. #if 0
  1746. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1747. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1748. return SCSI_STATUS_CHECK_CONDITION;
  1749. #endif
  1750. if(track > 1 || cdb[2] != 0)
  1751. {
  1752. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1753. dev->m_additional_sense_code = SCSI_ASC_INVALID_FIELD_IN_CDB;
  1754. return SCSI_STATUS_CHECK_CONDITION;
  1755. }
  1756. m_buf[1] = 18; // TOC length LSB
  1757. m_buf[2] = 1; // First Track
  1758. m_buf[3] = 1; // Last Track
  1759. // first track
  1760. m_buf[5] = 0x14; // data track
  1761. m_buf[6] = 1;
  1762. // leadout track
  1763. m_buf[13] = 0x14; // data track
  1764. m_buf[14] = 0xaa; // leadout track
  1765. if(msf)
  1766. {
  1767. LBAtoMSF(dev->m_blockcount, &m_buf[16]);
  1768. }
  1769. else
  1770. {
  1771. m_buf[16] = (byte)(dev->m_blockcount >> 24);
  1772. m_buf[17] = (byte)(dev->m_blockcount >> 16);
  1773. m_buf[18] = (byte)(dev->m_blockcount >> 8);
  1774. m_buf[20] = (byte)(dev->m_blockcount);
  1775. }
  1776. writeDataPhase(SCSI_TOC_LENGTH > len ? len : SCSI_TOC_LENGTH, m_buf);
  1777. return SCSI_STATUS_GOOD;
  1778. }
  1779. static byte onReadDiscInformation(SCSI_DEVICE *dev, const byte *cdb)
  1780. {
  1781. writeDataPhase((cdb[7] >> 8) | cdb[8], m_buf);
  1782. return SCSI_STATUS_GOOD;
  1783. }
  1784. static byte onReadDVDStructure(SCSI_DEVICE *dev, const byte *cdb)
  1785. {
  1786. dev->m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
  1787. dev->m_additional_sense_code = SCSI_ASC_INVALID_OPERATION_CODE;
  1788. return SCSI_STATUS_CHECK_CONDITION;
  1789. }
  1790. // Thanks RaSCSI :D
  1791. // LBA→MSF Conversion
  1792. static inline void LBAtoMSF(const uint32_t lba, byte *msf)
  1793. {
  1794. uint32_t m, s, f;
  1795. // 75 and 75*60 get the remainder
  1796. m = lba / (75 * 60);
  1797. s = lba % (75 * 60);
  1798. f = s % 75;
  1799. s /= 75;
  1800. // The base point is M=0, S=2, F=0
  1801. s += 2;
  1802. if (s >= 60) {
  1803. s -= 60;
  1804. m++;
  1805. }
  1806. // Store
  1807. msf[0] = 0x00;
  1808. msf[1] = (byte)m;
  1809. msf[2] = (byte)s;
  1810. msf[3] = (byte)f;
  1811. }
  1812. static inline uint32_t MSFtoLBA(const byte *msf)
  1813. {
  1814. uint32_t lba;
  1815. // 1, 75, add up in multiples of 75*60
  1816. lba = msf[1];
  1817. lba *= 60;
  1818. lba += msf[2];
  1819. lba *= 75;
  1820. lba += msf[3];
  1821. // Since the base point is M=0, S=2, F=0, subtract 150
  1822. lba -= 150;
  1823. return lba;
  1824. }