if (!vblank_hz_state)
return status != 0;
- if (vs < 0) {
- frame_shown = true;
- status = 1;
- return status != 0;
- }
+ frame_shown = true;
+ status = 1;
+ return status != 0;
}
status = 1;
}
if (busywait)
return;
- cpu_sleep_millis(1);
+ if (currprefs.m68k_speed < 0)
+ sleep_millis_main(1);
+ else
+ target_sleep_nanos(500);
}
static void linesync_first_last_line(int *first, int *last)
do_render_slice(1, display_slice_cnt);
display_rendered = true;
}
- if (!currprefs.turbo_emulation) {
- while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
- frame_time_t rpt = read_processor_time();
- if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -vsynctimebase * 2) {
- vsyncmintime = rpt + vsynctimebase;
- break;
- }
- maybe_process_pull_audio();
- target_spin(0);
+ while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
+ frame_time_t rpt = read_processor_time();
+ if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -vsynctimebase * 2) {
+ vsyncmintime = rpt + vsynctimebase;
+ break;
}
- do_display_slice();
- display_rendered = false;
- input_read_done = true;
+ maybe_process_pull_audio();
+ target_spin(0);
}
+ do_display_slice();
+ display_rendered = false;
+ input_read_done = true;
} else {
return input_read_done;
}
-static bool linesync_beam_multi(void)
+static bool linesync_beam_multi_single(void)
{
static int vsyncnextscanline;
static int vsyncnextscanline_add;
}
vsync_clear();
}
+
while (!currprefs.turbo_emulation && sync_timeout_check(maxtime)) {
int vp = target_get_display_scanline(-1);
if (vp < 0 || vp >= vsyncnextscanline)
} else if (vpos >= nextwaitvpos) {
+ // topmost/first slice?
if (display_slice_cnt == 0) {
- // topmost slice
if (currprefs.gfx_variable_sync) {
- do_render_slice(1, display_slice_cnt);
- display_rendered = true;
+ if (!currprefs.turbo_emulation) {
+ if (!was_syncline) {
+ do_render_slice(1, display_slice_cnt);
+ display_rendered = true;
+ }
- for(;;) {
- frame_time_t rpt = read_processor_time();
- if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase)
- break;
- maybe_process_pull_audio();
- target_spin(0);
+ frame_time_t rpt;
+ for(;;) {
+ rpt = read_processor_time();
+ if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase)
+ break;
+ maybe_process_pull_audio();
+ if (currprefs.m68k_speed < 0 && !was_syncline) {
+ is_syncline = -1;
+ return 0;
+ }
+ target_spin(0);
+ }
+ do_display_slice();
+ if ((int)rpt - (int)vsyncmintime < vsynctimebase && (int)rpt - (int)vsyncmintime > -vsynctimebase) {
+ vsyncmintime += vsynctimebase;
+ } else {
+ vsyncmintime = rpt + vsynctimebase;
+ }
+ display_rendered = false;
+ input_read_done = true;
}
- vsyncmintime = read_processor_time() + vsynctimebase;
- do_display_slice();
- display_rendered = false;
- input_read_done = true;
} else {
display_rendered = true;
}
+ // flip slightly early because flip regularly gets delayed if done during vblank
+ int lastflipline = vsync_activeheight - vsyncnextscanline_add / 3;
while (sync_timeout_check(maxtime)) {
int vp = target_get_display_scanline(-1);
maybe_process_pull_audio();
- if (vp < 0 || vp < vsync_activeheight / 2 || vp >= vsync_activeheight - 1)
+ if (vp < vsync_activeheight / 2 || vp >= lastflipline)
break;
if (currprefs.m68k_speed < 0 && !was_syncline) {
- is_syncline = -1;
+ is_syncline_end = lastflipline;
+ is_syncline = -2;
return 0;
}
target_spin(0);
do_display_slice();
display_rendered = false;
input_read_done = true;
+
+#if 1
+ // if flipped before vblank, wait for vblank
+ while (sync_timeout_check(maxtime)) {
+ int vp = target_get_display_scanline(-1);
+ if (vp < vsync_activeheight / 2)
+ break;
+ if (currprefs.m68k_speed < 0 && !was_syncline) {
+ is_syncline = -1;
+ return 0;
+ }
+ maybe_process_pull_audio();
+ target_spin(0);
+ }
+#endif
}
}
}
while (sync_timeout_check(maxtime)) {
int vp = target_get_display_scanline(-1);
- if (vp == -1) {
+ // We are still in vblank and second slice? Poll until vblank ends.
+ if (display_slice_cnt == 1 && vp == -1) {
maybe_process_pull_audio();
target_spin(0);
#if LLV_DEBUG
if (currprefs.gfx_display_sections <= 1) {
linesync_beam_single();
} else {
- if (vsync_hblank >= 85 && !currprefs.gfx_variable_sync)
+ if (vsync_vblank >= 85 && !currprefs.gfx_variable_sync)
linesync_beam_multi_dual();
else
- linesync_beam_multi();
+ linesync_beam_multi_single();
}
}
if (currprefs.gfx_display_sections <= 1) {
input_read_done = linesync_beam_single();
} else {
- if (vsync_hblank >= 85 && currprefs.gfx_variable_sync)
+ if (vsync_vblank >= 85 && !currprefs.gfx_variable_sync)
input_read_done = linesync_beam_multi_dual();
else
- input_read_done = linesync_beam_multi();
+ input_read_done = linesync_beam_multi_single();
}
} else if (!currprefs.cpu_thread && !cpu_sleepmode && currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) {
//currprefs.a4091rom.enabled = changed_prefs.a4091rom.enabled = RBB;
RBB;
RBB;
- currprefs.cs_cdtvscsi = changed_prefs.cs_cdtvscsi = RBB;
+ RBB;
currprefs.cs_pcmcia = changed_prefs.cs_pcmcia = RBB;
currprefs.cs_ciaatod = changed_prefs.cs_ciaatod = RB;
SB (is_board_enabled(&currprefs, ROMTYPE_A2091, 0) ? 1 : 0);
SB (is_board_enabled(&currprefs, ROMTYPE_A4091, 0) ? 1 : 0);
- SB (currprefs.cs_cdtvscsi ? 1 : 0);
+ SB (0);
SB (currprefs.cs_pcmcia ? 1 : 0);
SB (currprefs.cs_ciaatod);
static int guijoyaxis[MAX_JPORTS][4];
static bool guijoychange;
+typedef NTSTATUS(CALLBACK* NTDELAYEXECUTION)(BOOL, PLARGE_INTEGER);
+typedef NTSTATUS(CALLBACK* ZWSETTIMERRESOLUTION)(ULONG, BOOLEAN, PULONG);
+static NTDELAYEXECUTION pNtDelayExecution;
+static ZWSETTIMERRESOLUTION pZwSetTimerResolution;
+
#if TOUCH_SUPPORT
typedef BOOL (CALLBACK* REGISTERTOUCHWINDOW)(HWND, ULONG);
typedef BOOL (CALLBACK* GETTOUCHINPUTINFO)(HTOUCHINPUT, UINT, PTOUCHINPUT, int);
static CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle;
#endif
+static ULONG ActualTimerResolution;
+
+void target_sleep_nanos(int nanos)
+{
+ static bool init;
+ if (!init) {
+ pNtDelayExecution = (NTDELAYEXECUTION)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtDelayExecution");
+ pZwSetTimerResolution = (ZWSETTIMERRESOLUTION)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "ZwSetTimerResolution");
+ if (pZwSetTimerResolution) {
+ // 0.5ms
+ NTSTATUS status = pZwSetTimerResolution((500 * 1000) / 100, TRUE, &ActualTimerResolution);
+ if (!status) {
+ LARGE_INTEGER interval;
+ interval.QuadPart = -(int)ActualTimerResolution;
+ status = pNtDelayExecution(false, &interval);
+ if (!status) {
+ write_log(_T("Using NtDelayExecution. ActualTimerResolution=%u\n"), ActualTimerResolution);
+ } else {
+ write_log(_T("NtDelayExecution returned %08x\n"), status);
+ pNtDelayExecution = NULL;
+ pZwSetTimerResolution = NULL;
+ }
+ } else {
+ write_log(_T("NtDelayExecution not available\n"));
+ pNtDelayExecution = NULL;
+ pZwSetTimerResolution = NULL;
+ }
+ }
+ init = true;
+ }
+ if (pNtDelayExecution) {
+ LARGE_INTEGER interval;
+ int start = read_processor_time();
+ nanos *= 10;
+ if (nanos < ActualTimerResolution)
+ nanos = ActualTimerResolution;
+ interval.QuadPart = -nanos;
+ pNtDelayExecution(false, &interval);
+ idletime += read_processor_time() - start;
+ } else {
+ sleep_millis_main(1);
+ }
+}
+
static uae_u64 spincount;
void target_spin(int total)