Adding Ensoniq ASR-10 support and improved FORMAT UNIT command.
[SCSI2SD-V6.git] / software / SCSI2SD / src / disk.c
index fb76ff2..d9961d3 100755 (executable)
@@ -18,6 +18,7 @@
 \r
 #include "device.h"\r
 #include "scsi.h"\r
+#include "scsiPhy.h"\r
 #include "config.h"\r
 #include "disk.h"\r
 #include "sd.h"\r
@@ -38,11 +39,69 @@ static int doSdInit()
        return result;\r
 }\r
 \r
+// Callback once all data has been read in the data out phase.\r
+static void doFormatUnitComplete(void)\r
+{\r
+       // TODO start writing the initialisation pattern to the SD\r
+       // card\r
+       scsiDev.phase = STATUS;\r
+}\r
+\r
+static void doFormatUnitSkipData(int bytes)\r
+{\r
+       // We may not have enough memory to store the initialisation pattern and\r
+       // defect list data.  Since we're not making use of it yet anyway, just\r
+       // discard the bytes.\r
+       scsiEnterPhase(DATA_OUT);\r
+       int i;\r
+       for (i = 0; i < bytes; ++i)\r
+       {\r
+               scsiReadByte(); \r
+       }\r
+}\r
 \r
-static void doFormatUnit()\r
+// Callback from the data out phase.\r
+static void doFormatUnitPatternHeader(void)\r
 {\r
-       // Low-level formatting is not required.\r
-       // Nothing left to do.\r
+       int defectLength =\r
+               ((((uint16_t)scsiDev.data[2])) << 8) +\r
+                       scsiDev.data[3];\r
+                       \r
+       int patternLength =\r
+               ((((uint16_t)scsiDev.data[4 + 2])) << 8) +\r
+               scsiDev.data[4 + 3];\r
+\r
+               doFormatUnitSkipData(defectLength + patternLength);\r
+               doFormatUnitComplete();\r
+}\r
+\r
+// Callback from the data out phase.\r
+static void doFormatUnitHeader(void)\r
+{\r
+       int IP = (scsiDev.data[1] & 0x08) ? 1 : 0;\r
+       int DSP = (scsiDev.data[1] & 0x04) ? 1 : 0;\r
+       \r
+       if (! DSP) // disable save parameters\r
+       {\r
+               configSave(); // Save the "MODE SELECT savable parameters"\r
+       }\r
+       \r
+       if (IP)\r
+       {\r
+               // We need to read the initialisation pattern header first.\r
+               scsiDev.dataLen += 4;\r
+               scsiDev.phase = DATA_OUT;\r
+               scsiDev.postDataOutHook = doFormatUnitPatternHeader;\r
+       }\r
+       else\r
+       {\r
+               // Read the defect list data\r
+               int defectLength =\r
+                       ((((uint16_t)scsiDev.data[2])) << 8) +\r
+                       scsiDev.data[3];\r
+               doFormatUnitSkipData(defectLength);\r
+               doFormatUnitComplete();\r
+       }\r
 }\r
 \r
 static void doReadCapacity()\r
@@ -240,7 +299,22 @@ int scsiDiskCommand()
        else if (command == 0x04)\r
        {\r
                // FORMAT UNIT\r
-               doFormatUnit();\r
+               // We don't really do any formatting, but we need to read the correct\r
+               // number of bytes in the DATA_OUT phase to make the SCSI host happy.\r
+               \r
+               int fmtData = (scsiDev.cdb[1] & 0x10) ? 1 : 0;\r
+               if (fmtData)\r
+               {\r
+                       // We need to read the parameter list, but we don't know how\r
+                       // big it is yet. Start with the header.\r
+                       scsiDev.dataLen = 4;\r
+                       scsiDev.phase = DATA_OUT;\r
+                       scsiDev.postDataOutHook = doFormatUnitHeader;\r
+               }\r
+               else\r
+               {\r
+                       // No data to read, we're already finished!\r
+               }\r
        }\r
        else if (command == 0x08)\r
        {\r