ソースを参照

Merge pull request #43 from BlueSCSI/eric/validMacDisk

Validate Macintosh Disks
Eric Helgeson 2 年 前
コミット
cc1ff5f4d0

+ 105 - 0
lib/BlueSCSI_platform_RP2040/BlueSCSI_platform_config_hook.cpp

@@ -0,0 +1,105 @@
+/** 
+ * Copyright (C) 2023 Eric Helgeson
+ * 
+ * This file is part of BlueSCSI
+ * 
+ * This program 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. 
+ * 
+ * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+**/
+
+#include <minIni.h>
+#include "BlueSCSI_disk.h"
+#include "BlueSCSI_log.h"
+#include "BlueSCSI_platform_config_hook.h"
+
+
+static bool isValidMacintoshImage(image_config_t *img)
+{
+    bool result = true;
+    const char apple_magic[2] = {0x45, 0x52};
+    const char block_size[2]  = {0x02, 0x00};  // 512 BE == 2
+    const char lido_sig[4] = {'C', 'M', 'S', '_' };
+    byte tmp[4] = {0};
+
+    // Check for Apple Magic
+    img->file.seek(0);
+    img->file.read(tmp, 2);
+    if(memcmp(apple_magic, tmp, 2) != 0)
+    {
+        debuglog("Apple magic not found.");
+        result = false;
+    }
+    // Check HFS Block size is 512
+    img->file.seek(2);
+    img->file.read(tmp, 2);
+    if(memcmp(block_size, tmp, 2) != 0)
+    {
+        debuglog("Block size not 512", block_size);
+        result = false;
+    }
+    // Find SCSI Driver offset
+    img->file.seek(MACINTOSH_SCSI_DRIVER_OFFSET);
+    img->file.read(tmp, 4);
+    uint64_t driver_offset_blocks = int((unsigned char)(tmp[0]) << 24 | (unsigned char)(tmp[1]) << 16 |
+                                        (unsigned char)(tmp[2]) << 8  |  (unsigned char)(tmp[3]));
+    // Find size of SCSI Driver partition
+    img->file.seek(MACINTOSH_SCSI_DRIVER_SIZE_OFFSET);
+    img->file.read(tmp, 2);
+    int driver_size_blocks = int((unsigned char)(tmp[0]) << 8 | (unsigned char)(tmp[1]));
+    // SCSI Driver sanity checks
+    if((driver_size_blocks * MACINTOSH_BLOCK_SIZE) > MACINTOSH_SCSI_DRIVER_MAX_SIZE ||
+        (driver_offset_blocks * MACINTOSH_BLOCK_SIZE) > img->file.size())
+    {
+        debuglog("Invalid Macintosh SCSI Driver partition detected.");
+        result = false;
+    }
+    // Contains Lido Driver - driver causes issues on a Mac Plus and is generally slower than the Apple 4.3 or FWB.
+    // Also causes compatibility issues with other drivers.
+    img->file.seek(driver_offset_blocks * MACINTOSH_BLOCK_SIZE + LIDO_SIG_OFFSET);
+    img->file.read(tmp, 4);
+    if(memcmp(lido_sig, tmp, 4) == 0)
+    {
+        log("---- WARNING: This drive contains the LIDO driver and may cause issues.");
+    }
+
+    return result;
+}
+
+// Called from BlueSCSI_disk after image is initalized.
+void platformConfigHook(image_config_t *img)
+{
+    if(ini_getbool("SCSI", "DisableConfigHook", false, CONFIGFILE))
+    {
+        debuglog("Skipping platformConfigHook due to DisableConfigHook");
+        return;
+    }
+    if (img->quirks == S2S_CFG_QUIRKS_APPLE)
+    {
+        if(img->deviceType == S2S_CFG_FIXED)
+        {
+            if(!isValidMacintoshImage(img))
+            {
+                log("---- WARNING: This image does not appear to be a valid Macintosh Device image. See: https://github.com/BlueSCSI/BlueSCSI-v2/wiki/Disk-Images");
+            }
+            else
+            {
+                debuglog("---- Valid Macintosh Device Image detected.");
+            }
+        }
+        // Macintosh hosts reserve ID 7, so warn the user this configuration wont work
+        if((img->scsiId & S2S_CFG_TARGET_ID_BITS) == 7)
+        {
+          log("---- WARNING: Quirks set to Apple so can not use SCSI ID 7!");
+        }
+    }
+}

+ 32 - 0
lib/BlueSCSI_platform_RP2040/BlueSCSI_platform_config_hook.h

@@ -0,0 +1,32 @@
+
+/** 
+ * Copyright (C) 2023 Eric Helgeson
+ * 
+ * This file is part of BlueSCSI
+ * 
+ * This program 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. 
+ * 
+ * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+**/
+
+#pragma once
+#include "BlueSCSI_disk.h"
+
+#define PLATFORM_CONFIG_HOOK(X) platformConfigHook(X);
+void platformConfigHook(image_config_t *img);
+
+// Macintosh Device image constants
+#define MACINTOSH_SCSI_DRIVER_OFFSET 18
+#define MACINTOSH_SCSI_DRIVER_SIZE_OFFSET MACINTOSH_SCSI_DRIVER_OFFSET + 4
+#define MACINTOSH_BLOCK_SIZE 512
+#define MACINTOSH_SCSI_DRIVER_MAX_SIZE 64 * MACINTOSH_BLOCK_SIZE // 32768
+#define LIDO_SIG_OFFSET 24

+ 1 - 1
lib/SCSI2SD/include/scsi2sd.h

@@ -39,7 +39,7 @@ extern "C" {
 
 #include "stdint.h"
 
-#define S2S_MAX_TARGETS 7
+#define S2S_MAX_TARGETS 8
 #define S2S_CFG_SIZE (S2S_MAX_TARGETS * sizeof(S2S_TargetCfg) + sizeof(S2S_BoardCfg))
 
 typedef enum

+ 1 - 1
platformio.ini

@@ -5,7 +5,7 @@ default_envs = BlueSCSI_Pico
 
 ; BlueSCSI RP2040 hardware platform, based on the Raspberry Pi foundation RP2040 microcontroller
 [env:BlueSCSI_Pico]
-platform = raspberrypi@1.8.0
+platform = raspberrypi@1.9.0
 platform_packages = platformio/toolchain-gccarmnoneeabi@1.100301.220327 ; toolchain-gccarmnoneeabi@1.60301.0
 framework = arduino
 board = BlueSCSI_RP2040

+ 2 - 11
src/BlueSCSI.cpp

@@ -355,20 +355,12 @@ bool findHDDImages()
         strcat(fullname, name);
 
         // Check whether this SCSI ID has been configured yet
-        const S2S_TargetCfg* cfg = s2s_getConfigById(id);
-        if (cfg)
+        if (s2s_getConfigById(id))
         {
           log("-- Ignoring ", fullname, ", SCSI ID ", id, " is already in use!");
           continue;
         }
 
-        // Apple computers reserve ID 7, so warn the user this configuration wont work
-        if(id == 7 && cfg->quirks == S2S_CFG_QUIRKS_APPLE )
-        {
-          log("-- Ignoring ", fullname, ", SCSI ID ", id, " Quirks set to Apple so can not use SCSI ID 7!");
-          continue;
-        }
-
         // Type mapping based on filename.
         // If type is FIXED, the type can still be overridden in .ini file.
         S2S_CFG_TYPE type = S2S_CFG_FIXED;
@@ -426,11 +418,10 @@ bool findHDDImages()
   for (int i = 0; i < NUM_SCSIID; i++)
   {
     const S2S_TargetCfg* cfg = s2s_getConfigByIndex(i);
-
     if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
     {
       int capacity_kB = ((uint64_t)cfg->scsiSectors * cfg->bytesPerSector) / 1024;
-      log("* ID: ", (int)(cfg->scsiId & 7),
+      log("* ID: ", (int)(cfg->scsiId & S2S_CFG_TARGET_ID_BITS),
             ", BlockSize: ", (int)cfg->bytesPerSector,
             ", Type: ", typeToChar((int)cfg->deviceType),
             ", Quirks: ", quirksToChar((int)cfg->quirks),

+ 7 - 6
src/BlueSCSI_disk.cpp

@@ -11,6 +11,7 @@
 #include "BlueSCSI_config.h"
 #include "BlueSCSI_presets.h"
 #include "BlueSCSI_cdrom.h"
+#include "BlueSCSI_platform_config_hook.h"
 #include "ImageBackingStore.h"
 #include "ROMDrive.h"
 #include <minIni.h>
@@ -377,12 +378,6 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int
             img.deviceType = S2S_CFG_SEQUENTIAL;
         }
 
-#ifdef PLATFORM_CONFIG_HOOK
-        PLATFORM_CONFIG_HOOK(&img);
-#endif
-
-        setDefaultDriveInfo(target_idx);
-
         if (img.prefetchbytes != PREFETCH_BUFFER_SIZE)
         {
             log("---- Read prefetch enabled: ", (int)img.prefetchbytes, " bytes");
@@ -396,6 +391,12 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int
             debuglog("---- Read prefetch enabled: ", (int)img.prefetchbytes, " bytes");
         }
 
+        setDefaultDriveInfo(target_idx);
+
+#ifdef PLATFORM_CONFIG_HOOK
+        PLATFORM_CONFIG_HOOK(&img);
+#endif
+
         if (img.deviceType == S2S_CFG_OPTICAL &&
             strncasecmp(filename + strlen(filename) - 4, ".bin", 4) == 0)
         {

+ 6 - 0
src/BlueSCSI_log.cpp

@@ -123,6 +123,12 @@ void log_raw(double value)
     log_raw(buffer);
 }
 
+void log_raw(bool value)
+{
+    if(value) log_raw("true");
+    else log_raw("false");
+}
+
 uint32_t log_get_buffer_len()
 {
     return g_logpos;

+ 3 - 0
src/BlueSCSI_log.h

@@ -37,6 +37,9 @@ void log_raw(int value);
 // Log double
 void log_raw(double value);
 
+// Log bool
+void log_raw(bool value);
+
 // Log array of bytes
 struct bytearray {
     bytearray(const uint8_t *data, size_t len): data(data), len(len) {}