Инициализация администратора оверлеев
Здесь мы рассмотрим некоторые примеры того, как инициализи- руется администратор оверлеев (подсистема управления оверлеями). Код инициализации должен быть помещен перед первым обращением к оверлейной программе. Инициализацию обычно следует делать в опе- раторной части программы.
Следующая часть программы показывает, как немного требуется для того, чтобы инициализировать администратор оверлеев.
begin OvrInit('EDITOR.OVR'); end;
Проверка на ошибки не делается. Поэтому если для оверлейного буфера не хватает памяти или оверлейный файл не найден, то при попытке вызова оверлейной программы произойдет ошибка 208 (Overlay manager not installed - "Администратор оверлеев не уста- новлен").
Приведем другой небольшой пример, являющийся расширением предыдущего.
begin OvrInit('EDITOR.OVR'); OvrInitEMS; end;
В этом случае, если предположить, что для оверлейного буфера имеется достаточно памяти и что можно найти оверлейный файл, ад- министратор оверлеев проверяет, имеется ли память EMS, и если это так, загружает оверлейный файл в расширенную память.
Как уже упоминалось ранее, начальный размер оверлейного бу- фера выбирается минимально возможным или, иначе говоря, настолько большим, чтобы вместить оверлей наибольшего размера. Для некото- рых прикладных задач этого может быть достаточным, однако предс- тавим ситуацию, при которой одна из функций программы реализуется с помощью двух или более модулей, каждый из которых является оверлейным. Если общий размер таких модулей больше, чем размер наибольшего оверлея, то частое обращение модулей друг к другу приведет к интенсивному свопингу.
Очевидно, решение заключается в том, чтобы увеличить размер оверлейного буфера таким образом, чтобы в любой заданный момент времени имелось достаточно памяти для того, чтобы содержать в се- бе все оверлеи, часто обращающиеся друг к другу. Следующая часть программы показывает использование для увеличения размера овер- лейного буфера процедуры OvrSetBuf:
const OvrMaxSize = 80000; begin OvrInit('EDITOR.OVR'); OvrInitEMS; OvrSetBuf(OvrMaxSize); end;
Для определения идеального размера оверлейного буфера общих рекомендаций нет. Подходящее значение можно определить только имея некоторую информацию о прикладной задачи и экспериментальным путем.
Использование процедуры OvrInitEMS для размещения оверлейно- го файла в расширенной памяти не устраняет необходимости работы с оверлейным буфером. Ведь оверлеи перед выполнением тем не менее должны копироваться из расширенной памяти в обычную (то есть в оверлейный буфер). Однако, поскольку такие передачи из памяти в память выполняются значительно быстрее, чем чтение с диска, то необходимость увеличения размера оверлейного буфера становится менее очевидной.
Нужно также помнить о том, что процедура OvrSetBuf увеличи- вает размер оверлейного буфера за счет уменьшения размера динами- чески распределяемой области памяти. Таким образом, динамически распределяемая область должна быть пустой, иначе процедура OvrSetBuf не окажет никакого действия. Если вы используете модуль Graph, убедитесь в том, что вы обращаетесь к процедуре OvrSetBuf перед вызовом процедуры InitGraph, которая выделяет память в ди- намически распределяемой области.
Приведем теперь более исчерпывающий пример инициализации подсистемы управления оверлеями, включающей в себя полную провер- ку на возможное возникновение ошибок.
const OvrMaxSize = 80000; var OvrName: string[79]; Size: Longint; begin OvrName:='EDITOR.OVR'; repeat OvrInit(OvrName); if OvrResult=ovrNotFound then begin WriteLn('Оверлейный файл не найден'); WriteLn('Введите правильное имя оверлейного файла:'); ReadLn(OvrName); end; until OvrResult<>ovrNotFound; if OvrResult<>ovrOk then begin WriteLn('Ошибка администратора оверлеев.') Halt(1); end; OvrInEMS; if OvrResult<>OvrOk then begin case OvrResult of ovrIOError: Write('Ошибка ввода-вывода', ' оверлейного файла'); ovrNoEMSDriver: Write('Драйвер EMS не', ' установлен'); ovrNoEMSMemory: Write('Не хватает расширенной', ' памяти'); end; Write('. Нажмите клавишу Enter...'); ReadLn; end; OvrSetBuf(OvrMaxSize); end;
Сначала, если принятое по умолчанию имя оверлейного файла было неверным, пользователю будет выводиться подсказка на введе- ние правильного имени файла.
Далее проверяются другие ошибки, которые могут произойти при инициализации. В случае обнаружения ошибки программа останавлива- ется, так как ошибки в OvrInit являются фатальными. (Если они иг- норируются, то при первом обращении к оверлейной программе во время выполнения произойдет ошибка.)
Если предположить, что инициализация проходит успешно, далее для загрузки оверлейного файла в расширенную память (если это возможно) выполняется обращение к процедуре OvrInitEMS. В случае ошибки на экран выводится диагностическое сообщение, однако прог- рамма не останавливается. Вместо этого она просто продолжает счи- тывать оверлеи с диска.
Наконец, для задания значения размера оверлейного буфера, определенного с помощью анализа или эксперимента с конкретной прикладной программой, вызывается процедура OvrSetBuf. Ошибки, которые могут возникнуть при выполнении данной процедуры, игнори- руются, хотя OvrResult может возвращать код возврата по ошибке -3 (OvrNoMemory). Если памяти недостаточно, подсистема управления оверлеями будет просто продолжать использовать буфер минимального размера, выделенный при запуске программы.