From: Toni Wilen Date: Sat, 10 Mar 2012 11:15:02 +0000 (+0200) Subject: 2400b21 X-Git-Tag: 2400~8 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=dbdc5b2ab3c1282d48eda506c23ea367e279673c;p=francis%2Fwinuae.git 2400b21 --- diff --git a/blitter.cpp b/blitter.cpp index 30f34b0e..c6f85ed9 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -789,6 +789,19 @@ static void actually_do_blit (void) } } +static void blitter_doit (void) +{ + #ifdef BLITTER_DEBUG + if (!blitter_dontdo) + actually_do_blit (); + else + bltstate = BLT_done; +#else + actually_do_blit (); +#endif + blitter_done (current_hpos ()); +} + void blitter_handler (uae_u32 data) { static int blitter_stuck; @@ -809,15 +822,7 @@ void blitter_handler (uae_u32 data) blit_slowdown = -1; return; } -#ifdef BLITTER_DEBUG - if (!blitter_dontdo) - actually_do_blit (); - else - bltstate = BLT_done; -#else - actually_do_blit (); -#endif - blitter_done (current_hpos ()); + blitter_doit (); } #ifdef CPUEMU_12 @@ -1408,12 +1413,14 @@ static void do_blitter2 (int hpos, int copper) } blt_info.got_cycle = 1; - if (currprefs.immediate_blits) - cycles = 1; - blit_waitcyclecounter = 0; - blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); - event2_newevent (ev2_blitter, blit_cyclecounter, 0); + + if (currprefs.immediate_blits) { + blitter_doit (); + } else { + blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); + event2_newevent (ev2_blitter, blit_cyclecounter, 0); + } } void do_blitter (int hpos, int copper) @@ -1441,6 +1448,8 @@ void maybe_blit (int hpos, int hack) while (bltstate != BLT_done && dmaen (DMA_BLITTER)) { x_do_cycles (8 * CYCLE_UNIT); } + if (bltstate == BLT_done) + return; } if (warned && dmaen (DMA_BLITTER) && blt_info.got_cycle) { diff --git a/cfgfile.cpp b/cfgfile.cpp index ed6083f4..114735dd 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -807,7 +807,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, L"gfx_height_windowed", L"%d", p->gfx_size_win.height); cfgfile_write (f, L"gfx_width_fullscreen", L"%d", p->gfx_size_fs.width); cfgfile_write (f, L"gfx_height_fullscreen", L"%d", p->gfx_size_fs.height); - cfgfile_write (f, L"gfx_refreshrate", L"%d", p->gfx_refreshrate); + cfgfile_write (f, L"gfx_refreshrate", L"%d", p->gfx_apmode[0].gfx_refreshrate); + cfgfile_dwrite (f, L"gfx_refreshrate_rtg", L"%d", p->gfx_apmode[1].gfx_refreshrate); cfgfile_write_bool (f, L"gfx_autoresolution", p->gfx_autoresolution); cfgfile_dwrite (f, L"gfx_autoresolution_min_vertical", vertmode[p->gfx_autoresolution_minv + 1]); cfgfile_dwrite (f, L"gfx_autoresolution_min_horizontal", horizmode[p->gfx_autoresolution_minh + 1]); @@ -1476,7 +1477,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval (option, value, L"gfx_left_windowed", &p->gfx_size_win.y, 1) || cfgfile_intval (option, value, L"gfx_width_fullscreen", &p->gfx_size_fs.width, 1) || cfgfile_intval (option, value, L"gfx_height_fullscreen", &p->gfx_size_fs.height, 1) - || cfgfile_intval (option, value, L"gfx_refreshrate", &p->gfx_refreshrate, 1) + || cfgfile_intval (option, value, L"gfx_refreshrate", &p->gfx_apmode[0].gfx_refreshrate, 1) + || cfgfile_intval (option, value, L"gfx_refreshrate_rtg", &p->gfx_apmode[1].gfx_refreshrate, 1) || cfgfile_yesno (option, value, L"gfx_autoresolution", &p->gfx_autoresolution) || cfgfile_intval (option, value, L"gfx_backbuffers", &p->gfx_apmode[0].gfx_backbuffers, 1) || cfgfile_intval (option, value, L"gfx_backbuffers_rtg", &p->gfx_apmode[1].gfx_backbuffers, 1) diff --git a/cia.cpp b/cia.cpp index 51f2971a..793e8676 100644 --- a/cia.cpp +++ b/cia.cpp @@ -45,6 +45,7 @@ #define CIAB_DEBUG_R 0 #define CIAB_DEBUG_W 0 #define DONGLE_DEBUG 0 +#define KB_DEBUG 0 #define TOD_HACK @@ -82,10 +83,8 @@ static int ciaatodon, ciabtodon; static unsigned int ciaapra, ciaaprb, ciaadra, ciaadrb, ciaasdr, ciaasdr_cnt; static unsigned int ciabprb, ciabdra, ciabdrb, ciabsdr, ciabsdr_cnt; static int div10; -#define KBACK_WAIT 1 -#define KBACK_ACTIVE 2 -#define KBACK_GOT 3 -static int kbstate, kback; +static int kbstate, kblostsynccnt; +static uae_u8 kbcode; static uae_u8 serbits; static int warned = 10; @@ -533,13 +532,13 @@ static int resetwarning_phase, resetwarning_timer; static void setcode (uae_u8 keycode) { - ciaasdr = ~((keycode << 1) | (keycode >> 7)); + kbcode = ~((keycode << 1) | (keycode >> 7)); } static void sendrw (void) { setcode (AK_RESETWARNING); - kback = KBACK_WAIT; + kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. ciaaicr |= 8; RethinkICRA (); write_log (L"KB: sent reset warning code (phase=%d)\n", resetwarning_phase); @@ -569,29 +568,29 @@ static void resetwarning_check (void) if (resetwarning_timer <= 0) { write_log (L"KB: reset warning forced reset. Phase=%d\n", resetwarning_phase); resetwarning_phase = -1; - kback = 0; + kblostsynccnt = 0; uae_reset (0); } } if (resetwarning_phase == 1) { - if (kback == KBACK_GOT) { /* first AK_RESETWARNING handshake received */ + if (!kblostsynccnt) { /* first AK_RESETWARNING handshake received */ write_log (L"KB: reset warning second phase..\n"); resetwarning_phase = 2; resetwarning_timer = maxvpos_nom * 5; sendrw (); } } else if (resetwarning_phase == 2) { - if (kback >= KBACK_ACTIVE) { /* second AK_RESETWARNING handshake active */ + if (ciaacra & 0x40) { /* second AK_RESETWARNING handshake active */ resetwarning_phase = 3; write_log (L"KB: reset warning SP = output\n"); /* System won't reset until handshake signal becomes inactive or 10s has passed */ resetwarning_timer = 10 * maxvpos_nom * vblank_hz; } } else if (resetwarning_phase == 3) { - if (kback != KBACK_ACTIVE) { /* second AK_RESETWARNING handshake disabled */ + if (!(ciaacra & 0x40)) { /* second AK_RESETWARNING handshake disabled */ write_log (L"KB: reset warning end by software. reset.\n"); resetwarning_phase = -1; - kback = 0; + kblostsynccnt = 0; uae_reset (0); } } @@ -601,6 +600,17 @@ void CIA_hsync_prehandler (void) { } +static void keyreq (void) +{ +#if KB_DEBUG + write_log (L"code=%x\n", kbcode); +#endif + ciaasdr = kbcode; + kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits. + ciaaicr |= 8; + RethinkICRA (); +} + void CIA_hsync_posthandler (bool dotod) { @@ -617,11 +627,11 @@ void CIA_hsync_posthandler (bool dotod) resetwarning_check (); while (keys_available ()) get_next_key (); - } else if ((keys_available () || kbstate < 3) && (kback == 0 || kback == KBACK_GOT) && (hsync_counter & 15) == 0) { + } else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) { switch (kbstate) { case 0: - ciaasdr = 0; /* powerup resync */ + kbcode = 0; /* powerup resync */ kbstate++; break; case 1: @@ -633,12 +643,10 @@ void CIA_hsync_posthandler (bool dotod) kbstate++; break; case 3: - ciaasdr = ~get_next_key (); + kbcode = ~get_next_key (); break; } - kback = KBACK_WAIT; - ciaaicr |= 8; - RethinkICRA (); + keyreq (); } } @@ -686,6 +694,16 @@ void CIA_vsync_prehandler (void) { led_vsync (); CIA_handler (); + if (kblostsynccnt > 0) { + kblostsynccnt -= maxvpos; + if (kblostsynccnt <= 0) { + kblostsynccnt = 0; + keyreq (); +#if KB_DEBUG + write_log (L"lostsync\n"); +#endif + } + } } void CIA_vsync_posthandler (bool dotod) @@ -1104,13 +1122,6 @@ static void WriteCIAA (uae_u16 addr, uae_u8 val) case 12: CIA_update (); ciaasdr = val; - if (ciaacra & 0x40) { - kback = KBACK_ACTIVE; - } else { - if (kback == KBACK_ACTIVE) - kback = KBACK_GOT; - ciaasdr_cnt = 0; - } if ((ciaacra & 0x41) == 0x41 && ciaasdr_cnt == 0) ciaasdr_cnt = 8 * 2; CIA_calctimers (); @@ -1123,12 +1134,14 @@ static void WriteCIAA (uae_u16 addr, uae_u8 val) val &= 0x7f; /* bit 7 is unused */ if ((val & 1) && !(ciaacra & 1)) ciaastarta = CIASTARTCYCLESCRA; - ciaacra = val; - if (ciaacra & 0x40) { - kback = KBACK_ACTIVE; - } else if (kback == KBACK_ACTIVE) { - kback = KBACK_GOT; + if ((val & 0x40) != (ciaacra & 0x40)) { + /* todo: check if low to high or high to low only */ + kblostsynccnt = 0; +#if KB_DEBUG + write_log (L"KB_ACK %02x->%02x\n", val, ciaacra); +#endif } + ciaacra = val; if (ciaacra & 0x10) { ciaacra &= ~0x10; ciaata = ciaala; @@ -1312,7 +1325,7 @@ void CIA_reset (void) tod_hack_enabled = 312 * 50 * 10; #endif - kback = 0; + kblostsynccnt = 0; serbits = 0; oldovl = 1; oldcd32mute = 1; @@ -1973,13 +1986,15 @@ 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 + 1); + dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1 + 1 + 1 + 2); save_u32 (getcapslockstate () ? 1 : 0); save_u32 (1); save_u8 (kbstate); save_u8 (0); save_u8 (0); - save_u8 (kback); + save_u8 (0); + save_u8 (kbcode); + save_u16 (kblostsynccnt); *len = dst - dstbak; return dstbak; } @@ -1991,9 +2006,11 @@ uae_u8 *restore_keyboard (uae_u8 *src) kbstate = restore_u8 (); restore_u8 (); restore_u8 (); - kback = restore_u8 (); + restore_u8 (); if (!(v & 1)) kbstate = 3; + kbcode = restore_u8 (); + kblostsynccnt = restore_u16 (); return src; } diff --git a/custom.cpp b/custom.cpp index f45fa27b..bc323b8f 100644 --- a/custom.cpp +++ b/custom.cpp @@ -123,20 +123,13 @@ STATIC_INLINE void sync_copper (int hpos); /* Events */ -unsigned long int event_cycles, nextevent, is_lastline, currcycle; -long cycles_to_next_event; -long max_cycles_to_next_event; -long cycles_to_hsync_event; unsigned long int vsync_cycles; static int extra_cycle; -unsigned long start_cycles; static int rpt_did_reset; struct ev eventtab[ev_max]; struct ev2 eventtab2[ev2_max]; -volatile frame_time_t vsynctime, vsyncmintime; - int vpos; static int vpos_count, vpos_count_prev; static int lof_store; // real bit in custom registers @@ -426,8 +419,8 @@ void reset_frame_rate_hack (void) return; rpt_did_reset = 1; - is_lastline = 0; - vsyncmintime = read_processor_time () + vsynctime; + is_syncline = 0; + vsyncmintime = read_processor_time () + vsynctimebase; write_log (L"Resetting frame rate hack\n"); } @@ -2734,7 +2727,7 @@ static int islinetoggle (void) return linetoggle; } -int vsynctime_orig; +int vsynctimebase_orig; void compute_vsynctime (void) { @@ -2755,9 +2748,9 @@ void compute_vsynctime (void) if (!fake_vblank_hz) fake_vblank_hz = vblank_hz; if (currprefs.turbo_emulation) - vsynctime = vsynctime_orig = 1; + vsynctimebase = vsynctimebase_orig = 1; else - vsynctime = vsynctime_orig = syncbase / fake_vblank_hz; + vsynctimebase = vsynctimebase_orig = syncbase / fake_vblank_hz; #if 0 if (!picasso_on) { updatedisplayarea (); @@ -3509,52 +3502,6 @@ static void DMACON (int hpos, uae_u16 v) events_schedule(); } - -void MISC_handler (void) -{ - static bool dorecheck; - bool recheck; - int i; - evt mintime; - evt ct = get_cycles (); - static int recursive; - - if (recursive) { - dorecheck = true; - return; - } - recursive++; - eventtab[ev_misc].active = 0; - recheck = true; - while (recheck) { - recheck = false; - mintime = ~0L; - for (i = 0; i < ev2_max; i++) { - if (eventtab2[i].active) { - if (eventtab2[i].evtime == ct) { - eventtab2[i].active = false; - eventtab2[i].handler (eventtab2[i].data); - if (dorecheck || eventtab2[i].active) { - recheck = true; - dorecheck = false; - } - } else { - evt eventtime = eventtab2[i].evtime - ct; - if (eventtime < mintime) - mintime = eventtime; - } - } - } - } - if (mintime != ~0L) { - eventtab[ev_misc].active = true; - eventtab[ev_misc].oldcycles = ct; - eventtab[ev_misc].evtime = ct + mintime; - events_schedule (); - } - recursive--; -} - static int irq_nmi; void NMI_delayed (void) @@ -5195,11 +5142,10 @@ static void framewait (void) if (vs > 0) { - vsyncmintime = vsynctime; + curr_time = read_processor_time (); render_screen (); show_screen (); frame_shown = true; - return; } else if (vs < 0) { @@ -5209,15 +5155,15 @@ static void framewait (void) if (!vblank_hz_state) return; - vsyncmintime = vsynctime; - if (vs == -2 || vs == -3) { + // fastest possible - curr_time = vsync_busywait_end (); - vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); curr_time = read_processor_time (); - vsyncmintime = curr_time + vsynctime; + vsync_busywait_end (); + vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); vsync_busywait_start (); + vsyncmintime = curr_time; + vsyncmaxtime = curr_time + vsynctimebase; } else { @@ -5225,7 +5171,7 @@ static void framewait (void) bool show = show_screen_maybe (false); vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); curr_time = read_processor_time (); - vsyncmintime = curr_time + vsynctime; + vsyncmintime = curr_time + vsynctimebase; if (!show) { show_screen (); if (extraframewait) @@ -5236,6 +5182,16 @@ static void framewait (void) } return; } + if (currprefs.m68k_speed < 0) { + curr_time = read_processor_time (); + if (curr_time - vsyncmaxtime >= 0 && curr_time - vsyncmaxtime < vsynctimebase) { + vsyncmaxtime = curr_time + vsynctimebase - (curr_time - vsyncmaxtime); + } else { + vsyncmaxtime = curr_time + vsynctimebase; + } + vsyncmintime = curr_time; + return; + } bool didrender = false; if (!picasso_on) @@ -5250,9 +5206,9 @@ static void framewait (void) curr_time = start = read_processor_time (); while (rpt_vsync () < 0) rtg_vsynccheck (); - curr_time = read_processor_time (); - vsyncmintime = curr_time + vsynctime; idletime += read_processor_time() - start; + curr_time = read_processor_time (); + vsyncmintime = vsyncmaxtime = curr_time + vsynctimebase; if (didrender) show_screen (); frame_shown = true; @@ -5285,7 +5241,7 @@ static void fpscounter (void) frametime2 += last; timeframes++; if ((timeframes % mcnt) == 0) { - double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctime * mcnt)); + double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctimebase * mcnt)); int fps = frametime2 == 0 ? 0 : (syncbase * mcnt) / (frametime2 / 10); if (fps > 9999) fps = 9999; @@ -5369,48 +5325,12 @@ static void vsync_handler_post (void) vsync_rendered = false; frame_shown = false; - //write_log (L"%d %d %d\n", vsynctime, read_processor_time () - vsyncmintime, read_processor_time () - prevtime); + //write_log (L"%d %d %d\n", vsynctimebase, read_processor_time () - vsyncmintime, read_processor_time () - prevtime); prevtime = read_processor_time (); fpscounter (); - if (!isvsync_chipset () -#ifdef AVIOUTPUT - && ((avioutput_framelimiter && avioutput_enabled) || !avioutput_enabled) -#endif - ) { -#ifdef JIT - if (!currprefs.cachesize) { -#endif - if (currprefs.m68k_speed < 0) { - frame_time_t curr_time = read_processor_time (); - vsyncmintime += vsynctime; - /* @@@ Mathias? How do you think we should do this? */ - /* If we are too far behind, or we just did a reset, adjust the - * needed time. */ - if ((long int)(curr_time - vsyncmintime) > 0 || rpt_did_reset) - vsyncmintime = curr_time + vsynctime; - rpt_did_reset = 0; - if (render_screen ()) - show_screen (); - frame_shown = true; - } else { - framewait (); - } -#ifdef JIT - } else { - if (currprefs.m68k_speed == 0) { - framewait (); - } else { - if (render_screen ()) - show_screen (); - frame_shown = true; - } - } -#endif - } else { - framewait (); - } + framewait (); #if CUSTOM_DEBUG > 1 if ((intreq & 0x0020) && (intena & 0x0020)) @@ -5466,41 +5386,6 @@ static void vsync_handler_post (void) vsync_cycles = get_cycles (); } -#ifdef JIT - -#define N_LINES 8 - -STATIC_INLINE int trigger_frh (int v) -{ - return (v & (N_LINES - 1)) == 0; -} - -static long int diff32 (frame_time_t x, frame_time_t y) -{ - return (long int)(x - y); -} -static void frh_handler (void) -{ - 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? */ - /* If we are too far behind, or we just did a reset, adjust the - * needed time. */ - if (rpt_did_reset) { - vsyncmintime = curr_time + vsynctime; - rpt_did_reset = 0; - } - /* 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 || vblank_found_chipset || vblank_found_rtg) - break; - } - } -} -#endif - static void copper_check (int n) { if (cop_state.state == COP_wait) { @@ -5699,7 +5584,7 @@ static void events_dmal_hsync (void) events_dmal (7); } -static bool is_vsync (void) +static bool is_custom_vsync (void) { int vp = vpos + 1; int vpc = vpos_count + 1; @@ -5902,25 +5787,47 @@ static void hsync_handler_post (bool onvsync) } #endif - events_dmal_hsync (); + if (currprefs.m68k_speed < 0) { + if (vpos + 1 == maxvpos + lof_store) { + /* really last line, just run the cpu emulation until whole vsync time has been used */ + is_syncline = 1; + vsyncmintime = vsyncmaxtime; + } else { + /* end of scanline, run cpu emulation as long as we still have time */ + vsyncmintime += vsynctimebase / maxvpos_nom; + if (!vblank_found_chipset && (int)vsyncmaxtime - (int)vsyncmintime > 0) { + is_syncline = -1; + frame_time_t rpt = read_processor_time (); + /* No extra time left? Skip it */ + if ((int)rpt - (int)vsyncmintime >= 0) + is_syncline = 0; + } + } + } + +#if 0 #ifdef JIT if (currprefs.cachesize) { if (currprefs.m68k_speed < 0) { jitcount++; - if (trigger_frh (jitcount)) { + if (isvsync () >= 0 && trigger_frh (jitcount)) { frh_handler (); } - is_lastline = trigger_frh (jitcount + 1) && ! rpt_did_reset; + is_syncline = (trigger_frh (jitcount + 1) && ! rpt_did_reset) ? -1 : 0; + //write_log (L"%d %d\n", jitcount & (N_LINES - 1), is_syncline); } else { - is_lastline = 0; + is_syncline = 0; } + if (vpos + 1 == maxvpos + lof_store) + is_syncline = 1; } else { #endif - is_lastline = vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed < 0; + is_syncline = (vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed < 0) ? 1 : 0; #ifdef JIT } +#endif #endif if (!nocustom ()) { @@ -6020,7 +5927,7 @@ static void hsync_handler_post (bool onvsync) if (diw_change > 0) diw_change--; - if (is_lastline && isvsync_chipset () == -2 && !vsync_rendered && currprefs.gfx_apmode[0].gfx_vflip == 0) { + if (is_syncline > 0 && isvsync_chipset () == -2 && !vsync_rendered && currprefs.gfx_apmode[0].gfx_vflip == 0) { /* fastest possible + last line and no vflip wait: render the frame as early as possible */ vsync_rendered = true; vsync_handle_redraw (lof_store, lof_changed); @@ -6030,6 +5937,7 @@ static void hsync_handler_post (bool onvsync) } frame_shown = true; } + rtg_vsynccheck (); #if 0 @@ -6048,7 +5956,7 @@ static void hsync_handler_post (bool onvsync) static void hsync_handler (void) { - bool vs = is_vsync (); + bool vs = is_custom_vsync (); hsync_handler_pre (vs); if (vs) { vsync_handler_pre (); @@ -7693,4 +7601,4 @@ bool ispal (void) if (beamcon0 & 0x80) return currprefs.ntscmode == 0; return maxvpos_nom >= MAXVPOS_NTSC + (MAXVPOS_PAL - MAXVPOS_NTSC) / 2; -} \ No newline at end of file +} diff --git a/disk.cpp b/disk.cpp index 3d686bc6..1f6731e8 100644 --- a/disk.cpp +++ b/disk.cpp @@ -3471,17 +3471,23 @@ int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32) uae_u32 dos, crc, crc2; int wasdelayed = drv->dskchange_time; int sectable[MAX_SECTORS]; + int oldcyl, oldside; ret = 0; + *crc32 = 0; + oldcyl = drv->cyl; + oldside = side; drv->cyl = 0; side = 0; - *crc32 = 0; - if (!drive_insert (drv, p, num, p->floppyslots[num].df, true)) - return 1; - if (!drv->diskfile) + if (!drive_insert (drv, p, num, p->floppyslots[num].df, true) || !drv->diskfile) { + drv->cyl = oldcyl; + side = oldside; return 1; + } *crc32 = zfile_crc32 (drv->diskfile); decode_buffer (drv->bigmfmbuf, drv->cyl, 11, drv->ddhd, drv->filetype, &drvsec, sectable, 1); + drv->cyl = oldcyl; + side = oldside; if (sectable[0] == 0 || sectable[1] == 0) { ret = 2; goto end; diff --git a/events.cpp b/events.cpp new file mode 100644 index 00000000..2607a617 --- /dev/null +++ b/events.cpp @@ -0,0 +1,156 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* Event stuff +* +* Copyright 1995-2002 Bernd Schmidt +* Copyright 1995 Alessandro Bissacco +* Copyright 2000-2012 Toni Wilen +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "events.h" + +unsigned long int event_cycles, nextevent, currcycle; +int is_syncline; +long cycles_to_next_event; +long max_cycles_to_next_event; +long cycles_to_hsync_event; +unsigned long start_cycles; + +frame_time_t vsynctimebase, vsyncmintime, vsyncmaxtime; + +void events_schedule (void) +{ + int i; + + unsigned long int mintime = ~0L; + for (i = 0; i < ev_max; i++) { + if (eventtab[i].active) { + unsigned long int eventtime = eventtab[i].evtime - currcycle; + if (eventtime < mintime) + mintime = eventtime; + } + } + nextevent = currcycle + mintime; +} + +void do_cycles_slow (unsigned long cycles_to_add) +{ + if ((pissoff -= cycles_to_add) >= 0) + return; + + cycles_to_add = -pissoff; + pissoff = 0; + + while ((nextevent - currcycle) <= cycles_to_add) { + int i; + + /* Keep only CPU emulation running while waiting for sync point. */ + if (is_syncline) { + int rpt = read_processor_time (); + int v = rpt - vsyncmintime; + if (v > (int)vsynctimebase || v < -((int)vsynctimebase)) { + v = 0; + } + if (v < 0 && !vblank_found_chipset) { + pissoff = pissoff_value; + return; + } + is_syncline = 0; + } + + cycles_to_add -= nextevent - currcycle; + currcycle = nextevent; + + for (i = 0; i < ev_max; i++) { + if (eventtab[i].active && eventtab[i].evtime == currcycle) { + (*eventtab[i].handler)(); + } + } + events_schedule (); + + + } + currcycle += cycles_to_add; +} + +void MISC_handler (void) +{ + static bool dorecheck; + bool recheck; + int i; + evt mintime; + evt ct = get_cycles (); + static int recursive; + + if (recursive) { + dorecheck = true; + return; + } + recursive++; + eventtab[ev_misc].active = 0; + recheck = true; + while (recheck) { + recheck = false; + mintime = ~0L; + for (i = 0; i < ev2_max; i++) { + if (eventtab2[i].active) { + if (eventtab2[i].evtime == ct) { + eventtab2[i].active = false; + eventtab2[i].handler (eventtab2[i].data); + if (dorecheck || eventtab2[i].active) { + recheck = true; + dorecheck = false; + } + } else { + evt eventtime = eventtab2[i].evtime - ct; + if (eventtime < mintime) + mintime = eventtime; + } + } + } + } + if (mintime != ~0L) { + eventtab[ev_misc].active = true; + eventtab[ev_misc].oldcycles = ct; + eventtab[ev_misc].evtime = ct + mintime; + events_schedule (); + } + recursive--; +} + + +void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func) +{ + evt et; + static int next = ev2_misc; + + et = t + get_cycles (); + if (no < 0) { + no = next; + for (;;) { + if (!eventtab2[no].active) + break; + if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data) + break; + no++; + if (no == ev2_max) + no = ev2_misc; + if (no == next) { + write_log (L"out of event2's!\n"); + return; + } + } + next = no; + } + eventtab2[no].active = true; + eventtab2[no].evtime = et; + eventtab2[no].handler = func; + eventtab2[no].data = data; + MISC_handler (); +} + diff --git a/include/events.h b/include/events.h index ea94d2bc..f8d01173 100644 --- a/include/events.h +++ b/include/events.h @@ -16,9 +16,8 @@ #include "machdep/rpt.h" -extern volatile frame_time_t vsynctime, vsyncmintime; +extern frame_time_t vsynctimebase, vsyncmintime, vsyncmaxtime; extern void reset_frame_rate_hack (void); -extern int rpt_available; extern frame_time_t syncbase; extern unsigned long int vsync_cycles; extern unsigned long start_cycles; @@ -26,9 +25,14 @@ extern unsigned long start_cycles; extern void compute_vsynctime (void); extern void init_eventtab (void); extern void do_cycles_ce (unsigned long cycles); +extern void events_schedule (void); +extern void do_cycles_slow (unsigned long cycles_to_add); +extern void do_cycles_fast (unsigned long cycles_to_add); + extern int is_cycle_ce (void); -extern unsigned long currcycle, nextevent, is_lastline; +extern unsigned long currcycle, nextevent; +extern int is_syncline; typedef void (*evfunc)(void); typedef void (*evfunc2)(uae_u32); @@ -59,18 +63,50 @@ enum { ev2_max = 12 }; +extern int pissoff_value; +extern signed long pissoff; + +#define countdown pissoff +#define do_cycles do_cycles_slow + extern struct ev eventtab[ev_max]; extern struct ev2 eventtab2[ev2_max]; -#if 0 +extern volatile bool vblank_found_chipset; +extern volatile bool vblank_found_rtg; + +STATIC_INLINE void cycles_do_special (void) +{ #ifdef JIT -#include "events_jit.h" -#else -#include "events_normal.h" + if (currprefs.cachesize) { + if (pissoff >= 0) + pissoff = -1; + } else #endif -#else -#include "events_jit.h" + { + pissoff = 0; + } +} + +STATIC_INLINE void do_extra_cycles (unsigned long cycles_to_add) +{ + pissoff -= cycles_to_add; +} + +STATIC_INLINE unsigned long int get_cycles (void) +{ + return currcycle; +} + +STATIC_INLINE void set_cycles (unsigned long int x) +{ + currcycle = x; + eventtab[ev_hsync].oldcycles = x; +#ifdef EVT_DEBUG + if (currcycle & (CYCLE_UNIT - 1)) + write_log (L"%x\n", currcycle); #endif +} STATIC_INLINE int current_hpos (void) { @@ -84,36 +120,7 @@ STATIC_INLINE bool cycles_in_range (unsigned long endcycles) } extern void MISC_handler (void); - -STATIC_INLINE void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func) -{ - evt et; - static int next = ev2_misc; - - et = t + get_cycles (); - if (no < 0) { - no = next; - for (;;) { - if (!eventtab2[no].active) - break; - if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data) - break; - no++; - if (no == ev2_max) - no = ev2_misc; - if (no == next) { - write_log (L"out of event2's!\n"); - return; - } - } - next = no; - } - eventtab2[no].active = true; - eventtab2[no].evtime = et; - eventtab2[no].handler = func; - eventtab2[no].data = data; - MISC_handler (); -} +extern void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func); STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func) { @@ -121,7 +128,6 @@ STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func) func (data); return; } - event2_newevent_xx (no, t * CYCLE_UNIT, data, func); } @@ -134,7 +140,6 @@ STATIC_INLINE void event2_newevent2 (evt t, uae_u32 data, evfunc2 func) event2_newevent_x (-1, t, data, func); } - STATIC_INLINE void event2_remevent (int no) { eventtab2[no].active = 0; diff --git a/include/options.h b/include/options.h index bf74f805..c6647a37 100644 --- a/include/options.h +++ b/include/options.h @@ -178,6 +178,7 @@ struct apmode int gfx_vsyncmode; int gfx_backbuffers; bool gfx_interlaced; + int gfx_refreshrate; }; struct uae_prefs { @@ -256,7 +257,6 @@ struct uae_prefs { bool gfx_autoresolution; int gfx_autoresolution_minv, gfx_autoresolution_minh; bool gfx_scandoubler; - int gfx_refreshrate; struct apmode gfx_apmode[2]; int gfx_resolution; int gfx_vresolution; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index bad41817..89dc67cb 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -1656,8 +1656,8 @@ static void setupscenecoords (void) float sw2 = dw * tin_w / window_w; float sh2 = dh * tin_h / window_h; - maskmult.x = 1; //sw2 * maskmult_x / w; - maskmult.y = 1; //sh2 * maskmult_y / h; + maskmult.x = sw2 * maskmult_x / w; + maskmult.y = sh2 * maskmult_y / h; maskshift.x = 1.0f / maskmult_x; maskshift.y = 1.0f / maskmult_y; @@ -1930,11 +1930,16 @@ void D3D_free (void) ddraw_fs_hack_free (); } +#define VBLANKDEBUG 0 + bool D3D_getvblankpos (int *vpos) { HRESULT hr; D3DRASTER_STATUS rt; - +#if VBLANKDEBUG + static UINT lastline; + static BOOL lastinvblank; +#endif *vpos = -2; if (!isd3d ()) return false; @@ -1949,6 +1954,13 @@ bool D3D_getvblankpos (int *vpos) if (rt.ScanLine > maxscanline) maxscanline = rt.ScanLine; *vpos = rt.ScanLine; +#if VBLANKDEBUG + if (lastline != rt.ScanLine || lastinvblank != rt.InVBlank) { + write_log(L"%d:%d ", rt.InVBlank ? 1 : 0, rt.ScanLine); + lastline = rt.ScanLine; + lastinvblank = rt.InVBlank; + } +#endif if (rt.InVBlank != 0) *vpos = -1; return true; @@ -2076,7 +2088,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth vsync2 = 0; int hzmult = 0; if (isfullscreen () > 0) { - dpp.FullScreen_RefreshRateInHz = currprefs.gfx_refreshrate > 0 ? currprefs.gfx_refreshrate : 0; + dpp.FullScreen_RefreshRateInHz = ap->gfx_refreshrate > 0 ? ap->gfx_refreshrate : 0; modeex.RefreshRate = dpp.FullScreen_RefreshRateInHz; if (vsync > 0) { dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; diff --git a/od-win32/mman.cpp b/od-win32/mman.cpp index 9b3f6d4f..002114b0 100644 --- a/od-win32/mman.cpp +++ b/od-win32/mman.cpp @@ -14,7 +14,9 @@ #if defined(NATMEM_OFFSET) +/* JIT can access few bytes outside of memory block of it executes code at the very end of memory block */ #define BARRIER 32 + #define MAXZ3MEM 0x7F000000 #define MAXZ3MEM64 0xF0000000 @@ -423,7 +425,7 @@ void *shmat (int shmid, void *shmaddr, int shmflg) if(!_tcscmp (shmids[shmid].name, L"chip")) { shmaddr=natmem_offset; got = TRUE; - if ((currprefs.fastmem_size == 0 && (currprefs.rtgmem_size == 0 && !currprefs.rtgmem_type)) || currprefs.chipmem_size < 2 * 1024 * 1024) + if (getz2endaddr () <= 2 * 1024 * 1024 || currprefs.chipmem_size < 2 * 1024 * 1024) size += BARRIER; } if(!_tcscmp (shmids[shmid].name, L"kick")) { @@ -464,10 +466,13 @@ void *shmat (int shmid, void *shmaddr, int shmflg) } if(!_tcscmp (shmids[shmid].name, L"ramsey_low")) { shmaddr=natmem_offset + a3000lmem_start; + if (!currprefs.mbresmem_high_size) + size += BARRIER; got = TRUE; } if(!_tcscmp (shmids[shmid].name, L"ramsey_high")) { shmaddr=natmem_offset + a3000hmem_start; + size += BARRIER; got = TRUE; } if(!_tcscmp (shmids[shmid].name, L"z3")) { diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 47d4f5ec..a70f0bfe 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -1840,7 +1840,7 @@ static void FillBoardInfo (uaecptr amigamemptr, struct LibResolution *res, int w put_byte (amigamemptr + PSSO_ModeInfo_second_union, 14); put_long (amigamemptr + PSSO_ModeInfo_PixelClock, - width * height * (currprefs.gfx_refreshrate ? abs (currprefs.gfx_refreshrate) : default_freq)); + width * height * (currprefs.gfx_apmode[1].gfx_refreshrate ? abs (currprefs.gfx_apmode[1].gfx_refreshrate) : default_freq)); } struct modeids { @@ -2361,11 +2361,11 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) } -static void init_picasso_screen(void); +static void init_picasso_screen (void); void picasso_enablescreen (int on) { if (!init_picasso_screen_called) - init_picasso_screen(); + init_picasso_screen (); picasso_refresh (); checkrtglibrary(); diff --git a/od-win32/sounddep/sound.cpp b/od-win32/sounddep/sound.cpp index c0b221b3..ac6ee3b0 100644 --- a/od-win32/sounddep/sound.cpp +++ b/od-win32/sounddep/sound.cpp @@ -202,7 +202,7 @@ void update_sound (double freq, int longframe, int linetoggle) #endif } -extern int vsynctime_orig; +extern int vsynctimebase_orig; #ifndef AVIOUTPUT static int avioutput_audio; @@ -224,13 +224,13 @@ void sound_setadjust (double v) if (avioutput_audio && avioutput_enabled && avioutput_nosoundsync) mult = 1000.0; if (isvsync_chipset () || (avioutput_audio && avioutput_enabled && !currprefs.cachesize)) { - vsynctime = vsynctime_orig; + vsynctimebase = vsynctimebase_orig; scaled_sample_evtime = scaled_sample_evtime_orig * mult / 1000.0; } else if (currprefs.cachesize || currprefs.m68k_speed != 0) { - vsynctime = (long)(((double)vsynctime_orig) * mult / 1000.0); + vsynctimebase = (long)(((double)vsynctimebase_orig) * mult / 1000.0); scaled_sample_evtime = scaled_sample_evtime_orig; } else { - vsynctime = (long)(((double)vsynctime_orig) * mult / 1000.0); + vsynctimebase = (long)(((double)vsynctimebase_orig) * mult / 1000.0); scaled_sample_evtime = scaled_sample_evtime_orig; } } diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index eb27886c..97cbd33a 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -99,7 +99,7 @@ int log_scsi; int log_net; int log_vsync; int uaelib_debug; -int pissoff_value = 25000; +int pissoff_value = 25000 * CYCLE_UNIT; unsigned int fpucontrol; int extraframewait = 0; @@ -4856,7 +4856,7 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) return 2; } if (!_tcscmp (arg, L"jitevent")) { - pissoff_value = getval (np); + pissoff_value = getval (np) * CYCLE_UNIT; return 2; } if (!_tcscmp (arg, L"inputrecorddebug")) { @@ -5070,7 +5070,6 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR write_log (L"%d: '%s'\n", i + 1, argv2[i]); } if (WIN32_RegisterClasses () && WIN32_InitLibraries ()) { - DEVMODE devmode; DWORD i; WIN32_HandleRegistryStuff (); @@ -5090,6 +5089,8 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR write_log (L"%d:%s: %s\n", i, type == SOUND_DEVICE_XAUDIO2 ? L"XA" : (type == SOUND_DEVICE_DS ? L"DS" : (type == SOUND_DEVICE_AL ? L"AL" : (type == SOUND_DEVICE_WASAPI ? L"WA" : (type == SOUND_DEVICE_WASAPI_EXCLUSIVE ? L"WX" : L"PA")))), record_devices[i]->name); } write_log (L"done\n"); +#if 0 + DEVMODE devmode; memset (&devmode, 0, sizeof (devmode)); devmode.dmSize = sizeof (DEVMODE); if (EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &devmode)) { @@ -5099,6 +5100,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR else default_freq = 60; } +#endif WIN32_InitLang (); WIN32_InitHtmlHelp (); DirectDraw_Release (); diff --git a/od-win32/win32.h b/od-win32/win32.h index 79349436..5272ba6b 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,8 +19,8 @@ #define LANG_DLL 1 //#define WINUAEBETA L"" -#define WINUAEBETA L"Beta 20" -#define WINUAEDATE MAKEBD(2012, 3, 4) +#define WINUAEBETA L"Beta 21" +#define WINUAEDATE MAKEBD(2012, 3, 10) #define WINUAEEXTRA L"" //#define WINUAEEXTRA L"AmiKit Preview" #define WINUAEREV L"" diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 0f1b8b1f..e508f0aa 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -103,7 +103,7 @@ int window_extra_width, window_extra_height; static struct winuae_currentmode *currentmode = ¤tmodestruct; static int wasfullwindow_a, wasfullwindow_p; -static int vblankbasewait, vblankbasewait2, vblankbasewait3, vblankbasefull; +static int vblankbasewait1, vblankbasewait2, vblankbasewait3, vblankbasefull; static bool vblankbaselace; static int vblankbaselace_chipset; static bool vblankthread_oddeven; @@ -150,11 +150,11 @@ static void vsync_sleep (bool preferbusy) } else { dowait = false; } - if (dowait) + if (dowait && currprefs.m68k_speed >= 0) sleep_millis_main (1); } -static void changevblankthreadmode (int newmode) +static void changevblankthreadmode_do (int newmode, bool fast) { int t = vblankthread_counter; vblank_found = false; @@ -173,7 +173,18 @@ static void changevblankthreadmode (int newmode) flipevent = NULL; flipevent2 = NULL; } - while (t == vblankthread_counter && vblankthread_mode > 0); + if (!fast) { + while (t == vblankthread_counter && vblankthread_mode > 0); + } +} + +static void changevblankthreadmode (int newmode) +{ + changevblankthreadmode_do (newmode, false); +} +static void changevblankthreadmode_fast (int newmode) +{ + changevblankthreadmode_do (newmode, true); } int WIN32GFX_IsPicassoScreen (void) @@ -237,13 +248,12 @@ int WIN32GFX_GetHeight (void) static int init_round; static BOOL doInit (void); -int default_freq = 0; +int default_freq = 60; HWND hStatusWnd = NULL; static uae_u8 scrlinebuf[4096 * 4]; /* this is too large, but let's rather play on the safe side here */ - struct MultiDisplay *getdisplay (struct uae_prefs *p) { int i; @@ -1256,14 +1266,19 @@ static void update_gfxparams (void) if (screen_is_picasso) { currentmode->current_width = picasso96_state.Width; currentmode->current_height = picasso96_state.Height; - currentmode->frequency = abs (currprefs.gfx_refreshrate > default_freq ? currprefs.gfx_refreshrate : default_freq); + if (currprefs.win32_rtgvblankrate == 0) + currentmode->frequency = abs (currprefs.gfx_apmode[0].gfx_refreshrate); + else if (currprefs.win32_rtgvblankrate < 0) + currentmode->frequency = 0; + else + currentmode->frequency = abs (currprefs.gfx_apmode[1].gfx_refreshrate >= 50 ? currprefs.gfx_apmode[1].gfx_refreshrate : 50); if (currprefs.gfx_apmode[1].gfx_vsync) currentmode->vsync = 1 + currprefs.gfx_apmode[1].gfx_vsyncmode; } else { #endif currentmode->current_width = currprefs.gfx_size.width; currentmode->current_height = currprefs.gfx_size.height; - currentmode->frequency = abs (currprefs.gfx_refreshrate); + currentmode->frequency = abs (currprefs.gfx_apmode[0].gfx_refreshrate); if (currprefs.gfx_apmode[0].gfx_vsync) currentmode->vsync = 1 + currprefs.gfx_apmode[0].gfx_vsyncmode; #ifdef PICASSO96 @@ -1393,7 +1408,8 @@ int check_prefs_changed_gfx (void) c |= currprefs.gfx_apmode[1].gfx_vsync != changed_prefs.gfx_apmode[1].gfx_vsync ? 2 | 16 : 0; c |= currprefs.gfx_apmode[0].gfx_vsyncmode != changed_prefs.gfx_apmode[0].gfx_vsyncmode ? 2 | 16 : 0; c |= currprefs.gfx_apmode[1].gfx_vsyncmode != changed_prefs.gfx_apmode[1].gfx_vsyncmode ? 2 | 16 : 0; - c |= currprefs.gfx_refreshrate != changed_prefs.gfx_refreshrate ? 2 | 16 : 0; + c |= currprefs.gfx_apmode[0].gfx_refreshrate != changed_prefs.gfx_apmode[0].gfx_refreshrate ? 2 | 16 : 0; + c |= currprefs.gfx_apmode[1].gfx_refreshrate != changed_prefs.gfx_apmode[1].gfx_refreshrate ? 2 | 16 : 0; c |= currprefs.gfx_autoresolution != changed_prefs.gfx_autoresolution ? (2|8|16) : 0; c |= currprefs.gfx_api != changed_prefs.gfx_api ? (1|8|32) : 0; @@ -1845,7 +1861,8 @@ static int reopen (int full) currprefs.gfx_apmode[1].gfx_vsync = changed_prefs.gfx_apmode[1].gfx_vsync; currprefs.gfx_apmode[0].gfx_vsyncmode = changed_prefs.gfx_apmode[0].gfx_vsyncmode; currprefs.gfx_apmode[1].gfx_vsyncmode = changed_prefs.gfx_apmode[1].gfx_vsyncmode; - currprefs.gfx_refreshrate = changed_prefs.gfx_refreshrate; + currprefs.gfx_apmode[0].gfx_refreshrate = changed_prefs.gfx_apmode[0].gfx_refreshrate; + currprefs.gfx_apmode[1].gfx_refreshrate = changed_prefs.gfx_apmode[1].gfx_refreshrate; config_changed = 1; if (!quick) @@ -1905,9 +1922,9 @@ bool vsync_switchmode (int hz) } else { newh = found->res.height; changed_prefs.gfx_size_fs.height = newh; - changed_prefs.gfx_refreshrate = hz; + changed_prefs.gfx_apmode[0].gfx_refreshrate = hz; if (changed_prefs.gfx_size_fs.height != currprefs.gfx_size_fs.height || - changed_prefs.gfx_refreshrate != currprefs.gfx_refreshrate) { + changed_prefs.gfx_apmode[0].gfx_refreshrate != currprefs.gfx_apmode[0].gfx_refreshrate) { write_log (L"refresh rate changed to %d, new screenmode %dx%d\n", hz, w, newh); config_changed = 1; } @@ -2310,6 +2327,9 @@ static int maxscanline, minscanline, prevvblankpos; static bool getvblankpos (int *vp) { int sl; +#if 0 + frame_time_t t = read_processor_time (); +#endif *vp = -2; if (currprefs.gfx_api) { if (!D3D_getvblankpos (&sl)) @@ -2318,6 +2338,10 @@ static bool getvblankpos (int *vp) if (!DD_getvblankpos (&sl)) return false; } +#if 0 + t = read_processor_time () - t; + write_log (L"(%d:%d)", t, sl); +#endif prevvblankpos = sl; if (sl > maxscanline) maxscanline = sl; @@ -2414,6 +2438,11 @@ static unsigned int __stdcall flipthread (void *dummy) return 0; } +static int frame_missed, frame_counted, frame_errors; +static int frame_usage, frame_usage_avg, frame_usage_total; +extern int log_vsync; +static bool dooddevenskip; + static bool vblanklaceskip (void) { if (vblankbaselace_chipset >= 0 && vblankbaselace) { @@ -2441,7 +2470,7 @@ static unsigned int __stdcall vblankthread (void *dummy) // idle mode Sleep (100); } else if (vblankthread_mode == VBLANKTH_ACTIVE_WAIT) { - sleep_millis (ap->gfx_vflip ? 2 : 1); + sleep_millis (ap->gfx_vflip && currprefs.m68k_speed >= 0 ? 2 : 1); } else if (vblankthread_mode == VBLANKTH_ACTIVE_START) { // do not start until vblank has been passed bool vb = false; @@ -2456,8 +2485,8 @@ static unsigned int __stdcall vblankthread (void *dummy) // busy wait mode frame_time_t t = read_processor_time (); bool donotwait = false; - int vs = isvsync_chipset (); if (!vblank_found) { + int vs = isvsync_chipset (); // immediate vblank if mismatched frame type if (vs < 0 && vblanklaceskip ()) { vblank_found = true; @@ -2470,6 +2499,9 @@ static unsigned int __stdcall vblankthread (void *dummy) if (firstvblankbasewait2 == false) { firstvblankbasewait2 = true; vblank_getstate (&vb); + if (!dooddevenskip && ap->gfx_vflip > 0) { + doflipevent (); + } } ok = vblank_getstate (&vb); if (!ok || vb) { @@ -2489,10 +2521,14 @@ static unsigned int __stdcall vblankthread (void *dummy) donotwait = true; } } - if (t - vblank_prev_time > vblankbasefull * 3) + if (t - vblank_prev_time > vblankbasefull * 3) { + vblank_found = true; + vblank_found_rtg = true; + vblank_found_chipset = true; vblankthread_mode = VBLANKTH_IDLE; + } if (!donotwait || ap->gfx_vflip || picasso_on) - sleep_millis (ap->gfx_vflip ? 2 : 1); + sleep_millis (ap->gfx_vflip && currprefs.m68k_speed >= 0 ? 2 : 1); } else { break; } @@ -2501,11 +2537,6 @@ static unsigned int __stdcall vblankthread (void *dummy) return 0; } -static int frame_missed, frame_counted, frame_errors; -static int frame_usage, frame_usage_avg, frame_usage_total; -extern int log_vsync; -static bool dooddevenskip; - bool vsync_busywait_check (void) { return vblankthread_mode == VBLANKTH_ACTIVE || vblankthread_mode == VBLANKTH_ACTIVE_WAIT; @@ -2530,15 +2561,16 @@ frame_time_t vsync_busywait_end (void) if (!dooddevenskip) { vsync_notvblank (); while (!vblank_found && vblankthread_mode == VBLANKTH_ACTIVE) { - vsync_sleep (false); + vsync_sleep (currprefs.m68k_speed < 0); } } - changevblankthreadmode (VBLANKTH_ACTIVE_WAIT); + changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); return thread_vblank_time; } void vsync_busywait_start (void) { +#if 0 struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (!dooddevenskip) { vsync_notvblank (); @@ -2546,7 +2578,8 @@ void vsync_busywait_start (void) doflipevent (); } } - changevblankthreadmode (VBLANKTH_ACTIVE_START); +#endif + changevblankthreadmode_fast (VBLANKTH_ACTIVE_START); vblank_prev_time = thread_vblank_time; } @@ -2625,7 +2658,7 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) } if (!doskip) { - while (!framelost && read_processor_time () - prevtime < vblankbasewait) { + while (!framelost && read_processor_time () - prevtime < vblankbasewait1) { vsync_sleep (false); } v = vblank_wait (); @@ -2680,7 +2713,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly) depth = (currentmode->native_depth + 7) / 8; } - rate = currprefs.gfx_refreshrate; + rate = ap->gfx_refreshrate; mode = isfullscreen (); rv = vsyncmemory; while (rv) { @@ -2789,7 +2822,7 @@ skip: tsum2 = tsum / div; vblankbasefull = (syncbase / tsum2); - vblankbasewait = (syncbase / tsum2) * 3 / 4; + vblankbasewait1 = (syncbase / tsum2) * 75 / 100; vblankbasewait2 = (syncbase / tsum2) * 70 / 100; vblankbasewait3 = (syncbase / tsum2) * 90 / 100; vblankbaselace = lace; @@ -3305,6 +3338,7 @@ static BOOL doInit (void) changed_prefs.gfx_filter = currprefs.gfx_filter = 0; currentmode->current_depth = currentmode->native_depth; gfxmode_reset (); + DirectDraw_Start (); ret = -1; goto oops; } diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 6435ba74..2614dcab 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -5410,7 +5410,7 @@ static void init_frequency_combo (HWND hDlg, int dmode) _tcscat (hz, L" NTSC"); if (type) _tcscat (hz, L" (*)"); - if (abs (workprefs.gfx_refreshrate) == freq) + if (abs (workprefs.gfx_apmode[0].gfx_refreshrate) == freq) _tcscpy (hz2, hz); SendDlgItemMessage (hDlg, IDC_REFRESHRATE, CB_ADDSTRING, 0, (LPARAM)hz); } @@ -5420,7 +5420,7 @@ static void init_frequency_combo (HWND hDlg, int dmode) if (index == CB_ERR) { WIN32GUI_LoadUIString (IDS_VSYNC_DEFAULT, txt, sizeof (txt) / sizeof (TCHAR)); SendDlgItemMessage(hDlg, IDC_REFRESHRATE, CB_SELECTSTRING, i, (LPARAM)txt); - workprefs.gfx_refreshrate = 0; + workprefs.gfx_apmode[0].gfx_refreshrate = 0; } } @@ -6029,10 +6029,10 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (posn1 == CB_ERR) return; if (posn1 == 0) { - workprefs.gfx_refreshrate = 0; + workprefs.gfx_apmode[0].gfx_refreshrate = 0; } else { posn1--; - workprefs.gfx_refreshrate = md->DisplayModes[dmode].refresh[posn1]; + workprefs.gfx_apmode[0].gfx_refreshrate = md->DisplayModes[dmode].refresh[posn1]; } values_to_displaydlg (hDlg); } else if (LOWORD (wParam) == IDC_DA_MODE) { diff --git a/od-win32/winuae_msvc10/winuae_msvc.vcxproj b/od-win32/winuae_msvc10/winuae_msvc.vcxproj index 451de041..08ad3d6b 100644 --- a/od-win32/winuae_msvc10/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc10/winuae_msvc.vcxproj @@ -556,6 +556,7 @@ + diff --git a/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters index f4dd15f8..17c918d2 100644 --- a/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters +++ b/od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters @@ -499,6 +499,9 @@ common + + common + diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 239ba863..af70eabc 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,34 @@ +Beta 21: (Fastest possible vsync should be fixed finally, only some testing left to do) + +- Direct3D masks and scanlines fixed, forgotten testing code.. (b20) +- 2.3.2 "stop the cpu and wait until blitter has finished if any blitter register is accessed while blitter is busy and + cpu mode is fastest possible" was broken and could cause side-effects in some situations. +- Direct3D to DirectDraw fallback if DirectX is not recent enough crashed. (b5) +- Keyboard lost sync state emulated, needed with some programs that don't handshake all buffered key codes but still clear + the CIA keyboard interrupt flag, this caused dead keyboard after b1 update. Now keyboard should be fully emulated. +- Quickstart panel disk insert always reset track position to zero. (forgot to restore old track after checking disk + type and bootable state, bug since Quickstart was introduced!) Fixes Wrath of Demon disk swaps. +- Z2 RTG changes broke chip RAM "memory barrier" causing crash if JIT executed code at the very end of chip RAM. (b16) + +I finally really examined and even understood (I think..) how fastest possible and JIT modes handle CPU emulation, +(in reality fastest possible without JIT didn't really handle it all, other UAE ports most likely have exact same issue): +Some unnecessary and big event code inlining also removed (shorter code, should be faster on modern CPUs due to less cache trashing) + +- Huge improvement in fastest possible CPU (with or without JIT) + low latency vsync performance. +- Fastest possible without JIT performance improved in non-vsync modes. It now executes small chunks of extra code after + each scanline instead (as long as there is time, the faster the host CPU, the more extra time there is) of single huge + chunk just before vsync. JIT basically does the same but because it has "unknown" timing, it may execute "too much" + code first and then skip multiple scanlines until there is enough time again. +- Immediate blitter is now 100% immediate. Fastest possible (with or without JIT) performance greatly improved (10x+ possible!) + if program does lots of small blits. Previously, even in immediate blitter mode, blitter wait caused CPU emulator to waste + its extra "fastest possible time slot" by doing absolutely nothing else than waiting the blitter that never happened. It can't + happen until next scanline, during extra fastest CPU "slots" chipset emulation has to be paused. + +Fastest possible CPU throttling option will be also possible, this will be done later.. + +NOTE: Above changes WILL break some games/demos that (accidentally) worked previously. It is 100% guaranteed! + Beta 20: - Fixed DirectDraw on screen led status bar surface allocation error when switching modes in some situations. diff --git a/specialmonitors.cpp b/specialmonitors.cpp old mode 100755 new mode 100644