Предыдущий раздел

Кое-что полезное

Здесь вы можете получить готовые Pascal-модули, которые могут оказаться полезными для вас в вашей программистской работе.

  1. Для облегчения работы по отладке программ вычислительного характера предлагается использовать модуль ReadNum.tpu, разработанный студентами 2 курса матфака КубГУ.
   Использование его может значительно облегчить работу над вычислительными программами. Особенно это касается вычислительного практикума на 4 курсе.
   В ходе отладки программы приходится многократно запускать ее на исполнение, последовательно внося изменения в текст программы. При этом каждый раз требуется ввод некоторого количества числовых исходных данных.
   Эффективность работы по отладке программы и (в дальнейшем) ее использования можно повысить, предусмотрев ввод исходных данных из текстового файла. В этом файле кроме чисел, произвольно расположенных по строкам текста, могут находиться и комментарии.
   При этом вводить числа вручную придется только 1 раз. В ходе отладки, добиваясь правильного ответа, эти данные изменять не надо, и ваша программа сама, без вашего участия прочтет их.
   Для решения задачи с новыми исходными данными надо просто внести изменения в файл данных, используя любой текстовый редактор (под DOS).
   Вы можете просмотреть краткую документацию на модуль ReadNum и/или получить весь архив.

  2. Для любителей программирования на Pascal. Здесь предлагается получить модуль vts.tpu с документацией и демонстрационными примерами. Процедуры и функции модуля, написанные, в основном, на Ассемблере, собирались постепенно, отвечая на заявленные потребности студентов. В стандартных модулях Turbo Pascal такие процедуры и функции либо отсутствуют, либо реализация их возможностей неудобна и громоздка.
Модуль vts.tpu ссылается на модуль Crt, в котором на современных быстродействующих процессорах возникает известная ошибка Runtime Error 200 - Divide by 0. Вы можете использовать vts.tpu в том случае, если у вас не слишком крутой компьютер или установлен исправленный модуль Crt. Ниже я предлагаю вам такой модуль.

В настоящее время модуль vts.tpu затрагивает следующие темы.

  Оформление окна. Изображение на экране прямоугольного окна, окрашенного определенным текстовым атрибутом, с заданными цветом и символами рамки.

  Управление курсором . При хорошем стиле в оформлении программ курсор появляется на экране только тогда, когда в нем имеется потребность, т.е. при вводе пользователем информации с клавиатуры. В связи с этим надо иметь возможность скрывать курсор и восстанавливать его видимость. Также общепринято изменять вид курсора в зависимости от того, имеет место режим вставки или замены символов при редактировании текста. Эти возможности предлагаются рассматриваемым модулем.

  Работа с областями экрана. Запоминание прямоугольной области экрана и восстановление ее на экране. Очистка и скроллинг области. Окрашивание прямоугольной области экрана с заданным атрибутом, сохраняя текст.

  Анализ нажатой клавиши. Предлагается замена стандартной функции ReadKey, возвращающая сразу полный код нажатой клавиши или комбинации клавиш. Имеется необходимый набор функций для анализа этого полного кода. Проверка и очистка буфера клавиатуры.

  Что-то еще? Если вы испытываете потребность в развитии возможностей модуля или хотели бы принять участие в его разработке, можете обратиться ко мне лично или написать мне.

  3. Проблема модуля Crt. Runtime Error 200 - Divide by 0.
Эта хорошо известная ошибка проявляется на современных компьютерах с достаточно быстрым процессором, настолько быстрым, что в 1992 году, когда выпускался Turbo-Pascal 7.0, о таких еще и не могли предполагать.

Вот что пишет об этом Borland/Inprise/(и т.д.) (www.borland.com/devsupport/pascal, перевод и исправления мои):
Программы, использующие модуль Crt, могут выдавать такое сообщение об ошибке, когда выполняются на очень быстрых машинах (Pentium Pro 180 и выше). Причина такой ошибки в специальном цикле (назовем его DelayLoop - VTs), который выполняется при инициализации модуля Crt. При этом вычисляется число повторений цикла, происходящих между двумя соседними 'тиками' таймера компьютера (т.е. за 55 миллисекунд) и затем это число делится на 55. Результат этого деления (назовем его DelayCnt) получается слишком большим для значения типа WORD. При таком переполнении и выводится сообщение об ошибке 'Divide by 0'.
В настоящее время Inprise не поддерживает никакого решения этой проблемы. В Internet можно найти несколько вариантов, предлагаемых пользователями и исправляющих как модуль Crt, так и существующие EXE программы. Простейший способ получить эти решения – зайти по адресу www.altavista.digital.com и искать там '+ bp7patch.zip + tppatch.zip'  без кавычек.
Эти исправления не имеют официального одобрения или поддержки от Inprise и используются на собственный страх и риск.

Зачем нужен счетчик DelayCnt? Просто процедура Delay(milliseconds) заключается в повторении DelayLoop  DelayCnt * milliseconds раз.

До этого все известные мне, да и Borland/Inprise, (реализованные!) способы лечения Crt заключались в искуственном уменьшении величины DelayCnt, если она окажется слишком большой. Но тогда процедура Delay начинает врать, и тем сильнее, чем выше быстродействие процессора. Модуль Crt все равно не соответствует своему описанию в книгах и HELPе.

Выход здесь другой: надо переписать DelayLoop так, чтобы он выполнялся подольше. Где-то в Сетях я нашел исходные тексты модуля Crt с исправлениями в виде уменьшения полученного значения DelayCnt, удалил эти исправления и добавил свои. Это совсем не сложно (можете просмотреть тексты, если понимаете Assembler).

Я надеюсь, что Borland/Inprise не станет возражать против такого вмешательства в ее исходники, т.к. публично отказывется сделать это сама. Мы вынуждены делать это.

В результате получился новый модуль Crt. Все стандартные оговорки про AS IS, LIMITED WARRANTY и т.д. имеют место.

Новый модуль работает с удлиненным DelayLoop для процессоров, эквивалентных по скорости от Pentium-160 до Pentium-8300 (восемь тысяч триста). Если процессор медленнее, то DelayLoop укорачивается почти до того состояния, которое было в старом Crt. Правда, при этом инициализация модуля становится на 0.11 сек дольше. Если же процессор еще быстрее (вы можете себе такое представить сегодня?), то DelayLoop соответственно удлинняется. При этом инициализация тоже становится дольше
от Pentium-8.3 ГГц до Pentium-16 ГГц – на 0.11 сек;
от Pentium-16 ГГц до Pentium-32 ГГц – еще на 0.11 сек;
и т.д. до Pentium-120 000 ГГц (гига-Гц).
Разумеется, цифры очень приблизительные.

Я проверил погрешность выполнения процедуры Delay нового модуля на всех доступных мне процессорах, начиная с 386SX-40 с Turbo Off и кончая Pentium II-400. Относительная ошибка не превышала 0.1 % на длительностях до 40 сек и при приближении к 60 сек (загадка!) увеличивалась, но не более, чем до 0.2 %.

Вы можете получить архив, содержащий
   модуль Crt2.tpu – держите его в текущем каталоге и подключайте вместо Crt;
   файл библиотеки модулей Turbo.tpl с исправленным модулем Crt – замените им существующий файл TP\BIN\Turbo.tpl и забудьте о проблемах Crt;
   файл TestCrt2.pas с исходным текстом тестирующей программы – проверьте работу Delay на своем (и на соседском) компьютере;
   файл Crttpu.txt с описанием всего этого;
   подкаталог SOURCE с исходными текстами модуля (можете скомпилировать аналогичный модуль для Borland Pascal, если надо) и файлом Readme.txt c "бредом", в котором Philip Zholobov объясняет принятые ранее подходы к проблеме.

Следующий раздел