
LRP2
.pdf- процедуру прерывания 10H вызывать следующим образом:
Intr($10,reg).
5.1.2.Буфер видеоконтроллера в текстовом режиме можно представить в виде массива:
. buff:array[0..3999] of byte absolute $B800:$0000.
Тогда для вывода на экран символа в i-ю строку и в j-й столбец необходимо по адресу buff[i*160+j*2] записать ASCII код символа, а по следующему - байт видеоатрибута.
5.1.3. Если слова заданы в виде строки символов s типа string, то для определения ASCII кода k-й буквы строки можно воспользоваться выражением ord(s[k]).
5.2. На языке Турбо-Си.
5.2.1. При использовании программного прерывания необходимо : - подключить библиотеку dos , в которой описана процедура
int86 и тип смеси REGS директивой
#include <dos.h>
- объявить смесь REGS оператором
union REGS in,out
где in-имя структуры |
входных регистров |
||
. |
outимя структуры выходных регистров |
||
. |
-к |
8разрядным регистрам как in.h.al или out.h.ah, |
|
. |
-к |
16разрядным |
регистрам адресуются как in.x.ax или out.x.ax |
-процедуру прерывания 10H вызывать следующим образом:
int86(0x10,&in,&out);
5.2.2. Обращение к буферу видеоконтроллера в текстовом режиме осуществляется аналогично обращению к ячейкам ОЗУ и ПЗУ с помощью дальних указателей, объявленных
char far * uk;
Тогда для занесения начального адреса видеобуфера необходимо записать:
uk=( char far *)0xB8000000;
а для вывода на экран символа в i-й строке и в j-м столбце записать
21
*(uk + i*160+j*2)=kod;
*(uk + i*160+j*2+1)=attr;
где kod и attr -переменные типа char,описывающие ASCII код и атрибут символа соответственно.
6.Индивидуальные задания
1.Первые два слова красным цветом на белом фоне; третье слово синим высокой интенсивности; четвертое слово зеленое мигающее на красном.
2.Первые три слова синим цветом на красном фоне; второе слово высокой интенсивности.
3.Второе слово магента на черном фоне; пятое слово мигает; седьмое слово белым низкой интенсивности.
4.Первые три слова синим на белом фоне; четвертое слово красным высокой интенсивности; шестое слово зеленым мигающим.
5.Седьмое слово белым черном фоне; пятое слово красным цветом высокой интенсивности; первые три слова синим цветом мигают.
6.Два слова цвета циан на красном фоне; третье слово мигает; первое слово коричневым высокой интенсивности.
7.Первые два слова синим высокой интенсивности; третье слово мигает; четвертое слово зеленое на красном фоне.
8.Первое слово черным на белом фоне; четвертое слово красным на зеленом фоне мигает; шестое слово коричневым высокой интенсивности.
9.Второе слово розовое высокой интенсивности; третье слово циан на зеленом фоне; пятое слово мигает.
10.Первые два слова синим низкой интенсивности; третье слово мигает; четвертое слово красным цветом на белом фоне.
11.Четные слова голубым по розовому; нечетные - красным по
22
черному; последнее пятое слово мигает.
12.Первое слово черным на белом фоне; четвертое слово зеленое на красном фоне; остальные - голубым на черном фоне.
Указанные слова вывести на экран в строку и в столбец, номера которых совпадают с номером студента в журнале.
7. Содержание отчета
7.1.Тема лабораторной работы. 7.2.Цель работы.
7.3.Порядок выполнения. 7.4.Индивидуальное задание. 7.5.Текст программы. 7.6.Результаты работы программы. 7.7.Выводы.
Лабораторная работа 12
УПРАВЛЕНИЕ КУРСОРОМ,ЦВЕТОМ БОРДЮРА,РЕГИСТРАМИ ПАЛИТРЫ,СОЗДАНИЕ СПЕЦИАЛЬНЫХ СИМВОЛОВ
1. Цель работы
Получение практических навыков управления курсором, цветом бор дюра и регистрами палитры путем программирования регистров адаптера,создания специальных символов.
2.Темы для предварительной проработки
2.1.Назначение регистров видеоадаптера.
2.2.Описание символов в текстовом режиме.
3. Описание работы
3.1.Управление курсором.
Курсор служит двум целям. Во-первых, он служит указателем места на экране, в которое операторы программы посылают свой вывод. Во-вторых, он обеспечивает видимую точку отсчета на экране для пользователя программы. Только для второго применения курсор должен быть видимым. Когда курсор невидим (выключен), он все равно
23
указывает на позицию экрана. Это важно, поскольку любой вывод на экран, поддерживаемый операционной системой, начинается с текущей позиции курсора.
Курсор генерируется микросхемой контроллера дисплея 6845. Эта микросхема имеет регистры, устанавливающие размер и положение курсора. Микросхема 6845 обеспечивает только мерцающий курсор, хотя имеются программные способы создания немерцающего курсора. Частота мерцания курсора не может быть изменена. В графических режимах курсор не выводится, хотя символы позиционируются на экране теми же процедурами установки курсора, что и в текстовых режимах.
Когда видеосистема работает в режиме, допускающем несколько дисплейных страниц, каждая страница имеет свой собственный курсор и при переключении между страницами восстанавливается позиция курсора, которую он занимал, когда было последнее обращение к восстанавливаемой странице. Некоторые режимы дисплея позволяют иметь до 8 дисплейных страниц и соответствующие им позиции курсора хранятся в наборе восьми 2-байтовых переменных в области данных BIOS, начиная с адреса 0040:0050Н. В каждой переменной младший байт содержит номер столбца, отсчитывая от 0, а старший байт содержит номер строки, также отсчитывая от 0. Когда число страниц меньше 8, используются переменные, расположенные в более младших адресах памяти.
3.1.1. Управление координатами курсора (позиционирование). Для курсора могут быть установлены абсолютные координаты или
координаты относительно его текущей позиции. Абсолютные координаты могут меняться в пределах 25 строк и 80 (иногда 40) столбцов.
Регистры 0EH и 0FH микросхемы 6845 хранят положение курсора. Адресный регистр имеет порт 3D5 (заносятся данные).Старший байт хранится в регистре 0EH, младший -в регистре 0FH.
Вы можете изменить их значение и курсор передвинется в соответствующую позицию экрана, но прерывания вывода на экран DOS и BIOS будут игнорировать вашу установку и вернут курсор в старое положение. Это происходит потому, что каждый раз при вызове этих прерываний они восстанавливают регистры курсора, используя 2-бай- товое значение, хранящееся в области данных BIOS. В этой области, начиная с адреса 0040:0050H, могут находиться до восьми таких значений, дающих текущее положение курсора для каждой из страниц дисплея. Первая позиция соответствует странице 0,вторая-странице 1 и т.д.. Младший байт каждой переменной содержит номер столбца,а старший номер строки.Как столбцы,так и строки нумеруются с нуля. Процедура низкого уровня должна модифицировать и эти значения, чтобы изменить состояние курсора полностью.
24
Позиция курсора хранится в регистрах 0EH и 0FH как число от 0 до 1999, что соответствует 2000 (25х80) позициям экрана. Не спутайте эту систему нумерации с позициями видеобуфера от 0 до 3999, где каждый символ сопровождается еще байтом атрибутов (для получения эквивалентного указателя на позицию курсора надо сдвинуть указатель видеобуфера на 1 бит вправо). Обращаем также ваше внимание на то, что не надо менять местами старший и младший байты: в регистре 0EH - старший, а 0FH - младший.
Курсор генерируется микросхемой 6845. Он функционирует совершенно независимо от видеопамяти. Это значит, что при прямой адресации в память дисплея программное обеспечение должно координировать перемещения курсора с вставкой нового символа в буфер.
Программы иногда читают и сохраняют текущее положение курсора, с тем чтобы можно было временно перевести курсор в командную строку, а затем вернуть его в исходную позицию.Процедура чтения позиции курсора (из регистров и области данных BIOS) аналогична процедуре установки курсора.
3.1.2.Управление формой курсора.
Курсор может меняться по толщине от тонкой линии до максимального размера, отводимого под символ. Он строится из коротких горизонтальных отрезков, верхний из которых называется начальной строкой курсора, а нижний - конечной строкой. Для монох-
ромного дисплея под |
каждый |
символ отводится 14 строк, |
пронумерованных от 0 до |
13 начиная |
сверху. Промежутки между симво- |
лами обеспечиваются двумя верхними |
строками и тремя нижними. Боль- |
шинство символов располагается в строках |
2-10, хотя хвостики неко- |
||||||||||
торых |
символов |
достигают |
линий |
12 |
и 13, в то время как |
||||||
подчеркивание занимает одну двенадцатую |
строку. На 200-строчном |
||||||||||
цветном |
дисплее |
для каждого символа отводится только 8 строк, |
а |
||||||||
символ рисуется в верхних семи строках. |
Эти 8 строк пронумерованы |
||||||||||
от 0 |
до 7 начиная сверху, |
и нормальный курсор формируется одной |
|||||||||
строкой 7. |
(Отметим, что на цветном дисплее |
нет |
подчеркивания, |
||||||||
поскольку |
использование для этого строки 7 привело бы к тому, что |
||||||||||
символы сливались бы с расположенными под ними.) |
Цветной |
дисплей |
|||||||||
высокого |
разрешения использует 14-строчный монохромный вариант, |
||||||||||
когда он работает в режиме разрешения, |
и 8-строчный |
вариант |
при |
||||||||
работе в одном из цветных графических режимов. |
|
|
|
|
|
||||||
Курсор может быть сформирован |
любой |
комбинацией |
прилегающих |
||||||||
отрезков. |
Для монохромного дисплея он занимает все отведенное под |
||||||||||
символ место, когда начальная строка равна 0, |
а конечная |
строка |
|||||||||
|
|
|
|
25 |
|
|
|
|
|
|
|
равна 13 (для графического дисплея значение конечной строки должно быть равно 7). Если значения начальной и конечной строк совпадают, то возникает однострочный курсор. Если номер конечной строки меньше, чем номер начальной, то курсор становится невидимым.
BIOS хранит 2-байтовую переменную по адресу 0040:0060H,которая содержит текущие значения начальной и конечной строк. Первый байт содержит значение конечной строки, а второй - начальной.
3.1.3.Создание альтернативных типов курсора.
Все прерывания операционной системы, связанные с выводом на экран, используют курсор. Вы можете изменить форму курсора или сделать курсор невидимым путем задания адреса больше 2000 или задания номера начальной строки больше номера конечной строки. Возможны альтернативные типы курсора, когда вывод на экран осуществляется с помощью методов прямого отображения в память. При этом "истинный" курсор выключается, поскольку он не будет адресовать символы в определенную позицию видеобуфера. Вместо этого создается "фальшивый" курсор с помощью байта атрибутов.
Наиболее эффективным методом является установка атрибута вывода в негативе для символа, на который указывает курсор. Для чернобелого экрана в качестве этого атрибута следует применять код ASCII 112. Другой способ - заставить символ, на который указывает курсор, мигать. В этом случае надо просто добавить 128 к текущему значению атрибута, чтобы символ начал мигать, и вычесть 128, чтобы прекратить мигание. Третий способ - установить для символа режим подчеркивания (код ASCII 1). И наконец, в программах, использующих командную строку, можно рассмотреть применение специального графического символа, который следует за последним символом командной строки, такого, как стрелки, выводимые кодами ASCII 17 или 27. Отметим, что когда программа получает ввод в нескольких режимах, вы можете помочь идентифицировать текущий режим за счет особого типа курсора.
3.2.Управление цветом границы экрана (бордюра ).
Граница символьного экрана (за пределами адресной области) может иметь цвет,отличный от фонового цвета центральной части экрана. Может быть использован любой из 16 цветов для CGA или любой из 64 цветов для EGA. Для цветного графического адаптера CGA биты 0-3 порта 3D9H (регистр выбора цвета ) устанавливает цвет границы, когда экран находится в текстовом режиме.
Для адаптера EGA цвет бордюра задается регистром 11H блока атрибутов адаптера.При подключении улучшенного графического дисплея возможно задание любого из 64 цветов.Для задания цвета бордюра в
26
EGA необходимо выполнить следующие действия:
-прочитать порт 3DAH для инициализации адресного регистра; -задать номер регистра 11H путем его записи в порт 3C0H; -задать цвет засылки байта данных в порт 3C0H ( анализируются
6 или 4 бита ); -разрешить вывод на экран путем установки 5 бита адресного ре-
гистра блока в 1 ( засылка кода 20H в порт 3C0H).Изменение цвета бордюра используется в драйверах клавиатуры для индикации переключения между русским и латинским алфавитом.
3.3.Создание специальных символов.
Только монохромный адаптер не может выводить символы вида, заданного самим программистом. Цветной адаптер поддерживает 128 символов, определяемых пользователем, PCjr - 256, а EGA - 1024, из которых одновременно доступно 512. Для цветного адаптера ROM-BIOS содержит данные для разрисовки только первых 128 символов набора ASCII (с номерами от 0 до 127). Следующие 128 символов недоступны для вас, пока вы не создадите их, используя описанную здесь технику.
3.3.1. Адаптер CGA.
Символы для графического адаптера и PCjr описываются с помощью матрицы 8*8 точек. Данные для каждого символа содержатся в восьми байтах. Каждый байт содержит установку для точек одного ряда, начиная с верхнего, причем старший бит (номер 7) соответствует самой левой точке в ряду. Когда соответствующий бит равен 1, точка высвечивается. Для описания символа вы должны определить правильные последовательности битов для восьми байтов и поместить их в последовательные ячейки памяти.
Все 128 символов вместе требуют 1024 байта, хотя вовсе не обязательно, чтобы были описаны все символы. Специальный вектор прерывания (постоянный указатель в младших адресах памяти) указывает адрес первого байта первого символа расширенного набора, т.е. символ номер 128. Когда в позицию символа в видеобуфере посылается код 128, просматриваются и выводятся первые восемь байт. Если номер символа 129, то выводятся байты с девятого по шестнадцатый и т.д. Номер этого вектора прерывания 1FH и он расположен по адресу 0000:007СH. Поместите значение смещения в младшее слово (сначала младший байт), а адрес сегмента - в старшее слово (сначала младший байт) и измените 8 байт описания любого символа. Отметим, что можно определять символы с большими номерами кодов, не отводя памяти
27
для символов с меньшими номерами; надо просто, чтобы вектор указывал на некоторый адрес, который меньше, чем адрес начала блока, содержащего данные для описания символов.
3.3.2.Адаптер EGA.
Для EGA картина немного сложнее, хотя и более гибкая. При инициализации текстового режима один из двух наборов символов (8*8 или 8 *14) в зависимости от разрешающей способности дисплея копируется из ПЗУ EGA в битовую плоскость 2 видеобуфера. Эта часть буфера рассматривается как разбитая на блоки, причем стандартный набор символов помещается в блок 0. При условии, что EGA оснащен достаточной памятью, могут быть определены еще три блока для описания символов. Размер блока определяется числом строк матрицы, используемой для описания символа. Набор символов, описываемых матрицей 8*8, требует 8 х 256, или 2048 байт. Адресация видеобуфера в EGA начинается с B800:0000H, каждый очередной блок символов имеет смещение 8 Кбайт. Когда разрешено более одного блока символов, бит 3 байта атрибутов определяет, из какого блока будут браться данные для описания символа.
Какой из блоков будет необходим - зависит от установки битов регистра выбора набора символов, адрес порта которого 3C5H. Предварительно надо послать 3 в порт 3C4H, чтобы указать требуемый регистр. Для EGA биты 1-0 дают номер блока символов, каторый берется, когда бит 3 равен 0, а биты 2-3 дают номер блока символов, когда бит 3 байта атрибутов равен 1; для VGA соответственно биты 0,1,4 определяют номер блока, когда бит 3 равен 0, а биты 2,3,5 - когда бит 3 равен 1. В случае равенства номеров блоков возможность использования двух наборов символов отсутствует и бит 3 байта атрибутов переключается на установку интенсивности фона символа. В этом случае используется только блок 0. Однако ничто не может помешать вам поместить свои символы в любую нужную вам позицию в этом блоке. Для этого необходимо разрешить запись в 2 битовую плоскость путем засылки кода 02H в регистр маски битовой плоскости следующим образом:
-посылка 2 в порт 3C4H (адрес регистра маски битовой плоскос-
ти);
-посылка кода 2 в порт 3C5H ( код плоскости).
После разрешения записи с учетом кода ASCII и числа байт на символ изменяется N байт, начиная с адреса
. adr=B800:0000+kod*N.
28
где:kod-код ASCII;
N-число байт на символ.
Содержимое N байт определяется требуемым изображением символа. На рисунке 1 приведено рукописное изображение буквы "И" для EGA
(8*14):
. . . . . . . .
. . . . . . . .
■. . . ■ . . .
■. . . ■ . . .
■. . . ■ . . .
■. . . ■ . . .
■. . . ■ . . .
■. . . ■ . . .
■ . |
. |
■ |
■ . . . |
|
■ . |
■ |
. |
■ |
. ■ . |
. ■ |
. |
. |
. |
■ . . |
. . . . . . . .
. . . . . . . .
. . . . . . . .
Рис. 1
Обратите внимание на то, что сверху, снизу и справа (или слева) от изображения символа нужно оставить пустые строки для разделения символов в строке и между строками. Данная буква описывается следующими 14 байтами: 00,00,88,88,88,88,88,88,98,AA,44,00,00,00.
Если вы изменили стандартный набор символов, то можно в любой момент восстановить его из ПЗУ.
Для цветного адаптера и PCjrдля изменения вектора прерывания 1 FH применяйте функцию 25Н прерывания 21Н. При входе DS:DX должны указывать на первый байт блока данных.
Для адаптера EGA характерна функция 11Н прерывания 10Н, которая манипулирует набором символов. Эта функция может быть очень сложной, когда она применяется для создания специальных режимов экрана, но ее основное назначение достаточно простое. Существуют четыре подфункции. Когда AL равен 0, данные, определяемые пользователем, переносятся из памяти в специальный блок символов. Когда AL равен 1 или 2, наборы данных для символов 8*14 и 8*8 соответственно копируются из ПЗУ в блок символов. Для VGA когда AL равен 4, набор символов 8*16 копируется из ПЗУ в блок символов. Когда AL равен 3, функция устанавливает назначение блока в регистре выбора карты символов, как описано выше. В последнем случае надо просто
29
поместить соответствующие данные в BL и вызвать функцию. Для загрузки данных из ПЗУ поместите номер блока в BL и выполните функцию. Для загрузки своих данных надо, чтобы ES:BP указывали на них, число передаваемых символов должно быть в CX, смещение (номер символа) в блоке должно быть в DX, число байтов на символ - в BH, а номер блока - в BL. После этого вызывайте прерывание 10Н.
Вы можете получить информацию о статусе имеющегося набора символов с помощью подфункциии 30Н (регистр AL) функции 11H (регистр AH) прерывания 10Н. У этой подфункции нет входных регистров, а при возврате в СХ содержится число байтов, отведенных для каждого символа, а в DX - сколько рядов точек символ занимает на экране (оба этих параметра зависят как от размера символа, так и от вертикального разрешения экрана).
4.Порядок выполнения работы.
4.1.Определить ASCII коды символов,составляющих фамилию и имя студента.
4.2.Задать байтовые описания указанных символов при рукописном шрифте и описания личного иероглифа студента.
4.3.Составить программу,выполняющую следующие действия. 4.3.1.Устанавливает цвет границы экрана в соответствии с инди-
видуальным заданием.
4.3.2.Перемещает курсор в позицию, номер строки которой соответствует месяцу рождения студента,а номер столбца соответствует номеру студента в журнале.
4.3.3.Изменяет форму курсора путем изменения номера начальной и конечной строки.
4.3.4.Определяет число байт на символ при описании символа. 4.3.5.Изменяет байтовые описания символов фамилии и имени сту-
дента.
4.3.6.Выводит в заданную позицию курсора фамилию и имя студента рукописными буквами, завершая строку личными иероглифом.
4.3.7.Изменяет цвет фона, программируя 0 регистр палитры.
5.Особенности программирования.
5.1. На языке Турбо-Паскаль.
5.1.1. Для обращения к портам ПЭВМ применяются предопределенные массивы Port и PortW. Например, для записи адреса регистра би-
30