Вы находитесь на странице: 1из 131

МИНИСТЕРСТВО О БР А ЗО В А НИ Я И Н А УК И УКРАИН Ы

Н А Ц И О Н А Л Ь Н Ы Й ТЕХНИЧЕСКИЙ У НИ В ЕР С И ТЕТ
" ХАР ЬКОВСКИЙ ПОЛИ ТЕХНИЧЕСКИЙ ИН СТИ ТУТ "

А. И. ПОВОРОЗНЮК, Н. В. МЕЗЕНЦЕВ, О. А. ПОВОРОЗНЮК,

АРХИТЕКТУРА КОМПЬЮТЕРОВ

Лабораторный практикум

Утверждено редакционно-издательским
советом университета,
протокол № 2 от 25.06.2015 г.

Харьков
НТУ "ХПИ"
2016
УДК 004.3(075)
ББК 32.973–02я7
П 42

Рецензенты: А . И . Б ы х , д-р физ.-мат наук, проф., зав. каф.


биомедицинской инженерии Харьковского национального
университета радиоэлектроники;
Г . А . К у ч у к , д-р техн. наук, проф., зам. нач. НИР
Харьковского университета Воздушных сил

Поворознюк А.И.
П42 Архитектура компьютеров : лаб. практикум / А. И. Поворознюк,
Н. В. Мезенцев, О.А. Поворознюк,. – Харьков : Курсор, 2016. – 131 с.

ISBN 978-966-8944-80-2
В данном издании приведены методические указания к лабораторным работам
1–15, которые включают работы по определению конфигурации ПК, управлению
таймером и звуком, клавиатурой, накопителями на магнитных дисках, управлению
видеомонитором в текстовом и графическом режимах.
Предназначено для студентов всех специальностей бакалаврата 6.050102
"Компьютерная инженерия", а также может быть полезное как для начинающих, так и
для опытных программистов при создании эффективного программного обеспечения.

У даному виданні наведено методичні вказівки до лабораторних робіт 1–15, які


включають роботи з визначення конфігурації ПК, керування таймером і звуком,
клавіатурою, накопичувачами на магнітних дисках, керування відеомонітором у
текстовому й графічному режимах.
Призначено для студентів усіх спеціальностей бакалаврата 6.050102
"Комп'ютерна інженерія", а також може бути корисним як для початківців, так і для
досвідчених програмістів при створенні ефективного програмного забезпечення.

Іл. 39 Табл. 32. Бібліогр. 7 назв.

УДК 004.3(075)
ББК 32.973–02я7

ISBN 978-966-8944-80-2 © А. И. Поворознюк,


Н. В. Мезенцев,
О. А.. Поворознюк, 2016
3

СОДЕРЖАНИЕ

ВВЕДЕНИЕ.............................................................................................................4

Лабораторная работа 1. Знакомство с технологиями виртуальных


машин ......................................................................................................................5

Лабораторная работа 2. Конфигурация персонального компьютера ..............18

Лабораторная работа 3 Организация прерываний в ПК ...................................27

Лабораторная работа 4.Организация работы клавиатуры ПК .........................40

Лабораторная работа 5. Буфер клавиатуры ПК .................................................46

Лабораторная работа 6. Структура магнитных дисков.....................................51

Лабораторная работа 7. Структура корневого каталога ...................................59

Лабораторная работа 8. Структура таблицы размещения файлов FAT ..........67

Лабораторная работа 9. Системный таймер. Генерация звука.........................71

Лабораторная работа 10. Работа видеосистемы в текстовом режиме .............80

Лабораторная работа 11. Управление курсором, цветом бордюра, регистами


палитры, создание специальных символов........................................................88

Лабораторная работа 12. Работа со страницами................................................98

Лабораторная работа 13. Работа в графическом режиме. Управление экраном,


цветом. Изображение точки ..............................................................................104

Лабораторная работа 14.Изображение линий, затушевывание......................117

Лабораторная работа 15. Сохранение и загрузка графических изображений.


Перемещение и вращение объекта ...................................................................123

ЛИТЕРАТУРА....................................................................................................130
4

ВВЕДЕНИЕ

Лабораторный практикум к лабораторным работам по курсу


"Архитектура компьютеров" содержат описания 15 двухчасовых
лабораторных работ.
Лабораторные работы ориентированы на использование IBM PC
совместимых ПЭВМ, использующих микропроцессоры Intel и их клоны.
Цель лабораторного практикума
Целью лабораторных работ является закрепление практических навыков
управления модулями ПЭВМ на низком уровне путем программирования
адаптеров устройств на уровне портов. Прерывания BIOS и АРI-функции
используются лишь в тех случаях, когда управление на уровне портов требует
сложных алгоритмов управления с заданием временных задержек.
Так как современные ОС ограничивают, а во многих случаях запрещают
доступ к ресурсам ПК, то для обеспечения необходимого уровня доступа
создается виртуальная машина с ОС Windows 98, которая обеспечивает
необходимые действия.
Организация и проведение лабораторных работ
Студенты группы обьединяются в бригады по 2-3 человека, работающие
на закрепленном компьютере.
Каждый студент получает индивидуальное задание в соответствии с
номером в журнале и оформляет отчет по лабораторной работе.
Выполнение лабораторной работы предполагает предварительное
изучение соответствующего раздела курса и методических указаний к
очередной работе.
Для допуска к выполнению лабораторной работы студент должен
ознакомиться с темами для проработки и предварительно написать текст
программы, в соответствии с индивидуальным заданием.
Текст программы составляется на одном из языков программирования
Турбо-Си или Турбо-Паскаль с учетом глубины знаний студентами
конкретного языка.
При составлении программ пользоваться рекомендациями пункта
"Особенности программирования" для данной лабораторной работы.
В течение выполнения лабораторной работы студент должен ответить на
контрольные вопросы по предыдущей лабораторной работе.
К лабораторной работе не допускаются студенты, не сдавшие более двух
лабораторных работ.
Пропущенные лабораторные работы выполняются в конце семестра.
В процессе выполнения лабораторных работ следует ограничить
перемещения в лаборатории.
5

Лабораторная работа 1

Тема: Знакомство с технологиями виртуальных машин.

Цель работы: Получение практических навыков установки и настройки


виртуальных машин.

1.1. Описание работы.


Все лабораторне работы построены на получении информации или
программировании аппаратуры, входящей в состав ПЭВМ, напрямую через
порты ввода/вывода, прерывания или участки ОЗУ. Современные
операционные системы (ОС) не дают такой возможности, поэтому для
выполнения лабораторных работ следует использовать те ОС, которые это
позволяют или использовать программы виртуализации соответствующих ОС.
Например, можно использовать программные продукты DOSBox, VirtualBox,
VMWare Workstation и др. Далее будет описано настройка VMWare
Workstation для выполнения лабораторных работ.
После установки VMWare Workstation (версия 8) необходимо выбрать
пункт меню «Файл/Новая виртуальная машина…» или нажать комбинацию
Ctrl+N. На первой странице мастера создания виртуальной машины
необходимо выбрать пункт «Обычный». На второй странице необходимо
указать путь к установочному диску гостевой ОС (в данном случае будет
использоваться Windows 98) либо к файлу-образа диска с ОС (рис. 1.1).

Рис. 1.1 – Выбор установочного диска гостевой ОС


6

На следующем окне мастера нужно выбрать имя для гостевой ОС и


каталог для ее размещения на диске (рис. 1.2).

Рис. 1.2 – Выбор каталога размещения файлов виртуальной машины

После этого определить размер диска для гостевой ОС и вариант его


хранения (либо одним либо несколькими файлами) (рис. 1.3).

Рис. 1.3 – Выбор параметров диска для гостевой ОС

После этого процесс создания виртуальной машины завершен (рис. 1.4).


7

Рис. 1.4 – Окончание создания виртуальной машины

Можно настроить еще оборудование (нажав на кнопку «Настройка


оборудования…» рис. 1.4) где можно указать стандартные параметры
(рис. 1.5), такие как: объем ОЗУ, параметры процессора, тип CD-привода,
сетевой адаптер, USB-контроллер, звуковую карту и дисплей или установить
дополнительное оборудование (нажав на кнопку «Добавить…» на рис. 1.5).
После этого, нажав на кнопку «Готово» (рис. 1.4), необходимо установить
гостевую ОС.

Рис. 1.5 – Настройка оборудования гостевой ОС


8

Далее, если была выбрана опция «Включить виртуальную эту машину


после создания» (рис. 1.4), начнется процесс установки ОС. Данный процесс
ничем не отличается от процесса установки ОС на реальную ПЭВМ.
Рассмотрим установку ОС Windows 98.
Процесс установки начинается с выбора устройства загрузки. В данном
случае необходимо выбрать опцию 2: Boot from CD-ROM (рис. 1.6).

Рис. 1.6 – Выбор варианта загрузки

Далее необходимо выбрать 1 пункт: Start Windows 98 Setup from CD-ROM


(рис. 1.7).

Рис. 1.7 – Выбор варианта загрузки и установки ОС


9

На следующем этапе необходимо согласиться с установкой, нажав на


клавишу ENTER (рис. 1.8).

Рис. 1.8 – Окно старта установки ОС

Далее установник ОС предложит поготовить свободное пространство на


дисках. Нужно подтвердить данное действие нажатием клавиши ENTER
(рис. 1.9).

Рис. 1.9 – Подготовка свободного пространства на дисках


10

Затем нужно включить поддержку больших дисков (рис. 1.10).

Рис. 1.10 – Включение поддержки больших дисков

Затем мастер установки ОС предложит выполнить перезагрузку ОС.


Необходимо подтвердить это действие нажатием клавиши ENTER (рис. 1.11).

Рис. 1.11 – Завершение подготовки установки


11

После перезагрузки необходимо выбрать те же варианты, что и были на


рис. 1.6 и рис. 1.7. Затем мастер выполнит форматирование диска (рис. 1.12).

Рис. 1.12. – Форматирование диска

После необходимо согласится с началом процесса установки нажатием


клавиши ENTER (рис. 1.13).

Рис. 1.13. – Согласие на процесс установки

Далее мастер выполнит проверку диска и перейдет на процесс установки


ОС (рис. 1.14).
12

Рис. 1.14 – Установка гостевой ОС

При этом нужно выбрать папку установки ОС (рис. 1.15).

Рис. 1.15 – Выбор папки установки ОС

Затем нужно выбрать вариант установки ОС (рис. 1.16) и согласится с


установкой основних компонентов (рис. 1.17).
13

Рис. 1.16 – Выбор папки установки ОС

Рис. 1.17 – Выбор установки основних компонентов ОС

Затем нужно указать имя и описание данной рабочей машины (рис. 1.18).
14

Рис. 1.18 – Установка имени и описания компьютера гостевой ОС

Далее необходимо выбрать местоположение и согласиться с началом


процесса установки при этом мастер переходит на процесс копирования
файлов ОС (рис. 1.19).

Рис. 1.19 – Процесс копирования файлов гостевой ОС на виртуальную машину

После копирования фалов ОС на диск, будет выполнена перезагрузка


гостевой ОС. Затем нужно заполнить информацию о
пользователе(переключение между раскладками клавиатуры осуществляется
нажатием комбинации LeftAlt+LeftShift), согласиться с лицензионным
15

соглашением и ввести лицензионный ключ и согласится с продолжением


установки, нажав на кнопку «Готово» (рис. 1.20).

Рис. 1.20 – Продолжение процесса установки

Затем мастер настроит оборудование и после 2-х перезагрузок, ОС будет


установлена. После инсталляции ОС, ее запуск из VMWare Workstation
осуществляется выбором ее из библиотеки и нажатием на кнопку
«Включить/Возобновить» ( ) или комбинацией «Ctrl+B» (Рис. 1.21).

Рис. 1.21 – Окно VMWare Workstation с запущенной ОС Windows 98


16

После установки гостевой ОС необходимо установить пакет VMWare


Tools для данной ОС. Данный пакет устанавливает необходимые
дополнительные драйверы (в частности для Windows 98 устанавливается
драйверы дисплея и мыши), а также предоставляет возможность копирования
файлов из гостевой ОС в хостовую и обратно простыми операциями
перетаскивания. Для установки VMWare Tools необходимо при запущенной
гостевой ОС выбрать пункт меню «Виртуальная машина\Установить VMWare
Tools».
После установки VMWare Tools общий вид ОС Windows 98 представлен
на рис. 22. Система готова для выполнения лабораторных работ по курсу
«Архитектура компьютеров».

Рис. 1.22 – Общий вид ОС Windows 98

Каталог с установленной гостевой ОС (т.е. сама ОС) может быть


использован и на другом компьютере с установленным VMWare Workstation.
Для этого можно просто скопировать полностью весь каталог гостевой ОС на
другой компьютер и в VMWare Workstation выбрать его из меню
«Файл\Открыть…» или комбинацией Ctrl+O.
17

После установки гостевой ОС на нее необходимо добавить компиляторы


языков программирования для выполнения лабораторных работ. Данное
действие можно выполнить простым перетаскиванием файлов с хостовой ОС
на гостевую ОС.

1.2. Содержание отчета


1.2.1. Цель работы.
1.2.2. Ход установки гостевой ОС
1.2.3. Выводы.
18

Лабораторная работа 2

Тема: Конфигурация персонального компьютера

Цель работы: Получение практических навыков определения


конфигурации и основных характеристик ПЭВМ и ее модулей.

2.1. Темы для предварительной проработки

Состав, назначение и характеристики основных модулей ПЭВМ.


Конфигурация ПЭВМ.

2.2. Описание работы

При решении некоторых задач необходимо знать тип ПЭВМ, тип


микропроцессора, состав внешних устройств машины и их технические
характеристики (например, попытка обращения программы к
несуществующему устройству может привести к «зависанию» операционной
системы). Эта информация содержится в определенных ячейках ОЗУ, ПЗУ и
КМОП памяти и приведена ниже.

2.2.1. Определение типа ПЭВМ.

ПЗУ BIOS содержит по адресу F000:FFFEh байт позволяющий


идентифицировать тип ПЭВМ:
FFh – оригинальный IBM PC;
FEh – XT, Portable PC;
FDh – PCjr;
FCh – AT;
FBh – XT с памятью 640 К на системной плате;
FAh – PS/2 модель 25 или 30;
F9h – Convertible PC;
F8h – PS/2 модели 55SX, 70,80;
9Ah – Comrad XT, Compaq Plus;
30h – Sperry PC;
2Dh – Compaq PC, Compaq Deskpro.

2.2.2. Определение типа микропроцессора.


Алгоритм определения типа микропроцессора основывается на различиях
в регистрах флагов (РгФ) микропроцессоров (МП) 8086, 80286 и 80386 и
состоит в следующем:
19

В регистр флагов записывается 0. Если биты 12–15 РгФ устанавливаются


в 1 – это МП 8086. Если нет, то в регистр флага записывается код F000h. Если
после этого биты 12–15 РгФ остаются в 0, то это МП 80286, в противном
случае – 80386 и выше.
Для МП выше 80386 существует команда определения типа и параметров
МП: CPUID. Код данной команды в машинном коде 0Fh 0A2h. Получить
информацию о производителе МП можно, задав значение в регистре ЕАХ = 0.
Тогда CPUID возвращает в регистрах EBX, EDX и ECX идентификатор
производителя процессора (Vendor ID) в виде 12 символов ASCII. Для
получения полного наименование МП необходимо последовательно вызвать
команду CPUID с параметрами в EAX = 80000002h, 80000003h и 80000004h.
На каждый запрос в регистрах EAX:EBX:ECX:EDX будет возвращаться
фрагмент 48-символьной строки полного наименования процессора

2.2.3. Определение даты создания BIOS.

Дата создания BIOS занимает в ПЗУ BIOS 8 байтов начиная с адреса


F000:FFF5h и хранится в формате ASCII в виде мм/дд/гг, где
мм – номер месяца; дд – день; гг – год.

2.2.4. Определение конфигурации IBM PC AT.

2.2.4.1. Данные, хранящиеся в CMOS(КМОП)-памяти.

CMOS (КМОП)-память организована на базе микросхемы MC146818


фирмы Motorola и имеет 64 8-разрядных ячейки (регистра). В табл. 2.1
приведено содержимое тех ячеек памяти, в которых хранятся данные о
конфигурации и состоянии машины.
Обращение к CMOS (запись и считывание) осуществляется следующим
образом: сначала в порт 70h заносится адрес ячейки (номер регистра). Затем в
зависимости от выполняемой операциии в порт 71h или записываются данные,
или из порта 71h данные считываются.

Таблица 2.1 – Содержимое ячеек


Адрес
Содержимое
ячейки
0Eh Байт состояния диагностики при включении питания
10h Тип используемого НГМД
14h Конфигурация оборудования
15h–16h Объем основной памяти
30h–31h Объем расширенной (extended) памяти
20

2.2.4.1.1. Байт состояния диагностики.

Байт состояния диагностики содержит результаты выполнения


диагностики при включении питания машины. Формат байта состояния
приведен в табл. 2.2.

Таблица 2.2 – Содержимое байта диагностики


Биты Значение
0-1 Не используется, равно 0
0 – неправильная установка часов реального времени;
2
1 – часы установлены правильно.
1 – неисправность НМД, невозможно загрузить
3 операционную систему с жесткого диска;
0 – НМД исправен.
1 – фактический размер оперативной памяти не
4 соответствует указанному в КМОП-памяти;
0 – размер оперативной памяти указан правильно.
1 – ошибка в конфигурации системы;
5
0 – конфигурация указана правильно.
1 – ошибка в контрольной сумме КМОП-памяти;
6
0 – контрольная сумма КМОП-памяти правильна.
1 – разрядка аккумулятора, питающего КМОП-память и
7 часы реального времени;
0 – аккумулятор исправен и заряжен.

2.2.4.1.2. Тип используемых флоппи-дисков.

Младшая и старшая тетрады этого байта описывают соответственно


второй и первый НГМД:

0000 – дисковод не установлен;


0001 – дисковод на 360К;
0010 – дисковод на 1.2М;
0011 – дисковод на 720К;
0100 – дисковод на 1.44М.
21

2.2.4.1.3. Конфигурация оборудования.

Таблице 2.3 – Байт конфигурации


Биты Значение
1 – в системе установлены НГМД;
0
0 – НГМД не используются.
1 – установлен арифметический сопроцессор;
1
0 – сопроцессор не установлен.
2-3 Не используются, равны 0.
Тип видеоконтроллера и его режим:
Биты: 5 4
0 0 – не используются или EGA;
4-5
0 1 – CGA, EGA, VGA в режиме 40x25;
1 0 – CGA, EGA, VGA в режиме 80x25;
1 1 – монохромный контроллер.
6-7 Количество используемых НГМД.

2.2.4.1.4. Объем основной памяти.

Ячейка 15h содержит младший байт, а ячейка 16h – старший байт размера
основной памяти в килобайтах.

2.2.4.1.5. Объем дополнительной памяти.

Ячейки 16h и 17h содержат соответственно младший и старший байты


размера дополнительной памяти (расположенной выше 1М) в килобайтах.

2.2.4.1.6. Данные из RTC.

Данные в регистрах RTC хранятся в двоично-десятичном формате (BCD),


т.е. каждые 4 бита содержат один десятичный разряд. Поэтому для вывода
информации из RTC необходимо выполнять преобразование из BCD в
двоичный формат и наоборот. В табл. 2.4 приведено содержимое регистров
RTC.

Таблица 2.4 – Данные RTC


Адрес
Содержимое
ячейки
0h Текущее время, секунды.
1h Секунды будильника.
2h Текущее время, минуты.
3h Минуты будильника.
22

Продолжение таблицы 2.4.


Адрес
Содержимое
ячейки
4h Текущее время, часы.
5h Часы будильника.
6h Текущий день недели.
7h Текущий день месяца.
8h Текущий месяц.
9h Текущий год.
2.2.4.2. Данные, хранящиеся в области BIOS оперативной памяти.

BIOS в процессе инициализации опрашивает состояние перемычек и


анализирует содержимое КМОП-памяти. После анализа BIOS записывает в
свою область памяти по адресу 0040:0010h слово конфигурации. Назначение
отдельных битов этого слова приведено в табл. 2.5.

Таблица 2.5 – Содержимое слова конфигурации


Биты Значение
1 – в системе установлены НГМД;
0
0 – НГМД не используются.
1 – установлен арифметический сопроцессор;
1
0 – сопроцессор не установлен.
Объем основной памяти, установленной на системной
плате:
Биты: 3 2
2-3
0 1 – 16К;
1 0 – 32К;
1 1 – 64К и больше.
Тип видеоконтроллера и его режим:
Биты: 5 4
0 0 – не используются или EGA;
4-5
0 1 – CGA, EGA, VGA в режиме 40x25
1 0 – CGA, EGA, VGA в режиме 80x25
1 1 – монохромный контроллер
6-7 Количество используемых НГМД.
1 – используется контроллер прямого доступа к памяти;
8 0 – контроллер прямого доступа к памяти не
используется.
Количество установленных портов последовательной
9-11
передачи данных.
23

Продолжение таблицы 2.5.


Биты Значение
1 – применяется игровой адаптер (джойстик);
12
0 – игровой адаптер не применяется.
1 – установлен последовательный принтер(только для
13
PCjr).
14-15 Количество установленных принтеров.

2.3. Порядок выполнения работы

2.3.1. В соответствии с индивидуальным заданием, используя справочную


информацию о технических характеристиках ПЭВМ, приведенную в разделе 3,
определить адрес или область ПЗУ, ОЗУ или КМОП-памяти, содержащие
требуемые сведения.

2.3.2. Написать программу определения требуемых характеристик ПЭВМ.


2.4. Особенности программирования

2.4.1. На языке Паскаль.

2.4.1.1. Для обращения к ячейкам ОЗУ и ПЗУ применяются


предопределенные массивы Mem и MemW. Например, для чтения слова из
ячейки ОЗУ 0040:0010h используется выражение wo:=MemW[$0040:$0010],
где wo – переменная типа word; для чтения байта из ПЗУ по адресу
F000:FFF5h используется выражение b:=Mem[$f000:$fff5] (b переменная типа
byte).

2.4.1.2. Для обращения к портам ПЭВМ применяются предопределенные


массивы Port и PortW. Например, для записи значения 10h в порт 70h
используется выражение Port[$70]:=$10; для чтения из порта 71h используется
выражение data:=Port[$71], где data - переменная типа byte.

2.4.1.3. Для выделения определенного разряда в байте используется


битовая маска, содержащая единицу в проверяеммом разряде и нули – в
остальных. Битовая маска складывается с байтом по схеме поразрядной
коньюнкции AND в результате чего получаем значение 0, если заданный бит
содержит 0 и значение 1 в противоположном случае. Например,для
определения значения 0-го разряда переменной b(типа byte) необходимо
записать:

if(b and $01)=0 then writeln( '0-й разряд байта b содержит 0')
else writeln(' 0-й разряд байта b содержит 1');
24

2.4.2. На языке С.

2.4.2.1. Для обращения к ячейкам ОЗУ и ПЗУ используются дальние


указатели,которые обьявляются в программе следующим образом:
char far *uk; – для работы с байтами
int far *uk; –для работы с двухбайтными словами (переменные типа int).
При этом первым следует младший байт, потом – старший байт.
Например, для чтения слова из ОЗУ по адресу 0040:0010h используется
выражение:
uk= (int far *) 0x00400010;
wo=*uk;
где: wo – переменная типа int.
Для чтения байта из ПЗУ по адресу F000:FFF5h используется выражение:
uk = (char far *) 0xF000FFF5;
b = *uk;
где: b – переменная типа char.

2.4.2.2. Для вызова машинных команд необходимо использовать


встроенный асемблер. Так код програмы, определяющий производителя МП
будет иметь вмд:

char CPUVendor[12];
asm {
mov eax,0h;
db 0fh,0A2h
mov dword ptr CPUVendor,ebx
mov dword ptr CPUVendor+4,edx
mov dword ptr CPUVendor+8,ecx
}

2.4.2.3. Для обращения к портам ПЭВМ применяются функции чтения и


записи порта, которые хранятся в библиотеке <dos.h>. Библиотека
подключается директивой
#include < dos.h>
после чего, например, для записи значения 10h в порт 70h используется
функция:
outportb(0x70,0x10).
Для чтения из порта 71h используется функция:
data=intportb(0x71);
где data – переменная типа char.
25

2.4.2.4. Для выделения определенных разрядов в байте используется


битовая маска, которая складывается с байтом по схеме поразрядной
коньюнкции & (не путать с логической коньюнкцией &&), в результате чего
получается истинное значение (1), если заданный бит содержит 1 и ложное
значение (0) в противоположном случае. Например,для определения значения
0 разряда переменной b ( типа char) необходимо записать :

if(b&0x1) printf("0 разряд b содержит 1\n");


else printf("0 разряд b содержит 0\n").

2.5. Индивидуальные задания

1. Определить тип IBM; число НГМД; проверить, исправен ли


аккумулятор.
2. Определить день создания BIOS; объем основной памяти и число
подключенных принтеров.
3. Определить месяц создания BIOS и число подключенных
последовательных портов; проверить, установлен ли сопроцессор.
4. Определить тип 1-го НГМД и год создания BIOS; проверить, имеет ли
ПЭВМ контроллер прямого доступа к памяти.
5. Определить тип видеоконтроллера, его режим и дату создания BIOS;
проверить исправность НМД.
6. Определить тип IBM; определить, имеет ли данная ПЭВМ
видеоконтроллер EGA; проверить, правильно ли установлены часы реального
времени.
7. Определить объем дополнительной памяти; определить день создания
BIOS; проверить, установлен ли сопроцессор.
8. Определить тип 2-го НГМД (если он есть); объем основной памяти на
системной плате и год создания BIOS.
9. Определить число подключенных принтеров и дату создания BIOS;
проверить, правильно ли установлены часы реального времени.
10. Определить текущее время; определить месяц создания BIOS;
проверить, имеет ли ПЭВМ контроллер прямого доступа к памяти.
11. Определить тип микропроцессора и тип ПЭВМ; проверить, исправен
ли аккумулятор.
12. Определить текущую дату; определить год создания BIOS и число
подключенных принтеров.
13. Определить тип IBM; объем дополнительной памяти и число
подключенных последовательных портов.
14. Определить тип видеоконтроллера, его режим; проверить, установлен
ли сопроцессор; определить месяц создания BIOS.
15. Определить текущий месяц; определить число подключенных
26

принтеров и дату создания BIOS.


16. Определить тип IBM; объем дополнительной памяти; проверить,
имеет ли ПЭВМ контроллер прямого доступа к памяти.
17. Определить текущую дату, год создания BIOS и число подключенных
принтеров.
18. Определить тип микропроцессора и дату создания BIOS; проверить,
правильно ли установлены часы реального времени.
19. Определить тип IBM; определить тип видеоконтроллера, его режим;
проверить, установлен ли сопроцессор.
20. Определить текущее время; объем основной памяти на системной
плате и тип микропроцессора.

2.6. Содержание отчета

2.6.1. Тема лабораторной работы.


2.6.2. Цель работы.
2.6.3. Индивидуальное задание.
2.6.4. Текст программы.
2.6.5. Результаты работы программы.
2.6.6. Выводы.
27

Лабораторная работа 3

Тема: Организация прерываний в ПК

Цель работы: Изучение механизма прерываний, их типов, алгоритма и


средств их обработки, а также приобретение практических навыков создания
собственных программ обработки прерываний.

3.1. Темы для предварительной проработки

3.1.1. Работа контроллера прерываний. Установка вектора прерываний.


3.1.2. Маскирование прерываний.
3.1.3. Резидентные программы.

3.2. Описание работы

3.2.1. Механизм и типы прерываний.

Для обработки событий, происходящих асинхронно по отношению к


выполнению программы, лучше всего подходит механизм прерываний.
Прерывание можно рассматривать как некоторое особое событие в системе,
требующее моментальной реакции. Например, хорошо спроектированные
системы повышенной надежности используют прерывание по аварии в
питающей сети для выполнения процедур записи содержимого регистров и
оперативной памяти на магнитный носитель, с тем чтобы после
восстановления питания можно было бы продолжить работу с того же места.
Поскольку прерывания возможны самые разнообразные по самым
различным причинам, каждому прерыванию присваивается номер прерывания.
С каждым номером прерывания связывается то или иное событие. Система
умеет распознать какое прерывание, с каким номером произошло, и запускает
соответствующую этому номеру процедуру.
По источнику и характеру возникновения прерывания можно разделить
на группы (рис. 3.1).
Программные прерывания вызывают сами программы, поэтому они не
являются асинхронными. Для этого они используют команду INT.
Программные прерывания удобно использовать для организации доступа
к отдельным общим для всех программ модулям. Например, программные
модули операционной системы доступны прикладным программам именно
через прерывания, и нет необходимости при вызове этих модулей знать их
текущий адрес в памяти.
28

Прерывания

Аппаратные Программные

Внешние Внутренние

Маскируемые Немаскируемые

Рис. 3.1 – Типы прерываний

Прикладные программы сами могут устанавливать свои обработчики


прерываний для их последующего использования другими программами. Для
этого встраиваемые обработчики прерываний должны быть резидентными в
памяти.
Аппаратные прерывания вызываются физическими устройствами и
приходят асинхронно. Эти прерывания информируют систему о событиях,
связанных с работой устройств, например о том, что завершилась печать
символа на принтере и неплохо было бы выдать следующий символ, или о
том, что требуемый сектор диска уже прочитан, его содержание доступно
программе.
Использование прерываний при работе с медленными внешними
устройствами позволяет совместить ввод/вывод с обработкой данных в
центральном процессоре и в результате повышает общую производительность
системы.
Внешние аппаратные прерывания вызваны сигналами, внешними по
отношению к центральному процессору, и подаются на его входы INT и NMI.
Прерывания по входу INT относятся в аппаратным маскируемым
прерываниям, поскольку могут быть разрешены или запрещены флагом IF
регистра флагов. Номер вектора прерываний маскируемых прерываний
передается в процессор по его восьми младшим разрядам шины данных.
Вход немаскируемого прерывания NMI обычно используется для
сообщений о "катастрофических" событий (отключении питания,
обнаружении ошибок памяти и т.д.). Номер этого прерывания равен 2.
Внутренние (логические) прерывания формируются самим процессором,
когда он встречается с некоторыми особыми событиями вроде деления на 0.
Это прерывания с номерами 0, 1, 3, 4 (см. табл. 3.1).

В табл. 3.1 дано описание наиболее важных прерываний.


29

Таблица 3.1 – Описание прерываний


Номер Описание
Ошибка деления. Вызывается автоматически после выполнения
команд DIV или IDIV, если в результате деления произошло
переполнение. DOS обычно при об работке этого прерывания
выводит сообщение об ошибке и останавливает выполнение
0
программы. Для процессора 8086 при этом адрес возврата
указывает на следующую после команды деления команду, а в
процессоре 80286 – на первый байт команды, вызвавшей
прерывание.
Прерывание пошагового режима. Вырабатывается после
выполнения каждой машинной команды, если в слове флагов
установлен бит пошаговой трассировки TF. Используется для
1
отладки программ. Прерывание не вырабатывается после
выполнения команды MOV в сегментные регистры или после
загрузки сегментных регистров командой POP.
Аппаратное немаскируемое прерывание. Это прерывание может
использоваться по-разному в разных машинах. Обычно
2
вырабатывается при ошибке четности в оперативной памяти и
при запросе прерываний от сопроцессора.
Прерывание для трассировки. Это прерывание генерируется при
3 выполнении однобайтовой команды с кодом CCh и обычно
используется отладчиками для установки точки прерывания.
Переполнение. Генерируется машинной командой INTO,если
установлен флаг OF. Если флаг не установлен, то команда INTO
4
выполняется как NOP. Это прерывание используется для
обработки ошибок при выполнении арифметических операций.
Печать копии экрана. Генерируется при нажатии на клавиатуре
клавиши PrtScr. Обычно используется для печати образа экрана.
5 Для процессора 80286 генерируется при выполнении машинной
команды BOUND, если проверяемое значение вышло за
пределы заданного диапазона.
Неопределенный код операции или длина команды больше 10
6
байтов (для процессора 80286).
7 Особый случай отсутствия сопроцессора.
IRQ0 – прерывание интервального таймера, возникает 18,2 раза
8
в секунду.
IRQ1 – прерывание от клавиатуры. Генерируется при нажатии и
9 при отжатии клавиши. Используется для чтения данных от
клавиатуры.
IRQ2 – используется для каскадирования аппаратных
Ah
прерываний в машинах класса AT.
Bh IRQ3 – прерывание асинхронного порта COM2.
Ch IRQ4 – прерывание асинхронного порта COM1.
30

Продолжение таблицы 3.1


Номер Описание
Dh IRQ5 – прерывание от контроллера жесткого диска для XT.
IRQ6 – прерывание генерируется контроллером флоппи-диска
Eh
после завершения операции.
IRQ7 – прерывание принтера. Генерируется принтером,
Fh когда он готов к выполнению очередной операции. Многие
адаптеры принтера не используют это прерывание.
10h Обслуживание видеоадаптера.
11h Определение конфигурации устройств в системе.
12h Определение размера оперативной памяти в системе.
13h Обслуживание дисковой системы.
14h Последовательный ввод/вывод.
15h Расширенный сервис для AT-компьютеров.
16h Обслуживание клавиатуры.
17h Обслуживание принтера.
18h Запуск BASIC в ПЗУ, если он есть.
19h Загрузка операционной системы
1Ah Обслуживание часов.
1Bh Обработчик прерываний Ctrl-Break.
Прерывание возникает 18,2 раза в секунду, вызывается
1Ch
программно обработчиком прерывания таймера.
1Dh Адрес видеотаблицы для контроллера видеоадаптера 6845.
1Eh Указатель на таблицу параметров дискеты.
Указатель на графическую таблицу для символов с кодами
1Fh
ASCII 128-255.
20h-5Fh Используются DOS или зарезервированы для DOS.
60h-67h Прерывания, зарезервированные для пользователя.
68h-6Fh Не используются.
70h IRQ8 - прерывание от часов реального времени.
71h IRQ9 - прерывание от контроллера EGA.
72h IRQ10 – зарезервировано.
73h IRQ11 – зарезервировано.
74h IRQ12 – зарезервировано.
75h IRQ13 – прерывание от сопроцессора.
76h IRQ14 – прерывание от контроллера жесткого диска.
77h IRQ15 – зарезервировано.
78h-7Fh Не используются.
80h-85h Зарезервированы для BASIC.
86h-F0h Используются интерпретатором BASIC.
F1h-FFh Не используются
31

3.3.2. Таблица векторов прерываний.


Для того чтобы связать номер прерывания с адресом программы
обработки прерываний (обработчика прерываний), используется таблица
векторов прерываний, занимающая первый килобайт оперативной памяти -
адреса от 0000:0000 до 0000:03FFh. Таблица состоит из 256 элементов – FAR-
адресов обработчиков прерываний. Эти элементы называются векторами
прерываний. В первом слове элемента таблицы записано смещение, а во
втором – сегмент адреса обработчика прерываний.
Прерыванию с номером 0 соответствует адрес 0000:0000, прерыванию с
номером 1 – 0000:0004 и т.д. Прерыванию с номером n будет соответствовать
адрес 0000:4*n. Инициализация таблицы происходит частично программой
BIOS после тестирования аппаратуры, частично при загрузке ОС. ОС может
переключить на себя некоторые прерывания BIOS.

3.3.3. Обработка прерываний.

Несмотря на многообразие типов прерываний, алгоритм обработки


прерывания процессором один и тот же и изображен на рис. 3.2.

3.3.4. Маскирование прерываний.


Часто при выполнении критических участков программ, для того чтобы
гарантировать выполнение определенной последовательности команд,
приходится запрещать прерывания. Это можно сделать командой CLI (сброс
флага разрешения прерывания). Ее нужно поместить в начало критической
последовательности команд, а в конце расположить команду STI (установить
флаг разрешения прерывания). Команда CLI запрещает только маскируемые
прерывания, немаскируемые всегда обрабатываются процессором.
Если вы используете запрет прерываний с помощью команды CLI,
следите за тем, чтобы прерывания не отключались на длительный период
времени, т.к. это может привести к нежелательным последствиям, например,
будут отставать часы.
Если надо запретить не все прерывания, а только некоторые, например, от
клавиатуры, то для этого надо воспользоваться услугами контроллера
прерываний.
3.3.5. Изменение таблицы векторов прерываний.
Если программе потребуется организовать обработку некоторых
прерываний, то для этого необходимо переназначить требуемый вектор
прерываний на свой обработчик. Это можно сделать, изменив содержание
соответствующего элемента таблицы векторов прерываний. Очень важно не
забыть перед завершением работы программы восстановить содержимое
32

измененных векторов, т.к. после завершения работы программы память,


которая ей была распределена, считается свободной и может быть
использована для загрузки другой программы. Если вектор не был
восстановлен, и пришло прерывание, то работа системы может нарушиться –
вектор теперь указывает на область, которая может содержать все, что угодно.
начало N – номер вектора
прерывания
1
Поместить в стек регистр
флагов

2
Обнулить флаги
IF и TF

3
Поместить в стек
значение регистра CS
Команда INT 4
(Interrupt) Присвоить адресу век-
тора прерываний N*4

5
Загрузить старшее слово
вектора в CS

6
Поместить в стек
значение регистра IP

7
Загрузить младшее слово
вектора в IP
8
Выполнить действия
обработчика прерываний

9
Извлечь из стека и
загрузить значение IP

10
Команда IRET Извлечь из стека и
(Interrupt return) загрузить значение CS
11
Извлечь из стека и загрузить
значение регистра флагов

конец

Рис. 3.2 – Алгоритм обработки прерываний


33

Поэтому последовательность действий для нерезидентных программ,


обрабатывающих прерывания, должна быть такой:
– прочитать содержимое элемента таблицы векторов прерываний для
вектора с номером того прерывания, какое требуется обработать;
– запомнить это содержимое (адрес старого обработчика прерываний) в
области данных программы;
– установить новый адрес в таблице векторов прерываний так, чтобы он
соответствовал началу программы обработки прерываний пользователя;
– перед завершением работы программы прочитать из области данных
адрес старого обработчика прерывания и записать его в таблицу векторов
прерываний.
Отметим, что для резидентных программ (т.е. программ постоянно
находящихся в оперативной памяти) последний пункт выполнять не нужно.
Операция изменения вектора прерываний должна быть непрерывной в
том смысле, что во время изменения не должно произойти прерывание с
номером, для которого производится замена программы обработки. Если,
например, будет записано новое значение смещения, а сегмент адреса не
успеет обновиться, то по какому адресу будет передано управления в случае
прерывания и что при этом произойдет?
Поэтому перед записью в вектор прерываний нужно запретить
прерывания командой CLI, а после записи - разрешить командой STI.
Для облегчения работы по замене прерывания DOS имеет специальные
функции для чтения элемента таблицы прерываний и для записи в нее нового
адреса. Правильность операций при этом будет гарантирована.
Для чтения вектора используйте функцию 35h DOS (прерывания 21h).
Перед ее вызовом регистр AL должен содержать номер вектора в таблице.
После выполнения функции в регистрах ES:BX будет искомый адрес
обработчика прерывания.
Функция 25h DOS устанавливает для вектора с номером, находящимся в
AL, обработчик прерываний DS:DX.

3.3.6. Коррекция системных обработчиков прерываний.


Если необходимо добавить какие-либо собственные действия к тем, что
выполняет стандартный обработчик прерывания, то можно организовать
цепочку прерываний.
Для организации цепочки прерываний необходимо записать в таблицу
векторов адрес собственного обработчика, не забыв сохранить прежнее
содержимое таблицы. Обработчик пользователя получает управление по
прерыванию, выполняет какие-либо действия, затем передает управление
стандартному обработчику. Можно сделать и по-другому: Обработчик
пользователя вызывает стандартный обработчик, а затем выполняет
дополнительные действия. Т.е. можно вставить дополнительную обработку
34

как до вызова стандартного обработчика, так и после его вызова.

3.3.7. Состояние клавиш-переключателей.

В табл. 3.2 приведен формат байта по адресу 0040:0017h, содержащий


текущие состояния клавиш-переключателей.

Таблица 3.2 – Состояние клавиш-переключателей


Бит Значение, когда бит=1
0 нажата клавиша правый Shift
1 нажата клавиша левый Shift
2 нажата клавиша Ctrl
3 нажата клавиша Alt
4 режим ScrollLock включен
5 режим NumLock включен
6 режим CapsLock включен
7 режим вставки включен

3.4. Порядок выполнения

3.4.1. Разработать собственную процедуру обработки прерывания (см.


п. 3.5.1.4), которая выполняла бы следующие действия:
– вызов программы обработки прерывания (см. п. 3.5.1.3) с одним из
номеров прерывания, зарезервированных для пользователя (см. табл. 3.1);
– анализ состояния заданной клавиши-переключателя согласно
таблицы 3.2;
– при нажатии клавиши – вывод на экран ее наименования.

3.4.2. Разработать программу, выполняющие следующие действия:


– сохранить адрес системной программы обработки прерывания Int9;
– записать адрес этой системной программы в таблицу векторов
прерываний по выбранному номеру прерывания пользователя;
– записать адрес собственной процедуры обработки прерывания в
таблицу векторов по номеру 9;
– завершить программу и оставить ее в памяти резидентной.

3.5. Особенности программирования

3.5.1. На языке Паскаль.


35

3.5.1.1. Для чтения вектора прерывания и для изменения таблицы


векторов прерываний используйте предопределенный массив MemW.
Например, для чтения смещения вектора 9 можно применить выражение

ofs_:= MemW[0000:4*9];

а для записи сегмента адреса обработчика прерываний в $60-й вектор


прерываний

Memw[0000:4*$60+2]:=Seg(Int9d);

где: ofs_:word – переменная для временного хранения значения


смещения;
Int9d – имя процедуры обработки (коррекции) прерывания 9.

3.5.1.2. Для запрещения и разрешения прерываний используйте либо


команды на ассемблере:

begin
.....
asm
Cli {прерывания запрещены}
end
.....

asm
Sti {прерывания разрешены}
end
......

либо операторы Inline с машинными командами:


begin
.....
Inline($fa) { Cli }
......
Inline($fb) { Sti }
......
Inlin

3.5.1.3. Для вызова программ обработки заданного прерывания


используется процедура Intr.
Процедура Intr имеет следующую форму:
36

Intr(IntNo : byte; var Reg : Registers),

где:IntNo – номер прерывания (0...255),


Reg – запись типа Registers, определенного в модуле DOS, содержащая
значения регистров процессора. Надо указать в программе модуль DOS после
uses или включить в программу следующее описание типа записи:
type
Registers = record
case integer of
0:(AX, BX, CX, DX, BP, SI, DI, DS, ES,
Flags : word);
1:(AL, AH, BL, BH, CL, CH, DL, DH : byte);
end;

где: AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags,AL,AH,BL,BH,CL, CH,DL,DH


– переменные, соответствующие одноименным регистрам процессора.
При выполнении программного прерывания (выполнении процедуры Intr)
процедура Intr загружает регистры AX, BX, CX, DX, BP, SI, DI, DS и ES
процессора значениями из записи Regs (задаются пользователем). Когда
обработка прерывания завершается, содержимое регистров AX, BX, CX, DX,
BP, SI, DI, DS, ES и Flags возвращается в запись Regs.
Ограничения: Программные прерывания, которые зависят от
определенных значений в SP или SS на входе или изменяют значения SP или
SS на выходе, не могут быть выполнены с помощью этой процедуры.

3.5.1.4. Собственная процедура обработки прерываний имеет следующий


вид:

procedure NewIntr(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS,
ES, BP : Word); Interrupt;
begin
...
end.

Примечание:
– имя процедуры задается пользователем;
– любое число параметров (в том числе и все) в процедуре можно
опускать, но только подряд начиная с начала.
Вызов пользовательской процедуры обработки прерывания
осуществляется с помощью процедуры Intr (см. п. 3.5.1.2). Предварительно
адрес процедуры пользователя должен быть занесен в таблицу векторов
прерывания в соответствии с выбранным номером прерывания либо путем
37

прямой записи (см. п. 3.5.1.1), либо с помощью процедуры SetIntVec (см.


п. 3.5.1.5), а адрес системной процедуры обработки данного прерывания
сохранен либо в переменной (см. п. 3.5.1.1), либо с помощью процедуры
GetIntVec (см. п. 3.5.1.4).

3.5.1.5. Процедура GetIntVec возвращает адрес заданного вектора


прерывания и имеет следующий вид:

GetIntVec(IntNo:byte; var Vector:pointer),

где: IntNo задает номер прерывания (0...255) и адрес возвращается в параметре


Vector).

3.5.1.6. Процедура SetIntVec устанавливает заданный вектор прерывания


по заданному адресу и имеет следующий вид:

SetIntVec(IntNo:byte; Vector:pointer),

где: IntNo задает номер прерывания (0...255) и Vector задает адрес (при
задании адреса можно воспользоваться оператором @ или функцией Addr).

3.5.1.7. Чтобы сделать программу резидентной, т.е. такой, которая


постояно находилась бы в оперативной памяти (все программы обработки
прерывания должны быть такие), необходимо использовать в конце
программы процедуру Keep(0), которая завершает программу и оставляет ее в
памяти (параметр в процедуре указывает значение кода возврата).
Поскольку программа остается в памяти, включая сегмент данных,
сегмент стека и "кучу", необходимо перед программой указать директиву
компилятора, минимизирующую резидентную область памяти:
{$m $800,0,0}.

3.5.2. На языке С.

3.5.2.1. Для чтения вектора прерывания и для изменения таблицы


векторов прерываний используйте дальние указатели (сhar far *). Например,
для установки указателей на вектора 9 и 60 можно применить
выражение

char far *adr_p, *int9_p;


adr_p= (char far *)(4*9);
int9_p= (char far *)(4*60);

а для записи адреса обработчика 9 прерываний в 60-й вектор прерываний


38

*int9_p=*adr_p;

3.5.2.2. Для вызова программ обработки заданного прерывания


используется процедура geninterrupt(IntNo),
где: IntNo - номер прерывания (0...255).

Надо указать в программе подключение библиотеки директивой


#include <dos.h>

3.5.2.3. Собственная процедура обработки прерываний должна быть


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

Собственная процедура обработки прерываний должна быть описана как:

void interrupt New_intr();


Тогда при вызове автоматически определяется ее начальный адрес,
которому присваивается значение указателя

*adr_p=(char far *)New_intr;

3.5.2.4. Чтобы сделать программу резидентной, т.е. такой, которая


постояно находилась бы в оперативной памяти (все программы обработки
прерывания должны быть такие), необходимо использовать в конце
программы функцию 31h прерывания 21h,кототорая завершает программу и
оставляет ее в памяти резидентной.

union REGS in,out;


in.h.ah=0x31;/*задание 31h функции завершить и оставить резидентной
в регистер ah*/
in.h.al=0; /*код возврата*/
in.x.dx=size; /*обьем выделенной памяти в 16_байтных параграфах */
int86(0x21,&in,&out); /*обрашение к 21 прерыванию с параметрами*/

3.6. Индивидуальные задания

3.6.1. Осуществить коррекцию прерывания Int 9 (от клавиатуры) так,


чтобы:
а) выполнялись все действия системного обработчика данного
прерывания;
б) при нажатии одной из клавиш-переключателей вывести на экран
39

название этой клавиши.

3.6.2. Клавишу-переключатель выбрать по следующему правилу:

нк := нс mod 8,

где: нк – номер клавиши-переключателя в табл. 3.2;


нс – номер студента в журнале.

3.7. Содержание отчета

3.7.1. Тема лабораторной работы.


3.7.2. Цель работы.
3.7.3. Индивидуальное задание.
3.7.4. Текст программы.
3.7.5. Результаты работы программы.
3.7.6. Выводы.
40

Лабораторная работа 4

Тема: Организация работы клавиатуры ПК

Цель работы: Изучение организации и принципов работы клавиатуры и


приобретение практических навыков управления микропроцессором
клавиатуры.

4.1. Темы для предварительной проработки

4.1.1. Организация и принцип работы клавиатуры ПЭВМ.

4.2. Описание работы

4.2.1. Принципы работы клавиатуры. На рис. 4.1 представлена


упрощенная схема клавиатуры.

Переключатели +5В
клавиатуры
...
. . .
D 8048 T0
. 0 P26 cloc
. D1
. T1
D2 data
P27
P
10
P11

P
20 ГСИ
P21
Х1

Рис. 4.1 – Схема клавиатуры

В качестве контроллера клавиатуры используется специализированный


микропроцессор Intel 8042 на материнской плате, а на самой клавиатуре – Intel
8048, имеющий два порта – входной и выходной. Входной порт (X) подключен
к горизонтальным линиям матрицы, а выходной (Y) – к вертикальным. Все
горизонтальные линии подключены также через резисторы к источнику
питания +5B.
Устанавливая по очереди на каждой из вертикальных линий уровень
напряжения, соответствующий логическому нулю, клавиатурный контроллер
41

Intel 8048 опрашивает состояние горизонтальных линий. Если нажатых


клавиш нет, уровень напряжения на всех горизонтальных линиях
соответствует логической 1 (т.к. все эти линии подключены к источнику
питания +5B через резисторы). Если пользователь нажмет на какую-то
клавишу, то соответствующие вертикальная и горизонтальная линии окажутся
замкнутыми. Когда на этой вертикальной линии процессор установит значение
логического нуля, то уровень напряжения на горизонтальной линии также
будет соответствовать логическому нулю.
Как только на одной из горизонтальных линий появится уровень
логического нуля, клавиатурный процессор фиксирует нажатие на клавишу.
Номер фиксируемой клавиши однозначно связан с распайкой
клавиатурной матрицы и не зависит напрямую от обозначений, нанесенных на
поверхность клавиш. Этот номер называется скан-кодом (Scan Code).
Аналогичные действия выполняются, когда пользователь отпускает нажатую
ранее клавишу. Отметим, что скан-код отжатой клавиши отличается от скан-
кода нажатой клавиши единицей в старшем бите (т.е. больше на 128).
Слово scan ("сканирование") подчеркивает, что клавиатурный процессор
сканирует клавиатуру для поиска нажатой клавиши.
Получив по интерфейсу клавиатуры от Intel 8048 скан-код, Intel 8042
посылает в центральный процессор запрос на прерывание (Int 09h) и посылает
скан-код в порт 60h.
Если нажать на клавишу и не отпускать ее, клавиатура перейдет в режим
автоповтора. В этом режиме в центральный процессор автоматически через
некоторый промежуток времени, называемый периодом автоповтора,
посылается код нажатой клавиши.

4.2.2. Порты для работы с клавиатурой.

Для работы с клавиатурой ПК использует порты с адресами 60h и 64h.


Порт 64h служит для записи команд контроллеру 8042 (если команда
содержит байт данных, то он передается через порт 60h), при чтении порт 64h
содержит слово состояния 8042. Так как контроллер 8048 не имеет
непосредственной связи с системной шиной, то команды ему передаются через
контроллер 8042, для чего и команда и данные передается через порт 60h.
Порт 60h при чтении содержит скан-код последней нажатой клавиши.

4.2.3. Команды контроллера клавиатуры 8048.

Контроллер 8042 обслуживает не только клавиатуру, но и другие системы


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

Для посылки команды необходимо вначале убедиться в том, что его


внутренняя очередь команд пуста (если команда состоит из нескольких байтов,
проверка осуществляется для каждого байта). Это можно сделать, прочитав
слово состояния 8042 из порта с адресом 64h. Бит с номером 1 должен быть
равен нулю (биты нумеруются с 0). После того как программа дождется
готовности контроллера 8042, она может послать ему команду, записав ее в
соответствующий порт с адресом 64h или 60h (это делается для каждого байта
команды). Для управления клавиатурой контроллер 8048 использует
следующие команды, которые посылаются в порт 60h:

4.2.3.1. Команда установки характеристик режима автоповтора.

Команда состоит из двух байтов. Первый байт: код команды – F3h;


второй байт определяет характеристики режима, биты которого имеют
следующее назначения:
– 4-0: количество повторов в секунду (см. табл. 4.1);
– 6-5: начальная задержка до генерации автоповтора в мс (00=250,
01=500, 10=750, 11=1000);
– 7: зарезервирован, должен быть равен 0.

Таблица 4.1 – Параметры автоповтора

Константа Частота Константа Частота Константа Частота


00h 30.0 0Bh 10.9 16h 4.3
01h 26.7 0Ch 10.0 17h 4.0
02h 24.0 0Dh 9.2 18h 3.7
03h 21.8 0Eh 8.6 19h 3.3
04h 20.0 0Fh 8.0 1Ah 3.0
05h 18.5 10h 7.5 1Bh 2.7
06h 17.1 11h 6.7 1Ch 2.5
07h 16.0 12h 6.0 1Dh 2.3
08h 15.0 13h 5.5 1Eh 2.1
09h 13.3 14h 5.0 1Fh 2.0
0Ah 12.0 15h 4.6

Период автоповтора определяет количество посылок скан-кода,


генерируемых процессором клавиатуры в одну секунду.
Первоначально при инициализации системы период задержки для
включения режима автоповтора устанавливается модулями BIOS равным 500
мс при периоде автоповтора, равным 10 повторам в секунду.
43

4.2.3.2. Команда управления светодиодами клавиатуры.

Команда состоит из двух байтов. Первый байт: код команды – ЕDh; Для
включения или выключения светодиодов после кода команды (EDh) через 60h
порт посылается байт данных, биты которого имеют следующее назначения
(табл. 4.2):

Таблица 4.2 – Значение байта управления светодиодами

Биты Значение
0 1 – включить ScrollLock;
1 1 – включить NumLock;
2 1 – включить CapsLock;
3-7 не используются.

4.2.3.3. Команда возврата к значениям, задаваемым BIOS. Код команды –


F6h.

4.3. Порядок выполнения

4.3.1. В соответствии с индивидуальным заданием:


– установить соответствующие период и задержку автоповтора;
– осуществить мигание соответствующего светодиода.

4.3.2. Путем чтения из порта 60h скан-кода определить клавишу, скан-код


нажатия которой совпадает с номером студента в журнале. Определить скан-
код отжатия этой клавиши. При определении скан-кодов можно
воспользоваться алгоритмом, приведенным на рис. 4.2.

4.3.3. После выполнения пп. 3.1 и 3.2 восстановить характеристики


клавиатуры в исходное состояние.
44

1
начало

2
Для предотвращения чтения скан-
Задержка 100 мс кодов отжатия клавиш Ctrl и F9 при
запуске программы
3
I = 1,2
9
4 конец
Чтение из порта 60h
скан-кода

5
Чтение из порта 60h
скан-кода

да 6
Скан-коды совпадают?

нет
7
"новый" скан-код

8
"старый" скан-код =
"новому"

Рис. 4.2 – Алгоритм определения скан-кодов нажатия и отжатия

4.4. Особенности программирования

4.4.1. На языке Паскаль.


4.4.1.1. Для чтения данных из порта и записи данных в порт используйте
предопределенный массив Port. Например, для чтения из порта 64h
применяется выражение b:=Port[$64], а для записи в порт 60h - выражение
Port[$60]:=b, где b - переменная типа byte.
4.4.2. На языке Си.
4.4.2.1. Для обращения к портам ПЭВМ применяются функции чтения и
записи порта, которые хранятся в библиотеке <dos.h>. Библиотека
подключается директивой
45

#include < dos.h>


после чего, например, для записи значения b в порт 60h используется
выражение:
outportb(0x60,b);
Для чтения из порта 64h используется выражение:
b=intportb(0x64);
где:b – переменная типа char.

4.5. Индивидуальные задания

4.5.1. Индивидуальные задание выбрать в соответствии с табл. 4.3:


Таблица 4.3 – Варианты индивидуальных заданий
Номер в Период Задержка Наименование
журнале автоповтора автоповтора, (мс) светодиода
1 30,0 250 NumLock
2 26,7 500 CapsLock
3 24,0 750 ScrollLock
4 20,0 1000 NumLock
5 2,0 250 CapsLock
6 3,0 500 ScrollLock
7 30,0 750 NumLock
8 26,7 1000 CapsLock
9 24,0 250 ScrollLock
10 20,0 500 NumLock
11 2,0 750 CapsLock
12 3,0 1000 ScrollLock
13 5,0 250 NumLock
14 6,0 500 CapsLock
15 8,0 750 ScrollLock
16 10,0 1000 NumLock

4.6. Содержание отчета

4.6.1. Тема лабораторной работы.


4.6.2. Цель работы.
4.6.3. Индивидуальное задание.
4.6.4. Текст программы.
4.6.5. Результаты работы программы.
4.6.6. Выводы.
46

Лабораторная работа 5

Тема: Буфер клавиатуры ПК

Цель работы: Изучение организации буфера клавиатуры и приобретение


практических навыков определения хранящихся в буфере ASCII и скан-кодов
клавиш клавиатуры

5.1. Темы для предварительной проработки

5.1.1. Организация буфера клавиатуры.

5.1.2. Формирование ASCII кодов.

5.2. Описание работы

Записанная в ПЗУ BIOS подпрограмма обработки прерывания 09h,


вызванного контроллером клавиатуры при нажатии (отжатии) клавиши, читает
скан-код из порта 60h и, если это скан-код клавиши-переключателя (правый
Shift, левый Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock и Insert), то
изменяется содержимое ячеек памяти 0040:0017h и 0040:0018h, хранящих
состояния клавиш-переключателей. В буфер клавиатуры при этом ничего не
пишется (исключение составляет клавиша Insert).
В табл. 5.1 приведен формат байта по адресу 0040:0017h, а в табл. 5.2 –
по адресу 0040:0018h.

Таблица 5.1 – Формат байта по адресу 0040:0017h


Бит Значение, когда бит=1
0 нажата клавиша правый Shift
1 нажата клавиша левый Shift
2 нажата клавиша Ctrl
3 нажата клавиша Alt
4 режим ScrollLock включен
5 режим NumLock включен
6 режим CapsLock включен
7 режим вставки включен
47

Таблица 5.2 – Формат байта по адресу 0040:0018h.


Бит Значение, когда бит=1
0 нажаты клавиши левый Shift вместе с Ctrl
1 нажаты клавиши левый Shift вмести с Alt
2 нажата клавиша SysReq
3 нажаты клавиши Ctrl вместе с NumLock
4 режим ScrollLock включен
5 режим NumLock включен
6 режим CapsLock включен
7 режим вставки включен

Состояния клавиш-переключателей могут быть изменены программно.


Если же это скан-код клавиши, не являющейся переключателем, то в
соответствии с ее скан-кодом и состоянием клавиш-переключателей
формируется или однобайтный ASCII код данной клавиши, который вместе со
скан-кодом записывается в буфер клавиатуры, или двубайтный расширенный
код, первым байтом которого является 0, а второй байт в большинстве случаев
совпадает со скан-кодом. Эти два байта также записываются в буфер
клавиатуры. При отжатии клавиши в буфер ничего не записывается и
изменяется только состояние клавиш-переключателей.
Программа обработки прерывания 09h отслеживает также некоторые
комбинации клавиш. В табл. 5.3 приведены эти комбинации и действия,
выполняемые обработчиком прерывания при их обнаружении:

Таблица 5.3 – Функции клавиш


Комбинация клавиш Выполняемые действия
Ctrl-Alt-Del Сброс и перегрузка системы
Ctrl-NumLock Перевод машины в состояние ожидания
Shift-PrtSc Распечатка на принтере содержимого
экрана (обработка прерывания 05h)
Ctrl-Break Завершение выполнения программы

Структура буфера клавиатуры изображена на рис. 5.1. Буфер клавиатуры


расположен по адресам 0040:001h – 0040:003Ch оперативной памяти и
позволяет накапливать данные (ASCII и скан-коды) о 15 нажатиях клавиш.
В ячейке 0040:001Ah (указатель начала) хранится адрес первого
введенного символа, а в ячейке 0040:001Ch (указатель хвоста) – адрес первой
свободной ячейки после последнего введенного символа.
48

Адреса хранятся в виде байта смещения (второй байт ячейки не используется).


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

15 0
0040:003Ch Содержимое ячейки буфера
Физ. конец буфера F
F 0040:003Ah 15 87 0
U 0040:0038h Скан-код ASCII
B 0040:0036h
Если ASCII-код равен нулю, то
0040:0034h
вместо скан-кода указывается
расширенный код.

0040:0022h
R 0040:0020h
Физ. начало буфера E 0040:001Eh
Указатель хвоста 22 0040:001Ch
Указатель начала 36 0040:001Ah

Рис. 5.1 – Структура буфера клавиатуры

Запись в буфер осуществляется по адресу указателя хвоста, при этом


содержимое указателя увеличивается на 2. Чтение из буфера производится по
адресу указателя начала, при этом содержимое указателя также увеличивается
на 2 (если указатель содержит адрес последней ячейки буфера – 3Сh, то вместо
увеличения на 2 в него необходимо записать адрес начала буфера – 1Eh).

5.3. Порядок выполнения

5.3.1. Написать программу, реализующую изображенный на рис. 5.2


алгоритм чтения из буфера клавиатуры ASCII и скан-кодов.

5.3.2. В соответствии с индивидуальным заданием определить ASCII и


скан-код требуемых клавиш.
49

1
начало

да 2
Буфер пуст?

нет
3
Чтение байта по адресу Чтение ASCII-кода
начала буфера нажатой клавиши

4
Чтение байта по адресу Чтение скан-кода, если ASCII-код ≠0,
начала буфера иначе номера расширенного кода

5
ASCII и скан-код

6
Коррекция указателя
начала буфера

нет
Ctrl+Break?

да
8
конец

Рис. 5.2 – Алгоритм просмотра буфера клавиатуры

5.4. Особенности программирования

5.4.1. На языке Паскаль.

5.4.1.1. Для чтения данных из буфера клавиатуры используйте


предопределенный массив Mem. Например, для чтения содержимого указателя
хвоста применяется выражение Mem[$0040:$001С], а для чтения ASCII кода из
начала буфера - Mem[$0040:Mem[$0040:$001А]].

5.4.2. На языке С.

5.4.2.1. Для чтения данных из буфера клавиатуры используются дальние


указатели,которые обьявляются в программе следующим образом:
50

char far *uk;


Например, для чтения содержимого указателя хвоста применяется
выражение
uk=( char far *) 0x0040001C;
b=*uk;
а для чтения ASCII кода7 из начала буфера
uk=( char far *) 0x0040001A;
b=*uk;
где: b- переменная типа char.

5.5. Индивидуальные задания

5.5.1. Определить ASCII код русской буквы, номер которой в алфавите


совпадает с номером студента в журнале.
5.5.2. Определить скан-код этой клавиши.

5.6. Содержание отчета

5.6.1. Тема лабораторной работы.


5.6.2. Цель работы.
5.6.3. Индивидуальное задание.
5.6.4. Текст программы.
5.6.5. Результаты работы программы.
5.6.6. Выводы.
51

Лабораторная работа 6

Тема: Структура магнитных дисков

Цель работы: Изучение физической и логической структуры магнитных


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

6.1. Темы для предварительной проработки.

6.1.1. Физическая и логическая структура магнитных дисков.

6.2. Описание работы.

6.2.1. Физическая структура диска.

Все диски как гибкие, так и жесткие организованы одинаковым образом.


Данные всегда записываются на магнитной поверхности диска в виде
концентрических окружностей, называемых дорожками (цилиндрами), а
дорожки в свою очередь делятся радиально на сектора. Гибкие диски
(дискеты) имеют две стороны. Жесткие (фиксированные) диски могут иметь
более двух сторон. Количество информации на одной стороне диска зависит от
числа дорожек (называемого плотностью) и числа секторов на одной дорожке.
Плотность может существенно меняться от диска к диску. Например, диски
двойной плотности имеют 40 дорожек, а диски учетверенной (высокой)
плотности – 80 дорожек. Если число дорожек и число сторон являются
конструктивными особенностями дисков, то расположение, число и размер
секторов задаются программно при первоначальной разметке
(форматировании каждой дорожки диска). Стандартный размер сектора равен
512 байтам.
Файл располагают на таком количестве секторов, которое необходимо,
чтобы вместить его полностью. Только несколько секторов на внешнем ободе
дискеты зарезервированы для специальных нужд. Остальные доступны на
основе правила "первый подошел – первого обслужат". Это означает, что по
мере заполнения диска данными сектора постепенно заполняются по
направлению к центру диска. При уничтожении файла сектора освобождаются
и со временем свободные области становятся разбросанными по диску,
разбивая новые файлы и замедляя доступ к ним для чтения и записи.
52

6.2.2. Логическая структура гибкого диска (флеш-диска).

Процесс форматирования диска делит общее количество секторов на


четыре части, образующие непрерывные сегменты. Эти сегменты (в порядке
расположения на диске) называются загрузочная запись (Boot Record), таблица
размещения файлов (FAT – File Allocation Table), каталог (Directory) и
пространство данных.

6.2.2.1. Загрузочная запись.

На дискетах первый сектор (дорожка 0, сторона 0, сектор 1) содержит


запись начальной загрузки, которая является небольшой программой,
позволяющей компьютеру считывать с дискового накопителя остальные части
ОС, а также данные о структуре диска. Формат сектора представлен в
табл. 6.1.

Таблица 6.1 – Формат загрузочной записи (BOOT)


Смещ. Длина Обознач. Содержимое
+0 3 JMPxxNEAR переход на код загрузки
+3 8 имя компании и версия системы
+0Bh 2 SectSize число байтов на сектор начало BPB
+0Dh 1 ClustSize число секторов на кластер
+0Eh 2 ResSect число резервных секторов +1 (число секторов перед
первой FAT)
+10h 1 FatCnt число копий FAT
+11h 2 RootSiz максимальное число 32-байтовых элементов корневого
каталога
+13h 2 TotSecst общее число секторов в разделе DOS
+15h 1 Media дескриптор раздела (то же, что 1-й байт FAT)
+16h 2 FatSize размер таблицы FAT (число секторов)
+18h 2 TrkSec число секторов на дорожке (цилиндре)
+1Ah 2 HeadCnt число головок чтения/записи (сторон)
+1Bh 2 HidnSec число спрятанных секторов конец BPB
+1Eh начало программы загрузки.

Замечания: подмножество BPB корневого (BOOT) сектора используется


драйверами устройств.

6.2.2.1.1. Адрес области FAT.

Адрес области FAT вычисляется следующим образом:


Адрес FAT = начало раздела + корневой сектор + число резервных
секторов – 1.
53

6.2.2.1.2. Адрес корневого каталога.


Адрес корневого каталого вычисляется следующим образом:
Адрес каталога = начало раздела + корневой сектор + число резервных
секторов + число FAT x число секторов в одной FAT –1.
Необходимо заметить, что при вычислении адресов области FAT и
каталога с использованием трехмерных координат для задания адреса сектора
(головка, цилиндр, сектор) сначала изменяется значение сектора, затем -
головки, последним изменяется номер цилиндра. Для FAT32 корневой каталог
может находится не обязательно после таблицы FAT. Начальный кластер
корневого каталога для FAT32 хранится начиная с адреса +2Сh в BOOT
секторе и занимает 4 байта.
6.2.2.2. Таблица размещения файлов (FAT).
FAT располагается непосредственно после загрузочной записи, начиная с
сектора 2 на дорожке 0 стороны 0 и содержит код формата и полную карту
принадлежности секторов файлам. ОС использует FAT для хранения сведений
о размещении файлов. Каждый элемент таблицы соответствует участку
дискового пространства и содержит код состояния этого участка: занят,
свободен или содержит дефект поверхности и поэтому не используется.
Сохранность таблицы размещения файлов имеет критическое значение для
сохранности всего диска, поэтому на диске хранится две идентичные копии
этой таблицы.
6.2.2.3. Корневой каталог.
Каталог представляет собой таблицу, в которой каждый элемент
соответствует файлу или другому каталогу и содержит информацию об имени
файла, его размере и др.
6.2.2.4. Пространство данных.

Пространство данных используется для хранения собственно данных и


занимает большую часть диска (более 99% и с ростом емкости дисков этот
процент увеличивается).
6.2.3. Логическая структура жесткого диска.
Логическая структура жеского диска включает в себя все элементы
структуры гибкого диска, описанные в п. 6.2.2 и имеющие то же самое
назначение. Однако, помимо этого, жесткий диск содержит в самом первом
секторе (цилиндр (дорожка) 0, головка (сторона) 0, сектор 1) программу,
называемую главной корневой записью. Последняя часть этого сектора
содержит таблицу разделов – 4-элементную таблицу с 16-байтовыми
54

элементами. Этой таблицей манипулирует программа разбития дисков на


разделы. Каждый раздел на жестком диске имеет логическое имя, например, 1-
й раздел – "C:", 2-й раздел – "D:" и т.д.
Во время загрузки ROM-BIOS загружает главную корневую запись в
память и передает ей управление. Эта программа считывает таблицу разделов,
чтобы определить раздел, помеченный как активный. Затем в память
считывается корневой сектор активного раздела и выполняется. В табл. 6.2
приведена структура таблицы разделов.
Таблица 6.2 – Структура главной корневой записи.
Смещ. Длина Содержимое
+0 1BDh программа загрузки и выполнения загрузочного сектора активного
раздела
+1BEh 10h описатель раздела 1 (см. табл. 6.3)
+1CEh 10h описатель раздела 2
+1DEh 10h описатель раздела 3
+1EEh 10h описатель раздела 4
+1FEh 2 55 AA – подпись (сигнатура) таблицы разделов (AA55h)

Таблица 6.3 – Структура описателя раздела


Смещ. Длина Содержимое
+0 1 Boot Flag- флаг загрузки : 0=не активен, 80h = активен.
+1 1 Begin Hd - начало раздела: номер головки (стороны).
+2 2 Begin Sec/Cyl – начало раздела: сектор/цилиндр.
+4 1 System Code – код файловой системы (см. табл. 6.4).
+5 1 Ending Hd – конец раздела : номер головки.
+6 2 Ending Sec/Cyl – конец раздела : сектор/цилиндр последнего сектора.
+8 4 Starting Sector – логический номер начального сектора раздела (адрес в
системе LBA).
+0Ch 4 Num Sectors – размер раздела (число секторов)

Замечания:
Значения цилиндра и сектора занимают 10 и 6 бит соответственно.
Формат слова, задающего значения цилиндра и сектора приведен на рис. 6.1
(ц – разряды значения цилинда, Ц – старший разряд; с – разряды значения
сектора, С – старший разряд).

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
ц ц ц ц ц ц ц ц Ц ц С с с с с с

Рис. 6.1 – Формат упакованного сектора/цилиндра

Относительный сектор 0 совпадает с цилиндром 0, головкой 0, сектором


1. Относительный номер сектора увеличивается сначала по каждому сектору
на головке, затем по каждой головке и наконец по каждому цилиндру.
55

Таблица 6.4 – Значение кодов файловых систем


Код Тип раздела (файловая система, максимальный объем)
00h Неизвестный (неформатированный) раздел
01h DOS FAT12; до 15 Мбайт
02h XENIX root
03h XENIX usr
04h DOS FAT16; до 32 Мбайт
05h (DOS) Extended; до 2 Гбайт
06h DOS FAT16 (Big DOS); до 2 Гбайт
07h OS/2 HPFS или Windows NT NTFS
08h AIX
09h AIX bootable
0Аh OS/2 Boot Manage
0Bh Win95 FAT32; 512 Мбайт-2 Тбайт
0Сh Win95 FAT32 (LBA); 512 Мбайт-2 Тбайт
0Еh Win95 FAT16 (LBA); 32 Мбайт-2 Гбайт
0Fh (Win95) Extended (LBA)
40h Venix 80286
51h Novell
52h Microport
63h GNUHURD
64h Novell Netware 2
65h Novell Netware 3
80h Old MINIX
81h Linux/MINIX
82h LinuxSwap
83h Linux
85h Linux extended
93h Amoeba
94h Amoeba BBT
А5h BSD/386
В7h BSDI fs
В8h BSDI swap
С7h Syrinx
DBh CP/M
Е1h DOS access
E3h DOS R/0
F2h DOS secondary
FFh BBT
56

6.2.4. Чтение сектора диска в память.


Для чтения содержимого требуемого сектора в указанную область памяти
используется функция 2 прерывания 13h. При этом регистры имеют
следующее назначение:
• ah – номер функции;
• dl – номер дисковода: 0 – "A", 1 – "B", 80h – жесткий диск;
• dh – номер головки (стороны);
• ch – номер дорожки (цилиндра);
• cl – номер сектора;
• al – число секторов;
• es – значение сегмента адреса области памяти;
• bx – значение смещения адреса области памяти.
Если функция прерывания выполнена без ошибок, то флаг переноса CF
(младший разряд регистра флагов Flags) установлен в 0 и регистр ah содержит
0. Если флаг переноса установлен в 1, значит была ошибка и регистр ah
содержит код ошибки (байт состояния).

6.3. Порядок выполнения

6.3.1. С помощью функции 2 прерывания 13h прочитать в память


содержимое первого сектора жесткого диска (см. п. 6.2.4).
6.3.2. Проверить правильность выполненной операции.
6.3.3. Используя таблицу разделов жесткого диска (табл. 6.2), определить
число разделов жесткого диска ПК.
6.3.4. Используя табл. 6.3, определить начало раздела (номера головки,
сектора и цилиндра), т.е. адрес корневого BOOT сектора. Вывести на экран
содержимое таблицы разделов.
6.3.5. Используя таблицу 6.3 и 6.4, определить тип файловой системы.
6.3.6. С помощью функции 2 прерывания 13h прочитать в память
содержимое корневого BOOT сектора выбранного раздела и проверить
правильность операции. Вывести на экран содержимое BOOT сектора в
соответствии с табл. 6.1.
6.3.7. Используя табл. 6.1 определить адрес (номера головки, цилиндра и
сектора) области FAT и корневого каталога.

6.4. Особенности программирования

6.4.1. На языке Паскаль.

6.4.1.1. При использовании программного прерывания необходимо:


– подключить модуль Dos, в котором описаны процедура Intr и тип
57

переменной Registers;
– объявить переменную этого типа, например, reg:Registers;
– к регистрам микропроцессора обращаться, как reg.ah, reg.al и т.д.;
– процедуру прерывания 13h вызывать следующим образом:
Intr($13,reg).

6.4.1.2. Область памяти, куда считывается содержимое сектора, удобно


объявить как массив байтов:

var
sect:array[0..511] of byte;

Тогда необходимые значения сегмента и смещения адреса области


памяти можно задать, используя функции Seg и Ofs:

reg.es:=Seg(sect);
reg.bx:=Ofs(sect);

6.4.2. На языке С.

6.4.2.1. При использовании программного прерывания необходимо:


– подключить библиотеку Dos, в котором описаны процедура Int86x и тип
смеси REGS директивой:

#include <dos.h>

– объявить переменные смеси:


union REGS in,out,sr;

– к регистрам микропроцессора обращаться, как in.h.ah, in.x.ax;


– к сегментным регистрам обращаться, как sr.es;
– процедуру прерывания 13h вызывать следующим образом:

int86x(0x13,&in,&out,&sr).

6.4.2.2. Область памяти, куда считывается содержимое сектора, удобно


объявить как массив байтов:

unsigned char buf[512];

Тогда необходимые значения сегмента и смещения адреса области


памяти можно задать, используя функции FP_SEG() и FP_OFF():
58

sr.es=FP_SEG(buf);
in.x.bx=FP_OFF(buf);

6.5. Индивидуальные задания


Индивидуальные задания в данной лабораторной работе определены в
п. 6.3.

6.6. Содержание отчета

6.6.1. Тема лабораторной работы.


6.6.2. Цель работы.
6.6.3. Индивидуальное задание.
6.6.4. Текст программы.
6.6.5. Результаты работы программы.
6.6.6. Выводы.
59

Лабораторная работа 7

Тема: Структура корневого каталога

Цель работы: Изучение структуры корневого каталога и приобретение


практических навыков работы с его отдельными элементами.

7.1. Темы для предварительной проработки

7.1.1. Организация корневого каталога.

7.2. Описание работы

7.2.1. Структура корневого каталога.

Каждый диск c FAT имеет один корневой каталог. Расположение


корневого каталога на диске фиксировано и определяется типом и форматом
диска. Адрес каталога можно определить, используя таблицу разделов (только
для жестких дисков) и таблицу BOOT сектора (см. лаб. раб. 6. Структура
дисков).
Корневой каталог используется для хранения информации о файлах,
включая имя файла, его размер, начальный элемент таблицы размещения,
относящийся к данному файлу, дату и время его создания или модификации и
атрибуты файла (см. табл. 7.1).
Каталог представляет собой таблицу, в которой каждому файлу на диске
(включая подкаталоги и метку тома) соответствует одна запись. Эта запись
имеет размер 32 байта, следовательно на одном секторе размером 512 байтов
помещается 16 записей (элементов) каталога.

Таблица 7.1 – Поля записи каталога


Поле Смещ. Описание Размер Формат
1 0 Имя файла 8 Символы ASCII
2 8 Имя расширения файла 3 Символы ASCII
3 11 Атрибуты 1 Биты байта
4 12 Служебное поле 10 Не используется
5 22 Время создания 2 Слово
6 24 Дата создания 2 Слово
7 26 Начальный кластер 2 Слово
8 28 Размер файла 4 Длинное целое
60

7.2.2. Поля записи каталога.

7.2.2.1. Имя файла.

Первые восемь байтов записи каталога содержат имя файла в формате


ASCII. Если имя файла короче восьми символов, то оно дополняется справа
пробелами (ASCII код – 32). Буквы в имени обязательно должны быть
заглавными.
Существует три особых ситуации, отмечаемых специальными
значениями первого байта в имени файла.
Неиспользуемые элементы каталога имеют первый байт равный 0. DOS
прекращает просмотр каталога, как только встретит такой элемент. Этот же
признак может использовать программист при работе с каталогом как признак
окончания элементов каталога.
Если первый байт имени файла равен E5h, то это означает, что данный
файл уничтожен.
Уничтожение файла на диске, собственно, означает две вещи:
– первый байт имени устанавливается равным E5h;
– все кластеры, относящиеся к данному файлу, помечаются в таблице
размещения файлов как свободные.
Вся прочая информация об этом файле, включая остаток имени, размер
файла, его начальный кластер, остается в каталоге.
Третий особый случай - когда в качестве первого байта имени
используется символ "." (ASCII код – 2h). Этот символ применяется для
указания подкаталога. Если и второй символ имени – точка, тогда этот элемент
каталога соответсвует катологу-родителю текущего, а поле начального
кластера указывает расположение каталога-родителя.

7.2.2.2. Расширение имени файла.

Непосредственно за именем файла следует расширение имени файла,


записанное в формате ASCII. Длина его составляет три байта и подобно имени
файла, если расширение имени состоит меньше чем из трех символов, оно
дополняется пробелами. Однако если имя файла должно состоять хотя бы из
одного символа, расширение может иметь одни пробелы.

7.2.2.3. Атрибуты файла.

Формат байта атрибутов файла представлен в табл. 7.2.


61

Таблица 7.2 – Формат байта атрибутов файла


Биты Значение, когда бит=1
0 Разрешено только чтение
1 Скрытый
2 Системный
3 Метка тома
4 Подкаталог
5 Архив
6 Не используется
7 Не используется

Если разрешено только чтение файла, то в этом случае файл защищен от


любого изменения или удаления с помощью любых операций ОС.
Биты 1 и 2 маркируют файл как скрытый или системный. Файлы
помеченные как скрытые или системные, или и те и другие, нельзя увидеть с
помощью простой операции DOS вроде DIR (чтобы увидеть такой файл
необходимо изменить его атрибут). Атрибут "системный" не имеет какого-то
особого значения, он остался по наследству от операционной системы CP/M и
в DOS абсолютно ничего не делает.
Бит 3 маркирует элемент каталога как метку, что означает, что этот
элемент содержит идентифицирующую метку тома диска. Метка записывается
в полях имени и расширении имени файла, которые в данном случае
расматриваются как объединенное поле. Поля размера и начального кластера
не используются, хотя поля даты и времени используются.
Бит 4 маркирует элемент каталога как подкаталог. Подкаталоги
записываются на диске подобно обычным файлам. Для элемента каталога
такого типа используются все поля, за исключением поля размера файла,
которое равно нулю. Действительный размер подкаталога определяется
просмотром его FAT.
Бит 5, атрибут архива был создан для того, чтобы помочь копированию
большого количества файлов, хранящихся на жестком диске. Этот разряд
сброшен для всех файлов, которые изменились после последнего копирования.
Для дискет атрибут архива практически бесполезен.

7.2.2.4. Служебное поле.

В FAT32 используются для хранения символов «длинного имени файла».


Все 10 байтов поля обычно равны 0 (для файлов в формате «8.3»).

7.2.2.5. Время создания файла или его последней модификации.

Поле 5 содержит 2-байтовое значение, указывающее время создания или


последнего изменения файла. Вместе с полем даты эти два поля могут
62

рассматриваться как одно 4-байтовое беззнаковое число.


Это число может сравниваться с такими же числами в других элементах
каталога на больше, меньше или равно. Формат поля времени и выражения для
выделения часов, минут и 2-секундных единиц (для хранения полных секунд
не хватило одного бита) представлены на рис. 7.1.

15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
часы минуты сек/2

2-секундные единицы (0 – 30)


(t and 001Fh)
минуты (0 – 59) (t and 07E0h shr 5)

часы (0 – 23) (t and F800h shr 11)


Рис. 7.1 – Формат поля времени

7.2.2.6. Дата создания файла или его последней модификации.

Поле 6 содержит 2-байтовое значение, указывающее на дату создания или


изменения файла. Вместе с полем времени эти два поля могут рассматриваться
как одно 4-байтовое беззнаковое число. Это число может сравниваться с
такими же числами в других элементах каталога на больше, меньше или равно.
Формат поля даты и выражения для выделения дня, месяца и года
представлены на рис. 7.2.

15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
год месяц день

день (1 – 31) (d and 001Fh)


месяц (1 – 12) (d and 01E0h shr 5)
год (0 – 127) (d and FE00h shr 9)

Рис.7.2 – Формат поля даты

Для получения истинного значения года надо к значению года,


выделенного из даты прибавить 1980.

7.2.2.7. Номер начального кластера

Кластер - это группа смежных секторов. Величина кластера,которая для


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

Поле 7 – это 2-байтовое значение, которое дает номер начального


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

7.2.2.8. Размер файла.

Последнее поле элемента файла дает размер файла в байтах. Отметим,


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

7.2.3. Чтение сектора диска в память.

Для чтения содержимого требуемого сектора в указанную область памяти


используется функция 2 прерывания 13h. При этом регистры имеют
следующее назначение:
ah – номер функции;
dl – номер дисковода: 0 – "A", 1 – "B", 80h – жесткий диск;
dh – номер головки (стороны);
ch – номер дорожки (цилиндра);
cl – номер сектора;
al – число секторов;
es – значение сегмента адреса области памяти;
bx – значение смещения адреса области памяти.

Если функция прерывания выполнена без ошибок, то флаг переноса CF


(младший разряд регистра флагов Flags) установлен в 0 и регистр ah содержит
0. Если флаг переноса установлен в 1, значит была ошибка и регистр ah
содержит код ошибки (байт состояния).

7.3. Порядок выполнения

7.3.1. С помощью функции 2 прерывания 13h прочитать в память


содержимое первого сектора корневого каталога (адрес корневого каталога
был определен в лаб. раб. 6 Структура дисков).
7.3.2. Проверить правильность выполненной операции.
7.3.3. Для всех файлов этого сектора определить и вывести на экран
следующие данные файлов:
– имя файла и его расширение;
64

– атрибуты;
– номер начального кластера;
– время и дату создания;
– размер.
7.3.4. Сравнить полученную информацию о файлах с информацией,
предоставляемой операционной системой.

7.4. Особенности программирования

7.4.1. На языке Паскаль.

7.4.1.1. При использовании программного прерывания необходимо:


– подключить модуль Dos, в которой описаны процедура Intr и тип
переменной Registers;
– объявить переменную этого типа, например, reg:Registers;
– к регистрам микропроцессора обращаться, как reg.ah, reg.al и т.д.;
– процедуру прерывания 13h вызывать следующим образом:

Intr($13,reg).

7.4.1.2. Область памяти, куда считывается содержимое сектора каталога


удобно объявить как массив записей (см. табл. 7.1):

var
sec_cat:array[1..16] of record
name :array[1..8] of char;
name_e :array[1..3] of char;
atr :byte;
rez :array[1..10] of byte;
time,
date,
n_clast :word;
size :longint
end;

Необходимые значения сегмента и смещения адреса области памяти


можно задать, используя функции Seg и Ofs:

reg.es:=Seg(sec_cat);
reg.bx:=Ofs(sec_cat);
65

7.4.1.3. Для выделения полей времени и даты использовать выражения,


приведенные на рис. 7.1 и рис. 7.2. Символу & в Паскале соответсвтвует
операция AND, а символу >> – Shr (сдвиг вправо).

7.4.2. На языке Турбо-Си.

7.4.2.1. При использовании программного прерывания необходимо:


– подключить библиотеку Dos, в которой описаны процедура int86x и тип
смеси REGS директивой:

#include <dos.h>

– объявить переменные смеси:

union REGS in,out,sr;

– к регистрам микропроцессора обращаться, как in.h.ah, in.x.ax;


– к сегментным регистрам обращаться, как sr.es;
– процедуру прерывания 13h вызывать следующим образом:

int86x(0x13,&in,&out,&sr).

7.4.2.2. Область памяти, куда считывается содержимое сектора каталога


удобно объявить как шаблон структуры (см. табл. 7.1):

struct sec_cat{
unsigned char name[8];
unsigned char name_e[3];
unsigned char atr;
unsigned char rez[10];
unsigned int time;
unsigned int date;
unsigned int n_clast;
unsigned long size ;
};
и определить массив структур

struct sec_cat sec[16];

Тогда необходимые значения сегмента и смещения адреса области


памяти можно задать, используя функции FP_SEG() и FP_OFF():
66

sr.es=FP_SEG(sec);
in.x.bx=FP_OFF(sec);

7.4.2.3. Для выделения полей времени и даты использовать выражения,


приведенные на рис. 1 и рис. 2.

7.5. Индивидуальные задания

Индивидуальные задания в данной лабораторной работе определены в


п.7.3.

7.6. Содержание отчета

7.6.1. Тема лабораторной работы.


7.6.2. Цель работы.
7.6.3. Индивидуальное задание.
7.6.4. Текст программы.
7.6.5. Результаты работы программы.
7.6.6. Выводы.
67

Лабораторная работа 8

Тема: Структура таблицы размещения файлов FAT

Цель работы: Изучение структуры таблицы размещения файлов и


приобретение практических навыков определения последовательностей
кластеров, принадлежащих одному файлу.

8.1. Темы для предварительной проработки

8.1.1.Организация таблицы размещения файлов FAT.

8.2. Описание работы

8.2.1. Назначение FAT.

Диск использует таблицу размещения файлов (FAT) для отведения


дискового пространства файлам и хранения информации о свободных
секторах. Из соображений безопасности на всех дисках хранятся по две копии
FAT. Они хранятся последовательно начиная с первого сектора FAT. Для
дискеты первым сектором FAT будет сектор, следующий за корневым
сектором, т.е. сектор с координатами: дорожка 0, сторона 0, сектор 2. Для
жесткого диска первый сектор FAT определяется с помощью таблицы
разделов и таблицы корневого сектора (см. лаб. раб. 6 Структура дисков).
Число секторов, занимаемых FAT, определяется типом и форматом диска и
указывается в таблице BOOT сектора.
Таблица размещения файлов хранит информацию о каждом кластере
файла на диске. Кластер – это группа смежных секторов. Величина кластера,
которая для разных типов дисков и форматов может быть разной, указывается
в таблице BOOT сектора. Кластеры были введены с целью уменьшения
размера FAT.
8.2.2. Организация FAT.

Каждая позиция в таблице размещения файлов соответствует


определенной позиции кластера на диске. Обычно файл занимает несколько
кластеров и запись в каталоге файлов содержит номер стартового кластера, в
котором находится начало файла. Посмотрев позицию FAT, соответствующую
первому кластеру, DOS находит номер кластера, в котором хранится
следующая порция файла. Этому кластеру соответствует своя запись в FAT,
которая в свою очередь содержит номер следующего кластера в цепочке. Для
последнего кластера, занятого файлом, FAT содержит значения от FFF8h до
FFFFh (FAT16). Неиспользуемым (или освобожденным) кластерам
68

соответствует значение 0, а дефектным секторам – FFF7h. Наконец, значения


от FFF0h до FFF7h приписываются резервным кластерам.
На рис. 8.1 приведены элемент корневого каталога, описывающего файл с
именем MYFILE.TXT, и фрагмент таблицы размещения файлов,
определяющей размещение этого файла на диске:

Элемент корневого каталога (подкаталога)


Номер начального кластера
MYFILE TXT A t d 08 длина

элементы FAT

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
ID FF 03 04 05 FF 00 00 09 0A 0B 15 00 00 00 00

10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
00 00 00 00 00 16 17 19 FF7 1A 1B FFF 00 00 00 00

Рис. 8.1 – Основные концепции FAT

Этот рисунок иллюстрирует основные концепции FAT.


Из него видно, что
– Файл MYFILE.TXT занимает 10 кластеров. Первый кластер – это
кластер 08, последний кластер – 1bh. Цепочка кластеров – 8, 9, 0A, 0B, 15, 16,
17, 19, 1A, 1B. Каждый элемент указывает на следующий элемент цепочки, а
последний элемент содержит специальный код.
– Кластер 18h помечен как плохой и не входит в цепочку распределения.
– Кластеры 6,7, 0Ch-14h и 1Ch-1Fh пусты и доступны для распределения.
– Еще одна цепочка начинается с кластера 2 и кончается кластером 5.
Чтобы узнать имя файла, нужно отыскать элемент оглавления с
начальным номером кластера 02.
Для всех гибких дисков размер ячейки таблицы размещения файлов равен
12 битов, что позволяет обращаться к 4096 кластерам. Тип используемой FAT
указан в таблице разделов.

8.2.3. Чтение сектора диска в память.

Для чтения содержимого требуемого сектора в указанную область памяти


используется функция 2 прерывания 13h.
Если функция прерывания выполнена без ошибок, то флаг переноса CF
69

(младший разряд регистра флагов Flags) установлен в 0 и регистр AH


содержит 0. Если флаг переноса установлен в 1, значит была ошибка и регистр
AH содержит код ошибки (байт состояния).

8.3. Порядок выполнения

8.3.1. С помощью функции 2 прерывания 13h прочитать в память


содержимое первого сектора таблицы размещения файлов (адрес FAT был
определен в лаб. раб. 6 Структура магнитных дисков).
8.3.2. Проверить правильность выполненной операции.
8.3.3. Используя номера начальных кластеров файлов (номер файла
соответствует номеру по списку в журнале группы), полученных в лаб. раб. 7
Структура корневого каталога, по таблице размещения файлов построить
полные цепочки кластеров для этих файлов.

8.4. Особенности программирования.

8.4.1. На языке Паскаль.

8.4.1.1. При использовании программного прерывания необходимо:


– подключить модуль DOS, в котором описаны процедура Intr и тип
переменной Registers;
– объявить переменную этого типа, например, reg:Registers;
– к регистрам микропроцессора обращаться, как reg.ah, reg.al и т.д.;
– процедуру прерывания 13h вызывать следующим образом:
Intr($13,reg).

8.4.1.2. Область памяти, куда считывается содержимое сектора, удобно


объявить как массив байтов:

var
fat:array[0..511] of byte;

Необходимые значения сегмента и смещения адреса области памяти


можно задать, используя функции Seg и Ofs:

reg.es:=Seg(sect);
reg.bx:=Ofs(sect);
70

8.4.2. На языке С.

8.4.2.1.При использовании программного прерывания необходимо:


– подключить библиотеку DOS, в котором описаны процедура int86x и
тип смеси REGS директивой:

#include <dos.h>

– объявить переменные смеси:

union REGS in,out,sr;

– к регистрам микропроцессора обращаться, как in.h.ah, in.x.ax;


– к сегментным регистрам обращаться, как sr.es;
– процедуру прерывания 13h вызывать следующим образом:
int86x(0x13,&in,&out,&sr).

8.4.2.2. Область памяти, куда считывается содержимое сектора, удобно


объявить как массив байтов:
unsigned char buf[512];
Тогда необходимые значения сегмента и смещения адреса области
памяти можно задать, используя функции FP_SEG() и FP_OFF():

sr.es=FP_SEG(buf);
in.x.bx=FP_OFF(buf);

8.5. Индивидуальные задания

Индивидуальные задания в данной лабораторной работе определены в


п.8.3.

8.6. Содержание отчета

8.6.1. Тема лабораторной работы.


8.6.2. Цель работы.
8.6.3. Индивидуальное задание.
8.6.4. Текст программы.
8.6.5. Результаты работы программы.
8.6.6. Выводы.
71

Лабораторная работа № 9

Тема: Системный таймер. Генерация звука

Цель работы: Изучение функций системного таймера и приобретение


практических навыков работы с таймером и динамиком при генерации звука.

9.1. Темы предварительной проработки

9.1.1. Структура и назначение портов микросхемы конфигурации и


системного таймера.

9.2. Описание работы

9.2.1. Системный таймер.

Все компьютеры IBM содержат устройство, называемое системным


таймером. Это устройство подключено к линии запроса на прерывание IRQ0 и
вырабатывает прерывание INT 8h приблизительно 18,2 раза в секунду (точное
значение – 1193180/65535 раза в секунду).
При инициализации BIOS устанавливает свой обработчик для
прерывания таймера. Эта программа каждый раз увеличивает на 1 текущее
значение 4-байтовой переменной, располагающейся в области данных BIOS по
адресу 0040:006Ch – счетчика тиков таймера. Если этот счетчик переполняется
(т.е. прошло более 24 часов с момента запуска таймера), в ячейку 0040:0070h
заносится 1.
Стандартный обработчик прерывания таймера осуществляет также
контроль за работой двигателей НГМД. Если после последнего обращения к
НГМД прошло более 2 секунд, обработчик прерывания выключает двигатель
(ячейка с адресом 0040:0040h содержит время, оставшееся до выключения
двигателя).
Последнее действие, которое выполняет обработчик прерывания таймера,
это вызов прерывания INT 1Ch. После инициализации системы вектор INT
1Ch указывает на команду IRET, т.е. ничего не выполняется. Программа
пользователя может установить собственный обработчик этого прерывания
для того, чтобы выполнить какие-либо периодические действия.
Необходимо отметить, что прерывание INT 1Ch вызывается до сброса
контроллера прерываний, поэтому во время выполнения прерывания INT 1Ch
все аппаратные прерывания запрещены. Для сброса контроллера прерываний
надо в порт 20h записать значение 20h.
На рис. 9.1 показан механизм обработки прерывания таймера.
72

Обработчик INT 8h Обработчик INT 1Ch

Увеличение счетчика по Выполнение действий,


адресу 0040:006Сh, определенных в программе
проверка его переполнения
IRET
Проверка времени последнего
обращения к НГМД, если
оно больше 2 сек, выключ.
двигателя НГМД

Вызов прерывания INT 1Сh

Сброс контроллера
прерываний

IRET

Рис. 9.1 – Алгоритм обработчика прерывания от таймера

Таймер обычно реализуется на микросхеме Intel 8253 (для IBM PC и IBM


XT) или 8254 (для IBM AT и IBM PS/2)

9.2.2. Состав и режимы работы микросхемы таймера.


Таймеры 8253 и 8254 состоят из трех независимых каналов. Каждый
канал содержит регистры:
– состояния канала RS (8 разрядов);
– управляющего слова PSW (8 разрядов);
– буферный регистр OL (16 разрядов);
– регистр счетчика CE (16 разрядов);
– регистр констант пересчета CR (16 разрядов).

Каналы таймера подключаются к внешним устройствам при помощи трех


линий:
GATE – управляющий вход;
CLOCK – вход тактовой частоты;
OUT – выход таймера.

Регистр счетчика CE работает в режиме вычитания. Его содержимое


уменьшается по заднему фронту сигнала CLOCK при условии, что на входе
GATE установлен уровень логической 1. В зависимости от режима работы
73

таймера при достижении счетчиком CE нуля тем или иным способом меняется
выходной сигнал OUT.
Буферный регистр OL предназначен для запоминания текущего
содержимого регистра счетчика CE без остановки процесса счета. После
запоминания буферный регистр доступен программе для чтения.
Регистр констант пересчета CR может загружаться в регистр счетчика,
если это требуется в текущем режиме работы таймера.
Возможны 6 режимов работы таймера. Они разделяются на три типа:
• режимы 0 и 4- однократное выполнение функций;
• режимы 1 и 5 - работа с перезапуском;
• режимы 2 и 3 - работа с автозагрузкой.
В режиме однократного выполнения функций перед началом счета
содержимое регистра констант CR переписывается в регистр счетчика CE по
сигналу CLOCK, если сигнал GATE установлен в 1. В дальнейшем
содержимое регистра CE уменьшается по мере прихода сигналов CLOCK.
Процесс счета можно приостановить, если подать на вход GATE уровень
логического 0. Если затем на вход GATE подать 1, счет будет продолжен
дальше. Для повторения выполнения функции необходима новая загрузка
регистра CR, т.е. повторное программирование таймера.
При работе с перезапуском не требуется повторного программирования
таймера для выполнения той же функции. По фронту сигнала GATE значение
константы из регистра CR вновь переписывается в регистр СЕ, даже если
текущая операция не была завершена.
В режиме автозагрузки регистр CR автоматически переписывается в в
регистр CE после завершения счета. Сигнал на выходе OUT появляется только
при наличии на входе GATE уровня логической 1. Этот режим используется
для создания программируемых импульсных генераторов и генераторов
прямоугольных импульсов (меандров).
В компьютерах IBM PC/XT/AT/PS2 задействованы все три канала
таймера.
Канал 0 используется операционной системой для формирования
временных интервалов. Этот канал работает в режиме 3 и используется как
генератор импульсов с частотой примерно 18,2 Гц. Именно эти импульсы
вызывают аппаратное прерывание INT 8h.
Канал 1 используется для регенерации содержимого динамической
памяти компьютера, поэтому его лучше не трогать. Выходная линия канала
OUT связана с микросхемой прямого доступа к памяти (DMA), и ее импульс
заставляет DMA регенерировать память.
Канал 2 связан с громкоговорителем (динамиком) компьютера и может
быть использован для генерации различных звуков или музыки либо как
генератор случайных чисел. Канал использует режим 3 таймера.
74

9.2.3. Программирование таймера.

Таймеру соответствуют 4 порта ввода/вывода со следующими адресами:


40h – канал 0; 41h – канал 1; 42h – канал 2; 43h – управляющий регистр.
Формат байта управляющего регистра (управляющего слова) приведен в
табл. 9.1.

Таблица 9.1 – Формат управляющего регистра


Биты Значение
0 - двоичные данные;
0 1 - данные в форме BCD (двоично-десятичные).
номер режима:
000 – режим 0 (прерывание от таймера);
001 – режим 1 (программируемый ждущий мультивибратор);
3-1 X01 – режим 2 (программируемый генератор импульсов);
X11 – режим 3 (генератор меандра);
100 – режим 4 (программно-запускаемый одновибратор);
101 – режим 5 (аппаратно-запускаемый одновибратор).
тип операции:
00 – передать значения счетчика в буфер (чтение на лету);
5-4 01 – читать/писать только старший байт;
10 – читать/писать только младший байт;
11 – читать/писать сначала младший байт потом – старший.
номер канала: 00 - канал 0;
00 – канал 0;
7-6 01 – канал 1;
10 – канал 2;
11 – код команды RBC (обратное чтение).

Младший разряд байта определяет формат константы, использующейся


для счета. В двоично-десятичном режиме константа задается в диапазоне 1 –
9999.
Для программирования канала таймера необходимо выполнит
следующую последовательность действий:
• записать в управляющий регистр по адресу 43h управляющее слово;
• требуемое значение счетчика посылается в порт канала (адреса 40h –
42h), причем сначала посылается младший байт, а затем старший байт
значения счетчика.
Сразу после этого канал таймера начинает выполнять требуемую
функцию.
75

9.2.4. Генерация звуков и музыки.


Звуки и музыку на ПЭВМ можно воспроизводить двумя способами:
• с использованием таймера;
• без использования таймера.
В любом случае при поступлении на динамик электрического сигнала
некоторого уровня происходит втягивание мембраны динамика, а при
изменении уровня электрического сигнала – выталкивание. Таким образом
периодический электрический сигнал вызывает вибрацию мембраны
динамика, т.е. генерацию звука той же частоты.
Отметим, что во всех моделях IBM, за исключением IBM PCjr, которая
имеет (помимо динамика) специальный звуковой генератор, громкость звука
не изменяется.

9.2.4.1. Управление динамиком с использованием таймера.

Одно из наиболее распространенных применений таймера – генерация


звуковых сигналов и воспроизведение музыки. Таймер позволяет
воспроизводить музыку в фоновом режиме, т.е. во время работы программы
может звучать музыка. Как уже отмечалось выше, канал 2 микросхемы 8254
связан с динамиком. Однако динамик не просто соединен с выходом OUT
канала 2. Порт 61h также используется для управления динамиком (рис. 9.2).

Системный генератор
F = 1193180 Гц
импульсов
CLOCK0
OUT На IRQ0
КАНАЛ 0
Лог. GATE0 0
1
CLOCK1
OUT Регенерация
КАНАЛ 1
Лог. GATE1 1 памяти
1
CLOCK
OUT
2 КАНАЛ 2
2

Порт 61h
Динамик
7 6 5 4 3 2 1 0 &

Рис. 9.2 – Схема таймера


76

Младший бит этого порта при установке в 1 разрешает работу канала, т.е.
генерацию импульсов для динамика. Дополнительно для управления
динамиком используется бит 1 порта 61h. Если этот бит установлен в 1,
импульсы от канала 2 таймера смогут проходить на динамик.
Системный генератор импульсов (СГИ) независимо от типа и
производительности компьютера IBM вырабатывает импульсы одной и той же
частоты – 1 193 180 Гц.
Таким образом, для включения звука надо выполнить следующие
действия:
• запрограммировать канал 2 таймера на нужную частоту (т.е. загрузить
в регистр счетчика канала значение, равное отношению частоты СГИ и
требуемой частоты звука);
• для включения звука установить в 1 два младших разряда порта 61h.
Поскольку остальные разряда порта 61h используются для других целей,
они должны быть оставлены без изменения.
Для выключения звука надо сбросить два младших разряда порта 61h (не
изменяя опять-таки состояния остальных разрядов).

9.2.4.2. Управление динамиком без таймера.

Для генерации звука без таймера надо сбросить младший бит порта 61h
(запретив тем самым работу канала 2 таймера) и, управляя битом 1 этого
порта, т.е. устанавливая этот бит то в 1, то в 0, формировать импульсы для
динамика. Высота генерируемого звука будет соответствовать периоду
импульсов. Отметим, что этим способом можно генерировать импульсы
любой скважности, что дает больше возможностей для создания различных
звуковых эффектов.

9.2.4.3. Воспроизведение музыки.

Мелодия, как известно, состоит из нот, разделенных или не разделенных


паузами. При проигрывании мелодии необходимо для каждой ноты
программировать соответствующим образом канал 2 таймера и включать
динамик (с помощью порта 61h) на определенное время, равное длительности
ноты. Затем программа должна выключить динамик и выдержать паузу, если
потребуется, перед проигрыванием следующей ноты. В табл. 9.2 приведены
частоты для нот 2-й октавы. Для других октав при понижении или повышении
тона надо значения частот делить или умножать на два.
77

Таблица 9.2. Частоты нот второй октавы


Нота Частота, Гц Нота Частота, Гц
До 267,7 Фа-диез 370,0
До-диез 277,2 Соль 392,0
Ре 293,7 Соль-диез 415,3
Ре-диез 311,1 Ля 440,0
Ми 329,6 Ля-диез 466,2
Фа 349,2 Си 493,9

Плавные переходы тонов производятся за счет непрерывного изменения


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

9.3. Порядок выполнения

9.3.1. Воспроизвести "мелодию" согласно индивидуальному заданию.


Для этого необходимо:
• программировать канал 2 таймера в режиме 3 на нужную частоту
(определяемую нотой, см. табл. 9.2);
• с помощью порта 61h задавать требуемую длительность звучания ноты
и длительность паузы (длительность ноты в секундах задана в
индивидуальном задании после наименования ноты).
9.3.2. Воспроизвести звуковой эффект без использования таймера.

9.4. Особенности программирования

9.4.1. На языке Турбо-Паскаль.


9.4.1.1. Для выделения младшего и старшего байта некоторого слова
удобно использовать функции Lo и Hi:
78

Lo(w) – выделяет младший байт слова w;


Hi(w) – выделяет старший байт слова w, где w:word.
9.4.1.2. Для записи данных в порт используйте предопределенный массив
Port. Например, для записи младшего байта переменной kd в регистр счетчика
канала 2 можно применить выражение Port[$42]:=Lo(kd), где kd – переменная
типа word, задающая коэффициент деления частоты системного генератора на
требуемую частоту.
9.4.1.3. Для установки некоторых битов слова или байта без изменения
остальных битов используйте операцию OR с маской, содержащей 1 в
требуемых битах и 0 в остальных; для сброса – операцию AND с маской,
содержащей 0 в требуемых битах и 1 в остальных.
9.4.1.4. Для выполнения программной задержки используйте процедуру
Delay, описанную в модуле Crt. Аргумент процедуры задается в мс, например,
Delay(1000) означает задержку в 1 секунду.

9.4.2. На языке Турбо-Си.


9.4.2.1. Для записи данных в порт применяются функции записи порта,
которые хранятся в библиотеке <dos.h>. Библиотека подключается директивой

#include < dos.h>

после чего, например, для записи младшего байта переменной kd в


регистр счетчика канала 2 можно применить выражение

outportb(0x42,kd);

где kd – переменная типа int, задающая коэффициент деления частоты


системного генератора на требуемую частоту.
9.4.2.2. Для установки некоторых битов слова или байта без изменения
остальных битов используйте операцию | с маской, содержащей 1 в требуемых
битах и 0 в остальных; для сброса - операцию & с маской, содержащей 0 в
требуемых битах и 1 в остальных.
9.4.2.3. Для выполнения программной задержки используйте функцию
Delay(), описанную в библиотеке stdlib.h, которая подключается директивой
#include <stdlib.h>

9.5. Индивидуальные задания

Выполнить п. 9.3. Варианты мелодий приведены ниже. После ноты


указана ее длительность в секундах.
79

1. До(1), ре(2), ми(3).


2. Си(3), ля(2), соль(1).
3. До-диез(5), соль(1), ре(3).
4. Ми(2), до(3), ля-диез(1)
5. Фа(3), соль-диез(1), фа(3).
6. Фа-диез(2), ре(4), си(2).
7. Соль(1), ля-диез(1), ля(2).
8. Ля(3), до-диез(1), ля-диез(3).
9. Соль-диез(2), си(3), ми(1).
10. Ля-диез(1,5), фа(1), до(2).
11. Си(0,5), до-диез(3), ля-диез(0,5).
12. До(2,5), фа(1), соль(2).
13. Фа(2), фа-диез(2), соль(2).
14. Ре-диез(2,5), ре(2,5), до-диез(2,5).
15. Ми(1), ре(2), до(1).
16. Ре(1,5), ля-диез(2), ре-диез(1).
17. Соль(2), ля(1), до-диез(0,5).
18. Ля(4), ре-диез(1), си(0,5).
19. Ре(3), ми(0,5), фа(0,9).
20. Си(0,5), до(1,3), ля(1,5).

9.6. Содержание отчета

9.6.1. Тема лабораторной работы.


9.6.2. Цель работы.
9.6.3. Индивидуальное задание.
9.6.4. Текст программы.
9.6.5. Результаты работы программы.
9.6.6. Выводы.
80

Лабораторная работа 10

Тема: Работа видеосистемы ПЭВМ в текстовом режиме

Цель работы: Изучение особенностей функционирования видеосистемы в


текстовом режиме и приобретение практических навыков работы с
видеомонитором в этом режиме.

10.1. Темы для предварительной проработки

10.1.1. Организация видеопамяти в текстовом режиме.


10.1.2. Структура видеоадаптера.

10.2. Описание работы

Все видеосистемы используют буфер, представляющий собой


двупортовую память на плате видеоконтроллера (адаптера), в который
микропроцессор записывает данные для изображения на экране. Экран
периодически обновляется путем сканирования этих данных со стороны
дисплея. Размер и расположение буфера в адресном пространстве зависит от
типа видеоконтроллера и режима экрана. Когда в буфере хранится несколько
изображений экрана, каждое отдельное изображение экрана называют
дисплейной страницей.

10.2.1. Монохромный адаптер.

Имеет 4К байт памяти на плате, начиная с адреса B0000h (т.е.


B000:0000h). Этой памяти хватает для хранения одной 80-символьной
страницы текста.

10.2.2. Цветной графический адаптер (CGA).

CGA имеет 16К байт памяти на плате, начиная с адреса памяти B8000h.
Этого достаточно для отображения одного графического экрана, или для
отображения от четырех до восьми экранов текста в зависимости от числа
символов в строке – 40 или 80.

10.2.3. Графические адаптеры (EGA, VGA и SVGA).

Адаптеры EGA VGA и SVGA работают в текстовом режиме аналогичным


образом. Память адаптеров, помимо ее использования в качестве видеобуфера,
хранит также описания формы символов. Стартовый адрес видеобуфера
81

программируемый, поэтому буфер с адресами A000h – BFFFh используется


для улучшенных графических режимов, а начиная с адресов B000h и B800h –
для режимов, совместимых соответственно с монохромным и цветным
текстовыми режимами.
Доступное число страниц зависит как от режима экрана, так и от
количества имеющейся памяти. Вследствие своей сложности EGA, VGA и
SVGA имеют ПЗУ на 16К байт, которое заменяет и расширяет процедуры
BIOS работы с терминалом. Начало области ПЗУ – адрес C000:0000h.

10.2.4. Содержание буфера в текстовом режиме.

В текстовых режимах устанавливается следующее соответствие между


памятью видеоконтроллера и изображением на экране. В начале памяти
записываются данные о символе, находящемся на первой строке в левом углу,
затем данные об остальных символах первой строки, затем данные о символах
второй строки начиная слева и т.д.
При выводе текста различные видеосистемы работают одинаково. Для
экрана отводится 4000 байт, так что на каждую из 2000 позиций экрана (25
строк × 80 символов) приходится 2 байта. Первый байт содержит код ASCII
символа. Аппаратура дисплея преобразует номер кода ASCII в связанный с
ним символ и посылает его изображение на экран. Второй байт (байт
атрибутов) содержит информацию о том, как должен быть выведен данный
символ. Для монохромного дисплея он устанавливает, будет ли данный
символ подчеркнут, выделен яркостью или негативом, либо применяется
комбинация этих атрибутов. В цветных системах байт атрибутов
устанавливает основной и фоновый цвета символа, а также признак его
мигания.
При записи данных прямо в буфер монитора значительно повышается
скорость вывода на экран.

10.2.5. Видеоатрибуты символов.

Когда дисплей установлен в текстовом режиме в любой из видеосистем,


каждой позиции символа на экране отводится два байта памяти. Первый байт
содержит код ASCII символа, а второй – видеоатрибут символа. Цветной
адаптер может выводить в цвете как символ, так и всю область, отведенную
данному символу (фоновый цвет).
Монохромный адаптер ограничен только черным и белым цветом, но он
может генерировать подчеркнутые символы, чего не может делать цветной
адаптер.
EGA может делать все, что и остальные системы, а также многое другое.
82

В частности, на улучшенном дисплее он выводит подчеркнутые цветные


символы, поскольку матрица изображения символов 8×14 предоставляет
такую возможность.
На рис. 10.1 приведен формат байта видеоатрибута
7 6 5 4 3 2 1 0
M R G B I R G B
* Цвет фона Цвет символа

Рис. 10.1 – Байт видеоатрибута

R – вхождение красного цвета :0=не входит; 1=входит


G – вхождение зеленого цвета: 0=не входит; 1=входит
B – вхождение синего цвета: 0=не входит; 1=входит
I – интенсивность: 0=символ неяркий; 1=символ яркий;
М – мерцание: 0=символ не мерцает; 1=символ мерцает.
* – возможен режим, когда этот бит будет определять не мигание
символа, а интенсивность цвета фона.
Как цвет символа, так и цвет фона определяются как сумма трех
основных цветов – красного, зеленого и синего. Все возможные цвета
приведены в табл. 10.1.

Таблица 10.1 – Цвета символов и фона


IRGB Цвет
0000 черный
0001 синий
0010 зеленый
Цвет фона

0011 голубой (циан)


0100 красный
0101 розовый (мажента)
Цвет символа

0110 коричневый
0111 серый
1000 темно-серый
1001 ярко-синий
1010 светло-зеленый
1011 светло-голубой
1100 светло-красный
1101 светло-розовый
1110 желтый
1111 белый

Монохромные символы используют байт атрибутов несколько по


другому. Как и с атрибутами цвета, биты 0-2 устанавливают цвет символа, а
биты 4-6 – фона. Эти цвета могут быть только белым и черным.
83

Нормальный режим – белый на черном, когда биты 0-2 установлены в


111, а биты 4-6 установлены в 000. Негативное изображение создается
обратными значениями битов. Символы выводятся с повышенной яркостью,
когда бит 3 установлен в 1. Во всех случаях установка в 1 бита 7 дает мигание
символов.

10.2.5. Регистры видеоконтроллера.

Во всех видеосистемах контроллер видеотерминала CRTC выполнен на


базе микросхемы Motorola 6845 (EGA VGA и SVGA используют заказные
микросхемы, основанные на 6845).
Микросхема 6845 имеет 25 управляющих регистров, пронумерованных от
0 до 18h. Первые 10 регистров фиксируют горизонтальные и вертикальные
параметры дисплея. Эти регистры автоматически устанавливаются BIOS при
изменении режима экрана. Не советуем экспериментировать с этими
регистрами, поскольку можно испортить терминал. Регистры имеют размер 8
бит, но некоторые связаны в пары, чтобы хранить 16-битовые величины. Пары
регистров Ah–Bh и Eh–Fh устанавливают форму и местоположение курсора.
Пара Ch–Dh управляет начальным адресом вывода на дисплей.
Регистр 14h определяет, какая линия сканирования в строке символа
используется для подчеркивания.
Доступ ко всем 25 регистрам осуществляется через один и тот же порт,
адрес которого для монохромного адаптера – 3B5h, для цветного адаптера и
PCjr – 3D5h. EGA VGA и SVGA использует один из этих двух адресов в
зависимости от того, присоединен к нему цветной или монохромный монитор.
Для записи в регистр надо сначала в регистр адреса, расположенный в порте
3B4h (3D4h для цветного), послать номер требуемого регистра. Тогда
следующий байт, посланный в порт с адресом 3B5h (3D5h), будет записан в
этот регистр.
У CGA и MDA есть еще три регистра которые важны для программистов.
Они имеют адреса 3B8h, 3B9h и 3BАh для монохромного и 3D8h, 3D9h и
3DAh – для цветного адаптера. Первый устанавливает режим экрана, второй
связан в основном с установкой цветов экрана, а третий сообщает полезную
информацию о статусе дисплея.
EGA VGA и SVGA распределяет эти функции между микросхемой
контроллера атрибутов (адрес порта 3C0h) и двумя микросхемами контроллера
графики (адреса портов 3CCh-3CFh). Контроллер атрибутов содержит 16
регистров палитры EGA, пронумерованных от 00h до 0Fh. Эти регистры могут
содержать 6-битовые коды цветов, когда подключен улучшенный цветный
дисплей, поэтому могут быть использованы любые 16 цветов из набора 64.
84

10.2.6. Режимы дисплея.

Возможные режимы приведены в табл. 10.2.

Таблица 10.2 – Режимы графического адаптера


Режим Тип Формат Размер Кол-во цветов Тип
символов видеопамяти
0 ТХТ 40х25 8х8* 16/8 (Shades) 4-х слойная
1 ТХТ 40х25 8х8* 16/8 4-х слойная
2 ТХТ 80х25 8х8* 16/8 (Shades) 4-х слойная
3 ТХТ 80х25 8х8* 16/8 4-х слойная
4 Gr 320х200 8х8 4 Линейная
5 Gr 320х200 8х8 4 (Shades) Линейная
6 Gr 640х200 8х8 2 Линейная
7 TXT 80х25 9х14* 3 (B/W/Bold) Линейная
08h-0Сh резерв
0Dh Gr 320х200 8х8 16 4-х слойная
0Eh Gr 640х200 8х8 16 4-х слойная
0Fh Gr 640х350 8х14 3 (B/W/Bold) Линейная
10h Gr 640х350 8х14 4 или 16 4-х слойная
llh Gr 640х480 8х16 2 Линейная
12h Gr 640х480 8х16 16 4-х слойная
13h Gr 320х200 8х8 256 Линейная
14h-7Fh Режимы нестандартных расширений BIOS для VGA и SVGA

Функция 0 прерывания 10h устанавливает режим дисплея. В AL должен


находиться номер режима согласно табл. 10.2.

10.3. Порядок выполнения работы

10.3.1.2. Установить текстовый (80×25) режим работы дисплея.


10.3.1.2. В соответствии с индивидуальным заданием вывести в заданное
место экрана слова с требуемыми видеоатрибутами.

10.4. Особенности программирования

10.4.1. На языке Турбо-Паскаль.

10.4.1.1. При использовании программного прерывания необходимо:


• подключить модуль Dos, в котором описаны процедура Intr и тип
переменной Registers;
• объявить переменную этого типа, например, reg:Registers;
85

• к регистрам микропроцессора обращаться, как reg.al;


• процедуру прерывания 10h вызывать следующим образом:
Intr($10,reg).

10.4.1.2.Буфер видеоконтроллера в текстовом режиме можно представить


в виде массива:

buff:array[0..3999] of byte absolute $B800:$0000.

Тогда для вывода на экран символа в i-ю строку и в j-й столбец


необходимо по адресу buff[i*160+j*2] записать ASCII код символа, а по
следующему – байт видеоатрибута.

10.4.1.3. Если слова заданы в виде строки символов s типа string, то для
определения ASCII кода k-й буквы строки можно воспользоваться
выражением ord(s[k]).

10.4.2. На языке Турбо-Си.

10.4.2.1. При использовании программного прерывания необходимо:


• подключить библиотеку dos, в которой описана процедура int86 и тип
смеси REGS директивой

#include <dos.h>

• объявить смесь REGS оператором

union REGS in,out

где in – имя структуры входных регистров


out – имя структуры выходных регистров
к 8разрядным регистрам как in.h.al или out.h.ah,
к 16разрядным регистрам адресуются как in.x.ax или out.x.ax
• процедуру прерывания 10h вызывать следующим образом:

int86(0x10,&in,&out);

10.4.2.2. Обращение к буферу видеоконтроллера в текстовом режиме


осуществляется аналогично обращению к ячейкам ОЗУ и ПЗУ с помощью
дальних указателей, объявленных
86

char far * uk;

Тогда для занесения начального адреса видеобуфера необходимо


записать:
uk=(char far *)0xB8000000;
а для вывода на экран символа в i-й строке и в j-м столбце записать

*(uk + i*160+j*2)=kod;
*(uk + i*160+j*2+1)=attr;

где kod и attr -переменные типа char,описывающие ASCII код и атрибут


символа соответственно.

10.5. Индивидуальные задания

1. Первые два слова красным цветом на белом фоне; третье слово синим
высокой интенсивности; четвертое слово зеленое мигающее на красном.
2. Первые три слова синим цветом на красном фоне; второе слово
высокой интенсивности.
3. Второе слово магента на черном фоне; пятое слово мигает; седьмое
слово белым низкой интенсивности.
4. Первые три слова синим на белом фоне; четвертое слово красным
высокой интенсивности; шестое слово зеленым мигающим.
5. Седьмое слово белым черном фоне; пятое слово красным цветом
высокой интенсивности; первые три слова синим цветом мигают.
6. Два слова цвета циан на красном фоне; третье слово мигает; первое
слово коричневым высокой интенсивности.
7. Первые два слова синим высокой интенсивности; третье слово мигает;
четвертое слово зеленое на красном фоне.
8. Первое слово черным на белом фоне; четвертое слово красным на
зеленом фоне мигает; шестое слово коричневым высокой интенсивности.
9. Второе слово розовое высокой интенсивности; третье слово циан на
зеленом фоне; пятое слово мигает.
10. Первые два слова синим низкой интенсивности; третье слово мигает;
четвертое слово красным цветом на белом фоне.
11. Четные слова голубым по розовому; нечетные – красным по черному;
последнее пятое слово мигает.
12. Первое слово черным на белом фоне; четвертое слово зеленое на
красном фоне; остальные – голубым на черном фоне.

Указанные слова вывести на экран в строку и в столбец, номера которых


87

совпадают с номером студента в журнале.

10.6. Содержание отчета

10.6.1. Тема лабораторной работы.


10.6.2. Цель работы.
10.6.3. Индивидуальное задание.
10.6.4. Текст программы.
10.6.5. Результаты работы программы.
10.6.6. Выводы.
88

Лабораторная работа 11

Тема: Управление курсором, цветом бордюра, регистрами палитры,


создание специальных символов

Цель работы: Получение практических навыков управления курсором,


цветом бордюра и регистрами палитры путем программирования регистров
адаптера, создания специальных символов.

11.1. Темы для предварительной проработки

11.1.1. Назначение регистров видеоадаптера.


11.1.2. Описание символов в текстовом режиме.

11.2. Описание работы

11.2.1. Управление курсором.

Курсор служит двум целям. Во-первых, он служит указателем места на


экране, в которое операторы программы посылают свой вывод. Во-вторых, он
обеспечивает видимую точку отсчета на экране для пользователя программы.
Только для второго применения курсор должен быть видимым. Когда курсор
невидим (выключен), он все равно указывает на позицию экрана. Это важно,
поскольку любой вывод на экран, поддерживаемый операционной системой,
начинается с текущей позиции курсора.
Курсор генерируется микросхемой контроллера дисплея 6845. Эта
микросхема имеет регистры, устанавливающие размер и положение курсора.
Микросхема 6845 обеспечивает только мерцающий курсор, хотя имеются
программные способы создания немерцающего курсора. Частота мерцания
курсора не может быть изменена. В графических режимах курсор не
выводится, хотя символы позиционируются на экране теми же процедурами
установки курсора, что и в текстовых режимах.
Когда видеосистема работает в режиме, допускающем несколько
дисплейных страниц, каждая страница имеет свой собственный курсор и при
переключении между страницами восстанавливается позиция курсора,
которую он занимал, когда было последнее обращение к восстанавливаемой
странице. Некоторые режимы дисплея позволяют иметь до 8 дисплейных
страниц и соответствующие им позиции курсора хранятся в наборе восьми 2-
байтовых переменных в области данных BIOS, начиная с адреса 0040:0050h. В
каждой переменной младший байт содержит номер столбца, отсчитывая от 0, а
старший байт содержит номер строки, также отсчитывая от 0. Когда число
страниц меньше 8, используются переменные, расположенные в более
89

младших адресах памяти.

11.2.1.1. Управление координатами курсора (позиционирование).

Для курсора могут быть установлены абсолютные координаты или


координаты относительно его текущей позиции. Абсолютные координаты
могут меняться в пределах 25 строк и 80 (иногда 40) столбцов.
Регистры 0Eh и 0Fh микросхемы 6845 хранят положение курсора.
Адресный регистр имеет порт 3D4h (данные заносятся в порт 3D5h). Старший
байт хранится в регистре 0Eh, младший – в регистре 0Fh.
Вы можете изменить их значение и курсор передвинется в
соответствующую позицию экрана, но прерывания вывода на экран DOS и
BIOS будут игнорировать вашу установку и вернут курсор в старое
положение. Это происходит потому, что каждый раз при вызове этих
прерываний они восстанавливают регистры курсора, используя 2-байтовое
значение, хранящееся в области данных BIOS. В этой области, начиная с
адреса 0040:0050h, могут находиться до восьми таких значений, дающих
текущее положение курсора для каждой из страниц дисплея. Первая позиция
соответствует странице 0, вторая – странице 1 и т.д. Младший байт каждой
переменной содержит номер столбца, а старший номер строки. Как столбцы,
так и строки нумеруются с нуля. Процедура низкого уровня должна
модифицировать и эти значения, чтобы изменить состояние курсора
полностью.
Позиция курсора хранится в регистрах 0Eh и 0Fh как число от 0 до 1999,
что соответствует 2000 (25×80) позициям экрана. Не спутайте эту систему
нумерации с позициями видеобуфера от 0 до 3999, где каждый символ
сопровождается еще байтом атрибутов (для получения эквивалентного
указателя на позицию курсора надо сдвинуть указатель видеобуфера на 1 бит
вправо). Обращаем также ваше внимание на то, что не надо менять местами
старший и младший байты: в регистре 0Eh – старший, а 0Fh – младший.
Курсор функционирует совершенно независимо от видеопамяти. Это
значит, что при прямой адресации в память дисплея программное обеспечение
должно координировать перемещения курсора с вставкой нового символа в
буфер.
Программы иногда читают и сохраняют текущее положение курсора, с
тем чтобы можно было временно перевести курсор в командную строку, а
затем вернуть его в исходную позицию. Процедура чтения позиции курсора
(из регистров и области данных BIOS) аналогична процедуре установки
курсора.
90

11.2.1.2. Управление формой курсора.

Курсор может меняться по толщине от тонкой линии до максимального


размера, отводимого под символ. Он строится из коротких горизонтальных
отрезков, верхний из которых называется начальной строкой курсора, а
нижний – конечной строкой. Для монохромного дисплея под каждый символ
отводится 14 строк, пронумерованных от 0 до 13 начиная сверху. Промежутки
между символами обеспечиваются двумя верхними строками и тремя
нижними. Большинство символов располагается в строках 2-10, хотя хвостики
некоторых символов достигают линий 12 и 13, в то время как подчеркивание
занимает одну двенадцатую строку. На 200-строчном цветном дисплее для
каждого символа отводится только 8 строк, а символ рисуется в верхних семи
строках. Эти 8 строк пронумерованы от 0 до 7 начиная сверху, и нормальный
курсор формируется одной строкой 7. (Отметим, что на цветном дисплее нет
подчеркивания, поскольку использование для этого строки 7 привело бы к
тому, что символы сливались бы с расположенными под ними.) Цветной
дисплей высокого разрешения использует 14-строчный монохромный вариант,
когда он работает в режиме разрешения, и 8-строчный вариант при работе в
одном из цветных графических режимов.
Курсор может быть сформирован любой комбинацией прилегающих
отрезков. Для монохромного дисплея он занимает все отведенное под символ
место, когда начальная строка равна 0, а конечная строка равна 13 (для
графического дисплея значение конечной строки должно быть равно 7). Если
значения начальной и конечной строк совпадают, то возникает однострочный
курсор. Если номер конечной строки меньше, чем номер начальной, то курсор
становится невидимым.
BIOS хранит 2-байтовую переменную по адресу 0040:0060h, которая
содержит текущие значения начальной и конечной строк. Первый байт
содержит значение конечной строки, а второй – начальной.

11.2.1.3. Создание альтернативных типов курсора.

Все прерывания операционной системы, связанные с выводом на экран,


используют курсор. Вы можете изменить форму курсора или сделать курсор
невидимым путем задания адреса больше 2000 или задания номера начальной
строки больше номера конечной строки. Возможны альтернативные типы
курсора, когда вывод на экран осуществляется с помощью методов прямого
отображения в память. При этом "истинный" курсор выключается, поскольку
он не будет адресовать символы в определенную позицию видеобуфера.
Вместо этого создается "фальшивый" курсор с помощью байта атрибутов.
Наиболее эффективным методом является установка атрибута вывода в
негативе для символа, на который указывает курсор. Для черно-белого экрана
91

в качестве этого атрибута следует применять код ASCII 112. Другой способ -
заставить символ, на который указывает курсор, мигать. В этом случае надо
просто добавить 128 к текущему значению атрибута, чтобы символ начал
мигать, и вычесть 128, чтобы прекратить мигание. Третий способ – установить
для символа режим подчеркивания (код ASCII 1). И наконец, в программах,
использующих командную строку, можно рассмотреть применение
специального графического символа, который следует за последним символом
командной строки, такого, как стрелки, выводимые кодами ASCII 17 или 27.
Отметим, что когда программа получает ввод в нескольких режимах, вы
можете помочь идентифицировать текущий режим за счет особого типа
курсора.

11.2.2. Управление цветом границы экрана (бордюра ).

Граница символьного экрана (за пределами адресной области) может


иметь цвет, отличный от фонового цвета центральной части экрана. Может
быть использован любой из 16 цветов для CGA или любой из 64 цветов для
EGA. Для цветного графического адаптера CGA биты 0-3 порта 3D9h (регистр
выбора цвета) устанавливает цвет границы, когда экран находится в текстовом
режиме.
Для адаптера EGA цвет бордюра задается регистром 11h блока атрибутов
адаптера. При подключении улучшенного графического дисплея возможно
задание любого из 64 цветов. Для задания цвета бордюра в EGA необходимо
выполнить следующие действия:
• прочитать порт 3DAh для инициализации адресного регистра;
• задать номер регистра 11h путем его записи в порт 3C0h;
• задать цвет засылкой байта данных в порт 3C0h (анализируются 6 бит);
• разрешить вывод на экран путем установки 5 бита адресного регистра
блока в 1 (засылка кода 20h в порт 3C0h). Изменение цвета бордюра
используется в драйверах клавиатуры для индикации переключения между
русским и латинским алфавитом.

11.2.3. Создание специальных символов.

Только монохромный адаптер не может выводить символы вида,


заданного самим программистом. Цветной адаптер поддерживает 128
символов, определяемых пользователем, PCjr – 256, а EGA – 1024, из которых
одновременно доступно 512. Для цветного адаптера ROM-BIOS содержит
данные для разрисовки только первых 128 символов набора ASCII (с номерами
от 0 до 127). Следующие 128 символов недоступны для вас, пока вы не
создадите их, используя описанную здесь технику.
92

11.2.3.1. Адаптер CGA.

Символы для графического адаптера и PCjr описываются с помощью


матрицы 8*8 точек. Данные для каждого символа содержатся в восьми байтах.
Каждый байт содержит установку для точек одного ряда, начиная с верхнего,
причем старший бит (номер 7) соответствует самой левой точке в ряду. Когда
соответствующий бит равен 1, точка высвечивается. Для описания символа вы
должны определить правильные последовательности битов для восьми байтов
и поместить их в последовательные ячейки памяти.
Все 128 символов вместе требуют 1024 байта, хотя вовсе не обязательно,
чтобы были описаны все символы. Специальный вектор прерывания
(постоянный указатель в младших адресах памяти) указывает адрес первого
байта первого символа расширенного набора, т.е. символ номер 128. Когда в
позицию символа в видеобуфере посылается код 128, просматриваются и
выводятся первые восемь байт. Если номер символа 129, то выводятся байты с
девятого по шестнадцатый и т.д. Номер этого вектора прерывания 1Fh и он
расположен по адресу 0000:007Сh. Поместите значение смещения в младшее
слово (сначала младший байт), а адрес сегмента – в старшее слово (сначала
младший байт) и измените 8 байт описания любого символа. Отметим, что
можно определять символы с большими номерами кодов, не отводя памяти
для символов с меньшими номерами; надо просто, чтобы вектор указывал на
некоторый адрес, который меньше, чем адрес начала блока, содержащего
данные для описания символов.

11.2.3.2. Адаптеры EGA, VGA, SVGA.

Для EGA картина немного сложнее, хотя и более гибкая. При


инициализации текстового режима один из двух наборов символов (8×8 или
8×14) в зависимости от разрешающей способности дисплея копируется из ПЗУ
EGA в битовую плоскость 2 видеобуфера. Эта часть буфера разбита на блоки,
причем стандартный набор символов помещается в блок 0. В EGA определены
четыре блока для описания символов, в VGA, SVGA – 8 блоков. Каждый блок
содержит описание 256 символов (ASCII коды 0–255). Независимо от размера
матрицы описания символа, под каждый символ отводится 32 байта, поэтому
каждый блок символов имеет размер 8 Кбайт (32*256). Когда имеется более
одного блока символов, бит 3 байта атрибутов определяет, из какого блока
будут браться данные для описания символа.
Какой из блоков будет необходим – зависит от установки битов регистра
выбора набора символов, адрес порта которого 3C5h.
Предварительно надо записать 3 в порт 3C4h, чтобы указать требуемый
регистр, после чего в 3C5h записать байт данных. Для EGA биты 1,0 дают
93

номер блока символов, который берется, когда бит 3 равен 0, а биты 3,2 дают
номер блока символов, когда бит 3 байта атрибутов равен 1; для VGA, SVGA
соответственно биты 1,0,4 определяют номер блока, когда бит 3 равен 0, а
биты 3,2,5 – когда бит 3 равен 1. В случае равенства номеров блоков
возможность использования двух наборов символов отсутствует, но можно
задать любой набор. В стандартных настройках BIOS все эти биты равны 0,
поэтому используется только блок 0. Однако ничто не может помешать вам
поместить свои символы в любую нужную вам позицию в любом блоке. Для
этого необходимо выполнить следующие действия:
• записать 6 в порт 3CЕh (адрес многоцелевого регистра графического
контроллера);
• записать 1 в порт 3CFh (Перевод видеосистемы в графический режим);
• записать 2 в порт 3C4h (адрес регистра маски битовой плоскости);
• записать 4 (0100b) в порт 3C5h (разрешить доступ к 2-й битовой
плоскости);
• записать 4 в порт 3C4h (адрес регистра режима использования
видеопамяти);
• записать 6 в порт 3C5h (отмена режима чет/нечет, который сцеплял
битовые плоскости 0–1 и 2–3 в текстовом режиме);
После разрешения записи с учетом номера блока (Blok), ASCII кода
символа (Kod) и числа байт в описании символа изменяется N байт, начиная с
адреса
Adr = A000h:Blok*2000h+kod*32.
После чего необходимо восстановить регистры и перевести видеосистему
в текстовый режим:
• записать 4 в порт 3C4h (адрес регистра режима);
• записать 2 в порт 3C5h (установка режима чет/нечет);
• записать 2 в порт 3C4h (адрес регистра маски битовой плоскости);
• записать 3 (0011b) в порт 3C5h (разрешить доступ к 0 и 1-й битовым
плоскостям);
• записать 6 в порт 3CЕh (адрес многоцелевого регистра);
• записать Eh в порт 3CFh (перевод в текстовый режим).
Содержимое N байт определяется требуемым изображением символа.
На рис. 11.1 приведено рукописное изображение буквы "И" для матрицы
(8×14).
Обратите внимание на то, что сверху, снизу и справа (или слева) от
изображения символа нужно оставить пустые строки для разделения символов
в строке и между строками. Данная буква описывается следующими 14
байтами: 00, 00, 88, 88, 88, 88, 88, 88, 98, AA, 44, 00, 00, 00.
Если вы изменили стандартный набор символов (Blok=0), то можно в
любой момент восстановить его из ПЗУ.
94

. . . . . . . .
. . . . . . . .
■ . . . ■ . . .
■ . . . ■ . . .
■ . . . ■ . . .
■ . . . ■ . . .
■ . . . ■ . . .
■ . . . ■ . . .
■ . . ■ ■ . . .
■ . ■ . ■ . ■ .
. ■ . . . ■ . .
. . . . . . . .
. . . . . . . .
. . . . . . . .

Рис. 11.1 – Изображение буквы И

Для цветного адаптера и PCjr для изменения вектора прерывания 1 Fh


применяйте функцию 25h прерывания 21h. При входе DS:DX должны
указывать на первый байт блока данных.
Для адаптера EGA характерна функция 11h прерывания 10h, которая
манипулирует набором символов. Эта функция может быть очень сложной,
когда она применяется для создания специальных режимов экрана, но ее
основное назначение достаточно простое. Существуют четыре подфункции.
Когда AL равен 0, данные, определяемые пользователем, переносятся из
памяти в блок описания символов 2-й битовой плоскости.
Когда AL равен 1 или 2, наборы данных для символов 8×14 и 8×8
соответственно копируются из ПЗУ в блок описания символов.
Для VGA когда AL равен 4, набор символов 8×16 копируется из ПЗУ в
блок символов. Когда AL равен 3, функция устанавливает назначение блока в
регистре выбора набора символов, как описано выше. В последнем случае
надо просто поместить соответствующие данные в BL и вызвать функцию.
Для загрузки данных из ПЗУ поместите номер блока в BL и выполните
функцию. Для загрузки своих данных надо, чтобы ES:BP указывали на них,
число передаваемых символов должно быть в CX, смещение (номер символа)
в блоке должно быть в DX, число байтов на символ – в BH, а номер блока – в
BL. После этого вызывайте прерывание 10h.
Вы можете получить информацию о статусе имеющегося набора
символов с помощью подфункциии 30h (регистр AL) функции 11h (регистр
AH) прерывания 10h. У этой подфункции нет входных регистров, а при
возврате в СХ содержится число байтов, отведенных для каждого символа, а в
DX – сколько рядов точек символ занимает на экране (оба этих параметра
зависят как от размера символа, так и от вертикального разрешения экрана).
95

11.3. Порядок выполнения работы.

11.3.1. Определить ASCII коды символов, составляющих фамилию и имя


студента.
11.3.2. Задать байтовые описания указанных символов при рукописном
шрифте и описания личного иероглифа студента.
11.3.3. Составить программу, выполняющую следующие действия.
11.3.3.1. Устанавливает цвет границы экрана в соответствии с
индивидуальным заданием.
11.3.3.2. Перемещает курсор в позицию, номер строки которой
соответствует месяцу рождения студента, а номер столбца соответствует
номеру студента в журнале.
11.3.3.3. Изменяет форму курсора путем изменения номера начальной и
конечной строки.
11.3.3.4. Определяет число байт на символ при описании символа.
11.3.3.5. Изменяет байтовые описания символов фамилии и имени
студента.
11.3.3.6. Выводит в заданную позицию курсора фамилию и имя студента
рукописными буквами, завершая строку личными иероглифом.
11.3.3.7. Изменяет цвет фона, программируя 0 регистр палитры.

11.4. Особенности программирования.

11.4.1. На языке Турбо-Паскаль.


11.4.1.1. Для обращения к портам ПЭВМ применяются предопределенные
массивы Port и PortW. Например, для записи адреса регистра битовой
плоскости в порт 3C4h используем выражение Port[$3C4]:=2.
11.4.1.2. При использовании программного прерывания необходимо:
• подключить модуль Dos, в котором описаны процедура Intr и тип
переменной Registers;
• объявить переменную этого типа, например, reg:Registers;
• к регистрам микропроцессора обращаться, как reg.al;
• процедуру прерывания 10h вызывать следующим образом:
Intr($10,reg).

11.4.1.3. Описание изображения символа удобно представить с помощью


типизированной константы. Например, описание символа, изображенного на
рис. 11.1, имеет следующий вид:
const
ms:array[1..14] of byte=($00,$00,$88,$88,$88,$88,$88,
$88,$98,$AA,$44,$00,$00,$00);
96

11.4.1.4. Если слова заданы в виде строки символов s типа string, то для
определения ASCII кода k-й буквы строки можно воспользоваться
выражением ord(s[k]).
11.4.1.5. Блок буфера видеоконтроллера можно представить в виде
массива:
block:array[0..32*256] of byte absolute $A000:$0000.

11.4.2. На языке Турбо-Си.


11.4.2.1. Для обращения к портам ПК применяются функции чтения и
записи порта,которые хранятся в библиотеке < dos.h>. Библиотека
подключается директивой

#include < dos.h>

после чего, например, для записи значения 0Eh в порт 3D5h используется
выражение:

outportb(0x3D5,0x0E);

11.4.2.2. При использовании программного прерывания необходимо:


• подключить библиотеку Dos, в котором писаны процедура int86x и тип
смеси REGS директивой:
#include <dos.h>
• объявить переменные смеси:

union REGS in,out,sr;

к регистрам микропроцессора обращаться, как in.h.ah, in.x.ax;


к сегментным регистрам обращаться, как sr.es;
для доступа к регистру BP необходимо объявить структуру

struct REGPACK inb;

после чего к регистру обращаться, как inb.r_bp;


процедуру прерывания 10h вызывать следующим образом:

int86x(0x10,&in,&out,&sr).

11.4.2.3. Описание изображения символа удобно представить при


инициализации массива. Например, описание символа, изображенного на
рис. 11.1, имеет следующий вид:
97

char ms[14]={0x00,0x00,0x88,0x88,0x88,0x88,0x88,
0x88,0x98,0xAA,0x44,0x00,0x00,0x00};

4.2.4. Обращение к буферу видеоконтроллера аналогично обращению к


ячейкам ОЗУ с помощью дальних указателей, объявленных

char far * uk;

Тогда для занесения начального адреса видеобуфера необходимо


записать:

uk=( char far *)0xA0000000;

11.5. Индивидуальные задания


По второй цифре номера студента по журналу выбрать параметры
формируемого изображения.

Таблица 11.1 – Варианты индивидуальных заданий


Параметры Номер в журнале
0 1 2 3 4 5 6 7 8 9
w_str 0 1 2 3 4 5 6 7 8 9
k_str 13 12 11 10 8 9 10 11 12 13
col_fon 30 31 32 33 34 35 36 37 38 39
col_for 10 9 8 7 6 5 4 3 2 1

где: n_str и k_str – начальная и конечная строка позиции курсора в знакоместе.


col_for – цвет фона (0 регистр палитры)
col_for – цвет границы экрана.

11.6. Содержание отчета

11.6.1. Тема лабораторной работы.


11.6.2. Цель работы.
11.6.3. Индивидуальное задание.
11.6.4. Текст программы.
11.6.5. Результаты работы программы.
11.6.6. Выводы.
98

Лабораторная работа 12

Тема: Работа со страницами

Цель работы: Получение практических навыков манипуляции с экраном,


используя переключение страниц.

12.1. Темы для предварительной проработки

12.1.1. Организация видеопамяти в текстовом режиме.


12.1.2. Назначение регистров видеоадаптера.

12.2. Описание работы

Сдвиг экрана и разбиение на страницы – это два способа переноса блока


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

12.2.1. Сдвиги экрана путем изменения данных в видеобуфере.

12.2.1.1. Вертикальный сдвиг всего экрана – тривиальная задача,


поскольку правая граница одной строки в памяти продолжается левой
границей следующей строки. Сдвиг всего содержимого видеобуфера на 160
байт вверх по памяти (80 символов в строке × 2 байта на символ) приводит к
сдвигу экрана вниз на одну строку.

12.2.1.2. Горизонтальный сдвиг экрана.

Видеобуфер представляет собой одну длинную строку. Поэтому если


каждый символ буфера сдвинуть на 10 байт вниз, то суммарный эффект будет
состоять в том, что самые левые 5 символов каждой строки будут передвинуты
в последние 5 позиций предыдущей строки. Таким образом, весь экран будет
99

сдвинут влево на 5 позиций, передвигая 5 ненужных столбцов в правую часть


экрана. Все, что после этого остается, – это очистить правые 5 столбцов или
запомнить их "невидимыми" за пределами экрана символами, которые
хранятся в ОЗУ или вводятся пользователем.

12.2.3. Страничная организация видеопамяти.

Поскольку все видеосистемы, кроме монохромного дисплея, имеют


достаточно памяти для нескольких видеобуферов, одновременно могут быть
сконструированы несколько экранов, каждый из которых может быть выведен
в нужный момент. Вместо того чтобы передвигать данные в видеопамяти,
монитор посылает данные из другой области видеопамяти. Число доступных
страниц может меняться в зависимости от видеосистемы и режима дисплея.
В режимах 0–3 и 7 имеется 8 страниц. BIOS хранит в своей области
данных однобайтовую переменную, указывающую, какая из страниц
выводится в данный момент. Диапазон значений этой переменной от 0 до 7.
Она расположена по адресу 0040:0062h.
Дисплейные страницы выбираются за счет изменения точки видеопамяти,
начиная с которой монитор принимает данные. Эта точка памяти
устанавливается регистрами 0Ch (старший байт) и 0Dh (младший байт)
микросхемы 6845, которые называются регистрами стартового адреса. Для
программирования регистров стартового адреса необходимо записать номер
регистра в адресный регистр блока (послать номер в порт 3D4h, после чего
записать данные в порт 3D5h. Значения адресов раздела страниц для буфера,
начинающегося с В800h, представлены в табл. 12.1.

Таблица 12.1 – Начальные адреса страниц в видеопамяти.


№ страницы Начальный адрес страницы в видеопамяти
Для страниц 40*25 Для страниц 80*25
0 0000h 0000h
1 0400h 0800h
2 0800h 1000h
3 0C00h 1800h
4 1000h 2000h
5 1400h 2800h
6 1800h 3000h
7 1C00h 3800h

12.2.4. Аппаратный сдвиг.

Поскольку страницы текста прилегают друг к другу в видеобуфере,


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

реально в буфере. Вместо этого экран начинает показывать содержимое


буфера, начиная с различных точек, и тем самым создается иллюзия сдвига.
Этот метод называется аппаратным сдвигом.
Аппаратный сдвиг достигается за счет изменения стартового адреса
вывода. Это число, указывающее на символ в видеобуфере, который будет
выводиться в левом верхнем углу экрана. Добавление 80 к этому числу
"сдвигает" весь экран на одну строку вверх, а вычитание 80 – на одну строку
вниз. В режиме с 40 символами в строке надо вместо 80 прибавлять или
вычитать 40.
Отметим, что регистр стартового адреса не считает байты атрибутов,
поэтому вы должны вычислять адреса памяти по-другому, а не так, как при
прямом отображении в память. Имейте также в виду, что, несмотря на наличие
разрывов памяти между границами страниц (96 байт между 80-символьными
страницами и 48 байт между 40-символьными страницами), микросхема 6845
пропускает эти области и сдвиг непрерывно происходит с одной страницы на
следующую. Аппаратный сдвиг происходит настолько быстро, что может
оказаться необходимым вставить процедуру задержки, чтобы пользователь
имел возможность увидеть, насколько сдвинулся экран.
BIOS хранит текущее значение регистра стартового адреса в переменной
в своей области данных. Эта двухбайтовая переменная расположена по адресу
0040:0004h.

12.2.5. Создание разделенного экрана

Адаптеры EGA VGA, SVGA позволяет на аппаратном уровне создавать


так называемый разделенный экран в алфавитно-цифровом режиме. Верхнюю
часть экрана будем называть экраном A, а нижнюю – экраном B, как это
показано на рисунке (рис. 12.1).

0000h Область данных Стартовый


Экран А экрана В адрес
0FFFh Область данных
экрана А
Экран В

а) структура разделенного экрана б) отображение экранов на видеопамять

Рис. 12.1 – Организация разделенного экрана

На рис. 12.1.б показано отображение экраном на видеопамять размером в


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

(0Ch и 0Dh) блока управления ЭЛТ. Данные экрана B всегда расположены в


видеобуфере по адресу 0000h.
Для организации работы с разделенным экраном используется регистр
сравнения строк (18h) блока управления ЭЛТ. Необходимо сначала послать в
порт 3D4h 18h (адрес регистра ), а затем в порт 3D5h – номер строки, которая
является границей двух экранов. В этом блоке содержится внутренний счетчик
выведенных в текущем кадре строк растра, значение которого постоянно
сравнивается со значением регистра сравнения строк. Как только их значения
становятся равными, генератор адреса памяти сбрасывается в 0. После этого
генератором адреса формируются последовательные адреса, начиная с
нулевого адреса до завершения вывода кадра.
Экран B может плавно перемещаться вверх/вниз по экрану монитора для
чего необходимо во время обратного вертикального хода луча производить
соответствующие изменения значения в регистре сравнения строк. В экране B
не может производиться аппаратный скроллинг, т.к. для его организации
используются регистры старшей и младшей составляющих начального адреса.

12.3. Порядок выполнения работы.


12.3.1. Написать программу, выполняющую следующие действия:
12.3.1.1. Ожидает в цикле нажатие алфавитно-цифровой клавиши, и при
нажатии клавиши выводит набранный пользователем текст путем прямого
отображения в видеобуфер в виде "бегущей строки".При этом символы
вначале заполняют строку слева направо до 80 позиций, а при дальнейшем
наборе текста вся строка сдвигается влево на 1 символ, последний введенный
символ записывается в 80 позицию, первый символ строки исчезает. Для
организации "бегущей строки" использовать аппаратный сдвиг экрана. Номер
строки выбирается из индивидуального задания.
12.3.1.2. Загружает текстовый файл объемом 32 Кбайта в видеобуфер,
начиная с адреса B800:0000h и при нажатии клавиш 0-7 выводит на экран
текущую видеостраницу.
12.3.1.3. При нажатии клавиши СТРЕЛКА ВВЕРХ и СТРЕЛКА ВНИЗ
выполняет скроллинг экрана на одну строку вверх или вниз соответственно.
12.3.1.4. Создает разделенный экран путем программирования регистра
сравнения строк, и по клавишам СТРЕЛКА ВВЕРХ и СТРЕЛКА ВНИЗ
выполняет скроллинг экрана А.

12.4. Особенности программирования.


12.4.1. На языке Турбо-Паскаль.
12.4.1.1. Буфер видеоконтроллера в текстовом режиме можно представить
в виде массива:
buff:array[0..3999] of byte absolute $B800:$0000.
102

Тогда для вывода на экран символа в i-ю строку и в j-й столбец


необходимо по адресу buff[i*160+j*2] записать ASCII код символа, а по
следующему – байт видеоатрибута.
12.4.1.2. Для чтения текстового файла с перезаписью в видеобуфер
необходимо:
• объявить файловую переменную, например,
var
f:text;
• связать файловую переменную с именем текстового файла на диске
(внешним именем) с помощью процедуры Assign, например, для файла на
диске D в каталоге CAT c именем FIL.PAS надо указать:
Assign(f, 'D:CAT\FIL.PAS');
• открыть файл для чтения процедурой Reset: Reset(f);
• читать посимвольно в цикле из текстового файла в переменную
например, ch (ch:char) c помощью процедуры Read и с переписыванием кода
прочитанного символа и его атрибута в видеобуфер Buff (см. п. 4.1.1):
Read(f,ch);
buff[2*i]:=ord(ch);
buff[2*i+1]:=$07; {белый на черном}
i - номер прочитанного символа (начиная с 0);
• читать из текстового файла до тех пор, пока не встретится символ
"конец файла" (функция Eof(f) при этом примет значение true);
• после обнаружения конца файла закрыть файл с помощью процедуры
Close: Close(f).

12.4.2. На языке Турбо-Си.


12.4.2.1. Обращение к буферу видеоконтроллера в текстовом режиме
осуществляется аналогично обращению к ячейкам ОЗУ с помощью дальних
указателей, объявленных
char far * uk;
Тогда для занесения начального адреса видеобуфера необходимо за
писать: uk=( char far *)0xB8000000;
а для вывода на экран символа в i-й строке и в j-м столбце записать:
* (uk + i*160+j*2)=kod; * (uk + i*160+j*2+1)=attr;
где:kod и attr – переменные типа char, описывающие ASCII код и атрибут
символа соответственно.

12.4.2.2. Загрузка файла в видеобуфер выполняется следующим образом:


• открытие файла и установка указателя на начало файла по выражению
fp=fopen(fname, "rb" );
где:fp – указатель, который должен быть описан как FILE *fp;
103

fname-имя загружаемого файла,


"rb"-режим чтения байтового файла.
• чтение в цикле байт из файла по выражению
*uk=getc(fp);
где *uk - указатель на видеобуфер, который должен быть описан как
char far *uk
• закрытие файла функцией
fclose(fp);
Для работы с указанными функциями необходимо подключить
библиотеку stdio.h директивой
#include <stdio.h>.

12.5. Индивидуальные задания

В табл. 12.2 по второй цифре номера студента по журналу выбрать


параметры "бегущей строки" и разделенного экрана.

Таблица 12.2 – Варианты индивидуальных заданий


Параметры Номер в журнале
0 1 2 3 4 5 6 7 8 9
N_s 5 6 7 8 9 10 11 12 13 14
BEG_S 0 1 2 3 4 10 9 8 7 6
END_S 60 65 70 75 80 75 70 65 60 50
N_CR 7 8 9 10 11 12 13 14 15 16
где: N_S – номер строки дисплея, где организуется "бегущая трока";
BEG_S,END_S – начальная и конечная позиция "бегущей строки".
N_CR – номер строки дисплея, которая является границей
разделенного экрана.

12.6. Содержание отчета

12.6.1. Тема лабораторной работы.


12.6.2. Цель работы.
12.6.3. Индивидуальное задание.
12.6.4. Текст программы.
12.6.5. Результаты работы программы.
12.6.6. Выводы.
104

Лабораторная работа 13

Тема: Работа в графическом режиме. Управление экраном, цветом.


Изображение точки

Цель работы: Приобретение практических навыков работы с


видеомонитором в графическом режиме.

13.1. Темы для предварительной проработки


13.1.1. Назначение и режимы работы адаптера в графическом режиме.
13.1.2. Организация видеобуфера в графическом режиме.

13.2. Описание работы

Цветной графический адаптер имеет три графических режима, PCjr –


шесть, а EGA – семь, VGA, SVGA – множество недокументированных
режимов. Требования к размеру памяти существенно различаются для
доступных режимов в зависимости от разрешения экрана и числа цветов. В
своих улучшенных графических режимах EGA использует память дисплея
совсем по-другому, чем остальные видеосистемы, но он точно эмулирует их
методы работы с памятью в трех общих режимах.

13.2.1. Цветной графический адаптер CGA и система PCjr.

Сначала рассмотрим цветной адаптер и систему PCjr. Два цвета (черный


и белый) требуют только один бит памяти для каждой точки на экране. Четыре
цвета занимают 2 бита, а 16 цветов – 4 (8-цветные режимы не используются,
поскольку три бита, требующиеся для их представления, нельзя удобно
разместить в битах байта). Для всех режимов по вертикали имеется 200 точек.
Низкое разрешение (используемое только на PCjr) выводит 160 точек по
горизонтали, среднее разрешение – вдвое больше (320 точек), а высокое
разрешение – еще вдвое больше (640 точек).
В двух- и четырехцветном режимах PCjr имеет возможность выбрать
любой из 16 доступных цветов. Цветной адаптер более ограничен. В
двухцветном режиме он всегда ограничен белым и черным, а в
четырехцветном режиме только цвет фона может выбираться из 16 цветов, в
то время как основной цвет нужно брать только из двух предопределенных
палитр. Палитра 0 содержит коричневый, зеленый и красный цвета, а палитра
1 – циан, магента и белый.
В отличие от текстовых данных в режимах 4-6 и 8-Аh графические
данные разбиты на видеостранице на части. В большинстве режимов данные
разбиваются на две части, при этом первая половина буфера содержит данные
105

для четных строк экрана, а вторая – для нечетных (строки нумеруются начиная
с верха экрана вниз).

13.2.2. Графические адаптеры EGA, VGA, SVGA.

Адаптер EGA обеспечивает возможность работы в различных


видеорежимах совместно с цветными или монохромными мониторами с
цифровыми входами. Кроме того, адаптер обеспечивает возможность работы
со световым пером. Адаптер может функционировать в нескольких
графических режимах (используются 4 битовые плоскости) и обладает
возможностью загрузки в видеопамять шрифтов в алфавитно-цифровых
режимах.
Адаптеры VGA, SVGA имеют аналоговые выходы (уровень сигнала
каждого аналогового выхода R, G, B задает интенсивность соответствующей
составляющей цвета), их архитектура является развитием архитектуры EGA, в
которую добавлен блок цифро-аналогового преобразователя, поэтому VGA,
SVGA эмулируют все режимы EGA, а также имеют собственные графические
режимы высокого разрешения и качества цветопередачи, для реализации
которых требуются значительные обьемы видеопамяти. Структурная схема
видеоадаптеров представлена на рис 13.1

ROM Блок управ-


(расширение К монитору
ления ЭЛТ
BIOS) (CRTC)

видео
RGB
К системной шине

Интерфейс
Блок монитора
Внешний синхрониза-
интерфейс ции (SEQ)
Видеопамять

Цифро-
аналоговый
Графический
преобразова-
контроллер
тель (DAC)
(CRAPH)
Блок
атрибутов
Графический (ATTRIB)
сопроцессор
Внутренняя шина

Рис. 13.1 – Архитектура видеоадаптера


106

13.2.2.1. Основные компоненты.

Блок управления электронно-лучевой трубкой (CRT Controller) управляет


сигналами горизонтальной и вертикальной синхронизации, начальным
адресом вывода в видеобуфере, положением и формой курсора и др.
Блок синхронизации (Sequencer) генерирует тактовые сигналы и сигналы
для синхронизации доступа к видеопамяти. Данным устройством
обеспечивается возможность доступа к видеопамяти со стороны процессора в
специально выделенные моменты времени в промежутке между интервалами
времени, необходимыми для доступа к видеопамяти в процессе регенерации
изображения на экране дисплея. В этом же блоке содержатся регистры
управления записью данных в битовые плоскости.
Графический контроллер (Graphics Controller) направляет данные из
памяти в контроллер атрибутов и в процессор.
В графических режимах данные из видеопамяти пересылаются в
микросхему контроллера атрибутов последовательно. В текстовых режимах
данные пересылаются в параллельной форме в обход графического
контроллера. Для быстрого изменения изображения на экране дисплея
аппаратурой обеспечивается возможность записи 32 бит данных за один цикл
памяти (8 бит для каждой плоскости), а дополнительная логика позволяет
процессору записывать данные в дисплейную память не придерживаясь
границ байтов.
Контроллер атрибутов (Attribute controller) выполняет первую ступень
индексации цвета в текстовых и графических режимах, т.е. расширяет 4-х
битовый код цвета, получаемый из видеопамяти (индекс цвета) до 6-ти
битового кода, который записан в одном из 16 регистров палитры. Этой же
микросхемой выполняются действия по управлению мерцанием и
подчеркиванием. Контроллер получает данные из видеобуфера и преобразует
их в управляющие сигналы, подаваемые на вход монитора.
Цифро-аналоговый преобразователь (DAC) появился в адаптере VGA,
выполняет вторую ступень индексации цвета в текстовых и графических
режимах, т.е. расширяет 8-ми битовый код цвета, получаемый из контроллера
атрибутов или непосредственно видеопамяти (индекс цвета) до 18-ти
разрядного кода (по 6 бит на каждую цветовую составляющую – R, G, B),
который записан в одном из 256 регистров PEL. Управляющие сигналы цвета
подаются на вход монитора в аналоговой форме по линиям R, G и B.
Видеобуфер (Display Buffer – называется также видеопамятью или
памятью адаптера). Видеобуфер является двухпортовой памятью, поэтому
доступен как со стороны видеоадаптера (чтение информации и вывод на
монитор), так и со стороны процессора в режимах записи и чтения.
В адресном пространстве процессора под видеобуфер выделено 2
107

сегмента памяти – A0000h и B0000h. Так как современные графические


режимы высокого разрешения и качества цветопередачи требуют существенно
больших объемов видеопамяти, то эта видеопамять отображается в область
старших адресов. Адресация видеобуфера со стороны процессора зависит от
видеорежимов: в монохромных режимах – начинается с сегментного адреса
B0000h; в цветных текстовых – с адреса B8000h; в цветных графических – с
адреса А0000h.
Базовая система ввода/вывода видеоадаптера (BIOSV) находится в
памяти специального ПЗУ установленного на плате адаптера. BIOSV
объединяется с системной базовой системой ввода/вывода. Здесь размещаются
шрифты, используемые для генерации символов и управляющие программы
видеоадаптера. Начальный адрес ПЗУ – C0000h.
13.2.2.2.Работа в графическом режиме 16/64 (10h)

Для графического режима 10Н память организована в виде 4-х битовых


плоскостей, каждая из которых организована так же, как для черно-белого
режима высокого разрешения: когда байт данных посылается в определенный
адрес видеобуфера, каждый бит соответствует точке на экране, причем они
описывают горизонтальный сегмент строки и бит 7 соответствует самой левой
точке. Записываются четыре такие битовые плоскости, соответствующие
одним и тем же адресам, в видеобуфере. Это отводит каждому пикселю 4 бита,
что позволяет описывать 16 цветов.
EGA может использовать первую ступень индексации цветов с помощью
регистров палитры. При этом становятся доступными 64 цвета, кодировка для
которых rgbRGB. Составляющие r, g, b – слабые интенсивности 1/3 от max,
RGB – нормальные интенсивности2/3 от max. Различные комбинации создают
64 оттенка. Как всегда, 111111b соответствует белому цвету, а 000000b –
черному.
VGA, SVGA могут использовать вторую ступень индексации цветов с
помощью регистров PEL, что позволяет задавать 218 оттенков.
13.2.2.3. Назначение регистров.

13.2.2.3.1. Регистры блока синхронизации


Назначение регистров блока синхронизации представлены в табл. 13.1.
Адресный – регистр, указывающий на один из регистров блока
синхронизации, расположенный по адресу 3С4h. В этот регистр загружается
двоичный номер регистра блока синхронизации, в который будет
производится запись. Номера регистров, помещаемые в адресный регистр
представлены в поле "Индекс" табл. 13.1, после чего по адресу 3С5h
выполняется запись/чтение информации в выбранный регистр.
108

Таблица 13.1 – Регистры блока синхронизации


№ Наименование Порт Индекс Режим
1 Адресный (Address) 3C4h - W
2 Инициализации (Reset) 3C5h 00h W
3 Тактового режима (Clocking mode) 3C5h 01h W
4 Маски бит. плоскости(Map mask) 3C5h 02h W
5 Выбора символьного блока 3C5h 03h W
(Character map select)
6 Режима использования памяти 3C5h 04h W
(Memory mode)

13.2.2.3.2. Регистры блока управления ЭЛТ представлены в табл. 13.2.

Таблица 13.2 – Назначение регистров блока управления ЭЛТ


Ин- Режим
№ Наименование Порт
декс в EGA
1 Адресный (Address) 3?4h - W
2 Общей длительность строки (horizontal total) 3?5h 00h W
3 Длит. участка отобр. в строке (Horizontal display enable end) 3?5h 01h W
4 Начала горизонтального гашения (Start horizontal blank) 3?5h 02h W
5 Окончания горизонт. гашения луча (End horizontal blank) 3?5h 03h W
6 Начала горизонт. обратного хода луча (Start horizontal retrace) 3?5h 04h W
7 Оконч. горизонт. обратного хода луча (End horizontal retrace) 3?5h 05h W
8 Общего количество строк растра в кадре (vertical total) 3?5h 06h W
9 Переполнения (Overflow) 3?5h 07h W
10 Установки строки растра (Preset row scan) 3?5h 08h W
11 Вертикального размера символа (Max scan line) 3?5h 09h W
12 Начала курсора (Cursor start) 3?5h 0Ah W
13 Окончания курсора (Cursor end) 3?5h 0Bh W
14 Старшей составляющей начального адреса (Start address high) 3?5h 0Ch R/W
15 Младшей составляющей начального адреса (Start address low) 3?5h 0Dh R/W
16 Старшей составляющей позиции курсора (Cursor location high) 3?5h 0Eh R/W
17 Младшей составляющей позиции курсора (Cursor location low) 3?5h 0Fh R/W
18 Начала верт. обратного хода луча (Vertical retrace start) 3?5h 10h W
19 Старшей составляющей адреса светового пера (Light pen high) 3?5h 10h R
20 Окончания обратного хода луча (Vertical retrace end) 3?5h 11h W
21 Младшей составляющей адреса светового пера (Light pen low) 3?5h 11h R
22 Длительности участка отображения в кадре (Vertical display end) 3?5h 12h W
23 Смещения (Offset) 3?5h 13h W
24 Положения символа подчеркивания (Underline location) 3?5h 14h W
25 Начала вертикального гашения луча (Start vertical blank) 3?5h 15h W
26 Окончания вертикального гашения луча (End vertical blank) 3?5h 16h W
27 Управления режимом (Mode control) 3?5h 17h W
28 Сравнения строк (Line compare) 3?5h 18h W
? = B в монохромных режимах и D в цветных
109

Эксперименты с регистрами блока управления ЭЛТ, которые формируют


изображение кадра, могут привести к поломке видеотерминала.

13.2.2.3.3. Регистры графического контроллера представлены в табл. 13.3.

Таблица 13.3 – Назначение регистров графического контроллера


N Наименование Порт Индекс
1 Регистр позиции графики 1 (Graphics 1 Position ) 3СС -
2 Регистр позиции графики 2 (Graphics 2 Position ) 3СA -
Адресный регистр графического контроллера (Graphics 1 & 3CE -
3
2 Address)
4 Цвета (Set/Reset) 3CF 00
5 Разрешения цвета (Enable Set/Reset) 3CF 01
6 Сравнения цвета (Color Compare) 3CF 02
7 Вращения данных (Data rotate) 3CF 03
8 Выбора плоскости для чтения (Read Map Select) 3CF 04
9 Выбора режима (Mode) 3CF 05
10 Многоцелевой (Miscellaneous) 3CF 06
Регистр независимости от значения плоскости при чтении 3CF 07
11
(Color Don't Care)
12 Битовой маски (Bit Mask) 3CF 08

13.2.2.3.4. Регистры контроллера атрибутов представлены в табл. 13.4.

Таблица 13.4 – Назначение регистров контроллера атрибутов


№ Наименование Порт Индекс
1 Адресный регистр (Address Register) 3C0h
2 Регистры палитры (Palette Registers) 3C0h 00 - 0Fh
3 Регистр управления режимом (Mode Control Register) 3C0h 10h
4 Регистр управления цветом бордюра (Overscan Color 3C0h 11h
Register)
5 Регистр разрешения отображения битовой плоскости (Color 3C0h 12h
Plane Enable Register)
6 Горизонтального сдвига пикселей (Horisontal Pel Panning 3C0h 13h
Register)
7 Регистр выбора цвета (только VGA) 3C0h 14h

13.2.2.4. Рисование точек.

Учитывая организацию графической информации в видеобуфере вывод


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

одной точки были изменены один, два и четыре бита соответственно. Для этих
операций необходимы огромные затраты процессорного времени, поэтому
графическое программное обеспечение, как правило, работает очень медленно.
Тщательное обдумывание часто позволяет сразу установить все биты одного
байта, а не обращаться к одному и тому же байту 4 или 8 раз.
Функция Сh прерывания 10h устанавливает точку. DX содержит строку, а
CX – столбец. Они отсчитываются от 0. Код цвета помещается в AL. Отметим,
что содержимое AX будет разрушено при выполнении прерывания.
В то время как цвет палитры помещается в младшие биты AL, старший
бит также имеет значение. Если он равен 1, то над цветом производится
операция исключающего ИЛИ с текущим цветом. Напомним, что операция
исключающего ИЛИ устанавливает бит только в том случае, если из двух
сравниваемых битов установлен только один. Если оба сравниваемые бита
равны 1 или оба равны 0, то результат будет 0.
На низком уровне мы имеем возможность прямого доступа к
видеобуферу (отображение в память). Сначала вы должны вычислить
смещение точки а – внутри буфера и б – внутри байта, содержащего биты,
относящиеся к данной точке. После этого битовые операции обеспечат
соответствующую установку.
В режимах Dh, Eh и 10h память разбита на 4 битовые плоскости. Каждая
плоскость организована таким же образом, как для черно-белого режима
высокого разрешения цветного адаптера, когда байт данных посылается в
определенный адрес видеобуфера, каждый бит соответствует горизонтальному
сегменту линии, а бит 7 – самой левой точке. Выводятся четыре такие битовые
плоскости, относящиеся к одним и тем же адресам в видеобуфере. Это
приводит к тому, что каждая точка описывается четырьмя битами (давая 16
цветов), причем каждый бит находится в отдельном байте отдельной битовой
плоскости.
Но как вы можете записать 4 различных байта данных, расположенных по
одному и тому же адресу? Ответ на этот вопрос состоит в том, что вы не
посылаете последовательно четыре байта по этому адресу. Вместо этого один
из трех режимов записи позволяет изменить все 4 байта на основании одного
байта данных, полученного от процессора. Влияние данных, посланных
процессором, зависит от установки нескольких регистров, включающих два
регистра маски, которые определяют, на какие биты и в каких битовых
плоскостях будут изменяться биты. Для понимания этих регистров мы должны
сначала разобраться с четырьмя регистрами задвижки (latch register). Они
содержат данные для четырех битовых плоскостей в той позиции, к которой
было последнее обращение. (Заметим, что термин "битовая плоскость"
используется как для целой области видеобуфера, так и для и однобайтового
буфера, временно хранящегося в регистре задвижки). Когда процессор
111

посылает данные по определенному адресу, эти данные могут изменить или


полностью сменить данные регистра задвижки, а впоследствии именно данные
из регистра задвижки записываются в видеобуфер. Каким образом данные
процессора влияют на регистр задвижки, зависит от режима записи, а также
установки некоторых других регистров. При чтении адреса из видеобуфера
регистры задвижки заполняются четырьмя байтами из четырех битовых
плоскостей по данному адресу. Регистрами задвижки легко манипулировать,
производя с их содержимым различные логические операции, что позволяет
устраивать различные графические трюки.
Регистр маски битов (смотри блок графического контроллера регистр
08h) и регистр маски (смотри блок синхронизации регистр 02h) карты
действуют на регистры задвижки, защищая определенные биты или битовые
плоскости от изменения под действием данных, поступающих от процессора.
Установка бита регистра маски битов в 0 маскирует этот бит во всех четырех
битовых плоскостях, делая соответствующую точку недоступной для
изменения. Однако поскольку оборудование работает в байтовых терминах,
реально "неизменяемые" биты перезаписываются в четыре битовые плоскости.
Данные для этих маскируемых битов хранятся в регистрах задвижки, поэтому
программа должна быть уверена, что текущее содержимое регистров задвижки
относится к правильному адресу. Поэтому перед записью в видеобуфер надо
сначала считывать из него. Биты 0-3 регистра маски карты соответствуют
битовым плоскостям 0-3. Старшие 4 бита регистра не используются. Когда
биты 0-3 равны 0, соответствующие битовые плоскости не меняются при
операциях записи. Посылаемые в видеобуфер данные могут быть
модифицированы и логически обработаны вместе с данными, хранящимися в
регистрах-задвижках с помощью регистра вращения данных (регистр 03h
блока графического контроллера) Биты 0-2 регистра вращения определяют
число разрядов, на которое производится циклический сдвиг данных
процессора влево при записи данных в видеобуфер. Для записи данных без
сдвига этот бит должен быть установлен в 0. При записи задают логическую
функцию данных процессора с данными регистров задвижек.
Значение битов:
00 – данные не меняются
01 – логическое "И"
10 – логическое "ИЛИ"
11 – исключающее "ИЛИ"
Операция сдвига выполняется раньше логической операции.
Это свойство используется по разному в различных режимах записи.
Три режима записи и два режима чтения устанавливаются регистром
установки режима(смотри блок графического контроллера регистр 05h).Режим
записи устанавливается в битах 0 и 1, как число от 0 до 2. Бит 2 должен быть
112

равным 0, также как и биты 4–7.


Бит 3 устанавливает один из двух режимов чтения из видеобуфера.
Этот бит может быть 0 или 1. BIOS EGA устанавливает режим записи в 0,
режим чтения в 0.

13.2.2.4.1. Режим записи 0.

В простейшем случае режим записи 0 копирует данные процессора в


каждую из четырех битовых плоскостей. Пусть, например, по определенному
адресу видеобуфера послано 11111111b и разрешены все биты и все битовые
плоскости (т.е. ничто не маскированно описанными выше регистрами масок).
Тогда каждый бит во всех четырех плоскостях будет установлен в 1, так что
цепочка битов для каждой из соответствующих точек будет 1111b. Это
означает, что восемь точек будут выведены в цвете 15, который изначально
соответствует белому цвету, хотя регистры палитры позволяют, чтобы на
самом деле был любой из допустимых цветов.
Теперь рассмотрим ту же ситуацию, когда посылается значение
00001000b. Цепочка битов для точки 3 будет 1111b, а для остальных 0000b, что
соответствует черному (изначально). Поэтому в данном случае только точка 3
появится на экране, остальные 7 точек будут выключены.
Если вы пошлете код палитры желаемого цвета в регистр маски карты, то
регистр будет маскировать определенные битовые плоскости таким образом,
что будет воспроизведен требуемый цвет. Приведенное выше обсуждение
касалось одновременного вывода восьми точек. Ну а как вывести меньшее
количество точек? В этом случае, конечно, необходимо сохранить
существующие данные для некоторых точек, а чтобы это было возможно,
текущее содержимое данного адреса сохраняется в регистрах задвижки. Затем
используется регистр маски битов для маскирования тех точек, которые не
должны изменяться. Если бит этого регистра сброшен в 0, то данные,
получаемые от процессора для этого бита, игнорируются и вместо них
используются данные, хранящиеся в регистрах задвижки. Заполнение
регистров-задвижек меняется при ненулевом значении регистра разрешения
цвета (регистр 01h блока графического адаптера), разряды 0-3 которого
разрешают заполнение байта выбранных битовых плоскостей значениями из
соответствующих разрядов регистра цвета (регистр 00h блока графического
адаптера). В этом случае значения данных процессора (маски карты
игнорируются).

13.2.2.4.2. Режим записи 1.

Режим записи 1 предназначен для специальных приложений. В этом


режиме текущее содержимое регистра задвижки записывается по указанному
113

адресу. Напоминаем, что регистры задвижки заполняются операцией чтения.


Этот режим очень полезен для быстрого переноса данных при операциях
сдвига экрана. Регистр маски битов и регистр маски карты не влияют на эту
операцию. Не имеет значения также, какие данные посылает процессор –
содержимое регистров задвижки записывается в память без изменений.

13.2.2.4.3. Режим записи 2.

Режим записи 2 представляет альтернативный способ установки


отдельных точек. Процессор посылает данные, у которых имеют значение
только 4 младших бита, рассматриваемые как цвет (индекс регистра палитры).
Можно сказать, что эта цепочка битов вставляется поперек плоскостей.
Цепочка дублируется на все восемь точек, относящихся к данному адресу, до
тех пор, пока регистр маски битов не предохраняет определенные точки от
изменения. Регистр маски карты активен, как и в режиме записи 0. Конечно,
процессор должен послать полный байт, но только младшие 4 бита
существенны.

13.2.2.4.4. Режим чтения 0.

Процессор осуществляет чтение данных (8 точек) из регистра задвижки


той плоскости, которая разрешена регистром выбора плоскости для чтения
(разряды 0-2 регистра 04h блока графического контроллера). Для чтения
цветов (кодов регистра палитры) всех 4 битовых плоскостей необходимо
последовательно разрешить чтение и прочитать все плоскости по одному
адресу.

13.2.2.4.5. Режим чтения 1.

В результате выполнения операции чтения в 1 будут установлены только


те биты в байте, для которых цвет совпадает с цветом, заданным в битах 0-3
регистра сравнения цвета (регистр 02h блока графического адаптера ).

13.2.2.5. Программирование регистров.

Каждая из микросхем адаптера обладает адресным регистром и


несколькими регистрами данных. Адресный регистр используется в качестве
указателя на тот или иной регистр данных. Адресный регистр является
регистром типа "только запись" в который процессор при помощи команды
OUT может быть помещен индекс выбранного регистра данных.
Регистры данных каждой микросхемы адаптера доступны через
соответствующий порт ввода/вывода. Доступ к различным регистрам данных
114

осуществляется путем предварительного занесения в адресный регистр


индекса требуемого регистра данных с последующей выдачей команды OUT
со стороны процессора для занесения в него необходимого значения. Отличие
имеют регистры контроллера атрибутов, где адресный регистр и регистр
данных имеют один порт с адресом 3C0h. Внутри контроллера адресация
организована таким образом, что каждый раз после записи в порт 3C0h,
производится переключение: адресный регистр – регистр данных,
соответствующий значению адресного регистра и наоборот. Для
инициализации процесса переключения адресный регистр – регистр данных
(вначале доступ к адресному регистру, а потом к регистру данных и т.д.)
необходимо выполнить операцию чтения из порта с адресом 3BAh или 3DAh.
После выполнения операции чтения, первый доступ к порту 3C0h будет
обращением к адресному регистру контроллера атрибутов. После загрузки
адресного регистра, следующая команда вывода в порт 3C0h приведет к
записи требуемого значения в соответствующий регистр данных контроллера
атрибутов. Выполнение этой команды снова делает адресный регистр
доступным для записи и процесс может быть продолжен.
После записи данных в регистры контроллера атрибутов необходимо
установить 5 бит адресного регистра контроллера в 1 (разрешение вывода), т.е.
послать в порт 3C0h значение 20h.
Видеоадаптер поддерживает стандартные графические функции BIOS.
Можно вывести точку с помощью функции Ch прерывания 10h. При входе DX
должен содержать номер строки, а CX – номер столбца, и то и другое
отсчитывается от 0. Код цвета помещается в AL.Содержимое AX меняется при
выполнении прерывания.

13.3. Порядок выполнения работы


13.3.1. Написать программу вывода на экран в графическом режиме,
которая выполняет следующие действия:
13.3.1.1. Переводит видео систему в графический режим 10h с помощью
прерывания 10.
13.3.1.2. Устанавливает заданный цвет фона путем программирования
регистра 00h палитры.
13.3.1.3. Выводит 16 строк точек при различных значениях регистров
адаптера. Начальный адрес i-й строки видеобуфера вычисляется в режиме 10h
по выражению
adp=A000:0000+80*i
13.3.1.4. Повторяет вывод следующих 16 строк с теми же параметрами
что и предыдущие, но с учетом сдвига данных в регистре вращения.
13.3.1.5. Повторяет вывод следующих 16 строк с теми же параметрами, но
с учетом логической операции.
115

13.3.1.6. Оставшуюся часть экрана после полученного изображения с


помощью режима записи 1 заполняет байтом, номер строки и столбца в
полученном выше изображении соответствует номеру студен та в журнале.
13.3.1.7. В полученном изображении "потушить" цвет первой строки
путем занесения кода фона в соответствующий регистр палитры.
13.3.1.8. Выполнить аппаратный горизонтальный сдвиг экрана путем
изменения начального адреса.
13.3.1.9. Вернуться в текстовый режим.
13.3.2. Написать, отладить и сохранить для выполнения работ 14, 15
процедуру put_pix чтения байта и вывода за одно обращение к памяти до 8
точек с заданными параметрами
put_pix(x,y,color,bit_m,log_op)
где:x,y – координаты байта видеопамяти
color – код цвета
bit_m-значение битовой маски
log_op – код логической операции с прочитанным значением, который
задается в регистре вращения.

13.4. Особенности программирования.

13.4.1. На языке Турбо-Паскаль.


13.4.1.1. Для обращения к видеопамяти применяется предопределенный
массив Mem. Например, для чтения байта по адресу A000:0000h используется
выражение b:=Mem[$A000:$0000] (b переменная типа byte).
13.4.1.2. Для обращения к портам ПК применяется предопределенный
массив Port. Например, для записи значения 3Dh в порт 3C0h используется
выражение Port[$3C0]:=$3D; для чтения из порта 3DAh используется
выражение data:=Port[$3DA], где data - переменная типа byte.

13.4.2. На языке Турбо-Си.


13.4.2.1. Для обращения к видеопамяти используются дальние указатели,
которые объявляются в программе следующим образом:
char far * uk; – для работы с байтами.
Для чтения байта по адресу A000:FFF5h используется выражение
uk=(char far *) 0xA0000000;
b=* uk; где b – переменная типа char;
13.4.2.2. Для обращения к портам ПК применяются функции чтения и
записи порта, которые хранятся в библиотеке <dos.h>. Библиотека
подключается командой
#include < dos.h>
после чего, например, для записи значения 3Dh в порт 3C0h используется
116

выражение:
outportb(0x3C0,0x3d);

Для чтения из порта 3DAh используется выражение:


data=intportb(0x3DA), где data – переменная типа char;

13.5. Индивидуальное задание.


13.5.1. По 2 цифре номера по журналу выбрать параметры из табл. 13.5

Таблица 13.5 – Варианты индивидуальных заданий


Номер в журнале
Параметры
0 1 2 3 4 5 6 7 8 9
Номер начальной
100 140 200 80 120 150 60 180 210 40
строки
Цвет фона 1А 23 31 18 2B 35 13 2F 39 1D
Цвет 1-й строки А 1 В 3 С 5 6 D 9 8
Приращение цвета
1 2 4 5 8 7 9 6 3 А
і-й строки
Маска видимых
61 63 67 82 86 8E 72 76 7E E2
точек
Сдвиг данных 1 2 3 4 5 6 7 1 2 3
Логическая
AND OR XOR AND OR XOR AND OR XOR AND
операция

13.6. Содержание отчета

13.6.1. Тема лабораторной работы.


13.6.2. Цель работы.
13.6.3. Индивидуальное задание.
13.6.4. Текст программы.
13.6.5. Результаты работы программы.
13.6.6. Выводы.
117

Лабораторная работа 14

Тема: Изображение линий, затушевывание

Цель работы: Приобретение практических навыков создания рисунков.

14.1. Темы для предварительной проработки


14.1.1. Изображение точки в графическом режиме.

14.2. Описание работы.

Функции вычерчивания линий являются основными подпрограммами


графики и используются для отображения линий в заданном цвете путем
задания ее начальных и конечных координат. В то время, как изображение
вертикальных горизонтальных линий не представляет особого труда, более
трудной задачей является создание функций, которые рисуют линии вдоль
диагоналей. Например, какие точки составляют линию, вычерчиваемую от
точки с координатами 0,0 до точки с координатами 80,120?
Один из подходов к разработке функций вычерчивания линий использует
отношение между смещением по координатам X и Y. Чтобы показать этот
подход в действии, проведем линию между точками с координатами 0,0 и 5,10.
Смещение по X равно 5, а по Y – 10. Отношение равно 1/2. Оно будет
использоваться при определении коэффициента зависимости, по которому
должны меняться координаты X и Y при изображении линий. В данном случае
это означает, что приращение координаты Х составляет половину величины
изменения координаты Y. Начинающий программист часто использует этот
метод при разработке функций вычерчивания линий. Хотя подход
математически верен и прост для понимания, для его правильной работы и для
того, чтобы избежать серьезных ошибок округления, необходимо
использовать математические операции с числами с плавающей точкой. Это
означает резкое снижение быстродействия, если в систему не будет включен
математический сопроцессор. По этой причине этот метод используется
довольно редко.
Наиболее общий метод изображения линий включает использование
алгоритма Брезенхейма. Хотя основой в нем служит также отношение между
расстояниями по координатам X и Y, в данном случае не требуется выполнять
деление или вычисление чисел с плавающей точкой. Вместо этого, отношение
между значениями координат Х и Y представляется косвенным образом через
серии сложений и вычитаний. Основной идеей алгоритма Брезенхейма,
является регистрация средних значений погрешностей между идеальным
положением каждой точки и той позицией на экране дисплея, в которой она
действительно отображается. Погрешность между идеальным и
118

действительным положением точки возникает ввиду ограниченных


возможностей технических средств. Фактически не существует дисплеев с
бесконечно большой разрешающей способностью, и, следовательно,
действительное положение каждой точки на линии требует наилучшей
аппроксимации. В каждой итерации цикла вычерчивания линии вызываются
две переменные X_err и Y_err, которые увеличиваются в зависимости от
изменения величин координат Х и Y соответственно.

Line_m Inc_x=sign(D_X)
Inc_y=sign(D_Y)
X_err=0 Y_err=0
D_X=EX-BX
D_Y=EY-BY D_X=abs(D_X)
D_Y=abs(D_Y)

да нет
D_X>D_Y

dist=D_X dist=D_Y

t=0, dist

return
Put_pix(BX,
BY, color)

X_err=X_err+D_X
Y_err=Y_err+D_Y

да X_err=X_err-dist
X_err>dist BX=BX+inc_X

нет

да
Y_err=Y_err-dist
Y_err>dist
BY=BY+inc_Y
нет

Рис. 14.1 – Алгоритм изображения линий (Брезенхейма)


119

Когда значение погрешности достигает определенного значения, оно


вновь устанавливается в исходное положение, а соответствующий счетчик
координат увеличивается. Этот процесс продолжается до тех пор, пока линия
не будет полностью вычерчена. В данном алгоритме приняты следующие
обозначения: BX, BY – координаты начальной точки; EX, EY – координаты
конечной точки; D_X, D_Y – максимальное расстояние на соответствующей
координате; с – цвет выводной точки; inc_X, inc_Y – направление движения по
соответствующей координате.
Как видно из алгоритма, при движении по большей координате (dist)
приращение по этой координате и изображение точки выполняется всегда, в то
время как по другой координате только при выполнении условия – err>=dist.
Если у вас есть функции вычерчивания линий, то не составит особого
труда создать функции вычерчивания прямоугольников. Пример, приведенный
здесь, вычерчивает прямоугольники в заданном цвете путем создания
координат двух противоположных углов.

/* вычерчивание прямоугольника */
void box(startx,starty,endx,endy,color_code)
int startx,starty,endx,endy,color_code;
{
line(startx,starty,endx,starty,color_code);
line(startx,starty,startx,endy,color_code);
line(startx,endy,endx,endy,color_code);
line(endx,starty,endx,endy,color_code);
}
Для того, чтобы закрасить прямоугольник, требуется выполнить запись в
каждую точку растра внутри прямоугольника. При этом необходимо в цикле
рисовать заданным цветом ряд горизонтальных линий, смещенных на единицу
по координате y – функция bar_m().
Тщательное продумывание позволяет исключить излишнюю
медлительность, свойственную многим программам заполнения областей для
графического экрана. Когда заполнение основано на простых вычислениях,
которые действуют по очереди для каждой точки, требуется расходующие
много времени битовые операции. Более экономичный код может определять,
все ли битовые позиции определенного байта видеобуфера должны иметь один
и тот же цвет, и когда это условие выполняется, этому байту присваивается
заранее заготовленное значение, которое устанавливает все точки в
правильный цвет. При этом нет необходимости повторять операции над одним
и тем же байтом, каждый раз устанавливая биты только для одной из точек,
информацию о которой содержит данный байт.
При заполнении прямоугольника линиями только первый и последний
120

байт каждой строки может быть неполным (если BX или EX не кратен 8). При
затушевывании горизонтальными линиями нет смысла использовать
процедуру line_m(), реализующую алгоритм Брезенхейма, необходимо просто
определять адрес байта в видеопамяти, который соответствует в данный
момент 8 выводимым точкам с начальными координатами X и Y, причем X
кратен 8: adr=A000:0000h + X/8 +Y*80.
В работе 11 объяснено, как создать описание символа в виде матрицы 8×8
точек, имеющего требуемый вам вид. Хотя такие символы могут выводиться
только в стандартные символьные позиции, их использование может
существенно облегчить заполнение графиков. Образец, высвечивающий все
8×8 точек можно вывести в интервале несколько строк и столбцов, заполняя
область намного быстрее, чем это достигается при поточечной зарисовке.
При затушевывании прямоугольника в центральной части желательно
использовать символы псевдографики с кодами ASCII 219, 220, 221, 222, 223,
которые заполняют все, знакоместо (219), нижнюю половину (220),
левую(221), правую (222) и верхнюю (223). При изображении прямоугольника
тоже нет смысла применять алгоритм Брезенхейма, так как он состоит из
горизонтальных и вертикальных отрезков. Изображение горизонтальных
отрезков выполняется аналогично рассмотренному выше способу
затушевывания горизонтальными линиями, а изображение вертикальных
отрезков сводится к выводу в цикле одного байта с заданной частной (при
текущей линии в 1 пиксель маска содержит одну 1) и приращение адреса на 80
– переход на следующую строку. Модификация изображения наклонной
линии.
При работе алгоритма Брезенхейма в случае D_X > D_Y в каждой строке
выводится несколько точек. Если перед блоком 9 в алгоритме анализировать
значение BX при неизменном BY и дописывать 1 в битовую маску. Тогда при
использовании разработанной в лабораторной работе процедуры вывода байта
с заданной маской обращение к ней выполняется только в случае кратности 8
значения BX (переход на следующий адрес видеопамяти) или изменения BY
(переход на следующую строку). В случае если D_Y > D_X и толщина линии
составляет 2, 3, и т.д. пикселя за одно обращение к put_pix() можно выводить
соответствующее число точек (если они относятся к одному адресу
видеопамяти).

14.3.Порядок выполнения работы.

14.3.1. Написать программу, которая использует разработанную в работе


13 процедуру put_pix() и выполняет следующие действия:
14.3.1.1. Переводит систему в графический режим 10h.
14.3.1.2. Вычерчивает прямоугольник с параметрами соответствующими
121

индивидуальному заданию (rest_m()).


14.3.1.3. Закрашивает прямоугольную область с параметрами
соответствующими индивидуальному заданию (bar_m()).
14.3.1.4. Рисует наклонную линию, используя модификацию алгоритма
Брезенхейма с параметрами, соответствующими индивидуальному заданию
(line_m()).
14.3.1.5. Возвращает систему в текстовый режим.

14.4. Особенности программирования.

14.4.1. На языке Паскаль.


14.4.1.1. Для обращения к видеопамяти применяется предопределенный
массив Mem. Например, для чтения байта по адресу A000:0000h используется
выражение b:=Mem[$A000:$0000] (b переменная типа byte).
14.4.1.2. Для обращения к портам ПК применяются предопределенный
массив Port. Например, для записи значения 3Dh в порт 3C0h используется
выражение Port[$3C0]:=$3D; для чтения из порта 3DAh используется
выражение data:=Port[$3DA], где data – переменная типа byte.
14.4.2. На языке Си.
14.4.2.1. Для обращения к видеопамяти используются дальние указатели,
которые объявляются в программе следующим образом:
char far * uk; – для работы с байтами.
Для чтения байта по адресу A000:0000h используется выражение:
uk=( char far * ) 0xA0000000;
b=* uk; где b – переменная типа char;
14.4.2.2. Для обращения к портам ПК применяются функции чтения и
записи порта, которые хранятся в библиотеке <dos.h>. Библиотека
подключается командой
#include < dos.h>
после чего, например, для записи значения 3Dh в порт 3C0h используется
выражение:
outportb(0x3C0,0x3D);
Для чтения из порта 3DAh используется выражение:
data=intportb(0x3DA),где data – переменная типа char;
122

14.5. Индивидуальные задания.

По второй цифре номера студента выбрать параметры согласно


табл. 14.1.
Таблица 14.1 – Варианты индивидуальных заданий
Номер в журнале
Параметры
0 1 2 3 4 5 6 7 8 9
Xn1 30 0 10 30 50 60 40 30 20 0
Yn1 60 0 20 50 10 40 30 10 40 50
Xk1 260 200 250 280 300 310 210 240 290 190
Yk1 120 150 140 130 120 110 100 150 140 130
L1 5 3 4 2 4 3 5 4 3 4
color C 1 3 4 5 6 7 8 A B
Xn2 350 400 410 450 430 460 360 330 420 340
Yn2 0 60 50 40 10 30 40 10 50 20
Xk2 580 500 600 550 630 560 680 510 520 530
Yk2 150 120 130 140 150 100 110 120 130 140
Color2 7 D E F 1 2 3 4 5 6
Xn2 10 30 0 20 30 40 60 50 100 90
Yn2 320 160 360 140 310 120 290 180 280 150
Xk2 630 500 400 600 580 530 420 510 620 460
Yk2 150 300 160 310 140 290 120 280 180 320
Color3 1 8 9 A B C D E F 2
L3 3 5 4 3 4 5 3 4 2 4

где: Xn1, Yn1, Xk1, Yk1 – координаты верхнего левого (индекс n ), и правого
(индекс k) угла прямоугольника; L1 – толщина линии в прямоугольнике; color1
– цвет; Xn2, Yn2, Xk2, Yk2, color2 – соответствующие параметры
затушевывания. Xn3, Yn3, Xk3, Yk3, L3, color3 – координаты, толщина и цвет
наклонной линии.

14.6. Содержание отчета

14.6.1. Тема лабораторной работы.


14.6.2. Цель работы.
14.6.3. Индивидуальное задание.
14.6.4. Текст программы.
14.6.5. Результаты работы программы.
14.6.6. Выводы.
123

Лабораторная работа 15

Тема: Сохранение и загрузка графических изображений. Перемещение и


вращение объекта.

Цель работы: Приобретение практических навыков в манипуляции


графическими объектами.

15.1. Темы для предварительной проработки


15.1.1. Изображений линий в графическом режиме

15.2. Описание работы


15.2.1. Сохранение и загрузка графических изображений.
Любой язык программирования имеет доступ к двум режимам чтения
видеопамяти. В режиме 0 возвращается байт, содержащийся во всех четырех
плоскостях, по указанному адресу. Режим 1 ищет указанный код цвета и
возвращает байт, в котором бит установлен в 1, когда соответствующая точка
имеет данный цвет. Бит 3 регистра режима определяет, какой режим чтения
установлен (0 = режим 0). Доступ к этому регистру осуществляется через порт
3CFh, и вы должны предварительно послать 5 в порт 3CEh, чтобы выбрать
этот регистр. Обычно все остальные биты этого регистра, который можно
только писать, сброшены в 0, кроме битов 0 и 1, которые определяют режим
записи. Поскольку при инициализации BIOS устанавливает эти биты в режим
записи 0 (так что они оба равны 0), вам нужно просто послать в этот регистр 0,
чтобы установить режим чтения 0, и послать 8, чтобы установить режим
чтения 1.
Режим чтения 0 требует, чтобы вы предварительно установили регистр
выбора карты. Единственная задача этого регистра – установить, какая из
битовых плоскостей должна быть прочитана. Поэтому в него надо послать
число от 0 до 3. Этот регистр имеет адрес порта 3CFh и надо предварительно
послать 4 в порт 3CEh, чтобы указать этот регистр.
Режим чтения 1 более сложен. Сначала регистр сравнения цветов должен
быть заполнен цепочкой битов для кода цвета, который вы ищете. Этот код
помещается в младшие 4 бита регистра; старшие четыре бита не существенны.
Этот регистр имеет адрес порта 3CFh и указывается предварительной
засылкой 2 в порт 3CEh. После чтения ячейки памяти возвращается байт,
который имеет биты, установленные в 1 для каждой точки, имеющей нужный
цвет. Однако за счет использования регистра безразличия цвета (color don't
care register) один и более битов кода цвета могут при сравнении
игнорироваться. Обычно 4 младших бита этого регистра установлены в 0;
логическая 1 в в одном из этих битов приведет к тому, что содержимое
124

соответствующей битовой плоскости будет игнорироваться.


Регистр безразличия цветов имеет адрес порта 3CFh и индексируется
засылкой 7 в порт 3CEh. Старшие 4 его бита не играют никакой роли.
Ни один из этих двух режимов чтения не может дать быстрый ответ.
В режиме чтения 0 необходимы 4 отдельных чтения, по одному для
каждой битовой плоскости. В режиме чтения 1 может потребоваться до 16
чтений, прежде чем для требуемой точки будет возвращен установленный бит,
указывающий, что эта точка имеет данный цвет.
Функция Dh прерывания 10h возвращает код цвета указанной точки. Надо
поместить номер строки (отсчитываемый от 0) в DX, а номер столбца (также
отсчитываемый от 0) – в CX. Результат возвращается в AL.

15.2.2. Вращение точки в плоскости экрана.


Вращение точки в плоскости экрана (двумерном пространстве)
представляет собой довольно простую задачу в декартовой системе координат.
Вы можете вспомнить из курса аналитической геометрии, что вращение точки
вокруг центра, который находится в начале координат на угол theta,
описывается формулами:
new_Y = Y * cos(theta) + X * sin(theta);
new_X = X * cos(theta) – Y * sin(theta).
Единственной сложностью при употреблении этих формул для
графических дисплеев будет тот факт, что экран дисплея не является
декартовым пространством. Декартовы оси определяют 4 квадранта. Однако
экран терминала представляет собой один из квадрантов, оси X и Y в котором
перевeрнуты ось X слева направо от верхнего угла, а ось Y – сверху вниз.
Для решения этой проблемы необходимо определить новый центр и
привести в соответствие координаты X и Y экрана в координаты осей D_X и
D_Y декартова пространства по выражениям:
D_X=X – X0;
D_Y=Y0 – Y.
Любая точка на экране может быть использована в качестве центра, но
обычно центр определяется как можно ближе к центру объекта, который мы
собираемся вращать. Угол вращения следует задавать в радианах. Таким
образом для вращения точки необходимо выполнить:
• "Потушить" точку, записав в нее цвет фона.
• Привести в соответствие координаты дисплея к декартовым.
• Повернуть точку в декартовых координатах на угол theta.
• Восстановить новые координаты дисплея по выражениям:
X=D_X + X0;
Y=Y0 – D_Y.
• Вывести точку на экран с заданным цветом.
125

15.2.3. Вращение плоской фигуры в плоскости экрана. Под объектом


здесь и далее будем понимать набор сегментов прямых отрезков. Координаты
крайних точек каждого отрезка содержатся в двумерном массиве чисел с
плавающей точкой. Каждая строка массива содержит начальные и конечные
координаты данного отрезка. Это означает, что первая размерность массива
представляет собой количество отрезков, входящих в состав объекта, а вторая
размерность будет равна 4 (число координат крайних точек отрезка).
Например, массив, приведенный ниже
double object [3][4]; определяет объект, состоящий из 3 отрезков (см.
табл. 15.1).
Таблица 15.1 – Описание объекта (треугольника)

Первый Второй индекс


индекс
0 1 2 3
0 start_X1 start_Y1 end_X1 end_Y1
1 start_X2 start_Y2 end_X2 end_Y2
2 start_X3 start_Y3 end_X3 end_Y3

Определить объект – это значит разместить в массиве координаты


начальных и конечных точек отрезков, составляющих объект. Например, если
объект представляет собой прямоугольник с координатами 0×0 15×10, то
массив, определяющий данный прямоугольник, заносятся следующие числа:
object[0][0] = 0; object[0][1] = 0; object[0][2] = 0; object[0][3] = 10;
object[1][0] = 0; object[1][1] = 10; object[1][2] = 15; object[1][3] = 10;
object[2][0] = 15; object[2][1] = 10; object[2][2] = 15; object[2][3] = 0;
object[3][0] = 15; object[3][1] = 0; object[3][2] = 0; object[3][3] = 0.
После того, как объект определен, вы можете вращать его, используя
функцию rotate_object(), по часовой стрелке, задавая соответствующий знак
theta или в противоположную сторону. При вращении объекта необходимо
выполнить следующие действия:
• Изображение объекта путем организации цикла по первому индексу
массива object считывания из соответствующей строки массива координат
двух точек и с помощью функции line_m() изображения отрезка прямой.
• Организация цикла нажатия клавиши (выход из цикла при нажатии
клавиши ESC) внутри которого выполняются действия:
• "Гашение" на экране объекта, которое состоит в изображении объекта
фоновым цветом. Если "гасить" объект цветом отличным от фона, то
вращающаяся фигура будет оставлять за собой след.
• Поворот каждой точки объекта с помощью рассмотренной ранее
процедуры поворота точки. При этом надо учесть, что каждая строка описания
126

объекта содержит координаты двух точек, поэтому для каждой строки


необходимо дважды вызывать функцию rotаte_point с параметрами:
оbject[i][0], object[i][1], theta, X0, Y0 – для 1 точки
object[i][2], object[i][3], theta, X0,Y0 – для 2 точки
• Изображение объекта с новыми координатами.
15.2.4. Вращение трехмерных объектов.
Прежде чем вращать трехмерные объекты необходимо рассмотреть
отображение трехмерных объектов, заданных отрезками прямых в декартовых
координатах экрана X, Y. Как и при вращении плоских фигур считаем, что
начало системы декартовых координат совпадает с центром вращения. Без
нарушения объекта рассмотрим преобразование координат одной точки.
Как известно из курса инженерной графики, для отображения
трехмерных координат в двумерные, используются различные виды проекций.
Наиболее распространенной является изометрическая проекция, у
которой ось D_Z направлена вертикально вверх, а ось D_X и D_Y повернуты
на угол +120 градусов и –120 градусов соответственно. Коэффициент сжатия
по всем трем осям равен 0,97 (для простоты можно взять 1).
Другой проекцией является диметрическая кабинетная, у которой ось
D_Z вертикально вверх, ось D_Y горизонтально влево, а ось D_X повернута на
+135 градусов относительно оси D_Z (или на -135 градусов относительно оси
D_Y).Коэффициент сжатия по осям D_Z и D_Y равен 1, а по оси D_X равен
0,5. Таким образом, учитывая особенности координатной системы экрана (ось
X влево, а ось Y вниз), преобразование координат точки выполняется:
• для изометрической проекции
X=X0 + cos(3.1418/6)*(D_Y – D_X);
Y=Y0 – D_Z + sin(3.1418/6)*(D_X+D_Y);
• для кабинетной проекции
X=X0 + D_Y – 0,5*sin(3.1418/4)*D_X;
Y=Y0 – D_Z + 0,5*sin(3.1418/4)*D_X;

где: X0, Y0 – координаты центра вращения и начала декартовых трехмерных


координат в плоскости экрана;
D_X, D_Y, D_Z – декартовы координаты точки;
X, Y – координаты точки на экране.
Сделав преобразование координат 2 точек отрезка можно построить
проекции каждого отрезка прямой, которые создают проекцию трехмерного
объекта на экране.
Ось вращения трехмерного объекта расположена в пространстве
произвольным образом и рассматриваются ее составляющие – проекции осей
вращения на координатные оси D_Z, D_Y, D_X. Поэтому рассмотрим
преобразование координат точки при вращении вокруг соответствующей оси
127

(координата оси вращения не меняется).


Вращение вокруг оси Z:
D_Y=D_Y*cos(theta) + D_X*sin(theta);
D_X=D_X*cos(theta) – D_Y*sin(theta).
Вращение вокруг оси Y:
D_X=D_X*cos(theta) + D_Z*sin(theta);
D_Z=D_Z*cos(theta) – D_X*sin(theta).
Вращение вокруг оси X:
D_Z=D_Z*cos(theta) + D_Y*sin(theta);
D_Y=D_Y*cos(theta) – D_Z*sin(theta).
Трехмерный объект удобно вначале описывать в декартовой трехмерной
системе координат в виде двух массивов:
– двумерный массив point описаний вершин (точек), в котором первая
размерность соответствует числу точек, а вторая размерность равна 3 и
соответствует трем координатам каждой точки D_X, D_Y, D_Z
соответственно.
– двумерный массив описания ребер (линий, в которых первая
размерность соответствует числу линий, а второй индекс (размерность равна
2) содержит индексы начальной и конечной точки линии (индекс точки
соответствует номеру строки в предыдущем массиве point).
Например, описание пирамиды с треугольным основанием (имеется 4
вершины), массив описания точек имеет вид:
double point[4][3]={60, 00, -40, /* координаты 1 точки */
-40, -60, -40,
-40, 60, -40,
00, 00, 60}
Массив описания ребер имеет вид:
int K_point[6][2]={0,1, 1,2, 2,0, 0,3, 1,3, 2,3};
Используя рассмотренные массивы и выполнив преобразование
декартовых трехмерных координат программа формирует описание объекта в
координатах экрана аналогично массиву object в двумерном случае.
Таким образом, при вращении трехмерного объекта программа выполняет
следующие действия:
• По заданным массивам point и K_point формирует описание проекции
объекта на экране – object.
• Выводит изображение объекта как в двумерном случае используя
описание object и функцию line_m.
• Организует цикл ожидания нажатия клавиши, (выход из цикла по ESC)
внутри которого выполняются следующие действия:
• "гашение" объекта, т.е. зарисовка его цветом фона.
• Поворот точек массива point вокруг заданной оси. При повороте точек
128

преобразования поворота выполняются для каждой строки массива point.


• Формирование нового значения массива object и вывод изображения на
экран.

15.3. Порядок выполнения работы.


15.3.1. Написать программу, которая использует разработанные в работе
14 функции bar_m() и line_m() и выполняет следующие действия:
15.3.1.1. Переводит систему в графический режим.
15.3.1.2. С помощью функции bar_m() закрашивает часть экрана в разные
цвета.
15.3.1.3. Копирует закрашенную часть экрана в остальную часть экрана.
15.3.1.4. Сохраняет полученное изображение в файл (запрос об имени
файла высвечивается в верхних 14 строках).
15.3.1.5. Заполняет экран фоновым цветом.
15.3.1.6. Выводит и вращает плоскую фигуру, параметры которой
соответствуют индивидуальному заданию.
15.3.1.7. Выводит и вращает трехмерный объект, параметры которого
соответствуют индивидуальному заданию.
15.3.1.8. Возвращает систему в текстовый режим.

15.4. Особенности программирования.


15.4.1. На языке Паскаль.
15.4.1.1. Для обращения к видеопамяти применяется предопределенный
массив Mem. Например, для чтения байта по адресу A000:0000h используется
выражение b:=Mem[$A000:$0000] (b – переменная типа byte).
15.4.1.2. Для обращения к портам ПК применяется предопределенный
массив Port. Например, для записи значения 3Dh в порт 3C0h используется
выражение Port[$3C0]:=$3D; для чтения из порта 3DAh используется
выражение data:=Port[$3DA], где data – переменная типа byte.

15.4.2. На языке Си.


15.4.2.1. Для обращения к видеопамяти используются дальние указатели,
которые объявляются в программе следующим образом:
char far * uk; – для работы с байтами.
Для чтения байта по адресу A000:0000h используется выражение:
uk=( char far *) 0xA0000000;
b=* uk; где b – переменная типа char;
15.4.2.2 . Для обращения к портам ПК применяются функции чтения и
записи порта, которые хранятся в библиотеке <dos.h>. Библиотека
подключается командой
#include <dos.h>
129

после чего, например, для записи значения 3Dh в порт 3C0h используется
выражение:
outportb(0x3C0,0x3D);
Для чтения из порта 3DAh используется выражение:
data=intportb(0x3DA),где data- переменная типа char;

15.5. Индивидуальные задания


По первой цифре номера студента в журнале выбрать проекцию для
трехмерного объекта.
0 – изометрическая
1 – диметрическая кабинетная.
В табл. 15.2 по второй цифре номера студента в журнале выбрать
параметры двумерного и трехмерного объекта.

Таблица 15.2 – Варианты индивидуальных заданий


Вторая цифра в номере по журналу
Параметры
0 1 2 3 4 5 6 7 8 9
obj_XY 4 3 4 5 5 4 6 5 3 6
obj_XYZ 15 44 13 33 44 14 44 15 55 33
Цвет фона 4 0 1 2 3 4 3 1 2 0
Цвет объекта B E C D A B 8 4 5 6
theta -0.12 0.05 -0.05 0.06 0.08 0.1 -0.08 0.1 -0.01 0.12
Ось вращения X X Y Z X Y X Y Z X

где : obj_XY – тип плоского выпуклого многоугольника: 3 – треугольник, 4 –


квадрат и т.д; obj_XYZ – тип трехмерного объекта, который в случае равенства
двух цифр является прямоугольной призмой, а каждая цифра соответствует
числу сторон основания. Если одна цифра равна 1, то трехмерный объект
представляет собой пирамиду. Например, 13 – пирамида с треугольным
основанием 44 –четырехугольная призма (параллелепипед ) и т.д.
Центр вращения и размера объекта студент выбирает самостоятельно.

15.6. Содержание отчета


15.6.1. Тема лабораторной работы.
15.6.2. Цель работы.
15.6.3. Индивидуальное задание.
15.6.4. Текст программы.
15.6.5. Результаты работы программы.
15.6.6. Выводы.
130

ЛИТЕРАТУРА

1. Поворознюк А. И. Архитектура компьютеров. Архитектура


микропроцессорного ядра и системных устройств: Учебное пособие. Ч.1. /
А. И. Поворознюк – Харьков: "Торнадо", 2014. – 355 с.
2. Поворознюк А. И. Архитектура компьютеров. Архитектура внешней
памяти, видеосистемы и внешних интерфейсов: Учебное пособие. Ч.2. /
А. И. Поворознюк – Харьков: "Торнадо", 2014. – 296 с.
3. Несвижский В. Программирование аппаратных средств в Windows. /
В. Несвижский – СПб: БХВ-Петербург, 2004. – 880 с.
4. Гук М. Аппаратные средства IBM PC. Энциклопедия / М. Гук – СПб:
Питер Ком, 2004. – 816 с.
5. Гук М. Процессоры Pentium 4, Athlon и Duron / М. Гук В. Юров– СПб:
ЗАО "Издательство "Питер", 2001. – 512 с.
6. Гук М. Процессоры Pentium II Pentium Pro и просто Pentium / М. Гук –
СПб: ЗАО "Издательство "Питер", 1999. – 288 с.
7. Фролов А.В. Аппаратное обеспечение IBM PC. Том 2, часть 1. /
А.В. Фролов, Г.В. Фролов – М. : "Диалог-Мифи", 2002. – 206 с.
Навчальне видання

ПОВОРОЗНЮК Анатолій Іванович


МЕЗЕНЦЕВ Микола Вікторович
ПОВОРОЗНЮК Оксана Анатоліївна

АРХІТЕКТУРА КОМП’ЮТЕРІВ

Лабораторний практикум

Роботу до видання рекомендував проф. М.Й. Заполовський

Відповідальний за випуск проф. В. Д. Дмитрієнко

В авторській редакції

План 2015 р., поз. 156

Підписано до друку 23.11.2016 р. Формат 60х84 1/16. Папір друк. №2


Гарнітура Times New Roman. Ум. друк. арк. 4,8. Обл. - вид. арк. 4,9.
Наклад 100 прим. Ціна договірна.

Видавництво Курсор. Україна, 61057, м. Харків, пр. Театральний 11/13, (057) 706-31-73
Свідоцтво про внесення до Державного реєстру суб’єктів видавничої справи
серія №21 від 24.03.2000 р.

Віддруковано ФОП Гуськов А. А. Україна, 61057, м. Харків, пр. Театральний 11/13

Вам также может понравиться