Go Premium for a chance to win a PS4. Enter to Win


One millisecond resolution is not enough!

Posted on 1998-09-20
Medium Priority
Last Modified: 2010-04-06
I am not very familiar with the internal workings of Windows, or the Windows API.  I know that in DOS you could easily manipulate the timer interrupt. How do you go about doing that in Delphi, or Windows in general?  Is it being unreasonable to set a timer at 1 MHz?

(note: I know about TTimer)
Question by:scrapdog

Expert Comment

ID: 1340316
Here is something(timer, I mean) with resolution 0.1 msec:
Z-timer on Delphi Super Page:
as the matter of fact I couldn't get it to work, co if you succeed, leave a comment how ;-)

Author Comment

ID: 1340317
Thanks for the tip.  I looked at the source code, and even though a lot of it confuses me (not the assembly code, but the windows functions), I will learn something by looking at it.  However, a component wasn't really what I was looking for.

I will elaborate of my question a little more.  The program PC64 for Windows emulates a Commodore 64, which is a computer that runs at about 1 MHz.  In order to execute instructions cycle-exact, some timing mechanism that runs at 1 MHz must be present in the program to carry out operations in the CPU.  

Or do emulation programs generally carry out a batch of instructions? (i.e. execute a batch of 1000 instructions every millisecond)

If the latter is the case, it is because it is not possible to set a timer to 1 MHz.  If it clearly is not possible to set a timer to that rate, I would like to know.

Other applications that use a timer with a very high resolution are applications that process sound.  Do sound applications use Timers with resolutions up to 44 KHz, or do they all use a Timer with an interval of 1 msec or more with buffers?  The question is not how to do it with buffers, the question is whether buffers MUST be used.

The main thing I am trying to get at:  is it typical for applications, including emulators and multimedia, to use timers of resolution much better than 1 msec?  And if so, how?

Thanks again to duke_n for his prompt reply.
LVL 20

Expert Comment

ID: 1340318

in windows it is dangerous to trust in lowlevel timers because windows is a multitasking system. Windows decides which application gets how much cpu time. So if Windows thinks that there is an application that is more important than yours, you'll get problems with the timers.
The better way is to use the "Application.Idle" event and asking win API "GetTickCount" in the event handler of this event.

Regards, Madshi.
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 1340319
Timers in NT and Win95+ are not a nice experience if your objective is other than to move around icons on the desktop. There is no good way to implement hires timers. Not even with kernelmode drivers.
Sound applications generally use buffers.
The multimedia timers (timeSetEvent) only have 1 millisecond resolution (not including timer latency).

Check QueryPerformanceCounter for very high granularity timers under NT.

/// John

Author Comment

ID: 1340320
So it is safe to assume that all emulation programs (such as PC64) execute instructions in a batch?

LVL 20

Expert Comment

ID: 1340321
I'm quite sure that these emulation programs does NOT install a timer at the cpu frequence of the emulated cpu. So they will have to use something like batch instructions...

Regards, Madshi.

Accepted Solution

wamoz earned 200 total points
ID: 1340322
High resolution timing under Windows is done using the Multimedia Timer Functions. If these aren't good enough then you have to build some custom hardware.

In the case of your "cycle-exact" emulator, I think you will find that it isn't cycle exact. What is most likely happening is that it is running rather faster than a C64, and every so often idles until the correct amount of time has elapsed.

Madshi sensibly warns you against trusting timers due to the pre-emptive nature of multi-tasking operating systems. There are three things you can do about this.

(1) Design your code on the expectation that it will occasionally miss a beat (literally) so that it doesn't matter. This is how streaming audio copes with packet loss and timing problems - it just drops late packets and plays whatever turns up exactly when the clock says they should be played.

(2) You can increase the priority of a thread to real-time, the purpose of which is self evident.

(3) Cut your code some slack. Size the batches of instructions (I refer to your own comment) so that their duty cycle is less than half of what is theoretically supported. When working this out, don't forget that there are other processes running.

I gather you want to do this sort of thing yourself. Boy have you jumped in at the deep end. Nevertheless, there's only one way to learn. If I wanted to do this I'd structure it as described in the previous paragraph. Controlling the wait state is most efficiently done by going into an idle loop that blocks on a simple flag. (repeat ... until bSynch).

If you want this to work under Win95 or in a multi-threaded application, don't forget to process the message queue inside the loop.

You tell the loop to exit using an event handler that you fire using timeSetEvent().

With respect to multimedia devices that require high frequency operation, they employ a similar clock synching strategy. For example, your sound card and your CPU dance an elaborate dance with the CPU bursting wave tables and and timing *descriptions* across a DMA channel in response to "more" requests expressed by the sound card using an interrupt and memory mapped I/O.

The following functions are used with multimedia timers. Most of these are documented to some degree in the Delphi help but if that's not enough I can furnish you with detailed APIs.


Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question