From: Toni Wilen Date: Sun, 11 Dec 2011 17:12:18 +0000 (+0200) Subject: 2400b3 X-Git-Tag: 2400~25 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=a21ae510925dc3088fb6c32989d703ae9785827f;p=francis%2Fwinuae.git 2400b3 --- diff --git a/akiko.cpp b/akiko.cpp index 1ab88a14..619b5bb0 100644 --- 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; diff --git a/audio.cpp b/audio.cpp index 4d426129..6d573dc5 100644 --- 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) { diff --git a/cdtv.cpp b/cdtv.cpp index 08ed12e0..211ec5ad 100644 --- 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); diff --git a/cfgfile.cpp b/cfgfile.cpp index 190a2a2d..860fe381 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -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 b2f82b99..8526a1a7 100644 --- 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); diff --git a/custom.cpp b/custom.cpp index 8420bbe7..d2f91741 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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 diff --git a/drawing.cpp b/drawing.cpp index 43d095c8..a5cec307 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -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; +} diff --git a/include/events_jit.h b/include/events_jit.h index d32a6bb6..3f5bac88 100644 --- a/include/events_jit.h +++ b/include/events_jit.h @@ -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; } diff --git a/include/events_normal.h b/include/events_normal.h index 8c55ef04..bc1a8495 100644 --- a/include/events_normal.h +++ b/include/events_normal.h @@ -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) { diff --git a/include/uae.h b/include/uae.h index 92c53039..68756c2c 100644 --- a/include/uae.h +++ b/include/uae.h @@ -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; diff --git a/include/xwin.h b/include/xwin.h index 9fa17047..b5e43d0b 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -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 */ diff --git a/jit/compemu.h b/jit/compemu.h index b15051de..7b7677f5 100644 --- a/jit/compemu.h +++ b/jit/compemu.h @@ -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)/SCALEdrvlettername); + return true; } } } + return false; } static int ioctl_scsiemu (int unitnum, uae_u8 *cmd) diff --git a/od-win32/blkdev_win32_spti.cpp b/od-win32/blkdev_win32_spti.cpp index e160521b..30314e36 100644 --- a/od-win32/blkdev_win32_spti.cpp +++ b/od-win32/blkdev_win32_spti.cpp @@ -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) diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 89681f3f..9ba0fcff 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -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)); diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 5139bd17..f903b5cd 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -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; diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index df949e16..ac55064d 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -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; +} diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 23af467d..f683b9da 100644 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -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); diff --git a/od-win32/sounddep/sound.cpp b/od-win32/sounddep/sound.cpp index f17286f2..6a8e1d66 100644 --- a/od-win32/sounddep/sound.cpp +++ b/od-win32/sounddep/sound.cpp @@ -27,6 +27,7 @@ #include "savestate.h" #include "driveclick.h" #include "gensound.h" +#include "xwin.h" #include #include @@ -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) diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 89f28729..3772702e 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -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 (); diff --git a/od-win32/win32.h b/od-win32/win32.h index 98f82df3..efb1c497 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -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); diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 445f8392..51b6ec3d 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -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); } diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 061b4502..70178ab8 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -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 = ¤tmodestruct; 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 -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 (); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 9d27874e..20b1ae93 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -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); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index c3deeae8..671df7c3 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -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. diff --git a/sana2.cpp b/sana2.cpp index d9069d04..ec23edf8 100644 --- 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;