blacksasi.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. #ifndef __BLACKSASI_H__
  2. #define __BLACKSASI_H__
  3. #include "sdcard.h"
  4. #include "gpio.h"
  5. #include "log.h"
  6. #include "config.h"
  7. #include "scsi.h"
  8. // Log File
  9. #define VERSION "0.xx-SNAPSHOT-BLACKSASI-2022-09-28-F4"
  10. #define LOG_FILENAME "LOG.txt"
  11. #define SPI_CLOCK SD_SCK_MHZ(50)
  12. #define DEBUG 1 // 0:No debug information output
  13. // 1: Debug information output to USB Serial
  14. // 2: Debug information output to LOG.txt (slow)
  15. #define SCSI_SELECT 0 // 0 for STANDARD
  16. // 1 for SHARP X1turbo
  17. // 2 for NEC PC98
  18. #define READ_SPEED_OPTIMIZE 1 // Faster reads
  19. #define WRITE_SPEED_OPTIMIZE 1 // Speeding up writes
  20. #define USE_DB2ID_TABLE 1 // Use table to get ID from SEL-DB
  21. // SCSI config
  22. #define NUM_SCSIID 7 // Maximum number of supported SCSI-IDs (The minimum is 0)
  23. #define NUM_SCSILUN 2 // Maximum number of LUNs supported (The minimum is 0)
  24. #define READ_PARITY_CHECK 0 // Perform read parity check (unverified)
  25. // HDD format
  26. #define MAX_BLOCKSIZE 2048 // Maximum BLOCK size
  27. #if DEBUG == 1
  28. #define serial Serial
  29. #define LOG(XX) serial.print(XX)
  30. #define LOGHEX(XX) serial.print(XX, HEX)
  31. #define LOGDEC(XX) serial.print(XX, DEC)
  32. #define LOGBIN(XX) serial.print(XX, BIN)
  33. #define LOGN(XX) serial.println(XX)
  34. #define LOGHEXN(XX) serial.println(XX, HEX)
  35. #define LOGDECN(XX) serial.println(XX, DEC)
  36. #define LOGBIN_N(XX) serial.println(XX, BIN)
  37. #elif DEBUG == 2
  38. #define LOG(XX) LOG_FILE.print(XX); LOG_FILE.sync();
  39. #define LOGHEX(XX) LOG_FILE.print(XX, HEX); LOG_FILE.sync();
  40. #define LOGDEC(XX) LOG_FILE.print(XX, DEC); LOG_FILE.sync();
  41. #define LOGBIN(XX) LOG_FILE.print(XX, BIN); LOG_FILE.sync();
  42. #define LOGN(XX) LOG_FILE.println(XX); LOG_FILE.sync();
  43. #define LOGHEXN(XX) LOG_FILE.println(XX, HEX); LOG_FILE.sync();
  44. #define LOGDECN(XX) LOG_FILE.println(XX, DEC); LOG_FILE.sync();
  45. #define LOGBIN_N(XX) LOG_FILE.println(XX, BIN); LOG_FILE.sync();
  46. #else
  47. #define LOG(XX) //serial.print(XX)
  48. #define LOGHEX(XX) //serial.print(XX, HEX)
  49. #define LOGDEC(XX) //serial.print(XX, DEC)
  50. #define LOGBIN(XX) //serial.print(XX, BIN)
  51. #define LOGN(XX) //serial.println(XX)
  52. #define LOGHEXN(XX) //serial.println(XX, HEX)
  53. #define LOGDECN(XX) //serial.println(XX, DEC)
  54. #define LOGBIN_N(XX) //serial.println(XX, BIN)
  55. #endif
  56. #define active 1
  57. #define inactive 0
  58. #define high 0
  59. #define low 1
  60. #define isHigh(XX) ((XX) == high)
  61. #define isLow(XX) ((XX) != high)
  62. // GPIO register port
  63. #define PAREG GPIOA->regs
  64. #define PBREG GPIOB->regs
  65. #define PCREG GPIOC->regs
  66. #define PDREG GPIOD->regs
  67. #define PEREG GPIOE->regs
  68. // Termination control (LOW is active)
  69. #define TERMINATION_HIGH() GPIOREG(BOARD_SCSI_TERM_HIGH)->BSRR = (1 << BOARD_SCSI_TERM_HIGH % 16) << 16 | (1 << BOARD_SCSI_TERM_LOW % 16);
  70. #define TERMINATION_LOW() GPIOREG(BOARD_SCSI_TERM_HIGH)->BSRR = (1 << BOARD_SCSI_TERM_LOW % 16) << 16 | (1 << BOARD_SCSI_TERM_HIGH % 16);
  71. #define TERMINATION_OFF() GPIOREG(BOARD_SCSI_TERM_HIGH)->BSRR = (1 << BOARD_SCSI_TERM_HIGH % 16) | (1 << BOARD_SCSI_TERM_LOW % 16);
  72. // Enable SCSI buffers
  73. #define SCSI_OUTPUT_ENABLE() GPIOREG(BOARD_TRANS_OE)->BSRR = (1 << (BOARD_TRANS_OE % 16)) << 16;
  74. #define SCSI_OUTPUT_DISABLE() GPIOREG(BOARD_TRANS_OE)->BSRR = (1 << (BOARD_TRANS_OE % 16));
  75. // SCSI Data Direction
  76. #define SCSI_DATABUS_IN() GPIOREG(BOARD_SCSI_DTD)->BSRR = (1 << (BOARD_SCSI_DTD % 16)) << 16;
  77. #define SCSI_DATABUS_OUT() GPIOREG(BOARD_SCSI_DTD)->BSRR = (1 << (BOARD_SCSI_DTD % 16))
  78. // SCSI IND Direction
  79. #define SCSI_IND_IN() GPIOREG(BOARD_SCSI_IND)->BSRR = (1 << (BOARD_SCSI_IND % 16));
  80. #define SCSI_IND_OUT() GPIOREG(BOARD_SCSI_IND)->BSRR = (1 << (BOARD_SCSI_IND % 16)) << 16;
  81. //SCSI Data and IND Direction
  82. #define SCSI_DATABUS_IND_IN() GPIOREG(BOARD_SCSI_DTD)->BSRR = ((1 << (BOARD_SCSI_DTD % 16)) << 16) | (1 << (BOARD_SCSI_IND % 16));
  83. #define SCSI_DATABUS_IND_OUT() GPIOREG(BOARD_SCSI_DTD)->BSRR = ((1 << (BOARD_SCSI_IND % 16)) << 16) | (1 << (BOARD_SCSI_DTD % 16));
  84. // SCSI TAD Direction
  85. #define SCSI_TAD_IN() GPIOREG(BOARD_SCSI_TAD)->BSRR = (1 << (BOARD_SCSI_TAD % 16));
  86. #define SCSI_TAD_OUT() GPIOREG(BOARD_SCSI_TAD)->BSRR = (1 << (BOARD_SCSI_TAD % 16)) << 16;
  87. // Virtual pin (Arduio compatibility is slow, so make it MCU-dependent)
  88. #define PA(BIT) (BIT)
  89. #define PB(BIT) (BIT + 16)
  90. #define PC(BIT) (BIT + 32)
  91. #define PD(BIT) (BIT + 48)
  92. #define PE(BIT) (BIT + 64)
  93. // Virtual pin decoding
  94. #define GPIOREG(VPIN) ((VPIN) >= 16 ? ((VPIN) >= 32 ? ((VPIN) >= 48 ? ((VPIN) >= 48 ? PEREG : PDREG) : PCREG) : PBREG) : PAREG)
  95. #define BITMASK(VPIN) (1 << ((VPIN % 16) & 15))
  96. #define vATN PB(14) // SCSI:ATN
  97. #define vBSY PB(6) // SCSI:BSY
  98. #define vACK PB(7) // SCSI:ACK
  99. #define vRST PA(15) // SCSI:RST
  100. #define vMSG PE(2) // SCSI:MSG
  101. #define vSEL PE(3) // SCSI:SEL
  102. #define vCD PE(4) // SCSI:C/D
  103. #define vREQ PE(5) // SCSI:REQ
  104. #define vIO PE(6) // SCSI:I/O
  105. #define vSD_CS PB(1) // SDCARD:CS
  106. #define vDTD PC(0) // SCSI:DTD
  107. #define vIND PC(1) // SCSI:IND
  108. #define vTAD PC(2) // SCSI:TAD
  109. #define vTRANS_OE PB(12) // SCSI:TRANS_OE
  110. // SCSI output pin control: active LOW (direct pin drive)
  111. #define SCSI_OUT(VPIN,ACTIVE) { GPIOREG(VPIN)->BSRR = BITMASK(VPIN) << ((ACTIVE) ? 16 : 0); }
  112. // SCSI input pin check (inactive=0,active=1)
  113. #define SCSI_IN(VPIN) ((~GPIOREG(VPIN)->IDR >> ((VPIN % 16) & 15)) & 1)
  114. // HDDiamge file
  115. #define HDIMG_ID_POS 2 // Position to embed ID number
  116. #define HDIMG_LUN_POS 3 // Position to embed LUN numbers
  117. #define HDIMG_BLK_POS 5 // Position to embed block size numbers
  118. #define MAX_FILE_PATH 32 // Maximum file name length
  119. // SCSI
  120. #define SCSI_INFO_BUF_SIZE 36
  121. #define SCSI_INFO_VENDOR_SIZE 9
  122. #define SCSI_INFO_PRODUCT_SIZE 17
  123. #define SCSI_INFO_VERSION_SIZE 5
  124. typedef struct hddimg_struct
  125. {
  126. FsFile m_file; // File object
  127. uint64_t m_fileSize; // File size
  128. size_t m_blocksize; // SCSI BLOCK size
  129. }HDDIMG;
  130. // Declare functions
  131. void onFalseInit(void);
  132. void onBusReset(void);
  133. void switchImage(void);
  134. void initFileLog(void);
  135. void finalizeFileLog(void);
  136. // SCSI config
  137. #define MAX_SCSIID 7 // Maximum number of supported SCSI-IDs (The minimum is 0)
  138. #define MAX_SCSILUN 8 // Maximum number of LUNs supported (The minimum is 0)
  139. #define NUM_SCSIID MAX_SCSIID // Number of enabled SCSI IDs
  140. #define NUM_SCSILUN 1 // Number of enabled LUNs
  141. #define READ_PARITY_CHECK 0 // Perform read parity check (unverified)
  142. #define DEFAULT_SCSI_ID 1
  143. #define DEFAULT_SCSI_LUN 0
  144. #define SCSI_BUF_SIZE 512 // Size of the SCSI Buffer
  145. #define HDD_BLOCK_SIZE 512
  146. #define OPTICAL_BLOCK_SIZE 2048
  147. // HDD format
  148. #define MAX_BLOCKSIZE 4096 // Maximum BLOCK size
  149. // LED ERRORS
  150. #define ERROR_FALSE_INIT 3
  151. #define ERROR_NO_SDCARD 5
  152. enum SCSI_DEVICE_TYPE
  153. {
  154. SCSI_DEVICE_HDD,
  155. SCSI_DEVICE_OPTICAL,
  156. };
  157. #define CDROM_RAW_SECTORSIZE 2352
  158. #define CDROM_COMMON_SECTORSIZE 2048
  159. #define MAX_SCSI_COMMAND 0xff
  160. #define SCSI_COMMAND_HANDLER(x) static byte x(SCSI_DEVICE *dev, const byte *cdb)
  161. #define ATN PB14 // SCSI:ATN
  162. #define BSY PB6 // SCSI:BSY
  163. #define ACK PB7 // SCSI:ACK
  164. #define RST PA15 // SCSI:RST
  165. #define MSG PE2 // SCSI:MSG
  166. #define SEL PE3 // SCSI:SEL
  167. #define CD PE4 // SCSI:C/D
  168. #define REQ PE5 // SCSI:REQ
  169. #define IO PB1 // SCSI:I/O
  170. #define LED1 PA4 // LED
  171. #define LED2 PA5 // Driven LED
  172. #define LED3 PA6 // Driven LED
  173. // Image Set Selector
  174. #define IMAGE_SELECT1 PC4
  175. #define IMAGE_SELECT2 PC5
  176. #define NOP(x) for(unsigned _nopcount = x; _nopcount; _nopcount--) { asm("NOP"); }
  177. /* SCSI Timing delays */
  178. // Due to limitations in timing granularity all of these are "very" rough estimates
  179. #define SCSI_BUS_SETTLE() NOP(30); // spec 400ns ours ~420us
  180. #define SCSI_DATA_RELEASE() NOP(30); // spec 400ns ours ~420us
  181. #define SCSI_HOLD_TIME() asm("NOP"); asm("NOP"); asm("NOP"); // spec 45ns ours ~42ns
  182. #define SCSI_DESKEW() // asm("NOP"); asm("NOP"); asm("NOP"); // spec 45ns ours ~42ns
  183. #define SCSI_CABLE_SKEW() // asm("NOP"); // spec 10ns ours ~14ns
  184. #define SCSI_RESET_HOLD() asm("NOP"); asm("NOP"); // spec 25ns ours ~28ns
  185. #define SCSI_DISCONNECTION_DELAY() NOP(15); // spec 200ns ours ~210ns
  186. /* SCSI phases
  187. +=============-===============-==================================-============+
  188. | Signal | Phase name | Direction of transfer | Comment |
  189. |-------------| | | |
  190. | MSG|C/D|I/O | | | |
  191. |----+---+----+---------------+----------------------------------+------------|
  192. | 0 | 0 | 0 | DATA OUT | Initiator to target \ | Data |
  193. | 0 | 0 | 1 | DATA IN | Initiator from target / | phase |
  194. | 0 | 1 | 0 | COMMAND | Initiator to target | |
  195. | 0 | 1 | 1 | STATUS | Initiator from target | |
  196. | 1 | 0 | 0 | * | | |
  197. | 1 | 0 | 1 | * | | |
  198. | 1 | 1 | 0 | MESSAGE OUT | Initiator to target \ | Message |
  199. | 1 | 1 | 1 | MESSAGE IN | Initiator from target / | phase |
  200. |-----------------------------------------------------------------------------|
  201. | Key: 0 = False, 1 = True, * = Reserved for future standardization |
  202. +=============================================================================+
  203. */
  204. // SCSI phase change as single write to port B
  205. #define SCSIPHASEMASK(MSGACTIVE, CDACTIVE, IOACTIVE) ((BITMASK(vMSG)<<((MSGACTIVE)?16:0)) | (BITMASK(vCD)<<((CDACTIVE)?16:0)) | (BITMASK(vIO)<<((IOACTIVE)?16:0)))
  206. #define SCSI_PHASE_DATAOUT SCSIPHASEMASK(inactive, inactive, inactive)
  207. #define SCSI_PHASE_DATAIN SCSIPHASEMASK(inactive, inactive, active)
  208. #define SCSI_PHASE_COMMAND SCSIPHASEMASK(inactive, active, inactive)
  209. #define SCSI_PHASE_STATUS SCSIPHASEMASK(inactive, active, active)
  210. #define SCSI_PHASE_MESSAGEOUT SCSIPHASEMASK(active, active, inactive)
  211. #define SCSI_PHASE_MESSAGEIN SCSIPHASEMASK(active, active, active)
  212. #define SCSI_PHASE_CHANGE(MASK) { PBREG->BSRR = (MASK); }
  213. //BLACKSASI clean this up and use defines
  214. // Data pins
  215. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  216. static const uint32_t scsiDbOutputRegOr_PDREG = 0b00000000000000000101010101010101;
  217. static const uint32_t scsiDbInputOutputAnd_PDREG = 0b00000000000000000000000000000000;
  218. static const uint32_t scsiDbInputOutputPullAnd_PDREG = 0b00000000000000000101010101010101;
  219. // Control pins
  220. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  221. static const uint32_t scsiDbOutputRegOr_PEREG = 0b00000000000000000000000000000001;
  222. static const uint32_t scsiDbInputOutputAnd_PEREG = 0b00000000000000000011111111110000;
  223. static const uint32_t scsiDbInputOutputPullAnd_PEREG = 0b00000000000000000001010101010001;
  224. // Put DB and DP in output mode and control buffers
  225. #define SCSI_DB_OUTPUT() { PDREG->MODER = (PDREG->MODER & scsiDbInputOutputAnd_PDREG) | scsiDbOutputRegOr_PDREG; PEREG->MODER = (PEREG->MODER & scsiDbInputOutputAnd_PEREG) | scsiDbOutputRegOr_PEREG; SCSI_DATABUS_OUT() ;}
  226. // Put DB and DP in input mode and control buffers
  227. #define SCSI_DB_INPUT() { PDREG->MODER = (PDREG->MODER & scsiDbInputOutputAnd_PDREG); PEREG->MODER = (PEREG->MODER & scsiDbInputOutputAnd_PEREG); SCSI_DATABUS_IN();}
  228. #define SCSI_SET_PULL() { PDREG->PUPDR |= scsiDbInputOutputPullAnd_PDREG; PEREG->PUPDR |= scsiDbInputOutputPullAnd_PEREG; }
  229. /*
  230. static const uint32_t scsiDbOutputRegOr = 0x55150011;
  231. static const uint32_t scsiDbInputOutputAnd = 0x00C0FFCC;
  232. // Put DB and DP in output mode
  233. #define SCSI_DB_OUTPUT() { PBREG->MODER = (PBREG->MODER & scsiDbInputOutputAnd) | scsiDbOutputRegOr; }
  234. // Put DB and DP in input mode
  235. #define SCSI_DB_INPUT() { PBREG->MODER = (PBREG->MODER & scsiDbInputOutputAnd); }
  236. */
  237. #if XCVR == 1
  238. #define TR_TARGET PC2 // Target Transceiver Control Pin
  239. #define TR_DBP PC0 // Data Pins Transceiver Control Pin
  240. #define TR_INITIATOR PC1 // Initiator Transciever Control Pin
  241. #define vTR_TARGET PC(2) // Target Transceiver Control Pin
  242. #define vTR_DBP PC(0) // Data Pins Transceiver Control Pin
  243. #define vTR_INITIATOR PC(1) // Initiator Transciever Control Pin
  244. #define TR_INPUT 0
  245. #define TR_OUTPUT 1
  246. // Transceiver control definitions
  247. #define TRANSCEIVER_IO_SET(VPIN,TR_INPUT) { GPIOREG(VPIN)->BSRR = BITMASK(VPIN) << ((TR_INPUT) ? 16 : 0); }
  248. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  249. static const uint32_t SCSI_TARGET_PORTD_AND = 0b11111111111111111100111111111111;
  250. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  251. static const uint32_t SCSI_TARGET_PORTD_OR = 0b00000000000000000001000000000000;
  252. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  253. static const uint32_t SCSI_TARGET_PORTE_AND = 0b11111111111111111100000110000011;
  254. // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  255. static const uint32_t SCSI_TARGET_PORTE_OR = 0b00000000000000000001010100010000;
  256. // Turn on the output only for BSY
  257. #define SCSI_BSY_ACTIVE() { PEREG->MODER = (PEREG->MODER & SCSI_TARGET_PORTE_AND) | SCSI_TARGET_PORTE_OR; PDREG->MODER = (PDREG->MODER & SCSI_TARGET_PORTD_AND) | SCSI_TARGET_PORTD_OR; SCSI_OUT(vBSY, active) }
  258. // BSY,REQ,MSG,CD,IO Turn off output, BSY is the last input
  259. #define SCSI_TARGET_INACTIVE() { PEREG->MODER = (PEREG->MODER & SCSI_TARGET_PORTE_AND); PDREG->MODER = (PDREG->MODER & SCSI_TARGET_PORTD_AND); TRANSCEIVER_IO_SET(vTR_TARGET,TR_INPUT); }
  260. #define SCSI_TARGET_ACTIVE() { PEREG->MODER = (PEREG->MODER & SCSI_TARGET_PORTE_AND) | SCSI_TARGET_PORTE_OR; PDREG->MODER = (PDREG->MODER & SCSI_TARGET_PORTD_AND) | SCSI_TARGET_PORTD_OR; }
  261. #else
  262. // Turn on the output only for BSY
  263. #define SCSI_BSY_ACTIVE() { pinMode(BSY, OUTPUT_OPEN_DRAIN); SCSI_OUT(vBSY, active) }
  264. // BSY,REQ,MSG,CD,IO Turn off output, BSY is the last input
  265. #define SCSI_TARGET_INACTIVE() { SCSI_OUT(vREQ,inactive); SCSI_PHASE_CHANGE(SCSI_PHASE_DATAOUT); SCSI_OUT(vBSY,inactive); pinMode(BSY, INPUT); }
  266. // BSY,REQ,MSG,CD,IO Turn on the output (no change required for OD)
  267. #define SCSI_TARGET_ACTIVE() { }
  268. #endif
  269. // HDDimage file
  270. #define HDIMG_ID_POS 2 // Position to embed ID number
  271. #define HDIMG_LUN_POS 3 // Position to embed LUN numbers
  272. #define HDIMG_BLK_POS 5 // Position to embed block size numbers
  273. #define MAX_FILE_PATH 64 // Maximum file name length
  274. /*
  275. * Data byte to BSRR register setting value and parity table
  276. */
  277. /**
  278. * BSRR register generator
  279. * Totally configurable for which pin is each data bit, which pin is PTY, and which pin is REQ.
  280. * The only requirement is that data and parity pins are in the same GPIO block.
  281. * REQ can be specified as -1 to ignore, as it doesn't have to be in the same GPIO block.
  282. * This is dramatically slower than the original static array, but is easier to configure
  283. */
  284. static uint32_t genBSRR(uint32_t data) {
  285. uint8_t masks[] = {0UL, 1UL, 2UL, 3UL, 4UL, 5UL, 6UL, 7UL};
  286. // Positions array indicates which bit position each data bit goes in
  287. // positions[0] is for data bit 0, position[1] for data bit 1, etc
  288. // DB0, DB1, DB2, DB4, DB5, DB6, DB7 in order
  289. uint8_t positions[] = {8UL, 9UL, 10UL, 2UL, 12UL, 13UL, 14UL, 15UL};
  290. uint8_t dbpPosition = 0UL;
  291. int reqPosition = 6;
  292. uint8_t bitsAsserted = 0;
  293. uint32_t output = 0x00000000;
  294. for (int i = 0; i < 8; i++) {
  295. if (data & (0x1 << masks[i])) {
  296. // There's a one in this bit position, BSRR reset
  297. output |= 0x1 << (positions[i] + 16);
  298. bitsAsserted++;
  299. } else {
  300. // There's a 0 in this bit position, BSRR set high
  301. output |= (0x1 << positions[i]);
  302. }
  303. }
  304. // Set the parity bit
  305. if (bitsAsserted % 2 == 0) {
  306. // Even number of bits asserted, Parity asserted (0, low, BSRR reset)
  307. output |= 0x01 << (dbpPosition + 16);
  308. } else {
  309. // Odd number of bits asserted, Parity deasserted (1, high, BSRR set)
  310. output |= 0x01 << dbpPosition;
  311. }
  312. // BSRR set REQ if specified
  313. // Only set > 0 if it's in the same GPIO block as DB and DBP
  314. if (reqPosition >= 0) {
  315. output |= 0x01 << reqPosition;
  316. }
  317. return output;
  318. }
  319. // BSRR register control value that simultaneously performs DB set, DP set, and REQ = H (inactrive)
  320. //uint32_t db_bsrr[256];
  321. // Parity bit acquisition
  322. #define PARITY(DB) (db_bsrr[DB]&1)
  323. // #define GET_CDB6_LBA(x) ((x[2] & 01f) << 16) | (x[3] << 8) | x[4]
  324. #define READ_DATA_BUS() (byte)((~(uint32_t)GPIOB->regs->IDR)>>8)
  325. struct SCSI_INQUIRY_DATA
  326. {
  327. union
  328. {
  329. struct {
  330. // bitfields are in REVERSE order for ARM
  331. // byte 0
  332. byte peripheral_device_type:5;
  333. byte peripheral_qualifier:3;
  334. // byte 1
  335. byte reserved_byte2:7;
  336. byte rmb:1;
  337. // byte 2
  338. byte ansi_version:3;
  339. byte always_zero_byte3:5;
  340. // byte 3
  341. byte response_format:4;
  342. byte reserved_byte4:2;
  343. byte tiop:1;
  344. byte always_zero_byte4:1;
  345. // byte 4
  346. byte additional_length;
  347. // byte 5-6
  348. byte reserved_byte5;
  349. byte reserved_byte6;
  350. // byte 7
  351. byte sync:1;
  352. byte always_zero_byte7_more:4;
  353. byte always_zero_byte7:3;
  354. // byte 8-15
  355. char vendor[8];
  356. // byte 16-31
  357. char product[16];
  358. // byte 32-35
  359. char revision[4];
  360. // byte 36
  361. byte release;
  362. // 37-46
  363. char revision_date[10];
  364. };
  365. // raw bytes
  366. byte raw[64];
  367. };
  368. };
  369. // HDD image
  370. typedef __attribute__((aligned(4))) struct _SCSI_DEVICE
  371. {
  372. FsFile *m_file; // File object
  373. uint64_t m_fileSize; // File size
  374. uint16_t m_blocksize; // SCSI BLOCK size
  375. uint16_t m_rawblocksize; // OPTICAL raw sector size
  376. uint8_t m_type; // SCSI device type
  377. uint32_t m_blockcount; // blockcount
  378. bool m_raw; // Raw disk
  379. SCSI_INQUIRY_DATA *inquiry_block; // SCSI information
  380. uint8_t m_senseKey; // Sense key
  381. uint16_t m_additional_sense_code; // ASC/ASCQ
  382. bool m_mode2; // MODE2 CDROM
  383. uint8_t m_sector_offset; // optical sector offset for missing sync header
  384. } SCSI_DEVICE;
  385. #endif // __BLACKSASI_H__