Поиск по сайту:


«Assembler IBM PC 8. Лабораторная работа № 3. Применение сервисных функций BIOS для работы с экраном и клавиатурой»

Файл: 4 КБ
Поделиться:

8.1. ЦЕЛЕВЫЕ УСТАНОВКИ

¨  Вывод текста на экран путём непосредственного программирования видеобуфера.

¨  Разработка прикладных программ с использованием сервисных функций BIOS для работы с экраном и клавиатурой.

¨  Введение задержки для программных операций.

8.2. МЕТОДИЧЕСКИЕ РЕКОМЕНДАЦИИ

8.2.1. ВВЕДЕНИЕ

В работе № 2 были рассмотрены различные системные функции DOS вывода на экран символьной информации. Однако возможности DOS весьма ограничены: она не имеет функций для изменения цвета выводимых символов и позиционирования курсора. Кроме того, в DOS отсутствуют средства формирования графических изображений.

Все возможности видеосистемы компьютера можно реализовать с помощью видеофункций BIOS прерывания int 10h. Прерывание int 10h обеспечи-вает: смену видеорежима (текстовый или графический); вывод символьной и текстовой информации; смену шрифтов, настройку цветовой палитры, работу с графическим изображением. Программирование видеосистемы с помощью средств BIOS более громоздко, однако большие возможности и высокая скорость вывода обуславливают широкое использование этого метода в прикладных программах.

В данной работе рассматриваются функции BIOS [10, 12] для обслуживания видеосистемы компьютера, а также функции для работы с клавиатурой. Перечислим функции, являющиеся предметом рассмотрения в лабораторной работе.

Int 10h:

функция 00h – установка видеорежима;

функция 02h – установка позиции курсора;

функция 03h – считывание позиции и размера курсора;

функция 05h – установка видеостраницы;

функция 06h (07h) – инициализация или прокрутка окна вверх (вниз);

функция 08h – чтение символа и атрибута в позиции курсора;

функция 09h – запись символа и атрибута в позицию курсора;

функция 0Ah – запись символа в позицию курсора с текущим атрибутом;

функция 0Eh – запись символа в режиме телетайпа с текущим атрибутом;

функция 0Fh – получить режим дисплея;

функция 1003h – переключение назначения старшего бита байта атрибута: мерцание/яркость,

функция 13h – запись строки с заданным атрибутом в режиме телетайпа.

Int 16h:

функция 00h (10h) – чтение символа с клавиатуры с ожиданием;

функция 01h (11h) – проверка буфера клавиатуры на наличие в нём символа;

функция 02h (12h) – получение флагов (расширенной) клавиатуры.

Int 15h,      функция 86h – задержка.

Int 1Ah,      функция 00h – получение системного времени.

8.2.2. ПРЯМОЕ ПРОГРАММИРОВАНИЕ ВИДЕОБУФЕРА В ТЕКСТОВОМ РЕЖИМЕ

Современные видеоконтроллеры поддерживают разнообразные текстовые и графические режимы. Текстовые режимы различаются по разрешению (число отображаемых символов по горизонтали и вертикали) и цветовой палитре (монохромный или 16-цветный режим). Для графических режимов основным признаком классификации является количество одновременно отображаемых цветов и, соответственно, количество бит видеопамяти, отводимое на каждую точку (пиксел) изображения. Различают следующие типы графических режимов:

–     монохромный (1-битное кодирование);

–     16-цветный EGA/VGA (4-битное кодирование);

–     256-цветный SVGA (8-битное кодирование);

–     HiColor (16-битное кодирование);

–     TrueColor (24-битное / 32-битное кодирование).

Графические режимы VGA (SVGA) сильно устарели, а текстовые продолжают успешно применяться (см. табл. 3.2 п. 8.2.3).

Всё, что изображено на мониторе – графика, текст – одновременно присутствует в памяти, встроенной в видеоадаптер. Для того чтобы изображение появилось на мониторе, оно должно быть записано в память видеоадаптера. В текстовом режиме для VGA-совместимых систем для видеопамяти отводится адресное пространство (исключая 7-й видеорежим с монохромным адаптером), начинающееся с логического адреса B800h:0000h и заканчивающееся адресом BF00h:0FFFh. Данная область разбивается на 8 секторов по числу видеостраниц (4 Кбайта на страницу). Таким образом, постраничное деление адресного пространства видеопамяти в текстовом режиме имеет следующий вид:

–     B800h:0000h – страница 0, смещение в диапазоне 0000h – 0FFFh

–     B900h:0000h – страница 1, смещение в диапазоне 0000h – 0FFFh

–      ...........

–      BF00h:0000h – страница 7, смещение в диапазоне 0000h – 0FFFh

На экране отображается видеобуфер, соответствующий активной странице. В текстовых режимах для изображения каждого символа отводится 2 байта: байт с ASCII-кодом символа и байт с его атрибутом. При этом по адресу B800h:0000h находится байт с кодом символа (левый верхний угол экрана), а в B800h:0001h – атрибут этого символа; B800h:0002h – код второго символа, а в B800h:0003h – атрибут второго символа и т.д. Вообще при формировании изображения непосредственно в видеобуфере, в обход программ DOS и BIOS, все управляющие коды ASCII теряют свои управляющие функции и отображаются в виде соответствующих символов. Структура байта атрибутов приведена на рис. 3.1.

 

 
 
 

 

 

 

 

 

 

 

 

Рис. 3.1. Структура байта атрибутов

 

Из рис. 3.1 следует, что каждый символ может принимать любой из 16 возможных цветов, определяемых сочетанием младших 4-х битов. Биты 4-6 байта атрибутов задают цвет фона под данным символом. Последний бит 7, в зависимости от режима видеоадаптера, определяет либо яркость фона под данным символом (тогда фон также может принимать 16 разных цветов), либо мерцание символа (устанавливаетсяDOS по умолчанию).

При загрузке машины устанавливается стандартная палитра, коды цветов которой приведены в табл. 3.1. Рассмотрим некоторые примеры. Так, в режиме мерцания значение старшего полубайта атрибута 8hобозначает не серый фон, а чёрный при мерцающем символе, цвет которого по-прежнему определяется младшим полубайтом; значение старшего полубайта 0Ch – красный фон при мерцающем символе. Переключение назначения бита 7 осуществляется подфункцией 03h функции 10h прерывания int 10h.

Таблица 3.1

Коды цветов стандартной палитры

Код

Цвет

Код

Цвет

0h

Чёрный

8h

Серый

1h

Синий

9h

Голубой

2h

Зелёный

0Ah

Салатовый

3h

Бирюзовый

0Bh

Светло-бирюзовый

4h

Красный

0Ch

Розовый

5h

Фиолетовый

0Dh

Светло-фиолетовый

6h

Коричневый

0Eh

Жёлтый

7h

Белый

0Fh

Ярко- белый

 

 

Двухбайтовые коды символов записываются в видеобуфер в том порядке, в каком они должны появиться на экране: первые 80*2 байт соответствуют первой строке экрана, вторые 80*2 байт – второй и т.д. При этом переход на следующую строку экрана определяется не управляющими кодами возврата каретки и перевода строки, а размещением кода в другом месте видеобуфера. Для того чтобы из программы получить доступ к видеобуферу, надо занести в один из сегментных регистров данных сегментный адрес видеобуфера. После этого, задавая те или иные смещения, можно выполнить запись в любые места (ячейки) видеобуфера. Вычислить смещение ячейки в координатах "строка-столбец" (row, clm) можно так:

VidAdd r= (row*160) + (clm*2)

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

Листинг 3.1. Запись строки в видеобуфер 0-страницы.

;Очистка экрана

                 

;Настроим сегментный регистр ES на страницу 0 видеобуфера, а ds на сегмент данных

            mov ax,0B800h

            mov es,ax

;Перешлём в видеобуфер строку символов, настроив соответствующим образом

;регистры si, di и cx

          mov si,offset msg            ;Смещение источника

                 mov di,160*12+36*2    ;Смещение приёмника (36 столбец 13 -ой строки),

          mov cx,msglen                ;Число пересылаемых байт

          cld                                 ;Просмотр вперёд

          rep movsb               ;)*   ;Переслать строку символов с атрибутами в видеобуфер

;Остановим программу для наблюдения результата (иначе после завершения программы

;запрос DOS на ввод команды может затереть выведенную информацию)

          mov ah,01h

          int 21h

          

;Поля данных в сегменте данных программы. Символы и атрибуты: 0B0h – cветло-

;бирюзовый по чёрному, 0E4h –красный по жёлтому

          msg             db                 ‘*’,0B0h,’T’,0E4h,’E’,0E4,’S’,0E4,’T’,0E4,’*’,0B0h

          msglen         =                   $-msg

В данном фрагменте программы символьные коды выводимого сообщения перемежаются с их атрибутами. Такой способ формирования полей данных, предназначенных для прямой записи в видеопамять, становится громоздким, однако его можно существенно упростить, если выводимые символы имеют одни и те же атрибуты. Так, если мы хотим осуществить вывод символов текста из сегмента данных с единственным атрибутом 0E4h, то нам нужно просто заменить одну командную строку, отмеченную в выше приведённом фрагменте символом "*)", на три. При этом задание строки данных приобретёт привычный для нас вид.

          

          mov si,offset msg              ;Смещение источника

                 mov di,160*12+36*2       ;Смещение приёмника (36 столбец 13 -ой строки),

          mov cx,msglen                  ;Число пересылаемых байт

          cld                                    ;Просмотр вперёд

          mov ah,0E4h                    ;Атрибут выводимых символов 0E4h – красный по жёлтому

cycle:        lodsb                                ;Загрузка в al очередного символа (al ← ds:si)

          stosw                           ;Выгрузка “символ + атрибут” из ах в видеобуфер (ax→es:di)

          loop cycle                         ;Повторить msglen раз

          

;Поля данных в сегменте данных программы.

                 msg             db                 ‘*TEST*’

          msglen         =                   $-msg

          

Изложенный выше способ вывода текста форматируется длиной видеостроки без учёта символов переноса или отступов от левой границы. Внесение элементарных правил текстового редактора в процедуру вывода сильно усложнит программу. В этом случае для вывода сообщений целесообразно использовать функции BIOS.

Разработка структуры программ, осуществляющих просмотр произвольных видеостраниц, на которые предварительно записана информация способом прямого программирования видеобуфера, удобно производить с применением функции 05int 10BIOS (п. 8.2.3.2).

8.2.3. СПРАВОЧНЫЕ ДАННЫЕ ПО ФУНКЦИЯМ BIOS

8.2.3.1. Прерывание int 10h. Видеофункции BIOS

¨  Функция 00h. Установка видеорежима (табл. 3.2) текущей видеостраницы с очисткой экрана (быстрая очистка экрана реализуется функцией 06h и 07h).

Вызов: AH = 00h,

Al = видеорежим (код режима задаётся в младших 7 битах, установка в 1 старшего бита запрещает очистку экрана).

Вызов разрушает регистры AX, BP, SI, и DI.

Таблица 3.2

Текстовые видеорежимы и страницы в стандарте VGA, поддерживаемые 
современными видеоконтроллерами

Режим

Тип

Разрешение

Цвет

Размер знака

Адрес

Страницы

0

text

40x25

16

полутонов

9x16

B8000

0 – 7

1

text

40x25

16/8

9x16

B8000

0 – 7

2

text

80x25

16

полутонов

9x16

B8000

0 – 7

3

text

80x25

16/8

9x16

B8000

0 – 7

6

graphic

640x200 / 80x25

2

8x8

B8000

0

7

text

80x25

3 (Mono)

9x16

B0000

0

10h

graphic

640x350 / 80x25

4 или 16

8x14

A0000

0 – 1

11h

graphic

640x480 / 80x30

2 (Mono)

8x16

A0000

0

12h

graphic

640x480 / 80x30

16

8x16

A0000

0

13h

graphic

640x480 / 80x30

256

8x8

A0000

0

 

 

По умолчанию в DOS используется режим 3 (впрочем, корректно оформленная программа должна выполнять проверку или установку требуемого текстового режима с последующим восстановлением прежнего).

¨  Функция 02h. Установка позиции курсора.

Задаёт положение курсора на экране в текстовых координатах, с которых в дальнейшем будет выводиться текст. Отсчёт номера строки и столбца ведётся от верхнего левого угла. Курсор можно установить как в текстовом, так и в графическом режиме, однако, в графическом режиме курсор не виден. BIOS поддерживает до восьми независимых курсоров – по одному на каждую страницу (см. табл. 3.2) независимо от того, какая страница является активной. Функцию 02h BIOS можно использовать в комбинации с функциями DOS для организации вывода на экран.

Вызов:    AH = 02h;        BH = номер страницы (0,1,...7), обычно 0;

  DH = строка;      DL = столбец.

Вызов разрушает регистры AX, BP, SI и DI.

¨  Функция 03h. Считывание позиции и размера курсора.

Возвращает текущие координаты состояния курсора на выбранной странице. Это даёт возможность временно перейти для работы на другое место экрана, а затем вернуться на старое место. Функцию 03hBIOS можно использовать в комбинации с функциями DOS для организации вывода на экран.

Вызов:    AH = 03h,        BH = номер страницы (0,1,...7), обычно 0.

Возврат:       DH, DL = строка и столбец текущей позиции курсора,

                     CH, CL = первая и последняя строки развёртки курсора.

Вызов разрушает регистры AX, BP, SI и DI.

 

¨  Функция 05h. Установка видеостраницы.

Устанавливает активную видеостраницу (как текстовую, так и графическую).

Вызов:    AH= 05h,     AL= номер страницы (0,...,7).

Вызов разрушает регистры AX, BP, SI и DI.

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

¨  Функция 06h (07h). Инициализация или прокрутка окна вверх (вниз).

Инициализирует окно с указанными координатами, пробелами ASCII с заданным атрибутом (AL = 0), или прокручивает содержимое окна вверх (вниз) на заданное число строк (AL = число строк). При прокрутке появляющиеся снизу (сверху) строки заполняются пробелами ASCII с заданным атрибутом. Функцию удобно использовать для быстрой очистки экрана или некоторого прямоугольного окна.

Вызов:        AH = 06h(07h);

               AL = 0 – очистка, AL = N (N  >0) – прокрутка на N строк;

               BH = атрибут символов в окне;

               CH, CL = координаты строки и столбца (Y,X) левого верхнего угла;

                   DH, DL = координаты строки и столбца (Y,X) правого нижнего угла.

Вызов разрушает регистры AX, BP, SI, и DI.

¨  Функция 08h. Чтение символа и атрибута в текущей позиции курсора на выбранной странице.

Вызов:    AH = 08h,                     BH = номер страницы (0,...,7), обычно 0.

Возврат: AH = атрибут символа,      AL = ASCII-код символа.

Вызов разрушает регистры BP, SI и DI.

¨  Функция 09h. Запись символа с заданным атрибутом на экран в позицию курсора. Действует как в графическом, так и в текстовом режимах. В графическом  режиме символы не должны переходить на следующую строку. Все коды в AL рассматриваются как символьные и не управляют положением курсора. После вывода символа курсор смещается к следующей позиции функцией 02h. Коэффициент повторения позволяет выводить строки одинаковых символов. В текстовом режиме символ выводится с указанным в BL атрибутом. В графическом – содержимое BL влияет только на цвет символа, но не на фон под ним. Графическое изображение под знакоместом затирается.

Вызов: AH  =09h,                                  AL = ASCII-код символа,

BL = атрибут символа (текстовый режим) или только цвет символа (графический режим),

                     BH = номер страницы (0,1,...7),   CX = коэффициент повторения.

Вызов разрушает регистры AX, BP, SI и DI.

¨  Функция 0Ah. Запись символа с текущим атрибутом на экран в позицию курсора. Функция действует как в графическом, так и в текстовом режимах. Символ принимает атрибут, установленный ранее для этой позиции. Все ASCII-коды в AL рассматриваются как символьные и не управляют положением курсора (также как и в функции 09h). После вывода символа курсор смещается к следующей позициифункцией 02h.

Вызов:    AH = 0Ah,                             AL = ASCII-код символа,

                       BH = номер страницы (0,1,...7), CX = коэффициент повторения.

Вызов разрушает регистры AX, BP, SI и DI.

¨  Функция 0Eh. Запись символа с текущим атрибутом в режиме телетайпа.

Записывает символ ASCII в позицию курсора (предварительно установленную функцией 02h) на активной странице и смещает курсор к следующей позиции. Коды ASCII: 07h – звонок (BEL), 08h – шаг назад(BS), 0Dh – возврат каретки (CR), 0Ah – перевод строки (LF), рассматриваются как управляющие и выполняются соответствующие им действия. Остальные управляющие коды рассматриваются как символы и выводятся на экран. Действует автоматический перевод курсора на следующую строку после завершения предыдущей, а также прокрутка экрана вверх на 1 строку после заполнения самой нижней.

Вызов: AH = 0Eh,                       AL = ASCII-код символа,

BL = цвет символа (только для графического режима),

BH = номер страницы (0,1,...7), по умолчанию действует активная страница.

¨  Функция 0Fh. Получить режим дисплея и номер текущей страницы.

Вызов:  AH = 0Fh.

Возврат:   AL = режим дисплея,   AH = ширина экрана в текстовом формате

BH  =номер активной страницы.

Вызов разрушает регистры BP, SI и DI.

Пример. Процедура установки позиции курсора на текущей странице.

Входdh = строка (0 – 25), dl = столбец (0 – 79)

Proc                     SetCursor

                            .......                               ;Сохранить регистры (по необходимости)

                            Mov ah,0Fh

                            Int 10h

                            Mov ah,02h

                            Int 10h

                            ..........                            ;Восстановить регистры

Endp                    SetCursor

¨  Функция 10h. Подфункция 03h. Переключение бита "мерцание/яркость".

Определяет назначение старшего бита 7 атрибута символа: мерцание символа или повышенная яркость фона.

Вызов:    A= 1003h,                       BL = назначение 7-го бита атрибута:

0 – повышенная яркость, 1 – мерцание (устанавливается по умолчанию).

Функция воздействует сразу на все символы экрана, у которых установлен старший бит атрибута фона.

¨  Функция 13h. Запись строки символов с заданными атрибутами.

Записывает строку в текущую страницу видеобуфера, начиная с указанной позиции. Коды ASCII07h – звонок, 08h – шаг назад, 0Ah – перевод строки, 
0Dh – возврат каретки, рассматриваются как управляющие, остальные – как символьные.

Вызов:    AH = 13h,              AL = режим записи:

0 – атрибут символа в BL, строка содержит только коды символов, после записи курсор принимает исходное положение (т.е. вывод следующей строки, если не изменить позицию курсора, начинается с изначально установленной позиции);

1 – отличается от режима 0 тем, что после записи курсор остаётся в конце строки;

2 – строка содержит попеременно коды символов и атрибутов (т.е. каждый символ описывается 2 байтами – ASCII-кодом и атрибутом), после записи курсор принимает исходное положение;

3 – отличается от режима 2 тем, что по окончании вывода курсор остаётся в конце строки.

BH = номер страницы (0,1,...7),        BL = атрибут для режимов 0 и 1,

CX = длина символьной строки (в длину входят только коды символов, но не байты атрибутов),

DX = DH.DL = координаты курсора (строка, столбец) в исходной точке вывода строки на экране,

ES:BP = адрес начала строки в памяти.

Обратите внимание на особенность задания адреса!

8.2.3.2. Рекомендации по использованию видеосервиса BIOS

1. Программы (учебный практикум), выполняемые в операционной среде DOS, используют по умолчанию текстовый режим 3, страницу 0.

2. Программы более широкого назначения должны запрашивать текущий видеорежим и страницу (функция 0Fh, int 10h) с последующим их применением в используемых функциях BIOS.

                        .......

                   Mov ah,0Fh                        ;Запрос текущего режима

                        Int 10h

                        Mov v_mode, al                  ;Сохраним режим

                        Mov current_page, bh         ;Сохраним строку

3. Если программа выводит изображение на разные страницы, то последовательность действий с каждой страницей может быть следующей (предполагается режим по умолчанию с "0" – страницей):

–     установка страницы функцией 05h;

–     установка позиции курсора функцией 02h;

–     построчное форматирование текста BIOS или DOS.

В дальнейшем может быть организован циклический просмотр содержания страниц путём их переключения функцией 05h, int 10h. При выходе из программы обязательно восстанавливаем искомую "0"-страницу. Сделать это, к примеру, можно так.

                        ..........

continue:

                        ..........

;Анализ буфера клавиатуры функцией DOS 06h int 21h с целью её завершения нажатием ;произвольной клавиши

                        mov ah,06h                         ;Функция ввода без ожидания

                        mov dl,0FFh                       ;Ввод

                        int 21h

                        jnz out_program                  ;zf=0, есть символ, на выход

                        jmp continue                       ;zf=1, символа нет, продолжим работу

out_program:                                              ;Восстановим страницу функцией 05h, int 10h

                        ..........

exit:                  mov ax,4C00h                    ;Вызов функции завершения программы

                        int 21h

                        End start

Страницы видеобуфера могут быть последовательно отформатированы и способом непосредственного программирования памяти. Выбор страниц при этом осуществляется соответствующей инициализацией сегментного регистра ES (см. п. 8.2.2). Просмотр содержимого страниц также может быть выполнен путём их последовательного переключения с помощью функции 05h, int 10h.

4. Структура демонстрационной программы, исследующей функцию "мерцание – яркость фона" (функция 10h, подфункция 03h, int 10h).

;Очистка экрана

                        ..........

;Инициализация 2-х локальных окон, каждое со своим атрибутом и текстом. При задании

;атрибутов цвета старший (7-ой по номеру) бит выбран равным "1".

                        .........

continue:                                                     ;Включим мерцание

                        mov ah,10h

                        mov al,03h

                        mov bl,1                             ;Мерцание

                        int 21h                                ;

;Введём задержку на 3 сек

                        .........

;Включим повышенную яркость

                        .........

;Введём задержку на 3 сек

                        .........

;Анализ буфера клавиатуры функцией DOS 06h int 21h с целью её завершения нажатием

;произвольной клавиши

                        .........

                        jnz out_program                  ;zf=0, есть символ, на выход

                        jmp continue                       ;zf=1, символа нет, продолжим работу

out_program:                                              ;Восстановим мерцание (по умолчанию)

                        ..........

exit:                  mov ax,4C00h                    ;Вызов функции завершения программы

                        .........

5. Если в программе организован бесконечный цикл вывода данных на экран функциями BIOS (09h, 0Ah, 0Eh, 13h), то его нельзя будет аварийно прервать с помощью нажатия клавиш Ctrl+C (т.е. выйти из программы, как это можно сделать при использовании соответствующих функций DOS). Чтобы можно было это сделать, включите в тело цикла функцию 0Bh прерывания Int 21h.

8.2.3.3. Прерывание int 16h

¨  Функция 00h (10h). Чтение символа клавиатуры с ожиданием.

Читает из кольцевого буфера ввода символ и скан-код. После считывания они удаляются из буфера и возвращаются в регистре AXЕсли буфер пуст, ожидает ввода. Каждой клавише на клавиатуре соответствует так называемый скан-код, соответствующий только этой клавише. Этот код посылается клавиатурой при каждом нажатии и отпускании клавиши и обрабатывается в BIOS обработчиком прерывания Int 09h. Функция 00h даёт возможность получить код нажатия, не перехватывая этот обработчик. Если нажатой клавише соответствует ASCII-символ, то:

AL – ASCII-код символа,   AH – скан-код клавиши.

Если нажатой клавише соответствует расширенный ASCII-код, то:

AL – 00h,                            AH – расширенный ASCII-код.

Вызов:    AH = 00h (83/84-key).

Возврат: AL = ASCII-код символа, изображённый на клавише/00h,

               AH = скан-код/расширенный ASCII-код клавиши.

Функция 10h (AH = 10) – усовершенствованный вариант функции 00h для расширенной клавиатуры (101/102-key). Позволяет получить расширенные 
ASCII-коды для клавиш F11, F12, а также для ряда других комбинаций. 
В качества признака управляющих клавиш или их комбинаций, помимо значения 00h, используются 0Ah, 0Dh и E0h.

¨  Функция 01h (11h). Поверка буфера клавиатуры на наличие в нём символа.

Определяет, имеются ли в кольцевом буфере ожидающие ввода символы; возвращает флаг ожидания и сам символ при его наличии. Однако символ и его скан-код не извлекаются из буфера и могут быть снова получены при повторном вызове функции 00h Int 16h. Данная функция относится к числу асинхронных: определив состояние буфера ввода, она возвращает управление про-
грамме.

Вызов:    AH = 01h (83/84-key),         11h(101/102-key).

Возврат: ZF = 1, если буфер пуст и ZF = 0, если в буфере имеется ожидающий считывания символ. В этом случае:

AL = ASCII-код символа/00h,  AH = скан-код клавиши/расширенный ASCII-код.

Функция 11h (AH = 11h) – усовершенствованный вариант функции 01h для расширенной клавиатуры (101/102-key). Позволяет получить расширенные ASCII-коды для клавиш F11, F12, а также для ряда других комбинаций. В качестве признака управляющих клавиш или их комбинаций, помимо значения 00h, используются 0Ah, 0Dh и E0h.

¨  Функция 02h (12h). Получение флагов клавиатуры.

Возвращает байт флагов клавиатуры, описывающих состояние управляющих клавиш, записанное в байте (слове) области данных BIOS по адресу 0000h:0417h.

Вызов:    AH = 02h

Возврат: A L=1-ый байт флагов клавиатуры.

Биты байта имеют следующие значения:

 

               0:  1 – правая Shift нажата

               1:  1 – левая Shift нажата

               2:  1 – Ctrl (любая) нажата

               3:  1 – Alt (любая) нажата

4:  1 – режим Scroll Lock

5:  1 – режим Num Lock

6:  1 – режим Caps Lock

7:  1 – режим Insert активен

 

Функция 12h (AH = 12h) – усовершенствованный вариант функции 02для расширенной клавиатуры (101/102-key). Выводит такое же значение байта, как и функция 02h, по адресу 0000h:0417h, и, дополнительно, второй байт статуса клавиатуры (адрес 0000h:0418h) со следующими значениями:

      0:  1 – левая Ctrl нажата              4:  1 – нажата Scroll Lock

      1:  1 – левая Alt нажата                5:  1 – нажата Num Lock

      2:  1 – правая Ctrl нажата            6:  1 – нажата Caps Lock

      3:  1 – правая Alt нажата              7:  1 – нажата SysReg

8.2.3.4. Задержка программных операций

Программные задержки используются в тех случаях, когда в какой-либо точке программы надо приостановить её выполнение на некоторое время. По виду исполнения программные задержки делятся на два типа: задержки, реализуемые на основе выполнения программой "пустых" вложенных циклов, и задержки, реализуемые на основе системного таймера компьютера. В листинге 3.2 приведён пример реализации задержки первого типа.

Листинг 3.2. Программная задержка на основе выполнения вложенных циклов с командой Loop.

Proc                delay                     ;Подпрограмма задержки

                        Mov cx, N            ;N – счётчик внешнего цикла

Outer:              push cx                 ;Сохраним содержание счётчик внешнего цикла

                        Mov cx,0              ;Обеспечим максимальное число повторений (64К раз)

                                                    ;внутреннего цикла

Inner:               loop Inner             ;Внутренний цикл

                        Pop cx                  ;Восстановим содержание счётчик внешнего цикла

                        Loop Outer           ;Повторим вешний цикл N раз

Endp                delay

В листинге 3.2 параметр N выполняет роль масштабного множителя времени задержки

tзад = N*исполнения внутреннего цикла.

При этом наименьшей единицей времени (т.е. "тиком") является время выполнения внутреннего цикла, состоящего, в свою очередь, из времени исполнения 65535 раз команды Loop. Параметр Nподбирается экспериментально для получения tзад (в мсек или сек) с учётом быстродействия конкретного компьютера.

Из рассмотрения данного примера очевидны недостатки данного подхода, когда требуется обеспечить выполнение временной задержки в программе, независимо от типа используемого компьютера.Поэтому разумно определять время программной задержки непосредственно по таймеру. Выходные сигналы таймера с частотой 18,2 раза в секунду не зависят от производительности компьютера и играют роль счетчика суточного времени. Реализация данного способа использует функцию 00h прерывания BIOS Int 1Ah.

Int 1Аh, функция 00h. Чтение счетчика циклов таймера.

Обработчик прерывания BIOS от системного таймера (Int 8) подсчитывает количество прерываний (каждые 55 мсек или 18,2 раза в секунду) в двойном слове памяти с адресом 0040h:006Сh. Данная функция возвращает накопленное значение (двоичный код) и сбрасывает его в 0. В регистре AL возвращается 0, если содержимое счетчика не превысило значения, соответствующего 24 часам (при достижении этого значения счетчик сбрасывается), иначе возвращается AL = 1.

Вызов:        АН = 00h.

Возврат:     СХ:DX – число тактов системного времени от полуночи,

                          AL – флаг перехода через сутки.

Примеры возвращаемых значений в СХ:DX:

1 сек             12h или 18,

1 минута       04 44h или 1092,

1 час             1 00 07h или 65543,

24 часа                   18 00 B0h или 1 573 040.

Для задержек меньших 14 секунд можно пользоваться только младшим байтом регистра DX

Листинг 3.3. B данном примере установлена задержка на 5 секунд, что соответствует 91 отсчету таймера

                            ..........

                            mov ah,0                   ;Функция "чтения" циклов таймера

                            int 1Ah                      ;Получаем значение счетчика циклов в cx:dx

                            add dx,91                  ;Добавляем 5 сек. к младшему слову в dx

                            mov bx,dx                 ;Запоминаем требуемое значение в bx и выполняем

                            ;постоянную проверку значений счетчика времени суток

repeat:                  int 1Ah                      ;Вновь получаем значение счетчика

                            cmp dx,bx                 ;Сравниваем с искомым

                            jne repeat                  ;Если не равно, то повторяем снова,

                                                       ;иначе задержка окончена

Если требуется введение задержки с высокой точностью, то необходимо использовать функцию 86h прерывания BIOS Int 15h. Она позволяет определить время задержки в микросекундах. Во время выполнения задержки разрешены прерывания. Управление программе возвращается после истечения заданного времени.

Int 15h, функция 86h

Вызов:    AH = 86h,  СX:DX = время задержки в мксек.

Возврат: CF = 0 – нормальное исполнение, CF = 1 – функция не поддерживается.

Пример: CX:DX = 0098h:9680h = 10 000 000 мксек = 10 сек.

8.3. ВАРИАНТЫ ИНДИВИДУАЛЬНОГО ЗАДАНИЯ

1.       Инициализировать экран с определённым атрибутом. Наложить на него локальное окно меньшего размера с другим атрибутом цвета. В центральную часть окна вывести текст (несколько строк) из памяти с циклической реализацией скроллинга окна в несколько строк вверх и вниз. Смена типа скроллинга задаётся программной задержкой  (2...3 сек.). Предусмотреть выход из программы.

2.       Инициализировать две видеостраницы, каждая со своим атрибутом и записанным текстом (некоторые символы текста обязательно должны иметь отличный от других цвет). Организовать циклическую смену видеостраниц с периодом 2...3 сек. Предусмотреть выход из программы с восстановлением текущей страницы.

3.       На экране инициализировать 2 локальных окна. Каждое окно со своим атрибутом и текстом с несколькими строками. Организовать циклическое переключение атрибутов первого окна на второе и обратно. Цикл переключения задаётся временной задержкой в 2...3 сек. Предусмотреть выход из программы.

4.       На экране инициализировать 2 локальных окна. Каждое окно со своим атрибутом и текстом в несколько строк. Организовать циклическое переключение текста из одного окна в другое с временной задержкой 2...3 сек. Предусмотреть выход из программы.

5.       На экране инициализировать окно_1 с атрибутом и текстом в несколько строк. Спустя время задержки 2...3 сек частично наложить на него окно_2 с другим атрибутом и текстом. Процесс зациклить. Предусмотреть выход из программы.

6.       На экране инициализировать локальное окно с атрибутом (и текстом), сообщить ему дрейф в горизонтальном (вертикальном) направлении. При достижении границы экрана окно изменяет дрейф в противоположную сторону. Шаг движения локального окна в пространстве экрана должен быть во много раз меньше размеров самого экрана.

7.       На экране инициализировать локальное окно с атрибутом (и текстом). После нажатия командной клавиши окно начинает изменять свои размеры (пульсировать), увеличиваясь и уменьшаясь с определённым периодом. Временной шаг изменения размера окна должен быть много меньше периода 
пульсации.

8.       Инициализировать экран и локальное окно в нём со своими атрибутами. Организовать режим вывода текста в локальное окно с клавиатуры. Предусмотреть возможность редактирования текста, а также скроллинга окна при его заполнении.

9.       Инициализировать экран и два небольших локальных окна в нём. С помощью клавиши <Tab> организовать переключение курсора из одного окна в другое. Выбранное клавишей <Tab> окно приобретает повышенную яркость. Предусмотреть выход из программы.

10.   Инициализировать экран и два локальных окна в нём. В левое окно вывести первую половину таблицу ASCII, а в правое – вторую половину. Предусмотреть очистку окон и выход из программы.

11.   Инициализировать экран и два локальных окна в нём (каждое со своим атрибутом и текстом). Организовать циклическое переключение бита "яркость фона/мерцание". Выход из программы должен восстанавливать значение бита по умолчанию.

12.   Инициализировать экран и два локальных окна в нём. В левое окно вывести  вторую половину таблицы ASCII c символами псевдографики. Используя навигацию курсора, c помощью клавиш (¬,­,®,¯)организовать возможность непрерывного воспроизведения прямых линий во втором окне.

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

Вход: DS:SI – адрес ASCI-строки, AH – атрибуты;

               CX – число выводимых символов;

               DH/DL – строка (row)/столбец (clm);

               Indent_L, Indent_R – поля отступа (в столбцах) слева и справа.

Необходимо оптимизировать расчёт адреса видеобуфера ES:DI. Процедура должна возвращать исходное значение регистра ES.

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

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

8.4. КОНТРОЛЬНЫЕ ВОПРОСЫ

1.   Краткая характеристика возможностей, предоставляемых программисту базовой системой ввода-вывода BIOS, в сравнении с сервисными функциями DOS.

2.   Назовите объём видеопамяти для изображения одного символа и, соответственно, одной видеостраницы монитора в текстовом режиме.

3.   Дайте характеристику атрибута символа в видеобуфере.

4.   Разработайте макросы для:

¨  очистки экрана с установкой курсора в левый верхний угол экрана;

¨  позиционирования курсора в произвольную точку экрана с запоминанием его координат в памяти с помощью переменных row и clm;

¨  вывода сообщения mes длиною leng и атрибутом цвета attrib с позиции, определяемой переменными row и clm.

5.   Какая функция BIOS предоставляет пользователю исчерпывающую информацию о нажатой клавише клавиатуры.