{ This unit is necessary because the delay() function provided by Borland's Pascal compiler does not properly handle modern fast computers. This code is adapted from the Borland C++ compiler. } unit cppdelay; interface procedure cdelay(milliseconds : word); implementation { procedure cdelay - wait for specified period in milliseconds. } const multiplier : longint = 1193*2; procedure dummy; near; begin end; { Name readtimer - read the complemented value of timer 0 Usage unsigned readtimer (void); Prototype in local Description Obtain the complement of the value in timer 0. The complement is used so that the timer will appear to count up rather than down. The value returned will range from 0 to 0xffff. Return value The complement of the value in timer 0. } function readtimer : word; near; var tempword : word; begin asm pushf cli mov al,0h out 43h,al end; dummy; asm in al,40h mov bl,al end; dummy; asm in al,40h mov bh,al not bx popf mov tempword,bx end; readtimer := tempword; end; { Name timer_init - initialize multiplier for delay function Usage void timer_init (void); Prototype in local Description Determine the multiplier required to convert milliseconds to an equivalent interval timer value. Interval timer 0 is normally programmed in mode 3 (square wave), where the timer is decremented by two every 840 nanoseconds; in this case the multiplier is 2386. However, some programs and device drivers reprogram the timer in mode 2, where the timer is decremented by one every 840 ns; in this case the multiplier is halved, i.e. 1193. When the timer is in mode 3, it will never have an odd value. In mode 2, the timer can have both odd and even values. Therefore, if we read the timer 100 times and never see an odd value, it's a pretty safe assumption that it's in mode 3. This is the method used in timer_init. Return value None } procedure timer_init; var i : integer; begin for i := 0 to 99 do begin if ((readtimer AND 1) = 0) then begin multiplier := 1193; exit; end; end; end; { Name cdelay - wait for specified period. Usage cdelay(milliseconds : word); Description The current thread of execution is suspended for the specified number of milliseconds. Return value None } procedure cdelay(milliseconds : word); var stop : longint; cur, prev : word; begin prev := readtimer; stop := prev + (milliseconds * multiplier); cur := readtimer; while (cur < stop) do begin if (cur < prev) then if (stop > $10000) then stop := stop - $10000; prev := cur; cur := readtimer; end; end; begin timer_init; end.