]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
rc2 wip
authorToni Wilen <twilen@winuae.net>
Sat, 19 Jun 2010 12:46:58 +0000 (15:46 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 19 Jun 2010 12:46:58 +0000 (15:46 +0300)
14 files changed:
blkdev.cpp
blkdev_cdimage.cpp
cfgfile.cpp
driveclick.cpp
include/blkdev.h
include/options.h
od-win32/blkdev_win32_ioctl.cpp
od-win32/blkdev_win32_spti.cpp
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/rp.cpp
od-win32/win32.h
od-win32/win32gui.cpp
scsiemul.cpp

index d714127d26c42d78c336877dc8f1c344c5d1c07c..523ee2680a57695c43717782fc00d1f97f555b05 100644 (file)
@@ -32,8 +32,10 @@ static void install_driver (int flags)
 
        device_func[DF_IOCTL] = NULL;
        device_func[DF_SCSI] = &devicefunc_win32_aspi;
-       if (devicefunc_cdimage.openbus (0)) {
+       if (devicefunc_cdimage.openbus (flags)) {
                device_func[DF_IOCTL] = &devicefunc_cdimage;
+               device_func[DF_SCSI] = NULL;
+               return;
        }
 #ifdef WINDDK
        if (!device_func[DF_IOCTL])
@@ -53,18 +55,24 @@ static void install_driver (int flags)
 
 int sys_command_open (int mode, int unitnum)
 {
-       if (mode == DF_SCSI || !have_ioctl)
+       if (mode == DF_SCSI || !have_ioctl) {
+               if (device_func[DF_SCSI] == NULL)
+                       return 0;
                return device_func[DF_SCSI]->opendev (unitnum);
-       else
+       } else {
                return device_func[DF_IOCTL]->opendev (unitnum);
+       }
 }
 
 void sys_command_close (int mode, int unitnum)
 {
-       if (mode == DF_SCSI || !have_ioctl)
+       if (mode == DF_SCSI || !have_ioctl) {
+               if (device_func[DF_SCSI] == NULL)
+                       return;
                device_func[DF_SCSI]->closedev (unitnum);
-       else
+       } else {
                device_func[DF_IOCTL]->closedev (unitnum);
+       }
 }
 
 void device_func_reset (void)
@@ -82,9 +90,13 @@ int device_func_init (int flags)
                have_ioctl = 1;
        else
                have_ioctl = 0;
-       support_scsi = device_func[DF_SCSI]->openbus (oflags) ? 1 : 0;
+       if (flags & DEVICE_TYPE_ALLOWEMU)
+               oflags |= DEVICE_TYPE_ALLOWEMU;
+       if (device_func[DF_SCSI])
+               support_scsi = device_func[DF_SCSI]->openbus (oflags) ? 1 : 0;
+       oflags |= 1 << INQ_ROMD;
        if (have_ioctl)
-               support_ioctl = device_func[DF_IOCTL]->openbus (1 << INQ_ROMD) ? 1 : 0;
+               support_ioctl = device_func[DF_IOCTL]->openbus (oflags) ? 1 : 0;
        write_log (L"support_scsi = %d support_ioctl = %d\n", support_scsi, support_ioctl);
        return (support_scsi ? (1 << DF_SCSI) : 0) | (support_ioctl ? (1 << DF_IOCTL) : 0);
 }
index 59789dac35fd8bd4c84a9d46da5af95f938b18ef..e1c1930d1e90cbd8ec90ad6da9a0ace43af3b905 100644 (file)
@@ -60,6 +60,7 @@ static uae_u32 cd_last_pos;
 static int cdda_start, cdda_end;
 
 static int imagechange;
+static bool donotmountme;
 static TCHAR newfile[MAX_DPATH];
 
 /* convert minutes, seconds and frames -> logical sector number */
@@ -1014,7 +1015,8 @@ static int open_device (int unitnum)
 {
        if (unitnum)
                return 0;
-       return parse_image ();
+       parse_image ();
+       return 1;
 }
 
 static void close_device (int unitnum)
@@ -1050,12 +1052,19 @@ void cdimage_vsync (void)
        _tcscpy (changed_prefs.cdimagefile, newfile);
        newfile[0] = 0;
        write_log (L"CD: delayed insert '%s'\n", currprefs.cdimagefile[0] ? currprefs.cdimagefile : L"<EMPTY>");
+       donotmountme = true;
        int un = scsi_do_disk_change (-1, 1);
+       donotmountme = false;
        if (un >= 0) {
+               struct device_info di;
                media = sys_command_ismedia (DF_IOCTL, un, 1);
+               if (sys_command_info (DF_IOCTL, un, &di))
+                       scsi_do_disk_change (di.id, 1);
        } else {
+               device_func_init (DEVICE_TYPE_ANY); // active us again
                parse_image ();
                media = tracks > 0;
+               scsi_do_disk_change (255, 1);
        }
 #ifdef RETROPLATFORM
        rp_cd_image_change (0, media ? currprefs.cdimagefile : NULL);
@@ -1073,9 +1082,14 @@ static int ismedia (int unitnum, int quick)
 static int open_bus (int flags)
 {
        int v;
+
+       if (donotmountme && !(flags & DEVICE_TYPE_ALLOWEMU))
+               return 0;
        if (imagechange)
                return 1;
        v = currprefs.cdimagefile[0] ? 1 : 0;
+       if (currprefs.cdimagefileuse)
+               v = 1;
 #ifdef RETROPLATFORM
        rp_cd_change (0, 0);
        rp_cd_image_change (0, currprefs.cdimagefile[0] ? currprefs.cdimagefile : NULL);
@@ -1113,7 +1127,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di)
        }
        di->write_protected = 1;
        di->type = INQ_ROMD;
-       di->id = -1;
+       di->id = 255;
        _tcscpy (di->label, L"IMG_EMU");
        return di;
 }
index 6ea2a5d99860e7b2d735b1b57d69c79b92505425..b012b6e9e8f285821b65d17974fbc5108007b2ea 100644 (file)
@@ -188,7 +188,7 @@ static const TCHAR *obsolete[] = {
        L"kickstart_key_file", L"fast_copper", L"sound_adjust",
        L"serial_hardware_dtrdsr", L"gfx_filter_upscale",
        L"gfx_correct_aspect", L"gfx_autoscale", L"parallel_sampler", L"parallel_ascii_emulation",
-       L"avoid_vid", L"avoid_dga",
+       L"avoid_vid", L"avoid_dga", L"z3chipmem_size",
        NULL
 };
 
@@ -875,10 +875,11 @@ int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, i
                || strcasecmp (value, L"true") == 0 || strcasecmp (value, L"t") == 0)
                *location = 1;
        else if (strcasecmp (value, L"no") == 0 || strcasecmp (value, L"n") == 0
-               || strcasecmp (value, L"false") == 0 || strcasecmp (value, L"f") == 0)
+               || strcasecmp (value, L"false") == 0 || strcasecmp (value, L"f") == 0
+               || strcasecmp (value, L"0") == 0)
                *location = 0;
        else {
-               write_log (L"Option `%s' requires a value of either `yes' or `no'.\n", option);
+               write_log (L"Option `%s' requires a value of either `yes' or `no' (was '%s').\n", option, value);
                return -1;
        }
        return 1;
@@ -1111,8 +1112,10 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                }
        }
 
-       if (cfgfile_path (option, value, L"cdimage0", p->cdimagefile, sizeof p->cdimagefile / sizeof (TCHAR)))
+       if (cfgfile_path (option, value, L"cdimage0", p->cdimagefile, sizeof p->cdimagefile / sizeof (TCHAR))) {
+               p->cdimagefileuse = true;
                return 1;
+       }
 
        if (cfgfile_intval (option, value, L"sound_frequency", &p->sound_freq, 1)) {
                /* backwards compatibility */
index 45eeb80f391a14da68a0ca7ca2803462dc4f3cd5..152205d799e38383c2232c07a9560e7b2a597588 100644 (file)
@@ -342,16 +342,28 @@ void driveclick_mix (uae_s16 *sndbuffer, int size, int channelmask)
                        uae_s16 s = clickbuffer[i];
                        if (channelmask & 1)
                                sndbuffer[0] = limit (((sndbuffer[0] + s) * 2) / 3);
+                       else
+                               sndbuffer[0] = sndbuffer[0] * 2 / 3;
                        if (channelmask & 2)
                                sndbuffer[1] = limit (((sndbuffer[1] + s) * 2) / 3);
+                       else
+                               sndbuffer[1] = sndbuffer[1] * 2 / 3;
                        if (channelmask & 4)
                                sndbuffer[2] = limit (((sndbuffer[2] + s) * 2) / 3);
+                       else
+                               sndbuffer[2] = sndbuffer[2] * 2 / 3;
                        if (channelmask & 8)
                                sndbuffer[3] = limit (((sndbuffer[3] + s) * 2) / 3);
+                       else
+                               sndbuffer[3] = sndbuffer[3] * 2 / 3;
                        if (channelmask & 16)
                                sndbuffer[4] = limit (((sndbuffer[4] + s) * 2) / 3);
+                       else
+                               sndbuffer[4] = sndbuffer[4] * 2 / 3;
                        if (channelmask & 32)
                                sndbuffer[5] = limit (((sndbuffer[5] + s) * 2) / 3);
+                       else
+                               sndbuffer[5] = sndbuffer[5] * 2 / 3;
                        sndbuffer += 6;
                }
                break;
@@ -360,12 +372,20 @@ void driveclick_mix (uae_s16 *sndbuffer, int size, int channelmask)
                        uae_s16 s = clickbuffer[i];
                        if (channelmask & 1)
                                sndbuffer[0] = limit (((sndbuffer[0] + s) * 2) / 3);
+                       else
+                               sndbuffer[0] = sndbuffer[0] * 2 / 3;
                        if (channelmask & 2)
                                sndbuffer[1] = limit (((sndbuffer[1] + s) * 2) / 3);
+                       else
+                               sndbuffer[1] = sndbuffer[1] * 2 / 3;
                        if (channelmask & 4)
                                sndbuffer[2] = limit (((sndbuffer[2] + s) * 2) / 3);
+                       else
+                               sndbuffer[2] = sndbuffer[2] * 2 / 3;
                        if (channelmask & 8)
                                sndbuffer[3] = limit (((sndbuffer[3] + s) * 2) / 3);
+                       else
+                               sndbuffer[3] = sndbuffer[3] * 2 / 3;
                        sndbuffer += 4;
                }
                break;
@@ -374,8 +394,12 @@ void driveclick_mix (uae_s16 *sndbuffer, int size, int channelmask)
                        uae_s16 s = clickbuffer[i];
                        if (channelmask & 1)
                                sndbuffer[0] = limit (((sndbuffer[0] + s) * 2) / 3);
+                       else
+                               sndbuffer[0] = sndbuffer[0] * 2 / 3;
                        if (channelmask & 2)
                                sndbuffer[1] = limit (((sndbuffer[1] + s) * 2) / 3);
+                       else
+                               sndbuffer[1] = sndbuffer[1] * 2 / 3;
                        sndbuffer += 2;
                }
                break;
index 79cda4f32dd9c7c5994949d3f0074cf41412521e..7b618347b82700ad948a97d0ab76c2f6d3e11ce5 100644 (file)
@@ -25,6 +25,7 @@
 
 #define DEVICE_TYPE_ANY 1
 #define DEVICE_TYPE_SCSI 2
+#define DEVICE_TYPE_ALLOWEMU 0x100
 
 #define DF_SCSI 0
 #define DF_IOCTL 1
index 43ced3bddee1cd1d5a1b1ece530caa77fccbbcc3..a502e70110aa9584adea8ced63f1498c29a0f0a2 100644 (file)
@@ -280,6 +280,7 @@ struct uae_prefs {
        TCHAR amaxromfile[MAX_DPATH];
        TCHAR a2065name[MAX_DPATH];
        TCHAR cdimagefile[MAX_DPATH];
+       bool cdimagefileuse;
        TCHAR quitstatefile[MAX_DPATH];
 
        TCHAR path_floppy[256];
index f1bf993c970a7d4a8449d9093a51a338a4864284..6ed1cdba99e6009fa6b6c2159cf1708ba223f545 100644 (file)
@@ -742,7 +742,7 @@ static uae_u8 *ioctl_command_qcode (int unitnum)
                p[3] = 12;
                while (cnt-- > 0) {
                        reseterrormode (unitnum);
-                       if(!DeviceIoControl (ciw->h, IOCTL_CDROM_READ_Q_CHANNEL, &in, sizeof(in), &qcd, sizeof (qcd), &len, NULL)) {
+                       if(!DeviceIoControl (ciw->h, IOCTL_CDROM_READ_Q_CHANNEL, &in, sizeof in, &qcd, sizeof qcd, &len, NULL)) {
                                reseterrormode (unitnum);
                                if (win32_error (unitnum, L"IOCTL_CDROM_READ_Q_CHANNEL") < 0)
                                        continue;
@@ -1020,7 +1020,7 @@ static uae_u8 *ioctl_command_toc (int unitnum)
        gui_flicker_led (LED_CD, unitnum, 1);
        while (cnt-- > 0) {
                seterrormode (unitnum);
-               if (!DeviceIoControl (ciw32[unitnum].h, IOCTL_CDROM_READ_TOC, NULL, 0, toc, sizeof(CDROM_TOC), &len, NULL)) {
+               if (!DeviceIoControl (ciw32[unitnum].h, IOCTL_CDROM_READ_TOC, NULL, 0, toc, sizeof (CDROM_TOC), &len, NULL)) {
                        reseterrormode (unitnum);
                        if (win32_error (unitnum, L"IOCTL_CDROM_READ_TOC") < 0)
                                continue;
@@ -1227,7 +1227,7 @@ void win32_ioctl_media_change (TCHAR driveletter, int insert)
                        ciw32[i].mediainserted = insert;
                        scsi_do_disk_change (driveletter, insert);
 #ifdef RETROPLATFORM
-                       rp_cd_image_change (i, insert ? ciw32[i].drvlettername : NULL);
+                       rp_cd_image_change (i, ciw32[i].drvlettername);
 #endif
                }
        }
index e0e2da61570bd8a3e5c4bf29d0e4c652aaa314c8..3eff98ac83cd3ac08c8a806c6264641065424d8c 100644 (file)
@@ -543,7 +543,7 @@ void win32_spti_media_change (TCHAR driveletter, int insert)
                                dev_info[i].mediainserted = now;
                                scsi_do_disk_change (getid (i), insert);
 #ifdef RETROPLATFORM
-                               rp_cd_image_change (i, now ? (dev_info[i].drvletter ? dev_info[i].drvlettername : dev_info[i].name) : NULL);
+                               rp_cd_image_change (i, dev_info[i].drvletter ? dev_info[i].drvlettername : dev_info[i].name);
 #endif
                        }
                }
index 38ec6d1ef8f08db4d09342a85c38b5c20fa91387..6d1cb8d3fc52475c2bf783f1fcb9f7851dac5d04 100644 (file)
@@ -1180,10 +1180,18 @@ static int acquire (LPDIRECTINPUTDEVICE8 lpdi, TCHAR *txt)
 static int setcoop (struct didata *did, DWORD mode, TCHAR *txt)
 {
        HRESULT hr = DI_OK;
+       HWND hwnd;
+       int test = inputdevice_istest ();
+       
+       if (!test)
+               hwnd = hMainWnd;
+       else
+               hwnd = hGUIWnd;
+
        if (did->lpdi) {
                did->coop = 0;
-               if (!did->coop && hMainWnd) {
-                       hr = IDirectInputDevice8_SetCooperativeLevel (did->lpdi, hMainWnd, mode);
+               if (!did->coop && hwnd) {
+                       hr = IDirectInputDevice8_SetCooperativeLevel (did->lpdi, hwnd, mode);
                        if (FAILED (hr) && hr != E_NOTIMPL) {
                                write_log (L"setcooperativelevel %s failed, %s\n", txt, DXError (hr));
                        } else {
@@ -1342,7 +1350,7 @@ static BOOL CALLBACK EnumObjectsCallback (const DIDEVICEOBJECTINSTANCE* pdidoi,
                        did->axissort[did->axles] = makesort_mouse (&pdidoi->guidType, &did->axismappings[did->axles]);
                for (i = 0; i < 2; i++) {
                        did->axismappings[did->axles + i] = DIJOFS_POV(numpov);
-                       _stprintf (tmp, L"%s (%d)", pdidoi->tszName, i + 1);
+                       _stprintf (tmp, L"%s (%c)", pdidoi->tszName, i ? 'Y' : 'X');
                        did->axisname[did->axles + i] = my_strdup (tmp);
                        did->axissort[did->axles + i] = did->axissort[did->axles];
                        did->axistype[did->axles + i] = i + 1;
index 09d426647a5a88621ba458e5a2a1c1696f421c08..71e90851c4865df67059547254c486d9bf84b2a5 100644 (file)
@@ -8,8 +8,7 @@
 #if defined (D3D) && defined (GFXFILTER)
 
 #define EFFECT_VERSION 2
-#define D3DX9DLL1 L"d3dx9_42.dll"
-#define D3DX9DLL2 L"d3dx9_43.dll"
+#define D3DX9DLL L"d3dx9_43.dll"
 
 #include "options.h"
 #include "xwin.h"
@@ -446,7 +445,7 @@ int D3D_canshaders (void)
        if (d3d_yesno > 0)
                return 1;
        d3d_yesno = -1;
-       h = LoadLibrary (D3DX9DLL1);
+       h = LoadLibrary (D3DX9DLL);
        if (h != NULL) {
                FreeLibrary (h);
                d3dx = Direct3DCreate9 (D3D_SDK_VERSION);
@@ -1571,7 +1570,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
                return errmsg;
        }
 
-       d3dx = LoadLibrary (os_vista ? D3DX9DLL2 : D3DX9DLL1);
+       d3dx = LoadLibrary (D3DX9DLL);
        if (d3dx == NULL) {
                _tcscpy (errmsg, L"Direct3D: Newer DirectX Runtime required.\n\nhttp://go.microsoft.com/fwlink/?linkid=56513");
                if (isfullscreen () <= 0)
index ace8772f64c213584c8e57c27a7a1ff9e922ca9d..b4a7633ed508752c5a411fdcd2b36d9b852d3e38 100644 (file)
@@ -129,9 +129,11 @@ static int port_insert2 (int num, const TCHAR *name)
        TCHAR tmp2[MAX_DPATH];
        int i, type;
 
+       if (log_rp)
+               write_log (L"port_insert(%d,%s)\n", num, name);
        type = 1;
        _tcscpy (tmp2, name);
-       for (i = 1; i <= MAX_JPORTS; i++) {
+       for (i = 1; i < 10; i++) {
                TCHAR tmp1[1000];
                _stprintf (tmp1, L"Mouse%d", i);
                if (!_tcscmp (name, tmp1)) {
@@ -158,6 +160,8 @@ static int port_insert2 (int num, const TCHAR *name)
                }
        }
        trimws (tmp2);
+       if (log_rp)
+               write_log (L"-> %s,%d,%d\n", tmp2, num, type);
        return inputdevice_joyport_config (&changed_prefs, tmp2, num, 0, type);
 }
 
@@ -541,9 +545,14 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
 static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM lParam,
        LPCVOID pData, DWORD dwDataSize, LPARAM lMsgFunctionParam)
 {
-       if (log_rp)
+       if (log_rp) {
                write_log (L"RPFUNC(%s [%d], %08x, %08x, %08x, %d, %08x)\n",
                getmsg (uMessage), uMessage - WM_APP, wParam, lParam, pData, dwDataSize, lMsgFunctionParam);
+               if (uMessage == RPIPCHM_DEVICECONTENT) {
+                       struct RPDeviceContent *dc = (struct RPDeviceContent*)pData;
+                       write_log (L" Cat=%d Num=%d '%s'\n", dc->btDeviceCategory, dc->btDeviceNumber, dc->szContent);
+               }
+       }
 
        switch (uMessage)
        {
@@ -878,6 +887,7 @@ void rp_input_change (int num)
        TCHAR name[MAX_DPATH];
        TCHAR *name2 = NULL, *name3 = NULL;
 
+       name[0] = 0;
        if (JSEM_ISXARCADE1 (num, &currprefs)) {
                j = 2;
                m = k = -1;
index 397ec326e6466dc68e7225e95ed64d1bdb9a38c1..3f0559d88a8edc3fdf1317c37beeba8b81c05040 100644 (file)
@@ -19,7 +19,7 @@
 #define LANG_DLL 1
 
 #define WINUAEBETA L"10"
-#define WINUAEDATE MAKEBD(2010, 6, 15)
+#define WINUAEDATE MAKEBD(2010, 6, 19)
 #define WINUAEEXTRA L"RC1"
 #define WINUAEREV L""
 
index 39d9494ac1e3766a0bf760cb24c6cec1cc37599a..dc74e13a82022bb001da006a7e7e9fe360b37967 100644 (file)
@@ -8355,6 +8355,10 @@ static void volumeselectfile (HWND hDlg)
 {
        TCHAR directory_path[MAX_DPATH];
        _tcscpy (directory_path, current_fsvdlg.rootdir);
+       if (directory_path[0] == 0) {
+               int out = sizeof directory_path / sizeof (TCHAR);
+               regquerystr (NULL, L"FilesystemFilePath", directory_path, &out);
+       }
        if (DiskSelection (hDlg, 0, 14, &workprefs, directory_path)) {
                TCHAR *s = filesys_createvolname (NULL, directory_path, L"Harddrive");
                SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path);
@@ -8363,6 +8367,13 @@ static void volumeselectfile (HWND hDlg)
                CheckDlgButton (hDlg, IDC_FS_RW, FALSE);
                ew (hDlg, IDC_FS_RW, FALSE);
                archivehd = 1;
+               TCHAR *p = _tcsrchr (directory_path, '\\');
+               if (p) {
+                       TCHAR t = p[1];
+                       p[1] = 0;
+                       regsetstr (NULL, L"FilesystemFilePath", directory_path);
+                       p[1] = t;
+               }
        }
 }
 static void volumeselectdir (HWND hDlg, int newdir)
@@ -8373,9 +8384,15 @@ static void volumeselectdir (HWND hDlg, int newdir)
 
        _tcscpy (directory_path, current_fsvdlg.rootdir);
        if (!newdir) {
+               if (directory_path[0] == 0) {
+                       int out = sizeof directory_path / sizeof (TCHAR);
+                       regquerystr (NULL, L"FilesystemDirectoryPath", directory_path, &out);
+               }
                WIN32GUI_LoadUIString (IDS_SELECTFILESYSROOT, szTitle, MAX_DPATH);
-               if (DirectorySelection (hDlg, &volumeguid, directory_path))
+               if (DirectorySelection (hDlg, &volumeguid, directory_path)) {
                        newdir = 1;
+                       regsetstr (NULL, L"FilesystemDirectoryPath", directory_path);
+               }
        }
        if (newdir) {
                SetDlgItemText (hDlg, IDC_PATH_NAME, directory_path);
@@ -11381,8 +11398,8 @@ static void input_find (HWND hDlg, int mode, int set)
        static TCHAR tmp[200];
        if (set && !rawmode) {
                rawmode = mode ? 2 : 1;
-               inputdevice_acquire (-1);
                inputdevice_settest (TRUE);
+               inputdevice_acquire (-1);
                if (rawmode == 2) {
                        TCHAR tmp2[MAX_DPATH];
                        GetWindowText (guiDlg, tmp, sizeof tmp / sizeof (TCHAR));
@@ -13825,6 +13842,8 @@ static int GetSettings (int all_options, HWND hwnd)
                ShowWindow (dhwnd, SW_SHOW);
                MapDialogRect (dhwnd, &dialog_rect);
 
+               hGUIWnd = dhwnd;
+
                for (;;) {
                        HANDLE IPChandle;
                        IPChandle = geteventhandleIPC (globalipc);
index 1de355c9003f24f69f62cc802471759d90c15134..425cb9a4ef33aab37dd80a21a96a23bf3f873513 100644 (file)
@@ -271,7 +271,7 @@ static int is_async_request (struct devstruct *dev, uaecptr request)
 }
 
 
-int scsiemul_switchscsi (TCHAR *name)
+static int scsiemul_switchscsi (const TCHAR *name)
 {
        struct devstruct *dev = NULL;
        struct device_info *discsi, discsi2;
@@ -288,14 +288,17 @@ int scsiemul_switchscsi (TCHAR *name)
        dev = NULL;
        for (j = 0; j < 2; j++) {
                int mode = j == 0 ? DF_SCSI : DF_IOCTL;
-               device_func_init (j == 0 ? DEVICE_TYPE_SCSI : DEVICE_TYPE_ANY);
+               if (!(device_func_init (j == 0 ? DEVICE_TYPE_SCSI : DEVICE_TYPE_ANY) & (1 << mode)))
+                       continue;
+               if (devst[0].di.media_inserted < 0)
+                       devst[0].di.media_inserted = 0;
                i = 0;
                while (i < MAX_TOTAL_DEVICES && dev == NULL) {
                        discsi = 0;
                        if (sys_command_open (mode, i)) {
                                discsi = sys_command_info (mode, i, &discsi2);
                                if (discsi && discsi->type == INQ_ROMD) {
-                                       if (!_tcsicmp (currprefs.cdimagefile, discsi->label) || j) {
+                                       if (!_tcsicmp (currprefs.cdimagefile, discsi->label)) {
                                                dev = &devst[0];
                                                dev->unitnum = i;
                                                dev->allow_scsi = j == 0 ? 1 : 0;
@@ -316,11 +319,40 @@ int scsiemul_switchscsi (TCHAR *name)
                        i++;
                }
                if (dev)
-                       return i;
+                       return dev->unitnum;
+       }
+       return -1;
+}
+static int scsiemul_switchemu (const TCHAR *name)
+{
+       struct devstruct *dev = NULL;
+       struct device_info *discsi, discsi2;
+
+       if (!device_func_init (DEVICE_TYPE_ANY | DEVICE_TYPE_ALLOWEMU))
+               return -1;
+       if (sys_command_open (DF_IOCTL, 0)) {
+               if (discsi = sys_command_info (DF_IOCTL, 0, &discsi2)) {
+                       dev = &devst[0];
+                       dev->unitnum = 0;
+                       dev->allow_scsi = 0;
+                       dev->allow_ioctl = 1;
+                       dev->drivetype = discsi->type;
+                       memcpy (&dev->di, discsi, sizeof (struct device_info));
+                       dev->iscd = 1;
+                       write_log (L"IMG_EMU (%s) mounted as uaescsi.device:0\n", name);
+                       if (dev->aunit >= 0) {
+                               struct priv_devstruct *pdev = &pdevst[dev->aunit];
+                               setpdev (pdev, dev);
+                       }
+               }
+               if (devst[0].opencnt == 0)
+                       sys_command_close (DF_IOCTL, 0);
+               return 0;
        }
        return -1;
 }
 
+// device_id = -1 and insert==0 -> all medias going away
 int scsi_do_disk_change (int device_id, int insert)
 {
        int i, j, ret;
@@ -331,27 +363,33 @@ int scsi_do_disk_change (int device_id, int insert)
        uae_sem_wait (&change_sem);
        if (device_id < 0 && insert) {
                ret = scsiemul_switchscsi (currprefs.cdimagefile);
-               if (ret < 0)
+               if (ret < 0) {
+                       scsiemul_switchemu (currprefs.cdimagefile);
                        goto end;
+               }
        }
        for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
                struct devstruct *dev = &devst[i];
                if (dev->di.id == device_id || (device_id < 0 && i == 0)) {
                        ret = i;
-                       if (dev->aunit >= 0) {
-                               struct priv_devstruct *pdev = &pdevst[dev->aunit];
-                               devinfo (pdev->mode, dev->unitnum, &dev->di);
-                       }
-                       dev->changenum++;
-                       j = 0;
-                       while (j < MAX_ASYNC_REQUESTS) {
-                               if (dev->d_request_type[j] == ASYNC_REQUEST_CHANGEINT) {
-                                       uae_Cause (dev->d_request_data[j]);
+                       if ((dev->di.media_inserted > 0 && insert == 0) || (dev->di.media_inserted <= 0 && insert)) {
+                               if (dev->aunit >= 0) {
+                                       struct priv_devstruct *pdev = &pdevst[dev->aunit];
+                                       devinfo (pdev->mode, dev->unitnum, &dev->di);
                                }
-                               j++;
+                               if (device_id < 0 && insert == 0)
+                                       dev->di.media_inserted = -1; // stay away!
+                               dev->changenum++;
+                               j = 0;
+                               while (j < MAX_ASYNC_REQUESTS) {
+                                       if (dev->d_request_type[j] == ASYNC_REQUEST_CHANGEINT) {
+                                               uae_Cause (dev->d_request_data[j]);
+                                       }
+                                       j++;
+                               }
+                               if (dev->changeint)
+                                       uae_Cause (dev->changeint);
                        }
-                       if (dev->changeint)
-                               uae_Cause (dev->changeint);
                }
        }
 end:
@@ -527,7 +565,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
        {
        case CMD_READ:
                //write_log (L"CMD_READ %08x %d %d %08x\n", io_data, io_offset, io_length, bmask);
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                if (dev->drivetype == INQ_ROMD) {
                        io_error = command_cd_read (pdev->mode, dev, io_data, io_offset, io_length, &io_actual);
@@ -541,7 +579,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                break;
        case TD_READ64:
        case NSCMD_TD_READ64:
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                io_offset64 = get_long (request + 44) | ((uae_u64)get_long (request + 32) << 32);
                if ((io_offset64 & bmask) || bmask == 0 || io_data == 0)
@@ -555,7 +593,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                break;
 
        case CMD_WRITE:
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                if (dev->di.write_protected || dev->drivetype == INQ_ROMD) {
                        io_error = 28; /* writeprotect */
@@ -569,7 +607,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                break;
        case TD_WRITE64:
        case NSCMD_TD_WRITE64:
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                io_offset64 = get_long (request + 44) | ((uae_u64)get_long (request + 32) << 32);
                if (dev->di.write_protected || dev->drivetype == INQ_ROMD) {
@@ -584,7 +622,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                break;
 
        case CMD_FORMAT:
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                if (dev->di.write_protected || dev->drivetype == INQ_ROMD) {
                        io_error = 28; /* writeprotect */
@@ -598,7 +636,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                break;
        case TD_FORMAT64:
        case NSCMD_TD_FORMAT64:
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                io_offset64 = get_long (request + 44) | ((uae_u64)get_long (request + 32) << 32);
                if (dev->di.write_protected || dev->drivetype == INQ_ROMD) {
@@ -627,7 +665,11 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                io_actual = dev->changenum;
                break;
        case CMD_CHANGESTATE:
-               io_actual = devinfo (pdev->mode, dev->unitnum, &dev->di)->media_inserted ? 0 : 1;
+               if (dev->di.media_inserted >= 0) {
+                       io_actual = devinfo (pdev->mode, dev->unitnum, &dev->di)->media_inserted > 0 ? 0 : 1;
+               } else {
+                       io_actual = 1;
+               }
                break;
        case CMD_PROTSTATUS:
                io_actual = devinfo (pdev->mode, dev->unitnum, &dev->di)->write_protected ? -1 : 0;
@@ -636,7 +678,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                io_actual = dev->drivetype;
                break;
        case CMD_GETNUMTRACKS:
-               if (!dev->di.media_inserted)
+               if (dev->di.media_inserted <= 0)
                        goto no_media;
                io_actual = dev->di.cylinders;
                break;
@@ -644,7 +686,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request)
                {
                        struct device_info *di;
                        di = devinfo (pdev->mode, dev->unitnum, &dev->di);
-                       if (!di->media_inserted)
+                       if (di->media_inserted <= 0)
                                goto no_media;
                        put_long (io_data + 0, di->bytespersector);
                        put_long (io_data + 4, di->sectorspertrack * di->trackspercylinder * di->cylinders);
@@ -852,21 +894,32 @@ static void dev_reset (void)
        for (i = 0; i < MAX_OPEN_DEVICES; i++)
                memset (&pdevst[i], 0, sizeof (struct priv_devstruct));
 
-       if (currprefs.cdimagefile[0]) {
-               scsiemul_switchscsi (currprefs.cdimagefile);
-       } else {
+       int didswitch = -1;
+       if (currprefs.cdimagefile[0] || currprefs.cdimagefileuse)
+               didswitch = scsiemul_switchscsi (currprefs.cdimagefile);
+       if (didswitch < 0) {
                device_func_init (DEVICE_TYPE_SCSI);
                i = j = 0;
                while (i < MAX_TOTAL_DEVICES) {
+                       int mode = -1;
                        dev = &devst[i];
                        discsi = 0;
                        if (sys_command_open (DF_SCSI, j)) {
-                               discsi = sys_command_info (DF_SCSI, j, &discsi2);
-                               sys_command_close (DF_SCSI, j);
+                               dev->allow_scsi = 1;
+                               mode = DF_SCSI;
+                       }
+                       if (!dev->allow_scsi) {
+                               if (sys_command_open (DF_IOCTL, j)) {
+                                       dev->allow_ioctl = 1;
+                                       mode = DF_IOCTL;
+                               }
+                       }
+                       if (mode >= 0) {
+                               discsi = sys_command_info (mode, j, &discsi2);
+                               sys_command_close (mode, j);
                        }
                        if (discsi) {
                                dev->unitnum = j;
-                               dev->allow_scsi = 1;
                                dev->drivetype = discsi->type;
                                memcpy (&dev->di, discsi, sizeof (struct device_info));
                                if (discsi->type == INQ_ROMD)