Рекомендации по улучшению работоспособности файлов,
           содержащих модуль CRT из Паскаля версии 7 фирмы Borland.
                                    v 3.0 beta

                              Copyright (c) 22.09-21.10.1999 by Фёдор Меньшиков

          Автор рекомендации не несёт ответственности за любой вред,
          нанесённый вследствие применения описанных здесь действий.

Признак проблемы:
   На быстрых компьютерах (Pentium II и старше)
      программа сразу кончается с надписью Runtime error 200 at XXXX:YYYY
         (XXXX, YYYY - четырёхзначные шестнадцатеричные числа)

Компиляторы, создающие такой код:
   Borland (с входящим в его состав Turbo) Pascal 7.00-7.01
   Самостоятельная версия Turbo Pascal 7.00 (без BP) не имеет такой ошибки.

Введение.
   Ниже приводятся способы борьбы с данной проблемой. Каждый обладает своими
   достоинствами и недостатками. Какой из них применить - решать Вам.

Гарантия:
   В исправленном файле не будет возникать ошибок, связанных с CRT, и
   относящихся к реализации Delay в нём, ведущих к прерыванию программы.

Для разрабатывающихся программ - выполнить рекомендации для следующих файлов:
   CRT для TP/real mode BP находится в turbo.tpl
   CRT для protected mode BP находится в tpp.tpl

Проблемы, возникающие при использовании данных методов:
   1. Если одинаковых цепочек несколько, скорее всего, нужно выбрать первые
   2. Если цепочек нет, возможно, этот файл
      а) компилировался не рассматриваемыми компиляторами
      б) сжат программами типа LZEXE
      в) уже неудачно исправлен

Испытано на:
   turbo.tpl из BP 7.00
   tpp.tpl из BP 7.00
   файле, откомпилированном BP 7.01 в real mode.


                                    Метод 0.
Достоинства:
   Нужно изменить всего один байт.

Недостатки:
   Delay будет работать с расчётной задержкой в узком интервале скоростей
   процессора. Даже на 486 задержка меньше. На более быстрых процессорах
   задержка будет совсем незаметна.

Вывод:
   Удобен для исправления exe-файлов, в которых не используется Delay.

Рекомендации:
   Найти в файле цепочку байтов
      02 f7 d0 f7 d2
   заменить на (приведено новое значение байтов, которые нужно изменять)
      __ __ __ 33 __


                                    Метод 1.
Достоинства:
   Погрешность задержки при использовании Delay может достигать 50% (программа
   будет работать в два раза быстрей, чем предполагалось) на младших моделях
   Pentium II. На старших моделях погрешность практически не ощущается. На
   более быстрых процессорах она будет совсем незаметна.

Недостатки:
1. Данный метод позволяет исправленным программам правильно работать на быстрых
   компьютерах, но искажает задержки при использовании процедуры Delay
   на медленных компьютерах (увеличивает задержку: чем медленнее процессор,
   тем больше задержка).
2. В будущем на компьютерах, которые будут быстрее Pentium II (233-450MHz)
   в 300 раз, исправленный Delay будет работать некорректно: задержка будет
   меньше расчётной. Вообще говоря, до 2015 года можно спать спокойно.

Вывод:
   На компьютере, работающем на скорости от Pentium II до в 300 раз большей
   удобен для исправления exe-файлов, в которых использовался Delay.

Рекомендации:
   1. Найти в файле цепочку байтов
         2d 01 00 83 da 00 72 (контрольное продолжение 05 26)
      заменить на
         33 d2 4a 75 fd 48 74
   2. Найти в файле цепочку байтов (до первой цепочки)
         b8 e4 ff 99 e8 3c 02 f7 d0 f7 d2 (для real mode)
         -- -- -- -- -- 56 -- -- -- -- -- (для protected mode)
      заменить на (приведено новое значение байтов, которые нужно изменять)
         __ ff __ 90 __ __ __ __ __ 33 __  


                                    Метод 2.
Достоинства:
   Файлы, исправленные по этой методике, будут работать на любом компьютере
   от 8088 до в миллионы и миллиарды раз быстрее Pentium II.

Недостатки:
   На любом процессоре Delay будет давать погрешность до 50%.

Вывод:
   Ввиду независимости от скорости процессора удобен для разработки собственных
   программ (исправления tpl файлов).

Рекомендации:
   1. Найти в файле цепочку байтов
         2d 01 00 83 da 00 72 05 26 3a 1d 74 f3
      заменить на
         90 90 90 48 74 06 e8 f7 ff e8 f7 ff 40
   2. Найти в файле цепочку байтов (до первой цепочки)
         b8 e4 ff 99 e8 3c 02 f7 d0 f7 d2 b9 37 00 f7 f1(real mode)
         -- -- -- -- -- 56 -- -- -- -- -- -- -- -- -- --(protected mode)
      заменить на
         e8 40 02 40 26 3a 1d 74 f7 2d 06 00 90 90 90 90(real mode)
         -- 5a -- -- -- -- -- -- -- -- -- -- -- -- -- --(protected mode)

                                   ОБЪЯСНЕНИЕ

                             (на примере real mode)
                          (все числа шестнадцатеричные)
******************************> Исходный вариант <*****************************
//Подпрограмма считает число циклов до тика
02C6 2D0100         sub    ax,0001
02C9 83DA00         sbb    dx,0000
02CC 7205           jb     02D3
02CE 263A1D         cmp    bl,es:[di]
02D1 74F3           je     02C6
02D3 C3             ret
//Фрагмент, вызывающий ^ для инициализации
0080 268A1D         mov    bl,es:[di]
0083 B8E4FF         mov    ax,FFE4
0086 99             cwd
0087 E83C02         call   02C6
008A F7D0           not    ax
008C F7D2           not    dx
008E B93700         mov    cx,0037
0091 F7F1           div    cx       //Вот здесь-то и было деление на ноль
*******************************************************************************
**********************************> Метод 1. <*********************************
//
02C6 33D2           xor    dx,dx    //В принципе, можно и "mov dx,ss"
02C8 4A             dec    dx
02C9 75FD           jne    02C8
02CB 48             dec    ax
02CC 7405           je     02D3
02CE 263A1D         cmp    bl,es:[di]
02D1 74F3           je     02C6
02D3 C3             ret
//
0080 268A1D         mov    bl,es:[di]
0083 B8FFFF         mov    ax,FFFF  //Цикл большой, остальное учитывать не надо
0086 90             nop
0087 E83C02         call   02C6
008A F7D0           not    ax
008C 33D2           xor    dx,dx
008E B93700         mov    cx,0037
0091 F7F1           div    cx
*******************************************************************************
**********************************> Метод 2. <*********************************
//
02C6 90             nop
02C7 90             nop
02C8 90             nop
02C9 48             dec    ax
02CA 7406           je     02D2
02CC E8F7FF         call   02C6
02CF E8F4FF         call   02C6
02D2 40             inc    ax
02D3 C3             ret
//
0080 268A1D         mov    bl,es:[di]
0083 E84002         call   02C6
0086 40             inc    ax
0087 263A1D         cmp    bl,es:[di]
008A 74F7           je     0083
008C 2D0600         sub    ax,0006
008F 90             nop
0090 90             nop
0091 90             nop
0092 90             nop
*******************************************************************************