Эх сурвалжийг харах

Merge pull request #97 from erichelgeson/eric/minor_cleanup

Implement Test Unit Ready & minor cleanup
Eric Helgeson 3 жил өмнө
parent
commit
c04027c8ca
5 өөрчлөгдсөн 216 нэмэгдсэн , 267 устгасан
  1. 4 0
      platformio.ini
  2. 82 267
      src/BlueSCSI.cpp
  3. 84 0
      src/scsi_cmds.h
  4. 32 0
      src/scsi_sense.h
  5. 14 0
      src/scsi_status.h

+ 4 - 0
platformio.ini

@@ -1,4 +1,8 @@
 ; PlatformIO Project Configuration File https://docs.platformio.org/page/projectconf.html
+
+[platformio]
+default_envs = STM32F103C8
+
 [env]
 framework = arduino
 lib_deps =

+ 82 - 267
src/BlueSCSI.cpp

@@ -38,6 +38,9 @@
 #include <Arduino.h> // For Platform.IO
 #include <SdFat.h>
 #include <setjmp.h>
+#include "scsi_cmds.h"
+#include "scsi_sense.h"
+#include "scsi_status.h"
 
 #ifdef USE_STM32_DMA
 #warning "warning USE_STM32_DMA"
@@ -47,12 +50,6 @@
                                 // 1: Debug information output to USB Serial
                                 // 2: Debug information output to LOG.txt (slow)
 
-#define SCSI_SELECT      0      // 0 for STANDARD
-                                // 1 for SHARP X1turbo
-                                // 2 for NEC PC98
-#define READ_SPEED_OPTIMIZE  1  // Faster reads
-#define WRITE_SPEED_OPTIMIZE 1  // Speeding up writes
-
 // SCSI config
 #define NUM_SCSIID  7          // Maximum number of supported SCSI-IDs (The minimum is 0)
 #define NUM_SCSILUN 2          // Maximum number of LUNs supported     (The minimum is 0)
@@ -620,6 +617,18 @@ void findDriveImages(FsFile root) {
           }
         }
 
+        if(file_name_length > 3) { // HDN[N]
+          int tmp_lun = name[HDIMG_LUN_POS] - '0';
+
+          // If valid lun, set it, else use default
+          if(tmp_lun == 0 || tmp_lun == 1) {
+            lun = tmp_lun;
+          } else {
+            LOG_FILE.print(name);
+            LOG_FILE.println(" - bad SCSI LUN in filename, Using default LUN ID 0");
+          }
+        }
+
         int blk1 = 0, blk2, blk3, blk4 = 0;
         if(file_name_length > 8) { // HD00_[111]
           blk1 = name[HDIMG_BLK_POS] - '0';
@@ -667,8 +676,6 @@ void initFileLog(int success_mhz) {
   LOG_FILE.println(VERSION);
   LOG_FILE.print("DEBUG:");
   LOG_FILE.print(DEBUG);
-  LOG_FILE.print(" SCSI_SELECT:");
-  LOG_FILE.print(SCSI_SELECT);
   LOG_FILE.print(" SDFAT_FILE_TYPE:");
   LOG_FILE.println(SDFAT_FILE_TYPE);
   LOG_FILE.print("SdFat version: ");
@@ -789,15 +796,9 @@ void longjmpFromInterrupt(jmp_buf jmpb, int retval) {
  */
 void onBusReset(void)
 {
-#if SCSI_SELECT == 1
-  // SASI I / F for X1 turbo has RST pulse write cycle +2 clock ==
-  // I can't filter because it only activates about 1.25us
-  {{
-#else
   if(isHigh(gpio_read(RST))) {
     delayMicroseconds(20);
     if(isHigh(gpio_read(RST))) {
-#endif  
   // BUS FREE is done in the main process
 //      gpio_mode(MSG, GPIO_OUTPUT_OD);
 //      gpio_mode(CD,  GPIO_OUTPUT_OD);
@@ -872,7 +873,6 @@ inline void writeHandshake(byte d)
   while( SCSI_IN(vACK));
 }
 
-#if READ_SPEED_OPTIMIZE
 #pragma GCC push_options
 #pragma GCC optimize ("-Os")
 /*
@@ -934,7 +934,6 @@ void writeDataLoop(uint32_t blocksize, const byte* srcptr)
   WAIT_ACK_INACTIVE();
 }
 #pragma GCC pop_options
-#endif
 
 /*
  * Data in phase.
@@ -944,16 +943,10 @@ void writeDataPhase(int len, const byte* p)
 {
   LOGN("DATAIN PHASE");
   SCSI_PHASE_CHANGE(SCSI_PHASE_DATAIN);
-#if READ_SPEED_OPTIMIZE
   // Bus settle delay 400ns. Following code was measured at 800ns before REQ asserted. STM32F103.
   SCSI_DB_OUTPUT()
   writeDataLoop(len, p);
   SCSI_DB_INPUT()
-#else
-  for (int i = 0; i < len; i++) {
-    writeHandshake(p[i]);
-  }
-#endif
 }
 
 /*
@@ -976,13 +969,7 @@ void writeDataPhaseSD(uint32_t adds, uint32_t len)
     m_img->m_file.read(m_buf, m_img->m_blocksize);
     enableResetJmp();
 
-#if READ_SPEED_OPTIMIZE
     writeDataLoop(m_img->m_blocksize, m_buf);
-#else
-    for(int j = 0; j < m_img->m_blocksize; j++) {
-      writeHandshake(m_buf[j]);
-    }
-#endif
   }
   SCSI_DB_INPUT()
 #ifdef XCVR
@@ -990,7 +977,6 @@ void writeDataPhaseSD(uint32_t adds, uint32_t len)
 #endif
 }
 
-#if WRITE_SPEED_OPTIMIZE
 #pragma GCC push_options
 #pragma GCC optimize ("-Os")
     
@@ -1032,7 +1018,6 @@ void readDataLoop(uint32_t blockSize, byte* dstptr)
   WAIT_ACK_INACTIVE();
 }
 #pragma GCC pop_options
-#endif
 
 /*
  * Data out phase.
@@ -1043,12 +1028,7 @@ void readDataPhase(int len, byte* p)
   LOGN("DATAOUT PHASE");
   SCSI_PHASE_CHANGE(SCSI_PHASE_DATAOUT);
   // Bus settle delay 400ns. The following code was measured at 450ns before REQ asserted. STM32F103.
-#if WRITE_SPEED_OPTIMIZE
   readDataLoop(len, p);
-#else
-  for(uint32_t i = 0; i < len; i++)
-    p[i] = readHandshake();
-#endif
 }
 
 /*
@@ -1065,13 +1045,7 @@ void readDataPhaseSD(uint32_t adds, uint32_t len)
   m_img->m_file.seekSet(pos);
   for(uint32_t i = 0; i < len; i++) {
     m_resetJmp = true;
-#if WRITE_SPEED_OPTIMIZE
     readDataLoop(m_img->m_blocksize, m_buf);
-#else
-    for(int j = 0; j <  m_img->m_blocksize; j++) {
-      m_buf[j] = readHandshake();
-    }
-#endif
     m_resetJmp = false;
     m_img->m_file.write(m_buf, m_img->m_blocksize);
     // If a reset happened while writing, break and let the flush happen before it is handled.
@@ -1096,13 +1070,7 @@ void verifyDataPhaseSD(uint32_t adds, uint32_t len)
   uint64_t pos = (uint64_t)adds * m_img->m_blocksize;
   m_img->m_file.seekSet(pos);
   for(uint32_t i = 0; i < len; i++) {
-#if WRITE_SPEED_OPTIMIZE
     readDataLoop(m_img->m_blocksize, m_buf);
-#else
-    for(int j = 0; j <  m_img->m_blocksize; j++) {
-      m_buf[j] = readHandshake();
-    }
-#endif
     // This has just gone through the transfer to make things work, a compare would go here.
   }
 }
@@ -1110,31 +1078,11 @@ void verifyDataPhaseSD(uint32_t adds, uint32_t len)
 /*
  * INQUIRY command processing.
  */
-#if SCSI_SELECT == 2
-byte onInquiryCommand(byte len)
-{
-  byte buf[36] = {
-    0x00, //Device type
-    0x00, //RMB = 0
-    0x01, //ISO,ECMA,ANSI version
-    0x01, //Response data format
-    35 - 4, //Additional data length
-    0, 0, //Reserve
-    0x00, //Support function
-    'N', 'E', 'C', 'I', 'T', 'S', 'U', ' ',
-    'A', 'r', 'd', 'S', 'C', 'S', 'i', 'n', 'o', ' ', ' ',' ', ' ', ' ', ' ', ' ',
-    '0', '0', '1', '0',
-  };
-  writeDataPhase(len < 36 ? len : 36, buf);
-  return 0x00;
-}
-#else
 byte onInquiryCommand(byte len)
 {
   writeDataPhase(len < 36 ? len : 36, SCSI_INFO_BUF);
-  return 0x00;
+  return SCSI_STATUS_GOOD;
 }
-#endif
 
 /*
  * REQUEST SENSE command processing.
@@ -1163,9 +1111,9 @@ void onRequestSenseCommand(byte len)
 byte onReadCapacityCommand(byte pmi)
 {
   if(!m_img) {
-    m_senseKey = 2; // Not ready
-    m_addition_sense = 0x0403; // Logical Unit Not Ready, Manual Intervention Required
-    return 0x02; // Image file absent
+    m_senseKey = SCSI_SENSE_NOT_READY;
+    m_addition_sense = SCSI_ASC_LUN_NOT_READY_MANUAL_INTERVENTION_REQUIRED;
+    return SCSI_STATUS_CHECK_CONDITION;
   }
   
   uint32_t bl = m_img->m_blocksize;
@@ -1175,7 +1123,7 @@ byte onReadCapacityCommand(byte pmi)
     bl >> 24, bl >> 16, bl >> 8, bl    
   };
   writeDataPhase(8, buf);
-  return 0x00;
+  return SCSI_STATUS_GOOD;
 }
 
 /*
@@ -1185,18 +1133,18 @@ byte checkBlockCommand(uint32_t adds, uint32_t len)
 {
   // Check that image file is present
   if(!m_img) {
-    m_senseKey = 2; // Not ready
-    m_addition_sense = 0x0403; // Logical Unit Not Ready, Manual Intervention Required
-    return 0x02;
+    m_senseKey = SCSI_SENSE_NOT_READY;
+    m_addition_sense = SCSI_ASC_LUN_NOT_READY_MANUAL_INTERVENTION_REQUIRED;
+    return SCSI_STATUS_CHECK_CONDITION;
   }
   // Check block range is valid
   uint32_t bc = m_img->m_fileSize / m_img->m_blocksize;
   if (adds >= bc || (adds + len) > bc) {
-    m_senseKey = 5; // Illegal request
-    m_addition_sense = 0x2100; // Logical block address out of range
-    return 0x02;
+    m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
+    m_addition_sense = SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+    return SCSI_STATUS_CHECK_CONDITION;
   }
-  return 0x00;
+  return SCSI_STATUS_GOOD;
 }
 
 /*
@@ -1215,7 +1163,7 @@ byte onReadCommand(uint32_t adds, uint32_t len)
   LED_ON();
   writeDataPhaseSD(adds, len);
   LED_OFF();
-  return 0x00; //sts
+  return SCSI_STATUS_GOOD;
 }
 
 /*
@@ -1234,7 +1182,7 @@ byte onWriteCommand(uint32_t adds, uint32_t len)
   LED_ON();
   readDataPhaseSD(adds, len);
   LED_OFF();
-  return 0; //sts
+  return SCSI_STATUS_GOOD;
 }
 
 /*
@@ -1257,105 +1205,18 @@ byte onVerifyCommand(byte flags, uint32_t adds, uint32_t len)
     verifyDataPhaseSD(adds, len);
     LED_OFF();
   }
-  return 0x00;
+  return SCSI_STATUS_GOOD;
 }
 
 /*
  * MODE SENSE command processing.
  */
-#if SCSI_SELECT == 2
-byte onModeSenseCommand(byte scsi_cmd, byte dbd, int cmd2, uint32_t len)
-{
-  if(!m_img) {
-    m_senseKey = 2; // Not ready
-    m_addition_sense = 0x0403; // Logical Unit Not Ready, Manual Intervention Required
-    return 0x02; // Image file absent
-  }
-
-  int pageCode = cmd2 & 0x3F;
-
-  // Assuming sector size 512, number of sectors 25, number of heads 8 as default settings
-  int size = m_img->m_fileSize;
-  int cylinders = (int)(size >> 9);
-  cylinders >>= 3;
-  cylinders /= 25;
-  int sectorsize = 512;
-  int sectors = 25;
-  int heads = 8;
-  // Sector size
- int disksize = 0;
-  for(disksize = 16; disksize > 0; --(disksize)) {
-    if ((1 << disksize) == sectorsize)
-      break;
-  }
-  // Number of blocks
-  uint32_t diskblocks = (uint32_t)(size >> disksize);
-  memset(m_buf, 0, sizeof(m_buf)); 
-  int a = 4;
-  if(dbd == 0) {
-    uint32_t bl = m_img->m_blocksize;
-    uint32_t bc = m_img->m_fileSize / bl;
-    byte c[8] = {
-      0,// Density code
-      bc >> 16, bc >> 8, bc,
-      0, //Reserve
-      bl >> 16, bl >> 8, bl
-    };
-    memcpy(&m_buf[4], c, 8);
-    a += 8;
-    m_buf[3] = 0x08;
-  }
-  switch(pageCode) {
-  case 0x3F:
-  {
-    m_buf[a + 0] = 0x01;
-    m_buf[a + 1] = 0x06;
-    a += 8;
-  }
-  case 0x03:  // drive parameters
-  {
-    m_buf[a + 0] = 0x80 | 0x03; // Page code
-    m_buf[a + 1] = 0x16; // Page length
-    m_buf[a + 2] = (byte)(heads >> 8);// number of sectors / track
-    m_buf[a + 3] = (byte)(heads);// number of sectors / track
-    m_buf[a + 10] = (byte)(sectors >> 8);// number of sectors / track
-    m_buf[a + 11] = (byte)(sectors);// number of sectors / track
-    int size = 1 << disksize;
-    m_buf[a + 12] = (byte)(size >> 8);// number of sectors / track
-    m_buf[a + 13] = (byte)(size);// number of sectors / track
-    a += 24;
-    if(pageCode != 0x3F) {
-      break;
-    }
-  }
-  case 0x04:  // drive parameters
-  {
-      LOGN("AddDrive");
-      m_buf[a + 0] = 0x04; // Page code
-      m_buf[a + 1] = 0x12; // Page length
-      m_buf[a + 2] = (cylinders >> 16);// Cylinder length
-      m_buf[a + 3] = (cylinders >> 8);
-      m_buf[a + 4] = cylinders;
-      m_buf[a + 5] = heads;   // Number of heads
-      a += 20;
-    if(pageCode != 0x3F) {
-      break;
-    }
-  }
-  default:
-    break;
-  }
-  m_buf[0] = a - 1;
-  writeDataPhase(len < a ? len : a, m_buf);
-  return 0x00;
-}
-#else
 byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
 {
   if(!m_img) {
-    m_senseKey = 2; // Not ready
-    m_addition_sense = 0x0403; // Logical Unit Not Ready, Manual Intervention Required
-    return 0x02; // No image file
+    m_senseKey = SCSI_SENSE_NOT_READY;
+    m_addition_sense = SCSI_ASC_LUN_NOT_READY_MANUAL_INTERVENTION_REQUIRED;
+    return SCSI_STATUS_CHECK_CONDITION;
   }
 
   uint32_t bl =  m_img->m_blocksize;
@@ -1429,12 +1290,12 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
     break; // Don't want 0x3F falling through to error condition
 
   default:
-    m_senseKey = 5; // Illegal request
-    m_addition_sense = 0x2400; // Invalid field in CDB
-    return 0x02;
+    m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
+    m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB;
+    return SCSI_STATUS_CHECK_CONDITION;
     break;
   }
-  if(scsi_cmd == 0x5A) // MODE SENSE 10
+  if(scsi_cmd == SCSI_MODE_SENSE10)
   {
     m_buf[1] = a - 2;
     m_buf[7] = 0x08;
@@ -1445,16 +1306,15 @@ byte onModeSenseCommand(byte scsi_cmd, byte dbd, byte cmd2, uint32_t len)
     m_buf[3] = 0x08;
   }
   writeDataPhase(len < a ? len : a, m_buf);
-  return 0x00;
+  return SCSI_STATUS_GOOD;
 }
-#endif
     
 byte onModeSelectCommand(byte scsi_cmd, byte flags, uint32_t len)
 {
   if (len > MAX_BLOCKSIZE) {
-    m_senseKey = 5; // Illegal request
-    m_addition_sense = 0x2400; // Invalid field in CDB
-    return 0x02;
+    m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
+    m_addition_sense = SCSI_ASC_INVALID_FIELD_IN_CDB;
+    return SCSI_STATUS_CHECK_CONDITION;
   }
   readDataPhase(len, m_buf);
   //Apple HD SC Setup sends:
@@ -1465,62 +1325,22 @@ byte onModeSelectCommand(byte scsi_cmd, byte flags, uint32_t len)
     LOGHEX(m_buf[i]);LOG(" ");
   }
   LOGN("");
-  return 0x00;
-}
-    
-#if SCSI_SELECT == 1
-/*
- * dtc510b_setDriveparameter
- */
-#define PACKED  __attribute__((packed))
-typedef struct PACKED dtc500_cmd_c2_param_struct
-{
-  uint8_t StepPlusWidth;        // Default is 13.6usec (11)
-  uint8_t StepPeriod;         // Default is  3  msec.(60)
-  uint8_t StepMode;         // Default is  Bufferd (0)
-  uint8_t MaximumHeadAdress;      // Default is 4 heads (3)
-  uint8_t HighCylinderAddressByte;  // Default set to 0   (0)
-  uint8_t LowCylinderAddressByte;   // Default is 153 cylinders (152)
-  uint8_t ReduceWrietCurrent;     // Default is above Cylinder 128 (127)
-  uint8_t DriveType_SeekCompleteOption;// (0)
-  uint8_t Reserved8;          // (0)
-  uint8_t Reserved9;          // (0)
-} DTC510_CMD_C2_PARAM;
-
-static void logStrHex(const char *msg,uint32_t num)
-{
-    LOG(msg);
-    LOGHEXN(num);
+  return SCSI_STATUS_GOOD;
 }
 
-static byte dtc510b_setDriveparameter(void)
+/*
+ * Test Unit Ready command processing.
+*/
+byte onTestUnitReady()
 {
-  DTC510_CMD_C2_PARAM DriveParameter;
-  uint16_t maxCylinder;
-  uint16_t numLAD;
-  //uint32_t stepPulseUsec;
-  int StepPeriodMsec;
-
-  // receive paramter
-  writeDataPhase(sizeof(DriveParameter),(byte *)(&DriveParameter));
- 
-  maxCylinder =
-    (((uint16_t)DriveParameter.HighCylinderAddressByte)<<8) |
-    (DriveParameter.LowCylinderAddressByte);
-  numLAD = maxCylinder * (DriveParameter.MaximumHeadAdress+1);
-  //stepPulseUsec  = calcStepPulseUsec(DriveParameter.StepPlusWidth);
-  StepPeriodMsec = DriveParameter.StepPeriod*50;
-  logStrHex (" StepPlusWidth      : ",DriveParameter.StepPlusWidth);
-  logStrHex (" StepPeriod         : ",DriveParameter.StepPeriod   );
-  logStrHex (" StepMode           : ",DriveParameter.StepMode     );
-  logStrHex (" MaximumHeadAdress  : ",DriveParameter.MaximumHeadAdress);
-  logStrHex (" CylinderAddress    : ",maxCylinder);
-  logStrHex (" ReduceWrietCurrent : ",DriveParameter.ReduceWrietCurrent);
-  logStrHex (" DriveType/SeekCompleteOption : ",DriveParameter.DriveType_SeekCompleteOption);
-  logStrHex (" Maximum LAD        : ",numLAD-1);
-  return  0; // error result
+  // Check that image file is present
+  if(!m_img) {
+    m_senseKey = SCSI_SENSE_NOT_READY;
+    m_addition_sense = SCSI_ASC_MEDIUM_NOT_PRESENT;
+    return SCSI_STATUS_CHECK_CONDITION;
+  }
+  return SCSI_STATUS_GOOD;
 }
-#endif
 
 /*
  * MsgIn2.
@@ -1684,95 +1504,90 @@ void loop()
 
   LOGN("");
   switch(cmd[0]) {
-  case 0x00:
-    LOGN("[Test Unit]");
+  case SCSI_TEST_UNIT_READY:
+    LOGN("[Test Unit Ready]");
+    m_sts |= onTestUnitReady();
     break;
-  case 0x01:
+  case SCSI_REZERO_UNIT: // TODO: Implement me!
     LOGN("[Rezero Unit]");
     break;
-  case 0x03:
+  case SCSI_REQUEST_SENSE:
     LOGN("[RequestSense]");
     onRequestSenseCommand(cmd[4]);
     break;
-  case 0x04:
-    LOGN("[FormatUnit]");
+  case SCSI_FORMAT_UNIT4: // TODO: Implement me!
+    LOGN("[FormatUnit4]");
     break;
-  case 0x06:
-    LOGN("[FormatUnit]");
+  case SCSI_FORMAT_UNIT6: // TODO: Implement me!
+    LOGN("[FormatUnit6]");
     break;
-  case 0x07:
+  case SCSI_REASSIGN_BLOCKS: // TODO: Implement me!
     LOGN("[ReassignBlocks]");
     break;
-  case 0x08:
+  case SCSI_READ6:
     LOGN("[Read6]");
     m_sts |= onReadCommand((((uint32_t)cmd[1] & 0x1F) << 16) | ((uint32_t)cmd[2] << 8) | cmd[3], (cmd[4] == 0) ? 0x100 : cmd[4]);
     break;
-  case 0x0A:
+  case SCSI_WRITE6:
     LOGN("[Write6]");
     m_sts |= onWriteCommand((((uint32_t)cmd[1] & 0x1F) << 16) | ((uint32_t)cmd[2] << 8) | cmd[3], (cmd[4] == 0) ? 0x100 : cmd[4]);
     break;
-  case 0x0B:
+  case SCSI_SEEK6: // TODO: Implement me!
     LOGN("[Seek6]");
     break;
-  case 0x12:
+  case SCSI_INQUIRY:
     LOGN("[Inquiry]");
     m_sts |= onInquiryCommand(cmd[4]);
     break;
-  case 0x15:
+  case SCSI_MODE_SELECT6:
     LOGN("[ModeSelect6]");
     m_sts |= onModeSelectCommand(cmd[0], cmd[1], cmd[4]);
     break;
-  case 0x1A:
+  case SCSI_MODE_SENSE6:
     LOGN("[ModeSense6]");
     m_sts |= onModeSenseCommand(cmd[0], cmd[1]&0x80, cmd[2], cmd[4]);
     break;
-  case 0x1B:
+  case SCSI_START_STOP_UNIT: // TODO: Implement me!
     LOGN("[StartStopUnit]");
     break;
-  case 0x1E:
+  case SCSI_PREVENT_ALLOW_REMOVAL: // TODO: Implement me!
     LOGN("[PreAllowMed.Removal]");
     break;
-  case 0x25:
+  case SCSI_READ_CAPACITY:
     LOGN("[ReadCapacity]");
     m_sts |= onReadCapacityCommand(cmd[8]);
     break;
-  case 0x28:
+  case SCSI_READ10:
     LOGN("[Read10]");
     m_sts |= onReadCommand(((uint32_t)cmd[2] << 24) | ((uint32_t)cmd[3] << 16) | ((uint32_t)cmd[4] << 8) | cmd[5], ((uint32_t)cmd[7] << 8) | cmd[8]);
     break;
-  case 0x2A:
+  case SCSI_WRITE10:
     LOGN("[Write10]");
     m_sts |= onWriteCommand(((uint32_t)cmd[2] << 24) | ((uint32_t)cmd[3] << 16) | ((uint32_t)cmd[4] << 8) | cmd[5], ((uint32_t)cmd[7] << 8) | cmd[8]);
     break;
-  case 0x2B:
+  case SCSI_SEEK10: // TODO: Implement me!
     LOGN("[Seek10]");
     break;
-  case 0x2F:
+  case SCSI_VERIFY10:
     LOGN("[Verify10]");
     m_sts |= onVerifyCommand(cmd[1], ((uint32_t)cmd[2] << 24) | ((uint32_t)cmd[3] << 16) | ((uint32_t)cmd[4] << 8) | cmd[5], ((uint32_t)cmd[7] << 8) | cmd[8]);
     break;
-  case 0x35:
+  case SCSI_SYNCHRONIZE_CACHE: // TODO: Implement me!
     LOGN("[SynchronizeCache10]");
     break;
-  case 0x55:
+  case SCSI_MODE_SELECT10:
     LOGN("[ModeSelect10");
     m_sts |= onModeSelectCommand(cmd[0], cmd[1], ((uint32_t)cmd[7] << 8) | cmd[8]);
     break;
-  case 0x5A:
+  case SCSI_MODE_SENSE10:
     LOGN("[ModeSense10]");
     m_sts |= onModeSenseCommand(cmd[0], cmd[1] & 0x80, cmd[2], ((uint32_t)cmd[7] << 8) | cmd[8]);
     break;
-#if SCSI_SELECT == 1
-  case 0xc2:
-    LOGN("[DTC510B setDriveParameter]");
-    m_sts |= dtc510b_setDriveparameter();
-    break;
-#endif    
   default:
     LOGN("[*Unknown]");
-    m_sts |= 0x02;
-    m_senseKey = 5;  // Illegal request
-    m_addition_sense = 0x2000; // Invalid Command Operation Code
+    m_sts |= SCSI_STATUS_CHECK_CONDITION;
+    m_senseKey = SCSI_SENSE_ILLEGAL_REQUEST;
+    m_addition_sense = SCSI_ASC_INVALID_OPERATION_CODE;
     break;
   }
 

+ 84 - 0
src/scsi_cmds.h

@@ -0,0 +1,84 @@
+#ifndef __SCSI_CMDS_H__
+#define __SCSI_CMDS_H__
+
+// defines for SCSI commands
+#define SCSI_TEST_UNIT_READY        0
+#define SCSI_REZERO_UNIT            0x1
+#define SCSI_REQUEST_SENSE          0x3
+#define SCSI_FORMAT_UNIT4           0x4
+#define SCSI_FORMAT_UNIT6           0x6
+#define SCSI_REASSIGN_BLOCKS        0x7
+#define SCSI_READ6                  0x8
+#define SCSI_WRITE6                 0xA
+#define SCSI_SEEK6                  0xB
+#define SCSI_INQUIRY                0x12
+#define SCSI_MODE_SELECT6           0x15
+#define SCSI_RESERVE                0x16
+#define SCSI_RELEASE                0x17
+#define SCSI_COPY                   0x18
+#define SCSI_MODE_SENSE6            0x1A
+#define SCSI_START_STOP_UNIT        0x1B
+#define SCSI_RECV_DIAG_RESULTS      0x1C
+#define SCSI_SEND_DIAG              0x1D
+#define SCSI_PREVENT_ALLOW_REMOVAL  0x1E
+#define SCSI_READ_CAPACITY          0x25
+#define SCSI_READ10                 0x28
+#define SCSI_WRITE10                0x2A
+#define SCSI_SEEK10                 0x2B
+#define SCSI_WRITE_AND_VERIFY       0x2E
+#define SCSI_VERIFY10               0x2F
+#define SCSI_SEARCH_DATA_HIGH       0x30
+#define SCSI_SEARCH_DATA_EQUAL      0x31
+#define SCSI_SEARCH_DATA_LOW        0x32
+#define SCSI_SET_LIMITS             0x33
+#define SCSI_PREFETCH               0x34
+#define SCSI_SYNCHRONIZE_CACHE      0x35
+#define SCSI_LOCK_UNLOCK_CACHE      0x36
+#define SCSI_READ_DEFECT_DATA       0x37
+#define SCSI_COMPARE                0x39
+#define SCSI_COPY_AND_VERIFY        0x3A
+#define SCSI_WRITE_BUFFER           0x3B
+#define SCSI_READ_BUFFER            0x3C
+#define SCSI_READ_LONG              0x3E
+#define SCSI_WRITE_LONG             0x3F
+#define SCSI_CHANGE_DEFINITION      0x40
+#define SCSI_WRITE_SAME             0x41
+#define SCSI_LOG_SELECT             0x4C
+#define SCSI_LOG_SENSE              0x4D
+#define SCSI_MODE_SELECT10          0x55
+#define SCSI_MODE_SENSE10           0x5A
+#define SCSI_READ12                 0xA8
+#define SCSI_VERIFY12               0xAF
+
+
+#define SCSI_TOC_LENGTH 20 // length for default CDROM TOC
+
+// SCSI CDROM commands
+#define SCSI_AUDIO_SCAN1            0xBA
+#define SCSI_AUDIO_SCAN2            0xCD
+#define SCSI_PAUSE_RESUME           0x4B
+#define SCSI_PLAY_AUDIO10           0x45
+#define SCSI_PLAY_AUDIO12           0xA5
+#define SCSI_PLAY_AUDIO_MSF         0x47
+#define SCSI_PLAY_AUDIO_TRACK_IDX   0x48
+#define SCSI_PLAY_TRACK_RELATIVE10  0x49
+#define SCSI_PLAY_TRACK_RELATIVE12  0xA9
+#define SCSI_READ_CD                0xBE
+#define SCSI_READ_CD_DD             0xD8
+#define SCSI_READ_CD_MSF            0xB9
+#define SCSI_READ_CDDA_MSF          0xD9
+#define SCSI_READ_CDXA              0xDB
+#define SCSI_READ_ALL_SUBCODE       0xDF
+#define SCSI_READ_HEADER            0x44
+#define SCSI_READ_SUBCHANNEL        0x42
+#define SCSI_READ_TOC               0x43
+#define SCSI_READ_DISC_INFORMATION  0x51
+#define SCSI_READ_DVD_STRUCTURE     0xAD
+#define SCSI_SET_CDROM_SPEED1       0xBB
+#define SCSI_SET_CDROM_SPEED2       0xDA
+#define SCSI_STOP_PLAY_SCAN         0x4E
+#define SCSI_READ_CDP               0xE4
+#define SCSI_READ_DRIVE_STATUS      0xE0
+#define SCSI_WRITE_CDP              0xE3
+
+#endif // __SCSI_CMDS_H__

+ 32 - 0
src/scsi_sense.h

@@ -0,0 +1,32 @@
+#ifndef __SCSI_SENSE_H__
+#define __SCSI_SENSE_H__
+
+#define SCSI_SENSE_NO_SENSE         0
+#define SCSI_SENSE_RECOVERED_ERROR  0x1
+#define SCSI_SENSE_NOT_READY        0x2
+#define SCSI_SENSE_MEDUIM_ERROR     0x3
+#define SCSI_SENSE_HARDWARE_ERROR   0x4
+#define SCSI_SENSE_ILLEGAL_REQUEST  0x5
+#define SCSI_SENSE_UNIT_ATTENTION   0x6
+#define SCSI_SENSE_DATA_PROTECT     0x7
+#define SCSI_SENSE_BLANK_CHECK      0x8
+#define SCSI_SENSE_VENDOR_SPECIFIC  0x9
+#define SCSI_SENSE_COPY_ABORTED     0xa
+#define SCSI_SENSE_ABORTED_COMMAND  0xb
+#define SCSI_SENSE_EQUAL            0xc
+#define SCSI_SENSE_VOLUME_OVERFLOW  0xd
+#define SCSI_SENSE_MISCOMPARE       0xe
+#define SCSI_SENSE_RESERVED         0xf
+
+
+#define SCSI_ASC_INVALID_OPERATION_CODE                         0x2000
+#define SCSI_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE             0x2100
+#define SCSI_ASC_INVALID_FIELD_IN_CDB                           0x2400
+#define SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED                     0x2500
+#define SCSI_ASC_INVALID_FIELD_PARAMETER_LIST                   0x2600
+#define SCSI_ASC_WRITE_PROTECTED                                0x2700
+#define SCSI_ASC_CANNOT_READ_MEDIUM_UNKNOWN_FORMAT              0x3001
+#define SCSI_ASC_CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT         0x3002
+#define SCSI_ASC_MEDIUM_NOT_PRESENT                             0x3A00
+#define SCSI_ASC_LUN_NOT_READY_MANUAL_INTERVENTION_REQUIRED     0x0403
+#endif

+ 14 - 0
src/scsi_status.h

@@ -0,0 +1,14 @@
+#ifndef __SCSI_STATUS_H__
+#define __SCSI_STATUS_H__
+
+#define SCSI_STATUS_GOOD                            0
+#define SCSI_STATUS_CHECK_CONDITION                 0x2
+#define SCSI_STATUS_CONDITION_MET                   0x4
+#define SCSI_STATUS_BUSY                            0x8
+#define SCSI_STATUS_INTERMEDIATE                    0x16
+#define SCSI_STATUS_INTERMEDIATE_CONDITION_MET      0x20
+#define SCSI_STATUS_RESERVATION_CONFLICT            0x24
+#define SCSI_STATUS_COMMAND_TERMINATED              0x34
+#define SCSI_STATUS_QUEUE_FULL                      0x40
+
+#endif