Графические устройства



 

Русский текст на экране

Прежде всего, разберемся с тем, как появляются символы на экране. Задача самостоятельно или с помощью функций BIOS помещает выводимый текст в видеопамять. Коды символов должны соответствовать стандарту ASCII (American Standard Code for Information Interchange — американский стандартный код для обмена информацией). После кода каждого символа в видеопамять записывается атрибут, назначение которого будет описано ниже.

Таблицы знакогенератора

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

Таким образом, изображение символов, которое мы видим на экране при работе с текстом, зависит от используемой таблицы знакогенератора. Его размеры позволяют загрузить 8 разных таблиц, содержащих по 256 рисунков символов (в режиме EGA только 4 таблицы).

При установке видеорежима после включения компьютера или при переходе от одного видеорежима к другому BIOS загружает в знакогенератор свои таблицы символов из ROM BIOS. По понятным причинам в них отсутствуют рисунки русских букв. Для поддержки работы с русским текстом в процессе загрузки DOS вызывается программа-русификатор, которая остается резидентной в памяти компьютера. Она выполняет множество функций, в том числе отслеживает все прерывания int 10h, и при смене текущего видеорежима загружает в знакогенератор таблицы с рисунками русских букв. Пока русификатор находится в оперативной памяти, русский текст будет выводиться при установке любого стандартного видеорежима. Одним из распространенных русификаторов является программа Keyrus Д. Гуртяка.

Установка режимов VESA происходит без использования стандартной команды "set video Mode" прерывания int 10h, поэтому русификатор не "замечает" смены видеорежима и не заменяет русскоязычными базовые шрифты, загруженные из ROM BIOS. Такую замену должна произвести задача, работающая с русским текстом в режимах VESA. При этом она может загрузить собственную таблицу или "заставить" русификатор загрузить одну из его таблиц. В любом случае задача обращается к одной из функций BIOS.

Группа функций 11h. В состав прерывания int 10h входит группа, состоящая из 15-ти функций. Они выполняют загрузку знакогенератора, изменение количества строк и столбцов на экране, установку таблиц символов для текстового и графического режимов и получение информации об используемых таблицах символов. Группа создавалась для обслуживания мониторов EGA и была несколько расширена для мониторов VGA. Расширение заключалось в том, что добавились шрифты высотой в 16 строк и возможность загружать в знакогенератор до 8 (вместо 4) разных таблиц. При запросах функций код группы (llh) указывается в регистре ah, а код нужной функции — в регистре ai, его значение может изменяться от 0 до 30h. Реально используются не все значения из этого интервала. Описание всей группы можно найти в книгах, в TECH HELP и в других руководствах. Ниже мы рассмотрим только те функции, которые нужны для установки русифицированных таблиц.

Загрузка собственной таблицы

Функции BIOS позволяют загрузить в знакогенератор собственные таблицы выполняемой задачи или таблицы, принадлежащие русификатору. В первом случае используется запрос nooh.

Запрос 11ooh "Load User-defined Font" предназначен для загрузки в знако-генератор таблицы, указанной при обращении к BIOS. Перед изданием запроса в регистры помещаются следующие данные: es:bp— адрес начала загружаемой таблицы в оперативной памяти, сх — количество загружаемых символов, dx — порядковый номер первого символа (начиная с 0), bh — размер рисунка символа в байтах, bl— порядковый номер таблицы в знакогенераторе, который может изменяться от 0 до 7. По умолчанию доступна нулевая таблица, поэтому если вы выберете значение ы отличное от нуля, то для работы с таблицей придется принимать специальные меры.

Размеры символов таблицы должны соответствовать характеристикам установленного видеорежима, например, для режима VESA I09h они составляют 8x16 точек, а для режима ЮАЬ — 8x8 точек. Здесь первая цифра указывает ширину, а вторая высоту символа. Для большинства текстовых режимов ширина символов составляет 8 точек.
Таблица должна располагаться в выделенном для задачи пространстве оперативной памяти. Если при выполнении задачи таблица загружается в знакогенератор один раз, то постоянно держать ее в оперативной памяти не целесообразно. Ее можно хранить в отдельном файле и в нужный момент прочитать, например, в буфер обмена.

В любом случае при загрузке надо знать полный адрес таблицы (сегмент и смещение в нем). Для хранения этих величин в разделе данных программы выделяются два слова, например:

RsFntl6: dw 0 ; Смещение начала таблицы в указанном ниже сегменте
dw 0 ; Значение сегмента, в котором расположена таблица

Если расположение таблицы известно при составлении программы, то вместо нулей в директивах указываются конкретные значения сегмента и смешения. В противном случае содержимое обоих слов формируется при выполнении задачи.

Пример загрузки таблицы.

Фрагмент программы, приведенный в примере 5.1, составлен с учетом того, что адрес таблицы указан в переменной RsFntie, а размер символов таблицы составляет 8x16 точек.

Пример 5.1. Загрузка таблицы символов 8x16 в знакогенератор

push es сохранение содержимого es
les bp, dword ptr RsFntl6; es:bp = адрес начала таблицы
mov ex, 256 количество символов в таблице
xor dx, dx смещение первого символа в таблице
mov bh, 16 количество байтов на символ
хог Ы, Ы номер таблицы в знакогенераторе
mov ax, llOOh код запроса "загрузить таблицу"
int 10h выполнение запроса
pop es восстановление содержимого es

В приведенном примере таблица загружается полностью, что, вообще говоря, делать не обязательно. Первая половина любой таблицы содержит латинский алфавит, цифры, знаки препинания и пр., она является стандартной и уже находится в знакогенераторе. Поэтому можно хранить (в файле или в памяти) и загружать в знакогенератор только вторую половину таблицы, содержащую русские буквы, символы псевдографики и несколько специальных символов. Для загрузки второй половины таблицы в примере 5.1 в регистры сх и dx надо помещать значение 128.

Использование таблиц русификатора

Собственная таблица делает выполнение задачи независимым от наличия русификатора на компьютере. Отсутствие русификатора не такая уж редкость, если пользователи не работают в среде DOS, то он просто не нужен.

Если же русификатор установлен, то можно "заставить" его загружать свои таблицы. Русификатор контролирует все запросы, имеющие отношение к таблицам символов. В частности, при попытке загрузить одну из таблиц ROM Bios, он загружает свою (хранящуюся в ОЗУ) таблицу с русскими шрифтами. BIOS позволяет загрузить из ROM три таблицы со шрифтами следующих размеров:

  • запрос HOlh "Load ROM 8x14 Character Font";
  • запрос 1102h "Load ROM 8x8 Character Font";
  • запрос 1104h "Load ROM 8x16 Character Font".

Перед изданием этих запросов заполняется только регистр ы, содержащий номер таблицы в знакогенераторе (обычно нуль), все остальные величины функция BIOS формирует самостоятельно. В примере 5.2 приведен фрагмент программы, загружающий таблицу шрифтов 8x16 из ROM.

Пример 5.2. Загрузка таблицы символов 8x16 точек из ROM BIOS

хог bl, bl ; номер таблицы в знакогенераторе
mov ax, 1104h ; запрос "загрузка таблицы ROM 8x16"
int 10h ; выполнение запроса

Данный пример проще примера 5.1 и исключает необходимость хранения таблицы в теле задачи, но при отсутствии установленного русификатора в знакогенераторе окажется англоязычная таблица из ROM BIOS.

 
Назад Начало Вперед