V4.7 release fixes
authorMichael McMaster <michael@codesrc.com>
Sun, 12 Mar 2017 04:15:05 +0000 (14:15 +1000)
committerMichael McMaster <michael@codesrc.com>
Sun, 12 Mar 2017 04:15:05 +0000 (14:15 +1000)
18 files changed:
CHANGELOG
software/SCSI2SD/src/config.c
software/SCSI2SD/src/inquiry.c
software/SCSI2SD/src/scsi.c
software/SCSI2SD/src/scsi.h
software/SCSI2SD/src/scsiPhy.c
software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit
software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyprj
software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit
software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyprj
software/include/scsi2sd.h
software/scsi2sd-util/ConfigUtil.cc [changed mode: 0644->0755]
software/scsi2sd-util/Makefile
software/scsi2sd-util/TargetPanel.cc [changed mode: 0644->0755]
software/scsi2sd-util/scsi2sd-util.cc
software/scsi2sd-util/wxWidgets/src/osx/carbon/dataobj.cpp [changed mode: 0644->0755]
software/scsi2sd-util/wxWidgets/src/osx/core/bitmap.cpp [changed mode: 0644->0755]
software/scsi2sd-util/wxWidgets/src/stc/scintilla/src/Editor.cxx

index e773d33..00010ff 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,15 @@
-2016xxxx               4.x
+20170312               4.7
+       - Fix bug in SCSI Inquiry command for SCSI2 hosts
+       - Added OMTI host quirks mode
+       - Fix for booting from early Mac Plus ROMS
+       - Performance fix when SCSI2 mode is enabled. Some users may need
+       to disable SCSI2 mode if it was incorrectly enabled previously.
        - Added support for configurable mode pages
+       - Fix for exporting selectionDelay/startupDelay parameters to XML
+       via scsi2sd-util
+       - scsi2sd-util is now built with libudev1 on Linux, as all distros have
+       moved to this version. Users on older Linux distributions will need to
+       compile from source.
 
 20160111               4.6
        - Fixed bug when using sector size that isn't a multiple of 4
index eed072d..c5172e9 100755 (executable)
@@ -33,7 +33,7 @@
 \r
 #include <string.h>\r
 \r
-static const uint16_t FIRMWARE_VERSION = 0x0460;\r
+static const uint16_t FIRMWARE_VERSION = 0x0470;\r
 \r
 // 1 flash row\r
 static const uint8_t DEFAULT_CONFIG[256] =\r
@@ -418,13 +418,24 @@ void configSave(int scsiId, uint16_t bytesPerSector)
 \r
 const TargetConfig* getConfigByIndex(int i)\r
 {\r
-       size_t row = SCSI_CONFIG_0_ROW + (i * SCSI_CONFIG_ROWS);\r
-       return (const TargetConfig*)\r
-               (\r
-                       CY_FLASH_BASE +\r
-                       (CY_FLASH_SIZEOF_ARRAY * (size_t) SCSI_CONFIG_ARRAY) +\r
-                       (CY_FLASH_SIZEOF_ROW * row)\r
-                       );\r
+       if (i <= 3)\r
+       {\r
+               size_t row = SCSI_CONFIG_0_ROW + (i * SCSI_CONFIG_ROWS);\r
+               return (const TargetConfig*)\r
+                       (\r
+                               CY_FLASH_BASE +\r
+                               (CY_FLASH_SIZEOF_ARRAY * (size_t) SCSI_CONFIG_ARRAY) +\r
+                               (CY_FLASH_SIZEOF_ROW * row)\r
+                               );\r
+       } else {\r
+               size_t row = SCSI_CONFIG_4_ROW + ((i-4) * SCSI_CONFIG_ROWS);\r
+               return (const TargetConfig*)\r
+                       (\r
+                               CY_FLASH_BASE +\r
+                               (CY_FLASH_SIZEOF_ARRAY * (size_t) SCSI_CONFIG_ARRAY) +\r
+                               (CY_FLASH_SIZEOF_ROW * row)\r
+                               );\r
+       }\r
 }\r
 \r
 const TargetConfig* getConfigById(int scsiId)\r
index bc85904..9545475 100755 (executable)
-//     Copyright (C) 2013 Michael McMaster <michael@codesrc.com>\r
-//\r
-//     This file is part of SCSI2SD.\r
-//\r
-//     SCSI2SD is free software: you can redistribute it and/or modify\r
-//     it under the terms of the GNU General Public License as published by\r
-//     the Free Software Foundation, either version 3 of the License, or\r
-//     (at your option) any later version.\r
-//\r
-//     SCSI2SD is distributed in the hope that it will be useful,\r
-//     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-//     GNU General Public License for more details.\r
-//\r
-//     You should have received a copy of the GNU General Public License\r
-//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.\r
-#pragma GCC push_options\r
-#pragma GCC optimize("-flto")\r
-\r
-#include "device.h"\r
-#include "scsi.h"\r
-#include "config.h"\r
-#include "inquiry.h"\r
-\r
-#include <string.h>\r
-\r
-static uint8 StandardResponse[] =\r
-{\r
-0x00, // "Direct-access device". AKA standard hard disk\r
-0x00, // device type modifier\r
-0x02, // Complies with ANSI SCSI-2.\r
-0x01, // Response format is compatible with the old CCS format.\r
-0x1f, // standard length.\r
-0, 0, // Reserved\r
-0x08 // Enable linked commands\r
-};\r
-// Vendor set by config 'c','o','d','e','s','r','c',' ',\r
-// prodId set by config'S','C','S','I','2','S','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',\r
-// Revision set by config'2','.','0','a'\r
-\r
-/* For reference, here's a dump from an Apple branded 500Mb drive from 1994.\r
-$ sudo sg_inq -H /dev/sdd --len 255\r
-standard INQUIRY:\r
- 00     00 00 02 01 31 00 00 18  51 55 41 4e 54 55 4d 20    ....1...QUANTUM \r
- 10     4c 50 53 32 37 30 20 20  20 20 20 20 20 20 20 20    LPS270          \r
- 20     30 39 30 30 00 00 00 d9  b0 27 34 01 04 b3 01 1b    0900.....'4.....\r
- 30     07 00 a0 00 00 ff                                   ......\r
- Vendor identification: QUANTUM \r
- Product identification: LPS270          \r
- Product revision level: 0900\r
-*/\r
-\r
-\r
-static const uint8 SupportedVitalPages[] =\r
-{\r
-0x00, // "Direct-access device". AKA standard hard disk\r
-0x00, // Page Code\r
-0x00, // Reserved\r
-0x04, // Page length\r
-0x00, // Support "Supported vital product data pages"\r
-0x80, // Support "Unit serial number page"\r
-0x81, // Support "Implemented operating definition page"\r
-0x82 // Support "ASCII Implemented operating definition page"\r
-};\r
-\r
-static const uint8 UnitSerialNumber[] =\r
-{\r
-0x00, // "Direct-access device". AKA standard hard disk\r
-0x80, // Page Code\r
-0x00, // Reserved\r
-0x10, // Page length\r
-'c','o','d','e','s','r','c','-','1','2','3','4','5','6','7','8'\r
-};\r
-\r
-static const uint8 ImpOperatingDefinition[] =\r
-{\r
-0x00, // "Direct-access device". AKA standard hard disk\r
-0x81, // Page Code\r
-0x00, // Reserved\r
-0x03, // Page length\r
-0x03, // Current: SCSI-2 operating definition\r
-0x03, // Default: SCSI-2 operating definition\r
-0x03 // Supported (list): SCSI-2 operating definition.\r
-};\r
-\r
-static const uint8 AscImpOperatingDefinition[] =\r
-{\r
-0x00, // "Direct-access device". AKA standard hard disk\r
-0x82, // Page Code\r
-0x00, // Reserved\r
-0x07, // Page length\r
-0x06, // Ascii length\r
-'S','C','S','I','-','2'\r
-};\r
-\r
-static void useCustomVPD(const TargetConfig* cfg, int pageCode)\r
-{\r
-       int cfgIdx = 0;\r
-       int found = 0;\r
-       while ((cfgIdx < sizeof(cfg->vpd) - 4) &&\r
-               (cfg->vpd[cfgIdx + 3] != 0)\r
-               )\r
-       {\r
-               int pageSize = cfg->vpd[cfgIdx + 3] + 4;\r
-               int dataPageCode = cfg->vpd[cfgIdx + 1];\r
-               if (dataPageCode == pageCode)\r
-               {\r
-                       memcpy(scsiDev.data, &(cfg->vpd[cfgIdx]), pageSize);\r
-                       scsiDev.dataLen = pageSize;\r
-                       scsiDev.phase = DATA_IN;\r
-                       found = 1;\r
-                       break;\r
-               }\r
-               cfgIdx += pageSize;\r
-       }\r
-\r
-       if (!found)\r
-       {\r
-               // error.\r
-               scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
-               scsiDev.phase = STATUS;\r
-       }\r
-}\r
-\r
-void scsiInquiry()\r
-{\r
-       uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.\r
-       uint8 pageCode = scsiDev.cdb[2];\r
-       uint32 allocationLength = scsiDev.cdb[4];\r
-\r
-       // SASI standard, X3T9.3_185_RevE  states that 0 == 256 bytes\r
-       if (allocationLength == 0) allocationLength = 256;\r
-\r
-       if (!evpd)\r
-       {\r
-               if (pageCode)\r
-               {\r
-                       // error.\r
-                       scsiDev.status = CHECK_CONDITION;\r
-                       scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-                       scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
-                       scsiDev.phase = STATUS;\r
-               }\r
-               else\r
-               {\r
-                       const TargetConfig* config = scsiDev.target->cfg;\r
-                       memcpy(scsiDev.data, StandardResponse, sizeof(StandardResponse));\r
-                       scsiDev.data[1] = scsiDev.target->cfg->deviceTypeModifier;\r
-                       memcpy(&scsiDev.data[8], config->vendor, sizeof(config->vendor));\r
-                       memcpy(&scsiDev.data[16], config->prodId, sizeof(config->prodId));\r
-                       memcpy(&scsiDev.data[32], config->revision, sizeof(config->revision));\r
-                       scsiDev.dataLen = sizeof(StandardResponse) +\r
-                               sizeof(config->vendor) +\r
-                               sizeof(config->prodId) +\r
-                               sizeof(config->revision);\r
-                       scsiDev.phase = DATA_IN;\r
-               }\r
-       }\r
-       else if (scsiDev.target->cfg->vpd[3] != 0)\r
-       {\r
-               useCustomVPD(scsiDev.target->cfg, pageCode);\r
-       }\r
-       else if (pageCode == 0x00)\r
-       {\r
-               memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));\r
-               scsiDev.dataLen = sizeof(SupportedVitalPages);\r
-               scsiDev.phase = DATA_IN;\r
-       }\r
-       else if (pageCode == 0x80)\r
-       {\r
-               memcpy(scsiDev.data, UnitSerialNumber, sizeof(UnitSerialNumber));\r
-               scsiDev.dataLen = sizeof(UnitSerialNumber);\r
-               scsiDev.phase = DATA_IN;\r
-       }\r
-       else if (pageCode == 0x81)\r
-       {\r
-               memcpy(\r
-                       scsiDev.data,\r
-                       ImpOperatingDefinition,\r
-                       sizeof(ImpOperatingDefinition));\r
-               scsiDev.dataLen = sizeof(ImpOperatingDefinition);\r
-               scsiDev.phase = DATA_IN;\r
-       }\r
-       else if (pageCode == 0x82)\r
-       {\r
-               memcpy(\r
-                       scsiDev.data,\r
-                       AscImpOperatingDefinition,\r
-                       sizeof(AscImpOperatingDefinition));\r
-               scsiDev.dataLen = sizeof(AscImpOperatingDefinition);\r
-               scsiDev.phase = DATA_IN;\r
-       }\r
-       else\r
-       {\r
-               // error.\r
-               scsiDev.status = CHECK_CONDITION;\r
-               scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
-               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;\r
-               scsiDev.phase = STATUS;\r
-       }\r
-\r
-\r
-       if (scsiDev.phase == DATA_IN)\r
-       {\r
-               // "real" hard drives send back exactly allocationLenth bytes, padded\r
-               // with zeroes. This only seems to happen for Inquiry responses, and not\r
-               // other commands that also supply an allocation length such as Mode Sense or\r
-               // Request Sense.\r
-               // (See below for exception to this rule when 0 allocation length)\r
-               if (scsiDev.dataLen < allocationLength)\r
-               {\r
-                       memset(\r
-                               &scsiDev.data[scsiDev.dataLen],\r
-                               0,\r
-                               allocationLength - scsiDev.dataLen);\r
-               }\r
-               // Spec 8.2.5 requires us to simply truncate the response if it's\r
-               // too big.\r
-               scsiDev.dataLen = allocationLength;\r
-\r
-               // Set the device type as needed.\r
-               switch (scsiDev.target->cfg->deviceType)\r
-               {\r
-               case CONFIG_OPTICAL:\r
-                       scsiDev.data[0] = 0x05; // device type\r
-                       scsiDev.data[1] |= 0x80; // Removable bit.\r
-                       break;\r
-\r
-               case CONFIG_SEQUENTIAL:\r
-                       scsiDev.data[0] = 0x01; // device type\r
-                       scsiDev.data[1] |= 0x80; // Removable bit.\r
-                       break;\r
-                       \r
-               case CONFIG_MO:\r
-                       scsiDev.data[0] = 0x07; // device type\r
-                       scsiDev.data[1] |= 0x80; // Removable bit.\r
-                       break;\r
-\r
-               case CONFIG_FLOPPY_14MB:\r
-               case CONFIG_REMOVEABLE:\r
-                       scsiDev.data[1] |= 0x80; // Removable bit.\r
-                       break;\r
-                default:\r
-                       // Accept defaults for a fixed disk.\r
-                       break;\r
-               }\r
-       }\r
-\r
-       // Set the first byte to indicate LUN presence.\r
-       if (scsiDev.lun) // We only support lun 0\r
-       {\r
-               scsiDev.data[0] = 0x7F;\r
-       }\r
-}\r
-\r
-#pragma GCC pop_options\r
+//     Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
+//
+//     This file is part of SCSI2SD.
+//
+//     SCSI2SD is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+//
+//     SCSI2SD is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+//
+//     You should have received a copy of the GNU General Public License
+//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#pragma GCC push_options
+#pragma GCC optimize("-flto")
+
+#include "device.h"
+#include "scsi.h"
+#include "config.h"
+#include "inquiry.h"
+
+#include <string.h>
+
+static uint8 StandardResponse[] =
+{
+0x00, // "Direct-access device". AKA standard hard disk
+0x00, // device type modifier
+0x02, // Complies with ANSI SCSI-2.
+0x01, // Response format is compatible with the old CCS format.
+0x1f, // standard length.
+0, 0, // Reserved
+0x08 // Enable linked commands
+};
+// Vendor set by config 'c','o','d','e','s','r','c',' ',
+// prodId set by config'S','C','S','I','2','S','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',
+// Revision set by config'2','.','0','a'
+
+/* For reference, here's a dump from an Apple branded 500Mb drive from 1994.
+$ sudo sg_inq -H /dev/sdd --len 255
+standard INQUIRY:
+ 00     00 00 02 01 31 00 00 18  51 55 41 4e 54 55 4d 20    ....1...QUANTUM 
+ 10     4c 50 53 32 37 30 20 20  20 20 20 20 20 20 20 20    LPS270          
+ 20     30 39 30 30 00 00 00 d9  b0 27 34 01 04 b3 01 1b    0900.....'4.....
+ 30     07 00 a0 00 00 ff                                   ......
+ Vendor identification: QUANTUM 
+ Product identification: LPS270          
+ Product revision level: 0900
+*/
+
+
+static const uint8 SupportedVitalPages[] =
+{
+0x00, // "Direct-access device". AKA standard hard disk
+0x00, // Page Code
+0x00, // Reserved
+0x04, // Page length
+0x00, // Support "Supported vital product data pages"
+0x80, // Support "Unit serial number page"
+0x81, // Support "Implemented operating definition page"
+0x82 // Support "ASCII Implemented operating definition page"
+};
+
+static const uint8 UnitSerialNumber[] =
+{
+0x00, // "Direct-access device". AKA standard hard disk
+0x80, // Page Code
+0x00, // Reserved
+0x10, // Page length
+'c','o','d','e','s','r','c','-','1','2','3','4','5','6','7','8'
+};
+
+static const uint8 ImpOperatingDefinition[] =
+{
+0x00, // "Direct-access device". AKA standard hard disk
+0x81, // Page Code
+0x00, // Reserved
+0x03, // Page length
+0x03, // Current: SCSI-2 operating definition
+0x03, // Default: SCSI-2 operating definition
+0x03 // Supported (list): SCSI-2 operating definition.
+};
+
+static const uint8 AscImpOperatingDefinition[] =
+{
+0x00, // "Direct-access device". AKA standard hard disk
+0x82, // Page Code
+0x00, // Reserved
+0x07, // Page length
+0x06, // Ascii length
+'S','C','S','I','-','2'
+};
+
+static void useCustomVPD(const TargetConfig* cfg, int pageCode)
+{
+       int cfgIdx = 0;
+       int found = 0;
+       while ((cfgIdx < sizeof(cfg->vpd) - 4) &&
+               (cfg->vpd[cfgIdx + 3] != 0)
+               )
+       {
+               int pageSize = cfg->vpd[cfgIdx + 3] + 4;
+               int dataPageCode = cfg->vpd[cfgIdx + 1];
+               if (dataPageCode == pageCode)
+               {
+                       memcpy(scsiDev.data, &(cfg->vpd[cfgIdx]), pageSize);
+                       scsiDev.dataLen = pageSize;
+                       scsiDev.phase = DATA_IN;
+                       found = 1;
+                       break;
+               }
+               cfgIdx += pageSize;
+       }
+
+       if (!found)
+       {
+               // error.
+               scsiDev.status = CHECK_CONDITION;
+               scsiDev.target->sense.code = ILLEGAL_REQUEST;
+               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+               scsiDev.phase = STATUS;
+       }
+}
+
+void scsiInquiry()
+{
+       uint8 evpd = scsiDev.cdb[1] & 1; // enable vital product data.
+       uint8 pageCode = scsiDev.cdb[2];
+       uint32 allocationLength = scsiDev.cdb[4];
+
+       // SASI standard, X3T9.3_185_RevE  states that 0 == 256 bytes
+       // BUT SCSI 2 standard says 0 == 0.
+       if (scsiDev.compatMode <= COMPAT_SCSI1) // excludes COMPAT_SCSI2_DISABLED
+       {
+               if (allocationLength == 0) allocationLength = 256;
+       }
+
+       if (!evpd)
+       {
+               if (pageCode)
+               {
+                       // error.
+                       scsiDev.status = CHECK_CONDITION;
+                       scsiDev.target->sense.code = ILLEGAL_REQUEST;
+                       scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+                       scsiDev.phase = STATUS;
+               }
+               else
+               {
+                       const TargetConfig* config = scsiDev.target->cfg;
+                       memcpy(scsiDev.data, StandardResponse, sizeof(StandardResponse));
+                       scsiDev.data[1] = scsiDev.target->cfg->deviceTypeModifier;
+
+                       if (scsiDev.compatMode >= COMPAT_SCSI2)
+                       {
+                               scsiDev.data[3] = 2; // SCSI 2 response format.
+                       }
+                       memcpy(&scsiDev.data[8], config->vendor, sizeof(config->vendor));
+                       memcpy(&scsiDev.data[16], config->prodId, sizeof(config->prodId));
+                       memcpy(&scsiDev.data[32], config->revision, sizeof(config->revision));
+                       scsiDev.dataLen = sizeof(StandardResponse) +
+                               sizeof(config->vendor) +
+                               sizeof(config->prodId) +
+                               sizeof(config->revision);
+                       scsiDev.phase = DATA_IN;
+               }
+       }
+       else if (scsiDev.target->cfg->vpd[3] != 0)
+       {
+               useCustomVPD(scsiDev.target->cfg, pageCode);
+       }
+       else if (pageCode == 0x00)
+       {
+               memcpy(scsiDev.data, SupportedVitalPages, sizeof(SupportedVitalPages));
+               scsiDev.dataLen = sizeof(SupportedVitalPages);
+               scsiDev.phase = DATA_IN;
+       }
+       else if (pageCode == 0x80)
+       {
+               memcpy(scsiDev.data, UnitSerialNumber, sizeof(UnitSerialNumber));
+               scsiDev.dataLen = sizeof(UnitSerialNumber);
+               scsiDev.phase = DATA_IN;
+       }
+       else if (pageCode == 0x81)
+       {
+               memcpy(
+                       scsiDev.data,
+                       ImpOperatingDefinition,
+                       sizeof(ImpOperatingDefinition));
+               scsiDev.dataLen = sizeof(ImpOperatingDefinition);
+               scsiDev.phase = DATA_IN;
+       }
+       else if (pageCode == 0x82)
+       {
+               memcpy(
+                       scsiDev.data,
+                       AscImpOperatingDefinition,
+                       sizeof(AscImpOperatingDefinition));
+               scsiDev.dataLen = sizeof(AscImpOperatingDefinition);
+               scsiDev.phase = DATA_IN;
+       }
+       else
+       {
+               // error.
+               scsiDev.status = CHECK_CONDITION;
+               scsiDev.target->sense.code = ILLEGAL_REQUEST;
+               scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+               scsiDev.phase = STATUS;
+       }
+
+
+       if (scsiDev.phase == DATA_IN)
+       {
+               // "real" hard drives send back exactly allocationLenth bytes, padded
+               // with zeroes. This only seems to happen for Inquiry responses, and not
+               // other commands that also supply an allocation length such as Mode Sense or
+               // Request Sense.
+               // (See below for exception to this rule when 0 allocation length)
+               if (scsiDev.dataLen < allocationLength)
+               {
+                       memset(
+                               &scsiDev.data[scsiDev.dataLen],
+                               0,
+                               allocationLength - scsiDev.dataLen);
+               }
+               // Spec 8.2.5 requires us to simply truncate the response if it's
+               // too big.
+               scsiDev.dataLen = allocationLength;
+
+               // Set the device type as needed.
+               switch (scsiDev.target->cfg->deviceType)
+               {
+               case CONFIG_OPTICAL:
+                       scsiDev.data[0] = 0x05; // device type
+                       scsiDev.data[1] |= 0x80; // Removable bit.
+                       break;
+
+               case CONFIG_SEQUENTIAL:
+                       scsiDev.data[0] = 0x01; // device type
+                       scsiDev.data[1] |= 0x80; // Removable bit.
+                       break;
+                       
+               case CONFIG_MO:
+                       scsiDev.data[0] = 0x07; // device type
+                       scsiDev.data[1] |= 0x80; // Removable bit.
+                       break;
+
+               case CONFIG_FLOPPY_14MB:
+               case CONFIG_REMOVEABLE:
+                       scsiDev.data[1] |= 0x80; // Removable bit.
+                       break;
+                default:
+                       // Accept defaults for a fixed disk.
+                       break;
+               }
+       }
+
+       // Set the first byte to indicate LUN presence.
+       if (scsiDev.lun) // We only support lun 0
+       {
+               scsiDev.data[0] = 0x7F;
+       }
+}
+
+#pragma GCC pop_options
index 7aecf95..9ac58d6 100755 (executable)
@@ -33,6 +33,7 @@
 #include "debug.h"\r
 #include "tape.h"\r
 #include "mo.h"\r
+#include "vendor.h"\r
 \r
 #include <string.h>\r
 \r
@@ -138,6 +139,16 @@ void process_Status()
        uint8 message;\r
 \r
        uint8 control = scsiDev.cdb[scsiDev.cdbLen - 1];\r
+\r
+       if (scsiDev.target->cfg->quirks == CONFIG_QUIRKS_OMTI)\r
+       {\r
+               // OMTI non-standard LINK control\r
+               if (control & 0x01)\r
+               {\r
+                       scsiDev.phase = COMMAND; return;\r
+               }\r
+       }\r
+\r
        if ((scsiDev.status == GOOD) && (control & 0x01))\r
        {\r
                // Linked command.\r
@@ -155,6 +166,10 @@ void process_Status()
        {\r
                message = MSG_COMMAND_COMPLETE;\r
        }\r
+\r
+// TODO OMTI ENABLE VIA CONFIG\r
+// scsiDev.status |=  (scsiDev.target->targetId & 0x03) << 5 ;\r
+\r
        scsiWriteByte(scsiDev.status);\r
 \r
        scsiDev.lastStatus = scsiDev.status;\r
@@ -403,7 +418,7 @@ static void process_Command()
        {\r
                scsiReadBuffer();\r
        }\r
-       else if (!scsiModeCommand())\r
+       else if (!scsiModeCommand() && !scsiVendorCommand())\r
        {\r
                scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
                scsiDev.target->sense.asc = INVALID_COMMAND_OPERATION_CODE;\r
@@ -566,7 +581,7 @@ static void process_SelectionPhase()
 \r
        // Only read these pins AFTER SEL and BSY - we don't want to catch them\r
        // during a transition period.\r
-       uint8 mask = scsiReadDBxPins();\r
+       uint8 mask = (selLatchCfg && scsiDev.selFlag) ? scsiDev.selDBX : scsiReadDBxPins();\r
        int maskBitCount = countBits(mask);\r
        int goodParity = (Lookup_OddParity[mask] == SCSI_ReadPin(SCSI_In_DBP));\r
        int atnFlag = SCSI_ReadFilt(SCSI_Filt_ATN);\r
@@ -617,9 +632,9 @@ static void process_SelectionPhase()
                }\r
                else if (!(scsiDev.boardCfg.flags & CONFIG_ENABLE_SCSI2))\r
                {\r
-                       scsiDev.compatMode = COMPAT_SCSI1;\r
+                       scsiDev.compatMode = COMPAT_SCSI2_DISABLED;\r
                }\r
-               else if (scsiDev.compatMode == COMPAT_UNKNOWN)\r
+               else\r
                {\r
                        scsiDev.compatMode = COMPAT_SCSI2;\r
                }\r
index 844bbe3..63cc83f 100755 (executable)
@@ -61,6 +61,11 @@ typedef enum
 {
        COMPAT_UNKNOWN,
        COMPAT_SCSI1,
+
+       // Messages are being used, yet SCSI 2 mode is disabled.
+       // This impacts interpretation of INQUIRY commands.
+       COMPAT_SCSI2_DISABLED,
+
        COMPAT_SCSI2
 } SCSI_COMPAT_MODE;
 
@@ -106,12 +111,14 @@ typedef struct
 
        // Set to true (1) if the RST flag was set.
        volatile int resetFlag;
-       
+
        // Set to true (1) if the SEL flag was set.
        volatile int selFlag;
-
+       
        // Set to true (1) if a parity error was observed.
-       int parityError;
+    int parityError;
+
+       volatile int selDBX;
 
        int phase;
 
index f9959d5..d9699b3 100755 (executable)
@@ -80,6 +80,9 @@ CY_ISR(scsiSelectionISR)
        // selFlag is required for Philips P2000C which releases it after 600ns\r
        // without waiting for BSY.\r
        scsiDev.selFlag = 1;\r
+\r
+       // Required for some early Mac Plus roms\r
+       scsiDev.selDBX = scsiReadDBxPins();\r
 }\r
 \r
 uint8_t\r
index 24f0451..be43088 100644 (file)
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index 206f402..71f8a17 100755 (executable)
 <build_action v="C_FILE" />\r
 <PropertyDeltas />\r
 </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
+<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">\r
+<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.c" persistent="..\..\src\vendor.c">\r
+<Hidden v="False" />\r
+</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>\r
+<build_action v="C_FILE" />\r
+<PropertyDeltas />\r
+</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
 </dependencies>\r
 </CyGuid_0820c2e7-528d-4137-9a08-97257b946089>\r
 </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>\r
 <build_action v="NONE" />\r
 <PropertyDeltas />\r
 </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
+<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">\r
+<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.h" persistent="..\..\src\vendor.h">\r
+<Hidden v="False" />\r
+</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>\r
+<build_action v="NONE" />\r
+<PropertyDeltas />\r
+</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
 </dependencies>\r
 </CyGuid_0820c2e7-528d-4137-9a08-97257b946089>\r
 </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>\r
index c95451f..c2567cd 100644 (file)
Binary files a/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index 2ba239f..5a2f270 100755 (executable)
 <build_action v="C_FILE" />\r
 <PropertyDeltas />\r
 </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
+<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">\r
+<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.c" persistent="..\..\src\vendor.c">\r
+<Hidden v="False" />\r
+</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>\r
+<build_action v="C_FILE" />\r
+<PropertyDeltas />\r
+</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
 </dependencies>\r
 </CyGuid_0820c2e7-528d-4137-9a08-97257b946089>\r
 </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>\r
 <build_action v="NONE" />\r
 <PropertyDeltas />\r
 </CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
+<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFile" version="3" xml_contents_version="1">\r
+<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItem" version="2" name="vendor.h" persistent="..\..\src\vendor.h">\r
+<Hidden v="False" />\r
+</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>\r
+<build_action v="NONE" />\r
+<PropertyDeltas />\r
+</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>\r
 </dependencies>\r
 </CyGuid_0820c2e7-528d-4137-9a08-97257b946089>\r
 </CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>\r
index fdd43b8..7b17b52 100755 (executable)
@@ -46,8 +46,18 @@ extern "C" {
                        |Row 188 | Config target 0
                        ---------------------------------
                        |Row 187 | Board Config
+                       | ...    | Empty
+                       |Row 172 | Empty
                        ---------------------------------
-                       |Row 186 |
+                       |Row 171 |
+                       | ...    |
+                       |Row 156 | Config target 6
+                       | ...    |
+                       |Row 140 | Config target 5
+                       | ...    |
+                       |Row 124 | Config target 4
+                       ---------------------------------
+                       |Row 123 |
                        | ...    |
                        |Row 0   |
        --------|        |
@@ -65,6 +75,7 @@ extern "C" {
 
 #include "stdint.h"
 
+//#define MAX_SCSI_TARGETS 7
 #define MAX_SCSI_TARGETS 4
 #define SCSI_CONFIG_ARRAY 1
 #define SCSI_CONFIG_ROWS 16
@@ -77,6 +88,9 @@ extern "C" {
 #define SCSI_CONFIG_1_ROW 204
 #define SCSI_CONFIG_2_ROW 220
 #define SCSI_CONFIG_3_ROW 236
+#define SCSI_CONFIG_4_ROW 124
+#define SCSI_CONFIG_5_ROW 140
+#define SCSI_CONFIG_6_ROW 156
 
 typedef enum
 {
@@ -110,7 +124,8 @@ typedef enum
 typedef enum
 {
        CONFIG_QUIRKS_NONE,
-       CONFIG_QUIRKS_APPLE
+       CONFIG_QUIRKS_APPLE,
+       CONFIG_QUIRKS_OMTI
 } CONFIG_QUIRKS;
 
 typedef struct __attribute__((packed))
old mode 100644 (file)
new mode 100755 (executable)
index 3c3cdd0..6ac525b
@@ -248,9 +248,19 @@ ConfigUtil::toXML(const TargetConfig& config)
                "       <!-- ********************************************************\n" <<
                "       Space separated list. Available options:\n" <<
                "       apple\t\tReturns Apple-specific mode pages\n" <<
+               "       omti\t\tOMTI host non-standard link control\n" <<
                "       ********************************************************* -->\n" <<
-               "       <quirks>" <<
-                       (config.quirks & CONFIG_QUIRKS_APPLE ? "apple" : "") <<
+               "       <quirks>";
+       if (config.quirks == CONFIG_QUIRKS_APPLE)
+       {
+               s << "apple";
+       }
+       else if (config.quirks == CONFIG_QUIRKS_OMTI)
+       {
+               s << "omti";
+       }
+
+       s <<
                        "</quirks>\n" <<
 
                "\n\n" <<
@@ -393,6 +403,19 @@ ConfigUtil::toXML(const BoardConfig& config)
                "       <mapLunsToIds>" <<
                        (config.flags & CONFIG_MAP_LUNS_TO_IDS ? "true" : "false") <<
                        "</mapLunsToIds>\n" <<
+
+               "       <!-- ********************************************************\n" <<
+               "       Delay (in milliseconds) before responding to a SCSI selection.\n" <<
+               "       255 (auto) sets it to 0 for SCSI2 hosts and 1ms otherwise.\n" <<
+               "       Some samplers need this set to 1 manually.\n" <<
+               "       ********************************************************* -->\n" <<
+               "       <selectionDelay>" << static_cast<int>(config.selectionDelay) << "</selectionDelay>\n" <<
+
+               "       <!-- ********************************************************\n" <<
+               "       Startup delay (in seconds) before responding to the SCSI bus \n" <<
+               "       after power on. Default = 0.\n" <<
+               "       ********************************************************* -->\n" <<
+               "       <startupDelay>" << static_cast<int>(config.startupDelay) << "</startupDelay>\n" <<
                "</BoardConfig>\n";
 
        return s.str();
@@ -471,6 +494,10 @@ parseTarget(wxXmlNode* node)
                                {
                                        result.quirks |= CONFIG_QUIRKS_APPLE;
                                }
+                               else if (quirk == "omti")
+                               {
+                                       result.quirks |= CONFIG_QUIRKS_OMTI;
+                               }
                        }
                }
                else if (child->GetName() == "deviceType")
@@ -559,7 +586,15 @@ parseBoardConfig(wxXmlNode* node)
        wxXmlNode *child = node->GetChildren();
        while (child)
        {
-               if (child->GetName() == "unitAttention")
+               if (child->GetName() == "selectionDelay")
+               {
+                       result.selectionDelay = parseInt(child, 255);
+               }
+               else if (child->GetName() == "startupDelay")
+               {
+                       result.startupDelay = parseInt(child, 255);
+               }
+               else if (child->GetName() == "unitAttention")
                {
                        std::string s(child->GetNodeContent().mb_str());
                        if (s == "true")
index cfcac9b..842441e 100755 (executable)
@@ -42,7 +42,8 @@ LDFLAGS += -L$(BUILD)/libzipper/.libs -lzipper $(LDFLAGS_ZLIB) $(LDFLAGS_HIDAPI)
 
 # wxWidgets 3.0.2 uses broken Webkit headers under OSX Yosemeti
 # liblzma not available on OSX 10.7
-WX_CONFIG=--disable-webkit --disable-webviewwebkit  \
+# --disable-mediactrl for missing Quicktime.h on Mac OSX Sierra
+WX_CONFIG=--disable-webkit --disable-webviewwebkit  --disable-mediactrl \
        --without-libtiff --without-libjbig --without-liblzma --without-opengl \
        --enable-monolithic --enable-stl --disable-shared
 
@@ -80,6 +81,13 @@ ifeq ($(TARGET),Darwin)
        CXX=clang++ -stdlib=libc++ -mmacosx-version-min=10.7
        WX_CONFIG += --with-macosx-version-min=10.7
        BUILD := $(PWD)/build/mac
+all: $(BUILD)/scsi2sd-util.dmg
+
+$(BUILD)/scsi2sd-util.dmg: $(BUILD)/scsi2sd-util $(BUILD)/scsi2sd-monitor
+       mkdir -p $(dir $@)/dmg
+       cp $(BUILD)/scsi2sd-util $(BUILD)/scsi2sd-monitor $(dir $@)/dmg
+       chmod a+rx $(dir $@)/dmg/*
+       hdiutil create -srcfolder $(dir $@)/dmg $@
 endif
 
 export CC CXX
old mode 100644 (file)
new mode 100755 (executable)
index a49deb7..d466643
@@ -312,7 +312,7 @@ TargetPanel::evaluate()
        {
        case CONFIG_OPTICAL:
                mySectorSizeCtrl->ChangeValue("2048");
-               mySectorSizeCtrl->Enable(false);
+               mySectorSizeCtrl->Enable(true); // Enable override
                break;
        case CONFIG_FLOPPY_14MB:
                mySectorSizeCtrl->ChangeValue("512");
index a80b462..333ad30 100644 (file)
@@ -570,7 +570,7 @@ private:
                        std::vector<zipper::CompressedFilePtr> files(decomp.getEntries());
                        for (auto it(files.begin()); it != files.end(); it++)
                        {
-                               if (myBootloader->isCorrectFirmware((*it)->getPath()))
+                               if (myBootloader && myBootloader->isCorrectFirmware((*it)->getPath()))
                                {
                                        std::stringstream msg;
                                        msg << "Found firmware entry " << (*it)->getPath() <<
@@ -1007,11 +1007,13 @@ private:
                        }
                }
 
-               flashRow = SCSI_CONFIG_0_ROW;
                for (size_t i = 0;
                        i < myTargets.size();
-                       ++i, flashRow += SCSI_CONFIG_ROWS)
+                       ++i)
                {
+                       flashRow = (i <= 3)
+                               ? SCSI_CONFIG_0_ROW + (i*SCSI_CONFIG_ROWS)
+                               : SCSI_CONFIG_4_ROW + ((i-4)*SCSI_CONFIG_ROWS);
                        std::vector<uint8_t> raw(sizeof(TargetConfig));
 
                        for (size_t j = 0; j < SCSI_CONFIG_ROWS; ++j)
@@ -1135,8 +1137,12 @@ private:
                flashRow = SCSI_CONFIG_0_ROW;
                for (size_t i = 0;
                        i < myTargets.size();
-                       ++i, flashRow += SCSI_CONFIG_ROWS)
+                       ++i)
                {
+                       flashRow = (i <= 3)
+                               ? SCSI_CONFIG_0_ROW + (i*SCSI_CONFIG_ROWS)
+                               : SCSI_CONFIG_4_ROW + ((i-4)*SCSI_CONFIG_ROWS);
+
                        TargetConfig config(myTargets[i]->getConfig());
                        std::vector<uint8_t> raw(ConfigUtil::toBytes(config));
 
old mode 100644 (file)
new mode 100755 (executable)
index 758e3a7..6757e5e
@@ -30,7 +30,7 @@
 #include "wx/osx/private.h"
 
 #if wxOSX_USE_COCOA_OR_CARBON
-    #include <QuickTime/QuickTime.h>
+//    #include <QuickTime/QuickTime.h>
 #endif
 
 // ----------------------------------------------------------------------------
old mode 100644 (file)
new mode 100755 (executable)
index 3c61c17..4dd8e8e
@@ -36,7 +36,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
 #endif
 
 #ifndef __WXOSX_IPHONE__
-#include <QuickTime/QuickTime.h>
+//#include <QuickTime/QuickTime.h>
 #endif
 
 CGColorSpaceRef wxMacGetGenericRGBColorSpace();
index cd72953..2081df2 100644 (file)
@@ -11,6 +11,7 @@
 #include <ctype.h>
 #include <assert.h>
 
+#include <cmath>
 #include <string>
 #include <vector>
 #include <map>
@@ -5841,9 +5842,9 @@ void Editor::GoToLine(int lineNo) {
 }
 
 static bool Close(Point pt1, Point pt2) {
-       if (abs(pt1.x - pt2.x) > 3)
+       if (std::abs(pt1.x - pt2.x) > 3)
                return false;
-       if (abs(pt1.y - pt2.y) > 3)
+       if (std::abs(pt1.y - pt2.y) > 3)
                return false;
        return true;
 }