home *** CD-ROM | disk | FTP | other *** search
- HPTIMER Version 1.00
- By Rich Geldreich 1992
- April 20th, 1992
-
- HPTIMER is a high precision timer for QuickBASIC 4.5 programs. It can
- be configured for any speed from 18.2 Hz to about 30,000 Hz (depending on
- your computer's speed). It can also interrupt your program at any
- specified period of time if you need it to. (Have you ever tried to tell
- QB ON SLEEP(.5) GOTO xxx ? Didn't work like expected, huh? With HPTIMER,
- you can specify any time period, from about 1 millisecond to 7.5 years!
- You can now also time your code with as much precision as you want - much
- "cleaner" then QB's limited TIMER function.)
-
- I am placing this program in the public domain, this isn't shareware
- or anything and I don't require anything in return for you using this
- program. I am not responsible for anything this program does! Of course,
- I have tested this program to make sure that it works correctly, but
- nobody is perfect. (If anything does go wrong, however, the worst that
- could happen is a locked up computer.)
-
- You should of received the following seven files...
-
- HPTIMER.ASM..............TASM v2.00 source code (should also
- assemble on MASM too, but I haven't tried)
-
- HPTIMER.QLB..............The quick library for HPTIMER
-
- HPTIMER.LIB..............The library for HPTIMER
-
- HPTIMER.OBJ..............The object code for HPTIMER(Just in case you
- don't have an Assembler of you wish to
- combine HPTIMER with another program)
-
- EXAMPLE1.BAS.............Example program #1
-
- EXAMPLE2.BAS.............Example program #2
-
- README...................You'd better know what this is !
-
- History...
-
- There isn't much history to this program. It's really pretty simple.
- For the past couple weeks, I've been quietly reading messages on a
- QuickBASIC echo about the "TIMER" function. Most of the posters didn't
- realize that the TIMER function is only accurate to about 1/18.2 of a
- second. I made this program to enable users to time their code with as
- much precision as they wanted. (The routines do have other uses, but I'll
- leave it up to you to discover them...)
-
- Another neat feature of HPTIMER is it's ability to invoke QB's
- SetUEvent trap at any specified time period. At HPTIMER's slowest rate,
- you can have a maximum delay of about 7.5 years!
-
-
- How to use it...
-
- You must load in QB like this before you can use HPTIMER:
-
- QB/lhptimer.qlb
-
- This tells QB to load in the quick library I have supplied.
-
- There are four functions used in controlling the timer, and another four
- functions that control the alarm. They are:
-
- InitTimer - Initializes the timer. No timing functions can be
- used unless the timer is initialized first.
- Parameters: An integer value which is sent to the delay
- latch of the 8253. This is not the frequency! If you
- want to set the timer to a certain rate, use
- this formula:
-
- (Delay Value) = 1193180/(frequency in hertz)
-
- To set the timer to 5,000 cycles a second, use this:
-
- InitTimer (1193180/5000)
-
- Where 1193180 is the clock frequency of the 8253 timer.
-
- DetachTimer - Turns off the timer. If the timer was never attached,
- or the vector to interrupt 8 was destroyed, then this
- function will do nothing.
- Parameters: None.
-
- SetTimer - Sets the timer. What else would it do?
- Parameters: An long integer value to set the
- clock to. To reset the timer, use this:
-
- SetTimer 0
-
-
- GetTimer - Gets the current clock count.
- Parameters: A long integer variable.
-
- GetTimer NumClicks&
-
-
- Alarm functions...
-
-
-
- AlarmOn - Enables the alarm.
- Parameters: None.
-
- AlarmOff - Disables the alarm.
- Parameters: None.
-
- GetAlarm - Gets the current alarm value. I know, it's not that
- useful, but it may come in handy some day...
- Parameters: A long integer.
-
- SetAlarm - Sets the clock value at which the alarm will be
- triggered.
- Parameters: A long integer.
-
- For example, to invoke the alarm at 3,000 click
- ticks, use this code:
-
- SetTimer 0 <--- reset the timer to 0
- SetAlarm 3,000 <--- set alarm to 3,000 ticks
- AlarmOn <--- enable alarm
- UEVENT ON <--- enable QB trapping of
- the UEVENT function
-
-
- ------------------------------------------------------------------------------
-
- YOU MUST DETACH THE TIMER BEFORE THE PROGRAM EXITS! IF YOU
- DON'T, YOU RISK HANGING UP THE COMPUTER
- WHEN YOUR PROGRAM TERMINATES!
-
- Also note that SHELLing to another program (SHELL "COMMAND.COM" or
- something) could possibly destroy HPTIMER's interrupt vector. If the
- program behaves correctly, then when it ends it should re-install
- HPTIMER's interrupt vector and leave thing the way they were. No harm
- done, but the timer will of course be inaccurate.
-
- ------------------------------------------------------------------------------
-
- Notes while using HPTIMER in the QuickBASIC environment:
-
- First of all, you should know that HPTIMER attempts to keep the
- system's clock as accurate as possible while it is in use(It may drift, or
- even stop, at extremely high speeds). Also, the quicker you set the
- timer, the slower your code will go. (Although you probably won't see
- this occur unless you set the timer to a very, very high rate.)
-
- Don't forget the timer is only 32 bits! It you set the timer to
- 10,000 hz, then the maximum time period you can time can be calculated by:
- (65536+65536#*65535)/10000 or (2^32)/10000
-
- It seems that QB fiddles with interrupt 8 while inside the
- environment. For instance, if your timing some code, and you strike
- control break to stop the program, and then continue it with F5, then the
- timer probably will be at a dead stop because QB turned it off. Not to
- worry, DetachTimer checks for this condition and does nothing if this
- occurs. This is why I recommend that you call DetachTimer before you try
- to attach it. Consider this scenario:
-
- You press shift+F5 to run your program. While it's timing, you hit
- Ctrl+Break to stop it. QB (usually, I can't tell when it does it though)
- takes over interrupt 8, leaving HPTIMER in the dust. Then you press
- shift+F5 to run the program all over again. Utt Ow! You forget to tell
- HPTIMER to turn itself off. So that is why I recommend you put
- DetachTimer in the beginning of your program. Clear as mud, huh?...
-
- If you still don't understand, then see the two example programs.
-
- I pray that I have implemented the interrupt code correctly. If you
- any problems or suggestions, then write/call to...
-
- Rich Geldreich, Jr.
- 410 Market St.
- Gloucester City, NJ 08030
- (609)-456-0721
-
- I'll be glad to answer any questions you have.
-
-
- NOTE: I almost stopped making this program because I couldn't get QB's
- "SetUEvent" function to work correctly within the environment. For some
- reason, the following code hanged up after a while or didn't even work at
- all: (remember, this is in an interrupt procedure!)
-
- (ax and bx are already on the stack)
- push cx
- push dx
- push bp
- push si
- push di
- push ds
- push es
- call far ptr SetUevent <--- call QB's setuevent procedure
- pop es
- pop dx
- pop di
- pop si
- pop bp
- pop dx
- pop cx
-
-
- I tried for hours to get that little fragment of code to work.
-
- Thank God for Dos's DEBUG command. I put a breakpoint right before
- the call to the setuevent function, and traced the code.
-
- Aaaa!! I found out that when you call the SetUEvent procedure, you
- must have DS pointing to QB's data segment! How stupid! Why doesn't
- SetUEvent take care of this? It seems that QB does something like this in
- the midst of it's SetUEvent code:
-
- JMP FAR [00BE]
-
- If DS isn't set up correctly, then who knows where the CPU would go.
-
- The reason why the code worked some of the time is simple: sometimes
- the interrupt code would stop QB while DS was set to QB's data segment.
- Sometimes it would not.
-
- The following code solved the problem:
-
- push cx
- push dx
- push bp
- push si
- push di
- push ds
- push es
- mov ds, [cs:QB_data_segment]
- call far ptr SetUevent <--- call QB's setuevent procedure
- pop es
- pop dx
- pop di
- pop si
- pop bp
- pop dx
- pop cx
-
- When you call InitTimer, the QB_data_segment variable is set to QB's
- data segment. I hope that helps somebody out there!
-
-
- Other stuff...
-
- Remember, if you press Ctrl+Break while HPTIMER is active I don't what
- could possibly happen! At low speeds(<7000 or so), QB seems to do just
- fine... Anything that revectors interrupt 8 (the SOUND & PLAY commands
- do) will clobber HPTIMER! (The BEEP command works okay, for whatever
- that's worth!)
- The best way to determine what bothers interrupt 8 is to just
- experiment... have fun and good luck
-
-
-
-
-
-