|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Supporting functions for timekeeping in event.h ! 5: * ! 6: * Copyright 1995-2007 Bernd Schmidt ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: ! 12: #include <ctype.h> ! 13: #include <assert.h> ! 14: ! 15: #include "options.h" ! 16: #include "threaddep/thread.h" ! 17: #include "uae.h" ! 18: #include "gensound.h" ! 19: #include "sounddep/sound.h" ! 20: #include "events.h" ! 21: #include "memory.h" ! 22: #include "custom.h" ! 23: ! 24: /* Events */ ! 25: ! 26: unsigned long int currcycle, nextevent; ! 27: struct ev eventtab[ev_max]; ! 28: ! 29: /* Time taken for one frame given the current display settings ! 30: (NTSC vs. PAL). */ ! 31: frame_time_t vsynctime; ! 32: /* Timestamps of the next VSYNC event. */ ! 33: frame_time_t vsyncmintime; ! 34: ! 35: int vsyncmintime_valid; ! 36: ! 37: /* Set if gettimeofday has high enough resolution for our purposes. */ ! 38: int use_gtod = 0; ! 39: ! 40: /* Adjusted in do_cycles to keep track of how many gettimeofday calls ! 41: we can safely afford to skip. */ ! 42: unsigned long nr_gtod_to_skip = 50000; ! 43: /* An upper bound on the previous value, determined at runtime. */ ! 44: unsigned long max_gtod_to_skip = ULONG_MAX; ! 45: ! 46: /* First time we measured in do_cycles when waiting for vsyncmintime. */ ! 47: frame_time_t first_measured_gtod; ! 48: /* Number of gettimeofday calls while waiting for vsyncmintime. ! 49: Affected by nr_gtod_to_skip. */ ! 50: unsigned long nr_gtod_done; ! 51: /* A counter used internally by do_cycles to skip calls to gettimeofday. */ ! 52: unsigned long gtod_counter; ! 53: ! 54: int rpt_available = 0; ! 55: ! 56: int is_lastline; ! 57: volatile int blocking_on_sound; ! 58: ! 59: void reset_frame_rate_hack (void) ! 60: { ! 61: if (currprefs.m68k_speed != -1) ! 62: return; ! 63: ! 64: if (! rpt_available) { ! 65: currprefs.m68k_speed = 0; ! 66: return; ! 67: } ! 68: ! 69: vsyncmintime_valid = 0; ! 70: is_lastline = 0; ! 71: vsyncmintime = get_current_time(1); ! 72: vsyncmintime += vsynctime; ! 73: write_log ("Resetting frame rate hack\n"); ! 74: } ! 75: ! 76: void compute_vsynctime (void) ! 77: { ! 78: vsynctime = syncbase / vblank_hz; ! 79: if (use_gtod) ! 80: vsynctime -= gtod_resolution < 100 ? 100 : gtod_resolution; ! 81: if (currprefs.produce_sound > 1) { ! 82: vsynctime = vsynctime * 19 / 20; ! 83: } ! 84: } ! 85: ! 86: void time_vsync (void) ! 87: { ! 88: if (vsyncmintime_valid) { ! 89: frame_time_t measured = vsyncmintime - first_measured_gtod; ! 90: unsigned long ideal; ! 91: if (nr_gtod_done) { ! 92: if (use_gtod && gtod_resolution < measured) ! 93: measured -= gtod_resolution; ! 94: /* Interval between gettimeofday calls. */ ! 95: measured /= nr_gtod_done; ! 96: ! 97: /* syncbase has the number of ticks in one second. ! 98: Hence, syncbase / 5000 ~= 0.2ms. We want to have at least 100 ! 99: gtod calls per frame. */ ! 100: if (measured < syncbase / 5000) { ! 101: if (max_gtod_to_skip == ULONG_MAX) ! 102: max_gtod_to_skip = nr_gtod_to_skip; ! 103: else ! 104: max_gtod_to_skip = max_gtod_to_skip * 19 / 20; ! 105: } ! 106: } ! 107: } ! 108: ! 109: if (currprefs.m68k_speed == -1) { ! 110: frame_time_t curr_time = get_current_time (1); ! 111: /* If we got behind in one frame, try catching up by using the ! 112: previous vsyncmintime as a base. If we get too far behind, ! 113: give up and reset. */ ! 114: if (vsyncmintime_valid ! 115: && curr_time > vsyncmintime ! 116: && curr_time < vsyncmintime + vsynctime / 2) ! 117: vsyncmintime += vsynctime; ! 118: else ! 119: vsyncmintime = curr_time + vsynctime; ! 120: nr_gtod_done = 0; ! 121: vsyncmintime_valid = 1; ! 122: } else { ! 123: if (vsyncmintime_valid ! 124: && (use_gtod ! 125: #ifdef RPT_WORKS_OK ! 126: || RPT_WORKS_OK ! 127: #endif ! 128: )) ! 129: { ! 130: frame_time_t curr_time; ! 131: do ! 132: curr_time = get_current_time (0); ! 133: while ((long int)(get_current_time (0) - vsyncmintime) < 0); ! 134: } ! 135: vsyncmintime = get_current_time (1) + vsynctime; ! 136: vsyncmintime_valid = 1; ! 137: } ! 138: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.