будет загружен в память графического адаптера сразу целиком, а не будет
формироваться побитно. А для этого необходимо произвести декомпозицию
изображения на четные и нечетные строки, после чего обеспечить их
размещение в соответствующих блоках памяти. Указанное обстоятельство
сильно усложняет процесс быстрой генерации изображений.
Решение задачи быстрой генерации изображений зависит от потребностей
и от принятых компромиссов. Один из возможных подходов состоит в разбиении
изображения на участки, помещаемые в один байт (четыре пикселя для режима
среднего разрешения и восемь пикселей для режима высокого разрешения).
Приняв такую схему, можно осуществлять загрузку фрагментов в память
графического адаптера побайтно. Такой метод позволяет резко снизить
вычислительные затраты, в противном случае, программы должны выполнять
массу операций манипулирования битами, таких, например, как сдвиги,
логические "И", логические "ИЛИ" и т.п. Работа с байтами повышает скорость
генерации образа приблизительно в три раза, при условии, что собственно
образ уже построен.
Существует и другой, более грубый способ повышения скорости генерации
изображения. Его суть состоит в использовании текстовой графики
(псевдографики), описываемой в следующем параграфе.
9.4. Представление текста (символов) в графическом режиме.
Отображение символов на экране дисплея не представляет особого труда,
даже если компьютер работает в графическом режиме. Символы в этом случае
представляются в виде совокупности пикселей, как если бы это были
графические объекты, подлежащие рисованию (вычерчиванию).
Для фиксации схемы вычерчивания символов в графическом режиме приняты
специальные соглашения. Площадь, занимаемая символом, представляется в
виде матрицы размером 8Х8 пикселей. Принятый принцип кодирования в
принципе очевиден. Для воспроизведения очертания (рисунка) символа
отводится восемь байтов. Восемь битов каждого байта управляют состоянием
восьми пикселей одной строки рисунка символа (нумерация пикселей ведется
слева направо). Очередной байт описывает очередную строку (нумерация строк
осуществляется сверху вниз).
На рис.9.2 представлена диаграмма отображения символов (букв),
содержащая сведения об особенностях взаимодействия с таблицей рисования
символов. В качестве примера выбрана буква "А".
Даже при беглом знакомстве с этой диаграммой возникает ряд интересных
вопросов. Нижняя строка диаграммы отведена под нижний выносной элемент
символа (литеры), такой, например, как "хвост" прописной буквы "у". Две
верхние строки отведены под заголовок литеры. В качестве литер, имеющих
заголовок, можно привести строчную букву "ь" (имеется в виду ее
вертикальный отрезок, используюший область заголовка), а также все
прописные буквы алфавита (буквы верхнего регистра). Вопреки "здравому
смыслу" буквы размещаются не по центру матрицы, а смещаются (выравниваются
) по ее левой границе, так что два столбца справа служат для отделения
символов друг от друга.
При формировании символов в графическом режиме BIOS-ПЗУ осуществляет
поиск рисунка (образа) символа во внутренней таблице отображения, а затем
найденное табличное описание использует для команд активизации пикселей.
На заключительной стадии устанавливаются соответствующие биты в памяти
дисплея путем пересылки четных и нечетных строк в соответствующие блоки
памяти.
Поскольку в графическом режиме высокого разрешения цвет не
воспроизводится (воспроизводятся только черный и белый цвета), то рисунок
(образ) символа непосредственно управляет активизацией пикселя. В цветном
режиме среднего разрешения воспроизводятся цвет очертания (рисунок) и
фоновый цвет. Фоновый цвет - это цвет, обозначенный кодом 0; этим кодом
может быть обозначен любой из 16-ти имеющихся цветов. Цвет очертания
устанавливается с помощью кода 3 текущей цветовой палитры; для палитры 1
это белый цвет, а для палитры 0 - коричневый/желтый.
Процедуры манипулирования символами BIOS-ПЗУ могут осуществлять как
считывание, так и запись символов. Функция обслуживания с кодом 8 является
именно такой процедурой. В текстовом режиме никаких проблем при чтении не
возникает, поскольку в памяти дисплея хранится байт с кодом ASCII
требуемого символа. В графическом режиме все обстоит не так просто,
поскольку байт с кодом ASCII в памяти отсутствует. Вместо этого память
содержит группу байтов, представляющих точечный (пиксельный) рисунок
символа. Поэтому процедура BIOS-ПЗУ чтения символа осуществляет
нетривиальные операции. Она читает пиксели и сопоставляет их с содержимым
таблицы рисунков (образов) символов, выполняя своего рода распознавание
образа.
Таблица рисунков (образов) символов состоит из двух частей и
представляет для пользователя значительный интерес. Первая часть этой
таблицы хранится в ПЗУ и содержит первые 128 символов кода ASCII, то есть
все стандартные символы алфавита. Вторая часть таблицы содержит рисунки
остальных 128 символов (т.е. символов CHR$(120)-CHR$(255)). Поскольку
первая часть находится в ПЗУ (указатель на нее строго фиксирован), то она
не может быть ни модифицирована, ни заменена на другую таблицу. Вторая
часть таблицы, в отличие от первой, ориентирована на пользователя; она
создается пользователем под его потребность.
Один из векторов прерывания (прерывание с кодом 31 (1F(16)),
размещенный в таблице векторов по адресу 124(7С(16)) используется для
указания на эту таблицу. В исходном состоянии таблица отсутствует и вектор
равен нулю. После создания нужной таблицы и загрузки ее адреса в вектор
прерывания любое обращение к BIOS-ПЗУ для записи символа с кодом
CHR$(128)-CHR$(255) приведет к воспроизведению на экране этого символа.
Такой подход, основанный на свободном определении таблицы рисунков
128 символов является важной предпосылкой для быстрого построения наиболее
типичных графических образов (несложные графики, схемы, рисунки, таблицы,
чертежи, диаграммы и др.). Если требования к изображаемым объектам не
слишком высоки, то всегда можно определить ансамбль, состоящий из 128
шаблонов (каждый шаблон имеет размер 8Х8 пикселей) и генерировать на их
основе эти объекты. Очевидно, что наиболее сложные и детальные образы не
могут быть построены таким способом. И все-таки ансамбль, состоящий из 128
предварительно определенных шаблонов, достаточно велик, чтобы
пользовательские программы обладали высоким быстродействием, были просты и
компактны. В сущности, процедуры обслуживания рисунков символов BIOS-ПЗУ
(используя таблицу, созданную пользователем) берут на себя основную работу
по генерации образов; пользовательские программы лишь помещают нужные
символы в нужные позиции экрана.
Описанные возможности генерации графических символов отнюдь не
исключают возможность непосредственного доступа к памяти дисплея и
управления отдельным пикселем. В графическом режиме пользователь может
сочетать обе возможности. Когда это удобно - использовать таблицу
графических символов, при необходимости - манипулировать пикселями. Вполне
допустимо, например, изменять любой пиксель внутри любого образа символа,
уже выведенного на экран.
Таблица рисунков символов требует для своего размещения 1024 байтов
памяти: 128 символов Х 8 байтов (требуемых для каждого символа). В
графическом режиме со средним разрешением один байт программы пользователя
может использоваться для управления образом, состоящим из 64 пикселей, что
эквивалентно восьми байтам отображаемой информации. При соблюдении
определенных требований такой подход позволяет в восемь раз сжать
графический образ по отношению к исходному.
Прежде чем использовать эти возможности, следует оценить последствия
ограничений, распространяемых не только на число возможных шаблонов, но и
на число воспроизводимых цветов в режиме среднего разрешения. Число таких
цветов не может превышать двух. Обычный режим цветной графики позволяет
использовать полную 4-х цветную палитру, в то время как при использовании
возможностей построения изображений на основе синтеза символов количество
цветов в палитре уменьшается до двух.
В тех случаях, когда таблица рисунков символов, формируемая
пользователем, не применяется для построения изображений в графическом
режиме, можно использовать специальные символы из расширенного набора. Это
может найти применение при имитации символов текстового режима, при
построении специальных шаблонов или алфавитов. Так, это наиболее простой и
эффективный способ генерации других национальных алфавитов - греческого,
славянского (кириллица), японского (кана). Символика арабского языка и
иврита также вполне представима, однако, здесь возникают другие сложности
- сложности, связанные с особенностями письма (справа-налево).
Приложение 9.1. Текст программы генерации изображений (Паскаль).
module listing_9_1;
type
word_bits_type = set of 0..15;
high_res_pixel_type = (off,on);
medium_res_pixel_type =(color_0,color_1,color_2,color_3;
graphics_screen_type=
record
even_pixel : array [0..99,0..39] of word_bits_type;
filler : array [1..192] of byte;
odd_pixel : array [0..99,0..39] of word_bits_type;
end;
var [static]
graphics_screen_pointer : ads of graphics_screen_type;
general_screen_pointer : adsmem;
row,column : integer;
value
graphics_screen_pointer.s := #B800;
graphics_screen_pointer.r := 0;
general_screen_pointer.s :=#B800;
general_screen_pointer.r :=0;
{===================================================================}
ТЕКСТ РАЗОБРАТЬ НЕЛЬЗЯ
graphics_screen_pointer ^ .odd_pixel [(row-1) div 2,column div 16]
else
work_byte :=
graphics_screen_pointer ^ .even_pixel [row div 2, column div 16];
work_value := column mod 16;
if color = on then
work_byte := work_byte + [work_value]
else
work_byte := work_byte - [work_value];
if odd (row) then
graphics_screen_pointer ^ .odd_pixel [(row-1) div 2, column div 16]
:= work_byte
else
graphics_screen_pointer ^ .even_pixel[row div 2, column div 16]
:= work_byte;
end;
{===========================================================}
procedure set_medium_res_pixel (color : medium_res_pixel_type);
var [static]
work_byte : word_bits_type;
work_set0 : set of 0..15;
work_set1 : set of 0..15;
begin
if odd (row) then
work_byte :=
graphics_screen_pointer ^ .odd_pixel [(row-1) div 2, column div 8];
else
work_byte :=
graphics_screen_pointer ^ .even_pixel [row div 2, column div 8];
work_set0 := [(column mod 8) * 2];
work_set1 := [(column mod 8) * 2 + 1];
if color in [color_2,color_3] then
work_byte := work_byte + work_set0
else
work_byte := work_byte - work_set0;
if color in [color_1,color_3] then
work_byte := work_byte + work_set1
else
work_byte := work_byte - work_set1;
if odd (row) then
graphics_screen_pointer ^ .odd_pixel [(row-1) div 2, column div 8]
:=work_byte
else
graphics_screen_pointer ^ .even_pixel [row div 2, column div 8]
:= work_byte;
end;
{===========================================================}