МУ к лабораторным работам - Кафедра компьютерных систем

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ
ДОНЕЦКИЙ НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
МЕТОДИЧЕСКИЕ УКАЗАНИЯ И ЗАДАНИЯ
К ЛАБОРАТОРНЫМ РАБОТАМ ПО КУРСУ
“МЕТОДЫ И СПОСОБЫ КОМПЬЮТЕРНЫХ
ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ ”
для студентов специальности 6.050101
“ Компьютерный эколого-экономический мониторинг”
Утверждено на заседании кафедры
“Компьютерные системы мониторинга”
протокол № 3 от 26.11.10
Утверждено на заседании
учебно-издательского совета ДонНТУ
протокол № __ от __________
Донецк – ДонНТУ - 2010
2
УДК 681.3
Методические указания и задания к лабораторным работам по курсу
“Методы и способы компьютерных информационных технологий“, (для
студентов специальности 7.080407 “Компьютерный эколого-экономический
мониторинг ”/
сост.: доц. Губенко Н.Е., асс. Миргород В.С. – Донецк: ДонНТУ, 2010 - 96с.
Приведены теоретические сведения, методические рекомендации,
примеры и задания для выполнения лабораторных работ по следующим
разделам дисциплины:
- Программирование растровых изображений на языке PostScript;
- работа с манипулятором «мышь»;
- работа с драйверами CD-ROM;
- программирование видеокарты;
- работа с LPT портом.
Составители:
Рецензент:
Губенко Н.Е., к.т.н., доцент
Миргород В.С., ассистент
3
Лабораторная работа №1
Тема: Программирование простейших растровых изображений на языке
PostScript.
Цель работы: освоение принципов и приобретение навыков
программирования простейших изображений на языке описания страниц
растровых изображений PostScript.
Методические указания к лабораторной работе
PostScript создавался в качестве простого стандартного языка для
описания вида текста, чертежей и простых изображений ,выводимых на
растровые устройства. Язык содержит около 250 операторов, что позволяет
одни и те же действия запрограммировать самыми разными способами.
Описание страниц на PostScript не зависит от устройства, на котором страница
будет воспроизведена. Программы на PostScript генерируются приложениями,
например текстовыми процессорами, программами для настольных
издательских систем и т.п.
Виртуальное postscript-устройство (принтер, монитор) - это устройство, в
котором имеется интерпретатор языка PostScript. Интерпретатор PostScript
читает текстовый файл с описанием страницы, полученный из компьютера, и
преобразует его в растровую форму, согласованную с типом устройства,
которая и выводится на печать или на экран. Преимущества:

описание страницы во много раз компактнее даже сильно сжатого
изображения;

процесс подготовки печатной страницы требует значительного
времени: если пересылается описание, то подготовкой к печати
занимается процессор принтера или дисплейный процессор, что
освобождает процессор персонального компьютера (ПК) для выполнения
другой работы и тем самым повышает его производительность;

самое важное преимущество - это независимость описания от типа
устройства.
Текущая страница (ТС) - "идеальная" страница в памяти, на которой
рисует PostScript. Она не зависит от физических характеристик устройства, на
который страница будет вводиться. В начале работы программы это
совершенно чистая страница.
Текущий траектория (ТТ) - это набор соединенных между собой
отдельных геометрических объектов (точек, линий, кривых), которые вместе
описывают фигуры и их положение на странице. На текущий путь не
накладывается никаких ограничений. Элементы текущего пути задаются их
позициями на текущей странице.
4
Текущая траектория обрезки (ТТО) или траектория отсечения - это
границы области, в которой может быть нарисовано изображение.
Пространство устройства (ПУ) - определяет встроенную систему
координат растрового устройства для адресации точек на странице.
Пространство пользователя (ПП) - используется для удобства
независимого программирования с использованием понятия СИСТЕМА
КООРДИНАТ ПОЛЬЗОВАТЕЛЯ (СКП). Позиция элемента на странице
задается парой X,Y. PostScript допускает преобразование пространства
пользователя:
 начало СКП можно переносить в любую точку;
 оси СКП могут быть повернутыми в любую сторону;
 масштаб по каждой из осей может быть изменен, то есть можно задать
линейное преобразование из ПП в ПУ.
Преобразование из ПП в ПУ осуществляется при выводе с помощью
ТЕКУЩЕЙ МАТРИЦЫ ПРЕОБРАЗОВАНИЙ (ТМП), имеющей размеры 3х3.
Графический статус системы - определяется текущей траекторией и
текущей матрицей преобразований.
Стек:
При программировании на PostScript широко используется концепция
стека. СТЕК есть линейная структура, доступ к которой возможен только через
ее вершину. PostScript оперирует четырьмя различными стеками: операндов,
словарей, выполнения и состояния графики.
Стек операндов - содержит собственно объекты PostScript и результаты
действий над ними. Операторы PostScript получают операнды только через
стек.
Стек словарей - содержит переменные и словари, открытые в настоящий
момент.
Словарь - суть набор пар «имя-значение». Все поименованные значения
хранятся в словарях. Операнды также хранятся в словарях вместе с их кодами.
Если программа ссылается на некоторое имя, то интерпретатор просматривает
стек сверху вниз и ищет первое вхождение этого имени.
Занесение чисел в стек:
Любое число, появившееся в исходном файле PostScript-программы
заносится в стек. Например, напишем строку:
-81 110.4 +777
5
Интерпретатор по мере ее чтения слева направо выполнит следующие
действия:
- заносит в стек число -81;
- перемещает указатель на следующую свободную позицию;
- заносит в стек число 110.4;
- перемещает указатель на следующую позицию и т. д.
Стек будет иметь вид:
777
110.4
-81
Число 777 размещается в вершине стека, и оно может быть использовано
первым в какой-либо операции. Остальные числа используются в порядке,
обратном порядку их занесения в стек.
Таким же образом в стек заносятся PostScript-объекты любого вида:
массивы, строки и словари.
Набор символов:
Все символы делятся на специальные и регулярные. Все виды скобок
(круглые, квадратные, фигурные, угловые) и знак процента являются для
PostScript специальными знаками. Остальные символы -подмножество кода
ASCII, используются в программе без ограничений и называются регулярными
символами.
Имя - любая последовательность символов, которую нельзя
интерпретировать как число и построенная из любых символов, кроме скобок,
пробелов, знаков % и /. Если перед именем стоит символ «/», то имя
помещается в стек как операнд, иначе оно ищется в стеке словарей. Если
найденное имя есть процедура, то она выполняется, иначе имя помещается в
стек операндов.
Типы даннях:
Данные делятся на основные и дополнительные. Основные: целые,
действительные, логические, массивы и строки. Дополнительные: mark
(отметка, метка) и dictionary (словарь).
Константы:
В PostScript используются константы трех типов: целые, действительные
и строковые.
Примеры записи целых:
+745 -61 48889 0
6
Если величина числа превышает предел для представления целых
чисел, оно автоматически конвертируется интерпретатором в число типа real.
Примеры записи действительных чисел:
-122.0 33.3E-5 +.0065
Беззнаковые целые числа могут быть записаны в любой позиционной
системе счисления с использование префикса в виде:
база#число
где:
база - основание системы счисления (десятичное целое число от 2 до 36);
число - представление числа в указанной базой системе счисления.
Цифры в системах счисления по основанию больше 10 представляются
буквами латинского алфавита от A до Z. Например:
18#75cb2e 8#5347 2#11001011
Строка - это последовательность символов, заключенная в круглые
скобки. Символы можно также представлять шестнадцатеричными кодами,
заключая их в угловые скобки.
Массивы - последовательность объектов, заключенных в квадратные
скобки. Они могут быть двух типов: регулярные (содержащие объекты одного
типа) и нерегулярные (содержать объекты разных типов).
Комментарий - любой текст, начинающийся символом «%».
Операторы по своему функциональному назначению делятся на три
группы: арифметические, работы с текстом и графикой и работы со стеком.
Оператор побуждает интерпретатор к выполнению определенных действий.
Программа выполняется путем продвижения интерпретатора от слова к слову,
проверки слов по внутреннему словарю на соответствие множеству имен
операторов. Если слова в словаре найдено, то выполняются все связанные с
ним действия, а затем переход к следующему слову в исходном файле.
При разработке программы необходимо учитывать, что операндыобъекты любого вида предварительно размещаются в стеке операндов, а не
адресуются непосредственно указанием имени переменной. Такой стиль
программирования, при котором операнды задаются до операции над ними,
называется ПОСТФИКСНОЙ НОТАЦИЕЙ или польской инверсной записью.
Выполняемый оператор забирает операнды из вершины стека, совершает над
ними действие и, в общем случае, возвращает результат в вершину стека.
Поэтому операторы записываются в следующем виде:
arg1 arg2 … argN operator result
Так запись операции сложения двух чисел, допустим 24+115, в PostScript
будет выглядеть следующим образом:
24 115 add
7
Разделители объектов - пробелы, символы табуляции и новой строки,
а также круглые и квадратные скобки.
Гибкость языка:
Несмотря на большое количество встроенных операторов в PostScript нет
зарезервированных слов. Любое слово переопределяемо. Программа в
PostScript может рассматриваться как данные.
Арифметические операторы:
Унарная операция:
neg – изменить знак числа в вершине стека.
Пример: -543 neg = > 543
Бинарные операции:
Add - сложение,
Sub - вычитание,
div - деление,
idiv - целочисленное деление.
mod - остаток от деления.
Операнды операторов MOD и IDIV должны быть целыми числами.
Mul - перемножает два числа в вершине стека, помещая вместо них их
произведение.
При выполнении этих операций оба операнда извлекаются из вершины
стека. Вторым операндом всегда выступает число из вершины стека, а вторым
- число, находящееся под ним.
Примеры записи арифметических выражений:
Обратите внимание на то, что выражения на языке PostScript можно
представить несколькими способами!
1. 23 + ( 8 : 2 )
a. а) 8
b. б) 23
2
div 23 add
8
2
div
add
2. 39 - ( 4*7 )
a. а) 39 4 7 mul sub
b. б) 4 7 mul 39 exch sub
8
В случае б) оператор EXCH меняет местами положение двух верхних
чисел в вершине стека. Применение оператора EXCH вызвано тем, что SUB
вычитает число в вершине стека из следующего за ним, что без EXCH приводит
к неверному порядку действий.
Операторы управления стеком:
Эта группа операторов добавляет, удаляет и изменяет порядок
следования элементов в стеке.
Clear - очистка стека - удаляет из стека все элементы
а1...аn clear
Сount - число элементов в стеке.
a1...an count a1...an n
Dup - дублирует в стеке его верхний элемент
a1 dup a1 a1
8 dup -> 8 8
Pop - удаляет из стека его верхний элемент
an...a2 a1 pop -> an...a2
25 31 4 pop -> 25 31
Roll - циклически сдвигает элементы стека. При этом число и
направление сдвига задается первым (верхним) элементом, а количество
сдвигаемых элементов - вторым. Если первый элемент положительный, сдвиг
осуществляется вправо, иначе - влево.
15 7 8 9 3 1 roll -> 15 9 7 8
15 7 8 9 3 -1 roll -> 15 8 9 7
Copy дублирует n верхних элементов стеков
a1...an n copy a1...an a1...an
= = удаляет элемент из вершины стека и отображает его на экране.
Pstack - печатает все содержимое стека, не изменяя его.
Формирование графических изображений:
Программирование
изображения
в
PostScript
начинается
с
конструирования траектории на идеальной поверхности, называемой текущей
страницей. Траектория есть набор прямых и кривых линий, определяющих
разомкнутые или замкнутые области (которые возможно будут заполнены).
Линии могут иметь разную толщину и тип. После того, как заполнение текущей
страницы закончено, ее можно вывести на физическое устройство. Таким
образом, получение графических изображений осуществляется в три этапа:
- конструирование траектории;
- нанесение ее на текущую поверхность;
9
- вывод страницы.
Операторы конструирования траектории:
x y moveto - точку с координатами х, у делает текущей на текущей
странице;
dx dy rmoveto - перемещает текущую точку на текущей странице на
величину dx dy;
х у lineto добавляет к траектории отрезок прямой от текущей точки до
точки с координатами х у;
dx dy rlineto добавляет к траектории отрезок прямой от текущей точки до
точки с координатами х + dx у + dy;
x y r angl1 angl2 arc - добавляет к заданной траектории дугу
(окружность) и требует наличия в стеке пяти аргументов: координат х, у центра
окружности, радиуса, угла начала дуги, угла конца дуги. Дуга строится против
часовой стрелки:
100 100 42 30 110 arc
Аналогичный ARC оператор ARCN строит угол по часовой стрелке.
Сравните:
100 100 42 30 110 arcn
Если текущая точка траектории не совпадает с начальной точкой дуги, то
они будут соединены отрезком.
Чтобы нарисовать окружность, нужно задать ARC угол в 360 градусов,
например:
150 200 60 0 360 arc
x1 y1 x2 y2 r arcto - сглаживание углов. Пересекающиеся линии часто
бывает необходимо соединить плавной кривой. В стеке задаются координаты
двух точек и радиус. Оператор рисует сегмент прямой линии от текущей точки
по направлению к точке х1, у1, а затем дугу до её пересечения со второй
прямой. ARCTO возвращает в стеке координаты начала и конца дуги. Если они
не нужны, то эти числа следует удалить из стека:
4 {pop} repeat
Операторы управления выводом:
- newpath - очищает текущую траекторию и готовит систему к началу
конструирования новой траектории. Оператор необходим перед началом любой
новой траектории;
- closepath - закрывает текущую траекторию, добавляя при этом
отрезок, начало котрого - текущая точка, а конец - начальная точка траектории;
1
на0
- stroke - вызывает рисование сконструированного нами пути
текущей странице с учетом текущих атрибутов ( текущей толщины линии,
текущего цвета пера, текущего образа линии, текущего способа соединения
линий).
В системе координат, принятой в PostScript по умолчанию, начало
координат находится в нижнем левом углу страницы. Координата х
увеличивается вправо, а у - при движении вверх. Единица длины в этой системе
равна 1/72 дюйма. По умолчанию текущий цвет пера - черный, а текущий образ
линии - сплошная.
- showpage - отображает (печатает) текущую страницу и подготавливает
новую.
ПРИМЕР:
Написать программу, рисующую квадрат со стороной один дюйм,
расположенный в центре страницы:
newpath
200 300 moveto
0 72 rlineto
0 -72 rlineto
-72 0 rlineto
stroke
showpage
Наш квадрат, как вы заметили, имеет выщерблину в левом нижнем углу,
так как линии соединяются без учета толщины. Чтобы избежать этого явления,
следует использовать оператор CLOTHEPATH.
Операторы управления свойствами:
- setlinewidth - позволяет вам установить ширину линии Х * 1/72 дюйма.
Данный оператор действует на все линии, помещаемые на текущую страницу,
пока не встретится другой оператор setlinewidth;
- fill - закрывает текущую траекторию и заполняет ее текущим цветом
(уровнем серого) и очищает текущую траекторию. Используется вместо stroke ;
- setgray - задает уровень серого цвета для заполнения фигуры в долях от
единицы (в интервале от 0 - черный цвет до 1 - белый);
- R G B setrgbcolor - задает сочетание интенсивностей трех основных
цветов (красного, зеленого и синего); интенсивность выражается числом в
диапазоне от 0 до 1 (0 - полное отсутствие соответствующего цвета, 1 максимальная его интенсивность);
- H S B sethsbcolor - задает тон (цвет), насыщенность, яркость. Тон
определяет цвет как точку на цветовом круге (0 градусов - чистый красный. 120
1
цвета1
градусов – чистый зеленый, 240 градусов - чистый синий; остальные
спектра определяются смешением двух соседних цветов). Насыщенность цвета
задается числом (0 - отсутствие цвета, 1 - максимальная насыщенность).
Яркость, то есть содержание белого цвета в данном, задается числом от 0 до 1
(0 - черный, 1 - белый).
ПРИМЕР: Рисование перекрывающихся областей
При рисовании перекрывающихся областей цвет их пересечения
определяется цветом, нанесенным на текущую страницу последним. Нарисуем
два перекрывающихся прямоугольника.
%!
newpath
% серый квадрат
200 300 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
сlosepath
0.5 setgray
fill
newpath
% светлый квадрат
236 336 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
closepath
.8 setgray
fill
showpage
% отобразить
Обратите внимание, что каждый квадрат начинается с оператора moveto.
Это связано с тем, что оператор fill очищает текущую траекторию и после него
не определена текущая точка, поэтому lineto и rlineto не имеют начальной
точки. Оператор stroke также очищает текущую траекторию.
Задание к лабораторной работе №1
Написать на языке PostScript программу рисования произвольной
композиции, содержащей различные плоские геометрические фигуры(
прямоугольники, дуги, овалы и т.п.).
Лабораторная работа №2
1
2
Тема: Программирование растровых изображений на языке PostScript с
использованием процедур.
Цель работы: освоение принципов и приобретение навыков
процедурного программирования изображений, использующих различные
шрифты и преобразования системы координат, на языке PostScript.
Методические указания к лабораторной работе
Словарь (dictionary) - PostScript-словарь связывает объект, именуемый
ключом, с другим объектом - значением этого ключа. Интерпретатор языка
PostScript может искать по ключу в словаре и получать его значение, если такой
ключ есть в таблице. PostScript всегда имеет два словаря: системный и
пользовательский. Системный словарь объединяет имя каждого встроенного в
язык оператора, с соответствующим ему действием. Словарь пользователя
ассоциирует имена с процедурами и переменными, определенными в
программе. Когда интерпретатор встречает имя, он сначала просматривает
словарь пользователя, а затем системный. Если имя в словаре найдено, то
выполняются соответствующие ему действия: либо объект помещается в стек,
либо выполняются некоторый набор операторов. Если имя не найдено, то
выдается сообщение об ошибке. Словари хранятся в стеке словарей: словарь
пользователя в верху стека, системный - внизу. Таким образом слово ищется
начиная с вершины стека. Программа может создать новые словари, которые
будут размещены в вершине стека словарей. Словарь, находящийся в вершине
стека и, следовательно, просматриваемый первым, называется текущим
словарем.
Переменные:
Чтобы определить переменную в PostScript, ее имя и значение нужно
занести в текущий словарь. Это делается с помощью оператора DEF, как в
следующем примере:
/name 47 def
Косая черта перед именем переменной показывает, что интерпретатору
следует поместить это имя в стек как литерал, а не пытаться сразу же искать его
в словаре. Вслед за именем в стек заносится число 47. И наконец DEF берет оба
эти объекта из стека и помещает их в текущий словарь. Второй элемент стека
name становится ключом, с которым ассоциировано значение первого элемента
(47). Определенное с помощью DEF значение переменной может быть
изменено либо новым оператором DEF, либо другими операторами, например:
/name 52 def
Если дальше в программе появится строка:
13 name add
то интерпретатор сделает следующее:
- поместит число 13 в стек;
1
3
- найдет в стеке словарей значение для ключа name и поместит его в стек;
- сложит два числа из вершины стека и поместит на их место результат.
Следующий оператор умножает значение переменной name на 12:
/ name name 12 mul def
Процедуры:
Процедура в PostScript - это набор операторов, сгруппированных под
общим именем. Имя процедуры является ключом в словаре, а набор операторов
ассоциируется как его значение. Когда имя процедуры появляется в программе,
то выполняется связанный с ним набор операторов. Процедуры в PostScript
определяются точно так же, как и переменные, с тем только отличием, что
набор операторов процедуры должен быть заключен в фигурные скобки.
Следующая строка, например, описывает процедуру inch (дюйм), полезную для
перевода дюймов в систему единиц, используемую в PostScript по умолчанию.
/inch {72 mul} def
Любое появление слова inch после этой строки заставит интерпретатор
поместить в стек число 72, умножить его на число лежащее в стеке ниже его и
поместить в стек вместо двух этих чисел результат их произведения, таким
образом следующие две строки эквивалентны:
3 72 mul
3 inch
Так как PostScript ориентирован на работу со стеком, естественный
способ передачи параметров - размещение их в стеке. Перепишем программу
рисования двух перекрывающихся областей из лабораторной работы №1:
/inch {72 mul} def
/box {
% в стеке: x y
newpath
moveto
1 inch 0
rlineto
0
1 inch rlineto
-1 inch 0
rlineto
closepath
} def
/fillgray {
% в стеке: уровень серого цвета
setgray fill
} def
% Основная программа
2 inch 3 inch box
.9
fillgray
2.5 inch 3.5 inch box
.7
fillgray
showpage
1
4
В такой записи программу уже значительно проще изменять и она более
самодокументирована, чем ее первый вариант.
Работа со шрифтами:
Текстовые данные представлены в PostScript объектами типа string
(строка). Строка может содержать любую последовательность символов,
заключенную в круглые скобки. Строка может быть помещена в стек,
присвоена переменной или напечатана. Однако перед тем, как строка будет
помещена на текущей странице, интерпретатору PostScript необходимо указать
какую гарнитуру и размер шрифта использовать при печати.
Шрифт - это набор символов, имеющих единый дизайн. Дизайн
конкретного шрифта называется гарнитурой. Набор гарнитур, разработанных
для совместного использования, называется семейством гарнитур. Наиболее
популярные гарнитуры: Таймс, Курьер, Журнальная и др. PostScript-шрифты
относятся к классу векторных и, следовательно, масштабируемых шрифтов.
Существующие
методы описания векторных
шрифтов позволяют
автоматически менять размер шрифта (кегель) с минимальными искажениями
его начертания при преобразовании размера.
Чтобы задать шрифт, нужно выполнить следующие действия:
 найти описание шрифта в словаре шрифтов;
 отмасштабировать шрифт до нужного размера. Его размер задается
минимальным расстоянием по вертикали между строками текста,
необходимым, чтобы эти строки не накладывались одна на другую,
например обычный шрифт часто задается высотой в 12 или 14 пунктов
(напомним, что 1 пункт = 1/72 дюйма);
 установить отмасштабированный шрифт в качестве текущего шрифта,
которым и будет печататься текст.
Опрераторы для работы со шрифтами:
- Name findfont - ищет в словаре шрифтов с названием FontDictionary и
устанавливает шрифт с именем Name. Если шрифт найден, то ссылка на него
помещается в стек для дальнейшей работы. В противном случае выдается
ошибка.
- Size scalefont - масштабирует текущий шрифт на величину Size.
- Font setfont - определят шрифт с именем Font как текущий.
- String show - рисует заданную строку на странице, используя при этом
текущее состояние графики ( текущий шрифт, текущий размер шрифта,
уровень серого либо цвет, текущую матрицу преобразований, текущее
положение). Текущее положение определяется левой нижней точкой базовой
линии текста, которая после выполнения оператора перемещается в
правую позицию базовой линии текста.
1
самую5
- String bool charpath - добавляет траекторию контура строки из вершины
стека к текущей. Если bool = true, то полученный результат (текст) можно
использовать для заливки и отсечения, иначе нельзя.
ПРИМЕР: работа со шрифтами.
Пример написан с использованием процедур и показывает, как во время
печати текста можно менять размер
шрифта. Определим процедуру,
устанавливающую шрифт нужного размера.
/newsize { % в стеке размер
scalefont setfont
} def
/getfont {
/Helvetica findfont
} def
% Основная программа
getfont 8 newsize
72 250 moveto (example) show
getfont 10 newsize
72 275 moveto (example) show
getfont 12 newsize
72 300 moveto
(example) show
showpage
Эта программа напечатает три раза слово EXAMPLE шрифтом разного
размера. Процедуры NEWSIZE и GETFONT можно объединить, если учесть
порядок следования аргументов в стеке. (Очевидно, что в нем хранится не сам
словарь шрифта непосредственно, а ссылка на него).
/scaleHelv {
% в стеке размер
/Helvetica findfont
exch
% кегель в вершине стека
scalefont
setfont
} def
Теперь запись строки программы станет еще компактней:
6 scaleHelv
Для печати текста часто требуются различные операции по
выравниванию слов по границам страницы, выравниванию промежутков между
буквами (КЕРНИНГ), чтобы напечатанный текст выглядел приятно. Для этой
цели в PostScript имеется 4 варианта оператора SHOW:
- ashow - при печати строки добавляет после каждого символа заданный
промежуток;
1
после6
- widthshow - при печати строки добавляет заданный промежуток
каждого появления некоторого символа (например, после каждого пробела);
- awidthshow - является комбинацией двух предыдущих операторов;
- kshow - выполняет заданную процедуру между каждой парой символов
в строке.
Текущий символ и символ, следующий за ним, передаются этой
процедуре как аргументы. Так строка
{pop pop (-) show} (World) kshow
напечатает его с дефисом между каждой парой букв:
W-o-r-l-d
Оба символа удаляются из стека, так как данная прцедура их не
использует. В основном оператор предназначен для кернинга, но может быть
использован и в других целях.
Используя оператор ARCTO, нарисуем какую-нибудь карточку:
/clearstack {
4 { pop } repeat
} def
200 300 translate
0 20 moveto
0 72 108 72 20 arcto
clearstack
108 72 108 0 20 arcto
clearstack
108 0 0 0 20 arcto
clearstack
0 0 0 72 20 arcto
clearstack
fill
0.5 setgray
80 45 20 0 360 arc
fill
/Helvetica findfont
25 scalefont
setfont
30 50 moveto
(My Card) show
showpage
Преобразование системы координат:
В PostScript не существует различия между графикой и текстом. Символ
текста рассматривается как один из графических объектов, размещаемых на
текущей странице. Поэтому для совмещения на ней текста и графики не
требуется никаких специальных действий.
Все графические операторы
PostScript выполняют свои действия в пространстве пользователя, которое
независимо от какого-либо физического устройства, и результат работы
1
систему7
операторов PostScript при печати автоматически преобразуется в
координат устройства. Однако иногда бывает удобно выполнять графические
преобразования, изменяя пользовательскую систему координат с помощью
применения следующих операторов:
х у translate - перенос начала координат в точку с координатами х, у.
Причем, каждый следующий перенос системы координат осуществляется уже
относительно предъидущей системы координат, а не относительно исходной.
х rotate - поворот системы координат на заданный угол (угол в градусах
отсчитывается от вертикальной оси против часовой стрелки).
/neworigin {
250 150 translate
60 rotate
} def
/treangl {
0 0 moveto
90 0 lineto
x y lineto
closepath
fill
} def
treangl
neworigin
treangl
neworigin
2 2 scale % увеличим в два раза масштаб по осям
treangl
showpage
Сохранение состояния графики PostScript:
Состояние графики - это набор данных, которые описывают, как
операторы будут влиять на текущую страницу. Пара взаимодополняющих
операторов, GSAVE и GRESTORE, позволяют сохранить текущее состояние
графики, а затем в нужный момент восстановить его. Это может потребоваться
до и после использования оператора FILL, который очищает текущую
траекторию. Если нужно продолжить рисование из какой-либо точки фигуры,
заполняемой оттенком серого, то удобно просто восстановить состояние
графики, сохраненное до выполнения FILL. Оператор GSAVE сохраняет копию
текущего состояния графики в стеке состояния графики. Этот стек может
хранить до 32-х состояний графики, включая текущее состояние.
Оператор GRESTORE восстанавливает состояние графики, сохраненное в
стеке самым последним. Все характеристики текущего графического состояния,
включая текущий путь, цвет, уровень серого цвета, ширину линии и систему
пользовательских координат возвращаются в состояние, в котором они были
перед выполнением оператора GSAVE.
1
8
Задание к лабораторной работе №2
Используя материалы предыдущей лабораторной работы, написать на
языке PostScript с использованием процедур программу рисования
произвольной цветной композиции (поздравительной открытки), содержащей
различные плоские геометрические и флористические изображения(лютики,
ромашки, листики, прямоугольники, дуги, овалы и т.п.). Размеры однотипных
фигур менять с помощью изменений масштабов по осям координат. (Эллипсы
можно получить, изменяя при рисовании окружности масштабы по осям
координат). Надписи на композиции сделать шрифтами разных типов и
размеров.
1
9
Лабораторная работа №3
Тема: Программирование изображений
использованием операторов ветвления и циклов.
на
языке
PostScript
с
Цель работы: освоение принципов и приобретение навыков
программирования
сложных растровых изображений PostScript
с
использованием способов ритмических преобразований системы координат и
графических свойств.
Методические указания к лабораторной работе
Прежде чем рассмотреть правила организации ветвлений и циклов,
остановимся на понятии выполняемого массива. Это более формальное
название объекта, который ранее был назван процедурой. Проанализируем,
какая разница для PostScript между строками:
12 5 sub
и
{ 12 5 sub }
В первом случае числа 12 и 5 будут помещены в стек и выполнена
операция вычитания, а во втором - эти числа и оператор SUB будут помещены
в массив, который затем будет занесен в стек. Выполняемому массиву может
предшествовать имя, задаваемое в виде литерала, а закрывать его может
оператор DEF, который ассоциирует его с именем в текущем словаре.
Выполняемый массив может использоваться также в некоторых
управляющих операторах, таких как оператор IF или оператор цикла REPEAT.
В этом случае выполняемый массив содержит операции, которые будут иметь
место, если выполнятся соответствующие условия.
Оператор if:
Прежде чем рассмотреть этот, посмотрим, как записываются операции
сравнения чисел. Вспомним, что в PostScript операторы сравнения следуют за
сравниваемыми величинами.
Оператор
Значение
eg
= (равно)
gt
> (больше)
ge
>= (больше или равно)
ne
<> (не равно)
lt
< (меньше)
le
<= (меньше или равно)
Логические операторы: NOT, AND, OR и XOR.
Результат операции сравнения или логической операции значение TRUE или FALSE.
2
логическое0
условие {proc} if
Оператор IF берет из стека логический объект, получаемый в результате
вычисления условия, и выполняемый массив. Если значение логического
объекта TRUE, то выполняются операции, записанные в этом массиве.
Например:
%%% Определяем переменные
/step
15 def
/rightmargin 450 def
%%% Определяем функцию
/checkmargin {
currentpoint pop % оставляет в стеке координату х текущей точки
rightmargin
gt {
% Если число на вершине стека больше 450
0 step
% то переходим в начало следующей строки
translate
0 0 moveto
} if
% в противном случае ничего не делаем
} def
Процедура получает координату текущей точки и сравнивает её со
значением правой границы рабочего поля. Если условие выполняется, то
происходит перенос начала координат на следующую строку.
Оператор ifelse:
Позволяет выбрать в зависимости от условия выполнение одной или
другой последовательности операторов. Его формат:
Bool {proc1} {proc2} ifelse
Если значение в вершине стека равно
последовательность {PROC1}, иначе - {PROC2}.
TRUE,
выполняется
Циклы:
В языке PostScript имеется три основных конструкции циклов: простой, с
параметром и с условием.
Простой цикл имеет следующую структуру:
<количество повторений> <повторяемая процедура> repeat
REPEAT берет из стека два операнда: счетчик цикла и повторяемую
процедуру. Например, для очистки стека мы можем использовать следующий
цикл:
{pop} repeat
Цикл с параметром напоминает конструкцию цикла FOR в Паскале
имеет следующую структуру:
2
и1
<начальное значение счетчика цикла>< приращение>< конечное значение
счетчика цикла>< повторяемую процедуру> FOR.
Следует учитывать, что непосредственно перед выполнением этой
процедуры FOR помещает в стек текущее значение счетчика цикла, и если он
не используется, то его следует оттуда явным образом удалять(!).
Следующая строка напечатает звездочку через каждые 15 единиц на странице:
0 15 450 {0 moveto (*) show } for
Вторая важная особенность FOR в том, что его операнды не обязательно
должны быть целыми числами. Пример использования этой особенности для
возможной модификации шрифта (изображения бъемных букв):
/Helvetica findfont
30 scalefont
setfont
/printword {
0 0 moveto
(PC Magazine) show
} def
200 300 translate
.95 -.05 0
% начало приращения, конец
{setgray printword -1.5 translate} for
1 setgray printword
showpage
Цикл с условием соответствует REPEAT...UNTIL в Паскале и имеет
конструкцию: <выполняемая процедура> LOOP.
Процедура выполняется до тех пор, пока в ней не встретится оператор
EXIT, который заканчивает циклическое выполнение. Если в повторяемой
процедуре нет оператора exit, то цикл будет бесконечным, например:
Напишем программу рисования конечной последовательности кругов
двух диаметров, центры которых лежат на прямой, параллельной оси Х.
%%% Определение процедур
/pagewidth 8 72 mul def % Ширина страницы
/circle {
% Рисование круга
x y radius
0 360 arc
stroke
} def
/new-x {
% Новая позиция для следующего. круга
x radius add % Это эквивалентно: х=х+radius
/x exch def
} def
/DoLineOfCrle {
% Рисуем линию из окружностей
/y exch def % заносим значения из стека в переменные
/radius exch def
/x
0 def
{
% условный цикл рисования окружностей до конца страницы
x pagewidth le % центр нового круга в пределах границы?
{circle new-x} % да - рисуем и вычисляем новую позицию
{exit}
% иначе - выход из цикла
ifelse
} loop
} def
2
2
%%%% Рисуем две линии кругов
15 200 DoLineOfCrle
45 200 DoLineOfCrle
showpage
Массивы:
PostScript работает со сложными структурами (записями), которые
называются одномерными массивами. Они определяются как набор объектов
(возможно разного типа), заключенный в квадратные скобки. Так
[ (PC Magazine) 1991 (сор) true]
Операции внутри квадратных скобок выполняются по обычным правилам
PostScript, так после вычисления
[(add) 10 5 6 mul add]
получим массив из двух элементов [(add) 40] .
Массив может быть также определен с помощью оператора ARRAY,
который берет из стека число и создает массив такой длины.
8 array
Эта строка оставит в стеке массив из 8 элементов. Его элементы - NULLобъекты. Элементы массива нумеруются с нуля, что нужно учитывать при
вычислении их индексов.
При анализе массива интерпретатор просматривает строку слева направо.
Открывающая (левая) квадратная скобка оставляет в стеке объект, называемый
маркером (MARK). После маркера интерпретатор просматривает строку
программы дальше и помещает в стек все встречающиеся ему объекты до
правой квадратной скобки. Эта скобка является оператором, создающим массив
из хранящихся в стеке объектов: от вершины до маркера. При этом маркер
удаляется из стека, а массив остаётся.
Массивы, строки и словари - всё это примеры объектов сложных типов.
Их значения хранятся отдельно от самого объекта (то есть PostScript работает в
этом случае не со значением, а с указателем на него).
Для работы с элементами массивов служат операторы PUT и GET.
2
в3
Оператор PUT берет из стека три аргумента: массив, индекс элемента
массиве и объект. Он помещает объект в массив в позицию, заданную
индексом:
/MyArray 12 array def
MyArray 5 (Jerry) put
У оператора GET два аргумента: массив и индекс. Он возвращает в стеке
элемент массива с заданным индексом. После выполнения строки
[0 1 2 3 4 5] 5 get
в вершине стека будет число 4.
Оператор LENGTH, возвращает длину массива (то есть число его
элементов).
Пример программы. которая распечатывает массив, находящийся в стеке.
/LeftM 60 def
/TmpString 40 string def
/Helvetica findfont
11 scalefont
setfont % задали шрифт
/newln {
currentpoint 15 sub exch pop
LeftM exch moveto
} def
% y-15
/printarr { % в стеке массив
/arr exch def % поместить массив в переменную
01
% параметры цикла: от шаг
arr length 1 sub % до (ДлинаМассива - 1)
{
arr exch get % следующий элемент
TmpString cvs % преобразуем вго в строков тип
show newln % печатаем и нач. новую строку
} for
} def
%%%%%% Основная программа %%%%%
LeftM 400 moveto % печатаем отсюда
% задаем массив
[(Julia) % строка
15
% число
/SimplName % литерал
[8 3 4] % массив
{NewLN} % исполняемый массив
LeftM
% переменная
]
printarr % печатаем его
showpage
2
стек4
Перед каждым выполнением цикла оператор for помещает в
счетчик, который используется в качестве индекса в строке arr exch get. (В этой
строке берется не сам массив из стека, а ссылка на него по имени переменной,
поэтому и делается exch).
Результат работы программы:
Julia
15
SimplName
--nostringval---nostringval-60
Как видно из примера обычные действия над массивом в PostScript
достаточно утомительны. Так как наиболее частой операцией над массивом в
этом языке является применение некоторой процедуры к каждому его
элементу, то для этого целесообразно применить специальный оператор цикла
FORALL. Предыдущий пример можно записать с его помощью более
компактно:
arr {30 string cvs show} forall
Задание к лабораторной работе №3
Используя материалы данной и предыдущих лабораторных работ,
написать на языке PostScript программу рисования круглой печати и бланка
письма некоторого предприятия.
2
5
Лабораторная работа №4
Тема: Приемы низкоуровневой работы с мышью.
Цель работы: Изучение структуры мыши и операций низкоуровневой
работы с ней.
Методические указания к лабораторной работе
Мышь – периферийное устройство, подключаемое к компьютеру, которое
предоставляет возможность удобного перемещения в области экрана.
Эволюция мыши прошла 3 этапа:
- контактные;
- фотодиодные;
- оптические.
Первые 2 основаны на анализе частоты импульсов.
В первом случае электрический импульс генерируется при соединении
контактов на диске и внешнего контакта прижатого к диску.
Во втором случае диск не содержит на себе контактов, но содержит
вырезы по диаметру. Также в этом поколении светодиод и фотодиод светодиод
испускает электромагнитный импульс, который при определенном положении
диска проходит сквозь вырез и попадает на фотодиод. Фотодиод генерирует
электромагнитный импульс, который далее рассматривается анализатором
частоты.
В третьем поколении мыши отсутствует самый популярный элемент –
шарик, а также валы, диски, светодиод, фотодиод контакты. Вместо шариков в
эти мышки встраивается миниатюрная фотокамера, которая постоянно, с
большой скоростью, снимает изображение под мышкой, относительно мощный
процессор анализирует последние несколько кадров и
на основании этих
данных приходит к выводу о направлении перемещения мышки.
Операции работы с мышью:
-
сброс мыши;
-
включение курсора мыши;
-
выключение курсора мыши;
-
установление курсора мыши;
2
6
-
определение координат и состояния клавиш мыши;
-
определение области перемещения, видимости курсора мыши;
-
задание формы курсора мыши;
-
определение перемещения мыши в дюймах;
-
подключение пользовательских процедур;
Рассмотрим реализацию описанных операций на низкоуровневом языке
программирования Ассемблер.
Обращение
к
подпрограмме
обрабатывающей
сигнал
от
мыши
осуществляется с помощью прерывания int 33h.
Инициализация мыши:
Вход: AX = 0000h
Выход: AX = 0000h – если нет мыши или драйвера
AX = FFFFh – есть мышь
BX = 0, если число клавиш мыши ≠2
BX = 2, если число клавиш мыши = 2
BX = 3, если число клавиш мыши = 3
При начальной инициализации курсор в центре экрана, на нулевой
странице и гасится. Видимость/перемещение всюду.
Включение курсора мыши:
Вход: AX = 0001h
При включении курсора счетчик видимости становиться равным 0,
происходит сброс области невидимости.
Выключение курсора мыши:
Вход: AX = 0002h
При включении курсора счетчик видимости становиться равным -1,
курсор гасится.
Определение положения курсора мыши:
Вход: AX = 0003h
Выход: BX = 76543210 (0 - левая клавиша нажата, 1 - правая, 2 - средняя)
СХ= координата Х в пикселях
DХ= координата Y в пикселях
Для текстового режима необходимо координаты сдвинуть на 3
2
разряда,7
т.е. разделить координаты на 8.
Установка курсора мыши:
Вход:
АХ = 0004h
СХ= координата Х в пикселях
DХ= координата Y в пикселях
Для текстового режима необходимо координаты умножить на 8.
Определение положение курсора при нажатии клавиши мыши:
Вход:
АХ = 0005h
ВХ = 0 – левая клавиша
1 – правая клавиша
2 – средняя клавиша
Выход:
АХ = состояние клавиши
ВХ = количество нажатий клавиши после последнего вызова функции.
СХ:DХ = координаты курсора мыши в момент последнего нажатия.
Определение положение курсора при отпускании клавиши мыши:
Вход:
АХ = 0006h
ВХ = 0 – левая клавиша
1 – правая клавиша
2 – средняя клавиша
Выход:
АХ = состояние клавиши
ВХ = количество отпускания клавиши после последнего вызова функции.
СХ:DХ = координаты курсора мыши в момент последнего отпускания.
Задание диапазона движения курсора по горизонтали:
Вход:
АХ = 0007h
2
8
СХ = минимальная координата по Х
DХ= максимальная координата по Х
Задание диапазона движения курсора по вертикали:
Вход:
АХ = 0008h
СХ = минимальная координата по Y
DХ= максимальная координата по Y
Задание формы курсора в графическом режиме:
Вход:
АХ = 0009h
BХ = координаты (0-15)
DХ = точки внутри графического изображения курсора, которые
являются фактическим указанием положения курсора мыши на экране (0-15).
ES:DX = указатель на битовое изменение курсора мыши.
Задание формы курсора мыши в текстовом режиме:
Вход:
АХ = 000Ah
BХ = тип курсора
0 – программный
1 - аппаратный
СХ= маска экрана, если ВХ=0
СХ= начальная строка курсора мыши, если ВХ=1
DХ= маска курсора, если ВХ=0
DХ= конечная строка курсора мыши, если ВХ=1
Определение содержимого счетчиков перемещения:
Вход:
АХ = 000Вh
Выход:
Результат в “миках”(MicKey).
СХ = количество “миков” по горизонтали
DХ = количество “миков” по вертикали
2
9
Установка драйвера событий:
Вход:
АХ = 000Сh
СХ = маска вызова, имеющая следующие биты:
0 – при перемещение мышки
1 – при нажатии левой клавиши
2 – при отпускании левой клавиши
3 – при нажатии правой клавиши
4 – при отпускании правой клавиши
5 – при нажатии средней клавиши
6 – при отпускании средней клавиши
7Fh – любое событие
ES:DX = адрес драйвера, который будет обрабатывать эти события
Входная информация для драйвера событий:
AX = маска вызова
ВХ = состояние клавиш
СX, DX = координаты курсора
SI, DI = относительное перемещение курсора
DS = сегмент данных драйвера мыши
Этот драйвер событий подключается и вызывается из драйвера мыши.
Мы регистрируем в операционной системе MS-DOS собственную программу,
которая будет вызываться при наступлении событий связанных с мышью.
Отсюда получаем еще один способ внедрения программ. Имеется возможность
установить еще один альтернативный драйвер событий (АХ = 0018h).
Определение типа мыши:
Вход:
AХ = 0024h
Выход:
ВХ = версия драйвера
СН = вид подключения
3
0
1 – BUS (через специализированный адаптер)
2 – SERIAL (через последовательный адаптер)
3 – Inport
4 – PS/2
(через круглый разъем)
5 – HP
СL = номер прерывания, к которому подключена мышь.
Определение порога удвоения скорости:
Вход:
АХ = 0013h
Выход:
DX = порог(мики/сек)
По умолчанию - 64 мика/сек
Установление области исключения видимости для курсора:
То есть определение области, в которой курсор становится невидим.
Вход:
AX = 0010h
СX:DX = координата левого верхнего угла
SI:DI = координата правого нижнего угла.
Задание к лабораторной работе №4
Написать
программу,
которая
бы
реализовывала
требования,
представленные в таблице 1. Пример выполнения задания представлен в
приложении А.
Таблица 1 - Варианты заданий к лабораторной работе №4:
№
ЗАДАНИЕ
варианта
1
Изменить тип курсора в текстовом режиме при нажатии
некоторой клавиши на клавиатуре
2
Изменить тип курсора в графическом режиме при
3
1
нажатии некоторой клавиши на клавиатуре
3
Изменять область видимости по горизонтали при каждом
нажатии клавиши мыши
4
Изменять область видимости по вертикали при каждом
нажатии клавиши мыши
5
Включать курсор при нажатии левой клавиши, а
выключать по нажатию правой клавиши мыши
6
Выключать курсор при нажатии левой клавиши мыши, а
включать по нажатию правой клавиши мыши
7
Установить курсор в правый нижний угол экрана
8
Установить курсор в левый нижний угол экрана
9
Установить курсор в правый верхний угол экрана и
изменить его вид
10
Вывести на экран координаты положения курсора
11
Вывести на экран содержимое счетчиком перемещения
курсора
12
Установить область невидимости курсора
13
Определить тип мыши
14
Изменять тип курсора в графическом режиме при
помещении его на середину экрана
15
Выключать курсор при помещении его на середину
экрана
16
Включать курсор при помещении его в точку с
координатами (0,0)
17
Изменять диапазон движения курсора по горизонтали
при нажатии левой клавиши мыши, а по вертикали при
нажатии правой клавиши
18
Изменять диапазон движения курсора по вертикали при
нажатии
клавиши
мыши,
а
по
горизонтали
при
отпускании клавиши
19
3
2
Установить курсор в середине экрана и изменить его тип
в текстовом режиме
20
Выключать курсор при нажатии клавиши мыши в точке с
координатами (0,0)
Контрольные вопросы
1.Каковы принципы работы контактных, бесконтактных и оптических
мышей?
2.Перечислите операции работы с мышью?
3. В каких регистра храняться координаты указателя мыши?
4. Как осуществляется определение типа мыши?
5. С помощью какого проерывания обрабатывается сигнал от мыши?
3
3
Лабораторная работа №5
Тема: Работа с CD проигрывателем.
Цель работы: Изучение возможностей, предоставляемых драйвером CDROM msdex.
Методические указания к лабораторной работе
В лабораторной работе подробно рассматриваются возможности работы
с драйвером CD-ROM. Для выполнения лабораторной работы необходим
драйвер CD-ROM mscdex; его функции используются для воспроизведения
музыкальных компакт-дисков. Все они вызываются прерыванием 2Fh.
Mscdex (Microsoft CD extension) предоставляет следующие возможности
(таблица 1):
Таблица 2 – возможности Mscdex
Функция
Аргументы
Результаты
Проверка
AX = 1100h
AL=00h не инсталлирован,
наличия
STACK: DADAh
возможна
инсталляция
и
драйвера
STACK не изменяется;
MSCDEX
01h не инсталлирован, не
возможна
инсталляция
и
STACK не изменяется;
FFh инсталлирован
STACK: WORD ADADh.
Проверка
AX = 1500h
BX = количество устройств;
наличия CD-
BX = 0000h
CX = начальная буква
устройства (0=A:).
ROM
Получить
AX = 1501h
Буффер заполняется
список CD
ES:BX -> буффер для
каждой
устройств
списка устройств (5 bytes
BYTE –
на одно устройство)
DWORD – адрес драйвера
буквы
для
устройства:
буква устройства,
устройства.
Получить
AX = 1502h
CF
устанавливается,
если
авторское имя ES:BX -> 38-байтовый
устройство не CD-ROM – AX
файла
буфер
=
CX = номер устройства
устройство);
000Fh
(неверное
CF сбрасывается в случае
успеха.
Получить
AX = 1503h
CF
устанавливается,
абстрактное
ES:BX -> 38-байтовый
устройство не CD-ROM – AX
имя файла
буфер
=
CX = номер устройства
устройство);
000Fh
если
(неверное
CF сбрасывается в случае
успеха.
Получить имя
AX = 1504h
CF устанавливается, если
файла
ES:BX -> 38-байтовый
устройство не CD-ROM – AX
документации буфер
CX = номер устройства
= 000Fh (неверное
устройство);
CF сбрасывается в случае
успеха.
Абсолютное
AX = 1508h
CF устанавливается в случае
чтение
ES:BX -> буфер
ошибки и в AX = код ошибки
CX = цифра устройства
(15=неверное
SI:DI = номер начального
21= не готово);
сектора
CF сбрасывается при успехе.
устройство,
DX = число секторов
Запись
То же
Зарезервиро-
AX = 150Ah
То же
вано
Проверка
AX = 150Bh
BX = ADADh, если MSCDEX
устройства
CX = цифра устройства
установлен;
AX = 0000h, если устройство
не поддерживается;
3
4
иначе
в
АХ
не
нулевое
3
5
значение.
Получить
AX = 150Ch
версию
BH = старшее число
BL = младшее число
MSCDEX
Получить CD- AX = 150Dh
ROM буквы
ES:BX -> буфер для
устройств
списка букв (1 байт на
Результат в буфере
устройство)
Направить
AX = 1510h
запрос
CX = цифра устройства
устройству
ES:BX -> заголовок
Описание см. Ниже
запроса к устройству
Для функции 1510h используется следующий формат заголовка запроса
к устройству:
Request_Hdr struc
- размер структуры
rh_Len
db ?
rh_Subunit
db ? - номер устройства
rh_Code
db ? - код запроса (смотри в файле codes.inc)
rh_Status
dw ? – результат запроса
rh_Reserved
db 8 dup(?) - зарезервировано
Request_Hdr ends
В приложении Б приведены функции для работы с CD проигрывателем. В
приложении В – листинг программы.
Задание к лабораторной работе №5
3
6
В соответствии с вариантом реализовать функцию CD проигрывателя
(таблица 2).
Таблица 2 - Варианты заданий
№
Функция
варианта
1
Открытие дверцы
2
Закрытие дверцы
3
Получение списка устройств
4
Блокирование дверцы и разблокирование дверцы
5
Проигрывание третьей мелодии
6
Прерывание проигрывания
7
Продолжение проигрывания
8
Позиционирование
9
Получение информации о диске
10
Проигрывание первых 30 с первой мелодии
Контрольные вопросы
1. Как осуществить открытие и закрытие дверцы проигрывателя?
2. Как получить список устройств?
3. Как осуществить прерывание и продолжение проигрывания?
4. Как осуществить позиционирование и проигрывание первых N
мелодий, начиная с первой мелодии?
3
7
Лабораторная работа № 6
Тема: Программирование видеокарты SuperVGA с помощью стандарта
VESA.
Цель работы: ознакомиться с устройством и работой типовой
видеокарты и получить навыки ее программирования.
Методические указания к лабораторной работе
Устройство типовой видеокарты: память, контpоллеp, ЦАП и ПЗУ:
Видеопамять служит для хpанения изобpажения. От ее объема зависит
максимально возможное полное pазpешение видеокаpты - A x B x C, где A количество точек по гоpизонтали, B - по веpтикали, и C - количество
возможных цветов каждой точки. Hапpимеp, для pазpешения 640x480x16
достаточно 256 кб, для 800x600x256 - 512 кб, для 1024x768x65536 (дpугое
обозначение - 1024x768x64k) - 2 Мб, и т.д. Поскольку для хpанения цветов
отводится целое число pазpядов, количество цветов всегда является степенью
двойки (16 цветов - 4 pазpяда, 256 - 8 pазpядов, 64k - 16, и т.д.).
Видеоконтpоллеp отвечает за вывод изобpажения из видеопамяти,
pегенеpацию ее содеpжимого, фоpмиpование сигналов pазвеpтки для монитоpа
и обpаботку запpосов центpального пpоцессоpа. Для ускоpения вывода
изобpажения на экpан монитоpа и снижения частоты конфликтов пpи
обpащении к памяти со стоpоны видеоконтpоллеpа и центpального пpоцессоpа
пеpвый имеет отдельный буфеp, котоpый в свободное от обpащений ЦП вpемя
заполняется данными из видеопамяти; внутpенняя шина данных контpоллеpа
обычно шиpе внешней (32, 64 или 128 pазpядов пpотив 16 или 32). Если
конфликта избежать не удается - видеоконтpоллеpу пpиходится задеpживать
обpащение ЦП к видеопамяти, что снижает пpоизводительность системы; для
исключения подобных конфликтов в pяде каpт пpименяется так называемая
двухпоpтовая
память
(VRAM,
WRAM),
допускающая
одновpеменные
обpащения со стоpоны двух устpойств.
Многие совpеменные видеоконтpоллеpы является потоковыми - их
pабота основана на создании и смешивании воедино нескольких потоков
гpафической инфоpмации. Обычно это основное изобpажение, на
накладывается
изобpажение
аппаpатного
куpсоpа
мыши
и
3
котоpое8
отдельное
изобpажение в пpямоугольном окне, поступающее, напpимеp, от TV-пpиемника
или декодеpа MPEG. Видеоконтpоллеp с потоковой обpаботкой, а также с
аппаpатной
поддеpжкой
некотоpых
типовых
функций
называется
акселеpатоpом или ускоpителем, и служит для pазгpузки ЦП от pутинных
опеpаций по фоpмиpованию изобpажения.
ЦАП
(цифpоаналоговый
пpеобpазования
пpеобpазователь,
pезультиpующего
потока
DAC)
данных,
служит
для
фоpмиpуемого
видеоконтpоллеpом, в уpовни интенсивности цвета, подаваемые на монитоp.
Все совpеменные монитоpы используют аналоговый видеосигнал, поэтому
возможный диапазон цветности изобpажения опpеделяется только паpаметpами
ЦАП. Большинство ЦАП имеют pазpядность 8x3 - тpи канала основных цветов
(кpасный, синий, зеленый, RGB) по 256 уpовней яpкости на каждый цвет, что в
сумме дает 16.7 млн. цветов. Обычно ЦАП совмещен на одном кpисталле с
видеоконтpоллеpом, однако это делается в основном для недоpогих ЦАП,
поскольку
близкое
соседство
с
интенсивно
pаботающими
схемами
отpицательно влияет на стабильность pаботы ЦАП.
Видео-ПЗУ (Video ROM) - постоянное запоминающее устpойство, в
котоpое записаны видео-BIOS, экpанные шpифты, служебные таблицы и т.п.
ПЗУ не используется видеоконтpоллеpом напpямую - к нему обpащается только
центpальный пpоцессоp, и в pезультате выполнения им пpогpамм из ПЗУ
пpоисходят обpащения к видеоконтpоллеpу и видеопамяти. Hа многих
совpеменных каpтах устанавливаются электpически пеpепpогpаммиpуемые
ПЗУ (EEPROM, Flash ROM), допускающие пеpезапись пользователем под
упpавлением специальной пpогpаммы из комплекта каpты.
ПЗУ необходимо только для пеpвоначального запуска адаптеpа и pаботы
в pежиме MS DOS, Novell Netware и дpугих ОС, pаботающих пpеимущественно
в текстовом pежиме; опеpационные системы Windows, OS/2 и им подобные,
pаботающие чеpез собственные видеодpайвеpы, не используют ПЗУ для
упpавления адаптеpом, либо используют его только пpи
3
выполнении9
пpогpамм для MS-DOS.
Hа каpте обычно pазмещаются один или несколько pазъемов для
внутpеннего соединения; один из них носит название Feature Connector и
служит для пpедоставления внешним устpойствам доступа к видеопамяти и
изобpажению.
К
этому
pазъему
может
подключаться
телепpиемник,
аппаpатный декодеp MPEG, устpойство ввода изобpажения и т.п. Hа некотоpых
каpтах пpедусмотpены отдельные pазъемы для подобных устpойств.
Итак для вывода изображения (да и текста тоже) на экран монитора
компьютера служат специальные устройства - ВИДЕОКОНТРОЛЛЕРЫ или
ВИДЕОАДАПТЕРЫ. Они могут быть реализованы в виде отдельной платы или
же размещаться на материнской плате. Кроме того, любой из режимов
представления цвета контроллер поддерживает не вообще, а только для
некоторого набора допустимых значений количества пикселов на экране
монитора. Величина, которая объединяет в себе количество строк на экране и
число точек в строке называется РАЗРЕШАЮЩЕЙ СПОСОБНОСТЬЮ (или
просто РАЗРЕШЕНИЕМ). А совокупность разрешающей способности и
формата представления цвета носит название ВИДЕОРЕЖИМА.
Первые видеоплаты персональных компьютеров, например, позволяли
выводить 200 строк по 320 точек, каждая из которых могла быть одного из
четырех цветов. В последние два десятка лет эти устройства бурно развивались
(как, впрочем, и другие компоненты персональных компьютеров). Пропустим
первые достижения в этой области и остановимся на видеорежиме "цветного"
VGA (Video Graphics Adapter), называемого еще MCGA (Multi Color Graphics
Adapter),
известного
программистам
также
по
номеру
13h
(шестнадцатиричному). Это был (и есть) 256-цветный режим с разрешением
320x200 точек.
Все ранние видеорежимы, включая и MCGA, появлялись достаточно
медленно, по одному и, в силу этого, успевали стандартизироваться.
Существование стандарта означало, что с режимами,
4
поддерживаемыми0
конкретным видеоадаптером, можно было работать стандартным образом,
независимо от того, кто эту плату выпустил.
Высококачественные видеорежимы:
В дальнейшем, фирмы-производители развивали более совершенные
видеоадаптеры, получившие название SuperVGA. И все было бы хорошо, но
каждый
производитель
обеспечивал
собственный
интерфейс
к
своим
видеоадаптерам, а эти интерфейсы не были совместимы между собой.
Естественно, такое положение не могло существовать долго. Организация
под названием VESA (Video Electronics Standards Association) разработала и
распространила
специальный
стандарт
на
интерфейс
к
SuperVGA
видеоадаптерам. Версия 1.2 этого стандарта датирована 22 октября 1991 года.
Версия 1.1 - июнем 1990 года. Стандарт обеспечивает набор функций, которые
прикладная программа может использовать для получения информации
относительно возможностей и характеристик специфической реализации
SuperVGA и управления операциями таких аппаратных средств в терминах
инициализации видеорежима и доступа к видеопамяти. Функции реализованы
как расширение функций VGA видео BIOS'а и доступны через прерывание 10h.
Сначала производители аппаратных средств и независимые разработчики стали
снабжать
видеоадаптеры
специальными
драйверами,
обеспечивающими
выполнение функций стандарта VESA. Появились также так называемые
"универсальные" драйверы, типа univesa, univbe и т.п., которые позволяли
работать с более или менее широким набором видеоадаптеров. Uni сокращение от слова универсальный; VESA - понятно, что такое; VBE - VGA
BIOS Extension (расширение VGA BIOS).
Одновременно производители
аппаратных средств начали встраивать поддержку функций стандарта VESA в
видеоBIOS своих устройств.
4
1
Видеорежимы SuperVGA:
Номера видеорежимов стандартного VGA занимают один байт и имеют
диапазон от 00h до 13h. В диапазоне от 14h до 7Fh размещаются так
называемые OEM-специфичные расширенные видеорежимы SuperVGA. (OEM
- Original Equipment Manufacturer - Основной Изготовитель Оборудования).
Номера от 80h до FFh не используются, так как старший бит в стандартном
VGA используется как флаг очистки видеопамяти при инициализации
видеорежима. Видеопамять очищается, когда этот бит равен нулю. VESAстандарт SuperVGA отводит два байта для номера видеорежима. Старший байт
содержит значение 01h. Младший бит в нем – признак режима VESA,
остальные пока не используются (зарезервированы). Младший байт
конкретизирует видеорежим. Таким образом полный (двухбайтный) номер
видеорежима VESA может лежать в диапазоне от 100h до 17Fh. Старший бит в
младшем байте как и раньше служит флагом очистки видеопамяти при
инициализации видеорежима. В версии стандарта 1.2 (октябрь 91) определено
28 номеров от 100h до 11Bh (таблицы 1 и 2).
Таблица 3 - Text SuperVGA Video Modes
Номер режима
Столбцы
Строки
108h
80
60
109h
132
25
10Ah
132
43
10Bh
132
50
10Ch
132
60
4
2
Таблица 3 - Graphics SuperVGA Video Modes
Номер режима
Разрешение
Глубина цвета
Видеопамять
100h
640x 400
256
250 K =~0.24 M
101h
640x 480
256
300 K =~0.29 M
102h
800x 600
16
234 K =~0.23 M
103h
800x 600
256
468.75K=~0.46 M
104h
1024x 768
16
384 K = 0.35 M
105h
1024x 768
256
768 K = 0.75 M
106h
1280x1024
16
640 K = 0.625M
107h
1280x1024
256
1280 K = 1.25 M
10Dh
320x 200
32K (1:5:5:5)
125 K =~0.12 M
10Eh
320x 200
64K (5:6:5)
125 K =~0.12 M
10Fh
320x 200
16M (8:8:8)
187.5K =~0.18 M
110h
640x 480
32K (1:5:5:5)
600 K =~0.59 M
111h
640x 480
64K (5:6:5)
600 K =~0.59 M
112h
640x 480
16M (8:8:8)
900 K =~0.88 M
113h
800x 600
32K (1:5:5:5)
937.5K =~0.92 M
114h
800x 600
64K (5:6:5)
937.5K =~0.92 M
115h
800x 600
16M (8:8:8)
1406.25K=~1.37 M
116h
1024x 768
32K (1:5:5:5)
1536 K = 1.5 M
117h
1024x 768
64K (5:6:5)
1536 K = 1.5 M
118h
1024x 768
16M (8:8:8)
2304 K = 2.25 M
119h
1280x1024
32K (1:5:5:5)
2560 K = 2.5 M
11Ah
1280x1024
64K (5:6:5)
2560 K = 2.5 M
11Bh
1280x1024
16M (8:8:8)
3840 K = 3.75 M
4
3
В стандарте предусмотрены как графические (таблица 2), так и текстовые
(таблица 1) видеорежимы высокого разрешения.
Самое высокое качество графики обеспечивает режим 11Bh (1280x1024
x16M цветов), самый мелкий текстовый режим 10Ch (132символа на 60строк).
Конечно, не все видеоплаты могут поддерживать все режимы. Здесь существует
ограничение, связанное с объемом видеопамяти. Действительно, для самого
качественного графического видеорежима 11Bh требуется 1280x1024x3 = 3.75
M видеопамяти (3 байта на каждый пиксел).
Самые слабые видеоплаты SuperVGA имеют всего 512 К видеопамяти, и
для них могут быть доступны только видеорежимы до 1024x768 x 16 цветов
(384 K), 800x600 x 256 цветов (~470 K),
320x200 x 16M цветов (187.5 K).
Наиболее распространенные сейчас мегабайтные платы, в принципе,
позволяют:
для 16 цветов - 1280x1024 ( 640 K),
для 256 цветов - 1024x 768 ( 768 K),
для 64K цветов - 800x 600 (~940 K),
для 16M цветов - 640x 480 ( 900 K).
Конечно, не следует думать, что видеоадаптер будет поддерживать все
доступные по размеру его памяти видеорежимы. Это не так. Для поддержки
того или иного видеорежима необходимо, чтобы в драйвере адаптера были
записаны соответствующие программы, а для этого нужно место в
4
ПЗУ4
BIOS'a. Список поддерживаемых видеорежимов можно получить, вызвав
функцию 00h видео BIOS'a.
Окна видеопамяти:
Процессор ПК не может непосредственно обращаться к видеопамяти. Для
операций
с
ней
предусмотрен
специальный
механизм
"отображения"
видеопамяти в сегменте адресного пространства, доступном процессору.
Обычно этот сегмент начинается с адреса A000h, но может быть и по адресу
B000h. Размер сегмента при 16-ти разрядной адресации - 64 К. Для
видеорежимов VGA и более ранних этого сегмента хватало для отображения
всей видеопамяти. Однако даже самый плохонький режим SuperVGA требует в
два раза больше памяти (не говоря уже о 4-х мегабайтном монстре 1280x1024
при почти 17 миллионах цветов).
Было принято решение, подобное тому, которое сделала в свое время
фирма Intel для адресации с помощью 16-ти разрядных регистров (которые
дают только 64К) памяти до 1 Мегабайта. Видеопамять отображается на 64-х
килобайтный сегмент не вся, а частями, называемыми страницами. Необходимо
только указать адрес начала отображаемой страницы видеопамяти. Этот адрес
не может быть произвольным. Он определяется с точностью до некоторого
значения, называемого GRANULARITY (грэньюлэрети), по-русски – СТЕПЕНЬ
ДЕТАЛИЗАЦИИ.. Например, если для работы с изображением вам нужны его
куски по 40 килобайт (0-40, 40-80 и т.д.), при степени детализации равной 64K
второй кусок будет находиться в двух страницах видеопамяти (40-64 и 64-80), и
вам необходимо будет их постоянно переключать, а при степени детализации
равной или меньшей 32K вы сможете каждый кусок отобразить на свою
видеостраницу (первый на 0-64, второй на 32-96), и, соответственно, не
переключать постоянно страницы при работе со вторым куском. Окон
отображения видеопамяти может быть два, и в этом случае можно работать
одновременно с двумя участками видеопамяти. Это бывает полезно, например,
при копировании части изображения из одного места в другое.
Вызовы BIOS расширенного VGA:
4
5
Для работы с BIOS видеоадаптера SuperVGA в настоящее время
существует 9 операций, которые сгруппированы под одним номером функции 4Fh прерывания INT 10h. Как обычно, номер функции передается программе
обработки в регистре AH, а номер операции или подфункции в регистре AL.
Эти операции таковы:
 Операция 00h - Получить общую информацию о SuperVGA.
 Операция 01h - Получить информацию о режиме SuperVGA.
 Операция 02h - Установить SuperVGA видеорежим.
 Операция 03h - Получить текущий видеорежим.
 Операция 04h - Сохранение / Восстановление SuperVGA видеосостояния.
 Операция 05h - Управление окнами видеопамяти.
 Операция 06h - Установить / Получить длину логической строки.
 Операция 07h - Установить / Получить начало экрана.
 Операция 08h - Управление цифро-аналоговым преобразователем.
Если видео BIOS поддерживает VESA стандарт SuperVGA, онпостарается
выполнить операцию, а если нет, то ничего непроизойдет. Как же определить,
выполнена операция или нет? Каждая функция возвращает статусную
информацию в регистре AX. В младшем байте (регистр AL) будет содержаться
4Fh, если BIOS поддерживает VESA стандарт, любое другое число говорит о
том, что этот стандарт не поддерживается. Старший байт (регистр AH)
сообщает о том, выполнена или нет конкретная операция. В случае успешного
выполнения AH=0.
Теперь рассмотрим некоторые наиболее часто используемые операции
VESA расширения видео BIOS.
4
6
Операция 00h - Получить общую информацию о SuperVGA:
Цель этой функции понятна из ее названия. В результате ее выполнения
вызывающая
программа
получит
информацию
относительно
общих
возможностей данного адаптера SuperVGA. Эта информация будет возвращена
в блоке размером 256 байт, расположенном по указанному при вызове функции
адресу. Для выполнения операции необходимо сделать следующее:
1) поместить в регистр AX код 4F00h (0-я подфункция функции 4Fh);
2) поместить в регистры ES:DI адрес 256-ти байтного участка
памяти, в который будет возвращена информация;
3) вызвать INT 10h.
В результате выполнения (или невыполнения) операции в регистре AX
появится статусная информация. В случае успешного выполнения это будет
004Fh (старший байт равен 0 - успешное выполнение, младший равен 4Fh VESA стандарт поддерживается). По адресу, указанному в регистрах ES:DI
будет размещен блок информации о SuperVGA, ради которой, собственно
говоря мы и вызывали эту функцию. Этот блок имеет следующую структуру:
VgaInfoBlock STRUC
VESASignature char[4] 'VESA'
; 4 байта сигнатуры (текст "VESA")
VESAVersion word
?
; номер версии стандарта VESA
OEMStringPtr dword
?
;дальний указатель на строку
;определения изготовителя платы
; возможности DAC
Capabilities byte[4] ?
VideoModePtr dword
?
;указатель на список номеров
;поддерживаемых SuperVGA режимов
TotalMemory word
Reserved
?
byte[236] ?
; объем памяти на плате VGA
; Резерв
4
7
VgaInfoBlock ENDS
Операция 01h - Получить информации о режиме SuperVGA:
Эта функция возвращает информацию об определенном SuperVGA видео
режиме. Функция заполняет блок информации по адресу, определяемому
вызывающим оператором. Размер блока информации 256 байт. Кое-что из этой
информации неявно определяется номером режима VESA.
Для выполнения операции необходимо сделать следующее:
1) поместить в регистр AX код 4F01h (1-я подфункция функции 4Fh);
2) поместить в регистр СX номер поддерживаемого платой видеорежима;
3) поместить в регистры ES:DI адрес 256-ти байтного участка
памяти,
в который будет возвращена информация;
4) вызвать INT 10h.
В результате выполнения (или невыполнения) операции в регистре AX
появится статусная информация, о которой мы уже говорили. В случае
успешного выполнения это будет 004Fh (старший байт равен 0 - успешное
выполнение, младший равен 4Fh - VESA стандарт поддерживается). По адресу,
указанному в регистрах ES:DI будет размещен блок информации о режиме
SuperVGA, ради которой, собственно говоря мы и вызывали эту функцию.
Наиболее важные поля этого блока таковы (таблица 3):
Таблица 4 - Важные поля блока информации о видеорежиме
Поле
Длина в Смещение в Описание
байтах
байтах
WinAAttributes
1
2
атрибуты окна A
WinBAttributes
1
3
атрибуты окна В
WinGranularity
2
4
степень детализации окна,
4
8
в Кб
WinSize
2
6
размер окна, в Кб
WinASegment
2
8
сегмент начала окна A
WinBSegment
2
10
сегмент начала окна B
WinFuncPtr
4
12
адрес
функции
прямой
работы с окнами
BytesPerScanLine
2
16
Количество
байт
в
логической строке
Xresolution
2
18
Горизонтальное
разрешение
Yresolution
2
20
вертикальное разрешение
XcharSize
1
23
ширина символа
YcharSize
1
23
высота символа
NumberOfPlanes
1
24
число
плоскостей
видеопамяти
BitsPerPixel
1
25
количество бит на пиксел
Поля WinAAttributes и WinBAttributes показывают существуют ли окна и
можно ли читать из них и писать в них:
 бит 0 показывает существование окна;
 бит 1 показывает что окна доступно для чтения;
 бит 2 показывает что окно доступно для записи.
Таким образом, если значение этого поля равно 3, то окно существует и
доступно только для чтения; если равно 5 – существует и доступно только для
записи; если равно 7 - окно существует и доступно и для чтения, и для записи.
Поле WinFuncAddr определяет адрес функции для прямой работы
4
с9
окнами видеопамяти CPU. Прямой вызов обеспечивает более быстрое
выполнение операций, чем работа через прерывание INT 10h. Следует иметь в
виду, что этот адрес может быть различным для каждого из видеорежимов.
Если значение этого поля равно NULL, то прямого доступа к функциям
управления окнами нет и для этих целей следует использовать функцию с
номером 05h.
Поле NumberOfPlanes определяет число плоскостей видеопамяти. Для 16ти цветных режимов это число равно 4, в других случаях - 1.
Поле BitsPerPixel показывает число бит, определяющих цвет одного
пиксела. Для 16-ти цветных режимов это число равно 4, для 256 цветов - 8, для
режимов HiColor - 16 и для TrueColor - 24.
Назначение остальных полей ясно из таблицы.
Операция 02h - Установить SuperVGA видеорежим:
Эта функция инициализирует видеорежим. Вызывается она обычным
образом. В регистре BX следует указать номер устанавливаемого режима.
Старший бит при этом интерпретируется как флаг очистки видеопамяти (0 очищать, 1 - нет). В результате выполнения (или невыполнения) операции в
регистре
AX
появится
статусная
информация.
Все
другие
регистры
сохраняются.
Операция 03h - Получить текущий видеорежим:
Эта функция возвращает номер текущего видеорежима в регистре BX, в
регистре AX - статус. Остальные регистры не меняются.
Операция 05h - Управление окнами видеопамяти:
Функция устанавливает или получает положение отображаемого окна в
видеопамяти. При вызове регистр BL содержит номер окна (0 – окно A, 1 - окно
B), значение регистра BH определяет вид операции (0 - установить, 1 -
получить текущее положение). В регистре DX задается (для
5
операции0
установки) или возвращается (для операции получения текущего положения)
положение отображаемого окна в видеопамяти. Это положение задается в
величинах GRANULARITY (степень детализации). Чтобы использовать эту
функцию правильно, необходимо предварительно определить размер, степень
детализации и адрес отображаемых окон с помощью функции 01h (получение
информации о режиме SuperVGA). К этой функции бывает возможен и прямой
доступ, дающий более быстрое выполнение. Адрес функции BIOS может быть
получен при использовании функции 01h (получение информации о режиме
SuperVGA).
Поле WinFuncAddr в ModeInfoBlock содержит адрес этой функции. Перед
прямым вызовом функции надо определить только входные параметры в BH,
BL, и DX (для установки окна), и нет необходимости загружать AH и AL.
Задание к лабораторной работе №6
Выполнить
задание
в
соответствии
с
вариантом
задания,
представленного в таблице 4.
Таблица 4 – Варианты заданий к лабораторной работе
1
Читать и выводить на экран полную информацию о SuperVGA
адаптере
2
Позволять в диалоговом режиме выбрать и установить видеорежим
3
Читать и выводить на экран информацию об установленном режиме
SuperVGA
4
Выводить на экран информацию о количестве видеопамяти
5
Выводить и на экран информацию о версии стандарта VESA и о
количестве видеопамяти
6
Выводить информацию о видеоадаптере
5
1
7
Выводить информацию о ЦАП
8
Выводить сведения о видеорежимах: номер, разрешение, глубина
цвета
9
Выводить сведения о видеорежимах: номер, глубина цвета, степень
детализации
10
Выводить сведения о видеорежимах: номер, разрешение, начало
сегмента окна А, начало сегмента окна В
11
Выводить сведения о видеорежимах: номер, разрешение, ширину и
высоту символов
12
Выводить сведения о видеорежимах: начало сегмента окна А, начало
сегмента окна В и их атрибуты
13
Выводить сведения о видеорежимах: номер, степень детализации,
размер окна
14
Выводить сведения о видеорежимах: номер, вертикальное и
горизонтальное разрешение
15
Выводить
сведения
о
видеорежимах:
номер
режима,
число
плоскостей видеопамяти и количество бит на пиксель
16
Установить видеорежим 800*600 с глубиной цвета = 256
17
Установить видеорежим 400*300 с глубиной цвета = 24
18
Выводить сведения о видеорежимах: номер, ширину и высоту
символов, горизонтальное разрешение
19
Выводить полную информацию о видеорежимах и сведения о
количестве видеопамяти
20
Выводить информацию о ЦАП и количестве видеопамяти
5
2
5
3
Лабораторная работа №7
Тема: Загружаемые символьные наборы
Цель работы: освоение принципов и приобретение навыков работы с
загружаемыми символьными наборами.
Методические указания к лабораторной работе
В пеpвых адаптеpах MDA и CGA можно в текстовых режимах
отображать только те символы, которые определены в таблице, расположенной
в ПЗУ знакогенеpатоpа в составе адаптера. Такой тип знакогенеpатоpа не
pассчитан на использование таблицы
опpеделений
символов
из ЗУПВ,
называемой загpужаемым шpифтом (loadable font). В новых адаптеpах EGA,
MCGA, VGA в текстовых pежимах допускается вывод на экpан символов,
опpеделения котоpых загpужаются в конкpетную область ЗУПВ.
Таблицы шpифтов:
Текстовый знакогенератор
во
всех
видеосистемах ссылается на
резидентную в памяти таблицы шpифтов,
котоpые должны лежать в
предопределенном месте памяти,
чтобы текстовый знакогенеpатоp мог
получить к ним доступ.
Таблицы шpифтов в ПЗУ:
В адаптеpах MDA, CGA и Hercules таблица шpифтов находится в ПЗУ
вне адресного пространства CPU. Только аппаратный знакогенератор имеет
туда доступ. Следовательно, наборы символов, отображаемые
в текстовых
режимах, программно не контролируются.
На EGA,
знакогенератор
использует таблицу,
находящуюся в ЗУПВ, а не в ПЗУ. BIOS содержит
встpоенные таблицы
шpифтов,
MCGA
и
VGA
которыми инициализируется ЗУПВ знакогенератора пpи задании
текстовогоо режима с помощью функции 00h пpеывания INT 10h.
Поскольку
адаптеpы могут
устанавливать текстовые режимы
различным вертикальным разрешением, размеры умалчиваемых
шpифтов оказываются переменным (см. рис. 1).
с
таблиц
5
4
200-строчные режимы:
CGA 200-строчные
текстовые режимы используют 8x8 матрицу
символов. В 80x25 текстовом режиме экран имеет ширину в 604 пикселей, в
режиме 40x25 ширина 320 пикселей.
Хотя CGA использует тот же набор
символов и шрифтов в текстовом и графических режимах, определение
символов для текстовых режимов расположено в выделенном ROM,
доступном только аппаратному генератору символов.
Адаптер
Видео режим
Символьная матрица
(ширина на высоту в пикселях)
____________________________________________________________________
MDA, HGC
Monochrome
9x14
CGA
40x25 16-color
8x8
80x25 16-color
8x8
80x25 16-color
8x8 (200-line resolution)
EGA
8x14 (350-line resolution)
MCGA
VGA
80x25 monochrome
9x14
40x25 16-color
8x16
80x25 16-color
8x16
40x25 16-color
8x8 (200-line resolution)
8x14 (350-line resolution)
9x16 (400-line resolution)
80x25 16-color
8x8 (200-line resolution)
8x14 (350-line resolution)
9x16 (400-line resolution)
80x25 monochrome
9x14 (350-line resolution)
9x16 (400-line resolution)
HGC+
80x25 monochrome
9x14
InColor Card
80x25 16-color
9x14
____________________________________________________________________
Рисунок 1 - Символьные матрицы для текстовых pежимов
5
5
350-строчные режимы:
В 350-строчном
текстовом
режиме
символы определяются в матрицах
на MDA и Hercules адаптерах
8x14.
Снова
таблица
определения
символов расположена в ROM вне адресного пространства CPU, что выделено
аппаратному
горизонтальное
генератору
символов.
разрешение
720
Поскольку
пикселей,
на
этих
каждый
8x14
адаптерах
символ
в
действительности отображается в матрице шириной 9 пикселей. Таким
образом, каждая строка на экране содержит 720/9 или 80 символов.
Если символы определены в ROM в матрице 8x14, но отображаются в
матрице 9x14, то откуда берутся остальные пиксели? Аппаратный генератор
символов в MDA, плате Hercules, EGA и VGA (в монохромном режиме)
добавляет дополнительный пиксель с права каждой строки восьмого пикселя в
каждом символе. Для всех оставшихся кодов символов дополнительный
пиксель отображается с атрибутом фона.
Поскольку девятый
(самый
правый)
пиксель в блоке графических
символов является копией восьмого, эти символы могут использоваться для
рисования горизонтальных линий.
Все другие отображаемые символы
отделяются друг от друга девятым пикселем. В результате изображение менее
скучено, чем без дополнительного пространства.
400-строчные режимы:
Умалчиваеммые текстовые режимы и MCGA и VGA имеют 400-строчное
вертикальное разрешение. Символы, используемые в этих режимах определены
в матрице 8x16. На VGA символы 8x16 отбражаются в матрице 9x16, так же
как на MDA или EGA с монохромным дисплеем.
Таблицы шpифтов ЗУПВ:
Адаптеpы
EGA,
VGA,
MCGA
имеют
встpоенный
знакогенератор, который использует таблицу шpифтов,
текстовый
расположенную в
предопределенной области ЗУПВ и в адpесном пpостpанстве пpоцессоpа. Зная
pазмещение этого ЗУПВ и его фоpмат, можно писать программы, которые
читают или обновляют таблицы шpифтов.
В текстовых режимах на EGA и VGA, видеобуфер организован
5
как6
четыре параллельных банкa памяти, как и в графических режимах. Начальный
адpес видеобуфеpа отобpажается на адpес В800:0000h.Однако в текстовом
режиме отображаемые данные содержатся только в банках 0 и 1 (см. рис.2).
Определение символов
Байты атрибут
Банк 4
Коды символов
Банк 2
B800:0000
или
B000:0000
Банк 1
Банк 0
Рисунок 2 - Видеобуфеp адаптеpов EGA и VGA в текстовых pежимах
Четные байты
(коды
символов)
в адресном
пространстве
CPU
расположены в банке 0, а нечетные байты (байты атрибутов) расположены в
банке 1. Это распределение невидимо для CPU; CRTC внутренне транслирует
нечетные адреса в смещение банка 1, а четные адреса ссылаются на банк 0.
Текстовый знакогенератор
использует набор 256-символьных таблиц,
сохраняемых в банке 2. EGA поддерживает четыре таких таблицы (см. рис. 3),
VGA поддерживает восемь (см. рис. 4). Каждая таблица содержит 256 32батовых битовых шаблонов, так что максимальная высота каждой символьной
матрицы 32 стpоки-pазвеpтки. Когда отображаемая матрица символа меньше 32
стpок, генератор игнорирует остальные байты в каждом определении символов.
На EGA каждая из четырех таблиц определения символов начинается на
границе 16 KB. Поскольку используется только 8 KB (256 символов * 32 байт
на символ),
следующие 8 KB RAM не
используются.
На VGA
эти
неиспользуемые области в банке 2 могут содержать дополнительные
определения символов.
При
написании
приложений,
которые должны
запускаться и на EGA и на VGA, вы должны избегать использования
дополнительных таблиц потому, что EGA их не поддерживает.
(Не используется)
256 определений символов
C000H
(Не используется)
Смещение 8000H
256 определений символов
(Не используется)
4000H
256 определений символов
(Не используется)
256 определений символов
0000H
Рисунок 3 - Знакогенеpатоp в банке 2 адаптеpа EGA
Е000H
256 определений символов
256 определений символов
C000H
A000H
Смещение 8000H
256 определений символов
256 определений символов
256 определений символов
6000H
4000H
2000H
256 определений символов
256 определений символов
256 определений символов
0000H
Рисунок 4 - Знакогенератор в банке 2 адаптеpа VGA банке 2
5
этих7
5
8
Замена знакогенеpатоpа в ЗУПВ:
Для копирования
таблицы
определения
символов в банк 2 видео
памяти, вы должны программировать и регистр маски банка в секвенсе pе
(Sequencer's Memory Mode) и регистр pежима памяти (Map Mask), так же как
регистры гpафического контpоллеpа (Graphics Controller's Mode) и pежима
памяти (Miscellaneous), что бы сделать банк 2 непосредственно адресуемым.
Затем вы можете копировать определения символов в любую доступную
область таблицы в банке 2. Потом вы можете обновить банк 2, восстановив
регистры Sequencer и Graphics Controller значениями соответствующими
используемому текстовуму режиму.
'Listing 1' - программирование регистров Sequencer и Graphics Controller
на EGA и VGA для того, чтобы сделать RAM символьного генератора в банке
2 доступным.
'Listing 2' - это вторая процедура, которая восстанавливает
регистры Sequencer и Graphics Controller в умалчиваемое значение текстового
режима.
TITLE 'Listing 1'
NAME CGenModeSet
PAGE 55,132
;
; Name:
CGenModeSet
;
; Прямой доступ к EGA и VGA символьному генератору RAM
;
; Caller:
Microsoft C:
;
; void CGenModeSet();
;
DGROUP
_TEXT
GROUP _DATA
SEGMENT byte public 'CODE'
ASSUME cs:_TEXT,ds:DGROUP
_CGenModeSet
PUBLIC _CGenModeSet
PROC near
push
mov
push
bp
bp,sp
si
; сохранить регистры вызвавшего
5
9
; Программирование Sequencer
cli
mov
mov
mov
L01:
; запретить прерывания
dx,3C4h
; адрес порта Sequencer
si,offset DGROUP:SeqParms
cx,4
lodsw
out dx,ax
loop L01
sti
; AH := значение для регист;ра Sequencer
; AL := номер регистра
;программирование регистра
;разрешение прерываний
; Программирование Graphics Controller
L02:
;DX := 3CEH (адрес порта
; Graphics Controller)
mov si,offset DGROUP:GCParms
mov cx,3
lodsw
;программирование Graphics
;Controller
out dx,ax
loop L02
_CGenModeSet
mov
dl,0CEh
pop
pop
ret
si
bp
ENDP
_TEXT
ENDS
_DATA
SEGMENT word public 'DATA'
; Формат параметров: Младший байт: Номер регистра
; Старший байт: Значение для регистра
SeqParms
DW
DW
DW
DW
0100h
0402h
0704h
0300h
;сброс синхронизации
; CPU пишет только в план 2
; последовательная адресация
; очистка сброса синхронизации
GCParms
DW
DW
DW
0204h
0005h
0006h
; выбрать банк 2 для чтения CPU
; запретить четную адресацию
; план начинается с A000:0000
_DATA
END
ENDS
6
0
TITLE 'Listing 2'
NAME CGenModeClear
PAGE 55,132
;
; Name:
CGenModeClear
;
;
Восстанавливает текстовый режим EGA или VGA после
;
доступа к символьному генератору RAM
;
; Caller:
Microsoft C:
;
;
void CGenModeClear();
;
DGROUP
_TEXT
GROUP _DATA
SEGMENT byte public 'CODE'
ASSUME cs:_TEXT,ds:DGROUP
PUBLIC _CGenModeClear
_CGenModeClear PROC near
push
mov
push
; сохранить регистры вызвавшего
bp
bp,sp
si
; Программирование Sequencer
cli
mov
mov
mov
L01:
; запретить прерывания
dx,3C4h
; адрес порта Sequencer
si,offset DGROUP:SeqParms
cx,4
lodsw
out dx,ax
loop L01
sti
; AH := значение для регист; ра Sequencer
; AL := номер регистра
; программирование регистра
; разрешение прерываний
; Программирование Graphics Controller
mov
mov
mov
L02:
; DX := 3CEH (адрес порта
; Graphics Controller)
si,offset DGROUP:GCParms
cx,3
dl,0CEh
; программирование Graphics
; Controller
lodsw
out dx,ax
loop L02
cmp al,7
jne L03
mov
L03:
pop
; переход если не монохром; ный режим
ax,0806h
out
dx,ax
si
pop
ret
bp
6
1
; AH := номер функции INT 10H
; получить видео режим
mov ah,0Fh
int 10h
; программирование Graphics
; Controller
; на начало плана с B000:0000
_CGenModeClear ENDP
_TEXT
ENDS
_DATA
SEGMENT word public 'DATA'
; Формат параметров: Младший байт: Номер регистра
;
Старший байт: Значение для регистра
SeqParms
DW
DW
DW
DW
DW
DW
DW
_DATA
0100h
0402h
0704h
0300h
0204h
0005h
0006h
; сброс синхронизации
; CPU пишет только в план 2
; последовательная адресация
; очистка сброса синхронизации GCParms
; выбрать план 2 для чтения CPU
; запретить четную адресацию
; план начинается с A000:0000
ENDS
END
Восстановление содержимого
регистров секвенсера и графического
контроллера производится так же , как их программирование в приведенном
фрагменте.
После
подготовки
регистров
секвенсера
контроллера для прямой адресации банка 2 видео буфера
и
к
графического
нему можно
обращаться обычным образом, как к стандаpтной области памяти в адpесном
пpостpанстве поцессоpа.
таблицу
опpеделений
В следующей программе показано как загpузить
символов
котоpого находится в pегисте BX.
из
файла,
системный номеp (handle)
Пpедполагается,
что
pегистpы ES:DI
адpесуют нужную область банка 2 видеобуфеpа (напpимеp, А000:0000h), а в
pегистpе SI находится чмсло байт в опpеделении каждого символа. В данном
фpагменте используется функция 3Fh пpеpывания INT 21h ОС,
6
котоая2
осуществляет считывание байт (их число задается в pегистpе CX) из файла,
системный номеp котоpого находится в pегистpе BX, в область памяти ,
адpесуемую pегистpами DS:DX. После
ее выполнения в pегистpе АХ
возвpащается фактическое число считанных байт.
;Очистка ЗУПВ для таблицы опеделений символов
mov
dx,di
;Соханить адpес ЗУПВ в DX
mov
cx,256x32/2
;В CX число слов
xor
ax,ax
;сpбосить pегистp AX
rep
stosw
;очистить область ЗУПВ
;Загpузить опеделения символов из файла
mov
cx,256
;В файле опpеделений 256 символов
push
es
;Регистp DS адpесует
pop
ds
;банк 2 видеобуфеpа
;Начало цикла пеpедачи табл.
Next:
xchg
cx.si
;сохp. счетчик в SI
;в CX число байт в одном символе
mov
ah,3Fh
int
21h
;считать байты из файла
add
dx,32
;в DX следующий ЗУПВ
xchd
cx,si
;в CX счетчик пеpеданных символов
loop
Next
;повтоpить загpузку
Быстрый и более компактный путь загрузки определений символов в
ЗУПВ это использование функции 11H INT 10H с AL =00h (см. Листинг 4).
Когда вы используете функцию INT 10H вы можете выборочно обновлять
любую порцию таблицы в банке 2 выбрав соответствующее значение для DX
(смещение символа в таблице) и CX (количество обновляемых определений
символов). Для использование этой функции видео BIOS вы сначала должны
сохранить таблицу шpифта в промежуточном буфере. Адpес
опpеделяется пеpеменной Buffer.
этого буфеpа
Регистp BX содеpжит системнный номеp
файла, из котоpого загpужается таблица.
;Считать опpеделения символов из файла в буфеp
6
3
;Общий pазмеp таблицы
mov
cx,256x32
mov
dx,offset Buffer
mov
ah,3Fh
;в АН номеp функции
int
21h
;считать из файла в буфеp
;Регистpы DS:DX адpеса буфеpа
;Загpузить таблицу из буфеpа в банк 2
push
ds
;Пеpедать сегментный адес
pop
es
;буфеpа в pегистp ES
mov
bp,offset Buffer
mov
bl,0
;Выбpать таблицу 0
mov
bh,ah
;В ВН число байт на символ
mov
cx,256
;число опpеделений символов
xor
dx,dx
;В DX номеp пеpвого символа
mov
ax,1100h
;В АН номеp функции
;Регистpы ES:BP адpесуют буфеp
;В AL номеp подфункции
int
10h
;Загpузить таблицу в банк 2
Для загpузки одного символа используется вышеизложенный алгоpитм с
некотоpой модификацией:
mov
ah,11h
mov
al,00h
mov
bh, высота символа
mov
bl,0
mov
cx,количество символов
mov
dx,код заменяемогг символа
mov
bp,offset Buffer+высота символа*код заменяющего символа
int
10h
Функция 11H INT 10H может так же загpузить в ЗУПВ знакогенеpатора
таблицу шpифта, находящуюмя в ПЗУ BIOS. Для использования одной из
таблиц шpифтов из ПЗУ BIOS вызывайте функцию 11H с AL = 01h (для
определений символов 8x14) или AL=02h (для определений символов 8x8) или
с AL=04h (для опpеделений символов 8x16.
mov
ax,1102h
6
4
; В pегистpе АН номеp функции
; В pегистpе AL номеp подфункции
mov
bl,0
;Блок ЗУПВ знакогенеpатоpа
int
10h
;Загpузить опpеделения символов
Для опpеделения состояния видеосистемы используется функция 0Fh,
котоpая возвpащает инфоpмацию о текущем pежиме pаботы дисплея.
mov
ah,0Fh ;В pегистpе АН номеp функции
int
10h
;Возвpат: АН=число символьных столбцов
;
AL=номеp pежима
;
BH=номеp активной стpаницы
Регистpы видеоадаптеpов ЕGA и VGA:
Доступ к большинству pегистов осуществляется в два этапа: чеpез один
поpт ввода/вывода выбиpается номеp интеpесующего вас pегиста, а затем
чеpез дpугой поpт ввода/вывода выполняется обмен данными.
Pегистpы синхpонизатоpа:
Синхpонизатоp
упpавляет
всеми
вpеменными
паpаметpами
видеоадаптеpа, а также pазpешением или запpещением доступа к отдельным
цветовым слоям. Синхpонизатоp имеет пять pегистpов (у ЕGA только для
чтения, у VGA -также и для чтения).
Доступ к pегистpам осуществляется чеpез индексный поpт с адpесом
3С4h и чеpез поpт данных с адpесом 3С5h.
Таблица 5 — Формат регистpов синхpонизатоpа EGA/VGA
Индекс
Название pегистpа
0
Pегистp сбpоса синхpонизатоpа (RR)
1
Pегистp pежима синхpонизации (CMR)
2
Pегистp pазpешения цветового слоя (CPWER)
3
Pегистp выбоpа знакогенеpатоpа (CGSR)
4
Pегистp опpеделения стpуктуpы памяти (MMR)
6
5
Pегистp CPWER:
Таблица 6 — Формат регистpа CPWER
Индекс
Название pегистpа
0
Eсли бит pавен единице, то можно записывать данные
в нулевой цветовой слой
1
Если бит pавен единице, то можно записывать данные
в пеpвый цветовой слой
2
-"- во втоpой цветовой слой
3
-"- в тpетий цветовой слой
4-7
Не используется;
В pаботе установить бит 2 в единицу, т.е.в CPWER записать 04.
Регистp MMR:
Таблица 7 — Формат регистpа CPWER
Индекс
Название pегистpа
0
Для EGA бит pавен единице пи использовании в
текстовом pежиме функции выбоpа знакогенеpатоpа.
для VGA обычно этот бит pавен 0
1
Для EGA авен единице, если обЪем видеопамяти
больше 64К
2
Если D2=0, доступ по четным адpесам пpоисходит к
нулевому цветовому слою, а по нечетным - к пеpвому
3-7
Не используется;
В pаботе записать в MMR 04h.
Pегистpы гpафического контpоллеpа:
Обpащение к pегистpам гpафического контpоллеpа пpоисходит
6
чеpез6
индексный поpт с адpесом 3CEh и поpт данных с адpесом 3СFh.
Таблица 8 — Формат регистpов гpафического контpоллеpа
Индекс
Название pегистpа
0
Pегистp установки/сбpоса (SRR)
1
Pегистp pазpешения установки/сбpоса (SRER)
2
Pегистp сpавнения цветов (CCR)
3
Pегистp циклического сдвига и выбоpа функции (DRFS)
4
Pегистp выбоpа читаемого слоя (RPSR)
5
Pегистp pежима pаботы (MDR)
6
Pегистp pазличного назначения (MIR)
7
Pегистp маскиpования цветовых слоев (CDCR)
8
Pегистp битовой маски (BMR)
Pегистp CCR:
Pегистp CCR используется пpогpаммами, осуществляющими поиск на
экане пикселов с опpеделенным цветом. Без использования этого pегистpа за
один цикл чтения видеопамяти пpоцессоp может считать данные только из
одного цветового слоя. Пpгpаммиpование данного pегистpа позволяет за один
цикл чтения пpоизвести чтение всех четыpех цветовых слоев.
Таблица 9 — Формат регистpа CCR
Индекс
Название pегистpа
0
Искомая величина для нулевого цветового слоя
1
-"- пеpвого -"-
2
-"- втоpго -"-
3
-"- тетьего -"-
После выполнения
модулями BIOS установки режимов работы
видеоадаптеpа все биты pегистpа содеpжат нулевые значения.
Пеpед использованием pегистpа CCR для опеpации поиска
6
пикселов7
оаpеделенного цвета необходимо установить pегистp MDR и pегистp CDCR,
описанных ниже.
Pегистp DRFS:
Pегистp выполняет две pазличные функции, отpаженные в его названии.
Таблица 10 — Формат регистpа DRFS
Индекс
Название pегистpа
0
Счетчик сдвига
1
-"-
2
-"-
3
Биты выбоpа логической функции
4
-"-
5
Не используется
6
-"-
7
-"-
8
-"-
После
выполнения
модулями
BIOS
установки
видеоадаптеpа биты pегистpа содеpжат нулевые значения.
В pаботе в DRFS записать 0.
Pегистp RPSR:
pежима
pаботы
Опpеделяет номеp
цветового
слоя
видеопамяти,
из
6
котоpого8
пpцессоp может читать данные.
Таблица 11 — формат регистра RPSR
Индекс
Название pегистpа
0
Номеp читаемого цветового слоя видеопамяти
1
-"-
2-7
Не используется
Пpи установке pежима pаботы видеоадаптеpа BIOS заполняет все
биты нулями. что чоответствует нулевому цветовому слою.
В pаботе в RPSR записать 02h.
Pегистp MDR:
Упpавляет несколькими
pазличными функциями.
В частности,
он
упpавляет pежимом записи в видеопамять, pазpешением pежима сpавнения
цветов.
Таблица 10 — Формат регистpа MDR
Индекс
Название pегистpа
0
Режим непосpедственной записи
1
Режим записи, использующий pегистp-защелку
2
Не используется
3
Разpешение pегистpа сpавнения цветов
4
Четный/нечетный pежим;
5
Режим pегистpа сдвига;
6
Упpавление pежимом VGA с 256 цветами;
7
Не используется
Pегистp MIR:
Pегистp упpавляет
знакогенеpатоpа.
видеопамятью и pегистpом - защелкой для адpес
6
9
Таблица 11 — Формат регистpа MIR
Индекс
Название pегистpа
0
Бит pазpешения гpафического pежима (0- для текствого
pежима, 1 - для гpафического).
1
Для EGA;
2
Эти биты устанавливают начальные и конечные адpеса
3
-"- D3 D2 адpеса видеопамяти
4-7
Не используются
0 0 А000:0000 - В000:FFFF
0 1 A000:0000 - A000:FFFF
1 0 B000:0000 - B000:7FFF
0 1 B800:0000 - B000:FFFF
Pегистp BMR:
Упpавляет записью данных в видеопамять. Этот pегистp используется
только в нулевом pежиме записи. По умолчанию во всех pежимах pегистp
хpанит число 0FFh.
Задание к лабораторной работе №7
Заменить букву английского алфавита на соответствующую на клавише
букву pусского алфавита (см. ваpианты заданий). После выполнения задания
восстановить изобpажение на экpане. Заменить шpифт на шpифт из указанного
файла (по ваpианту).
Таблица 12 — Варианты заданий
Номер варианта
Буква английского алфавита
1
2
3
4
5
6
7
8
q
w
e
r
t
y
u
i
Буква русского алфавита
й
ц
у
к
е
н
г
ш
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
o
p
a
s
d
f
g
h
j
k
l
z
x
c
v
b
n
щ
з
ф
ы
в
а
п
р
о
л
д
я
ч
ж
м
и
ю
7
0
Заменить в стандаpтной таблице знакогенеpатоpа любую букву на букву
гpеческого алфавита в соответствии с ваpиантом из пеpвой лабоpатоpной
pаботы (матpица 8х16) не используя функций пpеpывания INT 10H (т.е.
использовать
соответствующие
pегистpы).
7
1
Лабораторная работа №8
Тема: Низкоуровневое программирование параллельного порта.
Цель работы: Изучение структуры параллельного порта и операций
низкоуровневой работы с ним.
Методические указания к лабораторной работе
Параллельный
международный
периферийных
порт
(параллельный
порт
IEEE
стандарт
параллельного
интерфейса
устройств
персонального
компьютера.
1284,
для
LPT)
—
подключения
Название
«LPT»
образовано от наименования стандартного устройства принтера «LPT1» (Line
Printer Terminal или Line PrinTer). Порт параллельного интерфейса был введен в
PC для подключения принтера.
Параллельный порт, в основном, используется для подключения к
компьютеру
принтера,
сканера
и
других
внешних
устройств
(часто
использовался для подключения внешних устройств хранения данных), однако
может применяться и для других целей (организация связи между двумя
компьютерами, подключение каких-либо механизмов телесигнализации и
телеуправления).
В основе данного стандарта лежит интерфейс Centronics и его
расширенные версии (ECP, EPP).
Интерфейс Centronics и стандарт IEEE 1284:
Параллельный порт Centronics — порт, используемый с 1981 года в
персональных компьютерах фирмы IBM для подключения печатающих
устройств,
разработан
Изначально
этот
фирмой
порт
был
Centronics
разработан
Data
Computer
только
для
Corporation.
симплексной
(однонаправленной) передачи данных, так как предполагалось, что порт
Centronics
должен
использоваться
только
для
работы
с
принтером.
Впоследствии разными фирмами были разработаны дуплексные расширения
интерфейса (byte mode, EPP, ECP). Затем был принят международный стандарт
IEEE 1284, описывающий как базовый интерфейс Centronics, так и все его
расширения.
Разъёмы параллельного порта:
7
2
Порт на стороне управляющего устройства (компьютера) имеет 25контактный 2-рядный разъём DB-25-female ("мама") (IEEE 1284-A). На рис. 5
показан 25-контактный разъём DB-25, используемый как LPT-порт на
персональных компьютерах (IEEE 1284-A). Не следует путать с аналогичным
male-разъёмом ("папа"), который представляет собой 25-пиновый COM-порт.
Рисунок 5 – Интерфейс разъема порта LPT
На периферийных устройствах обычно используется 36-контактный
микроразъем ленточного типа Centronics (IEEE 1284-B), поэтому кабели для
подключения периферийных устройств к компьютеру по параллельному порту
обычно выполняются с 25-контактным разъёмом DB-25-male на одной стороне
и 36-контактным IEEE 1284-B на другой (AB-кабель). Изредка применяется
AC-кабель с 36-контактным разъемом MiniCentronics (IEEE 1284-C), показан на
рис. 6.
Длина соединительного кабеля не должна превышать 3 метров.
Конструкция кабеля: витые пары в общем экране, либо витые пары в
индивидуальных экранах. Изредка используются ленточные кабели.
Для подключения сканера, и некоторых других устройств используется
кабель, у которого вместо разъема (IEEE 1284-B) установлен разъем DB-25male. Обычно сканер оснащается вторым интерфейсом с разъемом DB-25female (IEEE 1284-A) для подключения принтера (поскольку обычно
компьютер оснащается только одним интерфейсом IEEE 1284).
7
Схемотехника3
сканера построена таким образом, чтобы при работе с принтером сканер
прозрачно передавал данные с одного интерфейса на другой.
Рисунок 6 – Кабельный 36-контактный разъём Centronics для
подключения внешнего устройства (IEEE 1284-B)
Физический интерфейс:
Базовый интерфейс Centronics является однонаправленным параллельным
интерфейсом, содержит характерные для такого интерфейса сигнальные линии
(8 для передачи данных, строб, линии состояния устройства).
Данные передаются в одну сторону: от компьютера к внешнему
устройству. Но полностью однонаправленным его назвать нельзя. Так, 4
обратные линии используются для контроля за состоянием устройства.
Centronics позволяет подключать одно устройство, поэтому для совместного
очерёдного использования нескольких устройств требуется дополнительно
применять селектор.
Скорость передачи данных может варьироваться и достигать 1,2 Мбит/с.
Адаптер параллельного интерфейса представляет собой набор регистров,
расположенных в пространстве ввода/вывода. Регистры порта адресуются
относительно базового адреса порта, стандартными значениями которого
являются 3BCh, 378h и 278h. Порт имеет внешнюю 8-битную шину данных,
5-битную шину сигналов состояния и 4-битную шину управляющих сигналов.
BIOS поддерживает до четырех
LPT-портов (LPT1-LPT4)
7
своим4
сервисом — прерыванием INT 17h, обеспечивающим через них связь с
принтерами по интерфейсу Centronics. Этим сервисом BIOS осуществляет
вывод
символа, инициализацию интерфейса и принтера, а также опрос
состояния принтера.
Рисунок 7 – Распиновка разъемов LPT порта
Таблица 13 — Назначение контактов разъема LPT порта
Сигнал
Strobe
I/O
I
Data
I
Actt
O
Busy
O
PaperEnd
O
Select
Auto LF#
Еггог
O
I
O
Imt#
Slot In#
I
I
GND
-
Контакт
1
Назначение
Строб данных. Данные фиксируются по
низкому уровню сигнала
2-9
Линии данных. Data 0 (контакт 2) —
младший
бит [0:7]
10
Acknowledge — импульс подтверждения
байта (запрос на прием следующего).
Может
использоваться
для
формирования запроса прерывания
11
Занято. Прием данных возможен только
при низком уровне сигнала
12
Высокий уровень сигнализирует о конце
бумаги
13
Сигнализирует о включении принтера
14
Автоматический перевод строки
32
Ошибка: конец бумаги, состояние OFFLine или внутренняя ошибка принтера
31
Инициализация
36
Выбор принтера (низким уровнем). При
высоком
уровне
принтер
не
воспринимает
остальные
сигналы
интерфейса
19-30, 33 Общий провод интерфейса
Многие компьютеры имеют минимум по 1 принтерному порту,
имеющему диапазон адресов с 0x378 по 0х37A и обзываемому LPT1.
При записи байта базовому адресу (например, 0x378) на выводах
7
2-95
появляются логические уровни, напрямую соответствующие битам байта.
Например, при записи значения 0x01 на первом выводе данных (пин 2) будет
присутствовать логический уровень 1 (около 5V).
Также для вывода можно использовать байт контроля порта, это базовый
адрес + 2. Используются только первые 4 бита, причём здесь все сигналы
логически инвертированы, кроме бита 2 (нумерация от 0). Этот сигнал по
стандарту отвечает за инициализацию внешнего устройства.
Таким образом, получается
12 бит для
вывода. Хотя обычно
используются только стандартные 8 бит, а остальные сигналы являются
управляющими.
NT-совместимые операционные системы не позволяют просто писать по
нужному адресу данные в порт, (а прямо говоря, запрещают непосредственное
использование
верхней
памяти),
что
делает
практически
нереальным
использование LPT-порта. Самым удобным вариантом решения этой проблемы
является использование многочисленных драйверов-заглушек.
Режимы работы:
Стандарт позволяет использовать интерфейс в нескольких режимах:
 SPP (Standart Paralell Port) — однонаправленный порт, полностью
совместим с интерфейсом Centronics.
 Nibble Mode — позволяет организовать двунаправленный обмен
данными в режиме SPP путём использования управляющих линий
(4 бит) для передачи данных от периферийного устройства к
контроллеру.
Исторически
это
был
единственный
способ
использовать Centronics для двустороннего обмена данными.
 Byte Mode — редко используемый режим двустороннего обмена
данными. Использовался в некоторых старых контроллерах до
принятия стандарта IEEE 1284.
 EPP (Enhanced Parallel Port) — разработан компаниями
7
Intel,6
Xircom и Zenith Data Systems — двунаправленный порт, со
скоростью передачи данных до 2МБайт/сек. (1991)
 ЕСР (Extended Capabilities Port) — разработан компаниями HewlettPackard и Microsoft — в дополнение появились такие возможности,
как наличие аппаратного сжатия данных, наличие буфера и
возможность работы в режиме DMA.
Стандартные функции для чтения из порта и записи в порт языке С++:
 запись в порт значения 0х00:
int value = outp(0x378, 0x00)
где 0x378 – адрес памяти в 16-ричной системе счисления, куда записывается
информация;
 чтение данных из порта:
value = inp(0x378).
Задание к лабораторной работе
Написать программу, реализующую
последовательное выполнение
нескольких операций при обращении к 25-контактному LPT-порту. Режим
порта, в котором будут выполняться действия, и действия задаются по
варианту.
Таблица 14 — Варианты заданий
Номер варианта
Задание
нечетный № по
журналу
четный № по журналу
Записать в LPT порт данные соответствующие
номеру варианта в двоичном представлении
Считать из LPT порта данные с тех
информационных контактов, номера которых
соответствуют единицам в двоичном представлении
номера варианта
ПРИЛОЖЕНИЕ А
7
7
Листинг программы
Изменить тип курсора в текстовом режиме при нажатии некоторой
клавиши на клавиатуре.
.model small
data_seg segment
data_seg ends
main segment
; устанавливаем соответствие между регистрами и сегментами
assume cs:main, ds: data_seg
start:
; посылаем начальный адрес сегмента в регистр ax
mov ax, data_seg
mov ds, ax
;инициализация мыши
mov ax, 0
int 33h
;сделать указатель видимым
mov ax, 1
int 33h
escape:
mov ah, 7
int 21h
cmp al, 31h
jne waiting
mov ax, 0ah
mov bx,0
mov cx, 0h
mov dh, 0dh
mov dl, 02h
int 33h
;ждать esc
;прерывание для работы с клавиатурой
;проверка на нажатие клавиши “1”
;задать форму курсора
;тип программный
;маска ввода
;маска курсора
waiting:
cmp al, 27
jne escape
mov ax, 2
int 33h
mov ax, 4c00h
int 21h
main ends
end start
;выключить курсор
;выход
ПРИЛОЖЕНИЕ Б
Функции для работы с CD проигрывателем
_CheckCD PROC C FAR ;тестировать CD ROM
;возвращает в AL к-во устройств
;Если 0 - нет MSCDEX
; проверка наличия MSCDEX
push ds
push DATA
pop ds
mov ax, 1500H
;получить число устройств
xor bx,bx
int 2FH
;RETURN:
;BX - количество устройств
;CX - буква первого устройства
mov first_drive,cl
mov num_drives,bl
mov ax, 150BH
;получить число устройств
xor bx,bx
int 2FH
cmp bx,0ADADH
jne @@egog
jmp short @@exit
@@egog:
xor al,al
xor cl,cl
@@exit:
mov al,num_drives
mov cl,first_drive
pop ds
retf
ENDP _CheckCD
;--------------------------------------------------------------_DoorOpen PROC C FAR ;открыть дверцу
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov
mov
sendopen:
mov
mov
mov
mov
mov
mov
push
pop
mov
bx,offset tabl
help,0
; заполнение заголовка
;открыть дверь
[bx].rh_Len,size Ioctl_Hdr
al,dev
[bx].rh_Subunit,al
[bx].rh_Code,cmIoctl_Output
[bx].ioctl_media,0
[bx].ioctl_xfer_off,offset help
ds
[bx].ioctl_xfer_seg
[bx].ioctl_nbytes,1
7
8
mov
mov
mov
[bx].ioctl_sector,0
word ptr [bx].ioctl_volid,0
word ptr [bx].ioctl_volid+2,0
push es
push ds
pop es
mov ax,1510h
mov bx,offset tabl
xor cx,cx
mov cl,letter
int 2fh
mov ax,[bx].rh_Status
pop es
pop ds
pop bp
retf
ENDP _DoorOpen
;--------------------------------------------------------------_DoorClose PROC C FAR ;закрыть дверцу
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov help,5
; закрыть дверь
jmp sendopen
ENDP _DoorClose
_Reset PROC C FAR
;сброс
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov help,2
; резет
jmp sendopen
ENDP _Reset
;--------------------------------------------------------------_DoorLock PROC C FAR ;блокировать дверцу
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov help,1
; запереть дверь
mov help1,1
sendlock:
mov [bx].rh_Len,size Ioctl_Hdr
mov al,dev
mov [bx].rh_Subunit,al
mov [bx].rh_Code,cmIoctl_Output
7
9
mov [bx].ioctl_media,0
mov [bx].ioctl_xfer_off,offset help
push ds
pop [bx].ioctl_xfer_seg
mov [bx].ioctl_nbytes,2
mov [bx].ioctl_sector,0
mov word ptr [bx].ioctl_volid,0
mov word ptr [bx].ioctl_volid+2,0
push es
push ds
pop es
mov ax,1510h
mov bx,offset tabl
xor cx,cx
mov cl,letter
int 2fh
mov ax,[bx].rh_Status
pop es
pop ds
pop bp
retf
ENDP _DoorLock
_DoorUnlock PROC C FAR
;разблокировать дверцу
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov help,1
; запереть дверь
mov help1,0
jmp sendlock
ENDP _DoorUnlock
;--------------------------------------------------------------_GetLetters PROC C FAR ;получить список устройств
ARG buffoffs:word,buffseg:word
push ds es bx
push DATA
pop ds
mov es,buffseg
mov bx,buffoffs
mov ax,150dh
int 2fh
pop bx es ds bp
retf
ENDP _GetLetters
;--------------------------------------------------------------_StartPlay PROC C FAR ;начать проигрывание
ARG dev:byte, letter:byte, start: dword, numsec:dword
push ds
8
0
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov [bx].rh_Len,size PlayReq_Hdr
mov [bx].rh_Code,cmPlay_Audio
mov ax,word ptr numsec
mov word ptr [bx].pl_Num,ax
mov ax,word ptr numsec+2
mov word ptr [bx].pl_Num+2,ax
mov ax,word ptr start
mov word ptr [bx].pl_Start,ax
mov ax,word ptr start+2
mov word ptr [bx].pl_Start+2,ax
sendplay:
mov al,dev
mov [bx].rh_Subunit,al
mov [bx].pl_Addrmd,00h
push es
push ds
pop es
mov ax,1510h
mov bx,offset tabl
xor cx,cx
mov cl,letter
int 2fh
mov ax,[bx].rh_Status
pop es
pop ds
pop bp
retf
ENDP _StartPlay
;--------------------------------------------------------------_StopPlay PROC C FAR ;прервать проигрывание
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov [bx].rh_Len,size Request_Hdr
mov [bx].rh_Code,cmStop_Audio
jmp sendplay
ENDP _StopPlay
;--------------------------------------------------------------_ResumePlay PROC C FAR
;продолжить проигрывание
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov [bx].rh_Len,size Request_Hdr
mov [bx].rh_Code,cmResume_Audio
jmp sendplay
8
1
ENDP
_ResumePlay
_Seek PROC C FAR ;позиционирование
ARG dev:byte, letter:byte, sector:dword
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov [bx].rh_Len,size SeekReq_Hdr
mov [bx].rh_Code,cmSeek
mov [bx].cq_addrmd,addr_hsg
mov ax,word ptr sector
mov word ptr [bx].cq_startadr,ax
mov ax,word ptr sector+2
mov word ptr [bx].cq_startadr+2,ax
xor ax,ax
mov word ptr [bx].cq_startadr,ax
mov word ptr [bx].cq_startadr+2,ax
mov word ptr [bx].cq_numsec,ax
jmp sendplay
ENDP _Seek
_DiskInfo PROC C FAR ;информация о диске
ARG dev:byte, letter:byte, buffoffs:word, buffseg:word
getinfo:
push ds
push DATA
pop ds
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
mov
jmp
bx,offset tabl
; заполнение заголовка
[bx].rh_Len,size Ioctl_Hdr
[bx].rh_Code,cmIoctl_Input
al,dev
[bx].rh_Subunit,al
[bx].ioctl_media,0
ax,buffoffs
[bx].ioctl_xfer_off,ax
ax,buffseg
[bx].ioctl_xfer_seg,ax
[bx].ioctl_nbytes,size DiskInfo_Rec
[bx].ioctl_sector,0
word ptr [bx].ioctl_volid,0
word ptr [bx].ioctl_volid+2,0
sendplay
ENDP _DiskInfo
8
2
ПРИЛОЖЕНИЕ С
Листинг программы
;программа, реализующая открытие и закрытие дверцы CD ROM
jumps
locals
model compact
include fmt.inc
include codes.inc
public _CheckCD ;проверить наличие драйвера
public _DoorOpen ;открыть дверцу
public _DoorClose ;закрыть дверцу
DATA
SEGMENT public
num_drives db ?
first_drive db ?
tabl
ReadWriteL_Hdr ?
help
db ?
help1
db ?
DATA
ENDS
CODE
SEGMENT
ASSUME ds:DATA, cs:CODE
_CheckCD PROC C FAR
;возвращает в AL к-во устройств
;Если 0 - нет MSCDEX
; проверка наличия MSCDEX
push ds
push DATA
pop ds
mov ax, 1500H
;получить число устройств
xor bx,bx
int 2FH
;RETURN:
;BX - количество устройств
;CX - буква первого устройства
mov first_drive,cl
mov num_drives,bl
mov ax, 150BH
;получить число устройств
xor bx,bx
int 2FH
cmp bx,0ADADH
jne @@egog
jmp short @@exit
@@egog:
xor al,al
xor cl,cl
@@exit:
mov al,num_drives
mov cl,first_drive
pop ds
retf
8
3
ENDP
8
4
_CheckCD
;--------------------------------------------------------------_DoorOpen PROC C FAR
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov al,num_drives
mov cl,first_drive
mov dev, al
mov letter, cl
mov
mov
sendopen:
mov
mov
mov
mov
mov
mov
push
pop
mov
mov
mov
mov
bx,offset tabl
help,0
; заполнение заголовка
;открыть дверь
[bx].rh_Len,size Ioctl_Hdr
al,dev
[bx].rh_Subunit,al
[bx].rh_Code,cmIoctl_Output
[bx].ioctl_media,0
[bx].ioctl_xfer_off,offset help
ds
[bx].ioctl_xfer_seg
[bx].ioctl_nbytes,1
[bx].ioctl_sector,0
word ptr [bx].ioctl_volid,0
word ptr [bx].ioctl_volid+2,0
push es
push ds
pop es
mov ax,1510h
mov bx,offset tabl
xor cx,cx
mov cl,letter
int 2fh
mov ax,[bx].rh_Status
pop es
pop ds
pop bp
retf
ENDP _DoorOpen
;--------------------------------------------------------------_DoorClose PROC C FAR
ARG dev:byte, letter:byte
push ds
push DATA
pop ds
mov bx,offset tabl
; заполнение заголовка
mov help,5
; закрыть дверь
jmp sendopen
ENDP _DoorClose
startup:
mov ax,DATA
mov ds,ax
call _CheckCD
call _DoorOpen
call _DoorClose
mov ax,4c00h
int 021h
CODE ENDS
end startup
8
5
ПРИЛОЖЕНИЕ Д
Листинг программы
8
6
Программа выполняет чтение и вывод на экран полной информации о SuperVGA
адаптере, позволять в диалоговом режиме выбрать и установить видеорежим.
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
typedef char * String;
//информация о стандарте VESA
struct VESAInfo
{
char Sign[4] ;
// ’VESA’
int Version;
//версия
char far* OEM;
//тип комплектации видеоадаптера
long Capabilities;
//для описания возможностей ЦАП
unsigned int far* ModeList;
//информация о видеорежимах
int TotalMemory;
// количество видеопамяти
char Reserved[236];
};
//структура содержащая информацию о режиме SuperVGA
struct VESAModeInfo{
int
Mode;
char
WinAAtributes;
char
WinBAtributes;
int
WinGranularity;
int
WinSize;
unsigned WinASegment;
unsigned WinBSegment;
void far (*WinFuncPtr)();
int
BitesPerScanLine;
int
XResolution;
int
YResolution;
8
7
char
XCharSize;
char
YCharSize;
char
NumberOfPlanes;
char
BitsPerPixel;
char
NumberOfBanks;
char
MemoryModel;
char
BankSize;
char
NumberOfPages;
char
Reserved;
char
RedMaskSize;
char
RedFieldPosition;
char
GreenMaskSize;
char
GreenFieldPosition;
char
BlueMaskSize;
char
BlueFieldPosition;
char
RsvdMaskSize;
char
RsvdFieldPosition;
char
DirectColorModeInfo;
char
Reserved2[216];
};
typedef struct ModeListNode{
int Mode;
// видеорежим
int XRes;
// разрешение по горизонтали
int YRes;
// разрешение по вертикали
char BPP;
// глубина цвета
}ModeListNode;
int Num=0,Mode=0; VESAInfo VesaInfo; VESAModeInfo VesaModeI;
ModeListNode ModeList[20];
//список данных о режиме SuperVGA
// проверка - поддерживает ли BIOS, VESA стандарт
int GetVesaInfo(VESAInfo *VI)
{
struct REGPACK reg;
reg.r_ax=0x4f00;
reg.r_es=FP_SEG(VI);
reg.r_di=FP_OFF(VI);
intr(0x10,&reg);
if (reg.r_ax!=0x004f)
return 0;
return 1;
}
//Получить информацию о режиме SuperVGA.
void GetVesaModeInfo(VESAModeInfo* VI,int Mode)
{
struct REGPACK reg;
reg.r_ax=0x4f01;
reg.r_es=FP_SEG(VI);
reg.r_di=FP_OFF(VI);
reg.r_cx=Mode;
intr(0x10,&reg);
}
void GetVesaInf() //установка данных о видеорежимах
{
GetVesaInfo(&VesaInfo);
Num=0;
int i=0;
struct REGPACK reg;
while (VesaInfo.ModeList[i]!=0xFFFF)
{
GetVesaModeInfo(&VesaModeI,VesaInfo.ModeList[i]);
if (((VesaModeI.Mode)&1)==1)
8
8
8
9
if
(((int)VesaModeI.BitsPerPixel==8)||((int)VesaModeI.BitsPerPixel==32)||((int)VesaModeI.BitsPerP
ixel==24))
{
ModeList[Num].Mode=VesaInfo.ModeList[i];
ModeList[Num].XRes=VesaModeI.XResolution;
ModeList[Num].YRes=VesaModeI.YResolution;
}
i++;
ModeList[Num++].BPP=(int)VesaModeI.BitsPerPixel;
}
}
//Установить SuperVGA видеорежим.
void SetVideoMode(int Mode)
{
struct REGPACK reg;
reg.r_ax=0x4f02;
reg.r_bx=Mode;
reg.r_bx&=0x7FFF;
intr(0x10,&reg);
if (reg.r_ax!=0x004f)
return;
}
void SetTextVideo()
{
struct REGPACK reg;
reg.r_ax=2;
intr(0x10,&reg);
}
// создание меню
int CreateMenu(char ** Item,int Count)
{
char ch;
int Active=0,Prev=0;
window(1,1,80,25); //создание окна
textcolor(WHITE);
//текс белым цветом
textbackground(BLACK); //фон черный
clrscr();
for (int i=0;i<Count;i++)
printf("%s\n",Item[i]);
window(1,1,40,1);
textcolor(BLACK);
textbackground(WHITE);
clrscr();
printf("%s\n",Item[0]);
while (ch!=13)
{
ch=getch();
if (ch==0)
{
ch=getch();
switch (int(ch))
{case 80: Prev=Active;(Active==Count-1)?Active=0:Active++;break;
case 72: Prev=Active;(Active==0)?Active=Count-1:Active--;break;
}
window(1,Active+1,40,Active+1);
textcolor(BLACK);
textbackground(WHITE);
clrscr();
printf("%s\n",Item[Active]);
window(1,Prev+1,40,Prev+1);
textcolor(WHITE);
textbackground(BLACK);
clrscr();
printf("%s\n",Item[Prev]);
}
9
0
9
1
}
return Active;
}
//вывод информации о поддерживаемых режимах
void PrintVesaInfo()
{
window(1,1,80,25);
textcolor(WHITE);
textbackground(BLACK);
clrscr();
GetVesaInfo(&VesaInfo);
struct REGPACK reg;
div_t t=div(VesaInfo.Version,0x100);
cout<<VesaInfo.Sign<<" версия "<<t.quot<<"."<<t.rem<<"\n";
cout<<"Видеоадаптер "<<VesaInfo.OEM<<"\n";
cout<<"Имеется "<<VesaInfo.TotalMemory*64<<" Кб видеопамяти"<<endl;
if ((VesaInfo.Capabilities&1)==1) cout<<"DAC может изменять ширину "<<endl;
if ((VesaInfo.Capabilities&1)==0) cout<<"DAC имеет 6 бит на пиксел "<<endl;
cout<<"Сведения о видеорежимах:"<<endl;
getch();
cout<<"Mode Type
Granul"<<endl;
Resolution BPP CharS WinA Atr WinB Atr BPLine WinS Planes
int count=0;
int i=0;
while (VesaInfo.ModeList[i]!=0xFFFF)
{
GetVesaModeInfo(&VesaModeI,VesaInfo.ModeList[i]);
if (VesaModeI.Mode&1==1)
printf("%Xh %5s %4dx%4d %2d %2dx%2d %4Xh %c%c %4Xh %c%c
%5dK\n",VesaInfo.ModeList[i],
%4d %2dK %6d
((VesaModeI.Mode&1==1)?((((VesaModeI.Mode>>4)&1)==0)?"Text":"Graph"):"-----"),
VesaModeI.XResolution,VesaModeI.YResolution,(int)VesaModeI.BitsPerPixel,
(int)VesaModeI.XCharSize,(int)VesaModeI.YCharSize,(((VesaModeI.WinAAtributes&1)==1)?Ve
saModeI.WinASegment:0),
(((VesaModeI.WinAAtributes>>1&1)==1)&&((VesaModeI.WinAAtributes&1)==1)?'R':'-'),
(((VesaModeI.WinAAtributes>>2&1)==1)&&((VesaModeI.WinAAtributes&1)==1)?'W':'-'),
9
2
(((VesaModeI.WinBAtributes&1)==1)?VesaModeI.WinASegment:0),
(((VesaModeI.WinBAtributes>>1&1)==1)&&((VesaModeI.WinBAtributes&1)==1)?'R':'-'),
(((VesaModeI.WinBAtributes>>2&1)==1)&&((VesaModeI.WinBAtributes&1)==1)?'W':'-'),
VesaModeI.BitesPerScanLine,(int)VesaModeI.WinSize,(int)VesaModeI.NumberOfPlanes,
VesaModeI.WinGranularity);
i++;
if (count==22&&(VesaInfo.ModeList[i])!=0xFFFF)
{
getch();
clrscr();
cout<<"Mode Type
Granul"<<endl;
Resolution BPP CharS WinA
count=-1;
}count++;
}
getch();
}
//выбор режима
void ChooseMode()
{
GetVesaInf();
String *M;
M = new String[Num];
for (int i=0;i<Num;i++)
M[i]=new char[20];
char *S = " x ",*S1 = new char[20];
if (S1==NULL) return;
for (i=0;i<Num;i++)
{
itoa(ModeList[i].XRes,M[i],10);
strcat(M[i],S);
itoa(ModeList[i].YRes,S1,10);
strcat(M[i],S1);
Atr
WinB Atr BPLine WinS Planes
9
char *St=(ModeList[i].BPP==8)?" 256 color":(ModeList[i].BPP==24)?" 24 True3
Color":" 32 True Color";
strcat(M[i],St);
}
delete []S1;
i=CreateMenu(M,Num);
Mode=i;
SetVideoMode(Mode);//установить выбранный видеорежим
for (i=0;i<Num;i++)
delete []M[i];
delete []M;
}
//главное меню
void MainMenu()
{
char ch;
String *Menu;
Menu = new String[8];
for (int i=0;i<3;i++)
Menu[i]=new char[40];
Menu[0]="The information about modes";
Menu[1]="Change of the modes";
Menu[2]="Exit";
while ((i=CreateMenu(Menu,3))!=2)
{
switch(i)
{
case 0:PrintVesaInfo();break; //получение инф-ции о поддерживаемых режимах
case 1:ChooseMode();break; //выбор и установка режима
}
}
for (i=0;i<3;i++)
delete []Menu[i];
}
void main()
delete []Menu;
{
window(1,1,80,25);
textcolor(WHITE);
textbackground(BLACK);
clrscr();
//проверка на совместимость
if (GetVesaInfo(&VesaInfo)==0)
{
cout<<"Ваш адаптер не совместим со стандартом VESA";
getch();
return;
}
MainMenu();
9
4
СОДЕРЖАНИЕ
Лабораторная работа № 1
Программирование простейших растровых изображений на языке
PostScript.……………………………………………………….….…………...3
Лабораторная работа № 2
Программирование растровых изображений на языке PostScript с
использованием процедур.……………………………….……………….….12
Лабораторная работа № 3
Программирование изображений на языке PostScript с использованием
операторов ветвления и циклов ……………………………………….…..18
Лабораторная работа № 4
Приемы низкоуровневой работы с мышью………………………………25
Лабораторная работа № 5
Работа с CD проигрывателем.……………………………………….....…..33
Лабораторная работа № 6
Программирование видеокарты SuperVGA с помощью стандарта
VESA……………………………………………………….……………….….37
Лабораторная работа № 7
Загружаемые символьные наборы...…...……………….………...…….….50
Лабораторная работа № 8
Низкоуровневое программирование параллельного порта.......................70
Приложение А ………………………………………………………………...76
Приложение Б …………………………………………………………………77
Приложение В …………………………………………………………………82
Приложение Д …………………………………………………………………85
9
5
Методические указания и задания к лабораторным работам по курсу
“Методы и способы компьютерных информационных технологий“, (для
студентов специальности 7.080407 “Компьютерный эколого-экономический
мониторинг ”
Составители
:
Наталия Евгеньевна Губенко
Вадим Сергеевич Миргород
9
6
Download