]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
FloppyBridge updates.
authorToni Wilen <twilen@winuae.net>
Thu, 14 Oct 2021 15:51:20 +0000 (18:51 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 14 Oct 2021 15:51:20 +0000 (18:51 +0300)
cfgfile.cpp
disk.cpp
floppybridge/floppybridge_abstract.h
floppybridge/floppybridge_lib.cpp
floppybridge/floppybridge_lib.h
include/disk.h
include/options.h
od-win32/resources/winuae.rc
od-win32/win32.cpp
od-win32/win32gui.cpp

index 0543beff37a1a15dc41974a76de2db4b3b4c537b..e2be72c5978c64a018910a0aee350155de7aa801 100644 (file)
@@ -1972,8 +1972,16 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                cfgfile_write_path2(f, tmp, p->floppyslots[i].df, PATH_FLOPPY);
                _stprintf (tmp, _T("floppy%dwp"), i);
                cfgfile_dwrite_bool (f, tmp, p->floppyslots[i].forcedwriteprotect);
-               _stprintf (tmp, _T("floppy%dtype"), i);
-               cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxtype);
+               _stprintf(tmp, _T("floppy%dtype"), i);
+               cfgfile_dwrite(f, tmp, _T("%d"), p->floppyslots[i].dfxtype);
+               if (p->floppyslots[i].dfxsubtype) {
+                       _stprintf(tmp, _T("floppy%dsubtype"), i);
+                       cfgfile_dwrite(f, tmp, _T("%d"), p->floppyslots[i].dfxsubtype);
+                       if (p->floppyslots[i].dfxsubtypeid) {
+                               _stprintf(tmp, _T("floppy%dsubtypeid"), i);
+                               cfgfile_dwrite_escape(f, tmp, _T("%s"), p->floppyslots[i].dfxsubtypeid);
+                       }
+               }
                _stprintf (tmp, _T("floppy%dsound"), i);
                cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxclick);
                if (p->floppyslots[i].dfxclick < 0 && p->floppyslots[i].dfxclickexternal[0]) {
@@ -1986,10 +1994,6 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                        _stprintf (tmp, _T("floppy%dsoundvolume_empty"), i);
                        cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_empty[i]);
                }
-               if (p->floppyslots[i].config[0]) {
-                       _stprintf(tmp, _T("floppy%dconfig"), i);
-                       cfgfile_write_str_escape(f, tmp, p->floppyslots[i].config);
-               }
                if (p->floppyslots[i].dfxtype < 0 && p->nr_floppies > i)
                        p->nr_floppies = i;
        }
@@ -5631,6 +5635,10 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_intval(option, value, _T("floppy1type"), &p->floppyslots[1].dfxtype, 1)
                || cfgfile_intval(option, value, _T("floppy2type"), &p->floppyslots[2].dfxtype, 1)
                || cfgfile_intval(option, value, _T("floppy3type"), &p->floppyslots[3].dfxtype, 1)
+               || cfgfile_intval(option, value, _T("floppy0subtype"), &p->floppyslots[0].dfxsubtype, 1)
+               || cfgfile_intval(option, value, _T("floppy1subtype"), &p->floppyslots[1].dfxsubtype, 1)
+               || cfgfile_intval(option, value, _T("floppy2subtype"), &p->floppyslots[2].dfxsubtype, 1)
+               || cfgfile_intval(option, value, _T("floppy3subtype"), &p->floppyslots[3].dfxsubtype, 1)
                || cfgfile_intval(option, value, _T("maprom"), &p->maprom, 1)
                || cfgfile_intval(option, value, _T("parallel_autoflush"), &p->parallel_autoflush_time, 1)
                || cfgfile_intval(option, value, _T("uae_hide"), &p->uae_hide, 1)
@@ -5930,8 +5938,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                                p->floppyslots[i].df[0] = 0;
                        return 1;
                }
-               _stprintf(tmpbuf, _T("floppy%dconfig"), i);
-               if (cfgfile_string_escape(option, value, tmpbuf, p->floppyslots[i].config, sizeof p->floppyslots[i].config / sizeof(TCHAR))) {
+               _stprintf(tmpbuf, _T("floppy%dsubtypeid"), i);
+               if (cfgfile_string_escape(option, value, tmpbuf, p->floppyslots[i].dfxsubtypeid, sizeof p->floppyslots[i].dfxsubtypeid / sizeof(TCHAR))) {
                        return 1;
                }
        }
index 2ac4480c0ea652d63e38c9c9d9f4c477ac6a071a..5880d8becdfa91e28d6cccd7b333866549f908a9 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -565,16 +565,17 @@ static int createimagefromexe (struct zfile *src, struct zfile *dst)
 static FloppyBridgeAPI *bridges[4];
 static int bridge_type[4];
 static const FloppyDiskBridge::BridgeDriver *bridge_driver[4];
-static bool floppybridge_available;
 static FloppyBridgeAPI::BridgeInformation bridgeinfo;
-static bool bridgeinfoloaded;
+static int bridgeinfoloaded;
 static std::vector<FloppyBridgeAPI::DriverInformation> bridgedriverinfo;
 static void floppybridge_read_track(drive *drv);
+bool floppybridge_available;
+std::vector<FloppyBridgeAPI::FloppyBridgeProfileInformation> bridgeprofiles;
+static char *floppybridge_config = NULL;
 
 bool DISK_isfloppybridge(struct uae_prefs *p, int num)
 {
-       int v = p->floppyslots[num].dfxtype;
-       return v == DRV_FB_A_35_DD || v == DRV_FB_A_35_HD || v == DRV_FB_B_35_DD || v == DRV_FB_B_35_HD;
+       return p->floppyslots[num].dfxtype == DRV_FB;
 }
 #endif
 
@@ -643,18 +644,21 @@ static const TCHAR *drive_id_name(drive *drv)
 */
 static void drive_settype_id (drive *drv)
 {
-       int t = currprefs.floppyslots[drv - &floppy[0]].dfxtype;
+       int drvnum = drv - &floppy[0];
+       int t = currprefs.floppyslots[drvnum].dfxtype;
 
 #ifdef FLOPPYBRIDGE
        if (drv->bridge)
        {
                if (drv->bridge->isDiskInDrive()) {
+                       FloppyBridgeAPI::BridgeDensityMode mode = FloppyBridgeAPI::BridgeDensityMode::bdmDDOnly;
+                       bridges[drvnum]->getBridgeDensityMode(&mode);
                        switch (drv->bridge->getDriveTypeID()) {
                        case FloppyDiskBridge::DriveTypeID::dti35DD:
                                drv->drive_id = DRIVE_ID_35DD;
                                break;
                        case FloppyDiskBridge::DriveTypeID::dti35HD:
-                               if (t == DRV_35_HD) {
+                               if (t == DRV_35_HD && mode != FloppyBridgeAPI::BridgeDensityMode::bdmDDOnly) {
                                        drv->drive_id = DRIVE_ID_35HD;
                                } else {
                                        drv->drive_id = DRIVE_ID_35DD;
@@ -878,9 +882,11 @@ void DISK_get_path_text(struct uae_prefs *p, int n, TCHAR *text)
 #ifdef FLOPPYBRIDGE
        if (DISK_isfloppybridge(p, n) && floppybridge_available) {
                if (!bridgeinfoloaded) {
-                       FloppyBridgeAPI::getBridgeDriverInformation(bridgeinfo);
+                       FloppyBridgeAPI::getBridgeDriverInformation(false, bridgeinfo);
+                       bridgeinfoloaded = 1;
                }
                _tcscpy(text, bridgeinfo.about);
+               floppybridge_init(p);
                if (bridge_driver[n]) {
                        _tcscat(text, _T(", "));
                        TCHAR *name = au(bridge_driver[n]->name);
@@ -4829,7 +4835,7 @@ static void floppybridge_read_track(drive *drv)
                        }
                        sleep_millis(10);
                }
-               while (!b->isReady()) {
+               while (!b->isReady() && b->isDiskInDrive()) {
                        if (timeout-- < 0) {
                                break;
                        }
@@ -4864,9 +4870,35 @@ static void floppybridge_read_track(drive *drv)
                }
                break;
        }
+       b->gotoCylinder(0, false);
        b->setMotorStatus(false, side);
 }
 
+static void floppybridge_update_config(void)
+{
+       if (floppybridge_available && floppybridge_config) {
+               FloppyBridgeAPI::importProfilesFromString(floppybridge_config);
+               xfree(floppybridge_config);
+               floppybridge_config = NULL;
+       }
+}
+
+void floppybridge_set_config(const char *c)
+{
+       xfree(floppybridge_config);
+       floppybridge_config = strdup(c);
+       floppybridge_update_config();
+}
+
+void floppybridge_reload_profiles(void)
+{
+       if (floppybridge_available) {
+               floppybridge_update_config();
+               bridgeprofiles.clear();
+               FloppyBridgeAPI::getAllProfiles(bridgeprofiles);
+       }
+}
+
 static void floppybridge_init3(void)
 {
        static bool checked;
@@ -4877,6 +4909,7 @@ static void floppybridge_init3(void)
        if (FloppyBridgeAPI::isAvailable()) {
                floppybridge_available = true;
                FloppyBridgeAPI::getDriverList(bridgedriverinfo);
+               floppybridge_reload_profiles();
        }
 }
 
@@ -4888,10 +4921,11 @@ bool floppybridge_has(void)
 
 static void floppybridge_init2(struct uae_prefs *p)
 {
+       floppybridge_init3();
        bool needbridge = false;
        for (int i = 0; i < MAX_FLOPPY_DRIVES; i++) {
                int type = p->floppyslots[i].dfxtype;
-               if (type == DRV_FB_A_35_DD || type == DRV_FB_A_35_HD || type == DRV_FB_B_35_DD || type == DRV_FB_B_35_HD) {
+               if (type >= DRV_FB) {
                        needbridge = true;
                }
        }
@@ -4905,10 +4939,9 @@ static void floppybridge_init2(struct uae_prefs *p)
                }
                return;
        }
-       floppybridge_init3();
        for (int dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
                int type = p->floppyslots[dr].dfxtype;
-               if (type == DRV_FB_A_35_DD || type == DRV_FB_A_35_HD || type == DRV_FB_B_35_DD || type == DRV_FB_B_35_HD) {
+               if (type == DRV_FB) {
                        if (floppy[dr].bridge == NULL || type != bridge_type[dr]) {
                                if (bridges[dr]) {
                                        bridges[dr]->shutdown();
@@ -4919,29 +4952,31 @@ static void floppybridge_init2(struct uae_prefs *p)
                                bridge_driver[dr] = NULL;
                                bridge_type[dr] = type;
                                FloppyBridgeAPI *bridge = NULL;
-                               bool configConfigured = true;
-                               if (p->floppyslots[dr].config[0]) {
-                                       char *c = ua(p->floppyslots[dr].config);
-                                       bridge = FloppyBridgeAPI::createDriverFromString(c);
-                                       xfree(c);
+                               int id = _tstol(p->floppyslots[dr].dfxsubtypeid);
+                               const TCHAR *name = _tcschr(p->floppyslots[dr].dfxsubtypeid, ':');
+                               if (name) {
+                                       name++;
+                                       for (int i = 0; i < bridgeprofiles.size(); i++) {
+                                               FloppyBridgeAPI::FloppyBridgeProfileInformation fbpi = bridgeprofiles.at(i);
+                                               if (fbpi.profileID == id && !_tcscmp(fbpi.name, name)) {
+                                                       bridge = FloppyBridgeAPI::createDriverFromProfileID(id);
+                                                       break;
+                                               }
+                                       }
+                                       if (!bridge) {
+                                               for (int i = 0; i < bridgeprofiles.size(); i++) {
+                                                       FloppyBridgeAPI::FloppyBridgeProfileInformation fbpi = bridgeprofiles.at(i);
+                                                       if (!_tcscmp(fbpi.name, name)) {
+                                                               bridge = FloppyBridgeAPI::createDriverFromProfileID(fbpi.profileID);
+                                                               break;
+                                                       }
+                                               }
+                                       }
                                }
                                if (!bridge) {
-                                       configConfigured = false;
-                                       bridge = FloppyBridgeAPI::createDriver(1);
-                                       p->floppyslots[dr].config[0] = 0;
-                                       changed_prefs.floppyslots[dr].config[0] = 0;
+                                       bridge = FloppyBridgeAPI::createDriverFromProfileID(id);
                                }
                                if (bridge) {
-                                       bridge->setBridgeDensityMode(FloppyBridgeAPI::BridgeDensityMode::bdmAuto);
-                                       if (p->floppy_speed == 0) {
-                                               bridge->setBridgeMode(FloppyBridgeAPI::BridgeMode::bmTurboAmigaDOS);
-                                       } else {
-                                               bridge->setBridgeMode(FloppyBridgeAPI::BridgeMode::bmFast);
-                                       }
-                                       if (!configConfigured) {
-                                               bridge->setComPortAutoDetect(true);
-                                               bridge->setDriveCableSelection(type == DRV_FB_B_35_DD || type == DRV_FB_B_35_HD);
-                                       }
                                        if (!bridge->initialise()) {
                                                const char *errorMessage = bridge->getLastErrorMessage();
                                                const char *name = bridge->getDriverInfo()->name;
@@ -4953,10 +4988,6 @@ static void floppybridge_init2(struct uae_prefs *p)
                                                xfree(tname);
                                                xfree(terrorMessage);
                                        } else {
-                                               char *config = NULL;
-                                               bridge->getConfigAsString(&config);
-                                               au_copy(p->floppyslots[dr].config, sizeof(p->floppyslots[dr].config) / sizeof(TCHAR), config);
-                                               _tcscpy(changed_prefs.floppyslots[dr].config, p->floppyslots[dr].config);
                                                bridge_driver[dr] = bridge->getDriverInfo();
                                        }
                                }
@@ -4979,6 +5010,7 @@ static void floppybridge_init2(struct uae_prefs *p)
 void floppybridge_init(struct uae_prefs *p)
 {
        floppybridge_init2(p);
+       floppybridge_reload_profiles();
 }
 
 void DISK_init (void)
@@ -5165,11 +5197,16 @@ static void abrcheck(struct diskinfo *di)
        }
 }
 
-static void get_floppybridgeinfo(TCHAR *infotext, int num)
+static void get_floppybridgeinfo(struct uae_prefs *prefs, TCHAR *infotext, int num)
 {
        if (!infotext) {
                return;
        }
+       floppybridge_init(prefs);
+       if (bridgeinfoloaded <= 1) {
+               FloppyBridgeAPI::getBridgeDriverInformation(true, bridgeinfo);
+               bridgeinfoloaded = 2;
+       }
        TCHAR *p = infotext;
        _tcscat(p, bridgeinfo.about);
        p += _tcslen(p);
@@ -5214,7 +5251,7 @@ int DISK_examine_image(struct uae_prefs *p, int num, struct diskinfo *di, bool d
        memset (di, 0, sizeof (struct diskinfo));
 
        if (fb) {
-               get_floppybridgeinfo(infotext, num);
+               get_floppybridgeinfo(p, infotext, num);
        }
 
        di->unreadable = true;
@@ -5287,17 +5324,19 @@ int DISK_examine_image(struct uae_prefs *p, int num, struct diskinfo *di, bool d
                di->bootblocktype = 2;
        }
 end:
-       load_track(num, 40, 0, sectable);
-       if (sectable[0]) {
-               if (!disk_checksum (writebuffer, NULL) &&
-                       writebuffer[0] == 0 && writebuffer[1] == 0 && writebuffer[2] == 0 && writebuffer[3] == 2 &&
-                       writebuffer[508] == 0 && writebuffer[509] == 0 && writebuffer[510] == 0 && writebuffer[511] == 1) {
-                       writebuffer[512 - 20 * 4 + 1 + writebuffer[512 - 20 * 4]] = 0;
-                       TCHAR *n = au ((const char*)(writebuffer + 512 - 20 * 4 + 1));
-                       if (_tcslen (n) >= sizeof (di->diskname))
-                               n[sizeof (di->diskname) - 1] = 0;
-                       _tcscpy (di->diskname, n);
-                       xfree (n);
+       if (!fb || (fb && infotext)) {
+               load_track(num, 40, 0, sectable);
+               if (sectable[0]) {
+                       if (!disk_checksum(writebuffer, NULL) &&
+                               writebuffer[0] == 0 && writebuffer[1] == 0 && writebuffer[2] == 0 && writebuffer[3] == 2 &&
+                               writebuffer[508] == 0 && writebuffer[509] == 0 && writebuffer[510] == 0 && writebuffer[511] == 1) {
+                               writebuffer[512 - 20 * 4 + 1 + writebuffer[512 - 20 * 4]] = 0;
+                               TCHAR *n = au((const char *)(writebuffer + 512 - 20 * 4 + 1));
+                               if (_tcslen(n) >= sizeof(di->diskname))
+                                       n[sizeof(di->diskname) - 1] = 0;
+                               _tcscpy(di->diskname, n);
+                               xfree(n);
+                       }
                }
        }
 end2:
index 4723e5e3819c2842d44609c129d9bcc285362c9a..cf8664ef6a3e267e09f5b5221075027b279bca29 100644 (file)
@@ -113,12 +113,13 @@ public:
        virtual bool isMotorRunning()  = 0;
 
        // Turn on and off the motor
-       virtual void setMotorStatus(bool turnOn, bool side)  = 0;
+       virtual void setMotorStatus(bool side, bool turnOn)  = 0;
 
        // Returns TRUE if the drive is ready (ie: the motor has spun up to speed to speed)
        virtual bool isReady()  = 0;
 
-
+       // Returns the currently selected side
+       virtual bool getCurrentSide() = 0;
 
        /////////////////////// Disk Detection ///////////////////////////////////////////////////
        // Return TRUE if there is a disk in the drive.  This is usually called after gotoCylinder
index 47716612fe661918d26b77a90e639539e568321a..4055240b1d6c443b6e346a6738cda4c9e1d99f27 100644 (file)
@@ -31,17 +31,38 @@ struct BridgeAbout {
        unsigned int updateMajorVersion, updateMinorVersion;
 };
 
+// Information about a floppy bridge profile
+struct FloppyBridgeProfileInformationDLL {
+       // Unique ID of this profile
+       unsigned int profileID;
+
+       // Driver Index, incase it's shown on the GUI
+       unsigned int driverIndex;
+
+       // Some basic information
+       FloppyBridgeAPI::BridgeMode bridgeMode;
+       FloppyBridgeAPI::BridgeDensityMode bridgeDensityMode;
+
+       // Profile name
+       char* name;
+
+       // Pointer to the Configuration data for this profile. - Be careful. Assume this pointer is invalid after calling *any* of the *profile* functions apart from getAllProfiles
+       char* profileConfig;
+};
+
 #ifdef _WIN32
 #include <Windows.h>
+#ifdef WINUAE
+HMODULE WIN32_LoadLibrary(const TCHAR*);
+#endif
 #define CALLING_CONVENSION _cdecl
 #define GETFUNC GetProcAddress
-HMODULE WIN32_LoadLibrary(const TCHAR *name);
 #else
 #define CALLING_CONVENSION
 #define GETFUNC dlsym
 #endif
 
-#ifdef WIN64
+#ifdef _WIN64
 #define MODULENAME _T("FloppyBridge_x64.dll")
 #else
 #ifdef _WIN32
@@ -60,19 +81,28 @@ void* hBridgeDLLHandle = nullptr;
 
 
 // Bridge library function definitions
-typedef void                    (CALLING_CONVENSION* _BRIDGE_About)(BridgeAbout** output);
+typedef void                    (CALLING_CONVENSION* _BRIDGE_About)(bool allowCheckForUpdates, BridgeAbout** output);
 typedef unsigned int    (CALLING_CONVENSION* _BRIDGE_NumDrivers)(void);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_GetDriverInfo)(unsigned int driverIndex, FloppyDiskBridge::BridgeDriver** driverInformation);
-
+#ifdef _WIN32
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_ShowConfigDialog)(HWND hwndParent, unsigned int* profileID);
+#endif
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_GetAllProfiles)(FloppyBridgeProfileInformationDLL** profiles, unsigned int* numProfiles);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_ImportProfilesFromString)(char* profilesConfigString);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_ExportProfilesToString)(char** profilesConfigString);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_GetProfileConfigFromString)(unsigned int profileID, char** configString);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_SetProfileConfigFromString)(unsigned int profileID, char* configString);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_SetProfileName)(unsigned int profileID, char* name);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_CreateNewProfile)(unsigned int driverIndex, unsigned int* profileID);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_DeleteProfile)(unsigned int profileID);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_EnumComports)(char* output, unsigned int* bufferSize);
-
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_CreateDriver)(unsigned int driverIndex, BridgeDriverHandle* bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_CreateDriverFromConfigString)(char* config, BridgeDriverHandle* bridgeDriverHandle);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_CreateDriverFromProfileID)(unsigned int profileID, BridgeDriverHandle* bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_Close)(BridgeDriverHandle bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_Open)(BridgeDriverHandle bridgeDriverHandle, char** errorMessage);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_GetDriverIndex)(BridgeDriverHandle bridgeDriverHandle, unsigned int* driverIndex);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_FreeDriver)(BridgeDriverHandle bridgeDriverHandle);
-
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_GetConfigString)(BridgeDriverHandle bridgeDriverHandle, char** config);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_SetConfigFromString)(BridgeDriverHandle bridgeDriverHandle, char* config);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_DriverGetAutoCache)(BridgeDriverHandle bridgeDriverHandle, bool* isAutoCacheMode);
@@ -87,6 +117,8 @@ typedef bool                          (CALLING_CONVENSION* _BRIDGE_DriverGetAutoDetectComPort)(Bridge
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_DriverSetAutoDetectComPort)(BridgeDriverHandle bridgeDriverHandle, bool autoDetectComPort);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_DriverGetCable)(BridgeDriverHandle bridgeDriverHandle, bool* isOnB);
 typedef bool                    (CALLING_CONVENSION* _BRIDGE_DriverSetCable)(BridgeDriverHandle bridgeDriverHandle, bool isOnB);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_DriverGetSmartSpeedEnabled)(BridgeDriverHandle bridgeDriverHandle, bool* enabled);
+typedef bool                    (CALLING_CONVENSION* _BRIDGE_DriverSetSmartSpeedEnabled)(BridgeDriverHandle bridgeDriverHandle, bool enabled);
 typedef unsigned char   (CALLING_CONVENSION* _DRIVER_getBitSpeed)(BridgeDriverHandle bridgeDriverHandle);
 typedef FloppyDiskBridge::DriveTypeID (CALLING_CONVENSION* _DRIVER_getDriveTypeID)(BridgeDriverHandle bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_resetDrive)(BridgeDriverHandle bridgeDriverHandle, int trackNumber);
@@ -96,14 +128,15 @@ typedef void                        (CALLING_CONVENSION* _DRIVER_gotoCylinder)(BridgeDriverHandle b
 typedef void                    (CALLING_CONVENSION* _DRIVER_handleNoClickStep)(BridgeDriverHandle bridgeDriverHandle, bool side);
 typedef unsigned char   (CALLING_CONVENSION* _DRIVER_getCurrentCylinderNumber)(BridgeDriverHandle bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_isMotorRunning)(BridgeDriverHandle bridgeDriverHandle);
-typedef void                    (CALLING_CONVENSION* _DRIVER_setMotorStatus)(BridgeDriverHandle bridgeDriverHandle, bool turnOn, bool side);
+typedef bool                    (CALLING_CONVENSION* _DRIVER_getCurrentSide)(BridgeDriverHandle bridgeDriverHandle);
+typedef void                    (CALLING_CONVENSION* _DRIVER_setMotorStatus)(BridgeDriverHandle bridgeDriverHandle, bool side, bool turnOn);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_isReady)(BridgeDriverHandle bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_isDiskInDrive)(BridgeDriverHandle bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_hasDiskChanged)(BridgeDriverHandle bridgeDriverHandle);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_isMFMPositionAtIndex)(BridgeDriverHandle bridgeDriverHandle, int mfmPositionBits);
 typedef bool                    (CALLING_CONVENSION* _DRIVER_isMFMDataAvailable)(BridgeDriverHandle bridgeDriverHandle);
-typedef bool                    (CALLING_CONVENSION* _DRIVER_getMFMBit)(BridgeDriverHandle bridgeDriverHandle, const int mfmPositionBits);
-typedef int                     (CALLING_CONVENSION* _DRIVER_getMFMSpeed)(BridgeDriverHandle bridgeDriverHandle, const int mfmPositionBits);
+typedef bool                    (CALLING_CONVENSION* _DRIVER_getMFMBit)(BridgeDriverHandle bridgeDriverHandle, int mfmPositionBits);
+typedef int                     (CALLING_CONVENSION* _DRIVER_getMFMSpeed)(BridgeDriverHandle bridgeDriverHandle, int mfmPositionBits);
 typedef void                    (CALLING_CONVENSION* _DRIVER_mfmSwitchBuffer)(BridgeDriverHandle bridgeDriverHandle, bool side);
 typedef void                    (CALLING_CONVENSION* _DRIVER_setSurface)(BridgeDriverHandle bridgeDriverHandle, bool side);
 typedef int                     (CALLING_CONVENSION* _DRIVER_maxMFMBitPosition)(BridgeDriverHandle bridgeDriverHandle);
@@ -124,6 +157,16 @@ _BRIDGE_GetDriverInfo      BRIDGE_GetDriverInfo = nullptr;
 _BRIDGE_CreateDriver   BRIDGE_CreateDriver = nullptr;
 _BRIDGE_Close  BRIDGE_Close = nullptr;
 _BRIDGE_Open   BRIDGE_Open = nullptr;
+_BRIDGE_CreateDriverFromProfileID BRIDGE_CreateDriverFromProfileID = nullptr;
+_BRIDGE_GetAllProfiles BRIDGE_GetAllProfiles = nullptr;
+_BRIDGE_ImportProfilesFromString BRIDGE_ImportProfilesFromString = nullptr;
+_BRIDGE_ExportProfilesToString BRIDGE_ExportProfilesToString = nullptr;
+_BRIDGE_GetProfileConfigFromString BRIDGE_GetProfileConfigFromString = nullptr;
+_BRIDGE_SetProfileConfigFromString BRIDGE_SetProfileConfigFromString = nullptr;
+_BRIDGE_SetProfileName BRIDGE_SetProfileName = nullptr;
+_BRIDGE_CreateNewProfile BRIDGE_CreateNewProfile = nullptr;
+_BRIDGE_DeleteProfile BRIDGE_DeleteProfile = nullptr;
+_BRIDGE_ShowConfigDialog BRIDGE_ShowConfigDialog = nullptr;
 _BRIDGE_GetDriverIndex BRIDGE_GetDriverIndex = nullptr;
 _BRIDGE_FreeDriver     BRIDGE_FreeDriver = nullptr;
 _BRIDGE_DriverGetMode  BRIDGE_DriverGetMode = nullptr;
@@ -138,6 +181,8 @@ _BRIDGE_DriverGetCable      BRIDGE_DriverGetCable = nullptr;
 _BRIDGE_DriverSetCable BRIDGE_DriverSetCable = nullptr;
 _BRIDGE_DriverGetAutoCache BRIDGE_DriverGetAutoCache = nullptr;
 _BRIDGE_DriverSetAutoCache BRIDGE_DriverSetAutoCache = nullptr;
+_BRIDGE_DriverGetSmartSpeedEnabled BRIDGE_DriverGetSmartSpeedEnabled = nullptr;
+_BRIDGE_DriverSetSmartSpeedEnabled BRIDGE_DriverSetSmartSpeedEnabled = nullptr;
 _BRIDGE_GetConfigString BRIDGE_GetConfigString = nullptr;
 _BRIDGE_SetConfigFromString BRIDGE_SetConfigFromString = nullptr;
 _BRIDGE_CreateDriverFromConfigString BRIDGE_CreateDriverFromConfigString = nullptr;
@@ -145,6 +190,7 @@ _DRIVER_getBitSpeed DRIVER_getBitSpeed = nullptr;
 _DRIVER_getDriveTypeID DRIVER_getDriveTypeID = nullptr;
 _DRIVER_resetDrive     DRIVER_resetDrive = nullptr;
 _DRIVER_isAtCylinder0  DRIVER_isAtCylinder0 = nullptr;
+_DRIVER_getCurrentSide DRIVER_getCurrentSide = nullptr;
 _DRIVER_getMaxCylinder DRIVER_getMaxCylinder = nullptr;
 _DRIVER_gotoCylinder   DRIVER_gotoCylinder = nullptr;
 _DRIVER_handleNoClickStep      DRIVER_handleNoClickStep = nullptr;
@@ -174,7 +220,15 @@ void prepareBridge() {
        if (hBridgeDLLHandle) return;
 
 #ifdef WIN32
+#ifdef WINUAE
        hBridgeDLLHandle = WIN32_LoadLibrary(MODULENAME);
+#else
+#ifdef _UNICODE
+       hBridgeDLLHandle = LoadLibraryW(MODULENAME);
+#else
+       hBridgeDLLHandle = LoadLibraryA(MODULENAME);
+#endif
+#endif
 #else
        hBridgeDLLHandle = dlopen(MODULENAME, RTLD_NOW);
 #endif
@@ -188,8 +242,18 @@ void prepareBridge() {
        BRIDGE_GetDriverInfo = (_BRIDGE_GetDriverInfo)GETFUNC(hBridgeDLLHandle, "BRIDGE_GetDriverInfo");
        BRIDGE_CreateDriver = (_BRIDGE_CreateDriver)GETFUNC(hBridgeDLLHandle, "BRIDGE_CreateDriver");
        BRIDGE_GetDriverIndex = (_BRIDGE_GetDriverIndex)GETFUNC(hBridgeDLLHandle, "BRIDGE_GetDriverIndex");     
+       BRIDGE_ShowConfigDialog = (_BRIDGE_ShowConfigDialog)GETFUNC(hBridgeDLLHandle, "BRIDGE_ShowConfigDialog");
        BRIDGE_Close = (_BRIDGE_Close)GETFUNC(hBridgeDLLHandle, "BRIDGE_Close");
        BRIDGE_Open = (_BRIDGE_Open)GETFUNC(hBridgeDLLHandle, "BRIDGE_Open");
+       BRIDGE_CreateDriverFromProfileID = (_BRIDGE_CreateDriverFromProfileID)GETFUNC(hBridgeDLLHandle, "BRIDGE_CreateDriverFromProfileID");
+       BRIDGE_GetAllProfiles = (_BRIDGE_GetAllProfiles)GETFUNC(hBridgeDLLHandle, "BRIDGE_GetAllProfiles");
+       BRIDGE_ImportProfilesFromString = (_BRIDGE_ImportProfilesFromString)GETFUNC(hBridgeDLLHandle, "BRIDGE_ImportProfilesFromString");
+       BRIDGE_ExportProfilesToString = (_BRIDGE_ExportProfilesToString)GETFUNC(hBridgeDLLHandle, "BRIDGE_ExportProfilesToString");
+       BRIDGE_GetProfileConfigFromString = (_BRIDGE_GetProfileConfigFromString)GETFUNC(hBridgeDLLHandle, "BRIDGE_GetProfileConfigFromString");
+       BRIDGE_SetProfileConfigFromString = (_BRIDGE_SetProfileConfigFromString)GETFUNC(hBridgeDLLHandle, "BRIDGE_SetProfileConfigFromString");
+       BRIDGE_SetProfileName = (_BRIDGE_SetProfileName)GETFUNC(hBridgeDLLHandle, "BRIDGE_SetProfileName");     
+       BRIDGE_CreateNewProfile = (_BRIDGE_CreateNewProfile)GETFUNC(hBridgeDLLHandle, "BRIDGE_CreateNewProfile");
+       BRIDGE_DeleteProfile = (_BRIDGE_DeleteProfile)GETFUNC(hBridgeDLLHandle, "BRIDGE_DeleteProfile");
        BRIDGE_FreeDriver = (_BRIDGE_FreeDriver)GETFUNC(hBridgeDLLHandle, "BRIDGE_FreeDriver");
        BRIDGE_DriverGetAutoCache = (_BRIDGE_DriverGetAutoCache)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverGetAutoCache");
        BRIDGE_DriverSetAutoCache = (_BRIDGE_DriverSetAutoCache)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverSetAutoCache");
@@ -204,9 +268,12 @@ void prepareBridge() {
        BRIDGE_DriverSetCurrentComPort = (_BRIDGE_DriverSetCurrentComPort)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverSetCurrentComPort");
        BRIDGE_DriverGetAutoDetectComPort = (_BRIDGE_DriverGetAutoDetectComPort)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverGetAutoDetectComPort");
        BRIDGE_DriverSetAutoDetectComPort = (_BRIDGE_DriverSetAutoDetectComPort)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverSetAutoDetectComPort");
+       BRIDGE_DriverGetSmartSpeedEnabled = (_BRIDGE_DriverGetSmartSpeedEnabled)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverGetSmartSpeedEnabled");
+       BRIDGE_DriverSetSmartSpeedEnabled = (_BRIDGE_DriverSetSmartSpeedEnabled)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverSetSmartSpeedEnabled");
        BRIDGE_DriverGetCable = (_BRIDGE_DriverGetCable)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverGetCable");
        BRIDGE_DriverSetCable = (_BRIDGE_DriverSetCable)GETFUNC(hBridgeDLLHandle, "BRIDGE_DriverSetCable");
        DRIVER_getBitSpeed = (_DRIVER_getBitSpeed)GETFUNC(hBridgeDLLHandle, "DRIVER_getBitSpeed");
+       DRIVER_getCurrentSide = (_DRIVER_getCurrentSide)GETFUNC(hBridgeDLLHandle, "DRIVER_getCurrentSide");
        DRIVER_getDriveTypeID = (_DRIVER_getDriveTypeID)GETFUNC(hBridgeDLLHandle, "DRIVER_getDriveTypeID");
        DRIVER_resetDrive = (_DRIVER_resetDrive)GETFUNC(hBridgeDLLHandle, "DRIVER_resetDrive");
        DRIVER_isAtCylinder0 = (_DRIVER_isAtCylinder0)GETFUNC(hBridgeDLLHandle, "DRIVER_isAtCylinder0");
@@ -235,7 +302,7 @@ void prepareBridge() {
        DRIVER_isReadyToWrite = (_DRIVER_isReadyToWrite)GETFUNC(hBridgeDLLHandle, "DRIVER_isReadyToWrite");
 
        // Test a few
-       if ((!BRIDGE_About) || (!BRIDGE_NumDrivers)) {
+       if ((!BRIDGE_About) || (!BRIDGE_NumDrivers) || (!BRIDGE_DeleteProfile)) {
 #ifdef WIN32
                if (hBridgeDLLHandle) FreeLibrary(hBridgeDLLHandle);
                hBridgeDLLHandle = 0;
@@ -282,6 +349,8 @@ std::vector<std::wstring> memoryPortList;
 #else
 std::vector<std::string> memoryPortList;
 #endif
+std::vector<std::string> stringListsForProfiles;
+
 
 /*********** STATIC FUNCTIONS ************************/
 
@@ -294,7 +363,7 @@ const bool FloppyBridgeAPI::isAvailable() {
 
 // Populates bridgeInformation with information about the Bridge DLL. This should be called and shown somewhere
 // As it contains update and support information too
-bool FloppyBridgeAPI::getBridgeDriverInformation(BridgeInformation& bridgeInformation) {
+bool FloppyBridgeAPI::getBridgeDriverInformation(bool allowCheckForUpdates, BridgeInformation& bridgeInformation) {
        if (!isAvailable()) {
                // Populate some basics
                memset(&bridgeInformation, 0, sizeof(bridgeInformation));
@@ -304,7 +373,7 @@ bool FloppyBridgeAPI::getBridgeDriverInformation(BridgeInformation& bridgeInform
        }
        
        BridgeAbout* info = nullptr;
-       BRIDGE_About(&info);
+       BRIDGE_About(allowCheckForUpdates, &info);
        if (!info) return false;
 
        bridgeInformation.isBeta = info->isBeta != 0;
@@ -406,6 +475,130 @@ void FloppyBridgeAPI::enumCOMPorts(std::vector<const TCHAR*>& portList) {
        free(tmp);
 }
 
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Profile based management
+
+
+// Creates the driver instance from a profile ID.  You need to call importProfilesFromString() before using this function
+FloppyBridgeAPI* FloppyBridgeAPI::createDriverFromProfileID(unsigned int profileID) {
+       if (!isAvailable()) return nullptr;
+
+       BridgeDriverHandle driverHandle = nullptr;
+
+       if (!BRIDGE_CreateDriverFromProfileID(profileID, &driverHandle)) return nullptr;
+
+       unsigned int driverIndex;
+       if (!BRIDGE_GetDriverIndex(driverHandle, &driverIndex)) {
+               BRIDGE_FreeDriver(driverHandle);
+               return nullptr;
+       }
+
+       return new FloppyBridgeAPI(driverIndex, driverHandle);
+}
+
+// Retreive a list of all of the profiles currently loaded that can be used.
+bool FloppyBridgeAPI::getAllProfiles(std::vector<FloppyBridgeProfileInformation>& profileList) {
+       if (!isAvailable()) return false;
+
+       profileList.clear();
+       stringListsForProfiles.clear();
+
+       FloppyBridgeProfileInformationDLL* profile = nullptr;
+       unsigned int numProfiles = 0;
+
+       if (!BRIDGE_GetAllProfiles(&profile, &numProfiles)) return false;
+       
+       while (numProfiles) {
+               FloppyBridgeProfileInformation p;
+               p.driverIndex = profile->driverIndex;
+               p.profileID = profile->profileID;
+
+               p.bridgeMode = profile->bridgeMode;
+               p.bridgeDensityMode = profile->bridgeDensityMode;
+
+               _char2TChar(profile->name, p.name, BRIDGE_STRING_MAX_LENGTH);
+               stringListsForProfiles.push_back(profile->profileConfig);
+               profileList.push_back(p);
+               numProfiles--;
+               profile++;
+       }
+
+       // Just populate the strings.. This was incase vector resizes etc changed memory locations
+       for (size_t pos = 0; pos < profileList.size(); pos++)
+               profileList[pos].profileConfig = stringListsForProfiles[pos].c_str();
+
+       return true;
+}
+
+// Imports all profiles into memory from the supplied string.  This will erase any currently in memory
+bool FloppyBridgeAPI::importProfilesFromString(const char* profilesString) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_ImportProfilesFromString((char*)profilesString);
+}
+
+// Exports all profiles and returns a pointer to the string.  This pointer is only valid while the driver is loaded and until this is called again
+bool FloppyBridgeAPI::exportProfilesToString(char** profilesString) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_ExportProfilesToString(profilesString);
+}
+
+// Returns a pointer to a string containing the details for a profile
+bool FloppyBridgeAPI::getProfileConfigAsString(unsigned int profileID, char** config) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_GetProfileConfigFromString(profileID, config);
+}
+
+// Creates a new profile and returns its unique ID
+bool FloppyBridgeAPI::createNewProfile(unsigned int driverIndex, unsigned int* profileID) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_CreateNewProfile(driverIndex, profileID);
+}
+
+
+// Updates a profile from the supplied string
+bool FloppyBridgeAPI::setProfileConfigFromString(unsigned int profileID, const char* config) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_SetProfileConfigFromString(profileID, (char*)config);
+}
+
+// Updates a profile from the supplied string
+bool FloppyBridgeAPI::setProfileName(unsigned int profileID, const char* config) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_SetProfileName(profileID, (char*)config);
+}
+
+// Deletes a profile by ID.
+bool FloppyBridgeAPI::deleteProfile(unsigned int profileID) {
+       if (!isAvailable()) return false;
+
+       return BRIDGE_DeleteProfile(profileID);
+}
+
+#ifdef _WIN32
+// Displys the config dialog (modal) for Floppy Bridge profiles.  
+// *If* you pass a profile ID, the dialog will jump to editing that profile, or return FALSE if it was not found.
+// Returns FALSE if cancel was pressed
+bool FloppyBridgeAPI::showProfileConfigDialog(HWND hwndParent, unsigned int* profileID) {
+       if (!isAvailable()) return false;
+        
+       return BRIDGE_ShowConfigDialog(hwndParent, profileID);
+}
+#endif
+
 /*********** CLASS FUNCTIONS ************************/
 
 // Dont call this. You should use the static createDriver member to create it.
@@ -503,6 +696,17 @@ bool FloppyBridgeAPI::setDriveCableSelection(bool connectToDriveB) {
        return BRIDGE_DriverSetCable(m_handle, connectToDriveB);
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// These require ConfigOption_SmartSpeed bit set in DriverInformation::configOptions
+// Returns if the driver currently has Smart Speed enabled which can dynamically switch between normal and turbo disk speed without breaking copy protection
+bool FloppyBridgeAPI::getSmartSpeedEnabled(bool* enabled) {
+       return BRIDGE_DriverGetSmartSpeedEnabled(m_handle, enabled);
+}
+//  Sets if the driver can dynamically switch between normal and turbo disk speed without breaking copy protectionThis can be set while the bridge is in use
+bool FloppyBridgeAPI::setSmartSpeedEnabled(bool enabled) {
+       return BRIDGE_DriverSetSmartSpeedEnabled(m_handle, enabled);
+}
+
 
 /******************* BRIDGE Functions for UAE **********************************/
 
@@ -573,8 +777,11 @@ unsigned char FloppyBridgeAPI::getCurrentCylinderNumber() {
 bool FloppyBridgeAPI::isMotorRunning() {
        return DRIVER_isMotorRunning(m_handle);
 }
-void FloppyBridgeAPI::setMotorStatus(bool turnOn, bool side) {
-       DRIVER_setMotorStatus(m_handle, turnOn, side);
+void FloppyBridgeAPI::setMotorStatus(bool side, bool turnOn) {
+       DRIVER_setMotorStatus(m_handle, side, turnOn);
+}
+bool FloppyBridgeAPI::getCurrentSide() {
+       return DRIVER_getCurrentSide(m_handle);
 }
 bool FloppyBridgeAPI::isReady() {
        return DRIVER_isReady(m_handle);
index e8d81c0a7806a69aa752c041c7742c1e5635c594..38e0e453d8b112fe71181e37e9812c38817745ab 100644 (file)
 #pragma once
 
 #include "floppybridge_abstract.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <vector>
+#include <string>
 
 #define BRIDGE_STRING_MAX_LENGTH 255
 typedef TCHAR TCharString[BRIDGE_STRING_MAX_LENGTH];
@@ -64,6 +69,7 @@ public:
        static const unsigned int ConfigOption_ComPort                          = 0x02; // The driver requires a COM port selection
        static const unsigned int ConfigOption_AutoDetectComport        = 0x04; // The driver supports automatic com port detection and selection
        static const unsigned int ConfigOption_DriveABCable                     = 0x08; // The driver allows you to specify using cable select for Drive A or Drive B
+       static const unsigned int ConfigOption_SmartSpeed                       = 0x10; // The driver supports dynamically switching between normal and Turbo hopefully without breaking copy protection
 
        // Information about a Bridge Driver (eg: DrawBridge, Greaseweazle etc)
        struct DriverInformation {
@@ -79,6 +85,25 @@ public:
                // A bitmask of which options in configuration the driver can support, aside from the standard ones. See the ConfigOption_ consts above
                unsigned int configOptions;
        };
+
+       // Information about a floppy bridge profile
+       struct FloppyBridgeProfileInformation {
+               // Unique ID of this profile
+               unsigned int profileID;
+
+               // Driver Index, incase it's shown on the GUI
+               unsigned int driverIndex;
+
+               // Some basic information
+               FloppyBridgeAPI::BridgeMode bridgeMode;
+               FloppyBridgeAPI::BridgeDensityMode bridgeDensityMode;
+
+               // Profile name
+               TCharString name;
+
+               // Pointer to the Configuration data for this profile. - Be careful. Assume this pointer is invalid after calling *any* of the *profile* functions apart from getAllProfiles
+               const char* profileConfig;
+       };
        
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -91,7 +116,25 @@ public:
 
        // Populares bridgeInformation with information about the Bridge DLL. This should be called and shown somewhere
        // As it contains update and support information too.  If this returns FALSE it will still contain basic information such as a URL to get the DLL from.
-       static bool getBridgeDriverInformation(BridgeInformation& bridgeInformation);
+       static bool getBridgeDriverInformation(bool allowCheckForUpdates, BridgeInformation& bridgeInformation);
+
+       // Creates a driver instance.  If it fails, it will return NULL.  It should only fail if the index is invalid.
+       static FloppyBridgeAPI* createDriver(unsigned int driverIndex);
+
+       // Create a driver instance from a config string previously saved.  This will auto-select the driverIndex.
+       static FloppyBridgeAPI* createDriverFromString(const char* config);
+
+       // Creates the driver instance from a profile ID.  You need to call importProfilesFromString() before using this function
+       static FloppyBridgeAPI* createDriverFromProfileID(unsigned int profileID);
+
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       // Direct management
 
        // Populates driverList with a list of available floppy bridge drivers that could be created
        static void getDriverList(std::vector<DriverInformation>& driverList);
@@ -100,11 +143,46 @@ public:
        // NOTE: The TCHARs in the vector are only valid until this function is called again
        static void enumCOMPorts(std::vector<const TCHAR*>& portList);
 
-       // Creates a driver.  If it fails, it will return NULL.  It should only fail if the index is invalid.
-       static FloppyBridgeAPI* createDriver(unsigned int driverIndex);
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       // Profile based management
+
+       // Displays the config dialog (modal) for Floppy Bridge profiles.  
+       // *If* you pass a profile ID, the dialog will jump to editing that profile, or return FALSE if it was not found.
+       // Returns FALSE if cancel was pressed
+#ifdef _WIN32
+       static bool showProfileConfigDialog(HWND hwndParent, unsigned int* profileID = nullptr);
+#endif
+
+       // Retrieve a list of all of the profiles currently loaded that can be used.
+       static bool getAllProfiles(std::vector<FloppyBridgeProfileInformation>& profileList);
+
+       // Imports all profiles into memory from the supplied string.  This will erase any currently in memory
+       static bool importProfilesFromString(const char* profilesString);
+
+       // Exports all profiles and returns a pointer to the string.  This pointer is only valid while the driver is loaded and until this is called again
+       static bool exportProfilesToString(char** profilesString);
+
+       // Returns a pointer to a string containing the details for a profile
+       static bool getProfileConfigAsString(unsigned int profileID, char** config);
+
+       // Updates a profile from the supplied string
+       static bool setProfileConfigFromString(unsigned int profileID, const char* config);
+
+       // Updates a profile name the supplied string
+       static bool setProfileName(unsigned int profileID, const char* name);
+
+       // Creates a new profile and returns its unique ID
+       static bool createNewProfile(unsigned int driverIndex, unsigned int* profileID);
+
+       // Deletes a profile by ID.
+       static bool deleteProfile(unsigned int profileID);
 
-       // Createw a driver from a config string previously saved.  This will auto-select the driverIndex.
-       static FloppyBridgeAPI* createDriverFromString(const char* config);
 
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -159,12 +237,12 @@ public:
        // Sets if the driver should use a drive connected as Drive B (true) on the cable rather than Drive A (false)
        bool setDriveCableSelection(bool connectToDriveB);
 
-
-
-
-
-
-
+       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+       // These require ConfigOption_SmartSpeed bit set in DriverInformation::configOptions
+       // Returns if the driver currently has Smart Speed enabled which can dynamically switch between normal and turbo disk speed without breaking copy protection
+       bool getSmartSpeedEnabled(bool* enabled);
+       //  Sets if the driver can dynamically switch between normal and turbo disk speed without breaking copy protectionThis can be set while the bridge is in use
+       bool setSmartSpeedEnabled(bool enabled);
 
 
 
@@ -191,10 +269,11 @@ public:
        virtual void handleNoClickStep(bool side) override;
        virtual unsigned char getCurrentCylinderNumber() override;
        virtual bool isMotorRunning() override;
-       virtual void setMotorStatus(bool turnOn, bool side) override;
+       virtual void setMotorStatus(bool side, bool turnOn) override;
        virtual bool isReady() override;
        virtual bool isDiskInDrive() override;
        virtual bool hasDiskChanged() override;
+       virtual bool getCurrentSide() override;
        virtual bool isMFMPositionAtIndex(int mfmPositionBits) override;
        virtual bool isMFMDataAvailable() override;
        virtual bool getMFMBit(const int mfmPositionBits) override;
index 53c53e85a1320c7fa4e27695fa388f2286bb650d..0df447050ef51adeb502ff3c6e9682f584bb5293 100644 (file)
@@ -12,8 +12,7 @@
 #include "uae/types.h"
 
 typedef enum {
-       DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ESCOM, DRV_PC_525_ONLY_40, DRV_PC_35_ONLY_80, DRV_PC_525_40_80, DRV_525_DD,
-       DRV_FB_A_35_DD, DRV_FB_A_35_HD, DRV_FB_B_35_DD, DRV_FB_B_35_HD,
+       DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ESCOM, DRV_PC_525_ONLY_40, DRV_PC_35_ONLY_80, DRV_PC_525_40_80, DRV_525_DD, DRV_FB,
 } drive_type;
 
 #define HISTORY_FLOPPY 0
@@ -119,8 +118,13 @@ extern int disk_debug_track;
 
 #define MAX_PREVIOUS_IMAGES 50
 
-void floppybridge_init(struct uae_prefs *p);
+#ifdef FLOPPYBRIDGE
 bool floppybridge_has(void);
 bool DISK_isfloppybridge(struct uae_prefs*, int);
+void floppybridge_init(struct uae_prefs *p);
+void floppybridge_reload_profiles(void);
+void floppybridge_set_config(const char*);
+extern bool floppybridge_available;
+#endif
 
 #endif /* UAE_DISK_H */
index 901896f350e0693da589c716ba834cd56e150973..48b53304d249fd14025cb6d718449435e01def6d 100644 (file)
@@ -161,10 +161,11 @@ struct floppyslot
 {
        TCHAR df[MAX_DPATH];
        int dfxtype;
+       int dfxsubtype;
+       TCHAR dfxsubtypeid[32];
        int dfxclick;
        TCHAR dfxclickexternal[256];
        bool forcedwriteprotect;
-       TCHAR config[256];
 };
 
 #define ASPECTMULT 1024
index fd811d5ecb12b8d7de787344bd87d03ab3490092..6d83f47feabf36b70049c1bbf3c442661720d4cb 100644 (file)
@@ -1122,23 +1122,25 @@ BEGIN
     COMBOBOX        IDC_QUICKSTART_HOSTCONFIG,77,134,310,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     GROUPBOX        "Emulated Drives",IDC_QUICKSTART_DF,1,163,393,93
     CONTROL         "Floppy drive DF0:",IDC_DF0QENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,176,77,15
-    PUSHBUTTON      "Select image file",IDC_DF0QQ,93,176,98,15
-    RTEXT           "Write-protected",IDC_DF0WPTEXTQ,196,179,69,10,SS_CENTERIMAGE
-    CONTROL         "",IDC_DF0WPQ,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,270,177,10,15
+    PUSHBUTTON      "Select image file",IDC_DF0QQ,85,176,88,15
+    RTEXT           "Write-protected",IDC_DF0WPTEXTQ,244,179,69,10,SS_CENTERIMAGE
+    CONTROL         "",IDC_DF0WPQ,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,318,177,10,15
     PUSHBUTTON      "?",IDC_INFO0Q,334,176,19,15
     PUSHBUTTON      "Eject",IDC_EJECT0Q,358,176,30,15
     COMBOBOX        IDC_DF0TEXTQ,9,195,379,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     CONTROL         "Floppy drive DF1:",IDC_DF1QENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,214,77,15
-    PUSHBUTTON      "Select image file",IDC_DF1QQ,93,214,98,15
-    RTEXT           "Write-protected",IDC_DF1WPTEXTQ,195,217,69,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_CD0Q_TYPE,199,215,74,50,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "",IDC_DF1WPQ,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,270,213,10,15
+    PUSHBUTTON      "Select image file",IDC_DF1QQ,85,214,88,15
+    RTEXT           "Write-protected",IDC_DF1WPTEXTQ,243,217,69,10,SS_CENTERIMAGE
+    COMBOBOX        IDC_CD0Q_TYPE,253,215,74,50,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "",IDC_DF1WPQ,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,316,213,10,15
     PUSHBUTTON      "?",IDC_INFO1Q,334,214,19,15
     PUSHBUTTON      "Eject",IDC_EJECT1Q,358,214,30,15
     COMBOBOX        IDC_DF1TEXTQ,9,232,379,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Set configuration",IDC_QUICKSTART_SETCONFIG,9,266,88,15,NOT WS_VISIBLE
     GROUPBOX        "Mode",IDC_STATIC,250,258,144,28,BS_LEFT
     CONTROL         "Start in Quickstart mode",IDC_QUICKSTARTMODE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,259,269,131,12
+    COMBOBOX        IDC_DF0TYPE,179,177,66,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_DF1TYPE,179,215,68,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_FRONTEND DIALOGEX 0, 0, 420, 242
index 7d666750efc9cbfcae9d8b3f2059dc491fa8a4a9..b7b2e25b81e011e3cfea1f02f7a594175d47879b 100644 (file)
@@ -5584,6 +5584,7 @@ static void WIN32_HandleRegistryStuff (void)
        DWORD dwDisplayInfoSize = sizeof (colortype);
        int size;
        TCHAR path[MAX_DPATH] = _T("");
+       TCHAR tmp[MAX_DPATH];
        TCHAR version[100];
 
        initpath (_T("FloppyPath"), start_path_data);
@@ -5692,6 +5693,15 @@ static void WIN32_HandleRegistryStuff (void)
 
        if (!regqueryint (NULL, _T("QuickStartMode"), &quickstart))
                quickstart = 1;
+
+       tmp[0] = 0;
+       size = sizeof(tmp) / sizeof(TCHAR);
+       if (regquerystr(NULL, _T("FloppyBridge"), tmp, &size)) {
+               char *c = ua(tmp);
+               floppybridge_set_config(c);
+               xfree(c);
+       }
+
        reopen_console ();
        fetch_path (_T("ConfigurationPath"), path, sizeof (path) / sizeof (TCHAR));
        if (path[0])
@@ -7944,7 +7954,7 @@ static SETPROCESSMITIGATIONPOLICY pSetProcessMitigationPolicy;
 #endif
 
 int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
-{
+ {
        DWORD_PTR sys_aff;
        HANDLE thread;
 
index fa40854bc0ed78cbdadff0829241e9a1abab4d08..471959e492bbb261ac386f8a0f209283eb13e6ed 100644 (file)
 #include "ini.h"
 #include "specialmonitors.h"
 #include "gayle.h"
+#ifdef FLOPPYBRIDGE
+#include "floppybridge/floppybridge_abstract.h"
+#include "floppybridge/floppybridge_lib.h"
+#endif
 
 #define GUI_SCALE_DEFAULT 100
 
@@ -167,6 +171,8 @@ static TCHAR stored_path[MAX_DPATH];
 static int gui_size_changed;
 static int filterstackpos = 2 * MAX_FILTERSHADERS;
 
+extern std::vector<FloppyBridgeAPI::FloppyBridgeProfileInformation> bridgeprofiles;
+
 bool isguiactive(void)
 {
        return gui_active > 0;
@@ -7283,6 +7289,7 @@ static void testimage (HWND hDlg, int num)
        }
        if (!workprefs.floppyslots[num].df[0])
                return;
+       floppybridge_init(&workprefs);
        ret = DISK_examine_image (&workprefs, num, &di, false, NULL);
        if (!ret)
                return;
@@ -7337,6 +7344,124 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
 static int diskselectmenu (HWND hDlg, WPARAM wParam);
 static void addallfloppies (HWND hDlg);
 
+#define BUTTONSPERFLOPPY 9
+static const int floppybuttons[][BUTTONSPERFLOPPY] = {
+       { IDC_DF0TEXT,IDC_DF0,IDC_EJECT0,IDC_DF0TYPE,IDC_DF0WP,-1,IDC_SAVEIMAGE0,IDC_DF0ENABLE, IDC_INFO0 },
+       { IDC_DF1TEXT,IDC_DF1,IDC_EJECT1,IDC_DF1TYPE,IDC_DF1WP,-1,IDC_SAVEIMAGE1,IDC_DF1ENABLE, IDC_INFO1 },
+       { IDC_DF2TEXT,IDC_DF2,IDC_EJECT2,IDC_DF2TYPE,IDC_DF2WP,-1,IDC_SAVEIMAGE2,IDC_DF2ENABLE, IDC_INFO2 },
+       { IDC_DF3TEXT,IDC_DF3,IDC_EJECT3,IDC_DF3TYPE,IDC_DF3WP,-1,IDC_SAVEIMAGE3,IDC_DF3ENABLE, IDC_INFO3 }
+};
+static const int floppybuttonsq[][BUTTONSPERFLOPPY] = {
+       { IDC_DF0TEXTQ,IDC_DF0QQ,IDC_EJECT0Q,IDC_DF0TYPE,IDC_DF0WPQ,IDC_DF0WPTEXTQ,-1,IDC_DF0QENABLE, IDC_INFO0Q },
+       { IDC_DF1TEXTQ,IDC_DF1QQ,IDC_EJECT1Q,IDC_DF1TYPE,IDC_DF1WPQ,IDC_DF1WPTEXTQ,-1,IDC_DF1QENABLE, IDC_INFO1Q },
+       { -1,-1,-1,-1,-1,-1,-1,-1 },
+       { -1,-1,-1,-1,-1,-1,-1,-1 }
+};
+
+static int fromdfxtype(int num, int dfx, int subtype)
+{
+       if (currentpage == QUICKSTART_ID) {
+               switch (dfx)
+               {
+               case DRV_35_DD:
+                       return 0;
+               case DRV_35_HD:
+                       return 1;
+               }
+               if (dfx == DRV_FB) {
+                       return 2 + subtype;
+               }
+               return -1;
+       }
+
+       switch (dfx)
+       {
+       case DRV_35_DD:
+               return 0;
+       case DRV_35_HD:
+               return 1;
+       case DRV_525_SD:
+               return 2;
+       case DRV_525_DD:
+               return 3;
+       case DRV_35_DD_ESCOM:
+               return 4;
+       }
+       if (num < 2) {
+               if (dfx == DRV_FB) {
+                       return 5 + subtype;
+               }
+       } else {
+               switch (dfx)
+               {
+               case DRV_PC_525_ONLY_40:
+                       return 5;
+               case DRV_PC_525_40_80:
+                       return 6;
+               case DRV_PC_35_ONLY_80:
+                       return 7;
+               }
+               if (dfx == DRV_FB) {
+                       return 8 + subtype;
+               }
+       }
+       return -1;
+}
+
+static int todfxtype(int num, int dfx, int *subtype)
+{
+       *subtype = 0;
+       if (currentpage == QUICKSTART_ID) {
+               switch (dfx)
+               {
+               case 0:
+                       return DRV_35_DD;
+               case 1:
+                       return DRV_35_HD;
+               }
+               if (dfx >= 2) {
+                       *subtype = dfx - 2;
+                       return DRV_FB;
+               }
+               return -1;
+       }
+
+       switch (dfx)
+       {
+       case 0:
+               return DRV_35_DD;
+       case 1:
+               return DRV_35_HD;
+       case 2:
+               return DRV_525_SD;
+       case 3:
+               return DRV_525_DD;
+       case 4:
+               return DRV_35_DD_ESCOM;
+       }
+       if (num < 2) {
+               if (dfx >= 5) {
+                       *subtype = dfx - 5;
+                       return DRV_FB;
+               }
+       } else {
+               switch (dfx)
+               {
+               case 5:
+                       return DRV_PC_525_ONLY_40;
+               case 6:
+                       return DRV_PC_525_40_80;
+               case 7:
+                       return DRV_PC_35_ONLY_80;
+               }
+               if (dfx >= 8) {
+                       *subtype = dfx - 8;
+                       return DRV_FB;
+               }
+       }
+       return -1;
+}
+
 static void setfloppytexts (HWND hDlg, int qs)
 {
        SetDlgItemText (hDlg, IDC_DF0TEXT, workprefs.floppyslots[0].df);
@@ -7349,6 +7474,55 @@ static void setfloppytexts (HWND hDlg, int qs)
                addallfloppies (hDlg);
 }
 
+static void updatefloppytypes(HWND hDlg)
+{
+       TCHAR ft35dd[20], ft35hd[20], ft525sd[20], ftdis[20], ft35ddescom[20];
+       bool qs = currentpage == QUICKSTART_ID;
+
+       WIN32GUI_LoadUIString(IDS_FLOPPYTYPE35DD, ft35dd, sizeof ft35dd / sizeof(TCHAR));
+       WIN32GUI_LoadUIString(IDS_FLOPPYTYPE35HD, ft35hd, sizeof ft35hd / sizeof(TCHAR));
+       WIN32GUI_LoadUIString(IDS_FLOPPYTYPE525SD, ft525sd, sizeof ft525sd / sizeof(TCHAR));
+       WIN32GUI_LoadUIString(IDS_FLOPPYTYPE35DDESCOM, ft35ddescom, sizeof ft35ddescom / sizeof(TCHAR));
+       WIN32GUI_LoadUIString(IDS_FLOPPYTYPEDISABLED, ftdis, sizeof ftdis / sizeof(TCHAR));
+
+       for (int i = 0; i < (qs ? 2 : 4); i++) {
+               int f_type;
+               if (qs) {
+                       f_type = floppybuttonsq[i][3];
+               } else {
+                       f_type = floppybuttons[i][3];
+               }
+               SendDlgItemMessage(hDlg, f_type, CB_RESETCONTENT, 0, 0L);
+               //SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ftdis);
+               SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35dd);
+               SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35hd);
+               if (!qs) {
+                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft525sd);
+                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("5.25\" (80)"));
+                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35ddescom);
+                       if (i >= 2) {
+                               SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridgeboard 5.25\" 40"));
+                               SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridgeboard 5.25\" 80"));
+                               SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridgeboard 3.5\"  80"));
+                       }
+               }
+               if (floppybridge_available) {
+                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Configure FloppyBridge"));
+                       for (int j = 0; j < bridgeprofiles.size(); j++) {
+                               FloppyBridgeAPI::FloppyBridgeProfileInformation fbpi = bridgeprofiles.at(j);
+                               TCHAR tmp[256];
+                               if (_tcslen(fbpi.name) < sizeof(tmp) - 10) {
+                                       _stprintf(tmp, _T("FB: %s"), fbpi.name);
+                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)tmp);
+                               }
+                       }
+               }
+               int nn = fromdfxtype(i, workprefs.floppyslots[i].dfxtype, workprefs.floppyslots[i].dfxsubtype);
+               SendDlgItemMessage(hDlg, f_type, CB_SETCURSEL, nn, 0L);
+       }
+}
+
+
 static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        static int recursive;
@@ -7372,6 +7546,8 @@ static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, L
                        currentpage = QUICKSTART_ID;
                        enable_for_quickstart (hDlg);
                        setfloppytexts (hDlg, true);
+                       floppybridge_init(&workprefs);
+                       updatefloppytypes(hDlg);
                        setmultiautocomplete (hDlg, ids);
                        doinit = 1;
                        break;
@@ -7512,6 +7688,8 @@ static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, L
                case IDC_DF1QENABLE:
                case IDC_INFO0Q:
                case IDC_INFO1Q:
+               case IDC_DF0TYPE:
+               case IDC_DF1TYPE:
                        if (currentpage == QUICKSTART_ID)
                                ret = FloppyDlgProc (hDlg, msg, wParam, lParam);
                        break;
@@ -15579,24 +15757,10 @@ static void out_floppyspeed (HWND hDlg)
        SetDlgItemText (hDlg, IDC_FLOPPYSPDTEXT, txt);
 }
 
-#define BUTTONSPERFLOPPY 9
-static const int floppybuttons[][BUTTONSPERFLOPPY] = {
-       { IDC_DF0TEXT,IDC_DF0,IDC_EJECT0,IDC_DF0TYPE,IDC_DF0WP,-1,IDC_SAVEIMAGE0,IDC_DF0ENABLE, IDC_INFO0 },
-       { IDC_DF1TEXT,IDC_DF1,IDC_EJECT1,IDC_DF1TYPE,IDC_DF1WP,-1,IDC_SAVEIMAGE1,IDC_DF1ENABLE, IDC_INFO1 },
-       { IDC_DF2TEXT,IDC_DF2,IDC_EJECT2,IDC_DF2TYPE,IDC_DF2WP,-1,IDC_SAVEIMAGE2,IDC_DF2ENABLE, IDC_INFO2 },
-       { IDC_DF3TEXT,IDC_DF3,IDC_EJECT3,IDC_DF3TYPE,IDC_DF3WP,-1,IDC_SAVEIMAGE3,IDC_DF3ENABLE, IDC_INFO3 }
-};
-static const int floppybuttonsq[][BUTTONSPERFLOPPY] = {
-       { IDC_DF0TEXTQ,IDC_DF0QQ,IDC_EJECT0Q,-1,IDC_DF0WPQ,IDC_DF0WPTEXTQ,-1,IDC_DF0QENABLE, IDC_INFO0Q },
-       { IDC_DF1TEXTQ,IDC_DF1QQ,IDC_EJECT1Q,-1,IDC_DF1WPQ,IDC_DF1WPTEXTQ,-1,IDC_DF1QENABLE, IDC_INFO1Q },
-       { -1,-1,-1,-1,-1,-1,-1,-1 },
-       { -1,-1,-1,-1,-1,-1,-1,-1 }
-};
-
 static int isfloppybridge(int type)
 {
-       if (type >= DRV_FB_A_35_DD) {
-               return type - DRV_FB_A_35_DD;
+       if (type >= DRV_FB) {
+               return type - DRV_FB;
        }
        return -1;
 }
@@ -15632,8 +15796,7 @@ static void updatedfname(HWND hDlg, const TCHAR *text, int f_text, int type, int
        if (type == HISTORY_FLOPPY && DISK_isfloppybridge(&workprefs, num)) {
                TCHAR text2[MAX_DPATH];
                DISK_get_path_text(&workprefs, num, text2);
-               if (text)
-                       SendDlgItemMessage(hDlg, f_text, WM_SETTEXT, 0, (LPARAM)text2);
+               SendDlgItemMessage(hDlg, f_text, WM_SETTEXT, 0, (LPARAM)text2);
        } else {
                if (text)
                        SendDlgItemMessage(hDlg, f_text, WM_SETTEXT, 0, (LPARAM)text);
@@ -15759,132 +15922,10 @@ static void addcdtype (HWND hDlg, int id)
        SendDlgItemMessage (hDlg, id, CB_SETCURSEL, cdtype, 0);
 }
 
-static int fromdfxtype(int num, int dfx)
-{
-       switch (dfx)
-       {
-       case DRV_35_DD:
-               return 1;
-       case DRV_35_HD:
-               return 2;
-       case DRV_525_SD:
-               return 3;
-       case DRV_525_DD:
-               return 4;
-       case DRV_35_DD_ESCOM:
-               return 5;
-       }
-       if (num < 2) {
-               switch (dfx)
-               {
-               case DRV_FB_A_35_DD:
-                       if (!floppybridge_has()) {
-                               return 1;
-                       }
-                       return 6;
-               case DRV_FB_A_35_HD:
-                       if (!floppybridge_has()) {
-                               return 1;
-                       }
-                       return 7;
-               case DRV_FB_B_35_DD:
-               if (!floppybridge_has()) {
-                       return 1;
-               }
-               return 8;
-               case DRV_FB_B_35_HD:
-               if (!floppybridge_has()) {
-                       return 1;
-               }
-               return 9;
-       }
-} else {
-               switch (dfx)
-               {
-               case DRV_PC_525_ONLY_40:
-                       return 6;
-               case DRV_PC_525_40_80:
-                       return 7;
-               case DRV_PC_35_ONLY_80:
-                       return 8;
-               case DRV_FB_A_35_DD:
-                       if (!floppybridge_has()) {
-                               return 1;
-                       }
-                       return 9;
-               case DRV_FB_A_35_HD:
-                       if (!floppybridge_has()) {
-                               return 1;
-                       }
-                       return 10;
-               case DRV_FB_B_35_DD:
-                       if (!floppybridge_has()) {
-                               return 1;
-                       }
-                       return 11;
-               case DRV_FB_B_35_HD:
-                       if (!floppybridge_has()) {
-                               return 1;
-                       }
-                       return 11;
-               }
-       }
-       return 0;
-}
-
-static int todfxtype(int num, int dfx)
-{
-       switch (dfx)
-       {
-       case 1:
-               return DRV_35_DD;
-       case 2:
-               return DRV_35_HD;
-       case 3:
-               return DRV_525_SD;
-       case 4:
-               return DRV_525_DD;
-       case 5:
-               return DRV_35_DD_ESCOM;
-       }
-       if (num < 2) {
-               switch (dfx)
-               {
-               case 6:
-                       return DRV_FB_A_35_DD;
-               case 7:
-                       return DRV_FB_A_35_HD;
-               case 8:
-                       return DRV_FB_B_35_DD;
-               case 9:
-                       return DRV_FB_B_35_HD;
-               }
-       } else {
-               switch (dfx)
-               {
-               case 6:
-                       return DRV_PC_525_ONLY_40;
-               case 7:
-                       return DRV_PC_525_40_80;
-               case 8:
-                       return DRV_PC_35_ONLY_80;
-               case 9:
-                       return DRV_FB_A_35_DD;
-               case 10:
-                       return DRV_FB_A_35_HD;
-               case 11:
-                       return DRV_FB_A_35_DD;
-               case 12:
-                       return DRV_FB_A_35_HD;
-               }
-       }
-       return -1;
-}
-
 static void addfloppytype (HWND hDlg, int n)
 {
        int state, chk;
-       int nn = fromdfxtype(n, workprefs.floppyslots[n].dfxtype);
+       int nn = fromdfxtype(n, workprefs.floppyslots[n].dfxtype, workprefs.floppyslots[n].dfxsubtype);
        int fb = DISK_isfloppybridge(&workprefs, n);
        int showcd = 0;
        TCHAR *text;
@@ -15904,7 +15945,7 @@ static void addfloppytype (HWND hDlg, int n)
                TCHAR tmp[MAX_DPATH];
                f_text = floppybuttonsq[n][0];
                f_drive = floppybuttonsq[n][1];
-               f_type = -1;
+               f_type = floppybuttonsq[n][3];
                f_eject = floppybuttonsq[n][2];
                f_wp = floppybuttonsq[n][4];
                f_wptext = floppybuttonsq[n][5];
@@ -15941,7 +15982,7 @@ static void addfloppytype (HWND hDlg, int n)
                hide (hDlg, IDC_CD0Q_TYPE, 1);
        }
 
-       if (nn <= 0)
+       if (nn < 0)
                state = FALSE;
        else
                state = TRUE;
@@ -15981,33 +16022,71 @@ static void addfloppytype (HWND hDlg, int n)
        chk = !showcd && disk_getwriteprotect (&workprefs, text, n) && state == TRUE ? BST_CHECKED : 0;
        if (f_wp >= 0) {
                CheckDlgButton(hDlg, f_wp, chk);
-               ew(hDlg, f_wp, !fb);
        }
        if (f_info >= 0)
                ew (hDlg, f_info, text[0] != 0 || fb);
        chk = !showcd && state && DISK_validate_filename (&workprefs, text, n, NULL, 0, NULL, NULL, NULL) ? TRUE : FALSE;
        if (f_wp >= 0) {
-               ew (hDlg, f_wp, chk && !workprefs.floppy_read_only);
+               ew (hDlg, f_wp, chk && !workprefs.floppy_read_only && !fb);
                if (f_wptext >= 0)
                        ew (hDlg, f_wptext, chk);
        }
+       if (f_type >= 0) {
+               ew(hDlg, f_type, workprefs.floppyslots[n].dfxtype >= 0);
+       }
 }
 
 static void getfloppytype(HWND hDlg, int n)
 {
-       int f_text = floppybuttons[n][0];
-       int f_type = floppybuttons[n][3];
-       LRESULT val = SendDlgItemMessage(hDlg, f_type, CB_GETCURSEL, 0, 0L);
+       int f_text;
+       int f_type;
 
-       if (val != CB_ERR && workprefs.floppyslots[n].dfxtype != todfxtype(n, val)) {
-               workprefs.floppyslots[n].dfxtype = todfxtype(n, val);
-               workprefs.floppyslots[n].config[0] = 0;
+       if (currentpage == QUICKSTART_ID) {
+               f_text = floppybuttonsq[n][0];
+               f_type = floppybuttonsq[n][3];
+       } else {
+               f_text = floppybuttons[n][0];
+               f_type = floppybuttons[n][3];
+       }
+       LRESULT val = SendDlgItemMessage(hDlg, f_type, CB_GETCURSEL, 0, 0L);
+       int sub;
+       
+       if (val != CB_ERR && (workprefs.floppyslots[n].dfxtype != todfxtype(n, val, &sub) || workprefs.floppyslots[n].dfxsubtype != sub)) {
+               workprefs.floppyslots[n].dfxtype = todfxtype(n, val, &sub);
+               workprefs.floppyslots[n].dfxsubtype = sub;
+               workprefs.floppyslots[n].dfxsubtypeid[0] = 0;
+               if (workprefs.floppyslots[n].dfxtype == DRV_FB) {
+                       if (sub == 0) {
+                               FloppyBridgeAPI::showProfileConfigDialog(hDlg);
+                               floppybridge_reload_profiles();
+                               updatefloppytypes(hDlg);
+                               char *c = NULL;
+                               FloppyBridgeAPI::exportProfilesToString(&c);
+                               TCHAR *cc = au(c);
+                               regsetstr(NULL, _T("FloppyBridge"), cc);
+                               xfree(cc);
+                               workprefs.floppyslots[n].dfxtype = DRV_FB;
+                               sub = 1;
+                               workprefs.floppyslots[n].dfxsubtype = sub;
+                               if (bridgeprofiles.size() == 0) {
+                                       workprefs.floppyslots[n].dfxtype = DRV_35_DD;
+                                       workprefs.floppyslots[n].dfxsubtype = 0;
+                                       sub = 0;
+                               }
+                       }
+                       if (sub > 0) {
+                               if (sub - 1 < bridgeprofiles.size()) {
+                                       int nsub = sub - 1;
+                                       _stprintf(workprefs.floppyslots[n].dfxsubtypeid, _T("%d:%s"), bridgeprofiles.at(nsub).profileID, bridgeprofiles.at(nsub).name);
+                               }
+                       }
+               }
                for (int i = 0; i < 4; i++) {
-                       if (i != n && DISK_isfloppybridge(&workprefs, i) && DISK_isfloppybridge(&workprefs, n)) {
+                       if (i != n && workprefs.floppyslots[i].dfxtype == DRV_FB && sub == workprefs.floppyslots[i].dfxsubtype) {
                                workprefs.floppyslots[n].dfxtype = DRV_35_DD;
+                               workprefs.floppyslots[n].dfxsubtype = 0;
                        }
                }
-               floppybridge_init(&workprefs);
                addfloppytype(hDlg, n);
                addhistorymenu(hDlg, NULL, f_text, HISTORY_FLOPPY, true, n);
                updatedfname(hDlg, workprefs.floppyslots[n].df, f_text, HISTORY_FLOPPY, n);
@@ -16196,10 +16275,10 @@ static int diskselectmenu (HWND hDlg, WPARAM wParam)
        return 0;
 }
 
+
 static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        static int recursive = 0;
-       int i;
        static TCHAR diskname[40] = { _T("") };
        static int dropopen;
 
@@ -16210,7 +16289,7 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
        {
        case WM_INITDIALOG:
                {
-                       TCHAR ft35dd[20], ft35hd[20], ft35ddpc[20], ft35hdpc[20],  ft525sd[20], ftdis[20], ft35ddescom[20];
+                       TCHAR ft35dd[20], ft35hd[20], ft35ddpc[20], ft35hdpc[20],  ft525sd[20];
                        int df0texts[] = { IDC_DF0TEXT, IDC_DF1TEXT, IDC_DF2TEXT, IDC_DF3TEXT, -1 };
 
                        WIN32GUI_LoadUIString (IDS_FLOPPYTYPE35DD, ft35dd, sizeof ft35dd / sizeof (TCHAR));
@@ -16218,8 +16297,6 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                        WIN32GUI_LoadUIString (IDS_FLOPPYTYPE35DDPC, ft35ddpc, sizeof ft35ddpc / sizeof (TCHAR));
                        WIN32GUI_LoadUIString (IDS_FLOPPYTYPE35HDPC, ft35hdpc, sizeof ft35hdpc / sizeof (TCHAR));
                        WIN32GUI_LoadUIString (IDS_FLOPPYTYPE525SD, ft525sd, sizeof ft525sd / sizeof (TCHAR));
-                       WIN32GUI_LoadUIString (IDS_FLOPPYTYPE35DDESCOM, ft35ddescom, sizeof ft35ddescom / sizeof (TCHAR));
-                       WIN32GUI_LoadUIString (IDS_FLOPPYTYPEDISABLED, ftdis, sizeof ftdis / sizeof (TCHAR));
                        pages[FLOPPY_ID] = hDlg;
                        if (workprefs.floppy_speed > 0 && workprefs.floppy_speed < 10)
                                workprefs.floppy_speed = 100;
@@ -16233,28 +16310,8 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                        SendDlgItemMessage(hDlg, IDC_FLOPPYTYPE, CB_ADDSTRING, 0, (LPARAM)ft35hdpc);
                        SendDlgItemMessage(hDlg, IDC_FLOPPYTYPE, CB_ADDSTRING, 0, (LPARAM)ft525sd);
                        SendDlgItemMessage (hDlg, IDC_FLOPPYTYPE, CB_SETCURSEL, 0, 0);
-                       for (i = 0; i < 4; i++) {
-                               int f_type = floppybuttons[i][3];
-                               SendDlgItemMessage (hDlg, f_type, CB_RESETCONTENT, 0, 0L);
-                               SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ftdis);
-                               SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35dd);
-                               SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35hd);
-                               SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft525sd);
-                               SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("5.25\" (80)"));
-                               SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35ddescom);
-                               if (i >= 2) {
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridgeboard 5.25\" 40"));
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridgeboard 5.25\" 80"));
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridgeboard 3.5\"  80"));
-                               }
-                               if (floppybridge_has()) {
-                                       floppybridge_init(&workprefs);
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("FloppyBridge A: 3.5\" DD"));
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("FloppyBridge A: 3.5\" HD"));
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("FloppyBridge B: 3.5\" DD"));
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("FloppyBridge B: 3.5\" HD"));
-                               }
-                       }
+                       floppybridge_init(&workprefs);
+                       updatefloppytypes(hDlg);
                        setmultiautocomplete (hDlg, df0texts);
                        dropopen = 0;
                }