]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2600b10
authorToni Wilen <twilen@winuae.net>
Sat, 9 Mar 2013 13:03:26 +0000 (15:03 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 9 Mar 2013 13:03:26 +0000 (15:03 +0200)
35 files changed:
audio.cpp
blkdev.cpp
blkdev_cdimage.cpp
cia.cpp
custom.cpp
disk.cpp
filesys.cpp
hardfile.cpp
include/custom.h
include/drawing.h
include/fsdb.h
include/inputdevice.h
include/options.h
include/xwin.h
inputdevice.cpp
main.cpp
od-win32/avioutput.cpp
od-win32/blkdev_win32_ioctl.cpp
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/fsdb_mywin32.cpp
od-win32/fsdb_win32.cpp
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/srcrelease.cmd
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt
savestate.cpp
scsi.cpp
uaeipc.cpp

index 619ddb72edd1be005f47aff3bba48dec1fb4a25a..2ee141e367fd991dde6b644121846466c0e3ecca 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -1787,7 +1787,7 @@ void audio_hsync (void)
 {
        if (!isaudio ())
                return;
-       if (audio_work_to_do > 0 && currprefs.sound_auto) {
+       if (audio_work_to_do > 0 && currprefs.sound_auto && !avioutput_enabled) {
                audio_work_to_do--;
                if (audio_work_to_do == 0)
                        audio_deactivate ();
index a1e491942d454c1778333fa097b41683ceaf210b..2a12ad9b2e60c319933928e93cfc90b7f890e958 100644 (file)
@@ -28,6 +28,27 @@ int log_scsiemu = 0;
 
 #define PRE_INSERT_DELAY (3 * (currprefs.ntscmode ? 60 : 50))
 
+struct blkdevstate
+{
+       int scsiemu;
+       struct device_functions *device_func;
+       int isopen;
+       int waspaused;
+       int delayed;
+       uae_sem_t sema;
+       int sema_cnt;
+       int play_end_pos;
+       uae_u8 play_qcode[SUBQ_SIZE];
+       TCHAR newimagefile[256];
+       int imagechangetime;
+       bool cdimagefileinuse;
+       int wasopen;
+       bool mediawaschanged;
+};
+
+struct blkdevstate state[MAX_TOTAL_SCSI_DEVICES];
+
+#if 0
 static int scsiemu[MAX_TOTAL_SCSI_DEVICES];
 
 static struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES];
@@ -44,6 +65,8 @@ static TCHAR newimagefiles[MAX_TOTAL_SCSI_DEVICES][256];
 static int imagechangetime[MAX_TOTAL_SCSI_DEVICES];
 static bool cdimagefileinuse[MAX_TOTAL_SCSI_DEVICES];
 static int wasopen[MAX_TOTAL_SCSI_DEVICES];
+#endif
+
 static bool dev_init;
 
 /* convert minutes, seconds and frames -> logical sector number */
@@ -133,32 +156,34 @@ static int driver_installed[6];
 static void install_driver (int flags)
 {
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               scsiemu[i] = false;
-               device_func[i] = NULL;
+               struct blkdevstate *st = &state[i];
+               st->scsiemu = false;
+               st->device_func = NULL;
        }
        if (flags > 0) {
-               device_func[0] = devicetable[flags];
-               scsiemu[0] = true;
+               state[0].device_func = devicetable[flags];
+               state[0].scsiemu = true;
        } else {
                for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-                       scsiemu[i] = false;
-                       device_func[i] = NULL;
+                       struct blkdevstate *st = &state[i];
+                       st->scsiemu = false;
+                       st->device_func = NULL;
                        switch (cdscsidevicetype[i])
                        {
                                case SCSI_UNIT_IMAGE:
-                               device_func[i] = devicetable[SCSI_UNIT_IMAGE];
-                               scsiemu[i] = true;
+                               st->device_func = devicetable[SCSI_UNIT_IMAGE];
+                               st->scsiemu = true;
                                break;
                                case SCSI_UNIT_IOCTL:
-                               device_func[i] = devicetable[SCSI_UNIT_IOCTL];
-                               scsiemu[i] = true;
+                               st->device_func = devicetable[SCSI_UNIT_IOCTL];
+                               st->scsiemu = true;
                                break;
                                case SCSI_UNIT_SPTI:
                                if (currprefs.win32_uaescsimode == UAESCSI_CDEMU) {
-                                       device_func[i] = devicetable[SCSI_UNIT_IOCTL];
-                                       scsiemu[i] = true;
+                                       st->device_func = devicetable[SCSI_UNIT_IOCTL];
+                                       st->scsiemu = true;
                                } else {
-                                       device_func[i] = devicetable[SCSI_UNIT_SPTI];
+                                       st->device_func = devicetable[SCSI_UNIT_SPTI];
                                }
                                break;
                        }
@@ -168,10 +193,11 @@ static void install_driver (int flags)
        for (int j = 1; devicetable[j]; j++) {
                if (!driver_installed[j]) {
                        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-                               if (device_func[i] == devicetable[j]) {
-                                       int ok = device_func[i]->openbus (0);
+                               struct blkdevstate *st = &state[i];
+                               if (st->device_func == devicetable[j]) {
+                                       int ok = st->device_func->openbus (0);
                                        driver_installed[j] = 1;
-                                       write_log (_T("%s driver installed, ok=%d\n"), device_func[i]->name, ok);
+                                       write_log (_T("%s driver installed, ok=%d\n"), st->device_func->name, ok);
                                        break;
                                }
                        }
@@ -225,19 +251,20 @@ void blkdev_fix_prefs (struct uae_prefs *p)
 
 static bool getsem (int unitnum, bool dowait)
 {
-       if (unitsem[unitnum] == NULL)
-               uae_sem_init (&unitsem[unitnum], 0, 1);
+       struct blkdevstate *st = &state[unitnum];
+       if (st->sema == NULL)
+               uae_sem_init (&st->sema, 0, 1);
        bool gotit = false;
        if (dowait) {
-               uae_sem_wait (&unitsem[unitnum]);
+               uae_sem_wait (&st->sema);
                gotit = true;
        } else {
-               gotit = uae_sem_trywait (&unitsem[unitnum]) == 0;
+               gotit = uae_sem_trywait (&st->sema) == 0;
        }
        if (gotit)
-               unitsem_cnt[unitnum]++;
-       if (unitsem_cnt[unitnum] > 1)
-               write_log (_T("CD: unitsem%d acquire mismatch! cnt=%d\n"), unitnum, unitsem_cnt[unitnum]);
+               st->sema_cnt++;
+       if (st->sema_cnt > 1)
+               write_log (_T("CD: unitsem%d acquire mismatch! cnt=%d\n"), unitnum, st->sema_cnt);
        return gotit;
 }
 static bool getsem (int unitnum)
@@ -246,41 +273,44 @@ static bool getsem (int unitnum)
 }
 static void freesem (int unitnum)
 {
-       unitsem_cnt[unitnum]--;
-       if (unitsem_cnt[unitnum] < 0)
-               write_log (_T("CD: unitsem%d release mismatch! cnt=%d\n"), unitnum, unitsem_cnt[unitnum]);
-       uae_sem_post (&unitsem[unitnum]);
+       struct blkdevstate *st = &state[unitnum];
+       st->sema_cnt--;
+       if (st->sema_cnt < 0)
+               write_log (_T("CD: unitsem%d release mismatch! cnt=%d\n"), unitnum, st->sema_cnt);
+       uae_sem_post (&st->sema);
 }
 static void sys_command_close_internal (int unitnum)
 {
+       struct blkdevstate *st = &state[unitnum];
        getsem (unitnum, true);
-       waspaused[unitnum] = 0;
-       if (openlist[unitnum] <= 0)
-               write_log (_T("BUG unit %d close: opencnt=%d!\n"), unitnum, openlist[unitnum]);
-       if (device_func[unitnum]) {
-               device_func[unitnum]->closedev (unitnum);
-               if (openlist[unitnum] > 0)
-                       openlist[unitnum]--;
+       st->waspaused = 0;
+       if (st->isopen <= 0)
+               write_log (_T("BUG unit %d close: opencnt=%d!\n"), unitnum, st->isopen);
+       if (st->device_func) {
+               state[unitnum].device_func->closedev (unitnum);
+               if (st->isopen > 0)
+                       st->isopen--;
        }
        freesem (unitnum);
-       if (openlist[unitnum] == 0) {
-               uae_sem_destroy (&unitsem[unitnum]);
-               unitsem[unitnum] = NULL;
+       if (st->isopen == 0) {
+               uae_sem_destroy (&st->sema);
+               st->sema = NULL;
        }
 }
 
 static int sys_command_open_internal (int unitnum, const TCHAR *ident, cd_standard_unit csu)
 {
+       struct blkdevstate *st = &state[unitnum];
        int ret = 0;
-       if (unitsem[unitnum] == NULL)
-               uae_sem_init (&unitsem[unitnum], 0, 1);
+       if (st->sema == NULL)
+               uae_sem_init (&st->sema, 0, 1);
        getsem (unitnum, true);
-       if (openlist[unitnum])
-               write_log (_T("BUG unit %d open: opencnt=%d!\n"), unitnum, openlist[unitnum]);
-       if (device_func[unitnum]) {
-               ret = device_func[unitnum]->opendev (unitnum, ident, csu != CD_STANDARD_UNIT_DEFAULT);
+       if (st->isopen)
+               write_log (_T("BUG unit %d open: opencnt=%d!\n"), unitnum, st->isopen);
+       if (st->device_func) {
+               ret = state[unitnum].device_func->opendev (unitnum, ident, csu != CD_STANDARD_UNIT_DEFAULT);
                if (ret)
-                       openlist[unitnum]++;
+                       st->isopen++;
        }
        freesem (unitnum);
        return ret;
@@ -376,12 +406,13 @@ int get_standard_cd_unit (cd_standard_unit csu)
        int unitnum = get_standard_cd_unit2 (&currprefs, csu);
        if (unitnum < 0)
                return -1;
+       struct blkdevstate *st = &state[unitnum];
 #ifdef RETROPLATFORM
        rp_cd_device_enable (unitnum, true);
 #endif
-       delayed[unitnum] = 0;
+       st->delayed = 0;
        if (currprefs.cdslots[unitnum].delayed) {
-               delayed[unitnum] = PRE_INSERT_DELAY;
+               st->delayed = PRE_INSERT_DELAY;
        }
        return unitnum;
 }
@@ -393,22 +424,24 @@ void close_standard_cd_unit (int unitnum)
 
 int sys_command_isopen (int unitnum)
 {
-       return openlist[unitnum];
+       struct blkdevstate *st = &state[unitnum];
+       return st->isopen;
 }
 
 int sys_command_open (int unitnum)
 {
+       struct blkdevstate *st = &state[unitnum];
        blkdev_fix_prefs (&currprefs);
        if (!dev_init) {
                device_func_init (0);
                dev_init = true;
        }
 
-       if (openlist[unitnum]) {
-               openlist[unitnum]++;
+       if (st->isopen) {
+               st->isopen++;
                return -1;
        }
-       waspaused[unitnum] = 0;
+       st->waspaused = 0;
        int v = sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL, CD_STANDARD_UNIT_DEFAULT);
        if (!v)
                return 0;
@@ -420,8 +453,9 @@ int sys_command_open (int unitnum)
 
 void sys_command_close (int unitnum)
 {
-       if (openlist[unitnum] > 1) {
-               openlist[unitnum]--;
+       struct blkdevstate *st = &state[unitnum];
+       if (st->isopen > 1) {
+               st->isopen--;
                return;
        }
 #ifdef RETROPLATFORM
@@ -442,11 +476,12 @@ void blkdev_cd_change (int unitnum, const TCHAR *name)
 void device_func_reset (void)
 {
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               wasopen[i] = 0;
-               waspaused[i] = false;
-               imagechangetime[i] = 0;
-               cdimagefileinuse[i] = false;
-               newimagefiles[i][0] = 0;
+               struct blkdevstate *st = &state[i];
+               st->wasopen = 0;
+               st->waspaused = false;
+               st->imagechangetime = 0;
+               st->cdimagefileinuse = false;
+               st->newimagefile[0] = 0;
        }
 }
 
@@ -459,8 +494,9 @@ int device_func_init (int flags)
 
 bool blkdev_get_info (struct uae_prefs *p, int unitnum, struct device_info *di)
 {
-       bool open = true, opened = true, ok = false;
-       if (!openlist[unitnum]) {
+       bool open = true, opened = false, ok = false;
+       struct blkdevstate *st = &state[unitnum];
+       if (!st->isopen) {
                blkdev_fix_prefs (p);
                install_driver (0);
                opened = true;
@@ -477,24 +513,26 @@ bool blkdev_get_info (struct uae_prefs *p, int unitnum, struct device_info *di)
 void blkdev_entergui (void)
 {
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               waspaused[i] = 0;
+               struct blkdevstate *st = &state[i];
+               st->waspaused = 0;
                struct device_info di;
                if (sys_command_info (i, &di, 1)) {
                        if (sys_command_cd_pause (i, 1) == 0)
-                               waspaused[i] = 1;
+                               st->waspaused = 1;
                }
        }
 }
 void blkdev_exitgui (void)
 {
        for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
-               if (waspaused[i]) {
+               struct blkdevstate *st = &state[i];
+               if (st->waspaused) {
                        struct device_info di;
                        if (sys_command_info (i, &di, 1)) {
                                sys_command_cd_pause (i, 0);
                        }
                }
-               waspaused[i] = 0;
+               st->waspaused = 0;
        }
 }
 
@@ -507,15 +545,16 @@ void check_prefs_changed_cd (void)
 
 static void check_changes (int unitnum)
 {
+       struct blkdevstate *st = &state[unitnum];
        bool changed = false;
        bool gotsem = false;
 
-       if (device_func[unitnum] == NULL)
+       if (st->device_func == NULL)
                return;
 
-       if (delayed[unitnum]) {
-               delayed[unitnum]--;
-               if (delayed[unitnum] == 0)
+       if (st->delayed) {
+               st->delayed--;
+               if (st->delayed == 0)
                        write_log (_T("CD: startup delayed insert '%s'\n"), currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : _T("<EMPTY>"));
                return;
        }
@@ -527,32 +566,32 @@ static void check_changes (int unitnum)
 
        if (changed) {
                bool wasimage = currprefs.cdslots[unitnum].name[0] != 0;
-               if (unitsem[unitnum])
+               if (st->sema)
                        gotsem = getsem (unitnum, true);
-               cdimagefileinuse[unitnum] = changed_prefs.cdslots[unitnum].inuse;
-               _tcscpy (newimagefiles[unitnum], changed_prefs.cdslots[unitnum].name);
+               st->cdimagefileinuse = changed_prefs.cdslots[unitnum].inuse;
+               _tcscpy (st->newimagefile, changed_prefs.cdslots[unitnum].name);
                changed_prefs.cdslots[unitnum].name[0] = currprefs.cdslots[unitnum].name[0] = 0;
                currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse;
                int pollmode = 0;
-               imagechangetime[unitnum] = 3 * 50;
+               st->imagechangetime = 3 * 50;
                struct device_info di;
-               device_func[unitnum]->info (unitnum, &di, 0, -1);
-               if (wasopen[unitnum] >= 0)
-                       wasopen[unitnum] = di.open ? 1 : 0;
-               if (wasopen[unitnum]) {
-                       device_func[unitnum]->closedev (unitnum);
-                       wasopen[unitnum] = -1;
+               st->device_func->info (unitnum, &di, 0, -1);
+               if (st->wasopen >= 0)
+                       st->wasopen = di.open ? 1 : 0;
+               if (st->wasopen) {
+                       st->device_func->closedev (unitnum);
+                       st->wasopen = -1;
                        if (currprefs.scsi)  {
                                scsi_do_disk_change (unitnum, 0, &pollmode);
                                if (pollmode)
-                                       imagechangetime[unitnum] = 8 * 50;
+                                       st->imagechangetime = 8 * 50;
                                if (filesys_do_disk_change (unitnum, 0)) {
-                                       imagechangetime[unitnum] = newimagefiles[unitnum][0] ? 3 * 50 : 0;
+                                       st->imagechangetime = st->newimagefile[0] ? 3 * 50 : 0;
                                        pollmode = 0;
                                }
                        }
                }
-               write_log (_T("CD: eject (%s) open=%d\n"), pollmode ? _T("slow") : _T("fast"), wasopen[unitnum] ? 1 : 0);
+               write_log (_T("CD: eject (%s) open=%d\n"), pollmode ? _T("slow") : _T("fast"), st->wasopen ? 1 : 0);
 #ifdef RETROPLATFORM
                rp_cd_image_change (unitnum, NULL); 
 #endif
@@ -561,31 +600,31 @@ static void check_changes (int unitnum)
                        gotsem = false;
                }
        }
-       if (imagechangetime[unitnum] == 0)
+       if (st->imagechangetime == 0)
                return;
-       imagechangetime[unitnum]--;
-       if (imagechangetime[unitnum] > 0)
+       st->imagechangetime--;
+       if (st->imagechangetime > 0)
                return;
-       if (unitsem[unitnum])
+       if (st->sema)
                gotsem = getsem (unitnum, true);
-       _tcscpy (currprefs.cdslots[unitnum].name, newimagefiles[unitnum]);
-       _tcscpy (changed_prefs.cdslots[unitnum].name, newimagefiles[unitnum]);
-       currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = cdimagefileinuse[unitnum];
-       newimagefiles[unitnum][0] = 0;
-       write_log (_T("CD: delayed insert '%s' (open=%d,unit=%d)\n"), currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : _T("<EMPTY>"), wasopen[unitnum] ? 1 : 0, unitnum);
+       _tcscpy (currprefs.cdslots[unitnum].name, st->newimagefile);
+       _tcscpy (changed_prefs.cdslots[unitnum].name, st->newimagefile);
+       currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = st->cdimagefileinuse;
+       st->newimagefile[0] = 0;
+       write_log (_T("CD: delayed insert '%s' (open=%d,unit=%d)\n"), currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : _T("<EMPTY>"), st->wasopen ? 1 : 0, unitnum);
        device_func_init (0);
-       if (wasopen[unitnum]) {
-               if (!device_func[unitnum]->opendev (unitnum, currprefs.cdslots[unitnum].name, 0)) {
+       if (st->wasopen) {
+               if (!st->device_func->opendev (unitnum, currprefs.cdslots[unitnum].name, 0)) {
                        write_log (_T("-> device open failed\n"));
-                       wasopen[unitnum] = 0;
+                       st->wasopen = 0;
                } else {
-                       wasopen[unitnum] = 1;
+                       st->wasopen = 1;
                        write_log (_T("-> device reopened\n"));
                }
        }
-       if (currprefs.scsi && wasopen[unitnum]) {
+       if (currprefs.scsi && st->wasopen) {
                struct device_info di;
-               device_func[unitnum]->info (unitnum, &di, 0, -1);
+               st->device_func->info (unitnum, &di, 0, -1);
                int pollmode;
                if (gotsem) {
                        freesem (unitnum);
@@ -594,6 +633,7 @@ static void check_changes (int unitnum)
                scsi_do_disk_change (unitnum, 1, &pollmode);
                filesys_do_disk_change (unitnum, 1);
        }
+       st->mediawaschanged = true;
 #ifdef RETROPLATFORM
        rp_cd_image_change (unitnum, currprefs.cdslots[unitnum].name);
 #endif
@@ -614,12 +654,12 @@ void blkdev_vsync (void)
 
 static int do_scsi (int unitnum, uae_u8 *cmd, int cmdlen)
 {
-       uae_u8 *p = device_func[unitnum]->exec_out (unitnum, cmd, cmdlen);
+       uae_u8 *p = state[unitnum].device_func->exec_out (unitnum, cmd, cmdlen);
        return p != NULL;
 }
 static int do_scsi (int unitnum, uae_u8 *cmd, int cmdlen, uae_u8 *out, int outsize)
 {
-       uae_u8 *p = device_func[unitnum]->exec_in (unitnum, cmd, cmdlen, &outsize);
+       uae_u8 *p = state[unitnum].device_func->exec_in (unitnum, cmd, cmdlen, &outsize);
        if (p)
                memcpy (out, p, outsize);
        return p != NULL;
@@ -629,7 +669,7 @@ static int failunit (int unitnum)
 {
        if (unitnum < 0 || unitnum >= MAX_TOTAL_SCSI_DEVICES)
                return 1;
-       if (device_func[unitnum] == NULL)
+       if (state[unitnum].device_func == NULL)
                return 1;
        return 0;
 }
@@ -639,7 +679,7 @@ static int audiostatus (int unitnum)
        if (!getsem (unitnum))
                return 0;
        uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0};
-       uae_u8 *p = device_func[unitnum]->exec_in (unitnum, cmd, sizeof (cmd), 0);
+       uae_u8 *p = state[unitnum].device_func->exec_in (unitnum, cmd, sizeof (cmd), 0);
        freesem (unitnum);
        if (!p)
                return 0;
@@ -654,13 +694,13 @@ int sys_command_cd_pause (int unitnum, int paused)
        if (!getsem (unitnum))
                return 0;
        int v;
-       if (device_func[unitnum]->pause == NULL) {
+       if (state[unitnum].device_func->pause == NULL) {
                int as = audiostatus (unitnum);
                uae_u8 cmd[10] = {0x4b,0,0,0,0,0,0,0,paused?0:1,0};
                do_scsi (unitnum, cmd, sizeof cmd);
                v = as == AUDIO_STATUS_PAUSED;
        } else {
-               v = device_func[unitnum]->pause (unitnum, paused);
+               v = state[unitnum].device_func->pause (unitnum, paused);
        }
        freesem (unitnum);
        return v;
@@ -673,12 +713,12 @@ void sys_command_cd_stop (int unitnum)
                return;
        if (!getsem (unitnum))
                return;
-       if (device_func[unitnum]->stop == NULL) {
+       if (state[unitnum].device_func->stop == NULL) {
                int as = audiostatus (unitnum);
                uae_u8 cmd[6] = {0x4e,0,0,0,0,0};
                do_scsi (unitnum, cmd, sizeof cmd);
        } else {
-               device_func[unitnum]->stop (unitnum);
+               state[unitnum].device_func->stop (unitnum);
        }
        freesem (unitnum);
 }
@@ -691,8 +731,8 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       play_end_pos[unitnum] = endlsn;
-       if (device_func[unitnum]->play == NULL) {
+       state[unitnum].play_end_pos = endlsn;
+       if (state[unitnum].device_func->play == NULL) {
                uae_u8 cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
                int startmsf = lsn2msf (startlsn);
                int endmsf = lsn2msf (endlsn);
@@ -705,7 +745,7 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan)
                cmd[8] = (uae_u8)(endmsf >> 0);
                v = do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1;
        } else {
-               v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL);
+               v = state[unitnum].device_func->play (unitnum, startlsn, endlsn, scan, NULL, NULL);
        }
        freesem (unitnum);
        return v;
@@ -719,10 +759,10 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_s
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->play == NULL)
+       if (state[unitnum].device_func->play == NULL)
                v = sys_command_cd_play (unitnum, startlsn, endlsn, scan);
        else
-               v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc);
+               v = state[unitnum].device_func->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc);
        freesem (unitnum);
        return v;
 }
@@ -735,10 +775,10 @@ uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->volume == NULL)
+       if (state[unitnum].device_func->volume == NULL)
                v = -1;
        else
-               v = device_func[unitnum]->volume (unitnum, volume_left, volume_right);
+               v = state[unitnum].device_func->volume (unitnum, volume_left, volume_right);
        freesem (unitnum);
        return v;
 }
@@ -751,11 +791,11 @@ int sys_command_cd_qcode (int unitnum, uae_u8 *buf)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->qcode == NULL) {
+       if (state[unitnum].device_func->qcode == NULL) {
                uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0};
                v = do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
        } else {
-               v = device_func[unitnum]->qcode (unitnum, buf, -1);
+               v = state[unitnum].device_func->qcode (unitnum, buf, -1);
        }
        freesem (unitnum);
        return v;
@@ -769,7 +809,7 @@ int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->toc == NULL) {
+       if (state[unitnum].device_func->toc == NULL) {
                uae_u8 buf[4 + 8 * 103];
                int size = sizeof buf;
                uae_u8 cmd [10] = { 0x43,0,2,0,0,0,0,(uae_u8)(size>>8),(uae_u8)(size&0xff),0};
@@ -779,7 +819,7 @@ int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc)
                }
                v = 0;
        } else {
-               v = device_func[unitnum]->toc (unitnum, toc);
+               v = state[unitnum].device_func->toc (unitnum, toc);
        }
        freesem (unitnum);
        return v;
@@ -793,7 +833,7 @@ int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->read == NULL) {
+       if (state[unitnum].device_func->read == NULL) {
                uae_u8 cmd1[12] = { 0x28, 0, block >> 24, block >> 16, block >> 8, block >> 0, 0, size >> 8, size >> 0, 0, 0, 0 };
                v = do_scsi (unitnum, cmd1, sizeof cmd1, data, size * 2048);
 #if 0
@@ -803,7 +843,7 @@ int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size)
                }
 #endif
        } else {
-               v = device_func[unitnum]->read (unitnum, data, block, size);
+               v = state[unitnum].device_func->read (unitnum, data, block, size);
        }
        freesem (unitnum);
        return v;
@@ -815,11 +855,11 @@ int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int
                return -1;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->rawread == NULL) {
+       if (state[unitnum].device_func->rawread == NULL) {
                uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
                v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
        } else {
-               v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
+               v = state[unitnum].device_func->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
        }
        freesem (unitnum);
        return v;
@@ -831,11 +871,11 @@ int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int
                return -1;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->rawread == NULL) {
+       if (state[unitnum].device_func->rawread == NULL) {
                uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
                v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
        } else {
-               v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
+               v = state[unitnum].device_func->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
        }
        freesem (unitnum);
        return v;
@@ -849,7 +889,7 @@ int sys_command_read (int unitnum, uae_u8 *data, int block, int size)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->read == NULL) {
+       if (state[unitnum].device_func->read == NULL) {
                uae_u8 cmd[12] = { 0xa8, 0, 0, 0, 0, 0, size >> 24, size >> 16, size >> 8, size >> 0, 0, 0 };
                cmd[2] = (uae_u8)(block >> 24);
                cmd[3] = (uae_u8)(block >> 16);
@@ -857,7 +897,7 @@ int sys_command_read (int unitnum, uae_u8 *data, int block, int size)
                cmd[5] = (uae_u8)(block >> 0);
                v = do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048);
        } else {
-               v = device_func[unitnum]->read (unitnum, data, block, size);
+               v = state[unitnum].device_func->read (unitnum, data, block, size);
        }
        freesem (unitnum);
        return v;
@@ -871,10 +911,10 @@ int sys_command_write (int unitnum, uae_u8 *data, int offset, int size)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->write == NULL) {
+       if (state[unitnum].device_func->write == NULL) {
                v = 0;
        } else {
-               v = device_func[unitnum]->write (unitnum, data, offset, size);
+               v = state[unitnum].device_func->write (unitnum, data, offset, size);
        }
        freesem (unitnum);
        return v;
@@ -883,17 +923,18 @@ int sys_command_write (int unitnum, uae_u8 *data, int offset, int size)
 int sys_command_ismedia (int unitnum, int quick)
 {
        int v;
+       struct blkdevstate *st = &state[unitnum];
        if (failunit (unitnum))
                return -1;
-       if (delayed[unitnum])
+       if (st->delayed)
                return 0;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->ismedia == NULL) {
+       if (state[unitnum].device_func->ismedia == NULL) {
                uae_u8 cmd[6] = { 0, 0, 0, 0, 0, 0 };
                v = do_scsi (unitnum, cmd, sizeof cmd);
        } else {
-               v = device_func[unitnum]->ismedia (unitnum, quick);
+               v = state[unitnum].device_func->ismedia (unitnum, quick);
        }
        freesem (unitnum);
        return v;
@@ -901,14 +942,15 @@ int sys_command_ismedia (int unitnum, int quick)
 
 struct device_info *sys_command_info_session (int unitnum, struct device_info *di, int quick, int session)
 {
+       struct blkdevstate *st = &state[unitnum];
        if (failunit (unitnum))
                return NULL;
        if (!getsem (unitnum))
                return 0;
-       if (device_func[unitnum]->info == NULL)
+       if (st->device_func->info == NULL)
                return 0;
-       struct device_info *di2 = device_func[unitnum]->info (unitnum, di, quick, -1);
-       if (di2 && delayed[unitnum])
+       struct device_info *di2 = st->device_func->info (unitnum, di, quick, -1);
+       if (di2 && st->delayed)
                di2->media_inserted = 0;
        freesem (unitnum);
        return di2;
@@ -1044,15 +1086,15 @@ static bool nodisk (struct device_info *di)
 {
        return di->media_inserted == 0;
 }
-static uae_u64 cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len)
+static int cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len)
 {
        if (!getsem (unitnum))
                return 0;
-       int v = device_func[unitnum]->read (unitnum, dataptr, offset, len);
+       int v = state[unitnum].device_func->read (unitnum, dataptr, offset, len);
        freesem (unitnum);
-       if (v)
+       if (v >= 0)
                return len;
-       return 0;
+       return v;
 }
 
 static void wl (uae_u8 *p, int v)
@@ -1123,8 +1165,8 @@ static int scsiemudrv (int unitnum, uae_u8 *cmd)
        if (!getsem (unitnum))
                return 0;
        int v = 0;
-       if (device_func[unitnum]->scsiemu)
-               v = device_func[unitnum]->scsiemu (unitnum, cmd);
+       if (state[unitnum].device_func->scsiemu)
+               v = state[unitnum].device_func->scsiemu (unitnum, cmd);
        freesem (unitnum);
        return v;
 }
@@ -1146,37 +1188,77 @@ static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_i
        return sys_command_cd_rawread (unitnum, data, start, len, 0, (cmd[1] >> 2) & 7, cmd[9], subs);
 }
 
+static int scsi_read_cd_data (int unitnum, uae_u8 *scsi_data, uae_u32 offset, uae_u32 len, struct device_info *di, int *scsi_len)
+{
+       if (len == 0) {
+               *scsi_len = 0;
+               return 0;
+       } else {
+               if (len * di->bytespersector > SCSI_DATA_BUFFER_SIZE)
+                       return -3;
+               if (offset >= di->sectorspertrack)
+                       return -1;
+               int v = cmd_readx (unitnum, scsi_data, offset, len) * di->bytespersector;
+               if (v > 0) {
+                       *scsi_len = v;
+                       return 0;
+               }
+               return -2;
+       }
+}
+
 int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
        uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len, bool atapi)
 {
-       uae_u64 len, offset;
+       struct blkdevstate *st = &state[unitnum];
+       uae_u32 len, offset;
        int lr = 0, ls = 0;
        int scsi_len = -1;
+       int v;
        int status = 0;
        struct device_info di;
        uae_u8 cmd = cmdbuf[0];
-       int dlen = *data_len;
-
+       int dlen;
+       
+       if (cmd == 0x03) { /* REQUEST SENSE */
+               st->mediawaschanged = false;
+               return 0;
+       }
+       
+       dlen = *data_len;
        *reply_len = *sense_len = 0;
        memset (r, 0, 256);
        memset (s, 0, 256);
 
        sys_command_info (unitnum, &di, 1);
 
-       if (cmdbuf[0] == 0) { /* TEST UNIT READY */
-               if (nodisk (&di))
-                       goto nodisk;
-               scsi_len = 0;
-               goto end;
-       }
-       if (log_scsiemu)
+       if (log_scsiemu) {
                write_log (_T("SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%08X LEN=%d\n"), unitnum,
                        cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6], 
                        cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11],
                        scsi_cmd_len, scsi_data, dlen);
+       }
+
+       // media changed and not inquiry
+       if (st->mediawaschanged && cmd != 0x12) {
+               if (log_scsiemu) {
+                       write_log (_T("SCSIEMU %d: MEDIUM MAY HAVE CHANGED STATE\n"));
+               }
+               lr = -1;
+               status = 2; /* CHECK CONDITION */
+               s[0] = 0x70;
+               s[2] = 6; /* UNIT ATTENTION */
+               s[12] = 0x28; /* MEDIUM MAY HAVE CHANGED */
+               ls = 0x12;
+               goto end;
+       }
+
        switch (cmdbuf[0])
        {
-       case 0x03: /* REQUEST SENSE */
+       case 0x00: /* TEST UNIT READY */
+               if (nodisk (&di))
+                       goto nodisk;
+               scsi_len = 0;
                break;
        case 0x1e: /* PREVENT/ALLOW MEDIUM REMOVAL */
                scsi_len = 0;
@@ -1198,7 +1280,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                        r[3] |= 3 << 5; // atapi transport version
                r[4] = 32; /* additional length */
                r[7] = 0;
-               scsi_len = lr = len < 36 ? (uae_u32)len : 36;
+               scsi_len = lr = len < 36 ? len : 36;
                r[2] = 2;
                r[3] = 2;
                char *s = ua (di.vendorid);
@@ -1283,13 +1365,10 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                }
                bdsize = 0;
                if (!dbd) {
-                       if (nodisk (&di))
-                               goto nodisk;
-                       uae_u32 blocks = di.sectorspertrack * di.cylinders * di.trackspercylinder;
-                       bdsize = 8;
-                       wl(p + 0, blocks);
+                       wl(p + 0, 0);
                        wl(p + 4, di.bytespersector);
-                       p += 8;
+                       bdsize = 8;
+                       p += bdsize;
                }
                if (pcode == 0x3f) {
                        pcode = 1; // page = 0 must be last
@@ -1303,36 +1382,11 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                                p[2] = 0x20;
                                p[3] = 0;
                                psize = 4;
-#if 0
-                       } else if (pcode == 3) {
-                               if (nodisk (&di))
-                                       goto nodisk;
-                               p[0] = 3;
-                               p[1] = 24;
-                               p[3] = 1;
-                               p[10] = di.trackspercylinder >> 8;
-                               p[11] = di.trackspercylinder;
-                               p[12] = di.bytespersector >> 8;
-                               p[13] = di.bytespersector;
-                               p[15] = 1; // interleave
-                               p[20] = 0x80;
-                               psize = p[1];
-                       } else if (pcode == 4) {
-                               if (nodisk (&di))
-                                       goto nodisk;
-                               p[0] = 4;
-                               wl(p + 1, di.cylinders);
-                               p[1] = 24;
-                               p[5] = 1;
-                               wl(p + 13, di.cylinders);
-                               ww(p + 20, 0);
-                               psize = p[1];
-#endif
                        } else if (pcode == 14) { // CD audio control
                                uae_u32 vol = sys_command_cd_volume (unitnum, 0xffff, 0xffff);
                                p[0] = 0x0e;
                                p[1] = 0x0e;
-                               p[2] = 1;
+                               p[2] = 4|1;
                                p[3] = 4;
                                p[6] = 0;
                                p[7] = 75;
@@ -1340,7 +1394,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                                p[9] = pc == 0 ? (vol >> 7) & 0xff : 0xff;
                                p[10] = 2;
                                p[11] = pc == 0 ? (vol >> (16 + 7)) & 0xff : 0xff;
-                               psize = p[1];
+                               psize = p[1] + 2;
                        } else if (pcode == 0x2a) {  // cd/dvd capabilities
                                p[0] = 0x2a;
                                p[1] = 0x18;
@@ -1359,7 +1413,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                                p[18] = p[19] = 0;
                                p[20] = p[21] = 0;
                                p[22] = p[23] = 0;
-                               psize = p[1];
+                               psize = p[1] + 2;
                        } else {
                                if (!pcodeloop)
                                        goto err;
@@ -1396,7 +1450,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
        case 0x1d: /* SEND DIAGNOSTICS */
                scsi_len = 0;
                break;
-       case 0x25: /* READ_CAPACITY */
+       case 0x25: /* READ CAPACITY */
                {
                        int pmi = cmdbuf[8] & 1;
                        uae_u32 lba = (cmdbuf[2] << 24) | (cmdbuf[3] << 16) | (cmdbuf[4] << 8) | cmdbuf[5];
@@ -1433,9 +1487,13 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                        len = cmdbuf[4];
                        if (!len)
                                len = 256;
-                       if (len * di.bytespersector > SCSI_DATA_BUFFER_SIZE)
+                       v = scsi_read_cd_data (unitnum, scsi_data, offset, len, &di, &scsi_len);
+                       if (v == -1)
+                               goto outofbounds;
+                       if (v == -2)
+                               goto readerr;
+                       if (v == -3)
                                goto toolarge;
-                       scsi_len = (uae_u32)cmd_readx (unitnum, scsi_data, offset, len) * di.bytespersector;;
                } else {
                        goto notdatatrack;
                }
@@ -1452,9 +1510,13 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                struct cd_toc *t = gettoc (&di.toc, offset);
                if ((t->control & 0x0c) == 0x04) {
                        len = rl (cmdbuf + 7 - 2) & 0xffff;
-                       if (len * di.bytespersector > SCSI_DATA_BUFFER_SIZE)
+                       v = scsi_read_cd_data (unitnum, scsi_data, offset, len, &di, &scsi_len);
+                       if (v == -1)
+                               goto outofbounds;
+                       if (v == -2)
+                               goto readerr;
+                       if (v == -3)
                                goto toolarge;
-                       scsi_len = cmd_readx (unitnum, scsi_data, offset, len) * di.bytespersector;
                } else {
                        goto notdatatrack;
                }
@@ -1471,9 +1533,13 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                struct cd_toc *t = gettoc (&di.toc, offset);
                if ((t->control & 0x0c) == 0x04) {
                        len = rl (cmdbuf + 6);
-                       if (len * di.bytespersector > SCSI_DATA_BUFFER_SIZE)
+                       v = scsi_read_cd_data (unitnum, scsi_data, offset, len, &di, &scsi_len);
+                       if (v == -1)
+                               goto outofbounds;
+                       if (v == -2)
+                               goto readerr;
+                       if (v == -3)
                                goto toolarge;
-                       scsi_len = (uae_u32)cmd_readx (unitnum, scsi_data, offset, len) * di.bytespersector;;
                } else {
                        goto notdatatrack;
                }
@@ -1812,11 +1878,18 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                        scsi_len = 0;
                }
                break;
+               case 0x35: /* SYNCRONIZE CACHE (10) */
+                       scsi_len = 0;
+               break;
+
+               default:
+err:
+               write_log (_T("CDEMU: unsupported scsi command 0x%02X\n"), cmdbuf[0]);
 readprot:
                status = 2; /* CHECK CONDITION */
                s[0] = 0x70;
-               s[2] = 7; /* DATA PROTECT */
-               s[12] = 0x27; /* WRITE PROTECTED */
+               s[2] = 5;
+               s[12] = 0x20; /* INVALID COMMAND */
                ls = 0x12;
                break;
 nodisk:
@@ -1840,6 +1913,13 @@ notdatatrack:
                s[12] = 0x64; /* ILLEGAL MODE FOR THIS TRACK */
                ls = 0x12;
                break;
+outofbounds:
+               status = 2; /* CHECK CONDITION */
+               s[0] = 0x70;
+               s[2] = 5; /* ILLEGAL REQUEST */
+               s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */
+               ls = 0x12;
+               break;
 toolarge:
                write_log (_T("CDEMU: too large scsi data tranfer %d > %d\n"), len, dlen);
                status = 2; /* CHECK CONDITION */
@@ -1848,10 +1928,6 @@ toolarge:
                s[12] = 0x11; /* UNRECOVERED READ ERROR */
                ls = 0x12;
                break;
-
-               default:
-err:
-               write_log (_T("CDEMU: unsupported scsi command 0x%02X\n"), cmdbuf[0]);
 errreq:
                lr = -1;
                status = 2; /* CHECK CONDITION */
@@ -1868,6 +1944,9 @@ end:
        if (ls) {
                //s[0] |= 0x80;
                s[7] = ls - 7; // additional sense length
+               if (log_scsiemu) {
+                       write_log (_T("-> SENSE STATUS: KEY=%d ASC=%02X ASCQ=%02X\n"), s[2], s[12], s[13]);
+               }
        }
        if (cmdbuf[0] && log_scsiemu)
                write_log (_T("-> DATAOUT=%d ST=%d SENSELEN=%d\n"), scsi_len, status, ls);
@@ -1890,6 +1969,9 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as)
        if (as->sense_len > 32)
                as->sense_len = 32;
 
+       /* never report media change state if uaescsi.device */
+       state[unitnum].mediawaschanged = false;
+
        as->status = scsi_cd_emulate (unitnum, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen, false);
 
        as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */
@@ -1921,14 +2003,15 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as)
 
 int sys_command_scsi_direct_native (int unitnum, struct amigascsi *as)
 {
-       if (scsiemu[unitnum]) {
+       struct blkdevstate *st = &state[unitnum];
+       if (st->scsiemu) {
                return execscsicmd_direct (unitnum, as);
        } else {
-               if (!device_func[unitnum]->exec_direct)
+               if (!st->device_func->exec_direct)
                        return -1;
        }
-       int ret = device_func[unitnum]->exec_direct (unitnum, as);
-       if (!ret && device_func[unitnum]->isatapi(unitnum))
+       int ret = st->device_func->exec_direct (unitnum, as);
+       if (!ret && st->device_func->isatapi(unitnum))
                scsi_atapi_fixup_inquiry (as);
        return ret;
 }
@@ -1978,9 +2061,10 @@ int sys_command_scsi_direct (int unitnum, uaecptr acmd)
 
 uae_u8 *save_cd (int num, int *len)
 {
+       struct blkdevstate *st = &state[num];
        uae_u8 *dstbak, *dst;
 
-       memset(play_qcode[num], 0, SUBQ_SIZE);
+       memset(st->play_qcode, 0, SUBQ_SIZE);
        if (!currprefs.cdslots[num].inuse || num >= MAX_TOTAL_SCSI_DEVICES)
                return NULL;
        if (!currprefs.cs_cd32cd && !currprefs.cs_cdtvcd && !currprefs.scsi)
@@ -1991,16 +2075,17 @@ uae_u8 *save_cd (int num, int *len)
        save_u32 (currprefs.cdslots[num].type);
        save_u32 (0);
        save_u32 (0);
-       sys_command_cd_qcode (num, play_qcode[num]);
+       sys_command_cd_qcode (num, st->play_qcode);
        for (int i = 0; i < SUBQ_SIZE; i++)
-               save_u8 (play_qcode[num][i]);
-       save_u32 (play_end_pos[num]);
+               save_u8 (st->play_qcode[i]);
+       save_u32 (st->play_end_pos);
        *len = dst - dstbak;
        return dstbak;
 }
 
 uae_u8 *restore_cd (int num, uae_u8 *src)
 {
+       struct blkdevstate *st = &state[num];
        uae_u32 flags;
        TCHAR *s;
 
@@ -2020,8 +2105,8 @@ uae_u8 *restore_cd (int num, uae_u8 *src)
        if (flags & 8) {
                restore_u32 ();
                for (int i = 0; i < SUBQ_SIZE; i++)
-                       play_qcode[num][i] = restore_u8 ();
-               play_end_pos[num] = restore_u32 ();
+                       st->play_qcode[i] = restore_u8 ();
+               st->play_end_pos = restore_u32 ();
        }
        return src;
 }
index f1bdfcf001b52c9cc278aeca309e8a33ff2afbb0..d427500c31461ccf607ea1e81ec21a98929a4399 100644 (file)
@@ -605,7 +605,8 @@ static int command_pause (int unitnum, int paused)
        if (!cdu)
                return -1;
        int old = cdu->cdda_paused;
-       cdu->cdda_paused = paused;
+       if ((paused && cdu->cdda_play) || !paused)
+               cdu->cdda_paused = paused;
        return old;
 }
 
@@ -1654,7 +1655,7 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
                else
                        write_log (_T("    "));
                write_log (_T("%7d %02d:%02d:%02d"),
-                       t->address, (msf >> 16) & 0xff, (msf >> 8) & 0xff, (msf >> 0) & 0xff);
+                       t->address, (msf >> 16) & 0x7fff, (msf >> 8) & 0xff, (msf >> 0) & 0xff);
                if (i < cdu->tracks) {
                        write_log (_T(" %s %x %10lld %10lld %s%s"),
                                (t->ctrl & 4) ? _T("DATA    ") : (t->subcode ? _T("CDA+SUB") : _T("CDA     ")),
@@ -1670,7 +1671,7 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
        }
 
        cdu->blocksize = 2048;
-       cdu->cdsize = cdu->toc[cdu->tracks].address * cdu->blocksize;
+       cdu->cdsize = (uae_u64)cdu->toc[cdu->tracks].address * cdu->blocksize;
        
 
        zfile_fclose (zcue);
diff --git a/cia.cpp b/cia.cpp
index 0a0bc5f7df7ef00409df54710de3f6c949d28cd6..74bc12b0ef8e3358ee5808231dc1e33792c331f2 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -454,6 +454,15 @@ static int checkalarm (unsigned long tod, unsigned long alarm, int inc)
 
 STATIC_INLINE void ciab_checkalarm (int inc)
 {
+       // hack: do not trigger alarm interrupt if KS code and both
+       // tod and alarm == 0. This incorrectly triggers on non-cycle exact
+       // modes. Real hardware value written to ciabtod by KS is always
+       // at least 1 or larger due to bus cycle delays when reading
+       // old value.
+       if ((munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000) {
+               if (ciabtod == 0 && ciabalarm == 0)
+                       return;
+       }
        if (checkalarm (ciabtod, ciabalarm, inc)) {
                ciabicr |= 4;
                RethinkICRB ();
@@ -1532,8 +1541,8 @@ static uae_u32 REGPARAM2 cia_bget (uaecptr addr)
        case 3:
                if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible)
                        v = (addr & 1) ? regs.irc : regs.irc >> 8;
-               if (warned > 0) {
-                       write_log (_T("cia_bget: unknown CIA address %x PC=%x\n"), addr, M68K_GETPC);
+               if (warned > 0 || currprefs.illegal_mem) {
+                       write_log (_T("cia_bget: unknown CIA address %08X=%02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC);
                        warned--;
                }
                break;
@@ -1571,8 +1580,8 @@ static uae_u32 REGPARAM2 cia_wget (uaecptr addr)
        case 3:
                if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible)
                        v = regs.irc;
-               if (warned > 0) {
-                       write_log (_T("cia_wget: unknown CIA address %x PC=%x\n"), addr, M68K_GETPC);
+               if (warned > 0 || currprefs.illegal_mem) {
+                       write_log (_T("cia_wget: unknown CIA address %08X=%04X PC=%08X\n"), addr, v & 0xffff, M68K_GETPC);
                        warned--;
                }
                break;
@@ -1619,8 +1628,8 @@ static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
                        WriteCIAB (r, value);
                if ((addr & 0x1000) == 0)
                        WriteCIAA (r, value);
-               if (((addr & 0x3000) == 0x3000) && warned > 0) {
-                       write_log (_T("cia_bput: unknown CIA address %x %x\n"), addr, value);
+               if (((addr & 0x3000) == 0x3000) && (warned > 0 || currprefs.illegal_mem)) {
+                       write_log (_T("cia_bput: unknown CIA address %08X=%082X PC=%08X\n"), addr, value & 0xff, M68K_GETPC);
                        warned--;
                }
        }
@@ -1644,8 +1653,8 @@ static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
                        WriteCIAB (r, value >> 8);
                if ((addr & 0x1000) == 0)
                        WriteCIAA (r, value & 0xff);
-               if (((addr & 0x3000) == 0x3000) && warned > 0) {
-                       write_log (_T("cia_wput: unknown CIA address %x %x\n"), addr, value);
+               if (((addr & 0x3000) == 0x3000) && (warned > 0 || currprefs.illegal_mem)) {
+                       write_log (_T("cia_wput: unknown CIA address %08X=%04X %08X\n"), addr, value & 0xffff, M68K_GETPC);
                        warned--;
                }
        }
index 220d2b33dd9cad3c244d72b8967a0d1b23a8fd86..0881558deff9b81fe04be5171d0d415664f3c928 100644 (file)
@@ -2479,11 +2479,19 @@ static void calcsprite (void)
                int min, max;
                min = tospritexddf (thisline_decision.plfleft);
                max = tospritexddf (thisline_decision.plfright);
-               if (min > sprite_minx && min < max) /* min < max = full line ddf */
-                       sprite_minx = min;
+               if (min > sprite_minx && min < max) { /* min < max = full line ddf */
+                       if (currprefs.chipset_mask & CSMASK_ECS_DENISE) {
+                               sprite_minx = min;
+                       } else {
+                               if (thisline_decision.plfleft >= 0x28 || bpldmawasactive)
+                                       sprite_minx = min;
+                       }
+               }
                /* sprites are visible from first BPL1DAT write to end of line
-               * (undocumented feature)
-               */
+                * ECS Denise/AGA: not limits
+                * OCS Denise: BPL1DAT write only enables sprite if hpos >= 0x28 or so.
+                * (undocumented feature)
+                */
        }
 }
 
@@ -3012,7 +3020,7 @@ void compute_framesync (void)
                gfxvidinfo.drawbuffer.extrawidth = 0;
                gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
 
-               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << vres2;
+               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline + 1) << vres2;
                gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
 
        } else {
@@ -3020,7 +3028,7 @@ void compute_framesync (void)
                gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution;
                gfxvidinfo.drawbuffer.extrawidth = currprefs.gfx_extrawidth ? currprefs.gfx_extrawidth : -1;
                gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
-               gfxvidinfo.drawbuffer.inheight = (maxvpos_nom - minfirstline + 1) << currprefs.gfx_vresolution;
+               gfxvidinfo.drawbuffer.inheight = ((maxvpos_nom + 1) - minfirstline + 1) << currprefs.gfx_vresolution;
                gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
 
        }
@@ -3422,7 +3430,7 @@ static uae_u16 VPOSR (void)
                vp |= lol ? 0x80 : 0;
        hsyncdelay ();
 #if 0
-       if (M68K_GETPC < 0x00f00000 || M68K_GETPC >= 0x10000000)
+       if (1 || (M68K_GETPC < 0x00f00000 || M68K_GETPC >= 0x10000000))
                write_log (_T("VPOSR %04x at %08x\n"), vp, M68K_GETPC);
 #endif
        return vp;
@@ -5487,7 +5495,7 @@ static bool framewait (void)
                        t += (int)start - (int)vsync_time;
 
                if (!frame_shown)
-                       show_screen ();
+                       show_screen (1);
 
                int legacy_avg = mavg (&ma_legacy, t, MAVG_VSYNC_SIZE);
                if (t > legacy_avg)
@@ -5758,7 +5766,7 @@ static bool framewait (void)
                vsyncmintime = curr_time;
                vsyncmaxtime = vsyncwaittime = curr_time + vstb;
                if (frame_rendered) {
-                       show_screen ();
+                       show_screen (0);
                        t += read_processor_time () - curr_time;
                }
                t += frameskipt_avg;
@@ -5840,7 +5848,7 @@ static void vsync_handler_pre (void)
                if (vsync_handle_check ()) {
                        redraw_frame ();
                        render_screen (true);
-                       show_screen ();
+                       show_screen (0);
                }
                config_check_vsync ();
        }
index 37f9680bb2e9de289a2e3b2a76edc16796c73f36..681ff676e174b9cfb84fbd2a78ed646e001eb602 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -303,7 +303,8 @@ static void createrootblock (uae_u8 *sector, const TCHAR *disk_name)
 {
        char *dn = ua (disk_name);
        char *dn2 = dn;
-       dn2[30] = 0;
+       if (strlen (dn2) >= 30)
+               dn2[30] = 0;
        if (dn2[0] == 0)
                dn2 = "empty";
        memset (sector, 0, FS_FLOPPY_BLOCKSIZE);
index 2680a8df3626b4a322aea43b70ae9d1fad592c01..c1816945c56e95efd2b4b56355aa40523b43336d 100644 (file)
@@ -914,6 +914,8 @@ struct hardfiledata *get_hardfile_data (int nr)
 #define ACTION_ADD_NOTIFY              4097
 #define ACTION_REMOVE_NOTIFY   4098
 
+#define ACTION_READ_LINK               1024
+
 #define ACTION_CHANGE_FILE_POSITION64  8001
 #define ACTION_GET_FILE_POSITION64     8002
 #define ACTION_CHANGE_FILE_SIZE64      8003
@@ -921,7 +923,6 @@ struct hardfiledata *get_hardfile_data (int nr)
 
 /* not supported */
 #define ACTION_MAKE_LINK               1021
-#define ACTION_READ_LINK               1024
 
 #define DISK_TYPE_DOS 0x444f5300 /* DOS\0 */
 #define DISK_TYPE_DOS_FFS 0x444f5301 /* DOS\1 */
@@ -2106,6 +2107,10 @@ static a_inode *lookup_aino (Unit *unit, uae_u32 uniq)
        aino_test (a);
        return a;
 }
+static a_inode *aino_from_lock (Unit *unit, uaecptr lock)
+{
+       return lookup_aino (unit, get_long (lock + 4));
+}
 
 TCHAR *build_nname (const TCHAR *d, const TCHAR *n)
 {
@@ -2963,7 +2968,7 @@ static void
                get_long (lock) << 2, get_long (lock + 8),
                get_long (lock + 12), get_long (lock + 16),
                get_long (lock + 4)));
-       a = lookup_aino (unit, get_long (lock + 4));
+       a = aino_from_lock (unit, lock);
        if (a == 0) {
                TRACE((_T("not found!")));
        } else {
@@ -2978,7 +2983,7 @@ static a_inode *find_aino (Unit *unit, uaecptr lock, const TCHAR *name, int *err
        a_inode *a;
 
        if (lock) {
-               a_inode *olda = lookup_aino (unit, get_long (lock + 4));
+               a_inode *olda = aino_from_lock (unit, lock);
                if (olda == 0) {
                        /* That's the best we can hope to do. */
                        a = get_aino (unit, &unit->rootnode, name, err);
@@ -3226,7 +3231,6 @@ static void action_read_link_add_parent (Unit *u, a_inode *a, TCHAR *path)
        }
 }
 
-#if 0
 #define LINK_HARD 0
 #define LINK_SOFT 1
 
@@ -3234,35 +3238,62 @@ static void action_make_link (Unit *unit, dpacket packet)
 {
        uaecptr lock = GET_PCK_ARG1 (packet) << 2;
        uaecptr name = GET_PCK_ARG2 (packet) << 2;
-       uaecptr linkname = GET_PCK_ARG3 (packet);
+       uaecptr target = GET_PCK_ARG3 (packet);
        int type = GET_PCK_ARG4 (packet);
        a_inode *a1, *a2;
        int err;
+       TCHAR tmp[256], tmp2[MAX_DPATH], tmp3[MAX_DPATH];
+
+       _tcscpy (tmp, bstr (unit, name));
+       a1 = aino_from_lock (unit, lock);
 
        if (type == LINK_HARD) {
+
+               // we don't support hard links
+               uaecptr tlock = target << 2;
+               a2 = aino_from_lock (unit, tlock);
+               write_log (_T("ACTION_MAKE_LINK(HARD,'%s','%s','%s')\n"),
+                       a1 ? a1->aname : _T("?"), tmp,
+                       a2 ? a2->aname : _T("?"));
+
                PUT_PCK_RES1 (packet, DOS_FALSE);
                PUT_PCK_RES2 (packet, ERROR_NOT_IMPLEMENTED);
-               return;
-       }
-       a1 = find_aino (unit, lock, bstr (unit, name), &err);
-       if (err != 0) {
-               PUT_PCK_RES1 (packet, DOS_FALSE);
-               PUT_PCK_RES2 (packet, err);
-               return;
-       }
-       a2 = find_aino (unit, lock, cstr (unit, linkname), &err);
-       if (err != 0) {
-               PUT_PCK_RES1 (packet, DOS_FALSE);
-               PUT_PCK_RES2 (packet, err);
-               return;
-       }
-       if (!my_createsoftlink (a1->nname, a2->nname)) {
+
+       } else {
+
+               a_inode *a3;
+               TCHAR *link = cstr (unit, target);
+               write_log (_T("ACTION_MAKE_LINK(SOFT,'%s','%s','%s')\n"),
+                       a1 ? a1->aname : _T("?"), tmp, link);
+               if (!a1) {
+                       PUT_PCK_RES1 (packet, DOS_FALSE);
+                       PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND);
+                       return;
+               }
+               // try to find softlink target
+               for (Unit *u = units; u; u = u->next) {
+                       if (u->volflags & (MYVOLUMEINFO_ARCHIVE | MYVOLUMEINFO_CDFS))
+                               continue;
+                       a3 = find_aino (u, NULL, link, &err);
+                       if (err || !a3)
+                               continue;
+                       _tcscpy (tmp2, a1->nname);
+                       _tcscat (tmp2, FSDB_DIR_SEPARATOR_S);
+                       _tcscat (tmp2, tmp);
+                       tmp3[0] = 0;
+                       action_read_link_add_parent (u, a3, tmp3);
+                       if (!my_createshortcut (tmp2, a3->nname, tmp3)) {
+                               PUT_PCK_RES1 (packet, DOS_FALSE);
+                               PUT_PCK_RES2 (packet, dos_errno ());
+                       }
+                       return;
+               }
+               // real Amiga softlinks would accept invalid paths too,
+               // we won't.
                PUT_PCK_RES1 (packet, DOS_FALSE);
                PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND);
-               return;
        }
 }
-#endif
 
 static void action_read_link (Unit *unit, dpacket packet)
 {
@@ -3270,9 +3301,9 @@ static void action_read_link (Unit *unit, dpacket packet)
        uaecptr name = GET_PCK_ARG2 (packet);
        uaecptr newname = GET_PCK_ARG3 (packet);
        int size = GET_PCK_ARG4 (packet);
-       a_inode *a;
-       Unit *u = NULL;
-       int err, i;
+       a_inode *a, *matched_aino;
+       Unit *u = NULL, *u2 = NULL, *matched_unit;
+       int err, i, matched_len;
        TCHAR tmp[MAX_DPATH];
        TCHAR *namep, *extrapath;
 
@@ -3291,46 +3322,55 @@ static void action_read_link (Unit *unit, dpacket packet)
                        }
                }
        }
+       if (!a->softlink)
+               err = ERROR_OBJECT_WRONG_TYPE;
        if (err != 0) {
                PUT_PCK_RES1 (packet, DOS_FALSE);
                PUT_PCK_RES2 (packet, err);
                return;
        }
        _tcscpy (tmp, a->nname);
+       write_log (_T("Resolving softlink '%s'\n"), tmp);
        if (!my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) {
                PUT_PCK_RES1 (packet, DOS_FALSE);
                //  not sure what to return
                PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND);
                return;
        }
-       // TODO:
-       // now we have full absolute path, need to check if it can
-       // mapped to any Amiga side filesystem
-       // not that trivial..
-       a = NULL;
+       write_log (_T("-> '%s'\n"), tmp);
+       matched_aino = NULL;
+       matched_unit = NULL;
        err = 0;
+       matched_len = 0;
        for (u = units; u; u = u->next) {
                if (!(u->volflags & (MYVOLUMEINFO_ARCHIVE | MYVOLUMEINFO_CDFS))) {
                        TCHAR path[MAX_DPATH];
-                       if (my_issamevolume (u->rootnode.nname, tmp, path)) {
+                       i = my_issamevolume (u->rootnode.nname, tmp, path);
+                       if (i > matched_len) {
                                a = find_aino (u, 0, path, &err);
-                               if (a && !err)
-                                       break;
+                               if (a && !err) {
+                                       write_log (_T("Match found from '%s' (%d)\n"), u->rootnode.aname, i);
+                                       matched_aino = a;
+                                       matched_unit = u;
+                                       matched_len = i;
+                               }
                        }
                }
        }
-       if (!a || err) {
+       if (!matched_aino) {
+               write_log (_T("Path not found in any mounted drive\n"));
                PUT_PCK_RES1 (packet, DOS_FALSE);
                PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND);
                return;
        }
        tmp[0] = 0;
-       action_read_link_add_parent (u, a, tmp);
+       action_read_link_add_parent (matched_unit, matched_aino, tmp);
        if (extrapath) {
                _tcscat (tmp, _T("/"));
                _tcscat (tmp, extrapath);
        }
        xfree (extrapath);
+       write_log (_T("got target '%s'\n"), tmp); 
        char *s = ua_fs (tmp, -1);
        for (i = 0; s[i]; i++) {
                if (i >= size - 1)
@@ -3348,7 +3388,7 @@ static void action_free_lock (Unit *unit, dpacket packet)
        TRACE((_T("ACTION_FREE_LOCK(0x%lx)\n"), lock));
        DUMPLOCK(unit, lock);
 
-       a = lookup_aino (unit, get_long (lock + 4));
+       a = aino_from_lock (unit, lock);
        if (a == 0) {
                PUT_PCK_RES1 (packet, DOS_FALSE);
                PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND);
@@ -3597,7 +3637,7 @@ int get_native_path (uae_u32 lock, TCHAR *out)
        int i = 0;
        for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
                if (mountinfo.ui[i].self) {
-                       a_inode *a = lookup_aino (mountinfo.ui[i].self, get_long ((lock << 2) + 4));
+                       a_inode *a = aino_from_lock (mountinfo.ui[i].self, lock << 2);
                        if (a) {
                                _tcscpy (out, a->nname);
                                return 0;
@@ -3945,7 +3985,7 @@ static int action_examine_all_do (Unit *unit, uaecptr lock, ExAllKey *eak, uaecp
        TCHAR fn[MAX_DPATH];
 
        if (lock != 0)
-               base = lookup_aino (unit, get_long (lock + 4));
+               base = aino_from_lock (unit, lock);
        if (base == 0)
                base = &unit->rootnode;
        for (;;) {
@@ -4077,7 +4117,7 @@ static int action_examine_all (Unit *unit, dpacket packet)
                if (!eak)
                        goto fail;
                if (lock != 0)
-                       base = lookup_aino (unit, get_long (lock + 4));
+                       base = aino_from_lock (unit, lock);
                if (base == 0)
                        base = &unit->rootnode;
 #if EXALL_DEBUG > 0
@@ -4185,7 +4225,7 @@ static void action_examine_object (Unit *unit, dpacket packet)
        DUMPLOCK(unit, lock);
 
        if (lock != 0)
-               aino = lookup_aino (unit, get_long (lock + 4));
+               aino = aino_from_lock (unit, lock);
        if (aino == 0)
                aino = &unit->rootnode;
 
@@ -4280,7 +4320,7 @@ static void action_examine_next (Unit *unit, dpacket packet)
        DUMPLOCK(unit, lock);
 
        if (lock != 0)
-               aino = lookup_aino (unit, get_long (lock + 4));
+               aino = aino_from_lock (unit, lock);
        if (aino == 0)
                aino = &unit->rootnode;
        for(;;) {
@@ -4476,7 +4516,7 @@ static void
                return;
        }
 
-       aino = lookup_aino (unit, get_long (lock + 4));
+       aino = aino_from_lock (unit, lock);
        if (aino == 0)
                aino = &unit->rootnode;
        if (aino->softlink) {
@@ -4828,6 +4868,11 @@ static void
                PUT_PCK_RES2 (packet, err);
                return;
        }
+       if (a->softlink) {
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, ERROR_IS_SOFT_LINK);
+               return;
+       }
 
        a->amigaos_mode = mask;
        if (!fsdb_cando (unit))
@@ -4886,6 +4931,12 @@ maybe_free_and_out:
                        xfree (commented);
                return;
        }
+       if (a->softlink) {
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, ERROR_IS_SOFT_LINK);
+               goto maybe_free_and_out;
+       }
+
        PUT_PCK_RES1 (packet, DOS_TRUE);
        PUT_PCK_RES2 (packet, 0);
        if (a->comment == 0 && commented == 0)
@@ -5291,14 +5342,25 @@ static void
                return;
        }
 
-       amiga_to_timeval (&tv, get_long (date), get_long (date + 4), get_long (date + 8));
        a = find_aino (unit, lock, bstr (unit, name), &err);
+       if (err != 0) {
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, err);
+               return;
+       }
+       if (a->softlink) {
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, ERROR_IS_SOFT_LINK);
+               return;
+       }
+       amiga_to_timeval (&tv, get_long (date), get_long (date + 4), get_long (date + 8));
        write_log (_T("%llu.%u (%d,%d,%d) %s\n"), tv.tv_sec, tv.tv_usec, get_long (date), get_long (date + 4), get_long (date + 8), a->nname);
-       if (err == 0 && !my_utime (a->nname, &tv))
+       if (!my_utime (a->nname, &tv))
                err = dos_errno ();
        if (err != 0) {
                PUT_PCK_RES1 (packet, DOS_FALSE);
                PUT_PCK_RES2 (packet, err);
+               return;
        } else {
                notify_check (unit, a);
                PUT_PCK_RES1 (packet, DOS_TRUE);
@@ -5858,9 +5920,8 @@ static int handle_packet (Unit *unit, dpacket pck, uae_u32 msg)
        case ACTION_LOCK_RECORD: return action_lock_record (unit, pck, msg); break;
        case ACTION_FREE_RECORD: action_free_record (unit, pck); break;
        case ACTION_READ_LINK: action_read_link (unit, pck); break;
-#if 0
        case ACTION_MAKE_LINK: action_make_link (unit, pck); break;
-#endif
+
                /* OS4+ packet types */
        case ACTION_CHANGE_FILE_POSITION64: action_change_file_position64 (unit, pck); break;
        case ACTION_GET_FILE_POSITION64: action_get_file_position64 (unit, pck); break;
@@ -5869,7 +5930,6 @@ static int handle_packet (Unit *unit, dpacket pck, uae_u32 msg)
 
                /* unsupported packets */
        case ACTION_FORMAT:
-       case ACTION_MAKE_LINK:
                write_log (_T("FILESYS: UNSUPPORTED PACKET %x\n"), type);
                return 0;
        default:
index 676247128b85e818eabb0bdf46c54acddbbea791..60b68dc30d6288d9e56c6d72949156237203a6e7 100644 (file)
@@ -1153,8 +1153,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                if (!len)
                        len = 256;
                len *= hfd->ci.blocksize;
-               if (checkbounds(hfd, offset, len))
-                       scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
+               if (!checkbounds(hfd, offset, len))
+                       goto outofbounds;
+               scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
                break;
        case 0x0a: /* WRITE (6) */
                if (nodisk (hfd))
@@ -1167,8 +1168,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                if (!len)
                        len = 256;
                len *= hfd->ci.blocksize;
-               if (checkbounds(hfd, offset, len))
-                       scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
+               if (!checkbounds(hfd, offset, len))
+                       goto outofbounds;
+               scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
                break;
        case 0x12: /* INQUIRY */
                {
@@ -1346,8 +1348,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                offset *= hfd->ci.blocksize;
                len = rl (cmdbuf + 7 - 2) & 0xffff;
                len *= hfd->ci.blocksize;
-               if (checkbounds (hfd, offset, len))
-                       scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
+               if (!checkbounds (hfd, offset, len))
+                       goto outofbounds;
+               scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
                break;
        case 0x2a: /* WRITE (10) */
                if (nodisk (hfd))
@@ -1358,8 +1361,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                offset *= hfd->ci.blocksize;
                len = rl (cmdbuf + 7 - 2) & 0xffff;
                len *= hfd->ci.blocksize;
-               if (checkbounds (hfd, offset, len))
-                       scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
+               if (!checkbounds (hfd, offset, len))
+                       goto outofbounds;
+               scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
                break;
 #if 0
        case 0x2f: /* VERIFY */
@@ -1399,8 +1403,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                offset *= hfd->ci.blocksize;
                len = rl (cmdbuf + 6);
                len *= hfd->ci.blocksize;
-               if (checkbounds(hfd, offset, len))
-                       scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
+               if (!checkbounds(hfd, offset, len))
+                       goto outofbounds;
+               scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
                break;
        case 0xaa: /* WRITE (12) */
                if (nodisk (hfd))
@@ -1411,8 +1416,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                offset *= hfd->ci.blocksize;
                len = rl (cmdbuf + 6);
                len *= hfd->ci.blocksize;
-               if (checkbounds(hfd, offset, len))
-                       scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
+               if (!checkbounds(hfd, offset, len))
+                       goto outofbounds;
+               scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
                break;
        case 0x37: /* READ DEFECT DATA */
                if (nodisk (hfd))
@@ -1452,6 +1458,14 @@ errreq:
                s[12] = 0x24; /* ILLEGAL FIELD IN CDB */
                ls = 0x12;
                break;
+outofbounds:
+               lr = -1;
+               status = 2; /* CHECK CONDITION */
+               s[0] = 0x70;
+               s[2] = 5; /* ILLEGAL REQUEST */
+               s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */
+               ls = 0x12;
+               break;
 miscompare:
                lr = -1;
                status = 2; /* CHECK CONDITION */
index e6bb817c08fed5cc330aefbeced530543a771cf1..27b5f876ea0620f5043b62642996d5ea1483eccb 100644 (file)
@@ -103,10 +103,13 @@ extern uae_u16 INTREQR (void);
 
 #define MAXHPOS_PAL 227
 #define MAXHPOS_NTSC 227
+// short field maxvpos
 #define MAXVPOS_PAL 312
 #define MAXVPOS_NTSC 262
+// following endlines = first visible line
 #define VBLANK_ENDLINE_PAL 26
 #define VBLANK_ENDLINE_NTSC 21
+// line when sprite DMA fetches first control words
 #define VBLANK_SPRITE_PAL 25
 #define VBLANK_SPRITE_NTSC 20
 #define VBLANK_HZ_PAL 50
index 94575316c81623d94a1761a780d7a9815ac5abee..86147878ab5e750bd3ef06737638be5c11edcb90 100644 (file)
@@ -18,7 +18,7 @@
 #endif
 
 #define AMIGA_WIDTH_MAX (752 / 2)
-#define AMIGA_HEIGHT_MAX (574 / 2)
+#define AMIGA_HEIGHT_MAX (576 / 2)
 
 //#define NEWHSYNC
 
index 0e75ea0977ce3b973ed6111842dd4d6a4baed7e7..4ada269c935e921b460e0d36c70c0067d4ce538a 100644 (file)
@@ -82,7 +82,7 @@ typedef struct a_inode_struct {
     int shlock;
     long db_offset;
     unsigned int dir:1;
-    unsigned int softlink:1;
+    unsigned int softlink:2;
     unsigned int elock:1;
     /* Nonzero if this came from an entry in our database.  */
     unsigned int has_dbentry:1;
@@ -161,8 +161,11 @@ extern bool my_chmod (const TCHAR *name, uae_u32 mode);
 extern bool my_resolveshortcut(TCHAR *linkfile, int size);
 extern bool my_resolvessymboliclink(TCHAR *linkfile, int size);
 extern bool my_resolvesoftlink(TCHAR *linkfile, int size);
-extern bool my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path);
+extern void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size);
+extern int my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path);
 extern bool my_createsoftlink(const TCHAR *path, const TCHAR *target);
+extern bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TCHAR *description);
+
 
 extern char *custom_fsdb_search_dir (const char *dirname, TCHAR *rel);
 extern a_inode *custom_fsdb_lookup_aino_aname (a_inode *base, const TCHAR *aname);
index 9ff2dd87e7b3cdcd37806408e7d2ae8f751bf570..8f34daa771c6ec5d4cd821ea11f5859e8392afcc 100644 (file)
@@ -211,7 +211,7 @@ extern void inputdevice_testrecord (int type, int num, int wtype, int wnum, int
 extern int inputdevice_get_compatibility_input (struct uae_prefs*, int, int*, int**, int**);
 extern struct inputevent *inputdevice_get_eventinfo (int evt);
 extern bool inputdevice_get_eventname (const struct inputevent *ie, TCHAR *out);
-extern void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int mode);
+extern void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int mode, bool removeold);
 extern void inputdevice_compa_clear (struct uae_prefs *prefs, int index);
 extern int intputdevice_compa_get_eventtype (int evt, int **axistable);
 extern void inputdevice_sparecopy (struct uae_input_device *uid, int num, int sub);
index 87980e59238a067e5ae0656bf4ac41bdd2ae240a..dfd7035ce5728f7cedbfb1f908fef8edf965ea08 100644 (file)
@@ -217,6 +217,8 @@ struct apmode
        // -1 = wait for flip, before frame ends
        // 1 = wait for flip, after new frame has started
        int gfx_vflip;
+       // doubleframemode strobo
+       bool gfx_strobo;
        int gfx_vsyncmode;
        int gfx_backbuffers;
        bool gfx_interlaced;
index 6364a92830920c7e99de417b5a922529bf4ef23a..a5ff47ee2531b968a9b6ca785aefb60453bb324d 100644 (file)
@@ -45,7 +45,7 @@ extern void flush_block (struct vidbuffer*, int, int);
 extern void flush_screen (struct vidbuffer*, int, int);
 extern void flush_clear_screen (struct vidbuffer*);
 extern bool render_screen (bool);
-extern void show_screen (void);
+extern void show_screen (int);
 extern bool show_screen_maybe (bool);
 
 extern int lockscr (struct vidbuffer*, bool);
index a073cbd227a6ff895c11d6be8102a038041c8e15..c0a2b2bab8e6715a81c372b6a5d18046dae9fd10 100644 (file)
@@ -3368,7 +3368,6 @@ void inputdevice_reset (void)
        if (inputdevice_is_tablet ())
                mousehack_enable ();
        bouncy = 0;
-       potgo_value = 0;
 }
 
 static int getoldport (struct uae_input_device *id)
@@ -4491,7 +4490,7 @@ static void remove_custom_config (struct uae_prefs *prefs, bool nocustom, int in
 }
 
 // prepare port for custom mapping, remove all current Amiga side device mappings
-void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int newmode)
+void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int newmode, bool removeold)
 {
        int mode = prefs->jports[index].mode;
        freejport (prefs, index);
@@ -4502,10 +4501,12 @@ void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int n
                mode = index == 0 ? JSEM_MODE_WHEELMOUSE : (prefs->cs_cd32cd ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK);
        }
        prefs->jports[index].mode = mode;
-       prefs->jports[index].id = -2;
+       prefs->jports[index].id = JPORT_CUSTOM;
 
-       remove_compa_config (prefs, index);
-       remove_custom_config (prefs, false, index);
+       if (removeold) {
+               remove_compa_config (prefs, index);
+               remove_custom_config (prefs, false, index);
+       }
 }
 // clear device before switching to new one
 void inputdevice_compa_clear (struct uae_prefs *prefs, int index)
@@ -6334,8 +6335,8 @@ void inputdevice_testrecord (int type, int num, int wtype, int wnum, int state,
        if (testmode_count >= TESTMODE_MAX)
                return;
        if (type == IDTYPE_KEYBOARD) {
-               if (wnum == 0x100) {
-                       wnum = -1;
+               if (wnum >= 0x100) {
+                       wnum = 0x100 - wnum;
                } else {
                        struct uae_input_device *na = &keyboards[num];
                        int j = 0;
index 81dc58f9d8ba20b6e960909009a052b7fc5c6d15..0a32f1260c294605b6330b798c9a6ae269d67f0d 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -173,11 +173,15 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs)
                                        ap->gfx_vflip = 1;
                                if (!i && ap->gfx_backbuffers == 2)
                                        ap->gfx_vflip = 1;
+                               if (ap->gfx_vflip)
+                                       ap->gfx_strobo = true;
                        } else {
                                // legacy vsync: always wait for flip
                                ap->gfx_vflip = -1;
                                if (prefs->gfx_api && ap->gfx_backbuffers < 1)
                                        ap->gfx_backbuffers = 1;
+                               if (ap->gfx_vflip)
+                                       ap->gfx_strobo = true;
                        }
                } else {
                        // no vsync: wait if triple bufferirng
index d7dde9beedc7f4f0d23856d2b5f9cee890a408df..7551b62a117ac75e451aacd3bcad145eef88234d 100644 (file)
@@ -372,13 +372,14 @@ static int AVIOutput_GetAudioFromRegistry (WAVEFORMATEX *wft)
                return 0;
        getsettings (avikey);
        if (wft) {
+               ok = -1;
                ss = wfxMaxFmtSize;
                if (regquerydata (avikey, _T("AudioConfigurationVars"), wft, &ss)) {
                        if (AVIOutput_ValidateAudio (wft, NULL, 0))
                                ok = 1;
                }
        }
-       if (!ok)
+       if (ok < 0)
                regdelete (avikey, _T("AudioConfigurationVars"));
        regclosetree (avikey);
        return ok;
@@ -546,6 +547,7 @@ static int AVIOutput_GetCOMPVARSFromRegistry (COMPVARS *pcv)
                return 0;
        getsettings (avikey);
        if (pcv) {
+               ok = -1;
                ss = pcv->cbSize;
                pcv->hic = 0;
                if (regquerydata (avikey, _T("VideoConfigurationVars"), pcv, &ss)) {
@@ -569,7 +571,7 @@ static int AVIOutput_GetCOMPVARSFromRegistry (COMPVARS *pcv)
                        }
                }
        }
-       if (!ok) {
+       if (ok < 0) {
                regdelete (avikey, _T("VideoConfigurationVars"));
                regdelete (avikey, _T("VideoConfigurationState"));
        }
index 8effa6dc90068d6041955727ae961d8a0c33dd62..817b1082c7ea57f34c07a82fba5c1027197786a4 100644 (file)
@@ -697,7 +697,8 @@ static int ioctl_command_pause (int unitnum, int paused)
        if (!ciw)
                return -1;
        int old = ciw->cdda_paused;
-       ciw->cdda_paused = paused;
+       if ((paused && ciw->cdda_play) || !paused)
+               ciw->cdda_paused = paused;
        return old;
 }
 
index 88cca15412cd05b777ae8d6b3085f2a89cc2ea77..ec16b9b223f686765a3622ec47a25173762605ce 100644 (file)
@@ -2207,13 +2207,11 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                }
                rawkeystate[scancode] = pressed;
                if (istest) {
-                       if (pressed && (scancode == DIK_F12 || scancode == DIK_F11))
+                       if (pressed && (scancode == DIK_F12))
                                return;
-                       if (scancode == DIK_F12)
-                               scancode = -1;
-                       if (scancode == DIK_F11) {
-                               inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x100, 1, -1);
-                               inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x100, 0, -1);
+                       if (scancode == DIK_F12) {
+                               inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x101, 1, -1);
+                               inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x101, 0, -1);
                        } else {
                                inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, scancode, pressed, -1);
                        }
@@ -3232,13 +3230,11 @@ static void read_kb (void)
                                        continue;
                                di_keycodes[i][scancode] = pressed;
                                if (istest) {
-                                       if (pressed && (scancode == DIK_F12 || scancode == DIK_F11))
+                                       if (pressed && (scancode == DIK_F12))
                                                return;
-                                       if (scancode == DIK_F12)
-                                               scancode = -1;
-                                       if (scancode == DIK_F11) {
-                                               inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x100, 1, -1);
-                                               inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x100, 0, -1);
+                                       if (scancode == DIK_F12) {
+                                               inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x101, 1, -1);
+                                               inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x101, 0, -1);
                                        } else {
                                                inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, scancode, pressed, -1);
                                        }
index a090a3f193139d5ca4d473725e5e670267f63f18..ffb90c5396e2158fb77647c3371c25f95e2f6ecf 100644 (file)
@@ -2267,10 +2267,12 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult)
                        dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
                        getvsyncrate (dpp.FullScreen_RefreshRateInHz, &hzmult);
                        if (hzmult < 0) {
-                               if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
-                                       dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
-                               else
+                               if (!ap->gfx_strobo) {
+                                       if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
+                                               dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
+                               }  else {
                                        vsync2 = -1;
+                               }
                        } else if (hzmult > 0) {
                                vsync2 = 1;
                        }
@@ -2281,11 +2283,13 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult)
                getvsyncrate (dpp.FullScreen_RefreshRateInHz, &hzmult);
                if (hzmult > 0) {
                        vsync2 = 1;
-               } else if (hzmult < 0 && ap->gfx_vflip) {
-                       if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
-                               dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
-                       else
-                               vsync2 = -1;
+               } else if (hzmult < 0) {
+                       if (ap->gfx_vflip && !ap->gfx_strobo) {
+                               if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
+                                       dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
+                               else
+                                       vsync2 = -1;
+                       }
                }
        }
 
@@ -2464,7 +2468,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult)
                if (forcedframelatency >= 0)
                        hr = d3ddevex->SetMaximumFrameLatency (forcedframelatency);
                else if (v > 1 || !vsync)
-                       hr = d3ddevex->SetMaximumFrameLatency (vsync ? 1 : 0);
+                       hr = d3ddevex->SetMaximumFrameLatency (vsync ? (hzmult < 0 ? 2 : 1) : 0);
                if (FAILED (hr))
                        write_log (_T("%s: SetMaximumFrameLatency() failed: %s\n"), D3DHEAD, D3D_ErrorString (hr));
        }
@@ -3137,6 +3141,17 @@ void D3D_showframe (void)
        flushgpu (true);
 }
 
+void D3D_showframe_special (int mode)
+{
+       HRESULT hr;
+       if (!isd3d ())
+               return;
+       if (currprefs.turbo_emulation)
+               return;
+       hr = d3ddev->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0);
+       D3D_showframe2 (true);
+}
+
 void D3D_refresh (void)
 {
        if (!isd3d ())
index 1f48086310d0c82448e67f947a8f80471517852a..7dfbd44884dfe3f0eea8416852b0c79b25f1287e 100644 (file)
@@ -6,6 +6,7 @@ extern void D3D_getpixelformat (int depth,int *rb, int *bb, int *gb, int *rs, in
 extern void D3D_refresh (void);
 extern bool D3D_renderframe (bool);
 extern void D3D_showframe (void);
+extern void D3D_showframe_special (int);
 extern uae_u8 *D3D_locktexture(int*, bool);
 extern void D3D_unlocktexture(void);
 extern void D3D_flushtexture (int miny, int maxy);
index d99b58dc58606f49b7456dc95b2b380380c4d13c..3946b32eeaf33b65d4b910fc512727a7def99ea5 100644 (file)
@@ -764,42 +764,56 @@ bool my_utime (const TCHAR *name, struct mytimeval *tv)
 
 bool my_createsoftlink(const TCHAR *path, const TCHAR *target)
 {
-       return CreateSymbolicLink(path, target, my_existsdir(target) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != 0;
+       return CreateSymbolicLink(path, target, my_existsdir (target) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != 0;
 }
 
-bool my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path)
+void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size)
+{
+       TCHAR tmp[MAX_DPATH];
+       int v;
+       v = GetLongPathName (path, tmp, sizeof tmp / sizeof (TCHAR));
+       if (!v || v > sizeof tmp / sizeof (TCHAR)) {
+               _tcsncpy (out, path, size);
+               out[size - 1] = 0;
+               return;
+       }
+       PathCanonicalize(out, tmp);
+}
+
+int my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path)
 {
        TCHAR p1[MAX_DPATH];
        TCHAR p2[MAX_DPATH];
-       TCHAR p1b[MAX_DPATH];
-       TCHAR p2b[MAX_DPATH];
-       int len;
-
-       if (!GetFullPathName(path1, sizeof p1 / sizeof (TCHAR), p1, NULL))
-               return false;
-       if (!GetFullPathName(path2, sizeof p2 / sizeof (TCHAR), p2, NULL))
-               return false;
-       PathCanonicalize(p1b, p1);
-       PathCanonicalize(p2b, p2);
-       len = _tcslen (p1b);
-       if (len > _tcslen (p2b))
-               len = _tcslen (p2b);
-       if (_tcsnicmp (p1b, p2b, len))
-               return false;
-       _tcscpy (path, p2b + len);
+       int len, cnt;
+
+       my_canonicalize_path(path1, p1, sizeof p1 / sizeof (TCHAR));
+       my_canonicalize_path(path2, p2, sizeof p2 / sizeof (TCHAR));
+       len = _tcslen (p1);
+       if (len > _tcslen (p2))
+               len = _tcslen (p2);
+       if (_tcsnicmp (p1, p2, len))
+               return 0;
+       _tcscpy (path, p2 + len);
+       cnt = 0;
        for (int i = 0; i < _tcslen (path); i++) {
-               if (path[i] == '\\')
+               if (path[i] == '\\' || path[i] == '/') {
                        path[i] = '/';
+                       cnt++;
+               }
        }
-       return true;
+       write_log (_T("'%s' (%s) matched with '%s' (%s), extra = '%s'\n"), path1, p1, path2, p2, path);
+       return cnt;
 }
 
 bool my_resolvesoftlink(TCHAR *linkfile, int size)
 {
+       TCHAR tmp[MAX_DPATH];
        if (my_resolvessymboliclink(linkfile, size))
                return true;
        if (my_resolveshortcut(linkfile,size))
                return true;
+       _tcscpy (tmp, linkfile);
+       my_canonicalize_path (tmp, linkfile, size);
        return false;
 }
 
@@ -836,6 +850,7 @@ bool my_resolvessymboliclink(TCHAR *linkfile, int size)
        bool ret = false;
        DWORD returnedDataSize;
        uae_u8 tmp[MAX_DPATH * 2];
+       TCHAR tmp2[MAX_DPATH];
 
        h = FindFirstFile (linkfile, &fd);
        if (h == INVALID_HANDLE_VALUE)
@@ -850,23 +865,25 @@ bool my_resolvessymboliclink(TCHAR *linkfile, int size)
        if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, tmp, sizeof tmp, &returnedDataSize, NULL)) {
                REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)tmp;
                if (rdb->SymbolicLinkReparseBuffer.Flags & 1) { // SYMLINK_FLAG_RELATIVE
-                       PathRemoveFileSpec (linkfile);
-                       _tcscat (linkfile, _T("\\"));
-                       TCHAR *p = linkfile + _tcslen (linkfile);
+                       _tcscpy (tmp2, linkfile);
+                       PathRemoveFileSpec (tmp2);
+                       _tcscat (tmp2, _T("\\"));
+                       TCHAR *p = tmp2 + _tcslen (tmp2);
                        memcpy (p,
                                (uae_u8*)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset,
                                rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
                        p[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0;
                } else {
-                       memcpy (linkfile,
+                       memcpy (tmp2,
                                (uae_u8*)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset,
                                rdb->SymbolicLinkReparseBuffer.SubstituteNameLength);
-                       linkfile[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0;
+                       tmp2[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0;
                }
                ret = true;
-               if (!_tcsnicmp (linkfile, _T("\\??\\"), 4)) {
-                       memmove (linkfile, linkfile + 4, (_tcslen (linkfile + 4) + 1) * sizeof (TCHAR));
+               if (!_tcsnicmp (tmp2, _T("\\??\\"), 4)) {
+                       memmove (tmp2, tmp2 + 4, (_tcslen (tmp2 + 4) + 1) * sizeof (TCHAR));
                }
+               my_canonicalize_path (tmp2, linkfile, size);
        }
        CloseHandle(h);
        return ret;
@@ -921,8 +938,7 @@ bool my_resolveshortcut(TCHAR *linkfile, int size)
 
                         if (SUCCEEDED(hres)) 
                         {
-                                                       _tcsncpy (linkfile, szGotPath, size);
-                                                       linkfile[size - 1] = 0;
+                                                       my_canonicalize_path (szGotPath, linkfile, size);
                             ok = SUCCEEDED(hres);
                         }
                     }
@@ -938,3 +954,40 @@ bool my_resolveshortcut(TCHAR *linkfile, int size)
     } 
     return ok; 
 }
+
+// http://msdn.microsoft.com/en-us/library/aa969393.aspx
+bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TCHAR *description) 
+{ 
+    HRESULT hres; 
+    IShellLink* psl;
+       TCHAR tmp[MAX_DPATH];
+    // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
+    // has already been called.
+    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); 
+    if (SUCCEEDED(hres)) 
+    { 
+        IPersistFile* ppf; 
+        // Set the path to the shortcut target and add the description. 
+        psl->SetPath(target); 
+        psl->SetDescription(description); 
+        // Query IShellLink for the IPersistFile interface, used for saving the 
+        // shortcut in persistent storage. 
+        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); 
+        if (SUCCEEDED(hres)) 
+        { 
+            // Save the link by calling IPersistFile::Save. 
+                       _tcscpy (tmp, source);
+                       const TCHAR *ext = _tcsrchr (tmp, '.');
+                       if (!ext || _tcsicmp (ext, _T(".lnk")) != 0)
+                               _tcscat (tmp, _T(".lnk"));
+            hres = ppf->Save(tmp, TRUE); 
+            ppf->Release(); 
+        } 
+        psl->Release(); 
+    }
+       return SUCCEEDED(hres);
+}
index 635fe4c6aa19f121a19f906ee98f24aaa908ba98..b6857e45d3bd6752ec9d8f834265f3b4cd9cf1cb 100644 (file)
@@ -363,7 +363,7 @@ int fsdb_name_invalid_dir (const TCHAR *n)
        return v;
 }
 
-uae_u32 filesys_parse_mask(uae_u32 mask)
+uae_u32 filesys_parse_mask (uae_u32 mask)
 {
        return mask ^ 0xf;
 }
@@ -394,11 +394,22 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino)
                if (h != INVALID_HANDLE_VALUE) {
                        FindClose(h);
                        if (fd.dwReserved0 == IO_REPARSE_TAG_SYMLINK && (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
-                               aino->softlink = true;
+                               aino->softlink = 1;
                        }
                }
        }
        
+       if (!aino->softlink && !aino->dir) {
+               const TCHAR *ext = _tcsrchr (aino->nname, '.');
+               if (ext && !_tcsicmp (ext, _T(".lnk"))) {
+                       TCHAR tmp[MAX_DPATH];
+                       _tcscpy (tmp, aino->nname);
+                       if (my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) {
+                               aino->softlink = 2;
+                       }
+               }
+       }
+
        mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
 
        if ((base->volflags & MYVOLUMEINFO_STREAMS) && read_uaefsdb (aino->nname, NULL, fsdb)) {
@@ -432,17 +443,6 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino)
                write_uaefsdb (aino->nname, fsdb);
        }
 
-       if (!aino->softlink && !aino->dir) {
-               const TCHAR *ext = _tcsrchr (aino->nname, '.');
-               if (ext && !_tcsicmp (ext, _T(".lnk"))) {
-                       TCHAR tmp[MAX_DPATH];
-                       _tcscpy (tmp, aino->nname);
-                       if (my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) {
-                               aino->softlink = true;
-                       }
-               }
-       }
-
        return 1;
 }
 
index 712d48f802238bde7b429e37d044d01af4f58785..a94600a775a9b00f92edd60072e9e19df07275ea 100644 (file)
 #define IDC_PORT0_TEST                  1510
 #define IDC_SCREENRESTEXT               1511
 #define IDC_MAPDRIVES_AUTO              1511
-#define IDC_PORT0_TEST2                 1511
-#define IDC_PORT1_TEST                  1511
 #define IDC_WIDTHTEXT                   1512
 #define IDC_WINDOWEDTEXT                1512
-#define IDC_PORT2_TEST                  1512
 #define IDC_MAPDRIVES_LIMIT             1512
 #define IDC_HEIGHTTEXT                  1513
-#define IDC_PORT3_TEST                  1513
 #define IDC_SETTINGSTEXT                1514
 #define IDC_REFRESHTEXT                 1515
 #define IDC_SETTINGSTEXT2               1515
 #define IDC_CS_IDE4                     1816
 #define IDC_CS_DF0IDHW                  1817
 #define IDC_FILTERSTACK                 1818
+#define IDC_INPUTMAP_CAPTURE            1819
+#define IDC_INPUTMAP_CUSTOM             1820
+#define IDC_INPUTMAP_DELETE             1821
+#define IDC_INPUTMAP_TEST               1822
+#define IDC_INPUTMAP_DELETEALL          1823
+#define IDC_INPUTMAP_EXIT               1824
 #define ID__FLOPPYDRIVES                40004
 #define ID_FLOPPYDRIVES_DF0             40005
 #define ID_ST_CONFIGURATION             40010
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        388
 #define _APS_NEXT_COMMAND_VALUE         40050
-#define _APS_NEXT_CONTROL_VALUE         1819
+#define _APS_NEXT_CONTROL_VALUE         1820
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index 53361a723ea5521882bf74760835785cde3f1221..a4441f7b7fcb1a1187ed15ec03b98e5e2403266f 100644 (file)
@@ -438,22 +438,18 @@ BEGIN
     COMBOBOX        IDC_PORT0_JOYS,45,19,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_PORT0_AF,45,37,86,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_PORT0_JOYSMODE,136,38,106,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Test [] Test Port 1 (mouse) configuration.",IDC_PORT0_TEST,313,37,36,14
     PUSHBUTTON      "Remap [] Remap Port 1 configurarion.",IDC_PORT0_REMAP,352,37,36,14
     RTEXT           "Port 2:",IDC_STATIC,6,56,35,15,SS_CENTERIMAGE
     COMBOBOX        IDC_PORT1_JOYS,45,57,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_PORT1_AF,45,74,86,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_PORT1_JOYSMODE,136,74,106,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Test [] Test Port 2 (joystick) configuration.",IDC_PORT1_TEST,313,74,36,14
     PUSHBUTTON      "Remap [] Remap Port 2 configuration.",IDC_PORT1_REMAP,352,74,36,14
     PUSHBUTTON      "Swap ports [] Swap ports 1 and 2.",IDC_SWAP,45,100,78,14
     LTEXT           "Emulated parallel port joystick adapter",IDC_STATIC,10,124,179,15,SS_CENTERIMAGE
     RTEXT           "X-Arcade layout information []#1",IDC_STATIC,217,124,170,15,SS_NOTIFY | SS_CENTERIMAGE
     COMBOBOX        IDC_PORT2_JOYS,45,142,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Test [] Test Parallel port joystick port 1 configuration.",IDC_PORT2_TEST,313,159,36,14
     PUSHBUTTON      "Remap [] Remap Parallel port joystick port 1 configurarion.",IDC_PORT2_REMAP,352,159,36,14
     COMBOBOX        IDC_PORT3_JOYS,45,178,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Test [] Test Parallel port joystick 2 configuration.",IDC_PORT3_TEST,313,194,36,14
     PUSHBUTTON      "Remap [] Remap Parallel port joystick port 2 configurarion.",IDC_PORT3_REMAP,352,194,36,14
     GROUPBOX        "Mouse extra settings",IDC_STATIC,1,219,393,68
     RTEXT           "Mouse speed:",IDC_STATIC,19,237,82,10,SS_CENTERIMAGE
@@ -1077,13 +1073,21 @@ BEGIN
     CONTROL         "Always center",IDC_RTG_CENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,93,212,10
 END
 
-IDD_INPUTMAP DIALOGEX 0, 0, 396, 318
-STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
-FONT 8, "MS Sans Serif", 0, 0, 0x1
+IDD_INPUTMAP DIALOGEX 0, 0, 420, 318
+STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Input Remap"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
-    CONTROL         "",IDC_INPUTMAPLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,1,1,393,268
-    EDITTEXT        IDC_INPUTMAPOUT,1,272,393,14,ES_AUTOHSCROLL | ES_READONLY | WS_DISABLED
-    EDITTEXT        IDC_INPUTMAPOUTM,1,288,393,29,ES_MULTILINE | ES_READONLY | WS_DISABLED
+    DEFPUSHBUTTON   "OK",IDOK,147,51,58,14,NOT WS_VISIBLE
+    CONTROL         "",IDC_INPUTMAPLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,1,1,418,248
+    EDITTEXT        IDC_INPUTMAPOUT,1,253,418,14,ES_AUTOHSCROLL | ES_READONLY | WS_DISABLED
+    EDITTEXT        IDC_INPUTMAPOUTM,1,269,418,29,ES_MULTILINE | ES_READONLY | WS_DISABLED
+    PUSHBUTTON      "Remap",IDC_INPUTMAP_CAPTURE,72,300,66,14
+    PUSHBUTTON      "Add special",IDC_INPUTMAP_CUSTOM,142,300,66,14
+    PUSHBUTTON      "Delete",IDC_INPUTMAP_DELETE,212,300,66,14
+    PUSHBUTTON      "Delete all",IDC_INPUTMAP_DELETEALL,282,300,66,14
+    PUSHBUTTON      "Test",IDC_INPUTMAP_TEST,2,300,66,14
+    PUSHBUTTON      "Exit",IDC_INPUTMAP_EXIT,351,300,66,14
 END
 
 IDD_INFOBOX DIALOGEX 0, 0, 420, 68
@@ -1562,7 +1566,7 @@ BEGIN
     IDS_QS_CD               "CD"
     IDS_QS_CD_AUTO          "Autodetect"
     IDS_QS_CD_IMAGE         "Image mode"
-    IDS_REMAPTITLE          "Input captured. F12 = Exit. F11 = Skip current event in Remap mode."
+    IDS_REMAPTITLE          "Input captured. F12 = Exit."
     IDS_FILTER_NOOVERLAYS   "No overlays available"
     IDS_STMENUNOCD          "No CD inserted"
     IDS_ON                  "on"
index f3c3672e2245531ca346e86f93d4845c970c9089..a2e29808e493659f75eece6677a37323c44968f9 100644 (file)
@@ -283,7 +283,7 @@ int port_insert_custom (int inputmap_port, int devicetype, DWORD flags, const TC
        kb = inputdevice_get_device_total (IDTYPE_JOYSTICK) + inputdevice_get_device_total (IDTYPE_MOUSE);
 
        inputdevice_copyconfig (&currprefs, &changed_prefs);
-       inputdevice_compa_prepare_custom (&changed_prefs, inputmap_port, devicetype);
+       inputdevice_compa_prepare_custom (&changed_prefs, inputmap_port, devicetype, true);
        inputdevice_updateconfig (NULL, &changed_prefs);
        max = inputdevice_get_compatibility_input (&changed_prefs, inputmap_port, &mode, &events, &axistable);
        write_log (_T("custom='%s' max=%d port=%d dt=%d kb=%d kbnum=%d\n"), custom, max, inputmap_port, devicetype, kb, inputdevice_get_device_total (IDTYPE_KEYBOARD));
index 140058eaf2ae397ea9f911b6f939bfd237b9970d..7eff6cb7869f7155d833a1fead4a4f058003be46 100644 (file)
@@ -124,6 +124,7 @@ cd winuae_msvc11
 rm -rf debug
 rm -rf release
 rm -rf fullrelease
+rm -rf test
 cd ..
 
 cd singlefilehelper
index 67d13cd1af786778226ec7cf80ac374654f37800..161f10d0a907224e55af73868fad81824d8f8fdb 100644 (file)
@@ -5281,6 +5281,40 @@ static TCHAR **WIN32_InitRegistry (TCHAR **argv)
        return NULL;
 }
 
+static const TCHAR *pipename = _T("\\\\.\\pipe\\WinUAE");
+
+static bool singleprocess (void)
+{
+    DWORD mode, ret, avail;
+       bool ok = false;
+    TCHAR buf[1000];
+
+       HANDLE p = CreateFile(
+               pipename,
+               GENERIC_READ | GENERIC_WRITE,
+               0,
+               NULL,
+               OPEN_EXISTING,
+               0,
+               NULL);
+       if (p == INVALID_HANDLE_VALUE)
+               return false;
+       mode = PIPE_READMODE_MESSAGE;
+    if (!SetNamedPipeHandleState(p, &mode, NULL, NULL))
+               goto end;
+       buf[0] = 0xfeff;
+       _tcscpy (buf + 1, _T("IPC_QUIT"));
+       if (!WriteFile(p, (void*)buf, (_tcslen (buf) + 1) * sizeof (TCHAR), &ret, NULL))
+               goto end;
+       if (!PeekNamedPipe(p, NULL, 0, NULL, &avail, NULL))
+               goto end;
+    if (!ReadFile(p, buf, sizeof buf, &ret, NULL))
+               goto end;
+       ok = true;
+end:
+       CloseHandle(p);
+       return ok;
+}
 
 static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
 {
@@ -5296,6 +5330,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
        hInst = hInstance;
        hMutex = CreateMutex (NULL, FALSE, _T("WinUAE Instantiated")); // To tell the installer we're running
 
+       //singleprocess ();
 
        argv = xcalloc (TCHAR*, MAX_ARGUMENTS);
        argv3 = NULL;
index ef3f13421a83b3f12898cfec9d1f4a4c1ee8824e..3077391e98bef76c7b9f80d803a256a0b1966153 100644 (file)
 #define LANG_DLL 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("9")
+#define WINUAEBETA _T("10")
 #else
 #define WINUAEBETA _T("")
 #endif
-#define WINUAEDATE MAKEBD(2013, 2, 24)
+#define WINUAEDATE MAKEBD(2013, 3, 9)
 #define WINUAEEXTRA _T("")
 //#define WINUAEEXTRA _T("AmiKit Preview")
 #define WINUAEREV _T("")
index 314f6a3ae3484cada4686319568ba1afb18bb494..532b3dbb2715f9bdb7ae90559f40be0a3079b3e4 100644 (file)
@@ -988,15 +988,23 @@ void flush_screen (struct vidbuffer *vb, int a, int b)
 {
 }
 
-static volatile bool render_ok;
+static volatile bool render_ok, wait_render;
 
 bool render_screen (bool immediate)
 {
        bool v = false;
+       int cnt;
 
        render_ok = false;
        if (minimized || picasso_on || monitor_off || dx_islost ())
                return render_ok;
+       cnt = 0;
+       while (wait_render) {
+               sleep_millis(1);
+               cnt++;
+               if (cnt > 500)
+                       return render_ok;
+       }
        flushymin = 0;
        flushymax = currentmode->amiga_height;
        EnterCriticalSection (&screen_cs);
@@ -1020,12 +1028,12 @@ static void waitflipevent (void)
                        break;
        }
 }
-static void doflipevent (void)
+static void doflipevent (int mode)
 {
        if (flipevent == NULL)
                return;
        waitflipevent ();
-       flipevent_mode = 1;
+       flipevent_mode = mode;
        SetEvent (flipevent);
 }
 
@@ -1034,7 +1042,7 @@ bool show_screen_maybe (bool show)
        struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
        if (!ap->gfx_vflip || ap->gfx_vsyncmode == 0 || !ap->gfx_vsync) {
                if (show)
-                       show_screen ();
+                       show_screen (0);
                return false;
        }
 #if 0
@@ -1046,7 +1054,16 @@ bool show_screen_maybe (bool show)
        return false;
 }
 
-void show_screen (void)
+void show_screen_special (void)
+{
+       EnterCriticalSection (&screen_cs);
+       if (currentmode->flags & DM_D3D) {
+               D3D_showframe_special (1);
+       }
+       LeaveCriticalSection (&screen_cs);
+}
+
+void show_screen (int mode)
 {
        EnterCriticalSection (&screen_cs);
        if (!render_ok) {
@@ -2746,7 +2763,7 @@ end:
        return 1;
 }
 
-static volatile frame_time_t vblank_prev_time, thread_vblank_time;
+static volatile frame_time_t vblank_prev_time, vblank_real_prev_time, thread_vblank_time;
 static volatile int vblank_found_flipdelay;
 
 #include <process.h>
@@ -2916,13 +2933,19 @@ static unsigned int __stdcall flipthread (void *dummy)
                if (flipthread_mode == 0)
                        break;
                frame_time_t t = read_processor_time ();
-               while (!render_ok) {
+               while ((flipevent_mode & 1) && !render_ok) {
                        sleep_millis (1);
                        if (read_processor_time () - t > vblankbasefull)
                                break;
                }
-               show_screen ();
-               render_ok = false;
+               if (flipevent_mode & 1) {
+                       show_screen (0);
+                       render_ok = false;
+               }
+               if (flipevent_mode & 2) {
+                       show_screen_special ();
+                       wait_render = false;
+               }
                flipevent_mode = 0;
                SetEvent (flipevent2);
        }
@@ -3076,7 +3099,7 @@ static unsigned int __stdcall vblankthread (void *dummy)
                                        vblankthread_oddeven = (vp & 1) != 0;
                                }
                                if (!doflipped && ap->gfx_vflip > 0) {
-                                       doflipevent ();
+                                       doflipevent (1 | 2);
                                        doflipped = true;
                                }
                                ok = vblank_getstate (&vb, &vp);
@@ -3088,7 +3111,7 @@ static unsigned int __stdcall vblankthread (void *dummy)
                                                        if (read_processor_time () - t > vblankbasefull)
                                                                break;
                                                }
-                                               show_screen ();
+                                               show_screen (0);
                                                render_ok = false;
                                                int delay = read_processor_time () - t;
                                                if (delay < 0)
@@ -3117,7 +3140,7 @@ static unsigned int __stdcall vblankthread (void *dummy)
                        }
                        if (end) {
                                if (ap->gfx_vflip > 0 && !doflipped) {
-                                       doflipevent ();
+                                       doflipevent (1);
                                        doflipped = true;
                                }
                                thread_vblank_time = thread_vblank_time2;
@@ -3173,7 +3196,7 @@ frame_time_t vsync_busywait_end (int *flipdelay)
                        if (flipdelay)
                                *flipdelay = vblank_found_flipdelay;
                } else {
-                       show_screen ();
+                       show_screen (0);
                        prev = read_processor_time ();
                }
                changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT);
@@ -3285,7 +3308,7 @@ int vsync_busywait_do (int *freetime, bool lace, bool oddeven)
 
                if (currprefs.turbo_emulation) {
 
-                       show_screen ();
+                       show_screen (0);
                        dooddevenskip = 0;
                        vblank_prev_time = read_processor_time ();
                        framelost = true;
@@ -3306,10 +3329,20 @@ int vsync_busywait_do (int *freetime, bool lace, bool oddeven)
                                dooddevenskip = 1;
                        }
 
-                       if (ap->gfx_vflip != 0) {
-                               show_screen ();
+                       if (ap->gfx_vflip == 0 && vblank_skipeveryother) {
+                               // make sure that we really did skip one field
+                               while (!framelost && read_processor_time () - vblank_real_prev_time < vblankbasewait1) {
+                                       vsync_sleep (false);
+                               }
                        }
 
+                       if (ap->gfx_vflip != 0) {
+                               show_screen (0);
+                               if (ap->gfx_strobo && vblank_skipeveryother) {
+                                       wait_render = true;
+                                       doflipevent (2);
+                               }
+                       }
                        while (!framelost && read_processor_time () - prevtime < vblankbasewait1) {
                                vsync_sleep (false);
                        }
@@ -3331,9 +3364,9 @@ int vsync_busywait_do (int *freetime, bool lace, bool oddeven)
                        }
 
                        if (vp >= -1) {
-                               vblank_prev_time = read_processor_time ();
+                               vblank_real_prev_time = vblank_prev_time = read_processor_time ();
                                if (ap->gfx_vflip == 0) {
-                                       show_screen ();
+                                       show_screen (0);
                                        vblank_flip_delay = (read_processor_time () - vblank_prev_time) / (vblank_skipeveryother ? 2 : 1);
                                        if (vblank_flip_delay < 0)
                                                vblank_flip_delay = 0;
@@ -3518,12 +3551,12 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                int detectcnt = 6;
                for (cnt = 0; cnt < detectcnt; cnt++) {
                        render_screen (true);
-                       show_screen ();
+                       show_screen (0);
                        sleep_millis (1);
                        frame_time_t t = read_processor_time () + 1 * (syncbase / tsum);
                        for (int cnt2 = 0; cnt2 < 4; cnt2++) {
                                render_ok = true;
-                               show_screen ();
+                               show_screen (0);
                        }
                        int diff = (int)read_processor_time () - (int)t;
                        if (diff >= 0)
index f57603675760f2210d9adfc547aa3270c63aca0f..fbdcb691ed67c6596e829b444bc3e99a6894a433 100644 (file)
@@ -171,8 +171,9 @@ static int C_PAGES;
 #define MAX_C_PAGES 30
 static int LOADSAVE_ID = -1, MEMORY_ID = -1, KICKSTART_ID = -1, CPU_ID = -1,
        DISPLAY_ID = -1, HW3D_ID = -1, CHIPSET_ID = -1, CHIPSET2_ID = -1, SOUND_ID = -1, FLOPPY_ID = -1, DISK_ID = -1,
-       HARDDISK_ID = -1, IOPORTS_ID = -1, GAMEPORTS_ID = -1, INPUT_ID = -1, INPUTMAP_ID = -1, MISC1_ID = -1, MISC2_ID = -1,
+       HARDDISK_ID = -1, IOPORTS_ID = -1, GAMEPORTS_ID = -1, INPUT_ID = -1, MISC1_ID = -1, MISC2_ID = -1,
        AVIOUTPUT_ID = -1, PATHS_ID = -1, QUICKSTART_ID = -1, ABOUT_ID = -1, EXPANSION_ID = -1, FRONTEND_ID = -1;
+static const int INPUTMAP_ID = MAX_C_PAGES - 1;
 static HWND pages[MAX_C_PAGES];
 #define MAX_IMAGETOOLTIPS 10
 static HWND guiDlg, panelDlg, ToolTipHWND;
@@ -3447,7 +3448,7 @@ static void update_listview_input (HWND hDlg)
 
 static int inputmap_port = -1, inputmap_port_remap = -1;
 static int inputmap_groupindex[32];
-static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, int *inputmap_portp, int *inputmap_indexp, int state, int *inputmap_itemindexp)
+static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, int *inputmap_portp, int *inputmap_indexp, int state, int *inputmap_itemindexp, int deleteindex)
 {
        int cntitem, cntgroup, portnum;
        int mode, *events, *axistable;
@@ -3485,7 +3486,8 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum,
                                        lvstruct.iSubItem = 0;
                                        lvstruct.iGroupId = cntgroup;
                                        if (inputmap_itemindexp)
-                                               inputmap_itemindexp[cntgroup] = -1;
+                                               inputmap_itemindexp[cntgroup - 1] = -1;
+                                               inputmap_itemindexp[cntgroup + 1 - 1] = -1;
                                }
 
                                atpidx = 0;
@@ -3511,6 +3513,11 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum,
                                                                        if (inputdevice_get_mapping (devnum, j, &flags, &port, NULL, NULL, sub) == evtnum) {
                                                                                if (!port)
                                                                                        continue;
+                                                                               if (cntitem - 1 == deleteindex) {
+                                                                                       inputdevice_set_mapping (devnum, j, NULL, NULL, 0, 0, sub);
+                                                                                       deleteindex = -1;
+                                                                                       continue;
+                                                                               }
                                                                                inputdevice_get_widget_type (devnum, j, name);
                                                                                if (list) {
                                                                                        TCHAR target[MAX_DPATH];
@@ -3547,6 +3554,7 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum,
                                        if (list) {
                                                lvstruct.pszText = _T("");
                                                lvstruct.iItem = cntgroup * 256 + cntitem;
+                                               lvstruct.lParam = cntgroup;
                                                item = ListView_InsertItem (list, &lvstruct);
                                                if (inputmap_itemindexp && inputmap_itemindexp[cntgroup - 1] < 0)
                                                        inputmap_itemindexp[cntgroup - 1] = item;
@@ -3563,13 +3571,13 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum,
                return 1;
        return 0;
 }
-static void update_listview_inputmap (HWND hDlg)
+static void update_listview_inputmap (HWND hDlg, int deleteindex)
 {
        HWND list = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
 
        ListView_EnableGroupView (list, TRUE);
 
-       inputmap_handle (list, -1, -1, NULL, NULL, 0, inputmap_groupindex);
+       inputmap_handle (list, -1, -1, NULL, NULL, 0, inputmap_groupindex, deleteindex);
 }
 
 static int clicked_entry = -1;
@@ -3792,7 +3800,7 @@ void InitializeListView (HWND hDlg)
        } else if (lv_type == LV_INPUTMAP) {
 
                listview_column_width[0] = 400;
-               update_listview_inputmap (hDlg);
+               update_listview_inputmap (hDlg, -1);
 
        } else if (lv_type == LV_MISC1) {
 
@@ -4052,7 +4060,8 @@ void InitializeListView (HWND hDlg)
                }
                // Adjust our column widths so that we can see the contents...
                for(i = 0; i < listview_num_columns; i++) {
-                       if (ListView_GetColumnWidth (list, i) < listview_column_width[i])
+                       int w = ListView_GetColumnWidth (list, i);
+                       if (w < listview_column_width[i])
                                ListView_SetColumnWidth (list, i, listview_column_width[i]);
                }
                // Redraw the items in the list...
@@ -4558,7 +4567,7 @@ static INT_PTR CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                                {
                                case NM_DBLCLK:
                                        {
-                                               HTREEITEM ht = TreeView_GetSelection (GetDlgItem(hDlg, IDC_CONFIGTREE));
+                                               HTREEITEM ht = TreeView_GetSelection (GetDlgItem (hDlg, IDC_CONFIGTREE));
                                                if (ht != NULL) {
                                                        TVITEMEX pitem;
                                                        memset (&pitem, 0, sizeof (pitem));
@@ -11995,20 +12004,20 @@ static INT_PTR CALLBACK GamePortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                        updatejoyport (hDlg);
                } else if (LOWORD (wParam) == IDC_PORT0_REMAP) {
                        ports_remap (hDlg, 0);
+                       enable_for_gameportsdlg (hDlg);
+                       updatejoyport (hDlg);
                } else if (LOWORD (wParam) == IDC_PORT1_REMAP) {
                        ports_remap (hDlg, 1);
+                       enable_for_gameportsdlg (hDlg);
+                       updatejoyport (hDlg);
                } else if (LOWORD (wParam) == IDC_PORT2_REMAP) {
                        ports_remap (hDlg, 2);
+                       enable_for_gameportsdlg (hDlg);
+                       updatejoyport (hDlg);
                } else if (LOWORD (wParam) == IDC_PORT3_REMAP) {
                        ports_remap (hDlg, 3);
-               } else if (LOWORD (wParam) == IDC_PORT0_TEST) {
-                       input_test (hDlg, 0);
-               } else if (LOWORD (wParam) == IDC_PORT1_TEST) {
-                       input_test (hDlg, 1);
-               } else if (LOWORD (wParam) == IDC_PORT2_TEST) {
-                       input_test (hDlg, 2);
-               } else if (LOWORD (wParam) == IDC_PORT3_TEST) {
-                       input_test (hDlg, 3);
+                       enable_for_gameportsdlg (hDlg);
+                       updatejoyport (hDlg);
                } else if (HIWORD (wParam) == CBN_SELCHANGE) {
                        switch (LOWORD (wParam))
                        {
@@ -12517,68 +12526,84 @@ static void showextramap (HWND hDlg)
        SetWindowText (GetDlgItem (hDlg, IDC_INPUTMAPOUTM), out);
 }
 
-static void input_find (HWND hDlg, int mode, int set);
+static void input_find (HWND hDlg, HWND mainDlg, int mode, int set, bool oneshot);
 static int rawmode;
 static int inputmap_remap_counter, inputmap_view_offset;
+static int inputmap_mode_cnt;
+static bool inputmap_oneshot;
+
+#define INPUTMAP_F12 -1
+
+#if 0
+static void inputmap_next (HWND hDlg)
+{
+       HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
+       int inputmap = 1;
+       if (inputmap == 1) {
+               int mode, *events, *axistable;
+               int max = inputdevice_get_compatibility_input (&workprefs, inputmap_port, &mode, &events, &axistable);
+               inputmap_remap_counter++;
+               if (inputmap_remap_counter >= max)
+                       inputmap_remap_counter = 0;
+               int inputmap_index = inputmap_groupindex[inputmap_remap_counter];
+               ListView_EnsureVisible (h, inputmap_index, FALSE);
+               ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
+               ListView_SetItemState (h, inputmap_index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+       } else if (inputmap == 2) {
+               int itemcnt = ListView_GetItemCount (h);
+               if (inputmap_view_offset >= itemcnt - 1 || inputmap_view_offset < 0) {
+                       inputmap_view_offset = 0;
+               } else {
+                       inputmap_view_offset += ListView_GetCountPerPage (h);
+                       if (inputmap_view_offset >= itemcnt)
+                               inputmap_view_offset = itemcnt - 1;
+               }
+               ListView_EnsureVisible (h, inputmap_view_offset, FALSE);
+       }
+}
+#endif
 
 static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
 {
-       if (idEvent != 1)
-               return;
        int inputmap;
        WINDOWINFO pwi;
-       pwi.cbSize = sizeof pwi;
-       if (GetWindowInfo (guiDlg, &pwi)) {
-               // GUI inactive = disable capturing
-               if (pwi.dwWindowStatus != WS_ACTIVECAPTION) {
-                       input_find (hDlg, 0, false);
-                       return;
-               }
-       }
-       if (currentpage == INPUTMAP_ID) {
+       HWND myDlg;
+
+       if (idEvent != 1)
+               return;
+
+       if (pages[INPUTMAP_ID]) {
                inputmap = inputmap_remap_counter >= 0 ? 1 : 2;
                setfocus (hDlg, IDC_INPUTMAPLIST);
+               myDlg = hDlg;
        } else {
                inputmap = 0;
                setfocus (hDlg, IDC_INPUTLIST);
+               myDlg = guiDlg;
+       }
+
+       pwi.cbSize = sizeof pwi;
+       if (GetWindowInfo (myDlg, &pwi)) {
+               // GUI inactive = disable capturing
+               if (pwi.dwWindowStatus != WS_ACTIVECAPTION) {
+                       input_find (hDlg, myDlg, 0, false, false);
+                       return;
+               }
        }
+
        int inputmap_index;
        int devnum, wtype, state;
        int cnt = inputdevice_testread_count ();
        if (cnt < 0) {
-               input_find (hDlg, 0, FALSE);
+               input_find (hDlg, myDlg, 0, FALSE, false);
                return;
        }
        if (!cnt)
                return;
        int ret = inputdevice_testread (&devnum, &wtype, &state, true);
        if (ret > 0) {
-               if (wtype < 0) {
-                       if (!state)
-                               return;
-                       HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
-                       // F11
-                       if (inputmap == 1) {
-                               int mode, *events, *axistable;
-                               int max = inputdevice_get_compatibility_input (&workprefs, inputmap_port, &mode, &events, &axistable);
-                               inputmap_remap_counter++;
-                               if (inputmap_remap_counter >= max)
-                                       inputmap_remap_counter = 0;
-                               inputmap_index = inputmap_groupindex[inputmap_remap_counter];
-                               ListView_EnsureVisible (h, inputmap_index, FALSE);
-                               ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
-                               ListView_SetItemState (h, inputmap_index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
-                       } else if (inputmap == 2) {
-                               int itemcnt = ListView_GetItemCount (h);
-                               if (inputmap_view_offset >= itemcnt - 1 || inputmap_view_offset < 0) {
-                                       inputmap_view_offset = 0;
-                               } else {
-                                       inputmap_view_offset += ListView_GetCountPerPage (h);
-                                       if (inputmap_view_offset >= itemcnt)
-                                               inputmap_view_offset = itemcnt - 1;
-                               }
-                               ListView_EnsureVisible (h, inputmap_view_offset, FALSE);
-                       }
+               if (wtype == INPUTMAP_F12) {
+                       input_find (hDlg, myDlg, 0, FALSE, false);
                        return;
                }
                if (input_selected_widget != devnum || input_selected_widget != wtype) {
@@ -12612,7 +12637,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw
                                wcnt++;
                                for (;;) {
                                        ret = inputdevice_testread (&devnum, &wtype, &state, false);
-                                       if (ret <= 0)
+                                       if (ret <= 0 || wtype == -2)
                                                break;
                                        if (devnum != input_selected_device)
                                                continue;
@@ -12687,8 +12712,10 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw
                                        inputdevice_set_gameports_mapping (&workprefs, input_selected_device, input_selected_widget, evtnum, 0, inputmap_port);
                                InitializeListView (hDlg);
                                inputmap_remap_counter++;
-                               if (inputmap_remap_counter >= max)
-                                       inputmap_remap_counter = 0;
+                               if (inputmap_remap_counter >= max || inputmap_oneshot) {
+                                       input_find (hDlg, myDlg, 0, FALSE, false);
+                                       return;
+                               }
                                
                                inputmap_index = inputmap_groupindex[inputmap_remap_counter];
                                ListView_EnsureVisible (h, inputmap_index, FALSE);
@@ -12726,7 +12753,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw
                                bool found = false;
                                HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
                                int op = inputmap_port;
-                               if (inputmap_handle (NULL, input_selected_device, input_selected_widget, &op, &inputmap_index, state, NULL)) {
+                               if (inputmap_handle (NULL, input_selected_device, input_selected_widget, &op, &inputmap_index, state, NULL, -1)) {
                                        if (op == inputmap_port) {
                                                ListView_EnsureVisible (h, 1, FALSE);
                                                ListView_EnsureVisible (h, inputmap_index, FALSE);
@@ -12776,7 +12803,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw
                                ListView_SetItemState (GetDlgItem (hDlg, IDC_INPUTLIST), -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
                                ListView_SetItemState (GetDlgItem (hDlg, IDC_INPUTLIST), input_selected_widget, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
                                if (rawmode == 1) {
-                                       input_find (hDlg, 0, FALSE);
+                                       input_find (hDlg, myDlg, 0, FALSE, false);
                                        if (IsWindowEnabled (GetDlgItem (hDlg, IDC_INPUTAMIGA))) {
                                                setfocus (hDlg, IDC_INPUTAMIGA);
                                                SendDlgItemMessage (hDlg, IDC_INPUTAMIGA, CB_SHOWDROPDOWN , TRUE, 0L);
@@ -12795,35 +12822,44 @@ static int rawdisable[] = {
        IDC_INPUTCOPY, 0, 0, IDC_INPUTCOPYFROM, 0, 0, IDC_INPUTSWAP, 0, 0,
        IDC_INPUTDEADZONE, 0, 0, IDC_INPUTSPEEDD, 0, 0, IDC_INPUTAUTOFIRERATE, 0, 0, IDC_INPUTSPEEDA, 0, 0,
        IDC_PANELTREE, 1, 0, IDC_RESETAMIGA, 1, 0, IDC_QUITEMU, 1, 0, IDC_RESTARTEMU, 1, 0, IDOK, 1, 0, IDCANCEL, 1, 0, IDHELP, 1, 0,
+       IDC_INPUTMAP_DELETE, 0, 0, IDC_INPUTMAP_CAPTURE, 0, 0, IDC_INPUTMAP_CUSTOM, 0, 0,
+       IDC_INPUTMAP_TEST, 0, 0, IDC_INPUTMAP_DELETEALL, 0, 0, IDC_INPUTMAP_EXIT, 0, 0,
        -1
 };
 
+static void inputmap_disable (HWND hDlg, bool disable)
+{
+       for (int i = 0; rawdisable[i] >= 0; i += 3) {
+               HWND w = GetDlgItem (rawdisable[i + 1] ? guiDlg : hDlg, rawdisable[i]);
+               if (w) {
+                       if (disable) {
+                               rawdisable[i + 2] = IsWindowEnabled (w);
+                               EnableWindow (w, FALSE);
+                       } else {
+                               EnableWindow (w, rawdisable[i + 2]);
+                       }
+               }
+       }
+}
 
-static void input_find (HWND hDlg, int mode, int set)
+static void input_find (HWND hDlg, HWND mainDlg, int mode, int set, bool oneshot)
 {
        static TCHAR tmp[200];
        if (set && !rawmode) {
                rawmode = mode ? 2 : 1;
+               inputmap_oneshot = oneshot;
+               inputmap_disable (hDlg, true);
                inputdevice_settest (TRUE);
                inputdevice_acquire (-1);
-               if (rawmode == 2) {
-                       TCHAR tmp2[MAX_DPATH];
-                       GetWindowText (guiDlg, tmp, sizeof tmp / sizeof (TCHAR));
-                       WIN32GUI_LoadUIString (IDS_REMAPTITLE, tmp2, sizeof tmp2 / sizeof (TCHAR));
-                       SetWindowText (guiDlg, tmp2);
-               }
+               TCHAR tmp2[MAX_DPATH];
+               GetWindowText (guiDlg, tmp, sizeof tmp / sizeof (TCHAR));
+               WIN32GUI_LoadUIString (IDS_REMAPTITLE, tmp2, sizeof tmp2 / sizeof (TCHAR));
+               SetWindowText (mainDlg, tmp2);
                SetTimer (hDlg, 1, 30, timerfunc);
-               for (int i = 0; rawdisable[i] >= 0; i += 3) {
-                       HWND w = GetDlgItem (rawdisable[i + 1] ? guiDlg : hDlg, rawdisable[i]);
-                       if (w) {
-                               rawdisable[i + 2] = IsWindowEnabled (w);
-                               EnableWindow (w, FALSE);
-                       }
-               }
                ShowCursor (FALSE);
-               SetCapture (guiDlg);
+               SetCapture (mainDlg);
                RECT r;
-               GetWindowRect (guiDlg, &r);
+               GetWindowRect (mainDlg, &r);
                ClipCursor (&r);
        } else if (rawmode) {
                KillTimer (hDlg, 1);
@@ -12832,38 +12868,16 @@ static void input_find (HWND hDlg, int mode, int set)
                ShowCursor (TRUE);
                wait_keyrelease ();
                inputdevice_unacquire ();
-               for (int i = 0; rawdisable[i] >= 0; i += 3) {
-                       HWND w = GetDlgItem (rawdisable[i + 1] ? guiDlg : hDlg, rawdisable[i]);
-                       if (w)
-                               EnableWindow (w, rawdisable[i + 2]);
-               }
+               inputmap_disable (hDlg, false);
                inputdevice_settest (FALSE);
-               if (rawmode == 2) {
-                       SetWindowText (guiDlg, tmp);
-                       SetFocus (hDlg);
-               }
+               SetWindowText (mainDlg, tmp);
+               SetFocus (hDlg);
                rawmode = FALSE;
-               if (currentpage == INPUTMAP_ID)
-                       updatePanel (GAMEPORTS_ID);
+               SetWindowText (GetDlgItem (hDlg, IDC_INPUTMAPOUT), _T(""));
+               SetWindowText (GetDlgItem (hDlg, IDC_INPUTMAPOUTM), _T(""));
        }
 }
 
-static void ports_remap (HWND hDlg, int port)
-{
-       inputmap_port_remap = port;
-       inputmap_port = port;
-       inputmap_remap_counter = 0;
-       updatePanel (INPUTMAP_ID);
-}
-static void input_test (HWND hDlg, int port)
-{
-       inputmap_port_remap = -1;
-       inputmap_port = port;
-       inputmap_remap_counter = -1;
-       inputmap_view_offset = 0;
-       updatePanel (INPUTMAP_ID);
-}
-
 #if 0
 static void input_test (HWND hDlg, int port)
 {
@@ -12939,105 +12953,173 @@ static void handleXbutton (WPARAM wParam, int updown)
                setmousebuttonstate (dinput_winmouse (), num, updown);
 }
 
+static void handlerawinput (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+       if (msg == WM_INPUT) {
+               handle_rawinput (lParam);
+               DefWindowProc (hDlg, msg, wParam, lParam);
+       }
+}
+
+static int getremapcounter(int item)
+{
+       for (int i = 0; inputmap_groupindex[i] >= 0; i++) {
+               if (item < inputmap_groupindex[i + 1] || inputmap_groupindex[i + 1] < 0)
+                       return i;
+       }
+       return 0;
+}
+
 static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        static int recursive;
+       static int inputmap_selected;
+       HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
 
        switch (msg)
        {
+       case WM_CLOSE:
+               DestroyWindow (hDlg);
+               return TRUE;
        case WM_INITDIALOG:
        {
+               inputmap_port_remap = -1;
+               inputmap_remap_counter = -1;
+               inputmap_view_offset = 0;
                pages[INPUTMAP_ID] = hDlg;
-               currentpage = INPUTMAP_ID;
                inputdevice_updateconfig (NULL, &workprefs);
-               if (inputmap_remap_counter == 0) {
-                       inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1);
-                       inputdevice_updateconfig (NULL, &workprefs);
-               }
                InitializeListView (hDlg);
-               HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
-               if (inputmap_remap_counter == 0) {
-                       ListView_EnsureVisible (h, inputmap_remap_counter, FALSE);
-                       ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
-                       ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+               if (workprefs.jports[inputmap_port].id != JPORT_CUSTOM) {
+                       ew (hDlg, IDC_INPUTMAP_CAPTURE, FALSE);
+                       ew (hDlg, IDC_INPUTMAP_DELETE, FALSE);
+                       ew (hDlg, IDC_INPUTMAP_CUSTOM, FALSE);
                }
-               input_find (hDlg, 1, true);
-       }
-       case WM_USER:
-               recursive++;
-               recursive--;
-               return TRUE;
-       case WM_DESTROY:
-               input_find (hDlg, 0, false);
-       break;
-#if 0
-       case WM_MOUSEMOVE:
-       {
-               int wm = dinput_winmouse ();
-               int mx = (signed short) LOWORD (lParam);
-               int my = (signed short) HIWORD (lParam);
-               setmousestate (dinput_winmouse (), 0, mx, 0);
-               setmousestate (dinput_winmouse (), 1, my, 0);
                break;
        }
-       case WM_LBUTTONUP:
-               setmousebuttonstate (dinput_winmouse (), 0, 0);
-               return 0;
-       case WM_LBUTTONDOWN:
-       case WM_LBUTTONDBLCLK:
-               setmousebuttonstate (dinput_winmouse (), 0, 1);
-               return 0;
-       case WM_RBUTTONUP:
-               setmousebuttonstate (dinput_winmouse (), 1, 0);
-               return 0;
-       case WM_RBUTTONDOWN:
-       case WM_RBUTTONDBLCLK:
-               setmousebuttonstate (dinput_winmouse (), 1, 1);
-               return 0;
-       case WM_MBUTTONUP:
-               setmousebuttonstate (dinput_winmouse (), 2, 0);
-               return 0;
-       case WM_MBUTTONDOWN:
-       case WM_MBUTTONDBLCLK:
-               setmousebuttonstate (dinput_winmouse (), 2, 1);
-               return 0;
-       case WM_XBUTTONUP:
-               handleXbutton (wParam, 0);
-               return TRUE;
-       case WM_XBUTTONDOWN:
-       case WM_XBUTTONDBLCLK:
-               handleXbutton (wParam, 1);
+       case WM_DESTROY:
+               input_find (hDlg, hDlg, 0, false, false);
+               pages[INPUTMAP_ID] =  NULL;
+               inputmap_port_remap = -1;
+               inputmap_remap_counter = -1;
+               inputmap_view_offset = 0;
+               PostQuitMessage (0);
                return TRUE;
-       case WM_MOUSEWHEEL:
-               {
-                       int val = ((short)HIWORD (wParam));
-                       setmousestate (dinput_winmouse (), 2, val, 0);
-                       if (val < 0)
-                               setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 0, -1);
-                       else if (val > 0)
-                               setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 1, -1);
-                       return TRUE;
+       break;
+       case WM_NOTIFY:
+               if (((LPNMHDR) lParam)->idFrom == IDC_INPUTMAPLIST) {
+                       NM_LISTVIEW *lv = (NM_LISTVIEW*)lParam;
+                       switch (lv->hdr.code)
+                       {
+                               case NM_DBLCLK:
+                                       if (lv->iItem >= 0) {
+                                               inputmap_selected = lv->iItem;
+                                               inputmap_remap_counter = getremapcounter (lv->iItem);
+                                               if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) {
+                                                       input_find (hDlg, hDlg, 1, true, true);
+                                               }
+                                       }
+                               return TRUE;
+
+                               case NM_CLICK:
+                                       if (lv->iItem >= 0) {
+                                               inputmap_selected = lv->iItem;
+                                               inputmap_remap_counter = getremapcounter (lv->iItem);
+                                       }
+                               return TRUE;
+                       }
                }
-       case WM_MOUSEHWHEEL:
+       break;
+       case WM_COMMAND:
+       {
+               if (recursive)
+                       break;
+               recursive++;
+               switch(wParam)
                {
-                       int val = ((short)HIWORD (wParam));
-                       setmousestate (dinput_winmouse (), 3, val, 0);
-                       if (val < 0)
-                               setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 2, -1);
-                       else if (val > 0)
-                               setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 3, -1);
-                       return TRUE;
+                       case IDCANCEL:
+                       case IDOK:
+                       case IDC_INPUTMAP_EXIT:
+                       pages[INPUTMAP_ID] =  NULL;
+                       DestroyWindow (hDlg);
+                       //EndDialog (hDlg, 0);
+                       break;
+                       case IDC_INPUTMAP_TEST:
+                       inputmap_port_remap = -1;
+                       inputmap_remap_counter = -1;
+                       inputmap_view_offset = 0;
+                       input_find (hDlg, hDlg, 0, true, false);
+                       break;
+                       case IDC_INPUTMAP_CAPTURE:
+                       if (inputmap_remap_counter < 0)
+                               inputmap_remap_counter = 0;
+                       inputmap_port_remap = inputmap_port;
+                       if (workprefs.jports[inputmap_port].id != JPORT_CUSTOM) {
+                               inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1, false);
+                               inputdevice_updateconfig (NULL, &workprefs);
+                               InitializeListView (hDlg);
+                       }
+                       ListView_EnsureVisible (h, inputmap_remap_counter, FALSE);
+                       ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
+                       ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+                       input_find (hDlg, hDlg, 1, true, false);
+                       break;
+                       case IDC_INPUTMAP_CUSTOM:
+                       break;
+                       case IDC_INPUTMAP_DELETE:
+                       if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) {
+                               update_listview_inputmap (hDlg, inputmap_selected);
+                               InitializeListView (hDlg);
+                       }
+                       break;
+                       case IDC_INPUTMAP_DELETEALL:
+                       inputmap_remap_counter = 0;
+                       inputmap_port_remap = inputmap_port;
+                       inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1, true);
+                       inputdevice_updateconfig (NULL, &workprefs);
+                       InitializeListView (hDlg);
+                       ListView_EnsureVisible (h, inputmap_remap_counter, FALSE);
+                       ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
+                       ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+                       ew (hDlg, IDC_INPUTMAP_CAPTURE, TRUE);
+                       ew (hDlg, IDC_INPUTMAP_DELETE, TRUE);
+                       ew (hDlg, IDC_INPUTMAP_CUSTOM, TRUE);
+                       break;
                }
-#endif
+               recursive--;
+               break;
        }
-       return 0;
+       break;
+       }
+       handlerawinput (hDlg, msg, wParam, lParam);
+       return FALSE;
 }
 
-static void handlerawinput (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+static void ports_remap (HWND hDlg, int port)
 {
-       if (msg == WM_INPUT) {
-               handle_rawinput (lParam);
-               DefWindowProc (hDlg, msg, wParam, lParam);
+       inputmap_port = port;
+       HWND dlg = CustomCreateDialog (IDD_INPUTMAP, hDlg, InputMapDlgProc);
+       if (dlg == NULL)
+               return;
+       MSG msg;
+       for (;;) {
+               DWORD ret = GetMessage (&msg, dlg, 0, 0);
+               if (ret == -1 || ret == 0)
+                       break;
+               if (rawmode) {
+                       if (msg.message == WM_INPUT) {
+                               handlerawinput (msg.hwnd, msg.message, msg.wParam, msg.lParam);
+                               continue;
+                       }
+                       // eat all accelerators
+                       if (msg.message == WM_KEYDOWN || msg.message == WM_MOUSEMOVE || msg.message == WM_MOUSEWHEEL
+                               || msg.message == WM_MOUSEHWHEEL || msg.message == WM_LBUTTONDOWN)
+                               continue;
+               }
+               // IsDialogMessage() eats WM_INPUT messages?!?!
+               if (!rawmode && IsDialogMessage (dlg, &msg))
+                       continue;
+               TranslateMessage (&msg);
+               DispatchMessage (&msg);
        }
 }
 
@@ -13323,7 +13405,7 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                recursive--;
                return TRUE;
        case WM_DESTROY:
-               input_find (hDlg, 0, false);
+               input_find (hDlg, guiDlg, 0, false, false);
                break;
        case WM_COMMAND:
                if (recursive)
@@ -13333,10 +13415,10 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                {
                case IDC_INPUTREMAP:
                        input_selected_event = -1;
-                       input_find (hDlg, 0, true);
+                       input_find (hDlg, guiDlg, 0, true, false);
                        break;
                case IDC_INPUTTEST:
-                       input_find (hDlg, 1, true);
+                       input_find (hDlg, guiDlg, 1, true, false);
                        break;
                case IDC_INPUTCOPY:
                        input_copy (hDlg);
@@ -15856,7 +15938,6 @@ static int GetSettings (int all_options, HWND hwnd)
                HARDDISK_ID = init_page (IDD_HARDDISK, IDI_HARDDISK, IDS_HARDDISK, HarddiskDlgProc, HarddiskAccel, _T("gui/hard-drives.htm"), 0);
 #endif
                GAMEPORTS_ID = init_page (IDD_GAMEPORTS, IDI_GAMEPORTS, IDS_GAMEPORTS, GamePortsDlgProc, NULL, _T("gui/gameports.htm"), 0);
-               INPUTMAP_ID = init_page (IDD_INPUTMAP, IDI_GAMEPORTS, IDS_GAMEPORTS, InputMapDlgProc, NULL, NULL, IDC_INPUTMAPLIST);
                IOPORTS_ID = init_page (IDD_IOPORTS, IDI_PORTS, IDS_IOPORTS, IOPortsDlgProc, NULL, _T("gui/ioports.htm"), 0);
                INPUT_ID = init_page (IDD_INPUT, IDI_INPUT, IDS_INPUT, InputDlgProc, NULL, _T("gui/input.htm"), IDC_INPUTLIST);
                MISC1_ID = init_page (IDD_MISC1, IDI_MISC1, IDS_MISC1, MiscDlgProc1, NULL, _T("gui/misc.htm"), 0);
@@ -15969,8 +16050,10 @@ static int GetSettings (int all_options, HWND hwnd)
                                if (globalipc && IPChandle != INVALID_HANDLE_VALUE) {
                                        MsgWaitForMultipleObjects (1, &IPChandle, FALSE, INFINITE, QS_ALLINPUT);
                                        while (checkIPC (globalipc, &workprefs));
+                                       if (quit_program == -UAE_QUIT)
+                                               break;
                                } else {
-                                       WaitMessage();
+                                       WaitMessage ();
                                }
                                dialogmousemove (dhwnd);
 
index f196405b35c5ad7e6a4a8401a10df927dee43a2c..a8a892cb3a77452a06bd15575dbf5a332b728d78 100644 (file)
@@ -1,6 +1,35 @@
 
 - restore only single input target to default.
 
+Beta 10:
+
+- SCSI CD MODE SENSE emulation fixes.
+- SCSI CD Write commands should return unknown command error, it is not a CD writer.
+- SCSI CD and HD: return correct sense code if Read or Write command tries to access out of bounds LBAs.
+- SCSI/ATAPI CD: return medium changed unit attention sense data after media change.
+- OCS and ECS Denise/AGA have slightly different behavior when program writes to BPL1DAT to enable sprites
+  before DDFSTRT (sort of AGA bordersprite option), OCS: only works if hpos is large enough (~40+), ECS:
+  smaller limit (or no limit, didn't test).
+- Soft link emulation improved.
+- Directory filesystem ACTION_MAKE_LINK implemented, supports soft links only, creates shortcut (*.lnk) files.
+- Entering GUI Harddrives panel removed image from internel CD image mounter if mounted as ATAPI or SCSI. (introduced few betas ago)
+- Restructured blkdev.cpp unit handling.
+- Sound autoswitching is disabled when AVI recording is active.
+- Low latency vsync no buffer mode and doubled frames (100Hz+) was unstable.
+- POTGO right button bit was temporarily and incorrectly active in some situations when loading state.
+- D3D Low latency vsync in double and triple buffer double rate modes (100Hz+) now blank every other field to minimize "ghosting" effect.
+  Will be optional later. (http://www.blurbusters.com/ for more information)
+- Added hack that prevents incorrectly triggering CIA alarm interrupts in non-cycle exact modes due to not that good KS timer.device
+  code. (It did not cause any problems, just wasted some emulated CPU time)
+- Fixed memory corruption in exe to adf conversion code. (b1)
+- GamePorts panel test/remap option rewritten.
+  - Test and Remap buttons combined.
+  - One or more events can be added.
+  - Events can be removed one by one.
+  - Non-key/joystick/mouse events (insert floppy, reset emulator etc..) can be added and removed. Not yet implemented.
+  - Doubleclick on input list will record single input event.
+  NOTE: Built-in (non-custom mode) events can not be edited, you need to start from scratch. (Click "Delete all")
+
 Beta 9:
 
 - 68000 NBCD didn't emulate undocumented V-flag behavior. (Probably forgotten long time ago because SBCD had correct
@@ -121,7 +150,7 @@ Beta 2:
 - Fixed stuck IDE emulation interrupt that hangs the emulated system, happened randomly during A4000 IDE detection. (Old bug)
 - Geometry file FORCELOAD parameter added, forceload=1: do not re-use already loaded filesystem(s).
 - A590/A2091/A3000 SCSI CDROM emulation added, uses SCSI emulation originally made for uaescsi.device.
-- Gayle/A4000 ATAPI CDROM emulation added (uses uaescsi.device SCSI emulation, ATAPI = IDE CROM SCSI command support)
+- Gayle/A4000 ATAPI CDROM emulation added (uses uaescsi.device SCSI emulation, ATAPI = IDE CDROM SCSI command support)
 - CD image mounter SCSI emulation inquiry command's vendor/product/revision data was blank.
 - Ultra-minimal "Add CD Drive" GUI added. Only IDE or SCSI and only one CD entry can be added. Use hardddrives panel bottom
   CD drive/image selection select menu to select mounted CD. uaescsi.device still works as previously but note that
index 6736d8af6872efec225cc59ad9a5d3588130a5fe..e263bfa62015ce0dfbff1caa77dca94c37bb96af 100644 (file)
@@ -513,7 +513,7 @@ void restore_state (const TCHAR *filename)
                write_log (_T("%s is not an AmigaStateFile\n"), filename);
                goto error;
        }
-       write_log (_T("STATERESTORE:\n"));
+       write_log (_T("STATERESTORE: '%s'\n"), filename);
        config_changed = 1;
        savestate_file = f;
        restore_header (chunk);
index 3fe6ceadadc029af8fe5f789859cb0e9a2ee838c..f126be2af88f9d831ec64100512a574059e5831b 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
@@ -94,8 +94,9 @@ void scsi_emulate_cmd(struct scsi_data *sd)
        if (sd->cd_emu_unit >= 0) {
                if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
                        int len = sd->cmd[4];
-                       memset (sd->buffer, 0, len);
-                       memcpy (sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
+                       scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, 0, 0, 0, 0, 0, 0, 0, sd->atapi); /* ack request sense */
+                       memset(sd->buffer, 0, len);
+                       memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
                        sd->data_len = len;
                } else {
                        sd->status = scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len, sd->atapi);
@@ -109,8 +110,8 @@ void scsi_emulate_cmd(struct scsi_data *sd)
        } else if (sd->nativescsiunit < 0) {
                if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
                        int len = sd->cmd[4];
-                       memset (sd->buffer, 0, len);
-                       memcpy (sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
+                       memset(sd->buffer, 0, len);
+                       memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
                        sd->data_len = len;
                } else {
                        sd->status = scsi_hd_emulate(&sd->hfd->hfd, sd->hfd,
index d8abe9665db92bb69ee923236ff58fda3ab4e16a..fca20c7c5d982a6cff6a6d09501ffc30f48dffa1 100644 (file)
@@ -10,6 +10,7 @@
 #include "zfile.h"
 #include "inputdevice.h"
 #include "debug.h"
+#include "uae.h"
 
 #include <windows.h>
 
@@ -39,6 +40,10 @@ static void parsemessage(TCHAR *in, struct uae_prefs *p, TCHAR *out, int outsize
        out[0] = 0;
 
        my_trim (in);
+       if (!_tcsicmp (in, _T("IPC_QUIT"))) {
+               uae_quit ();
+               return;
+       }
        if (!_tcsicmp (in, _T("ipc_config"))) {
                ipcmode = 1;
                _tcscat (out, _T("200\n"));