                   CRT unit for Intel Pentium (R) II >=266 MHz.

Original units:  CRT.TPU, CRT.TPP for Borland Pascal 7.0.
                 (C) 1983,1992 Borland.
Corrected units: CRT_PII.TPU, CRT_PII.TPP
                 Corrected by Paul Maximov, 1997.

   When I tried to run one of my programs on Intel Pentium (R) II
processor with frequency 266 MHz I encountered an error:
"Runtime error 200 at XXXX:0091", that means "Divide overflow".
   At first I thought it was something wrong with my processor.
But other programs contained no division operations caused this
error too. Later on I found out that this error occurs in all
programs that use CRT unit. Even in a very simple program like this:

   program test;
      uses CRT;
   begin
   end.

   The address where this error occurs is always XXXX:0091. When CRT unit
initializes it calculates how many empty cycles can the computer perform
during one timer interval (55 milliseconds). Then this value is divided
by 55 to obtain the number of cycles required to perform 1 millisecond delay.
This value is used in Delay procedure. The Delay procedure does not use
the system timer itself, it runs a number of empty cycles, this number of
cycles depending on the performance of a computer calculated during the
initialization phase of the unit.
   When a program runs on a powerful computer, such as Intel Pentium (R) II
based one, the calculated number of empty cycles during 55 milliseconds
becomes very high. This value is higher than 65535*55 and when we try to
divide this value by 55 we cause Divide Overflow interrupt.
   There are two ways to solve this problem:
   1) to increase the duration of one cycle so that the number of cycles
      during one timer interval would be less than 65535*55.
   2) to modify the division algorithm so that the result (number of cycles
      per millisecond) might be more than 65535. This could be done by
      subsequent executions of DIV command for high-order and low-order
      parts of the dividend.
   The first way is better for cracking already compiled programs. (I am
not sure, but I hope that it is rather easy to increase the duration of one
cycle).
   I used the second way. I edited Borland's source file CRT.ASM and compiled
CRT.PAS in real and protected modes. I used double-word (32-bit) value for the
number of cycles per millisecond instead of a single-word (16-bit) in
original Borland's unit.
   To use this unit, place CRT_PII.TPU and CRT_PII.TPP in your UNITS
directory of Turbo Pascal 7.0 and replace "uses CRT" string in your program
with "uses CRT_PII".
   Do not hesitate to use this unit even if you do not encounter such
errors. Your program will become more universal. I have tested my unit on
Intel386DX-20 and Amd486DX2-66. It works all right. Generally (if there are
no bugs in my unit :-), there is no difference between original Borland's
unit and my corrected one when working on slow computers.

   Finally, it should be noted that programs compiled in Turbo Pascal 6.0
do not cause this error but the time in Delay procedure is not correct.
Hence, there is a third way to use CRT unit on powerful computer:
to compile your program in Turbo Pascal 6.0 and to use your own, correct
delay procedure instead of the standard one.


Paul V.Maximov
maximov@ippi.ras.ru
maximov@ippi.ac.msk.su

