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

  1.                         HPTIMER Version 1.00
  2.                        By Rich Geldreich 1992
  3.                          April  20th, 1992
  4.  
  5.     HPTIMER is a high precision timer for QuickBASIC 4.5 programs.  It can
  6. be configured for any speed from 18.2  Hz to about 30,000 Hz (depending on
  7. your computer's speed).   It  can  also  interrupt  your  program  at  any
  8. specified period of time if you need it to.   (Have you ever tried to tell
  9. QB ON SLEEP(.5) GOTO xxx ?  Didn't work like expected, huh?  With HPTIMER,
  10. you  can  specify any time period,  from about 1 millisecond to 7.5 years!
  11. You can now also time your code with  as much precision as you want - much
  12. "cleaner" then QB's limited TIMER function.)
  13.  
  14.     I am placing this program in the public domain,  this isn't  shareware
  15. or  anything  and  I  don't  require anything in return for you using this
  16. program.  I am not responsible for anything this program does!  Of course,
  17. I have tested this  program  to  make  sure  that it works correctly,  but
  18. nobody is perfect.   (If anything does go wrong,  however,  the worst that
  19. could happen is a locked up computer.)
  20.  
  21.     You should of received the following seven files...
  22.  
  23.     HPTIMER.ASM..............TASM  v2.00   source   code (should   also
  24.                              assemble on MASM too, but I haven't tried)
  25.  
  26.     HPTIMER.QLB..............The quick library for HPTIMER
  27.  
  28.     HPTIMER.LIB..............The library for HPTIMER
  29.  
  30.     HPTIMER.OBJ..............The object code for HPTIMER(Just in case you
  31.                              don't  have an Assembler of you wish to
  32.                              combine HPTIMER with another program)
  33.  
  34.     EXAMPLE1.BAS.............Example program #1
  35.  
  36.     EXAMPLE2.BAS.............Example program #2
  37.  
  38.     README...................You'd better know what this is !
  39.  
  40.     History...
  41.  
  42.     There isn't much history to this program.   It's really pretty simple.
  43. For the past couple weeks,   I've  been  quietly  reading  messages  on  a
  44. QuickBASIC  echo  about the "TIMER" function.   Most of the posters didn't
  45. realize that the TIMER  function  is  only  accurate  to about 1/18.2 of a
  46. second.   I made this program to enable users to time their code  with  as
  47. much precision as they wanted.  (The routines do have other uses, but I'll
  48. leave it up to you to discover them...)
  49.  
  50.     Another  neat  feature  of  HPTIMER  is  it's  ability  to invoke QB's
  51. SetUEvent trap at any specified  time period.   At HPTIMER's slowest rate,
  52. you can have a maximum delay of about 7.5 years!
  53.  
  54.  
  55.     How to use it...
  56.  
  57.     You must load in QB like this before you can use HPTIMER:
  58.  
  59.     QB/lhptimer.qlb
  60.  
  61.     This tells QB to load in the quick library I have supplied.
  62.  
  63.     There are four functions used in controlling the timer,   and  another  four
  64. functions that control the alarm.  They are:
  65.  
  66.     InitTimer  -    Initializes the timer.   No timing functions can be
  67.                     used unless the timer is initialized first.
  68.                     Parameters: An integer value which is sent to the delay
  69.                     latch of the 8253. This is not the frequency! If you
  70.                     want to set the timer to a  certain  rate,   use
  71.                     this formula:
  72.  
  73.                     (Delay Value) = 1193180/(frequency in hertz)
  74.  
  75.                     To set the timer to 5,000 cycles a second, use this:
  76.  
  77.                     InitTimer (1193180/5000)
  78.  
  79.                     Where 1193180 is the clock frequency of the 8253 timer.
  80.  
  81.     DetachTimer -   Turns off the timer. If the timer was never attached,
  82.                     or the vector to interrupt 8 was destroyed, then this
  83.                     function will do nothing.
  84.                     Parameters: None.
  85.  
  86.     SetTimer    -   Sets the timer. What else would it do?
  87.                     Parameters:  An long  integer  value  to set the
  88.                     clock to.  To reset the timer, use this:
  89.  
  90.                     SetTimer 0
  91.  
  92.  
  93.     GetTimer    -   Gets  the  current clock count.
  94.                     Parameters:  A long integer variable.
  95.  
  96.                     GetTimer NumClicks&
  97.  
  98.  
  99.     Alarm functions...
  100.  
  101.  
  102.  
  103.     AlarmOn     -   Enables the alarm.
  104.                     Parameters: None.
  105.  
  106.     AlarmOff    -   Disables the alarm.
  107.                     Parameters: None.
  108.  
  109.     GetAlarm    -   Gets the current alarm value.   I know,  it's not that
  110.                     useful, but it may come in handy some day...
  111.                     Parameters: A long integer.
  112.  
  113.     SetAlarm    -   Sets the clock value  at  which  the  alarm  will  be
  114.                     triggered.
  115.                     Parameters: A long integer.
  116.  
  117.                     For example,  to invoke the alarm at 3,000 click
  118.                     ticks, use this code:
  119.  
  120.                     SetTimer 0                <--- reset the timer to 0
  121.                     SetAlarm 3,000            <--- set alarm to 3,000 ticks
  122.                     AlarmOn                   <--- enable alarm
  123.                     UEVENT ON                 <--- enable QB trapping of
  124.                                                    the UEVENT function
  125.  
  126.  
  127. ------------------------------------------------------------------------------
  128.  
  129.          YOU MUST DETACH THE TIMER BEFORE THE  PROGRAM  EXITS! IF  YOU
  130.                     DON'T, YOU RISK HANGING UP THE COMPUTER
  131.                          WHEN YOUR PROGRAM TERMINATES!
  132.  
  133. Also note  that  SHELLing  to  another  program  (SHELL  "COMMAND.COM"  or
  134. something)  could  possibly  destroy  HPTIMER's interrupt vector.   If the
  135. program  behaves  correctly,   then  when  it  ends  it  should re-install
  136. HPTIMER's interrupt vector and leave thing the way they  were.    No  harm
  137. done, but the timer will of course be inaccurate.
  138.  
  139. ------------------------------------------------------------------------------
  140.  
  141.     Notes while using HPTIMER in the QuickBASIC environment:
  142.  
  143.     First  of  all,   you  should  know  that HPTIMER attempts to keep the
  144. system's clock as accurate as possible while it is in use(It may drift, or
  145. even stop,  at extremely high  speeds).    Also,   the quicker you set the
  146. timer,  the slower your code will go.   (Although you probably  won't  see
  147. this occur unless you set the timer to a very, very high rate.)
  148.  
  149.     Don't  forget  the  timer  is  only 32 bits!   It you set the timer to
  150. 10,000 hz, then the maximum time period you can time can be calculated by:
  151. (65536+65536#*65535)/10000 or (2^32)/10000
  152.  
  153.     It  seems  that  QB  fiddles   with   interrupt  8  while  inside  the
  154. environment.   For instance,  if your timing some code,   and  you  strike
  155. control break to stop the program,  and then continue it with F5, then the
  156. timer  probably  will be at a dead stop because QB turned it off.   Not to
  157. worry,  DetachTimer checks for  this  condition  and  does nothing if this
  158. occurs.   This is why I recommend that you call DetachTimer before you try
  159. to attach it.  Consider this scenario:
  160.  
  161.     You press shift+F5 to run your program.   While it's timing,  you  hit
  162. Ctrl+Break to stop it.   QB (usually, I can't tell when it does it though)
  163. takes  over  interrupt  8,  leaving  HPTIMER in the dust.   Then you press
  164. shift+F5 to run the program all over again.   Utt Ow!   You forget to tell
  165. HPTIMER to  turn  itself  off.    So  that  is  why  I  recommend  you put
  166. DetachTimer in the beginning of your program.  Clear as mud, huh?...
  167.  
  168.     If you still don't understand, then see the two example programs.
  169.  
  170.     I pray that I have implemented the interrupt code correctly.   If  you
  171. any problems or suggestions, then write/call to...
  172.  
  173.     Rich Geldreich, Jr.
  174.     410 Market St.
  175.     Gloucester City, NJ 08030
  176.     (609)-456-0721
  177.  
  178.     I'll be glad to answer any questions you have.
  179.  
  180.  
  181.     NOTE: I almost stopped making this program because I couldn't get QB's
  182. "SetUEvent"  function to work correctly within the environment.   For some
  183. reason,  the following code hanged up after a while or didn't even work at
  184. all: (remember, this is in an interrupt procedure!)
  185.  
  186.         (ax and bx are already on the stack)
  187.         push cx
  188.         push dx
  189.         push bp
  190.         push si
  191.         push di
  192.         push ds
  193.         push es
  194.         call far ptr SetUevent        <--- call QB's setuevent procedure
  195.         pop  es
  196.         pop  dx
  197.         pop  di
  198.         pop  si
  199.         pop  bp
  200.         pop  dx
  201.         pop  cx
  202.  
  203.  
  204.          I tried for hours to get that little fragment of code to work.
  205.  
  206.     Thank God for Dos's DEBUG  command.    I put a breakpoint right before
  207. the call to the setuevent function, and traced the code.
  208.  
  209.     Aaaa!!   I found out that when you call the SetUEvent procedure,   you
  210. must  have  DS  pointing to QB's data segment!   How stupid!   Why doesn't
  211. SetUEvent take care of this?  It seems that QB does something like this in
  212. the midst of it's SetUEvent code:
  213.  
  214.         JMP FAR [00BE]
  215.  
  216.     If DS isn't set up correctly, then who knows where the CPU would go.
  217.  
  218.     The reason why the code worked  some of the time is simple:  sometimes
  219. the interrupt code would stop QB while DS was set to  QB's  data  segment.
  220. Sometimes it would not.
  221.  
  222.     The following code solved the problem:
  223.  
  224.         push cx
  225.         push dx
  226.         push bp
  227.         push si
  228.         push di
  229.         push ds
  230.         push es
  231.         mov  ds, [cs:QB_data_segment]
  232.         call far ptr SetUevent                <--- call QB's setuevent procedure
  233.         pop  es
  234.         pop  dx
  235.         pop  di
  236.         pop  si
  237.         pop  bp
  238.         pop  dx
  239.         pop  cx
  240.  
  241.     When  you call InitTimer,  the QB_data_segment variable is set to QB's
  242. data segment.  I hope that helps somebody out there!
  243.  
  244.  
  245. Other stuff...
  246.  
  247.     Remember, if you press Ctrl+Break while HPTIMER is active I don't what
  248. could  possibly happen!   At low speeds(<7000 or so),  QB seems to do just
  249. fine...   Anything that revectors interrupt  8  (the SOUND & PLAY commands
  250. do) will clobber HPTIMER!   (The BEEP command works  okay,   for  whatever
  251. that's worth!)
  252.     The  best  way  to  determine  what  bothers  interrupt  8  is to just
  253. experiment... have fun and good luck
  254.  
  255.  
  256.  
  257.  
  258.  
  259.