]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2400b3
authorToni Wilen <twilen@winuae.net>
Sun, 11 Dec 2011 17:12:18 +0000 (19:12 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 11 Dec 2011 17:12:18 +0000 (19:12 +0200)
28 files changed:
akiko.cpp
audio.cpp
cdtv.cpp
cfgfile.cpp
cia.cpp
custom.cpp
drawing.cpp
include/events_jit.h
include/events_normal.h
include/uae.h
include/xwin.h
jit/compemu.h
newcpu.cpp
od-win32/blkdev_win32_aspi.cpp
od-win32/blkdev_win32_ioctl.cpp
od-win32/blkdev_win32_spti.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/dxwrap.cpp
od-win32/dxwrap.h
od-win32/sounddep/sound.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32_scaler.cpp
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt
sana2.cpp

index 1ab88a1420d0192499377db7220b31cea41fa889..619b5bb08c27e4528409e09c0e8f11b0a8cc2f44 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -400,7 +400,7 @@ static uae_u8 qcode_buf[SUBQ_SIZE];
 static int qcode_valid;
 
 static int cdrom_disk, cdrom_paused, cdrom_playing, cdrom_audiostatus;
-static int cdrom_command_active;
+static int cdrom_command_active, cdrom_command_startdelay, cdrom_command_idle;
 static int cdrom_command_length;
 static int cdrom_checksum_error, cdrom_unknown_command;
 static int cdrom_data_offset, cdrom_speed, cdrom_sector_counter;
@@ -435,6 +435,10 @@ static void checkint (void)
 
 static void set_status (uae_u32 status)
 {
+#if AKIKO_DEBUG_IO
+       if (!(cdrom_intreq & status))
+               write_log (L"Akiko INTREQ %08x (%08x)\n", status, cdrom_intreq | status);
+#endif
        cdrom_intreq |= status;
        checkint ();
        cdrom_led ^= LED_CD_ACTIVE2;
@@ -767,6 +771,14 @@ static int cdrom_command_led (void)
        return 0;
 }
 
+static int cdrom_command_idle_status (void)
+{
+       cdrom_result_buffer[0] = 0x0a;
+       cdrom_result_buffer[1] = 0x70;
+       write_log (L"X");
+       return 2;
+}
+
 static int cdrom_command_media_status (void)
 {
        cdrom_result_buffer[0] = 0x0a;
@@ -948,16 +960,20 @@ static void cdrom_run_command (void)
 
        if (!(cdrom_flags & CDFLAG_TXD))
                return;
+       if (cdrom_command_startdelay)
+               return;
        for (;;) {
                if (cdrom_command_active)
                        return;
                if (cdcomtxinx == cdcomtxcmp)
                        return;
                cdrom_command = get_byte (cdtx_address + cdcomtxinx);
+#if 1
                if ((cdrom_command & 0xf0) == 0) {
                        cdcomtxinx = (cdcomtxinx + 1) & 0xff;
                        return;
                }
+#endif
                cdrom_checksum_error = 0;
                cdrom_unknown_command = 0;
 
@@ -1050,7 +1066,7 @@ static void cdrom_run_read (void)
        int i, sector, inc;
        int read = 0;
        int sec;
-       static int seccnt;
+       int seccnt;
 
        if (!(cdrom_flags & CDFLAG_ENABLE))
                return;
@@ -1094,8 +1110,8 @@ static void cdrom_run_read (void)
                if (sector_buffer_info_1[sec] != 0xff)
                        sector_buffer_info_1[sec]--;
 #if AKIKO_DEBUG_IO_CMD
-               write_log (L"read sector=%d, scnt=%d -> %d. %08X\n",
-                       cdrom_data_offset, cdrom_sector_counter, sector, cdrom_addressdata + seccnt * 4096);
+               write_log (L"read sector=%d, scnt=%d -> %d. %d %08X\n",
+                       cdrom_data_offset, cdrom_sector_counter, sector, seccnt, cdrom_addressdata + seccnt * 4096);
 #endif
        } else {
                inc = 0;
@@ -1161,6 +1177,15 @@ static void akiko_internal (void)
                if (!cdrom_command_active)
                        cdrom_run_command_run ();
        }
+#if 0
+       if (!cdrom_playing && !cdrom_command_active) {
+               cdrom_command_idle++;
+               if (cdrom_command_idle > 1000) {
+                       cdrom_command_idle = 0;
+                       cdrom_start_return_data (cdrom_command_idle_status ());
+               }
+       }
+#endif
 }
 
 void AKIKO_hsync_handler (void)
@@ -1168,6 +1193,10 @@ void AKIKO_hsync_handler (void)
        if (!currprefs.cs_cd32cd || !akiko_inited)
                return;
 
+       if (cdrom_command_startdelay > 0) {
+               cdrom_command_startdelay--;
+       }
+
        static float framecounter;
        framecounter--;
        if (framecounter <= 0) {
@@ -1520,7 +1549,7 @@ static void akiko_bput2 (uaecptr addr, uae_u32 v, int msg)
        case 0x12:
        case 0x13:
                akiko_put_long (&cdrom_addressdata, addr - 0x10, v);
-               cdrom_addressdata &= 0x00ff0000;
+               cdrom_addressdata &= 0x00fff000;
                break;
        case 0x14:
        case 0x15:
@@ -1538,6 +1567,8 @@ static void akiko_bput2 (uaecptr addr, uae_u32 v, int msg)
        case 0x1d:
                cdrom_intreq &= ~CDINTERRUPT_TXDMADONE;
                cdcomtxcmp = v;
+               if (cdrom_command_active == 0)
+                       cdrom_command_startdelay = 2;
                break;
        case 0x1f:
                cdrom_intreq &= ~CDINTERRUPT_RXDMADONE;
index 4d426129648d3281719cd9836de105908a78bcdf..6d573dc5b0f1ea69e956018f41912bf0a26070f7 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -63,12 +63,19 @@ static bool debugchannel (int ch)
        return ((1 << ch) & DEBUG_CHANNEL_MASK) != 0;
 }
 
-STATIC_INLINE bool usehacks (void)
+STATIC_INLINE bool usehacks1 (void)
+{
+       return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0;
+}
+
+#if 0
+STATIC_INLINE bool usehacks2 (void)
 {
        if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68020)
                return false;
        return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0;
 }
+#endif
 
 #define SINC_QUEUE_MAX_AGE 2048
 /* Queue length 128 implies minimum emulated period of 16. I add a few extra
@@ -107,6 +114,9 @@ struct audio_channel_data {
        bool have_dat;
        int per_original;
 #endif
+       /* too fast cpu fixes */
+       uaecptr ptx;
+       bool ptx_written;
 };
 
 static int samplecnt;
@@ -1155,6 +1165,10 @@ static void newsample (int nr, sample8_t sample)
 #if DEBUG_AUDIO > 0
        if (!debugchannel (nr))
                sample = 0;
+#endif
+#if DEBUG_AUDIO > 1
+       if (debugchannel (nr))
+               write_log (L"SAMPLE%d: %02x\n", nr, sample & 0xff);
 #endif
        if (!(audio_channel_mask & (1 << nr)))
                sample = 0;
@@ -1227,7 +1241,7 @@ STATIC_INLINE void loadper (int nr)
 
        cdp->evtime = cdp->per;
        if (cdp->evtime < CYCLE_UNIT)
-               write_log (L"loadper%d bug %d\n", nr, cdp->evtime);
+               write_log (L"LOADPER%d bug %d\n", nr, cdp->evtime);
 }
 
 
@@ -1249,7 +1263,7 @@ static void audio_state_channel2 (int nr, bool perfin)
        }
        audio_activate ();
 
-       if ((cdp->state == 2 || cdp->state == 3) && usehacks () && !chan_ena && old_dma) {
+       if ((cdp->state == 2 || cdp->state == 3) && usehacks1 () && !chan_ena && old_dma) {
                // DMA switched off, state=2/3 and "too fast CPU": kill DMA instantly
                // or CPU timed DMA wait routines in common tracker players will lose notes
 #if DEBUG_AUDIO > 0
@@ -1276,27 +1290,23 @@ static void audio_state_channel2 (int nr, bool perfin)
                        cdp->dr = true;
                        cdp->drhpos = hpos;
                        cdp->wlen = cdp->len;
-                       // too fast CPU and some tracker players: enable DMA, CPU delay, update AUDxPT with loop position
-                       if (usehacks ()) {
-                               // copy AUDxPT - 2 to internal latch instantly
-                               cdp->pt = cdp->lc - 2;
-                               cdp->dsr = false;
-                       } else {
-                               // normal hardware behavior: latch it after first DMA fetch comes
-                               cdp->dsr = true;
-                       }
+                       cdp->ptx_written = false;
+                       cdp->dsr = true;
 #if TEST_AUDIO > 0
                        cdp->have_dat = false;
 #endif
 #if DEBUG_AUDIO > 0
-                       if (debugchannel (nr))
+                       if (debugchannel (nr)) {
                                write_log (L"%d:0>1: LEN=%d PC=%08x\n", nr, cdp->wlen, M68K_GETPC);
+                               if (cdp->wlen == 1)
+                                       write_log (L"*");
+                       }
 #endif
                } else if (cdp->dat_written && !isirq (nr)) {
                        cdp->state = 2;
                        setirq (nr, 0);
                        loaddat (nr);
-                       if (usehacks () && cdp->per < 10 * CYCLE_UNIT) {
+                       if (usehacks1 () && cdp->per < 10 * CYCLE_UNIT) {
                                // make sure audio.device AUDxDAT startup returns to idle state before DMA is enabled
                                newsample (nr, (cdp->dat2 >> 0) & 0xff);
                                zerostate (nr);
@@ -1343,6 +1353,10 @@ static void audio_state_channel2 (int nr, bool perfin)
                if (debugchannel (nr))
                        write_log (L"%d:>5: LEN=%d PT=%08X PC=%08X\n", nr, cdp->wlen, cdp->pt, M68K_GETPC);
 #endif
+               if (cdp->ptx_written) {
+                       cdp->ptx_written = 0;
+                       cdp->lc = cdp->ptx;
+               }
                loaddat (nr);
                if (napnav)
                        setdr (nr);
@@ -1782,9 +1796,10 @@ void AUDxDAT (int nr, uae_u16 v, uaecptr addr)
        int chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr));
 
 #if DEBUG_AUDIO > 0
-       if (debugchannel (nr) && (DEBUG_AUDIO > 1 || (!chan_ena || addr == 0xffffffff || (cdp->state != 2 && cdp->state != 3))))
+       if (debugchannel (nr) && (DEBUG_AUDIO > 1 || (!chan_ena || addr == 0xffffffff || (cdp->state != 2 && cdp->state != 3)))) {
                write_log (L"AUD%dDAT: %04X ADDR=%08X LEN=%d/%d %d,%d,%d %06X\n", nr,
                v, addr, cdp->wlen, cdp->len, cdp->state, chan_ena, isirq (nr) ? 1 : 0, M68K_GETPC);
+       }
 #endif
        cdp->dat = v;
        cdp->dat_written = true;
@@ -1837,7 +1852,15 @@ void AUDxLCH (int nr, uae_u16 v)
        struct audio_channel_data *cdp = audio_channel + nr;
        audio_activate ();
        update_audio ();
-       cdp->lc = (cdp->lc & 0xffff) | ((uae_u32)v << 16);
+
+       // someone wants to update PT but DSR has not yet been processed.
+       // too fast CPU and some tracker players: enable DMA, CPU delay, update AUDxPT with loop position
+       if (usehacks1 () && ((cdp->dsr && cdp->state == 1) || cdp->ptx_written)) {
+               cdp->ptx = cdp->lc;
+               cdp->ptx_written = true;
+       } else {
+               cdp->lc = (cdp->lc & 0xffff) | ((uae_u32)v << 16);
+       }
 #if DEBUG_AUDIO > 0
        if (debugchannel (nr))
                write_log (L"AUD%dLCH: %04X %08X\n", nr, v, M68K_GETPC);
@@ -1849,7 +1872,12 @@ void AUDxLCL (int nr, uae_u16 v)
        struct audio_channel_data *cdp = audio_channel + nr;
        audio_activate ();
        update_audio ();
-       cdp->lc = (cdp->lc & ~0xffff) | (v & 0xFFFE);
+       if (usehacks1 () && ((cdp->dsr && cdp->state == 1) || cdp->ptx_written)) {
+               cdp->ptx = cdp->lc;
+               cdp->ptx_written = true;
+       } else {
+               cdp->lc = (cdp->lc & ~0xffff) | (v & 0xFFFE);
+       }
 #if DEBUG_AUDIO > 0
        if (debugchannel (nr))
                write_log (L"AUD%dLCL: %04X %08X\n", nr, v, M68K_GETPC);
@@ -1953,7 +1981,7 @@ void audio_vsync (void)
 {
 #if SOUNDSTUFF > 0
        int max, min;
-       int vsync = isfullscreen () > 0 && currprefs.gfx_avsync;
+       int vsync = isvsync ();
        static int lastdir;
 
        if (!vsync) {
index 08ed12e02ba0471d2fa7184a389afa66a9aa23e6..211ec5ada8ecf893a260131483ab11b84f7de493 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -1728,7 +1728,7 @@ void cdtv_init (void)
                init_comm_pipe (&requests, 100, 1);
                uae_start_thread (L"cdtv", dev_thread, NULL, NULL);
                while (!thread_alive)
-                       sleep_millis(10);
+                       sleep_millis (10);
                uae_sem_init (&sub_sem, 0, 1);
        }
        write_comm_pipe_u32 (&requests, 0x0104, 1);
index 190a2a2d8085f3fc1fdf4e12ff618386d33341f4..860fe3819911c3a89205ccbbee62049fd0fe127a 100644 (file)
@@ -1017,7 +1017,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        if (p->m68k_speed > 0)
                cfgfile_write (f, L"finegrain_cpu_speed", L"%d", p->m68k_speed);
        else
-               cfgfile_write_str (f, L"cpu_speed", p->m68k_speed == -1 ? L"max" : L"real");
+               cfgfile_write_str (f, L"cpu_speed", p->m68k_speed < 0 ? L"max" : L"real");
 
        /* do not reorder start */
        write_compatibility_cpu(f, p);
diff --git a/cia.cpp b/cia.cpp
index b2f82b99948de1f3016120ad8d35a4a951ccd33e..8526a1a7586e48b7bd27688010d1e91f25285ce4 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -1974,7 +1974,7 @@ uae_u8 *save_keyboard (int *len, uae_u8 *dstptr)
        if (dstptr)
                dstbak = dst = dstptr;
        else
-               dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1);
+               dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1 + 1);
        save_u32 (getcapslockstate () ? 1 : 0);
        save_u32 (1);
        save_u8 (kbstate);
index 8420bbe764dd7df1a84f764cf895a4680b12a65a..d2f917418a02620b7d5b9c9d53f8945266d18a20 100644 (file)
@@ -411,7 +411,7 @@ int rpt_available = 0;
 
 void reset_frame_rate_hack (void)
 {
-       if (currprefs.m68k_speed != -1)
+       if (currprefs.m68k_speed >= 0)
                return;
 
        if (! rpt_available) {
@@ -2727,13 +2727,6 @@ static int islinetoggle (void)
        return linetoggle;
 }
 
-static int isvsync (void)
-{
-       if (picasso_on || !currprefs.gfx_avsync || (currprefs.gfx_avsync == 0 && !currprefs.gfx_afullscreen))
-               return 0;
-       return currprefs.gfx_avsyncmode == 0 ? 1 : -1;
-}
-
 int vsynctime_orig;
 
 void compute_vsynctime (void)
@@ -5119,31 +5112,46 @@ static void framewait (void)
                int freetime;
                extern int extraframewait;
                vsyncmintime = vsynctime;
-               render_screen ();
-               vsync_busywait (&freetime);
+               
+               if (vs == -2) {
 
-               curr_time = read_processor_time ();
-               vsyncmintime = curr_time + vsynctime * 8 / 10;
+                       show_screen ();
+                       vsync_busywait_end ();
+                       vsync_busywait_do (&freetime);
+                       curr_time = read_processor_time ();
+                       vsyncmintime = curr_time + vsynctime;
+                       render_screen ();
+                       vsync_busywait_start ();
+
+               } else {
+
+                       render_screen ();
+                       vsync_busywait_do (&freetime);
+                       curr_time = read_processor_time ();
+                       vsyncmintime = curr_time + vsynctime;
+                       show_screen ();
+                       if (extraframewait)
+                               sleep_millis (extraframewait);
 
-               show_screen ();
-               if (extraframewait) {
-                       sleep_millis (extraframewait);
                }
                return;
        }
-       render_screen ();
+       bool didrender = false;
+       if (!picasso_on)
+               didrender = render_screen ();
        for (;;) {
                double v = rpt_vsync () / (syncbase / 1000.0);
                if (v >= -4)
                        break;
-               sleep_millis (2);
+               sleep_millis_main (2);
        }
        curr_time = start = read_processor_time ();
        while (rpt_vsync () < 0);
        curr_time = read_processor_time ();
        vsyncmintime = curr_time + vsynctime;
        idletime += read_processor_time() - start;
-       show_screen ();
+       if (didrender)
+               show_screen ();
 }
 
 static frame_time_t frametime2;
@@ -5231,6 +5239,11 @@ static void vsync_handler_pre (void)
 // emulated hardware vsync
 static void vsync_handler_post (void)
 {
+       static frame_time_t prevtime;
+
+       //write_log (L"%d %d %d\n", vsynctime, read_processor_time () - vsyncmintime, read_processor_time () - prevtime);
+       prevtime = read_processor_time ();
+
        fpscounter ();
 
        if (!isvsync ()
@@ -5241,7 +5254,7 @@ static void vsync_handler_post (void)
 #ifdef JIT
                        if (!currprefs.cachesize) {
 #endif
-                               if (currprefs.m68k_speed == -1) {
+                               if (currprefs.m68k_speed < 0) {
                                        frame_time_t curr_time = read_processor_time ();
                                        vsyncmintime += vsynctime;
                                        /* @@@ Mathias? How do you think we should do this? */
@@ -5250,8 +5263,8 @@ static void vsync_handler_post (void)
                                        if ((long int)(curr_time - vsyncmintime) > 0 || rpt_did_reset)
                                                vsyncmintime = curr_time + vsynctime;
                                        rpt_did_reset = 0;
-                                       render_screen ();
-                                       show_screen ();
+                                       if (render_screen ())
+                                               show_screen ();
                                } else if (rpt_available) {
                                        framewait ();
                                }
@@ -5317,7 +5330,7 @@ static long int diff32 (frame_time_t x, frame_time_t y)
 }
 static void frh_handler (void)
 {
-       if (currprefs.m68k_speed == -1) {
+       if (currprefs.m68k_speed < 0) {
                frame_time_t curr_time = read_processor_time ();
                vsyncmintime += vsynctime * N_LINES / maxvpos_nom;
                /* @@@ Mathias? How do you think we should do this? */
@@ -5330,7 +5343,7 @@ static void frh_handler (void)
                /* Allow this to be one frame's worth of cycles out */
                while (diff32 (curr_time, vsyncmintime + vsynctime) > 0) {
                        vsyncmintime += vsynctime * N_LINES / maxvpos_nom;
-                       if (currprefs.turbo_emulation)
+                       if (currprefs.turbo_emulation || thread_vblank_found)
                                break;
                }
        }
@@ -5555,7 +5568,7 @@ static void set_hpos (void)
 }
 
 // this finishes current line
-static void hsync_handler_pre (bool isvsync)
+static void hsync_handler_pre (bool onvsync)
 {
        int hpos = current_hpos ();
 
@@ -5619,7 +5632,7 @@ static void hsync_handler_pre (bool isvsync)
        vpos_count++;
        if (vpos >= maxvpos_total)
                vpos = 0;
-       if (isvsync) {
+       if (onvsync) {
                vpos = 0;
                vsync_counter++;
        }
@@ -5635,7 +5648,7 @@ static void hsync_handler_pre (bool isvsync)
 }
 
 // this prepares for new line
-static void hsync_handler_post (bool isvsync)
+static void hsync_handler_post (bool onvsync)
 {
        last_copper_hpos = 0;
 #ifdef CPUEMU_12
@@ -5653,7 +5666,7 @@ static void hsync_handler_post (bool isvsync)
                        CIA_vsync_posthandler (1);
                        cia_hsync += ((MAXVPOS_PAL * MAXHPOS_PAL * 50 * 256) / (maxhpos * (currprefs.cs_ciaatod == 2 ? 60 : 50)));
                }
-       } else if (currprefs.cs_ciaatod == 0 && isvsync) {
+       } else if (currprefs.cs_ciaatod == 0 && onvsync) {
                CIA_vsync_posthandler (ciasyncs);
        }
 
@@ -5676,7 +5689,7 @@ static void hsync_handler_post (bool isvsync)
                }
        }
 
-       if (isvsync) {
+       if (onvsync) {
                // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely
                if ((bplcon0 & 8) && !lightpen_triggered) {
                        vpos_lpen = vpos - 1;
@@ -5727,7 +5740,7 @@ static void hsync_handler_post (bool isvsync)
 
 #ifdef JIT
        if (currprefs.cachesize) {
-               if (currprefs.m68k_speed == -1) {
+               if (currprefs.m68k_speed < 0) {
                        static int count = 0;
                        count++;
                        if (trigger_frh (count)) {
@@ -5739,7 +5752,7 @@ static void hsync_handler_post (bool isvsync)
                }
        } else {
 #endif
-               is_lastline = vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed == -1;
+               is_lastline = vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed < 0;
 #ifdef JIT
        }
 #endif
index 43d095c874e0f574d37e0cab9b8f4a3268c34fb0..a5cec3072922c0576783b160c2c553420af66756 100644 (file)
@@ -1836,7 +1836,7 @@ STATIC_INLINE void do_flush_screen (struct vidbuffer *vb, int start, int stop)
        unlockscr (vb);
        if (start <= stop)
                flush_screen (vb, start, stop);
-       else if (currprefs.gfx_afullscreen == GFX_FULLSCREEN && currprefs.gfx_avsync)
+       else if (isvsync ())
                flush_screen (vb, 0, 0); /* vsync mode */
 }
 
@@ -2771,7 +2771,7 @@ void vsync_handle_redraw (int long_frame, int lof_changed)
                else if (currprefs.cpu_cycle_exact)
                        init_hardware_for_drawing_frame ();
        } else {
-               if (currprefs.gfx_afullscreen == GFX_FULLSCREEN && currprefs.gfx_avsync)
+               if (isvsync ())
                        flush_screen (gfxvidinfo.inbuffer, 0, 0); /* vsync mode */
        }
        gui_flicker_led (-1, 0, 0);
@@ -2926,3 +2926,11 @@ void drawing_init (void)
        reset_drawing ();
 }
 
+int isvsync (void)
+{
+       if (picasso_on || !currprefs.gfx_avsync || (currprefs.gfx_avsync == 0 && !currprefs.gfx_afullscreen))
+               return 0;
+       if (currprefs.gfx_avsyncmode == 0)
+               return 1;
+       return currprefs.m68k_speed < 0 ? -2 : -1;
+}
index d32a6bb61292c1c4c9698a855daa8523f56a2a4c..3f5bac885a66691def6367b8a7dc18b802aa7515 100644 (file)
@@ -58,8 +58,13 @@ STATIC_INLINE void set_cycles (unsigned long int x)
 #endif
 }
 
+extern volatile bool thread_vblank_found;
+
 STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add)
 {
+       if (thread_vblank_found && pissoff > 0)
+               cycles_do_special ();
+
        if ((pissoff -= cycles_to_add) >= 0)
                return;
 
@@ -71,7 +76,7 @@ STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add)
                int v = rpt - vsyncmintime;
                if (v > (int)syncbase || v < -((int)syncbase))
                        vsyncmintime = rpt;
-               if (v < 0) {
+               if (v < 0 && !thread_vblank_found && !currprefs.turbo_emulation) {
                        pissoff = pissoff_value * CYCLE_UNIT;
                        return;
                }
index 8c55ef041b55445c96653806b2dc042662747505..bc1a849518bd24b7f254ff72405cb8ba5d395621 100644 (file)
@@ -21,10 +21,12 @@ STATIC_INLINE void events_schedule (void)
        nextevent = currcycle + mintime;
 }
 
+extern volatile bool thread_vblank_found;
+
 STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add)
 {
        if (is_lastline && eventtab[ev_hsync].evtime - currcycle <= cycles_to_add
-               && (long int)(read_processor_time () - vsyncmintime) < 0)
+               && (long int)(read_processor_time () - vsyncmintime) < 0 && !thread_vblank_found)
                return;
 
        while ((nextevent - currcycle) <= cycles_to_add) {
index 92c530393b657ef3f4f5c0fe3b177fba5bc1ef65..68756c2ccfba5a04e5d4fe7a7dc477227b2f6312 100644 (file)
@@ -14,6 +14,7 @@ extern void real_main (int, TCHAR **);
 extern void usage (void);
 extern void parse_cmdline (int argc, TCHAR **argv);
 extern void sleep_millis (int ms);
+extern void sleep_millis_main (int ms);
 extern void sleep_millis_busy (int ms);
 extern int sleep_resolution;
 
index 9fa170479a5be3270746aaa3c147821fb85fea77..b5e43d0b3ab033a570c2ae87e3a0964f98674583 100644 (file)
@@ -26,11 +26,14 @@ extern void toggle_fullscreen (int);
 extern void toggle_mousegrab (void);
 extern void desktop_coords (int *dw, int *dh, int *x, int *y, int *w, int *h);
 extern bool vsync_switchmode (int);
-extern bool vsync_busywait (int*);
+extern void vsync_busywait_end (void);
+extern bool vsync_busywait_do (int*);
+extern void vsync_busywait_start (void);
 extern double vblank_calibrate (double, bool);
 extern void doflashscreen (void);
 extern int flashscreen;
 extern void updatedisplayarea (void);
+extern int isvsync (void);
 
 extern void flush_line (struct vidbuffer*, int);
 extern void flush_block (struct vidbuffer*, int, int);
@@ -91,6 +94,7 @@ struct vidbuffer
        uae_u8 *bufmem, *bufmemend;
     uae_u8 *realbufmem;
        bool bufmem_allocated;
+       bool bufmem_lockable;
     int rowbytes; /* Bytes per row in the memory pointed at by bufmem. */
     int pixbytes; /* Bytes per pixel. */
        /* size of this buffer */
index b15051dee83d823bb1b05144a1abb1ad4e137786..7b7677f5eb1321334505866d9a08e1ef5a52d62b 100644 (file)
@@ -102,7 +102,7 @@ extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles);
 extern int check_for_cache_miss(void);
 
 
-#define scaled_cycles(x) (currprefs.m68k_speed==-1?(((x)/SCALE)?(((x)/SCALE<MAXCYCLES?((x)/SCALE):MAXCYCLES)):1):(x))
+#define scaled_cycles(x) (currprefs.m68k_speed<0?(((x)/SCALE)?(((x)/SCALE<MAXCYCLES?((x)/SCALE):MAXCYCLES)):1):(x))
 
 
 extern uae_u32 needed_flags;
index ab6bd6c2e80a746a89911b17ed87bddd437ea318..d7bdd2d204b6ed94fd975d2d8cd59c1ae6e23a20 100644 (file)
@@ -3388,7 +3388,7 @@ STATIC_INLINE int do_specialties (int cycles)
                                        lvpos = vpos;
                                        if (sleepcnt < 0) {
                                                sleepcnt = IDLETIME / 2;
-                                               sleep_millis (1);
+                                               sleep_millis_main (1);
                                        }
                                }
                        }
index f508ca798c0f871e7998671f9df8fddc0a38d019..64a09acd82234bcaa7c8b982163eb9abd81a741e 100644 (file)
@@ -995,7 +995,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
        return di;
 }
 
-void win32_aspi_media_change (TCHAR driveletter, int insert)
+bool win32_aspi_media_change (TCHAR driveletter, int insert)
 {
        int i, now;
 
@@ -1006,9 +1006,11 @@ void win32_aspi_media_change (TCHAR driveletter, int insert)
                                write_log (L"ASPI: media change %c %d\n", driveletter, insert);
                                si[i].mediainserted = now;
                                scsi_do_disk_change (i + 1, insert, NULL);
+                               return true;
                        }
                }
        }
+       return false;
 }
 
 static int check_isatapi (int unitnum)
index 61752f525afe253b91fb4b8cb26740c93a324690..cdcacc05d47685b56619d2dc84faff43dcc0abec 100644 (file)
@@ -1388,7 +1388,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
        return di;
 }
 
-void win32_ioctl_media_change (TCHAR driveletter, int insert)
+bool win32_ioctl_media_change (TCHAR driveletter, int insert)
 {
        for (int i = 0; i < total_devices; i++) {
                struct dev_info_ioctl *ciw = &ciw32[i];
@@ -1400,9 +1400,11 @@ void win32_ioctl_media_change (TCHAR driveletter, int insert)
                                update_device_info (unitnum);
                                scsi_do_disk_change (unitnum, insert, NULL);
                                blkdev_cd_change (unitnum, ciw->drvlettername);
+                               return true;
                        }
                }
        }
+       return false;
 }
 
 static int ioctl_scsiemu (int unitnum, uae_u8 *cmd)
index e160521bdeb604bcd9c8caa5557702cb175a86b0..30314e36253862218ba116d0ec4f2ef73e4f9106 100644 (file)
@@ -652,7 +652,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
        return di;
 }
 
-void win32_spti_media_change (TCHAR driveletter, int insert)
+bool win32_spti_media_change (TCHAR driveletter, int insert)
 {
        for (int i = 0; i < total_devices; i++) {
                struct dev_info_spti *di = &dev_info[i];
@@ -664,9 +664,11 @@ void win32_spti_media_change (TCHAR driveletter, int insert)
                                update_device_info (unitnum);
                                scsi_do_disk_change (unitnum, insert, NULL);
                                blkdev_cd_change (unitnum, di->drvletter ? di->drvlettername : di->name);
+                               return true;
                        }
                }
        }
+       return false;
 }
 
 static int check_isatapi (int unitnum)
index 89681f3f33921e6a5e983e3ff1fbe6f6257916b2..9ba0fcff985f17775057b33510b14a6c6b5e3b40 100644 (file)
@@ -1852,8 +1852,6 @@ static bool getvblankstate (int *vpos)
                return false;
        }
        *vpos = rt.ScanLine;
-       if (rt.ScanLine > maxscanline)
-               maxscanline = rt.ScanLine;
        if (rt.InVBlank != 0)
                *vpos = -1;
        return true;
@@ -1892,6 +1890,20 @@ bool D3D_vblank_busywait (void)
        }
 }
 
+bool D3D_vblank_getstate (bool *state)
+{
+       int vpos;
+       if (!getvblankstate (&vpos))
+               return false;
+       if (vpos <= 0 || vpos >= maxscanline - 5) {
+               *state = true;
+               return true;
+       }
+       *state = false;
+       return true;
+}
+
+
 const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth, int mmult)
 {
        HRESULT ret, hr;
@@ -1903,7 +1915,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        HINSTANCE d3dDLL, d3dx;
        typedef HRESULT (WINAPI *LPDIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
        LPDIRECT3DCREATE9EX d3dexp = NULL;
-       bool newvsync = currprefs.gfx_avsync && currprefs.gfx_avsyncmode && !picasso_on;
+       int vsync = isvsync ();
 
 
        D3D_free2 ();
@@ -1977,12 +1989,12 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        memset (&dpp, 0, sizeof (dpp));
        dpp.Windowed = isfullscreen () <= 0;
        dpp.BackBufferFormat = mode.Format;
-       dpp.BackBufferCount = newvsync ? 0 : currprefs.gfx_backbuffers;
+       dpp.BackBufferCount = vsync == -1 ? 0 : (vsync == -2 ? 2 : currprefs.gfx_backbuffers);
        dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
        dpp.BackBufferWidth = w_w;
        dpp.BackBufferHeight = w_h;
-       dpp.PresentationInterval = (dpp.Windowed || currprefs.gfx_backbuffers == 0 || newvsync) ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;
+       dpp.PresentationInterval = (dpp.Windowed || dpp.BackBufferCount == 0 || vsync == -1) ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;
 
        modeex.Width = w_w;
        modeex.Height = w_h;
@@ -2152,7 +2164,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        maxscanline = 0;
        d3d_enabled = 1;
 
-       if (newvsync) {
+       if (vsync == -1) {
                hr = d3ddev->CreateQuery(D3DQUERYTYPE_EVENT, &query);
                if (FAILED (hr))
                        write_log (L"%s: CreateQuery(D3DQUERYTYPE_EVENT) failed: %s\n", D3DHEAD, D3D_ErrorString (hr));
index 5139bd17e5ab10933f86437493d7b86d18cd91af..f903b5cd7216e48e883d4ab60e243071b4b51bae 100644 (file)
@@ -18,6 +18,7 @@ extern int D3D_goodenough (void);
 extern void D3D_setcursor (int x, int y, int visible);
 extern bool D3D_vblank_busywait (void);
 extern bool D3D_waitvblankstate (bool);
+extern bool D3D_vblank_getstate (bool *state);
 extern double D3D_getrefreshrate (void);
 extern LPDIRECT3DTEXTURE9 cursorsurfaced3d;
 
index df949e16804af86bdd5d3d9c1aa3f146a619d2f7..ac55064d4377c39fe72e3f4ff74792cece4035c7 100644 (file)
@@ -1184,8 +1184,7 @@ bool DirectDraw_waitvblankstate (bool state)
        BOOL vb;
        HRESULT hr;
 
-       dx_check ();
-       if (dxdata.islost)
+       if ((dxdata.primary == NULL && dxdata.fsmodeset > 0) || dxdata.islost || !dxdata.maindd)
                return false;
        for (;;) {
                hr = IDirectDraw7_GetVerticalBlankStatus (dxdata.maindd, &vb);
@@ -1204,3 +1203,19 @@ bool DirectDraw_vblank_busywait (void)
                return false;
        return true;
 }
+
+bool DirectDraw_getvblankstate (bool *state)
+{
+       BOOL vb;
+       HRESULT hr;
+
+       if ((dxdata.primary == NULL && dxdata.fsmodeset > 0) || dxdata.islost || !dxdata.maindd)
+               return false;
+       hr = IDirectDraw7_GetVerticalBlankStatus (dxdata.maindd, &vb);
+       if (FAILED (hr)) {
+               write_log (L"IDirectDraw7_GetVerticalBlankStatus %s\n", DXError (hr));
+               return false;
+       }
+       *state = vb != 0;
+       return true;
+}
index 23af467dbf0c7c60de9d2c06a10d59613615c378..f683b9da61d671ea8635dde21413214f4988f9aa 100644 (file)
@@ -132,6 +132,7 @@ void DirectDraw_Fill (RECT *rect, uae_u32 color);
 void DirectDraw_FillPrimary (void);
 bool DirectDraw_vblank_busywait (void);
 bool DirectDraw_waitvblankstate (bool);
+bool DirectDraw_getvblankstate (bool*);
 
 void dx_check (void);
 int dx_islost (void);
index f17286f26e9d8490911bc05c100ae9dc4419ee57..6a8e1d66e20580f6fbd0225c8bd31a94fde70b8b 100644 (file)
@@ -27,6 +27,7 @@
 #include "savestate.h"
 #include "driveclick.h"
 #include "gensound.h"
+#include "xwin.h"
 
 #include <windows.h>
 #include <mmsystem.h>
@@ -143,11 +144,6 @@ int setup_sound (void)
        return 1;
 }
 
-static int isvsync (void)
-{
-       return currprefs.gfx_avsync && currprefs.gfx_afullscreen == GFX_FULLSCREEN;
-}
-
 float scaled_sample_evtime_orig;
 extern float sampler_evtime;
 void update_sound (double freq, int longframe, int linetoggle)
index 89f2872923da92c2e4e4af7e4e83d484c64dec59..3772702e0f59814f7dcdecb7f9d5f1cf23b23270 100644 (file)
@@ -225,13 +225,14 @@ static int init_mmtimer (void)
        return 1;
 }
 
-void sleep_millis (int ms)
+static void sleep_millis2 (int ms, bool main)
 {
        UINT TimerEvent;
-       int start;
+       int start = 0;
        int cnt;
 
-       start = read_processor_time ();
+       if (main)
+               start = read_processor_time ();
        EnterCriticalSection (&cs_time);
        cnt = timehandlecounter++;
        if (timehandlecounter >= MAX_TIMEHANDLES)
@@ -241,8 +242,19 @@ void sleep_millis (int ms)
        WaitForSingleObject (timehandle[cnt], ms);
        ResetEvent (timehandle[cnt]);
        timeKillEvent (TimerEvent);
-       idletime += read_processor_time () - start;
+       if (main)
+               idletime += read_processor_time () - start;
+}
+
+void sleep_millis_main (int ms)
+{
+       sleep_millis2 (ms, true);
 }
+void sleep_millis (int ms)
+{
+       sleep_millis2 (ms, false);
+}
+
 
 frame_time_t read_processor_time_qpf (void)
 {
@@ -1209,9 +1221,9 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam,
                return TRUE;
        case WM_DEVICECHANGE:
                {
-                       extern void win32_spti_media_change (TCHAR driveletter, int insert);
-                       extern void win32_ioctl_media_change (TCHAR driveletter, int insert);
-                       extern void win32_aspi_media_change (TCHAR driveletter, int insert);
+                       extern bool win32_spti_media_change (TCHAR driveletter, int insert);
+                       extern bool win32_ioctl_media_change (TCHAR driveletter, int insert);
+                       extern bool win32_aspi_media_change (TCHAR driveletter, int insert);
                        DEV_BROADCAST_HDR *pBHdr = (DEV_BROADCAST_HDR *)lParam;
                        static int waitfornext;
 
@@ -1245,11 +1257,12 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam,
                                                                else
                                                                        inserted = 0;
                                                                if (pBVol->dbcv_flags & DBTF_MEDIA) {
+                                                                       bool matched = false;
 #ifdef WINDDK
-                                                                       win32_spti_media_change (drive, inserted);
-                                                                       win32_ioctl_media_change (drive, inserted);
+                                                                       matched |= win32_spti_media_change (drive, inserted);
+                                                                       matched |= win32_ioctl_media_change (drive, inserted);
 #endif
-                                                                       win32_aspi_media_change (drive, inserted);
+                                                                       matched |= win32_aspi_media_change (drive, inserted);
                                                                }
                                                                if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM || !inserted) {
                                                                        write_log (L"WM_DEVICECHANGE '%s' type=%d inserted=%d\n", drvname, type, inserted);
@@ -4018,7 +4031,7 @@ static int dxdetect (void)
 #endif
 }
 
-int os_winnt, os_winnt_admin, os_64bit, os_win7, os_vista, os_winxp;
+int os_winnt, os_winnt_admin, os_64bit, os_win7, os_vista, os_winxp, cpu_number;
 
 static int isadminpriv (void)
 {
@@ -4115,6 +4128,7 @@ static int osdetect (void)
                if (SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
                        os_64bit = 1;
        }
+       cpu_number = SystemInfo.dwNumberOfProcessors;
        if (!os_winnt)
                return 0;
        os_winnt_admin = isadminpriv ();
index 98f82df35a1b6b6a31c0665c4bf4ea693f4d80ca..efb1c49799c2d8035d0d8d7349af43e9ea7a0de7 100644 (file)
@@ -20,7 +20,7 @@
 
 //#define WINUAEBETA L""
 #define WINUAEBETA L"Beta 2"
-#define WINUAEDATE MAKEBD(2011, 12, 4)
+#define WINUAEDATE MAKEBD(2011, 12, 11)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
@@ -75,7 +75,7 @@ extern int framecnt;
 extern TCHAR prtname[];
 extern TCHAR VersionStr[256];
 extern TCHAR BetaStr[64];
-extern int os_winnt_admin, os_64bit, os_vista, os_winxp, os_win7;
+extern int os_winnt_admin, os_64bit, os_vista, os_winxp, os_win7, cpu_number;
 extern OSVERSIONINFO osVersion;
 extern int paraport_mask;
 extern int gui_active;
@@ -92,6 +92,7 @@ enum pathtype { PATH_TYPE_DEFAULT, PATH_TYPE_WINUAE, PATH_TYPE_NEWWINUAE, PATH_T
 void setpathmode (pathtype pt);
 
 extern void sleep_millis (int ms);
+extern void sleep_millis_main (int ms);
 extern void sleep_millis_busy (int ms);
 extern void wait_keyrelease (void);
 extern void keyboard_settrans (void);
index 445f839268e27d803ef8ee9c56d3fac5f5871233..51b6ec3dfdd80a5b45e720ea635993cebe472ae1 100644 (file)
@@ -951,7 +951,11 @@ end:
                getfilterrect2 (&dr, &sr, &zr, dst_width, dst_height, aw, ah, scale, temp_width, temp_height);
                //write_log (L"(%d %d %d %d) - (%d %d %d %d) (%d %d)\n", dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, zr.left, zr.top);
                OffsetRect (&sr, zr.left, zr.top);
-               if (sr.left >= 0 && sr.top >= 0 && sr.right < temp_width && sr.bottom < temp_height) {
+               if (sr.left < 0)
+                       sr.left = 0;
+               if (sr.top < 0)
+                       sr.top = 0;
+               if (sr.right < temp_width && sr.bottom < temp_height) {
                        if (sr.left < sr.right && sr.top < sr.bottom)
                                DirectDraw_BlitRect (NULL, &dr, tempsurf, &sr);
                }
index 061b45027415fd1af21b2ea7bd893a7844f61cda..70178ab8a8ac338a6044f6e309f177ccebf6b66d 100644 (file)
@@ -77,6 +77,7 @@
 struct uae_filter *usedfilter;
 static int scalepicasso;
 static double remembered_vblank;
+static volatile int vblankthread_mode, vblankthread_counter;
 
 struct winuae_currentmode {
        unsigned int flags;
@@ -103,12 +104,31 @@ int window_extra_width, window_extra_height;
 
 static struct winuae_currentmode *currentmode = &currentmodestruct;
 static int wasfullwindow_a, wasfullwindow_p;
-static int vblankbasewait, vblankbasefull;
+static int vblankbasewait, vblankbasewait2, vblankbasefull;
 
 int screen_is_picasso = 0;
 
 extern int reopen (int);
 
+#define VBLANKTH_KILL 0
+#define VBLANKTH_CALIBRATE 1
+#define VBLANKTH_IDLE 2
+#define VBLANKTH_ACTIVE_WAIT 3
+#define VBLANKTH_ACTIVE 4
+#define VBLANKTH_ACTIVE_START 5
+
+static void changevblankthreadmode (int newmode)
+{
+       int t = vblankthread_counter;
+       thread_vblank_found = false;
+       if (vblankthread_mode <= 0 || vblankthread_mode == newmode)
+               return;
+       vblankthread_mode = newmode;
+       while (t == vblankthread_counter && vblankthread_mode > 0)
+               sleep_millis (1);
+       thread_vblank_found = false;
+}
+
 int WIN32GFX_IsPicassoScreen (void)
 {
        return screen_is_picasso;
@@ -925,6 +945,7 @@ void unlockscr (struct vidbuffer *vb)
                return;
        } else if (currentmode->flags & DM_DDRAW) {
                DirectDraw_SurfaceUnlock ();
+               gfxvidinfo.outbuffer->bufmem = NULL;
        }
 }
 
@@ -1230,6 +1251,8 @@ static int open_windows (int full)
 {
        int ret, i;
 
+       changevblankthreadmode (VBLANKTH_IDLE);
+
        inputdevice_unacquire ();
        wait_keyrelease ();
        reset_sound ();
@@ -1838,7 +1861,7 @@ static int modeswitchneeded (struct winuae_currentmode *wc)
                                currentmode->current_height != wc->current_height ||
                                currentmode->current_depth != wc->current_depth)
                                return -1;
-                       if (!gfxvidinfo.outbuffer->bufmem_allocated)
+                       if (!gfxvidinfo.outbuffer->bufmem_lockable)
                                return -1;
                }
        } else if (isfullscreen () == 0) {
@@ -1979,6 +2002,7 @@ int graphics_setup (void)
 
 void graphics_leave (void)
 {
+       changevblankthreadmode (VBLANKTH_KILL);
        close_windows ();
 }
 
@@ -1989,6 +2013,7 @@ uae_u32 OSDEP_minimize_uae (void)
 
 void close_windows (void)
 {
+       changevblankthreadmode (VBLANKTH_IDLE);
        reset_sound();
 #if defined (GFXFILTER)
        S2X_free ();
@@ -1996,8 +2021,10 @@ void close_windows (void)
        xfree (gfxvidinfo.drawbuffer.realbufmem);
        xfree (gfxvidinfo.tempbuffer.realbufmem);
        gfxvidinfo.drawbuffer.bufmem_allocated = false;
+       gfxvidinfo.drawbuffer.bufmem_lockable = false;
        gfxvidinfo.drawbuffer.realbufmem = NULL;
        gfxvidinfo.tempbuffer.bufmem_allocated = false;
+       gfxvidinfo.tempbuffer.bufmem_lockable = false;
        gfxvidinfo.tempbuffer.realbufmem = NULL;
        DirectDraw_Release ();
        close_hwnds ();
@@ -2185,7 +2212,7 @@ static int getbestmode (int nextbest)
 }
 
 
-bool waitvblankstate (bool state)
+static bool waitvblankstate (bool state)
 {
        if (currprefs.gfx_api) {
                return D3D_waitvblankstate (state);
@@ -2194,6 +2221,19 @@ bool waitvblankstate (bool state)
        }
 }
 
+static bool getvblankstate (bool *state)
+{
+       if (currprefs.gfx_api) {
+               if (!D3D_vblank_getstate (state))
+                       return false;
+               return true;
+       } else {
+               if (!DirectDraw_getvblankstate (state))
+                       return false;
+               return true;
+       }
+}
+
 double getcurrentvblankrate (void)
 {
        if (remembered_vblank)
@@ -2204,16 +2244,63 @@ double getcurrentvblankrate (void)
                return DirectDraw_CurrentRefreshRate ();
 }
 
+static bool threaded_vsync = false;
+volatile bool thread_vblank_found;
+static volatile frame_time_t vblank_prev_time, thread_vblank_time;
+
 #include <process.h>
-static volatile int dummythread_die;
-int dummy_counter;
-static void _cdecl dummythread (void *dummy)
-{
-       SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_LOWEST);
-       while (!dummythread_die)
-               dummy_counter++;
+
+static void _cdecl vblankthread (void *dummy)
+{
+       while (vblankthread_mode > VBLANKTH_KILL) {
+               vblankthread_counter++;
+               if (vblankthread_mode == VBLANKTH_CALIBRATE) {
+                       // calibrate mode, try to keep CPU power saving inactive
+                       SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_LOWEST);
+                       while (vblankthread_mode == 0)
+                               vblankthread_counter++;
+                       SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_ABOVE_NORMAL);
+               } else if (vblankthread_mode == VBLANKTH_IDLE) {
+                       // idle mode
+                       Sleep(20);
+               } else if (vblankthread_mode == VBLANKTH_ACTIVE_WAIT) {
+                       sleep_millis (1);
+               } else if (vblankthread_mode == VBLANKTH_ACTIVE_START) {
+                       // do not start until vblank has been passed
+                       bool vb = false;
+                       bool ok = getvblankstate (&vb);
+                       if (vb == false)
+                               vblankthread_mode = VBLANKTH_ACTIVE;
+                       else
+                               sleep_millis (1);
+               } else if (vblankthread_mode == VBLANKTH_ACTIVE) {
+                       // busy wait mode
+                       frame_time_t t = read_processor_time ();
+                       bool donotwait = false;
+                       if (!thread_vblank_found) {
+                               if (t - thread_vblank_time > vblankbasewait2) {
+                                       bool vb = false;
+                                       bool ok = getvblankstate (&vb);
+                                       if (!ok || vb) {
+                                               thread_vblank_found = true;
+                                               //write_log (L"%d\n", t - thread_vblank_time);
+                                               thread_vblank_time = t;
+                                       }
+                                       donotwait = true;
+                               }
+                       }
+                       if (t - vblank_prev_time > vblankbasefull * 3)
+                               vblankthread_mode = VBLANKTH_IDLE;
+                       if (!donotwait)
+                               sleep_millis (1);
+               } else {
+                       break;
+               }
+       }
+       vblankthread_mode = -1;
 }
 
+
 double vblank_calibrate (double approx_vblank, bool waitonly)
 {
        frame_time_t t1, t2;
@@ -2221,20 +2308,27 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
        int maxcnt, maxtotal, total, cnt, tcnt2;
        HANDLE th;
        
-       if (remembered_vblank > 0)
+       threaded_vsync = (cpu_number > 1 && currprefs.m68k_speed < 0);
+
+       if (remembered_vblank > 0 && (!threaded_vsync || (threaded_vsync && vblankthread_mode > 0)))
                return remembered_vblank;
        if (waitonly) {
                vblankbasefull = syncbase / approx_vblank;
                vblankbasewait = (syncbase / approx_vblank) * 3 / 4;
+               vblankbasewait2 = (syncbase / approx_vblank) * 5 / 10;
                remembered_vblank = -1;
                return -1;
        }
+
        th = GetCurrentThread ();
        int oldpri = GetThreadPriority (th);
        SetThreadPriority (th, THREAD_PRIORITY_HIGHEST);
-       dummythread_die = -1;
-       dummy_counter = 0;
-       _beginthread (&dummythread, 0, 0);
+       if (vblankthread_mode <= VBLANKTH_KILL) {
+               vblankthread_mode = VBLANKTH_CALIBRATE;
+               _beginthread (&vblankthread, 0, 0);
+       } else {
+               changevblankthreadmode (VBLANKTH_CALIBRATE);
+       }
        sleep_millis (100);
        maxtotal = 10;
        maxcnt = maxtotal;
@@ -2246,28 +2340,28 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                cnt = total;
                for (cnt = 0; cnt < total; cnt++) {
                        if (!waitvblankstate (true))
-                               return -1;
+                               goto fail;
                        if (!waitvblankstate (false))
-                               return -1;
+                               goto fail;
                        if (!waitvblankstate (true))
-                               return -1;
+                               goto fail;
                        t1 = read_processor_time ();
                        if (!waitvblankstate (false))
-                               return -1;
+                               goto fail;
                        if (!waitvblankstate (true))
-                               return -1;
+                               goto fail;
                        t2 = read_processor_time ();
                        tval = (double)syncbase / (t2 - t1);
                        if (cnt == 0)
                                tfirst = tval;
                        if (abs (tval - tfirst) > 1) {
-                               write_log (L"very unstable vsync! %.6f vs %.6f, retrying..\n", tval, tfirst);
+                               write_log (L"Very unstable vsync! %.6f vs %.6f, retrying..\n", tval, tfirst);
                                break;
                        }
                        tsum2 += tval;
                        tcnt2++;
                        if (abs (tval - tfirst) > 0.1) {
-                               write_log (L"unstable vsync! %.6f vs %.6f\n", tval, tfirst);
+                               write_log (L"Unstable vsync! %.6f vs %.6f\n", tval, tfirst);
                                break;
                        }
                        tsum += tval;
@@ -2275,11 +2369,11 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                if (cnt >= total)
                        break;
        }
-       dummythread_die = 0;
+       changevblankthreadmode (VBLANKTH_IDLE);
        SetThreadPriority (th, oldpri);
        if (maxcnt >= maxtotal) {
                tsum = tsum2 / tcnt2;
-               write_log (L"unstable vsync reporting, using average value\n");
+               write_log (L"Unstable vsync reporting, using average value\n");
        } else {
                tsum /= total;
        }
@@ -2287,36 +2381,66 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                tsum /= 2;
        vblankbasefull = (syncbase / tsum);
        vblankbasewait = (syncbase / tsum) * 3 / 4;
-       write_log (L"VSync calibration: %.6fHz\n", tsum);
+       vblankbasewait2 = (syncbase / tsum) * 5 / 10;
+       write_log (L"VSync calibration: %.6fHz. Units = %d Mode = %s\n", tsum, vblankbasefull, threaded_vsync ? L"threaded" : L"normal");
        remembered_vblank = tsum;
+       vblank_prev_time = read_processor_time ();
        return tsum;
+fail:
+       write_log (L"VSync calibration failed\n");
+       changed_prefs.gfx_avsync = 0;
+       return -1;
 }
 
 static int frame_missed, frame_counted, frame_errors;
 static int frame_usage, frame_usage_avg, frame_usage_total;
 extern int log_vsync;
 
-bool vsync_busywait (int *freetime)
+void vsync_busywait_end (void)
+{
+//     frame_time_t t = read_processor_time ();
+
+       changevblankthreadmode (VBLANKTH_ACTIVE_WAIT);
+
+//     write_log (L"%d\n", t - thread_vblank_time);
+
+//     if (t - vblank_prev_time > vblankbasefull + vblankbasefull * 1 / 3) {
+//             frame_missed++;
+//             waitvblankstate (true);
+//     }
+}
+
+void vsync_busywait_start (void)
+{
+       changevblankthreadmode (VBLANKTH_ACTIVE_START);
+       vblank_prev_time = thread_vblank_time;
+}
+
+bool vsync_busywait_do (int *freetime)
 {
        bool v;
-       static frame_time_t prevtime;
        static bool framelost;
+       int ti;
        frame_time_t t;
+       frame_time_t prevtime = vblank_prev_time;
 
-       if (log_vsync) {
-               console_out_f(L"%8d %8d %3d%% (%3d%%)\r", frame_counted, frame_missed, frame_usage, frame_usage_avg);
-       }
-
-       *freetime = 0;
-       if (currprefs.turbo_emulation) {
+       t = read_processor_time ();
+       ti = t - prevtime;
+       if (ti > 2 * vblankbasefull || ti < -2 * vblankbasefull) {
+               waitvblankstate (false);
+               t = read_processor_time ();
+               vblank_prev_time = t;
+               thread_vblank_time = t;
                frame_missed++;
                return true;
        }
 
-       t = read_processor_time ();
+       if (log_vsync) {
+               console_out_f(L"F:%8d M:%8d E:%8d %3d%% (%3d%%) %10d\r", frame_counted, frame_missed, frame_errors, frame_usage, frame_usage_avg, (t - vblank_prev_time) - vblankbasefull);
+       }
 
-       if (!framelost && t - prevtime > vblankbasefull) {
-               framelost = true;
+       *freetime = 0;
+       if (currprefs.turbo_emulation) {
                frame_missed++;
                return true;
        }
@@ -2332,16 +2456,33 @@ bool vsync_busywait (int *freetime)
                frame_usage_avg = frame_usage_total / frame_counted;
 
        v = false;
-       while (!framelost && read_processor_time () - prevtime < vblankbasewait)
-               sleep_millis (1);
-       framelost = false;
-       if (currprefs.gfx_api) {
-               v = D3D_vblank_busywait ();
+
+       if (threaded_vsync) {
+
+               framelost = false;
+               v = true;
+
        } else {
-               v = DirectDraw_vblank_busywait ();
+
+               if (!framelost && t - prevtime > vblankbasefull) {
+                       framelost = true;
+                       frame_missed++;
+                       return true;
+               }
+
+               while (!framelost && read_processor_time () - prevtime < vblankbasewait)
+                       sleep_millis_main (1);
+
+               framelost = false;
+               if (currprefs.gfx_api) {
+                       v = D3D_vblank_busywait ();
+               } else {
+                       v = DirectDraw_vblank_busywait ();
+               }
        }
+
        if (v) {
-               prevtime = read_processor_time ();
+               vblank_prev_time = read_processor_time ();
                frame_counted++;
                return true;
        }
@@ -2606,14 +2747,23 @@ static int set_ddraw (void)
 
 static void allocsoftbuffer(struct vidbuffer *buf, int flags, int width, int height, int depth)
 {
-       if (!(flags & (DM_SWSCALE | DM_D3D)))
-               return;
 
        buf->pixbytes = (depth + 7) / 8;
        buf->width = (width + 7) & ~7;
        buf->height = height;
 
-       if (flags & DM_SWSCALE) {
+       if ((flags & DM_DDRAW) && !(flags & (DM_D3D | DM_SWSCALE))) {
+
+               if (buf != &gfxvidinfo.drawbuffer)
+                       return;
+
+               buf->bufmem = NULL;
+               buf->bufmemend = NULL;
+               buf->realbufmem = NULL;
+               buf->bufmem_allocated = false;
+               buf->bufmem_lockable = true;
+
+       } else if (flags & DM_SWSCALE) {
 
                int w = width * 2;
                int h = height * 2;
@@ -2624,6 +2774,7 @@ static void allocsoftbuffer(struct vidbuffer *buf, int flags, int width, int hei
                buf->rowbytes = w * 2 * buf->pixbytes;
                buf->bufmemend = buf->realbufmem + size - buf->rowbytes;
                buf->bufmem_allocated = true;
+               buf->bufmem_lockable = true;
 
        } else if (flags & DM_D3D) {
 
@@ -2633,6 +2784,8 @@ static void allocsoftbuffer(struct vidbuffer *buf, int flags, int width, int hei
                buf->rowbytes = currentmode->amiga_width * buf->pixbytes;
                buf->bufmemend = buf->bufmem + size;
                buf->bufmem_allocated = true;
+               buf->bufmem_lockable = true;
+
        }
 }
 
@@ -2790,38 +2943,32 @@ static BOOL doInit (void)
        gfxvidinfo.drawbuffer.realbufmem = NULL;
        gfxvidinfo.drawbuffer.bufmem = NULL;
        gfxvidinfo.drawbuffer.bufmem_allocated = false;
+       gfxvidinfo.drawbuffer.bufmem_lockable = false;
 
        gfxvidinfo.outbuffer = &gfxvidinfo.drawbuffer;
        gfxvidinfo.inbuffer = &gfxvidinfo.drawbuffer;
 
        if (!screen_is_picasso) {
-               if ((currentmode->flags & DM_DDRAW) && !(currentmode->flags & (DM_D3D | DM_SWSCALE))) {
-
-                       gfxvidinfo.drawbuffer.bufmem_allocated = true;
-
-               } else {
-
-                       allocsoftbuffer(&gfxvidinfo.drawbuffer, currentmode->flags,
-                               currentmode->current_width > currentmode->amiga_width ? currentmode->current_width : currentmode->amiga_width,
-                               currentmode->current_height > currentmode->amiga_height ? currentmode->current_height : currentmode->amiga_height,
+               allocsoftbuffer(&gfxvidinfo.drawbuffer, currentmode->flags,
+                       currentmode->current_width > currentmode->amiga_width ? currentmode->current_width : currentmode->amiga_width,
+                       currentmode->current_height > currentmode->amiga_height ? currentmode->current_height : currentmode->amiga_height,
+                       currentmode->current_depth);
+               if (currprefs.monitoremu)
+                       allocsoftbuffer(&gfxvidinfo.tempbuffer, currentmode->flags,
+                               currentmode->amiga_width > 1024 ? currentmode->amiga_width : 1024,
+                               currentmode->amiga_height > 1024 ? currentmode->amiga_height : 1024,
                                currentmode->current_depth);
-                       if (currprefs.monitoremu)
-                               allocsoftbuffer(&gfxvidinfo.tempbuffer, currentmode->flags,
-                                       currentmode->amiga_width > 1024 ? currentmode->amiga_width : 1024,
-                                       currentmode->amiga_height > 1024 ? currentmode->amiga_height : 1024,
-                                       currentmode->current_depth);
 
-                       if (currentmode->current_width > gfxvidinfo.drawbuffer.outwidth)
-                               gfxvidinfo.drawbuffer.outwidth = currentmode->current_width;
-                       if (gfxvidinfo.drawbuffer.outwidth > gfxvidinfo.drawbuffer.width)
-                               gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.width;
+               if (currentmode->current_width > gfxvidinfo.drawbuffer.outwidth)
+                       gfxvidinfo.drawbuffer.outwidth = currentmode->current_width;
+               if (gfxvidinfo.drawbuffer.outwidth > gfxvidinfo.drawbuffer.width)
+                       gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.width;
 
-                       if (currentmode->current_height > gfxvidinfo.drawbuffer.outheight)
-                               gfxvidinfo.drawbuffer.outheight = currentmode->current_height;
-                       if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height)
-                               gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height;
+               if (currentmode->current_height > gfxvidinfo.drawbuffer.outheight)
+                       gfxvidinfo.drawbuffer.outheight = currentmode->current_height;
+               if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height)
+                       gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height;
 
-               }
                init_row_map ();
        }
        init_colors ();
index 9d27874ecf458cb796fbadf8e957eb54a76484ec..20b1ae932a9992d81d60ffdc0e5aa1ad6f01e7ef 100644 (file)
@@ -7792,7 +7792,7 @@ static void values_to_cpudlg (HWND hDlg)
        CheckRadioButton (hDlg, IDC_CPU0, IDC_CPU5, cpu_ids[cpu]);
        CheckRadioButton (hDlg, IDC_FPU0, IDC_FPU3, fpu_ids[workprefs.fpu_model == 0 ? 0 : (workprefs.fpu_model == 68881 ? 1 : (workprefs.fpu_model == 68882 ? 2 : 3))]);
 
-       if (workprefs.m68k_speed == -1)
+       if (workprefs.m68k_speed < 0)
                CheckRadioButton(hDlg, IDC_CS_HOST, IDC_CS_ADJUSTABLE, IDC_CS_HOST);
        else if (workprefs.m68k_speed == 0)
                CheckRadioButton(hDlg, IDC_CS_HOST, IDC_CS_ADJUSTABLE, IDC_CS_68000);
index c3deeae8e721ab4c07805c1c7c5226c41ff96ae7..671df7c324f4928d6b5019b7f3ad456565d008b3 100644 (file)
@@ -1,4 +1,22 @@
 
+Beta 3:
+
+- Fixed DirectDraw mode crash (b1)
+- Fixed uaenet.device crash if program attempted to open it but winpcap was not installed. (old)
+- Added CD32 drive emulation hack, CD32 Mutation Gold Compilation games now load (but they didn't work on my real CD32 either so technically
+  not working is correct behavior. This hack is removed if it breaks other programs)
+- Too fast CPU audio hack update, one of the hacks actually caused sound glitches with some strange sound routines.
+- Do not blank screen if display can't be shown (DirectDraw display position negative upper left coordinates), now sets coordinates to zero.
+- Keyboard statesave buffer overflow (b1)
+
+- Experimental new vsync mode for fastest possible/JIT CPU modes. Tested using WHDLoad demos and games.
+  - Uses secondary thread which polls vblank state continuously. There is no way to get signal/message/whatever during vblank. Stupid Windows.
+  - Activates automatically if 2 or more CPUs/cores detected and fastest possible/JIT and low latency mode selected.
+  - JIT is also supported.
+  - Works in windowed and fullscreen modes (just like normal low latency vsync).
+  - This mode is currently buffered, used to hide horrible tearing (flip timing is much more complex if fastest possible CPU), will be hopefully improved later.
+  - Sound pitch changes possible, this also needs some improving later.
+
 Beta 2:
 
 - Adjusted horizontal positioning, full overscan was not visible.
index d9069d041421878651fb21d4a736123c75ad66d0..ec23edf8c8ecfd72c626195825ee96649aa44fc8 100644 (file)
--- a/sana2.cpp
+++ b/sana2.cpp
@@ -377,10 +377,10 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context)
        pdev->unit = unit;
        pdev->flags = flags;
        pdev->inuse = 1;
-       pdev->td = &td[unit];
+       pdev->td = td ? &td[unit] : NULL;
        pdev->promiscuous = (flags & SANA2OPF_PROM) ? 1 : 0;
 
-       if (pdev->td->active == 0)
+       if (pdev->td == NULL || pdev->td->active == 0)
                return openfail (ioreq, IOERR_OPENFAIL);
 
        if (dev->opencnt == 0) {
@@ -393,7 +393,7 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context)
                }
                write_log (L"%s: initializing unit %d\n", getdevname (), unit);
                dev->td = pdev->td;
-               dev->adapter = pdev->td->active;
+               dev->adapter = pdev->td ? pdev->td->active : 0;
                if (dev->adapter) {
                        dev->online = 1;
                        dev->configured = 1;