| 
					
				 | 
			
			
				@@ -74,7 +74,9 @@ void blinkStatus(int count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*********************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 volatile bool g_busreset = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static uint8_t g_sensekey = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint8_t   g_sensekey = 0;    // Error information 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint8_t   g_sense_asc = 0;   // Additional error code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint8_t   g_sense_ascq = 0;  // Additional error code qualifier 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t   g_scsi_id_mask;    // Mask list of responding SCSI IDs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t   g_scsi_id;         // Currently responding SCSI-ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t   g_scsi_lun;        // Logical unit number currently responding 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -510,25 +512,60 @@ void readDataPhase_ToSD(uint32_t adds, uint32_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* SCSI commands                 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*********************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-08.html#8.2.16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint8_t onTestUnitReady() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if(!g_currentimg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_sensekey = 2; // Not ready 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_sense_asc = 0x3A; // Medium not present 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_sense_ascq = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 0x02; // Check condition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 0x00; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // INQUIRY command processing. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t onInquiryCommand(uint8_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  writeDataPhase(len < 36 ? len : 36, SCSI_INFO_BUF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint8_t response[sizeof(SCSI_INFO_BUF)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int responselen = sizeof(SCSI_INFO_BUF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memcpy(response, SCSI_INFO_BUF, responselen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Select device type based on LUN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (g_scsi_lun >= NUM_SCSILUN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response[0] = 0x7F; // Unsupported LUN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if (!g_currentimg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response[0] = 0x3F; // Unconnected LUN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  writeDataPhase(len < responselen ? len : responselen, response); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0x00; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // REQUEST SENSE command processing. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Refer to https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-08.html#8.2.14 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void onRequestSenseCommand(uint8_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   uint8_t buf[18] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    0x70,   //CheckCondition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    0xF0,   //CheckCondition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     0,      //Segment number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     g_sensekey,   //Sense key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     0, 0, 0, 0,  //information 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     17 - 7 ,   //Additional data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    0, 0, 0, 0, // Command specific 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_sense_asc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_sense_ascq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    0, 0, 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   g_sensekey = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  g_sense_asc = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  g_sense_ascq = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   writeDataPhase(len < 18 ? len : 18, buf);   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -919,7 +956,7 @@ void scsi_loop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Set BSY to-when selected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SCSI_OUT(BSY, active); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  azdbg("SCSI device selected"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  azdbg("------------ SCSI device selected"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Ask for a TARGET-ID to respond 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   g_scsi_id = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -967,9 +1004,8 @@ void scsi_loop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // LUN confirmation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  g_scsi_sts = cmd[1] & 0xe0;      // Preset LUN in status byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  g_scsi_lun = g_scsi_sts >> 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // LUN selection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  g_scsi_lun = cmd[1] >> 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // HDD Image selection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   g_currentimg = (HDDIMG *)0; // None 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -979,11 +1015,17 @@ void scsi_loop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!(g_currentimg->m_file.isOpen())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       g_currentimg = (HDDIMG *)0;       // Image absent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  g_scsi_sts = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   azdbg("CMD ", cmd[0], " (", cmdlen, " bytes): ", "ID", (int)g_scsi_id, ", LUN", (int)g_scsi_lun); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   switch(cmd[0]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 0x00: azdbg("[Test Unit]"); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 0x00: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      azdbg("[Test Unit Ready]"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      g_scsi_sts |= onTestUnitReady(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case 0x01: azdbg("[Rezero Unit]"); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case 0x03: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       azdbg("[RequestSense]"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1075,7 +1117,7 @@ void scsi_loop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   delay_ns(g_scsi_timing.REQ_TYPE_SETUP_NS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   writeHandshake(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  azdbg("Command complete"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  azdbg("------------ Command complete"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SCSI_RELEASE_OUTPUTS(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |