home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progbas
/
hptimer.arj
/
README.DOC
< prev
Wrap
Text File
|
1992-04-23
|
10KB
|
259 lines
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