main.cpp 57 KB

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