[Back to TIMING SWAG index] [Back to Main SWAG index] [Original]

    {$A+,B-,E-,F-,I-,N-,O-,R-,S-,V-}

    (*
    FastWait               Copyright (c) 1991  Southern Software

    Version 1.00 - 4/8/91

    Allows PC's faster than 20 mhz (386/486) to properly use a delay
    function based upon a null looping procedure such as is used in the
    Turbo Pascal "Delay" procedure.  Wait is accurate for PC's as fast as
    1,100 mhz equivalent!

    USAGE: Simply place "FastWait" in the Uses section of your program
           and replace each occurrence of "delay" in your program with
           "wait".

    Example-
    =======

         Existing program:
         ----------------
         Uses CRT;

         begin
         writeln('This program delays for 5 seconds.);
         delay(5000);
         end.

         New program:
         -----------
         Uses FastWait, CRT;                {Now also uses "FastWait"}

         begin
         writeln('This program delays for 5 seconds.);
         wait(5000);                        {changed "delay" to "wait"}
         end.
    *)

    unit FastWait;

      (*   Version 1.00 - 4/8/91  *)

      {$ifdef DEBUG}
        {$D+,L+}
      {$else}
        {$D-,L-}
      {$endif}

    (****************************************************************************)
     interface
    (****************************************************************************)

    var
                       (* Number of loops to do for 1 ms wait.                  *)
      WaitOneMS : word;

                       (* Number of loops per timer tick.                       *)
      LoopsPerTick : longint;

                       (* System timer, 18.2/second.                            *)
      BIOSTick : longint absolute $40:$6C;

                       (* Pauses execution for "ms" milliseconds. *)
    procedure Wait(ms : word);

    {$ifdef VER60}

                     (* This procedure is for very short timing loops ( < 1ms)
                        that cannot be handled by the delay routine.

                        The variable "LoopsPerTick" has the number of loops
                        to do for one BIOS tick (18.2 of these/sec). If you
                        want to delay for "X" æs, the number of loops required
                        would be  "(LoopsPerTick * X) div 54945". This will not
                        compile if you are using TP 4.0, 5.0 or 5.5 due to the
                        conditional defines. This is because it makes use of
                        the "asm" statement which is not available in TP
                        versions prior to 6.0. *)

     procedure ShortDelay(NumLoops : word);

    {$endif}

    (****************************************************************************)
     implementation
    (****************************************************************************)

      {$L WAIT.OBJ}

      procedure Wait(ms : word); external;

      procedure WaitInit; external;

    {$ifdef VER60}

      procedure ShortDelay(NumLoops : word); assembler;
      asm
        mov  cx,NumLoops
        jcxz @@2
        xor  di,di         (* ES:DI points to dummy address *)
        mov  es,di         (* which won't change *)
        mov  al,es:[di]    (* AL has the value there *)
       @@1:
        cmp  al,es:[di]
        jne  @@2
        loop @@1
       @@2:
      end;

    {$endif}

    BEGIN              (* Code to execute at start-up to calibrate the loop     *)
                       (* delay.                                                *)
      WaitInit
    END.

    { XX3402 Code to WAIT.OBJ
    { Cut and save as WAIT.XX.  Execute : XX3402 D WAIT.XX to create WAIT.OBJ }
    { ------------------   CUT HERE -------------------------- }

    *XX3402-000319-080491--72--85-45848--------WAIT.OBJ--1-OF--1
    U+c+03R-GJEiEJBB8cUU++++J5JmMawUELBnNKpWP4Jm60-KNL7nOKxi616iA145W-++ECbg
    gsUK03R-GJEiEJBBhcU1+21dH7M0++-cW+A+E84IZUM+-2F-J234a+Q+8++++U2-BNM4++F1
    HoF3FNU5+0VR++A-+RSA4U+7Jo37J2xCFIpH++lAHoxEIp-3IZF7Eog+vt+D+++003R-GJF7
    HYZI8+++ld+9+++0-3R-GJE6+++WW+E+E86-YO-V++6++0Mu-LI0sjb1WxkqWpQ20x7o2nDz
    XgQaWUK95U++Wwjcrjx8RTX8+U0sE+0Ck9xg+9bzznDG7cc37Xc3RDgaWUIaCUJp-S9tEijq
    i1Q+YTTEck++WFM0+DTlck++kzWQ3E124kM-+QFF-U20l3I4+E92KUM-+E88+U++R+++
    ***** END OF BLOCK 1 *****

    { --------------------------   CUT HERE ------------------------   }
    { TEST PROGRAM }

    program TestWait;
    uses
      crt,
      FastWait;

    var
      Counter : word;
      jj : longint;

    BEGIN
      clrscr;
      HighVideo;
      writeln('           Southern Software  (c) 1991'#10);
      LowVideo;
      writeln('This test compares the standard "delay" routine with our new "Wait"');
      writeln('procedure.  Below is the calculated number of small loops the PC goes');
      writeln('through for one millisecond delay.  If this number is above 1,191 then');
      writeln('the "delay" routine in the Turbo CRT unit as well as those in the');
      writeln('TurboPower Software Object Professional and Turbo Professional series');
      writeln('will yield delays that are too short.  Our "wait" procedure is the same');
      writeln('as the "delay" procedure except that it will adjust for faster machines.');
      writeln;
      writeln('The looping below is for 10 seconds in each case.  The seconds are shown');
      writeln('and at the end, the number of BIOS ticks is shown.  A properly calibrated');
      writeln('delay routine should be almost exactly 10 seconds long, which is 182 ticks.');
      writeln;
      writeln('To abort at any time, press any key.');
      writeln(#10);
      write('The delay factor for this machine is actually ');
      HighVideo;
      writeln(WaitOneMS);
      LowVideo;
      writeln(#10);
      writeln('10 second delays using');
      write('    CRT unit "delay" : ');
      HighVideo;
                       (* Delay 10 seconds using the CRT unit "delay" routine.  *)
      jj := BIOSTick;
      repeat
      until (jj <> BIOSTick);
      jj := BIOSTick;
      for Counter := 1 to 10 do
        begin
          delay(1000);
          write(Counter)
        end;
      jj := (BIOSTick - jj);
      LowVideo;
      write('         BIOS Ticks : ');
      HighVideo;
      writeln(jj);
      LowVideo;
      write('FastWait unit "wait" : ');
      HighVideo;
                       (* Delay 10 seconds using FastWait unit "wait" routine.  *)
      jj := BIOSTick;
      repeat
      until (jj <> BIOSTick);
      jj := BIOSTick;
      for Counter := 1 to 10 do
        begin
          wait(1000);
          write(Counter)
        end;
      jj := (BIOSTick - jj);
      LowVideo;
      write('         BIOS Ticks : ');
      HighVideo;
      writeln(jj, #10);
      LowVideo;
      write('Press any key to end ');
      repeat
      until keypressed;
      while keypressed do
        Counter := ord(ReadKey);
      clrscr
    END.

[Back to TIMING SWAG index] [Back to Main SWAG index] [Original]