Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time irregularity #228

Open
Vort opened this issue Jan 19, 2024 · 4 comments
Open

Time irregularity #228

Vort opened this issue Jan 19, 2024 · 4 comments
Assignees

Comments

@Vort
Copy link
Contributor

Vort commented Jan 19, 2024

One method of providing uniform amount of resources to program is using sync=slowdown option.
However in reality, even with ips=1000000, resources to program are delivered with changing (oscillating) speed.
It makes hard to use programs (games), which requires correctly timed inputs from user.

For example, try to track single car movement in Frogger (frogger.zip):

bochs_irregular_time.mp4

It moves with approximately equal speed, then jumps forward, then moves evenly again and so on.
Even ingame music suffers from this effect.

Same game in DOSBox produce smooth movement.

Version: d9d07c0.

@stlintel
Copy link
Contributor

I wonder if it is related to jumpy TSC in Windows XP ...

@Vort
Copy link
Contributor Author

Vort commented Jan 20, 2024

Frogger knows nothing about Power Management Timer.
These are separate problems.

@Vort
Copy link
Contributor Author

Vort commented Sep 4, 2024

Something is wrong with implementation of sync=slowdown.
If I add hack to call msleep a little less often, time jumps almost disappear:

diff --git a/bochs/iodev/slowdown_timer.cc b/bochs/iodev/slowdown_timer.cc
index 2d715f50c..cf4c456dd 100644
--- a/bochs/iodev/slowdown_timer.cc
+++ b/bochs/iodev/slowdown_timer.cc
@@ -144,7 +144,8 @@ void bx_slowdown_timer_c::handle_timer()
 #if BX_HAVE_USLEEP
     usleep(s.Q);
 #elif BX_HAVE_MSLEEP
-    msleep(usectomsec((Bit32u)s.Q));
+    if (rand() % 100 > 20)
+        msleep(usectomsec((Bit32u)s.Q));
 #elif BX_HAVE_SLEEP
     sleep(usectosec(s.Q));
 #else 

This is not proper solution of course. More investigation is needed.

@Vort
Copy link
Contributor Author

Vort commented Sep 4, 2024

I have no idea why, but my next hack allows to get smooth animations in games for me:

diff --git a/bochs/iodev/slowdown_timer.cc b/bochs/iodev/slowdown_timer.cc
index 2d715f50c..3535804b9 100644
--- a/bochs/iodev/slowdown_timer.cc
+++ b/bochs/iodev/slowdown_timer.cc
@@ -26,6 +26,8 @@
 #include "pc_system.h"
 #include "slowdown_timer.h"
 
+#include <chrono>
+
 #include <errno.h>
 #if !defined(_MSC_VER)
 #include <unistd.h>
@@ -59,6 +61,12 @@ bx_slowdown_timer_c::bx_slowdown_timer_c()
   s.timer_handle=BX_NULL_TIMER_HANDLE;
 }
 
+uint64_t get_monotonic_microseconds()
+{
+  return std::chrono::duration_cast<std::chrono::microseconds>(
+    std::chrono::steady_clock::now().time_since_epoch()).count();
+}
+
 void bx_slowdown_timer_c::init(void)
 {
   // Return early if slowdown timer not selected
@@ -73,7 +81,7 @@ void bx_slowdown_timer_c::init(void)
   if(s.MAXmultiplier<1)
     s.MAXmultiplier=1;
 
-  s.start_time = sectousec(time(NULL));
+  s.start_time = get_monotonic_microseconds();
   s.start_emulated_time = bx_pc_system.time_usec();
   s.lasttime=0;
   if (s.timer_handle == BX_NULL_TIMER_HANDLE) {
@@ -103,7 +111,7 @@ void bx_slowdown_timer_c::handle_timer()
 {
   Bit64u total_emu_time = (bx_pc_system.time_usec()) - s.start_emulated_time;
   Bit64u wanttime = s.lasttime+s.Q;
-  Bit64u totaltime = sectousec(time(NULL)) - s.start_time;
+  Bit64u totaltime = get_monotonic_microseconds() - s.start_time;
   Bit64u thistime=(wanttime>totaltime)?wanttime:totaltime;
 
 #if BX_SLOWDOWN_PRINTF_FEEDBACK 

I just arbitrarily changed less precise time() with more precise <chrono> equivalent.
Probably I broke something in the process (especially compatibility), but I hope it will give ideas about how to make proper fix.

I tested this hack not only with 1M IPS Frogger, but also with 5M IPS Superfrog. It is playable now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants