Quellcode durchsuchen

Merge pull request #528 from ZuluSCSI/dev_auto_geometry

Automatically guess sectors/head settings from image size.
Alex Perez vor 8 Monaten
Ursprung
Commit
a4974f09aa
2 geänderte Dateien mit 87 neuen und 3 gelöschten Zeilen
  1. 84 0
      src/ZuluSCSI_disk.cpp
  2. 3 3
      src/ZuluSCSI_settings.cpp

+ 84 - 0
src/ZuluSCSI_disk.cpp

@@ -264,6 +264,85 @@ static void scsiDiskSetImageConfig(uint8_t target_idx)
     memcpy(img.serial, devCfg->serial, sizeof(img.serial));
 }
 
+static bool find_chs_capacity(uint64_t lba, uint16_t max_cylinders, uint8_t min_heads, uint16_t &c, uint8_t &h, uint8_t &s)
+{
+    bool found_chs = false;
+    uint32_t cylinders;
+    for (uint8_t heads = 16 ; heads >= min_heads; heads--)
+    {
+        if (lba % heads != 0)
+            continue;
+        for (uint8_t sectors = 63; sectors >= 1; sectors--)
+        {
+            if (lba % (heads * sectors) == 0)
+            {
+                cylinders = lba / (heads * sectors);
+                if (cylinders > max_cylinders)
+                    continue;
+                found_chs = true;
+                c = (uint16_t) cylinders;
+                h = heads;
+                s = sectors;
+                break;
+            }
+        }
+        if (found_chs)
+            break;
+    }
+    return found_chs;
+}
+
+static void autoConfigGeometry(image_config_t &img)
+{
+    const char *method = "INI config";
+    if (img.sectorsPerTrack == 0 || img.headsPerCylinder == 0)
+    {
+        uint16_t cyl = 0;
+        uint8_t head = 255;
+        uint8_t sect = 63;
+        bool found_chs = false;
+
+        if (img.deviceType == S2S_CFG_FLOPPY_14MB && img.scsiSectors <= 2880)
+        {
+            method = "device type floppy";
+            sect = 18;
+            head = 80;
+        }
+        else if (img.scsiSectors <= 1032192)
+        {
+            found_chs = find_chs_capacity(img.scsiSectors, 1024, 1, cyl, head, sect);
+            method = "image size";
+        }
+        else if (img.scsiSectors <= 16514064)
+        {
+            found_chs = find_chs_capacity(img.scsiSectors, 16383, 9, cyl, head, sect);
+            if (!found_chs)
+                found_chs = find_chs_capacity(img.scsiSectors, 32767, 5, cyl, head, sect);
+            if (!found_chs)
+                found_chs = find_chs_capacity(img.scsiSectors, 65535, 1, cyl, head, sect);
+            method = "image size";
+        }
+
+        if (!found_chs)
+        {
+            head = 255;
+            sect = 63;
+            method = "defaults";
+        }
+
+        img.sectorsPerTrack = sect;
+        img.headsPerCylinder = head;
+    }
+
+    bool divisible = (img.scsiSectors % ((uint32_t)img.sectorsPerTrack * img.headsPerCylinder)) == 0;
+    logmsg("---- Drive geometry from ", method,
+        ": SectorsPerTrack=", (int)img.sectorsPerTrack,
+        " HeadsPerCylinder=", (int)img.headsPerCylinder,
+        " total sectors ", (int)img.scsiSectors,
+        divisible ? " (divisible)" : " (not divisible)"
+        );
+}
+
 bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_lun, int blocksize, S2S_CFG_TYPE type, bool use_prefix)
 {
     image_config_t &img = g_DiskImages[target_idx];
@@ -365,6 +444,11 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_lun, in
             }
         }
 
+        if (type != S2S_CFG_OPTICAL && type != S2S_CFG_NETWORK)
+        {
+            autoConfigGeometry(img);
+        }
+
         quirksCheck(&img);
 
         if (img.name_from_image)

+ 3 - 3
src/ZuluSCSI_settings.cpp

@@ -319,8 +319,8 @@ scsi_system_settings_t *ZuluSCSISettings::initSystem(const char *presetName)
     // setting set for all or specific devices
     cfgDev.deviceType = S2S_CFG_NOT_SET;
     cfgDev.deviceTypeModifier = 0;
-    cfgDev.sectorsPerTrack = 63;
-    cfgDev.headsPerCylinder = 255;
+    cfgDev.sectorsPerTrack = 0;
+    cfgDev.headsPerCylinder = 0;
     cfgDev.prefetchBytes = PREFETCH_BUFFER_SIZE;
     cfgDev.ejectButton = 0;
     cfgDev.vol = DEFAULT_VOLUME_LEVEL;
@@ -552,4 +552,4 @@ zuluscsi_speed_grade_t ZuluSCSISettings::stringToSpeedGrade(const char *speed_gr
 const char *ZuluSCSISettings::getSpeedGradeString()
 {
     return speed_grade_strings[m_sys.speedGrade];
-}
+}