Функции bios int 16h сервис клавиатуры


Содержание

Аппаратное обеспечение IBM PC

2.4. Средства BIOS для работы с клавиатурой

Набор функций для работы с клавиатурой, предоставляемый в распоряжение программиста прерыванием BIOS INT 16h, включает в себя функции для выборки кода нажатого символа из буфера с ожиданием нажатия, функции для проверки содержимого буфера и для управления содержимым буфера, функции для изменения скоростных характеристик клавиатуры.

2.4.1. Чтение символа с ожиданием

Функция 00h выполняет чтение кода символа из буфера клавиатуры, если он там есть. Если буфер клавиатуры пуст, программа переводится в состояние ожидания до тех пор, пока не будет нажата какая-нибудь клавиша. Скан-код и ASCII-код нажатой клавиши передаются программе.

Приведем формат вызова функции:

Приведем таблицу скан-кодов для клавиатуры IBM PC/XT:

Для остальных клавиш функция 00h прерывания INT 16h возвращает расширенный ASCII-код:

В следующей таблице приведены скан-коды клавиш, имеющихся только на 101-клавишной клавиатуре:

Буква «Д» в последней таблице обозначает дополнительную («калькуляторную») клавиатуру.

Для демонстрации использования функции 00h прерывания INT 16h мы подготовили программу, выводящую на экран скан-коды и ASCII-коды нажимаемых клавиш:

2.4.2. Проверка буфера на наличие в нем символов

Функция 01h поможет вам проверить состояние буфера клавиатуры — есть там коды нажатых клавиш или нет. При этом программа не переводится в состояние ожидания, даже если буфер клавиатуры пуст. В этом случае в регистре флагов устанавливается в единицу флаг ZF и управление возвращается программе.

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

Кроме того, функцию можно использовать вместе с функцией 00h для сброса содержимого клавиатурного буфера. Для этого в цикле повторяют вызов функции 01h, вслед за которым идет вызов функции 00h при условии, что буфер клавиатуры не пуст. Сброс клавиатурного буфера полезно выполнять перед вводом ответственной информации, так как из-за случайного двойного или тройного нажатия на клавишу в буфере клавиатуры могут оказаться лишние символы.

Приведем текст программы, выводящей на экран в цикле символ ‘*’. При нажатии на любую клавишу, кроме ESC, программа выводит на экран строку текста — инструкцию для завершения работы программы. Если нажать на клавишу ESC, работа программы будет завершена.

2.4.3. Получение состояния переключающих клавиш

Функция возвращает в регистре AL состояние переключающих клавиш (Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock, Ins). Формат байта состояния соответствует формату байта, находящегося в области данных BIOS по адресу 0000h:0417h:

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

Изменим текст предыдущей программы таким образом, чтобы завершение ее работы происходило лишь в том случае, если переключающая клавиша CapsLock находится в выключенном состоянии (соответствующий светодиод не горит):

2.4.4. Установка временных характеристик клавиатуры

Мы уже рассказывали о возможности изменения временных характеристик клавиатуры. Если BIOS, установленная в вашей машине, изготовлена после 15 декабря 1985 года, вы можете воспользоваться этой функцией для ускорения (или замедления) работы клавиатуры.

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

2.4.5. Запись символов в буфер клавиатуры

С помощью этой функции можно вставить символы в буфер клавиатуры, как будто они были введены оператором.

Приведенная программа записывает в буфер клавиатуры пять символов ‘*’. Запустите ее и посмотрите на системное приглашение. Вы увидите что-нибудь похожее на C:\>*****.

2.4.6 Чтение символа с ожиданием для 101-клавишной клавиатуры

Функция 10h полностью аналогична функции 00h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу.

Приведем формат вызова функции:

Функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

2.4.7. Проверка буфера на наличие в нем символов для 101-клавишной клавиатуры

Функция 11h полностью аналогична функции 01h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу.

Эта функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

2.4.8. Получение состояния переключающих клавиш для 101-клавишной клавиатуры

Функция возвращает в регистре AL состояние переключающих клавиш (Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock, Ins):

Функция 12h аналогична функции 02h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу и имеет другой формат байта состояния.

Эта функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

Bios INT 16h

Функция 00h — чтение символа с клавиатуры.

Выход: АН — скан код

Функция 01h— чтение статуса клавиатуры.

Выход: АН — скан-код

флагZ: если 0, то в буфере есть символ, если 1 — нет символа.

Функция 02h— Флаги, возвращаемые клавиатурой.

Выход:AL — байт статуса клавиатуры:

бит 0 — нажат правыйShift;

бит 1 — нажат левыйShift;

бит 2 — нажата клавишаCtrl;

бит 3 — нажата клавишаAlt;

бит 4 — Scroll Lock в положенииON;

бит 5 — Num Lock в положенииON;

бит 6 — Caps Lock в положении ON;

бит 7 — Insert в положенииON.

Давайте теперь поговорим о такой вещи как скан-коды. Если вы считаете, что при нажатии клавиши А обработчик клавиатуры также получает код символа А, то вы ошибаетесь. К сожалению, это не так. Обработчику посылается скан-код. Более того, он посылается дважды — при нажатии и отпускании клавиши. В видеоиграх нас будут интересовать не столько ASCII-коды, сколько нажатия клавиш A, S, Пробел, которые обычно отвечают за маневры, стрельбу и т. д. Таким образом, нам надо знать, как получить именно скан-коды. И это все, что требуется. В таблице 3.2 перечислены скан-коды клавиш.

Таблица 3.2. Таблица скан-кодов.

Клавиша Скан-код Клавиша Скан-код Клавиша Скан-код Клавиша Скан-код
Esc I Z F7
O X F8
P C F9
[ V F10
] B F11
Enter N F12
Ctrl M Num Lock
A Запятая Scroll Lock
S Точка Home
D / Up
F Правый Shift PgUp
= G Print Screen Серый —
Backspace H Alt Left
Tab J Пробел 5 на цифр. клав.
Q K Caps Lock Right
W L F1 Серый +
E ; F2 End
R Апостроф F3 Down
T F4 PgDn
Y Левый Shift F5 Ins
U \ F6 Del

Если вы внимательно изучали таблицу, то должны, были заметить, что клавиши; имеющие двухсимвольную кодировку, обладают, тем не менее, только одним скан-кодом. Это происходит потому, что каждый скан-код может быть дополнен информацией о статусе клавиш. Кроме того, благодаря таблице 3.2, мы теперь сами можем по скан-коду определять код ASCII.

Мы должны иметь возможность определять:

§ Была ли нажата какая-нибудь клавиша;

§ Какая была нажата клавиша;

§ Статус клавиши Shift.

Статус клавиш — это просто битовый вектор (последовательность), со­держащий информацию о клавишах Shift, Alt, Ctrl и других. Эта последова­тельность находится в памяти по адресам 417h и 418h. Мы не будем читать эти ячейки напрямую, а воспользуемся BIOS и Си.

Листинг 3.4 содержит код, позволяющий получить статус клавиш.

Ввод информации с клавиатуры при помощи функций BIOS

Клавиатура является основным устройством ввода алфавитно-цифровой информации, а часто — и основным средством управления работой компьютера. Для ввода информации с клавиатуры можно использовать либо функции операционной системы, либо прямой опрос контроллера клавиатуры. Мы не будем рассматривать функции MS-DOS, используемые для ввода данных с клавиатуры, так как они достаточно подробно описаны в литературе [3, 10], но непригодны для сколько-нибудь серьезной работы. Функции DOS имеют два очень серьезных недостатка. Первый недостаток заключается в том, что они не позволяют полностью реализовать возможности функциональных клавиш. Второй недостаток — клавиатурные функции DOS предназначены для работы в режиме терминала (с построчным выводом информации сверху вниз и прокруткой изображения снизу вверх). В процессе считывания символа они выполняют ряд дополнительных операций, что делает весьма неудобным их использование в любом другом, не терминальном режиме.

Функции BIOS обладают гораздо более широкими возможностями, чем функции DOS. Этих возможностей вполне достаточно для выполнения любых операций реальном режиме работы процессора. Вызов клавиатурных функций BIOS выполняется по прерыванию Int 16h. Рассмотрим эти функции.

Прерывание Int 16h, функция 00h: прочитать символ с клавиатуры

Функция 00h считывает символ из буфера клавиатуры и выдает его ASCII-код и скан-код (символ после считывания будет удален из буфера клавиатуры).

Перед вызовом прерывания требуется записать в регистр АН значение 00h.

После выполнения функции в регистры будет помещена следующая информация:

• в АН — скан-код символа;

• в AL — ASCII-код символа.

При нажатии управляющих клавиш функция выдает ASCII-код со значением 0, благодаря чему их легко можно отличить от алфавитно-цифровых. Однако друг от друга управляющие клавиши, таким образом, отличаются только по скан-кодам.

Прерывание Int 16h, функция 01 h: получить состояние клавиатуры

Функция Olh проверяет наличие символа в буфере клавиатуры. Если символ присутствует в буфере, функция выдает его ASCII-код и скан-код (не удаляя символ из буфера).

Перед вызовом прерывания требуется записать в регистр АН значение Olh.

После выполнения функции при отсутствии символа в буфере будет установлен флаг ZF. При наличии символа в буфере флаг ZF будет сброшен и в регистры помещена следующая информация:

• в АН — скан-код символа;

• в AL — ASCII-код символа.

Данная функция применяется в тех случаях, когда для управления работой программы используется не только клавиатура, но и другие устройства. Простейший способ работы в этом случае — поочередный циклический опрос всех источников информации. Использовать функцию, аналогичную 00h, нельзя — она заблокирует опрос всех остальных устройств до тех пор, пока не будет введен какой- либо символ с клавиатуры. Поэтому в цикле осуществляется только контроль поступления новой информации, а считывание информации выполняется вне цикла.

Прерывание Int 16h, функция 02h: получить состояние флагов клавиатуры

Функция 02h выдает содержимое байта флагов BIOS. Перед вызовом прерывания требуется записать в регистр АН значение 02h.

После выполнения функции регистр AL содержит описание состояния флагов:

• бит 0 — правая клавиша Shift (0 — не нажата, 1 — нажата);

• бит 1 — левая клавиша Shift (0 — не нажата, 1 — нажата);

• бит 2 — клавиша Ctrl (0 — не нажата, 1 — нажата);

• бит 3 — клавиша Alt (0 — не нажата, 1 — нажата);

• бит 4 — переключатель Scroll Lock (0 — выключен, 1 — включен);

• бит 5 — переключатель Num Lock (0 — выключен, 1 — включен);

• бит 6 — переключатель Caps Lock (0 — выключен, 1 — включен);

• бит 7 — переключатель Insert (0 — выключен, 1 — включен). Функция 02h имеет один серьезный недостаток, который сильно ограничивает возможность ее использования совместно с функцией 00h: никак не фиксируется момент изменения состояния управляющих клавиш. Если было выполнено две операции, одна из которых изменила состояние алфавитно-цифровой клавиши, а другая — состояние управляющей клавиши, то далеко не всегда можно определить, какая из операций произошла раньше.

Прерывание Int 16h, функция 03h: управление режимом автоповтора

Функция 03h устанавливает характеристики режима автоповтора.

Перед вызовом прерывания требуется записать в регистры следующую информацию:

• в АН — значение 03h;

• в AL — значение 05h;

• в ВН — код, задающий значение задержки автоповтора (табл. 1.4);

• в BL — код, задающий скорость повторения (табл. 1.5).

Иллюстрированный самоучитель по задачам и примерам Assembler

Функции BIOS для работы с консолью

Бросая в воду камешки, смотри на круги, ими образуемые;
иначе бросание будет пустой забавой.

Козьма Прутков

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

Что касается языка ассемблера, то собственных средств обмена с консолью у него нет. Чтобы выполнить подобную операцию, программа использует возможности самого компьютера (прерывания BIOS) и операционной системы, в среде которой эта программа работает. Каждый программист самостоятельно ищет решение проблемы обмена с консолью. Так как эта задача актуальна всегда, то есть необходимость на конкретных примерах показать порядок использования средств BIOS и ОС для обмена с консолью в программах на ассемблере. Примеры не очень сложны, и читатель легко сможет быстро встроить их в свои программы.

В контексте нашего изложения ROM BIOS (Read Only Memory Basic Input Output System) представляет собой совокупность программ в энергонезависимой памяти компьютера, одной из задач которых является устранение специфики аппаратных компонент компьютера для функционирующего на нем программного обеспечения, включая операционную систему. Обслуживание клавиатуры и монитора выполняют программы BIOS, называемые драйверами. Структурно драйверы состоят из ряда подпрограмм, называемых функциями, каждая из которых выполняет определенные действия.

Обращение к функциям BIOS производится аналогично обращению к функциям MS DOS. Для работы с клавиатурой и экраном BIOS содержит два программных прерывания – 16h и 10h, обращение к которым, исходя из вышесказанного, является обращением к драйверам этих устройств. Для вызова этих прерываний, как обычно, используется команда INT – int 16h или int 10h. Для выполнения определенной операции в регистре АН указывается номер функции. При необходимости в других регистрах может указываться дополнительная (параметрическая) информация. Ниже рассмотрим подробнее возможности BIOS для работы с консолью.

Функции BIOS для работы с клавиатурой

Прерывание 16 BIOS имеет функции для различных типов клавиатур: обычной – 84 клавиши и двух типов расширенной клавиатуры – 101\102 и 122-клавишной.

Выяснить функциональные возможности клавиатуры позволяет функция 09h:

Выход: AL = битовое поле, установленные биты которого обозначают поддерживаемые функции:

  • 7 – резерв;
  • 6 – поддержка клавиатуры со 122 клавишами (и функций 20h-22h (int 16h));
  • 5 – поддержка расширенной клавиатуры со 101-102 клавишами (и функций 10h-12h (int 16h));
  • 4 – поддержка функции 0Ah (int 16h);
  • 3 – поддержка функции 0З06h (int 16h);
  • 2 – поддержка функции 0305h (int 16h);
  • 1 – поддержка функции 0304h (int 16h);
  • 0 – поддержка функции 0З00h (int 16h).

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

OcOh прерывания int 15h.

Вход: АН = COh получить конфигурацию.

Выход: CF = 1 – BIOS не поддерживает эту функцию;

  • CF – 0 – в случае успеха;
  • ES:BX – адрес конфигурационной таблицы в ROM-памяти;
  • АН = состояние (00h – успех; 86h – функция не поддерживается).

Ввод информации с клавиатуры средствами BIOS

Интерфейсом программ в персональном компьютере с клавиатурой является прерывание 16h BIOS. Далее приводится описание его функций.

АН = 00h — чтение с ожиданием двухбайтового кода из буфера клавиатуры. Прочитанный код возвращается в регистре АХ: младший байт — в регистре AL, старший — в АН. Если нажата ASCII-клавиша, в AL помещается ASCII-код символа, в АН — скэн-код. При нажатии специальных клавиш AL равен 0, а в АН возвращается расширенный скэн-код.

АН = 0lh — чтение без ожидания двухбайтового кода из буфера клавиатуры. Если буфер пуст, в 1 выставляется флаг нуля ZF. В противном случае в АХ возвращается двухбайтовый код из буфера клавиатуры, но продвижение указателя «головы» буфера не производится, т.е. код «остается» в буфере.

АН = 02h — определение состояния шифт- и триггерных клавиш. В регистре AL возвращается содержимое байта по адресу 40:17h (см. табл. 4.1).

Функция АН = 05h не имеет аналогов в библиотеке Turbo С и может использоваться для имитации нажатии клавиш в демонстрационных программах, программах переноса текста и т.д.

Функции АН = 10 — 12h являются аналогами функций 00 — 02h, но предназначены для использования в компьютерах с клавиатурой 101 /102 клавиши.

Функции АН = 00 — 02h прерывания 16h BIOS положены в основу функции bioskey() библиотеки Turbo С. Далее следует описание этой функции.

int bioskey(int cmd)

Обращается в зависимости от значения в cmd к функциям АН = 00 — 02h прерывания 16h. Возвращаемое функцией значение повторяет значение регистра АХ при выходе из прерывания.

Предварительная подготовка к работе

1.Ознакомиться с аппаратными средствами компьютера для ввода информации с клавиатуры.

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

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

1. Разработать, написать и отладить программу управления пе­ремещением символа (например, «*») в пределах заданного на экране окна.

Таблица 4.2. Варианты заданий

№ варианта X1 Y1 X2 Y2 Вид движения Клавиши управления Номер прерывания
Постоянное СтВВ, СтВН INT 21h
Пошаговое СтВП, СтВЛ INT 21h
Постоянное F1, F2 INT 21h
Пошаговое Все направления INT 21h
Постоянное F5, F6 INT 16h
Пошаговое F1-F4 INT 16h
Постоянное F9-F12 INT 16h
Пошаговое СтВВ, СтВН INT 16h
Постоянное СтВП, СтВЛ INT 21h
Пошаговое Все направления INT 21h
Постоянное F3, F4 INT 21h
Пошаговое F7, F8 INT 21h
Постоянное СтВВ, СтВН INT 16h
Пошаговое СтВП, СтВЛ INT 16h
Постоянное F9, F10 INT 16h
Пошаговое F11, F12 INT 16h
Постоянное СтВВ, СтВН INT 21h
Пошаговое СтВП, СтВЛ INT 21h
Постоянное F5, F10 INT 21h
Пошаговое F6, F12 INT 21h

Для управления использовать клавиши из набора: «стрелка вверх» (СтВВ), «стрелка вниз» (СтВН), «стрелка вправо» (СтВП), «стрелка влево» (СтВЛ) или функциональные клавиши Fl — F12 (варианты см. в таблице 4.2). Для ввода использовать стандартные функции языка C++. Сохранить отлаженную программу.

2. Изменить программу, заменив стандартные функции библиотеки C++ своими. Для написания функций используйте заданное прерывание (см. табл. 4.2), если его возможностей достаточно. Если его возможностей не достаточно, то замените его по своему усмотрению. Сохраните отлаженную программу.

3. Отлаженные программы предъявить преподавателю.

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

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

2. Алгоритмы и тексты отлаженных программ.

4.8. Контрольные вопросы

1. Что относится к устройствам ввода информации в ЭВМ?

2. Как можно классифицировать устройства ввода?

3. Назовите основные характеристики устройств ввода информации.

4. Зачем нужен буфер клавиатуры?

5. Почему существует ввод с буферизацией и без нее?

6. Какие бывают прерывания?


7. Зачем для ввода данных с клавиатуры используют прерывания?

8. Какое прерывание вырабатывается при нажатии клавиши?

9. Назовите основные характеристики системы прерываний.

10. Почему нужны программные прерывания?

11. Почему для организации ввода с клавиатуры используются два программных прерывания INT 21h и INT 16h?

12. Какие функции библиотеки C++ для ввода с клавиатуры Вы знаете?

13. Какие функции прерывания INT 16h Вы знаете?

14. Какие функции прерывания INT 21h Вы знаете?

15. Можно ли в прикладной программе обойтись без ввода с клавиатуры?

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

ИСПОЛЬЗОВАНИЕ АППАРАТНЫХ ПРЕРЫВАНИЙ

Цель работы – знакомство с различного вида аппаратными прерываниями и создание собственных подпрограмм обработки прерываний.

Общие положения

Микропроцессоры 8086/88 поддерживают механизм прерываний. В самом общем виде это наличие в аппаратуре специальных средств, с помощью которых выполнение текущей программы приостанавливается и процессор переходит к так называемой программе обслуживания прерывания (Interrupt Servise Routine — ISR). Механизм прерываний позволяет организовать выполнение тех или иных функций ядра и быструю реакцию процессора на возникновение каких-то внешних со­бытий: ошибок в арифметических операциях, изменению состояния пе­риферийных устройств и пр.

Микропроцессоры 8086/88 поддерживают 256 прерываний. Каждое из них имеет свой номер и ISR. Адрес точки входа в ISR называется вектором прерывания и хранится в специальной таблице, называемой таблицей векторов прерывания (ТВП). Код ISR может располагаться в любом месте памяти. Поэтому вектор прерывания занимает 4 байта: 2 байта отво­дится на значение сегментного регистра, устанавливаемое в CS (старшее слово), 2 байта — на значение смещения, уста­навливаемое в IP (младшее слово). Вся ТВП занимает 256 * 4 = 1024 байт и располагается в оперативной памяти, начиная с адреса 0000:0000.

При возникновении прерывания процессор помешает в стек 6 байт: текущее значение CS, текущее значение IP (пара этих регистров определяет точку, с которой выполнение прерываемой программы возобновится), а также 2 байта флагов процессора. В CS и IP устанавливаются значения из ТВП, которые задают адрес начала ISR. Прерыванию 0 соответствует вектор прерывания по адресу 0000:0000, прерыванию 1 — по адресу 0000:0004h, прерыванию 2 — по адресу 0000:0008h и т.д.

Сама ISR — это программа, построенная с соблюдением специальных правил:

1) в самом начале она сохраняет в стеке все регистры процессора, которые будут использоваться в этой программе;

2) перед завершением работы программы значения регистров восстанавли­ваются;

3) последней инструкцией ISR, как правило, является инструкция возврата из прерывания IRET. Выполняя IRET, процессор извлекает из стека шесть слов информации, которые последовательно помещает в регистры IP, CS и регистр фла­гов, возвращаясь к исполнению прерванной программы.

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

Некоторые векторы прерывания в ТВП на самом деле задают не точки входа в ISR, а используются для хранения важной системной информации: адресов данных и таблиц. Кроме того, за некоторые векторы «зацеплены» ISR, не выполняющие никаких действий. Они служат заглушками для подключения дополнительных обработчиков. Так, например, в нормальном состоянии обработчик прерывания 1Ch не выполняет никаких действий и содержит единственную инструкцию возврата из прерывания IRET. Прерывание 1Ch вызывается из пределов ISR таймера (обработчик прерывания 8). Прерывание от таймера, в свою очередь, генерируется 18.2 раза в секунду аппаратурой системного таймера. Есть и другие обработчики — заглушки, вызываемые при функционировании ISR BIOS и MS-DOS.

Аппаратные прерывания

В процессе функционирования персонального компьютера могут встретиться четыре типа прерываний:

3) исключительные ситуации процессора (processor exceptions);

Аппаратные прерывания возникают как результат некоторых внешних событий и в их генерации принимает участие специальная микросхема персонального компьютера — программируемый контроллер прерываний, или PIC (Programmable Interrupt Controller). Наиболее часто для этих целей используется одна или несколько микросхем 8259А либо их функциональные эквиваленты. В архитектуре компьютеры IBM PC AT используют PIC, построенный на двух микросхемах 8259А (рис. 5.1).

Микросхема 8259А рассчитана на 8 входов запросов прерываний, обозначаемых IRQ (Interrupt Request). Сигналы на них возбуждают внешние устройства: адаптеры асинхронной последовательной и параллельной связи, плата системного таймера и др. Контроллер прерываний имеет в своем составе ряд программируемых внутренних регистров, определяющих особенности обработки запросов прерываний.

Рис 5.1. Двухкаскадная схема построения

Выход ведущей (единственной в однокаскадной схеме) микросхемы 8259А контроллера прерываний подается на специальный вход процессора (INTR). Этот вход процессора является маскируемым: если флаг маскирования прерываний IF равен единице, процессор способен «ощущать» изменение состояния линии INTR (прерывания разрешены); если же IF сброшен в 0, изменения на линии INTR не влияют на работу центрального процессора. Поэтому часто аппаратные преры­вания, в формировании которых принимает участие PIC, называют маскируемыми. Если прерывания разрешены и устанавливается высокий потенциал на линии INTR, процессор завершает исполнение текущей инструкции и отвечает двумя циклами сигнала INTA.

Первый цикл сигнала INTA — это, по существу, пустой цикл, который готовит PIC к следующему циклу. Во время второго цикла PIC помещает на шину данных байт, задающий номер аппаратного прерывания. Получив байт номера прерывания, процессор умножает его на 4, формируя смещения до вектора прерываний в ТВП.

Процессор сохраняет в стеке текущее значение регистров флагов CS и IP, затем устанавливает в 0 флаг IF, а в CS и IP — значения из вектора прерывания. В результате управление передается в ISR.

Для того чтобы различать сигналы прерываний от различных внешних устройств, система прерываний IBM PC построена следующим образом. Каждое внешнее устройство подключено к собственной линии запроса прерываний IRQ. При получении сигнала на линии IRQ контроллер прерываний передает в процессор уникальный для данной IRQ байт номера прерывания. Соответствие линий IRQ и номеров прерывания задается программированием контроллера прерываний. Такое программирование выполняется в ходе начальной загрузки системы специальной процедурой BlOSa и в дальнейшем обычно не изменяется. В принципе, перепрограммирование PIC может выполняться в любой момент и некоторые программы (Windows, OS/2) используют это при своей загрузке. В ходе программирования PIC задаются старшие 5 бит номера прерывания, а младшие 3 бита генерирует микросхема 8259А, определяя двоичный код номера линии IRQ. Ведущая (единственная) микросхема программируется BIOSом так, чтобы передавать в процессор прерывания от 08h до 0Fh. Ведомая 8259А в IBM PC AT настраивается на передачу номеров прерываний от 70h до 77h.

Кроме отображения IRQ на номера прерывания, PIC выполняет упорядочивание по приоритету одновременно возникающих запросов. Обычно наивысший приоритет имеет запрос на линии IRQ0, затем в порядке убывания IRQI, IRQ2, . IRQ7. Вход процессора INTR является так называемым «уровнем чувствительным». Это значит, что если процессор ощущает высокий уровень, он всегда начинает цикл обработки прерывания. Если начатая ISR устанавливает IF в единицу (а это, как правило, так и бывает), сохранение сигнала на линии INTR вызовет повторное вхождение в ту же самую ISR, a затем вхождение в третий, четвертый и далее раз до тех пор, пока не переполнится стек. Для того чтобы этого не происходило, контроллер прерываний блокирует генерацию сигнала INTR для текущей активной линии IRQ до тех пор, пока исполняемая ISR не даст явного указания сделать это. Обычно так ISR обозначают свое завершение, посылая в PIC команду завершения прерывания, или EOI (End Of Interrupt). Если ISR не сделает этого, контроллер продолжает блокировать выработку сигнала INTR для всех последующих запросов прерывания как по данной линии, так и по другим, менее приоритетным линиям.

Любая из линий запросов IRQi может быть маскирована. Специальный внутренний регистр PIC хранит битовую маску входов IRQi: бит 0 регистра маски управляет IRQ0 (IRQ8 в ведомой микросхеме 8259А), бит 1 — IRQI (IRQ9), . бит 7 — IRQ7 (IRQ15). Если бит равен нулю контроллер генерирует сигнал на линии INTR, если бит равен единице, контроллер не «чувствует» запрос на маскированной битом линии IRQi.

Использование двухкаскадной схемы для построения контроллера прерываний расширяет до 15 чисто обслуживаемых внешних устройств. Для двухкаскадной схемы выход INTR ведомой микросхемы 8259А подается на линию LRQ2 ведущей микросхемы. В результате линии запросов упорядочиваются по приоритету следующим образом: максимальный приоритет имеет IRQ0, затем в порядке убывания IRQI, IRQ8, . IRQ15, IRQ3, . IRQ7. Как правило, PIC в ходе начальной загрузки настраивается так, что для линий IRQ0 — IRQ7 генерируются прерывания с номерами 08h — 0Fh соответственно, а для линий IRQ8 — IRQ15 — прерывания с номерами 70h — 77h. Подключение внешних устройств персональных компьютеров к линиям IRQ и, следовательно, закрепление аппаратных пре­рываний для большинства персональных компьютеров типа IBM PC фактически стандартизовано. В табл. 5.1 приводится закрепление внешних устройств и аппаратных прерываний для IBM PC AT.

Таблица5.1. Использование прерываний в IBM PC AT

indbooks

Читать онлайн книгу

12.8. Сервисы и прерывания BIOS

Системная BIOS предоставляет ряд сервисов низкого уровня, в основном предназначенных для обслуживания ввода-вывода и имеющих отношения к стандартным аппаратным интерфейсам. Традиционные сервисы BIOS обычно вызываются в реальном режиме или V86 посредством инструкций программных прерываний ( Int xx ). Большинство сервисов может быть вызвано и через фактически стандартизованные точки входа (адреса в области ROM BIOS) дальними вызовами процедур ( CALL Far ) с предварительным помещением в стек регистра флагов (сервисы построены как обработчики прерываний). Все традиционные сервисы BIOS работают в 16-разрядном режиме процессора, и ими можно пользоваться в реальном режиме, V86 и малопривлекательном 16-разрядном защищенном режиме.

Для процессоров 386+ оптимальным по эффективности является 32-разрядный защищенный режим. Для того чтобы из этого режима можно было пользоваться сервисами BIOS (правда, не всеми) без промежуточных переключений, по инициативе фирмы Phoenix ввели 32-разрядные вызовы BIOS32. Адрес точки входа BIOS32 заранее не известен, но известен способ его нахождения: в диапазоне адресов памяти 0E0000-0FFFFFh на границе параграфов (младшие 4 бита адреса нулевые) ищется строка-сигнатура « _32_ » (число 325F5F33h) заголовка, за которой следует физический адрес точки входа. Сами сервисы вызываются дальними вызовами точки входа в сервис. Номер, параметры вызываемых функций и результаты передаются на регистрах процессора.

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

♦ Int 00h — деление на 0;

♦ Int 01h — пошаговый режим;

♦ Int 03h — точка останова;

♦ Int 04h — переполнение;

♦ Int 06h — недопустимая команда 286+;

♦ Int 07h — вызов отсутствующего NPU.

♦ Int 02h — немаскируемое прерывание;

♦ Int 08h — таймер 8253/8254;

♦ Int 09h — клавиатура;

♦ Int 0Ah — IRQ2/9 ;

♦ Int 0Bh — IRQ3 ;

♦ Int 0Ch — IRQ4 ;

♦ Int 0Dh — IRQ5 ;

♦ Int 0Eh — IRQ6 — контроллер гибких дисков;

♦ Int 0Fh — IRQ7 ;

♦ Int 70h — CMOS-таймер;

♦ Int 71h — IRQ9 (перенаправлено на Int 0Ah );

♦ Int 72h — IRQ10 ;

♦ Int 73h — IRQ11 ;

♦ Int 74h — IRQ12 (контроллер мыши PS/2);

♦ Int 75h — IRQ13 — исключение сопроцессора;

♦ Int 76h — IRQ14 — контроллер жестких дисков;

♦ Int 77h — IRQ15 .

ПРИМЕЧАНИЕ

Прерывания Int 70h — 77h имеют место только в AT.

Функции ROM BIOS (16-битные сервисы):

♦ Int 05h (F000:FF54h) — печать экрана;

♦ Int 10h — видеосервис;

♦ Int 11h — чтение списка оборудования (слово из BDA 0040:0010h), возвращает в АХ :

• биты 15:14 — число обнаруженных LPT-портов: 00 — 0, …, 11 — 3;

• бит 12 — обнаружен игровой адаптер;

• биты 11:9 — число обнаруженных СОМ-портов: 000 — 0, …, 111 — 7;

• бит 8 — наличие контроллера DMA;

• биты 7:6 — число обнаруженных НГМД: 00 — 1, …, 11 — 4;

• биты 5:4 — активный видеорежим: 00 — резерв, 10 — 80-колоночный цветной, 01 — 40-колоночный цветной, 11 — монохромный;

• биты 3:2 — размер ОЗУ на системной плате (теперь обычно 00);

• бит 1 — присутствие математического сопроцессора;

• бит 0 — присутствие дисководов;

♦ Int 12h — размер непрерывной памяти;

♦ Int 13h — дисковый сервис (блочный ввод-вывод);

♦ Int 14h — обслуживание СОМ-портов;

♦ Int 15h — AT-функции (системный сервис, функции определяются значением АН / АХ ):

• 00-03h — управление и обмен данными с кассетным магнитофоном (были когда-то и такие «стриммеры»!) на старых PC;

• 4fh — перехват клавиатуры;

• 53xxh — сервисы управления потреблением АРМ (Advanced Power Management);

• 8300h — запуск таймера, устанавливающего флаг в заданной ячейке;

• 8301h — сброс того же таймера;

• 84h — джойстик (см. п. 8.6);

• 86h — программируемая задержка;

• 87h — перемещение блока расширенной памяти;

• 88h — получение размера расширенной памяти;

• 89h — переключение в режим V86;

• C0h — получение системной конфигурации, при успешном выполнении ( CF =0, AH =0) ES:BX указывает на таблицу данных конфигурации;

• 80-82h, 85h, 90h, 91h — функции многозадачных ОС (BIOS устанавливает заглушки);

♦ Int 16h — клавиатурный ввод-вывод;

♦ Int 17h — обслуживание LPT-портов;

♦ Int 18h — процедура восстановления при неудаче начальной загрузки (прежде — ROM-Basic);

♦ Int 19h — начальная загрузка (вызов процедуры Bootstrap);

♦ Int 1Ah — системное время, дата, будильник и 16-битные вызовы сервисов PCI;

♦ Int 1Bh — обработчик нажатия клавиш Ctrl+Break ;

♦ Int 1Ch — User Timer Interrupt, процедура, вызываемая обработчиком Int 08h каждые 55 мс; BIOS устанавливает простую заглушку ( IRET ), но программы могут перехватывать это прерывание; на время отработки этой процедуры все аппаратные прерывания запрещены (кроме NMI).

♦ Int 33h — поддержка мыши;

♦ Int 4Ah — обработчик будильника пользователя, установленного функцией BIOS Int 1Ah (6); прерывание вызывается асинхронно, так что при возврате из процедуры все регистры и флаги должны быть в том же состоянии, что и при входе; BIOS ставит заглушку ( IRET );

♦ Int 67h — EMS-функции.

Указатели на таблицы :

♦ Int 1Dh — видеопараметры;

♦ Int 1Eh — параметры дискет;

♦ Int 1Fh — знакогенератор СGA;

♦ Int 41h — параметры HDD 0;

♦ Int 46h — параметры HDD 1;

♦ Int 43h — знакогенератор EGA.

12.8.1. Int 09h, Int 16h — поддержка клавиатуры

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

Прерывания , вызванные приходом кодов нажатия и отпускания клавиш , обрабатывает BIOS Int 9h . Каждый принятый скан-код (или цепочка) обрабатывается с учетом состояния клавиатурных флагов . Результат обработки (как правило, ASCII-символ в младшем байте и скан-код в старшем) помещается в клавиатурный буфер , расположенный в ОЗУ. По приему каждого символа указатель головы буфера увеличивается. Буфер организован в виде кольца, после достижения конца области буфера указатель головы установится на начало области. В случае переполнения буфера (указатель головы «догнал» указатель хвоста) очередное слово не записывается, и подается звуковой сигнал. Размер позволяет хранить описание шестнадцати фактов нажатий клавиш. Нажатие клавиш Ctrl , Shift , Alt и некоторых комбинаций в буфере не отмечается, но приводит к модификации бит ячеек флагов клавиатуры. Нажатие «системной» комбинации Ctrl+Alt+Del , клавиши PrintScreen ( SysRq ) и некоторых других к записи в клавиатурный буфер не приводит, а вызывает специальные процедуры.

Для обслуживания клавиатуры используются ячейки ОЗУ из области данных BIOS (BIOS Data Area):

♦ 0:0417, 0:418 — флаги клавиатуры;

♦ 0:0419 — аккумулятор кода Alt -набора;

♦ 0:041А — указатель головы буфера (Buffer Head), 2 байта (модифицируется при помещении символа в буфер);

♦ 0:041C — указатель хвоста буфера (Buffer Tail), 2 байта (модифицируется при извлечении символа из буфера);

♦ 0:041E-0:042D — область кольцевого буфера (16 слов).

Обработчик аппаратного прерывания до обработки принятого скан-кода вызывает прерывание BIOS Int 15h с AH =4Fh, а в AL находится принятый скан-код. Стандартный обработчик Int 15h (4Fh) просто выполняет возврат с CF =0, но его можно заменить специальным обработчиком, который будет при необходимости подменять принятые скан-коды на какие-либо иные (оставляя их в AL ), что должно отмечаться установкой CF =1. В старых версиях BIOS такой возможности перехвата не было, ее наличие можно определить вызовом Int 15h (C0h).

Для клавиатуры USB или иного устройства ввода, заменяющего клавиатуру в качестве консоли, прерывание Int 9h должно вызываться программно при обработке каждого клавиатурного события. Обработчик этого прерывания должен выполнять те же действия: скан-код пропускать через Int 15h (4Fh) и помещать в клавиатурный буфер, а также модифицировать флаги клавиатуры.

Интерфейс прикладного уровня для клавиатуры представляет BIOS Int 16h . Его основное назначение — извлечение слов из клавиатурного буфера. Функция задается в регистре АН при вызове, результат помещается в регистр АХ .

♦ АН = 00h — чтение (с ожиданием готовности) и выборка слова из буфера (меняется указатель хвоста). Индикаторы клавиатуры обновляются в соответствии с состоянием флагов. Если буфер пуст, то на AT выполняется прерывание Int 15h (подфункция 90), что может использоваться ОС, например, для переключения задач. Чтобы программа не «зависала» на ожидании символа, предварительно стоит проверить готовность функцией 01h. Символы расширенной клавиатуры фильтруются — преобразуются в их аналоги 83-клавишной клавиатуры.

♦ АН = 01h — проверка готовности, чтение без выборки (указатели не изменяются). Признак наличия символа в буфере — установленный флаг ZF .

♦ АН = 02h — чтение состояния флагов (в AL — байт 0:417h, см. выше).

♦ АН = 03h — установка задержки и частоты автоповтора: BL — код задержки (00=250, 01=500, 02=750, 03=1000 мс), ВН — код частоты (см. п. 9.2.1).

♦ АН = 05h — запись слова из регистра СХ в буфер (меняется указатель головы). Признак успешной записи — AL =0, если в буфере нет места, то AL =1.

♦ АН = 10h и AH = 11h — функции, аналогичные 00h и 01h, но предназначены специально для 101/102-клавишных клавиатур — в них не выполняется фильтрация символов расширенной клавиатуры. Для ряда клавиш, отсутствующих в клавиатуре АТ-84, эти функции дадут результаты, отличающиеся от вызовов 00h и 01h.

♦ AH =12h — чтение расширенного состояния флагов (в АХ — слово KbdShiftFlags101Rec ), в котором младший байт совпадает с тем, что дает функция 02h (слово из 0:417h), а старший байт похож на слово из 0:418h. Назначение бит АХ :

• бит 0 — клавиша Shift (правая) нажата;

• бит 1 — клавиша Shift (левая) нажата;

• бит 2 — клавиша Ctrl (любая) нажата;

• бит 3 — клавиша Alt (любая) нажата;

• бит 4 — включен индикатор Scroll Lock ;

• бит 5 — включен индикатор Num Lock ;

• бит 6 — включен индикатор Caps Lock ;

• бит 7 — включен режим Insert ;

• бит 8 — клавиша Ctrl (левая) нажата;

• бит 9 — клавиша Alt (левая) нажата;

• бит 10 — клавиша Ctrl (правая) нажата;

• бит 11 — клавиша Alt (правая) нажата;

• бит 12 — клавиша Scroll Lock нажата;

• бит 13 — клавиша Num Lock нажата;

• бит 14 — клавиша Caps Lock нажата;

• бит 15 — клавиша SysReq нажата.


Функции чтения буфера (00 и 10h) в регистре AL возвращают ASCII-код символа, в АН — скан-код . Символы, полученные нестандартным способом (в русском регистре или Alt -набором), сопровождаются нулевым скан-кодом. Alt -набор позволяет ввести в буфер любой символ — для этого его код в десятичной системе набирается на цифровой клавиатуре при нажатой клавише Alt , результат заносится в буфер при отпускании клавиши Alt .

При AL =0 регистр АН содержит расширенный ASCII-код (Extended ASCII Keystroke). Дополнительные клавиши 101/102 клавиатур при использовании функций 10h-12h генерируют код E0h в младшем байте и скан-код, соответствующий аналогичным управляющим клавишам 83/84-клавишных клавиатур.

Функция записи (05h), несколько неожиданная для клавиатуры, позволяет легко имитировать работу оператора для различных демонстрационных программ. Если прикладная программа не перехватывает обслуживание клавиатуры на уровне аппаратного прерывания ( Int 9h ), то резидентная программа может ей «подбрасывать» слова в буфер, которые будут восприниматься как нажатие клавиш.

ASCII-коды буфера, соответствующие нажатию клавиш, приведены в [1, 7]. При русификации (или другой локализации) клавиатуры отслеживание переключения регистров (языков) ложится на обработчик аппаратного прерывания клавиатуры.

12.8.2. Int 10h — видеосервис

Int 10h — видеосервис — предназначен для работы с графическим адаптером. Его первичной задачей является управление видеорежимом (BIOS Video Mode), определяющим формат экрана. BIOS адаптера должна выполнять программирование всех стандартных и специфических управляющих регистров для установки (смены) требуемого видеорежима и выбранных параметров развертки — кроме нее о способах этих переключений остальное ПО может и не знать.

В пределах возможностей установленного видеорежима видеосервис предоставляет возможности отображения информации на различных уровнях. Простейший для программиста телетайпный режим позволяет посылать поток символов, которые будут построчно отображаться на экране с отработкой символов возврата каретки, перевода строки, обеспечивая «прокрутку» изображения при заполнении экрана. Есть функции и для полноэкранной работы с текстом, при которой доступны и атрибуты символа. В графическом режиме имеется возможность чтения и записи пиксела с указанными координатами. Однако видеосервисом Int 10h программисты пользуются далеко не всегда, поскольку работает он довольно медленно. Подробно рассматривать функции видеосервиса не будем (этому посвящены отдельные книги), отметим особо лишь функцию телетайпного вывода Int 10h (0Eh). При вызове AH =0Eh, в AL — код выводимого символа, в BL — цвет (только для графического режима). Символ выводится в текущую позицию курсора, и курсор сдвигается на следующую, переходя на новую строку после конца предыдущей и прокручивая экран при его заполнении. Специальные символы вызывают возврат на начало строки ( CR , код 0Dh), перевод строки ( LF , 0Ah) и короткий гудок ( BEL , 07h). Этой функцией часто пользуются для вывода сообщений программами, работающими на нижнем уровне (например, модули инициализации ПЗУ расширений BIOS, загрузчики и другие, не имеющие еще доступа к сервисам операционных систем). Программа вывода получается простейшей, работает на всех адаптерах и во всех режимах, но довольно медленно.

12.8.3. Int 13h — поддержка дисков

Функции дискового сервиса вызываются программным прерыванием Int 13h .

Традиционно дисковый сервис подразделяет физические диски на дискеты (diskette) и фиксированные диски (fixed disk). Набор функций (табл. 7.8) для этих классов устройств несколько различается как по составу, так и по реализации. Классы различаются по диапазонам номеров физических устройств: для дискет отводятся номера 0-7Fh (реально только 0–3), а для фиксированных дисков — 80h-FFh.

Контроллеры дисковых интерфейсов, имеющие в своем составе дополнительные модули BIOS, перехватывают вектор Int 13h , беря на себя обслуживание своих устройств. Когда в IBM PC/XT появились жесткие диски со своим контроллером, модуль BIOS этого контроллера, инициализирующийся во время теста POST, вставал на место Int 13h , а указатель на исходный обработчик дискового сервиса (драйвер НГМД из системной BIOS) сохранялся на месте Int 40h . Хотя поддержка жестких дисков давно уже включена в системную BIOS, ради совместимости возможность использования прерывания Int 40h для вызова драйвера гибких дисков сохраняется. Интерфейс этого вызова совпадает с Int 13h , но номер устройства (в регистре DL ) не должен превышать 7Fh.

Кроме функций дискового сервиса ( Int 13h ) c дисковыми устройствами связаны еще и векторы, обслуживающие аппаратные прерывания от контроллера НГМД — Int 0Eh (линия IRQ 6 ) и от контроллера жестких дисков — Int 76h (линия IRQ 14 ). При наличии двухканального порта ATA второй канал обычно задействует линию IRQ 15 (вектор 77h). В XT контроллер жестких дисков занимал линию IRQ 5 (вектор 0Dh). Дополнительные контроллеры дисков могут использовать и другие прерывания. Аппаратные прерывания вырабатываются контроллерами по завершении (нормальному и аварийному) внутренних операций. На эти прерывания BIOS не реагирует, а при инициализации их векторы направляются на программную заглушку (инструкцию IRET ).

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

Традиционный сервис BIOS

Традиционный дисковый сервис работает в 16-разрядном режиме процессора, все параметры вызова передаются через регистры процессора. Адрес сектора задается в системе CHS и размещен весьма специфично. Сервис вызывается программным прерыванием Int 13h , при вызове принимаются следующие соглашения:

♦ номер функции задается в регистре АН и не должен превышать 3Fh;

♦ логический номер диска задается в регистре DL (бит 7 = 0 — признак обращения к НГМД);

♦ номер цилиндра (0-1023) задается в регистре СН (младшие 8 бит) и CL[7:6] (старшие 2 бита);

♦ номер головки (0-255) задается в регистре DH ;

♦ номер начального сектора (1-63) задается в регистре CL[5:0] ;

♦ количество секторов , участвующих в операции, 8 бит — в регистре AL (0-255);

♦ указатель на начало буфера оперативной памяти для считываемых и записываемых данных (address of buffer) — в регистрах ЕS:BX ;

♦ результат выполнения операции определяется по флагу переноса: СF = 0 — успешное выполнение операции, CF = 1 — обнаружены ошибки (код состояния возвращается в регистре АН , код завершения последней операции с дискетами хранится по адресу 40:41h, с жесткими дисками — 40:74h);

♦ таблица параметров диска для дискет (DPT) задана указателем в памяти по адресу 0:78h, для жестких дисков (HDPT) — 0:104h или 0:118h.

Список функций традиционного сервиса приведен в табл. 12.7, подробнее они описаны в [4, 9]. Устройства могут не поддерживать некоторые функции, о чем драйверы должны «честно сообщить» кодом возврата 01h.

Таблица 12.7. Функции традиционного дискового сервиса

Номер функции АН Назначение параметров Использование регистров указателей и таблиц
DL DH, CL, CH AL ES: BX DPT/HDPT
00h Reset Disk System — сброс дисковой системы (всех контроллеров и устройств), позиционирование на нулевой цилиндр
01h Read Status of Last Operation — чтение состояния последней операции +
02h Read Sectors into Memory — чтение секторов с диска в память + + + + +
03h Write Sectors from Memory — запись секторов из памяти на диск + + + +
04h Verify Sectors — верификация секторов (холостое чтение без записи в память и проверка CRC/ECC) + + + +
05h Format Desired Track — форматирование трека + + + + +
08h Get Drive Parameters — получение параметров диска +Ві +Ві +Ві +Ві
09hВ№ Initialize Drive Parameters — инициализация таблиц параметров диска + +
0AhВ№ Read Long — «длинное» чтение (сектор и поле ЕСС) + + + + +
0BhВ№ Write Long — «длинная» запись (сектор и поле ЕСС) + + + + +
0ChВ№ Seek — поиск цилиндра + +
0DhВ№ Alternative Disk Reset — альтернативный сброс (не затрагивая контроллера дискет) +
10hВ№ Test Drive Ready — проверка готовности +
11hВ№ Recalibrate — рекалибровка (позиционирование на нулевой цилиндр) +
14hВ№ Controller Internal Diagnostics — диагностика контроллера жестких дисков
15h Read DASD Туре — получение типа диска: АН=0 — нет диска; АН=1 — дискета, без датчика смены диска; АН=2 — дискета, с датчиком смены диска; АН=3 — жесткий диск; иные значения — код ошибки. CX: DX содержат число 512-байтных секторов на диске +
16hВІ Diskette Change Line Status — проверка статуса смены дискеты: CF=0: АН=0 — смены носителя не было; CF=1: AH=1 — недопустимый номер диска; АН=6 — была смена диска или определение смены не поддерживается; AH=80h — дисковод не готов или не установлен; иные значения — код ошибки +
17hВІ Set Diskette Type for Format — установка типа дискеты для форматирования (перед форматированием) + +Ві
18hВІ Set Media Type for Format — установка типа носителя (для форматирования) + +Ві
20hВІ Get Media Type — получение типа установленного носителя +
24hВ№ Set Multiple Mode — установка параметров режима многосекторного обращения (в AL — число секторов за операцию) + +
25hВ№ Identify Drive ATA — идентификация накопителя (только для ATA-дисков) + +

В№ Только для фиксированных дисков.

ВІ Только для дискет и других сменных носителей.

Ві Назначение отличается от обычного.

Формально традиционный сервис позволяет работать с дисками, имеющими до 1024Г—256Г—63 = 16 515 072 секторов (около 8,4 Гбайт). Ряд операционных систем имеет ошибку, не позволяющую использовать полный объем, допустимый данным сервисом. Для дисков объемом более 15 481 935 секторов следует пользоваться только функциями расширенного сервиса (см. ниже). Однако при работе с устройствами ATA имеется еще и барьер в 528 Мбайт. Дело в том, что контроллер жесткого диска ATA, на который ориентированы драйверы Int 13h , имеет только 4-битный регистр номера головки (а в BIOS — 6 бит). Правда, этот же контроллер способен принимать 16-битный номер цилиндра (в BIOS — 10 бит). Понятно, что непосредственно без искажений через эти два фильтра (формат вызова и формат регистров контроллера) может пройти только вызов с самыми жесткими ограничениями по каждой координате. Тогда ограничение, полученное тем же перемножением диапазонов координат, получается около 528 миллионов байт:

(2 10 = 1024 цилиндра) Г— (2 4 = 16 головок) Г— (2 6 – 1 = 63 сектора) Г— 512 байт = 528 482 304 байт.

Для преодоления 528-мегабайтного барьера дисков ATA, не трогая программного интерфейса, в BIOS ввели расширение традиционного дискового сервиса. Интерфейс ATA в трехмерной геометрии позволяет реализовать довольно большой (но уже не запредельный) объем диска:

(2 16 = 65 536 цилиндров) Г— (2 4 = 16 головок) Г— (2 8 – 1 = 255 сектора) Г— 512 байт = 136,9 Гбайт.

Чтобы достичь хотя бы интерфейсного ограничения BIOS (8,4 Гбайт), стали применять трансляцию параметров вызова функций Int 13h , которые будем теперь называть логическими, в физические [6] параметры, передаваемые контроллерам ATA-дисков. В функции, которая сообщает параметры диска (функция 8), производится обратная трансляция, так что на стороне вызова программного интерфейса Int 13h присутствуют только логические параметры. Естественно, логический объем диска не может превышать физического: (С Г— H Г— S)ЛОà ≤ (С Г— H Г— S)ФИЗ.

Подробнее о преодолении барьеров и способах трансляции (LBA, Large Disk, ECHS) см. в [1, 4, 9]

Расширенный сервис BIOS

Чтобы получить возможность работы через BIOS с дисками объема более 8,4 Гбайт, потребовалось ввести новые функции дискового сервиса.

Расширенный дисковый сервис BIOS, Enhanced Disk Drive Services (EDD), продвигаемый фирмой Phoenix Technologies LTD, реализуется многими разработчиками BIOS и устройств массовой памяти. Он позволяет работать с устройствами, имеющими объем до 2 64 секторов, эффективно используя архитектуру процессоров IA-32 и IA-64. Сервис оперирует линейным логическим адресом сектора (LBA). Вместо традиционных таблиц параметров дисков в нем используются новые, дающие исчерпывающую информацию об устройствах, их физической организации и интерфейсе. Устройства могут иметь сменные носители и сами быть съемными в процессе работы компьютера (например, подключенные к шине USB или IEEE 1394), так что понятие «сменяемость носителя» несколько размывается. Такие устройства должны поддерживать механизм уведомления о смене носителя и программное блокирование смены носителя. По прогнозам емкости данного интерфейса должно хватить на 15–20 лет.

Расширения BIOS Int 13h используют ОС Windows 95, Windows 98, Windows 2000. Правда, это использование ограничено лишь начальной загрузкой и процессом установки (FDISK, FORMAT), поскольку в регулярной работе применяются собственные 32-разрядные драйверы. Расширения BIOS Int 13h не используют DOS (все версии), Windows 3.1x, Windows NT, Novell NetWare, OS/2 Warp, Linux, Unix.

В настоящее время определены три набора функций:

♦ доступ к фиксированным дискам (fixed disk access subset) — функции 41-44h, 47h и 48h;

♦ блокировка и смена носителя (device locking and ejecting subset) — функции 41h, 45h, 46h, 48h и 49h;

♦ поддержка расширенных дисков (enhanced disk drive (EDD) support subset) — функции 41h и 48h.

Расширенный сервис, как и традиционный, вызывается программным прерыванием Int 13h с номерами функций свыше 3Fh (регистр АН ); номер устройства (регистр DL ) допустим в диапазоне 80h-FFh. Основные параметры вызова — начальный адрес блока, число секторов для передачи и адрес буфера — передаются через адресный пакет (device address packet). Формат пакета в сравнении с передачей параметров традиционного сервиса через регистры процессора довольно просторный.

Поскольку расширение BIOS может и отсутствовать, имеется функция проверки его наличия (номер 41h). Расширение может действовать избирательно (не для всех устройств), так что проверку надо производить для конкретного устройства, интересующего программу. Проверка дает номер версии расширения и карту поддерживаемых наборов функций. Функции расширенного чтения, записи, верификации и поиска (42h, 43h, 44h и 47h) по смыслу не отличаются от их аналогов из традиционного сервиса. Для работы со сменными носителями введены функции отпирания/запирания, извлечения и проверки факта смены носителя (45h, 46h и 49h). От идеологии традиционного сервиса сильно отличается функция получения параметров устройства (48h). Она возвращает в ОЗУ буфер с набором параметров и детальным описанием устройства, позволяющим ОС и приложениям работать с ним, минуя BIOS. Функция установка аппаратной конфигурации (4Eh) позволяет управлять режимом передачи (PIO, DMA), а также предварительной выборкой (поиском).

Для эмуляции дисков на загружаемых CD-ROM к сервисам BIOS Int 13h добавляется несколько новых функций:

♦ начать/завершить эмуляцию диска (4Ah/4Bh), начать эмуляцию диска и выполнить загрузку (4Ch);

♦ прочитать секторы загрузочного каталога (4Dh); функции 41-48h позволяют обращаться к любым логическим секторам CD-ROM (в режиме LBA с размером сектора 2048 байт), когда для данного привода включена эмуляция.

Подробнее расширенный сервис рассмотрен в [4].

12.8.4. Int 14h — поддержка СОМ-портов

СОМ-порты поддерживаются сервисом BIOS Int 14h , который обеспечивает описанные ниже функции.

♦ 00h — инициализация (установка скорости обмена и формата посылок, заданных регистром AL ; запрет источников прерываний). На сигналы DTR и RTS влияния не оказывает (после аппаратного сброса они пассивны).

♦ 01h — вывод символа из регистра AL (без аппаратных прерываний). Активируются сигналы DTR и RTS , и после освобождения регистра THR в него помещается выводимый символ. Если за заданное время регистр не освобождается, фиксируется ошибка тайм-аута и функция завершается.

♦ 02h — ввод символа (без аппаратных прерываний). Активируется только сигнал DTR ( RTS переходит в пассивное состояние), и ожидается готовность принятых данных, принятый символ помещается в регистр AL . Если за заданное время данные не получены, функция завершается с ошибкой тайм-аута.

♦ 03h — опрос состояния модема и линии (чтение регистров МSR и LSR ). Эту гарантированно быструю функцию обычно вызывают перед функциями ввода-вывода во избежание риска ожидания тайм-аута.

При вызове Int 14h номер функции задается в регистре АН , номер порта (0–3) — в регистре DX (0 — COM1 , 1 — COM2 …). При возврате из функций 0, 1 и 3 регистр АН содержит байт состояния линии (регистр LSR), AL — байт состояния модема (MSR). При возврате из функции 2 нулевое значение бита 7 регистра АН указывает на наличие принятого символа в регистре AL ; ненулевое значение бита 7 — на ошибку приема, которую можно уточнить функцией 3.

Байт состояния линии (регистр АН ) имеет следующий формат:

♦ бит 7 — ошибка тайм-аута (после вызова функции 2 — признак любой ошибки);

♦ бит 6 — регистр сдвига передатчика пуст (пауза передачи);

♦ бит 5 — промежуточный регистр передатчика пуст (готов принять символ для передачи);

♦ бит 4 — обнаружен обрыв линии;

♦ бит 3 — ошибка кадра (отсутствие стоп-бита);

♦ бит 2 — ошибка паритета принятого символа;

♦ бит 1 — переполнение (потеря символа);

♦ бит 0 — регистр данных содержит принятый символ.

Байт состояния модема (регистр AL при возврате из функций 0, 1, 3) имеет следующий формат:

♦ бит 7 — состояние линии DCD ;

♦ бит 6 — состояние линии RI ;

♦ бит 5 — состояние линии DSR ;

♦ бит 4 — состояние линии CTS ;

♦ бит 3 — изменение состояния DCD ;

♦ бит 2 — изменение огибающей RI ;

♦ бит 1 — изменение состояния DSR ;

♦ бит 0 — изменение состояния CTS .

При инициализации порта биты регистра AL имеют следующее назначение:

♦ биты [7:5] — скорость обмена:

• 000=110; 100=1200; 001=150; 101=2400;

• 010=300; 110=4800; 011=600; 111=9600 бит/с;

♦ биты [4:3] — контроль паритета:

• 01 — число единиц нечетное;

• 0 и 10 — без контроля;

♦ бит 2 — количество стоп-бит: 0–1 бит, 1–2 бита (на скорости 110 бит/с — 1,5 стоп-бит);

♦ биты [1:0] — длина посылки: 00 — 5 бит, 01 — 6 бит, 10 — 7 бит, 11 — 8 бит.

В процессе начального тестирования POST BIOS проверяет наличие последовательных портов (регистров UART 8250 или совместимых) по стандартным адресам и помещает базовые адреса обнаруженных портов в ячейки BIOS Data Area 0:0400, 0402, 0404, 0406. Эти ячейки хранят адреса портов с логическими именами COM1 — СОМ4 . Нулевое значение адреса является признаком отсутствия порта с данным номером. В ячейки 0:047С, 047D, 047Е, 047F заносятся константы, задающие тайм-аут для портов.

Обнаруженные порты инициализируются на скорость обмена 2400 бит/с, 7 бит данных с контролем на четность (even), 1 стоп-бит. Управляющие сигналы интерфейса DTR и RTS переводятся в исходное состояние («выключено» — положительное напряжение).

12.8.5. Int 17h — поддержка принтера

Сервисы BIOS Int 17h : обеспечивают инициализацию, вывод байта данных и опрос состояния принтера, подключенного к LPT-порту. При вызове функция задается в регистре АН , номер LPT-порта — в регистре DX.

♦ АН = 00h — вывод байта из регистра AL по протоколу Centronics (без аппаратных прерываний). Данные помещаются в выходной регистр, и, дождавшись готовности принтера (снятия сигнала Busy ), формируется строб.

♦ АН = 01h — инициализация интерфейса и принтера (установка исходных уровней управляющих сигналов, формирование импульса Init# , запрет аппаратных прерываний и переключение на вывод двунаправленного интерфейса).

♦ АН = 02h — опрос состояния принтера (чтение регистра состояния порта).

При возврате регистр АН содержит байт состояния , который собирается из бит регистра состояния SR[7:3] и программно формируемого флага тайм-аута. Биты 6 и 3 относительно байта, считанного из регистра состояния, инвертированы. Назначение бит байта состояния:

♦ бит 7 — не занято (сигнал Busy ); нулевое значение означает, что принтер занят (буфер полон или состояние Off-Line, или ошибка);

♦ бит 6 — подтверждение (сигнал Ack# ); единичное значение означает, что принтер подключен;

♦ бит 5 — конец бумаги (сигнал PaperEnd );

♦ бит 4 — принтер готов (сигнал Select ); нулевое значение означает, что принтер в состоянии Off-Line;

♦ бит 3 — ошибка принтера (сигнал Error# ); единичное значение соответствует ошибке;

♦ биты 2:1=00 (не используются);

♦ бит 0 — флаг тайм-аута, устанавливается при неудачной попытке вывода символа, если сигнал Busy не снимается в течение времени, определенного для данного порта в ячейках тайм-аута (в BIOS Data Area); в этом случае согласно протоколу Centronics строб данных не вырабатывается.

Перехват прерывания Int 17h является удобным способом внедрения собственных драйверов принтера. Потребность в них может возникать при подключении к порту принтера с интерфейсом ИРПР или необходимости перекодировки символов. Если разрабатываемый драйвер предназначен не только для перекодировки, но и изменения протокола (через Int 17h можно организовать вывод через LPT-порт по протоколу ИРПР и даже через СОМ-порт), следует внимательно отнестись к битам возвращаемого байта состояния. При их неправильном формировании попытки вывода на печать могут приводить к ошибочным сообщениям.

12.8.6. Int 1Ah и Int 15h — поддержка таймеров

Сервисы BIOS Int 1Ah позволяют считывать и модифицировать значения системного таймера, даты и времени , а также установки будильника часов реального времени CMOS RTC. Перечисленные ниже номера функций указываются при вызове в регистре АН .

1. АН =0 — чтение системного таймера (двойного слова по адресу 40:006Eh в BIOS Data Area, инкрементируемого по прерываниям от канала 0 счетчика- таймера 8253/8254 примерно раз в 55 мс. Таймер обнуляется при выполнении теста POST после аппаратного сброса). Возвращает значение таймера, в СХ — старшую часть, в DX — младшую. AL =0, если за последние 24 часа не было переполнения таймера. В современных версиях сброс AL возвращает счетчик переполнений таймера, хранящийся в ячейке 40:0070h (в старых версиях это был флаг).

2. АН =1 — установка системного таймера ( СХ — старшая часть, в DX — младшая) и сброс флага (счетчика) переполнения таймера в ячейке 40:0070h. В случае ошибки устанавливается флаг CF =1.

3. АН =2 — чтение времени из RTC. Возвращает в упакованном BCD-формате час (в регистре СН ), минуту ( CL ), секунду ( DH ) и признак коррекции летнего/зимнего времени ( DL =1 — коррекция используется, DL =0 — нет). Признаком успешной операции является флаг CF =0. Во избежание ошибок некоторых BIOS при вызове флаг CF должен быть сброшен.

4. АН =3 — установка времени в RTC, назначение регистров и признак результата аналогичен функции 2.

5. АН =4 — чтение даты из RTC. Возвращает в упакованном BCD-формате век (в регистре СН ), две старшие цифры года ( CL ), месяц ( DH ) и день ( DL ). Признаком успешной операции является флаг CF =0. Во избежание ошибок некоторых BIOS при вызове флаг CF должен быть сброшен.

6. АН =5 — установка даты в RTC, назначение регистров и признак результата аналогичен функции 4.

7. АН =6 — установка времени срабатывания будильника RTC. Возвращает в упакованном BCD-формате час (в регистре СН ), минуту ( CL ) и секунду ( DH ). Если будильник уже установлен, переустановка не производится и возвращается флаг CF =1. При срабатывании будильник вызывает прерывание Int 4Ah .

8. АН =7 — отмена установки будильника.

Функции BIOS Int 15h позволяют программировать таймер CMOS RTC — вводить задержку или запускать таймер установки флага, указывая время в микросекундах (СХ — старшее слово, DX — младшее). Нулевое значение интервала не вызывает никаких действий. Достижимое разрешение в зависимости от производительности ПК может достигать единиц миллисекунд, максимальная выдержка — около 70 часов. Перечисленные ниже номера функций указываются при вызове в регистре АН или АХ .

9. AH =86h — задержка на заданное время. Управление будет возвращено вызвавшему процессу только через указанный интервал. По окончании задержки будет установлен бит 7 в ячейке BDA 0040:00A0. Таймер может оказаться занятым, тогда вызов сразу возвратит флаг CF =1 (при успехе CF =0, а в AL окажется маска, записанная в 8259А#2).

10. AX =8300h — запуск таймера, устанавливающего флаг после указанной задержке бит 7 в ячейке, заданной регистрами ES : BX . При успешном запуске CF =0; если таймер занят (он один) — CF =1 и AL =0. Управление возвращается процессу сразу, а флаг будет установлен через заданное время. Перед завершением программа, запускавшая таймер, должна его сбросить функцией 8301h (во-первых, чтобы освободить; во-вторых, чтобы снять «адскую машинку», которая неожиданно сама может изменить значение ячейки памяти, вполне возможно уже задействованную другим, ничего не «подозревающим» процессом).

11. AX =8301h — сброс того же таймера.

12.8.7. PCI BIOS

Функции PCI BIOS используются только для поиска и конфигурирования устройств PCI — процедур, требующих доступа к их конфигурационному пространству (см. п. 8.2). Регулярная работа с этими устройствами выполняется через обращения к регистрам устройств по адресам, полученным при конфигурировании, и обработке известных номеров прерываний от этих устройств. Для 16-битного интерфейса реального режима , V86 и 16-битного реального режима, функции PCI BIOS вызываются через прерывание Int 1Ah ; номер функции задается при вызове в регистре АХ . Возможна и программная имитация прерывания дальним вызовом по физическому адресу 000FFE6EH (стандартная точка входа в обработчик Int 1Ah ) с предварительным занесением в стек регистра флагов.

Признаком нормального выполнения является CF =0 и АН =0; при CF =1 АН содержит код ошибки :

♦ 81h — неподдерживаемая функция;

♦ 83h — неправильный идентификатор производителя;

♦ 86h — устройство не найдено;

♦ 87h — неправильный номер регистра PCI.

Вызовы требуют глубокого стека (до 1024 байт). Для 32-разрядных вызовов защищенного режима все эти же функции вызываются через точку входа, найденную через каталог 32-разрядных сервисов (см. выше), при этом назначение входных и выходных регистров и флага CF сохраняется. До использования 32-разрядного интерфейса следует сначала найти его каталог и убедиться в наличии сервисов PCI. Функции PCI BIOS перечислены ниже:

♦ АХ = B101h — проверка присутствия PCI BIOS . При наличии PCI BIOS возвращает CF =0, АН =0 и EDX =20494350h (строка символов «PCI «); проверяться должны все три признака. При этом в AL находится описатель аппаратного механизма доступа к конфигурационному пространству и генерации специальных циклов PCI:

• Бит 0 — поддержка механизма № 1 для доступа к конфигурационному пространству;

• Бит 1 — поддержка механизма № 2 для доступа к конфигурационному пространству;

• Биты 2:3=00 (резерв);

• Бит 4 — поддержка генерации специального цикла по механизму № 1;

• Бит 5 — поддержка генерации специального цикла по механизму № 2;

• Биты 6:7=00 (резерв).

В регистрах ВН и BL возвращается старший и младший номер версии (BCD-цифры), в CL — максимальный номер шины PCI, присутствующий в системе (число шин +1, поскольку они нумеруются с нуля последовательно). В регистре EDI может возвращаться линейный адрес точки входа 32-разрядных сервисов BIOS. Этот адрес возвращается не всеми версиями BIOS (некоторые не изменяют EDI ); для проверки можно при вызове обнулять EDI и проверять на нуль возвращенное значение.

♦ АХ = B102h — поиск устройства по идентификатору . При вызове в СХ указывается идентификатор устройства, в DX — идентификатор производителя, в SI — индекс (порядковый номер) устройства. При успешном возврате в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции. Для нахождения всех устройств с указанными идентификаторами вызовы выполняют, последовательно инкрементируя SI от 0 до получения кода возврата 86h.

♦ AX = B103h — поиск устройства по коду класса . При вызове в ЕСХ[23:16] указывается код класса, в ЕСХ[15:8] — подкласса, в ЕСХ[7:0] — интерфейс, в SI — индекс устройства (аналогично предыдущему). При успешном возврате в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции.

♦ АХ = B106h — генерация специального цикла PCI . При вызове в BL указывается номер шины, в EDX — данные специального цикла.

♦ АХ = В108h — чтение байта конфигурационного пространства устройства PCI . При вызове в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции, в DI — номер регистра (0-FFh). При успешном возврате в CL — считанный байт.

♦ АХ = B109h — чтение слова конфигурационного пространства устройства PCI . При вызове в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции, в DI — номер регистра (0-FFh, четный). При успешном возврате в СХ — считанное слово.

♦ АХ = В10Ah — чтение двойного слова конфигурационного пространства устройства PCI . При вызове в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции, в DI — номер регистра (0-FFh, кратный 4). При успешном возврате в ЕСХ — считанное двойное слово.

♦ АХ = B10Bh — запись байта конфигурационного пространства устройства PCI . При вызове в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции, в DI — номер регистра (0-FFh), в CL — записываемый байт.

♦ АХ = B10Ch — запись слова конфигурационного пространства устройства PCI . При вызове в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции, в DI — номер регистра (0-FFh, четный), в СХ — записываемое слово.

♦ АХ = B10Ah — запись двойного слова конфигурационного пространства устройства PCI . При вызове в ВН — номер шины, в BL[7:3] — номер устройства, BL[2:0] — номер функции, в DI — номер регистра (0-FFh, кратный 4), в ЕСХ — записываемое двойное слово.

[6] Зная устройство современных винчестеров, здесь и далее не будем добираться до истинно физических параметров — реального номера цилиндра, головки и сектора.

Аппаратные интерфейсы ПК. Энциклопедия (150 стр.)

♦ Int 02h — немаскируемое прерывание;

♦ Int 08h — таймер 8253/8254;

♦ Int 09h — клавиатура;

♦ Int 0Eh — IRQ6 — контроллер гибких дисков;

♦ Int 70h — CMOS-таймер;

♦ Int 71h — IRQ9 (перенаправлено на Int 0Ah );

♦ Int 74h — IRQ12 (контроллер мыши PS/2);


♦ Int 75h — IRQ13 — исключение сопроцессора;

♦ Int 76h — IRQ14 — контроллер жестких дисков;

Прерывания Int 70h — 77h имеют место только в AT.

Функции ROM BIOS (16-битные сервисы):

♦ Int 05h (F000:FF54h) — печать экрана;

♦ Int 10h — видеосервис;

♦ Int 11h — чтение списка оборудования (слово из BDA 0040:0010h), возвращает в АХ :

• биты 15:14 — число обнаруженных LPT-портов: 00 — 0, …, 11 — 3;

• бит 12 — обнаружен игровой адаптер;

• биты 11:9 — число обнаруженных СОМ-портов: 000 — 0, …, 111 — 7;

• бит 8 — наличие контроллера DMA;

• биты 7:6 — число обнаруженных НГМД: 00 — 1, …, 11 — 4;

• биты 5:4 — активный видеорежим: 00 — резерв, 10 — 80-колоночный цветной, 01 — 40-колоночный цветной, 11 — монохромный;

• биты 3:2 — размер ОЗУ на системной плате (теперь обычно 00);

• бит 1 — присутствие математического сопроцессора;

• бит 0 — присутствие дисководов;

♦ Int 12h — размер непрерывной памяти;

♦ Int 13h — дисковый сервис (блочный ввод-вывод);

♦ Int 14h — обслуживание СОМ-портов;

♦ Int 15h — AT-функции (системный сервис, функции определяются значением АН / АХ ):

• 00-03h — управление и обмен данными с кассетным магнитофоном (были когда-то и такие «стриммеры»!) на старых PC;

• 4fh — перехват клавиатуры;

• 53xxh — сервисы управления потреблением АРМ (Advanced Power Management);

• 8300h — запуск таймера, устанавливающего флаг в заданной ячейке;

• 8301h — сброс того же таймера;

• 84h — джойстик (см. п. 8.6);

• 86h — программируемая задержка;

• 87h — перемещение блока расширенной памяти;

• 88h — получение размера расширенной памяти;

• 89h — переключение в режим V86;

• C0h — получение системной конфигурации, при успешном выполнении ( CF =0, AH =0) ES:BX указывает на таблицу данных конфигурации;

• 80-82h, 85h, 90h, 91h — функции многозадачных ОС (BIOS устанавливает заглушки);

♦ Int 16h — клавиатурный ввод-вывод;

♦ Int 17h — обслуживание LPT-портов;

♦ Int 18h — процедура восстановления при неудаче начальной загрузки (прежде — ROM-Basic);

♦ Int 19h — начальная загрузка (вызов процедуры Bootstrap);

♦ Int 1Ah — системное время, дата, будильник и 16-битные вызовы сервисов PCI;

♦ Int 1Bh — обработчик нажатия клавиш Ctrl+Break ;

♦ Int 1Ch — User Timer Interrupt, процедура, вызываемая обработчиком Int 08h каждые 55 мс; BIOS устанавливает простую заглушку ( IRET ), но программы могут перехватывать это прерывание; на время отработки этой процедуры все аппаратные прерывания запрещены (кроме NMI).

♦ Int 33h — поддержка мыши;

♦ Int 4Ah — обработчик будильника пользователя, установленного функцией BIOS Int 1Ah (6); прерывание вызывается асинхронно, так что при возврате из процедуры все регистры и флаги должны быть в том же состоянии, что и при входе; BIOS ставит заглушку ( IRET );

♦ Int 67h — EMS-функции.

Указатели на таблицы:

♦ Int 1Dh — видеопараметры;

♦ Int 1Eh — параметры дискет;

♦ Int 1Fh — знакогенератор СGA;

♦ Int 41h — параметры HDD 0;

♦ Int 46h — параметры HDD 1;

♦ Int 43h — знакогенератор EGA.

12.8.1. Int 09h, Int 16h — поддержка клавиатуры

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

Прерывания, вызванные приходом кодов нажатия и отпускания клавиш, обрабатывает BIOS Int 9h . Каждый принятый скан-код (или цепочка) обрабатывается с учетом состояния клавиатурных флагов. Результат обработки (как правило, ASCII-символ в младшем байте и скан-код в старшем) помещается в клавиатурный буфер, расположенный в ОЗУ. По приему каждого символа указатель головы буфера увеличивается. Буфер организован в виде кольца, после достижения конца области буфера указатель головы установится на начало области. В случае переполнения буфера (указатель головы «догнал» указатель хвоста) очередное слово не записывается, и подается звуковой сигнал. Размер позволяет хранить описание шестнадцати фактов нажатий клавиш. Нажатие клавиш Ctrl , Shift , Alt и некоторых комбинаций в буфере не отмечается, но приводит к модификации бит ячеек флагов клавиатуры. Нажатие «системной» комбинации Ctrl+Alt+Del , клавиши PrintScreen ( SysRq ) и некоторых других к записи в клавиатурный буфер не приводит, а вызывает специальные процедуры.

Для обслуживания клавиатуры используются ячейки ОЗУ из области данных BIOS (BIOS Data Area):

♦ 0:0417, 0:418 — флаги клавиатуры;

♦ 0:0419 — аккумулятор кода Alt -набора;

♦ 0:041А — указатель головы буфера (Buffer Head), 2 байта (модифицируется при помещении символа в буфер);

♦ 0:041C — указатель хвоста буфера (Buffer Tail), 2 байта (модифицируется при извлечении символа из буфера);

♦ 0:041E-0:042D — область кольцевого буфера (16 слов).

Обработчик аппаратного прерывания до обработки принятого скан-кода вызывает прерывание BIOS Int 15h с AH =4Fh, а в AL находится принятый скан-код. Стандартный обработчик Int 15h (4Fh) просто выполняет возврат с CF =0, но его можно заменить специальным обработчиком, который будет при необходимости подменять принятые скан-коды на какие-либо иные (оставляя их в AL ), что должно отмечаться установкой CF =1. В старых версиях BIOS такой возможности перехвата не было, ее наличие можно определить вызовом Int 15h (C0h).

Для клавиатуры USB или иного устройства ввода, заменяющего клавиатуру в качестве консоли, прерывание Int 9h должно вызываться программно при обработке каждого клавиатурного события. Обработчик этого прерывания должен выполнять те же действия: скан-код пропускать через Int 15h (4Fh) и помещать в клавиатурный буфер, а также модифицировать флаги клавиатуры.

Интерфейс прикладного уровня для клавиатуры представляет BIOS Int 16h . Его основное назначение — извлечение слов из клавиатурного буфера. Функция задается в регистре АН при вызове, результат помещается в регистр АХ .

♦ АН = 00h — чтение (с ожиданием готовности) и выборка слова из буфера (меняется указатель хвоста). Индикаторы клавиатуры обновляются в соответствии с состоянием флагов. Если буфер пуст, то на AT выполняется прерывание Int 15h (подфункция 90), что может использоваться ОС, например, для переключения задач. Чтобы программа не «зависала» на ожидании символа, предварительно стоит проверить готовность функцией 01h. Символы расширенной клавиатуры фильтруются — преобразуются в их аналоги 83-клавишной клавиатуры.

♦ АН = 01h — проверка готовности, чтение без выборки (указатели не изменяются). Признак наличия символа в буфере — установленный флаг ZF .

2. КЛАВИАТУРА

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

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

Мы расскажем о работе с клавиатурой на разных уровнях — от использования клавиатурных портов ввода/вывода до средств, предоставляемых стандартными библиотеками трансляторов Microsoft QC 2.5 и C 6.0. Какой уровень вам следует выбрать, зависит от решаемой задачи. Единственное, что можно порекомендовать — это использовать по возможности средства высокого уровня. Если ваша программа работает с клавиатурой на уровне портов ввода/вывода, ее работа может оказаться зависимой от типа клавиатуры и от типа компьютера.

Клавиатура выполнена, как правило, в виде отдельного устройства, подключаемого к компьютеру тонким кабелем. Малогабаритные компьютеры Lap-Top используют встроенную клавиатуру.

Что же находится внутри клавиатуры? Оказывается, там есть компьютер! Только этот компьютер состоит из одной микросхемы и выполняет специализированные функции. Он отслеживает нажатия на клавиши и посылает номер нажатой клавиши в центральный компьютер.

Если рассмотреть сильно упрощенную принципиальную схему клавиатуры, представленную на рисунке, можно заметить, что все клавиши находятся в узлах матрицы:

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

Все горизонтальные линии матрицы подключены через резисторы к источнику питания +5 В. Клавиатурный компьютер имеет два порта — выходной и входной. Входной порт подключен к горизонтальным линиям матрицы (X0-X4), а выходной — к вертикальным (Y0-Y5).

Устанавливая по очереди на каждой из вертикальных линий уровень напряжения, соответствующий логическому 0, клавиатурный компьютер опрашивает состояние горизонтальных линий. Если ни одна клавиша не нажата, уровень напряжения на всех горизонтальных линиях соответствует логической 1 (т.к. все эти линии подключены к источнику питания +5 В через резисторы).

Если оператор нажмет на какую-либо клавишу, то соответствующая вертикальная и горизонтальная линии окажутся замкнутыми. Когда на этой вертикальной линии процессор установит значение логического 0, то уровень напряжения на горизонтальной линии также будет соответствовать логическому 0.

Как только на одной из горизонтальных линий появится уровень логического 0, клавиатурный процессор фиксирует нажатие на клавишу. Он посылает в центральный компьютер запрос на прерывание и номер клавиши в матрице. Аналогичные действия выполняются и тогда, когда оператор отпускает нажатую ранее клавишу.

Номер клавиши, посылаемый клавиатурным процессором, однозначно связан с распайкой клавиатурной матрицы и не зависит напрямую от обозначений, нанесенных на поверхность клавиш. Этот номер называется скан-кодом (Scan Code).

Слово scan («сканирование»), подчеркивает тот факт, что клавиатурный компьютер сканирует клавиатуру для поиска нажатой клавиши.

Но программе нужен не порядковый номер нажатой клавиши, а соответствующий обозначению на этой клавише ASCII-код. Этот код не зависит однозначно от скан-кода, т.к. одной и той же клавише могут соответствовать несколько значений ASCII-кода. Это зависит от состояния других клавиш. Например, клавиша с обозначением ‘1’ используется еще и для ввода символа ‘!’ (если она нажата вместе с клавишей SHIFT).

Поэтому все преобразования скан-кода в ASCII-код выполняются программным обеспечением. Как правило, эти преобразования выполняют модули BIOS. Для использования символов кириллицы эти модули расширяются клавиатурными драйверами.

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

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

В настоящее время существует три различных типа клавиатуры. Это клавиатура для компьютеров IBM PC/XT, 84-клавишная клавиатура для IBM AT и 101-клавишная (расширенная) клавиатура для IBM AT. Некоторые клавиатуры имеют переключатель режима работы (XT/AT), расположенный на нижней крышке. Он должен быть установлен в правильное положение.

Для работы с клавиатурой типа PC/XT используются порты с адресами 60h и 61h.

Порт 60h при чтении содержит скан-код последней нажатой клавиши.

Порт 61h управляет не только клавиатурой, но и другими устройствами компьютера, например, работой встроенного динамика. Этот порт доступен как для чтения, так и для записи. Для нас важен самый старший бит этого порта. Если в старший бит порта 61h записать значение 1, клавиатура будет заблокирована, если 0 — разблокирована.

Так как порт 61h управляет не только клавиатурой, при изменении содержимого старшего бита необходимо сохранить состояние остальных битов этого порта. Для этого можно сначала выполнить чтение содержимого порта в регистр, изменить состояние старшего бита, затем выполнить запись нового значения в порт:

Компьютер типа IBM AT позволяет управлять скоростными характеристиками клавиатуры, а также зажигать или гасить светодиоды на лицевой панели клавиатуры — Scroll Lock, Num Lock, Caps Lock.

Для расширенного управления клавиатурой используется порт 60h в режиме записи. Этот порт используются для управления подчиненным процессором Intel 8042, ответственным за обмен данными с клавиатурным компьютером.

При использовании порта 60h на запись программа дополнительно получает следующие возможности:

  • установка времени ожидания перед переходом клавиатуры в режим автоповтора;
  • установка периода генерации скан-кода в режиме автоповтора;
  • управление светодиодами, расположенными на лицевой панели клавиатуры — Scroll Lock, Num Lock, Caps Lock.

Процессор 8042 обслуживает не только клавиатуру, но и другие системы компьютера. Через порт 64h, например, выполняется сброс (отключение) процессора 80286 для возврата из защищенного режима работы в реальный.

Для посылки команды процессору 8042 вначале необходимо убедиться в том, что его внутренняя очередь команд пуста. Это можно сделать, прочитав слово состояния 8042 из порта с адресом 64h. Бит с номером 1 должен быть равен нулю.

Приведем фрагмент программы, составленной на языке ассемблера, проверяющий состояние очереди команд процессора 8042:

После того, как программа дождется готовности процессора 8042, она может послать ему команду, записав ее в порт с адресом 60h:

Некоторые команды состоят более чем из одного байта. Остальные байты команды необходимо записать в порт 60h, предварительно убедившись в готовности процессора 8042 с помощью последовательности команд, приведенной выше. В большинстве случаев можно также использовать простую временную задержку:

Мы приведем формат двух команд процессора 8042, имеющих отношение к работе с клавиатурой — команду установки задержки и периода автоповтора и команду управления светодиодами, расположенными на клавиатуре.

Для установки характеристик режима автоповтора в порт 60h необходимо записать код команды 0F3h, затем байт, определяющий характеристики режима:

Первоначально при инициализации системы период задержки для включения режима автоповтора устанавливается модулями BIOS равным 500 мс при периоде автоповтора, равном 10 повторам в секунду. Если это слишком медленно для вас, вы можете установить другие значения. Некоторые прикладные программы, например, текстовый процессор Microsoft Word, содержат средства для управления временными характеристиками клавиатуры.

Для управления светодиодами, расположенными на лицевой панели клавиатуры, используйте команду 0EDh. Вслед за этой командой в порт 60h необходимо записать байт, имеющий следующий формат:

Приведем пример простейшей программы, управляющей светодиодами на лицевой панели компьютера. Такое управление может выполняться только при использовании порта 60h управления клавиатурой, так как BIOS не содержит соответствующей поддержки. Наша программа после запуска включит все светодиоды и будет ожидать нажатия на любую клавишу. После нажатия программа выключит светодиоды.

Клавиатура подключена к линии прерывания IRQ1. Этой линии соответствует прерывание INT 09h.

Клавиатурное прерывание обслуживается модулями BIOS. Драйверы клавиатуры и резидентные программы могут организовывать дополнительную обработку прерывания INT 09h. Для этого может быть использована цепочка обработчиков прерывания. В первой книге первого тома мы приводили примеры расширения обработчика прерывания INT 09h.

Как работает стандартный обработчик клавиатурного прерывания, входящий в состав BIOS?

Этот обработчик выполняет следующие действия:

  • читает из порта 60h скан-код нажатой клавиши;
  • записывает вычисленное по скан-коду значение ASCII-кода нажатой клавиши в специальный буфер клавиатуры, расположенный в области данных BIOS;
  • устанавливает в 1 бит 7 порта 61h, разрешая дальнейшую работу клавиатуры;
  • возвращает этот бит в исходное состояние;
  • записывает в порт 20h значение 20h для правильного завершения обработки аппаратного прерывания.

Обработчик прерывания INT 09h не просто записывает значение ASCII-кода в буфер клавиатуры. Дополнительно отслеживаются нажатия таких комбинаций клавиш, как Ctrl-Alt-Del, обрабатываются специальные клавиши PrtSc и SysReq. При вычислении кода ASCII нажатой клавиши учитывается состояние клавиш Shift и CapsLock.

Буфер клавиатуры имеет длину 32 байта и расположен по адресу 0000h:041Eh для машин IBM PC/XT.

В IBM AT и PS/2 расположение клавиатурного буфера задается содержимым двух слов памяти с адресами 0000h:0480h (компонента смещения адреса начала буфера) и 0000h:0482h (смещение конца буфера). Обычно в IBM AT эти ячейки памяти содержат значения, соответственно, 001Eh и 003Eh. Так как смещения заданы относительно сегментного адреса 0040h, то видно, что обычное расположение клавиатурного буфера в IBM AT и PS/2 соответствует его расположению в IBM PC/XT.

Клавиатурный буфер организован циклически. Это означает, что при его переполнении самые старые значения будут потеряны. Две ячейки памяти, находящиеся в области данных BIOS с адресами 0000h:041Ah и 0000h:041Ch содержат, соответственно, указатели на начало и конец буфера. Если значения этих указателей равны друг другу, буфер пуст. (Можно удалить все символы из буфера клавиатуры, установив оба указателя на начало буфера. Однако есть более предпочтительный способ с использованием прерывания BIOS INT 16h).

Указателями на начало и конец клавиатурного буфера обычно управляют обработчики прерываний INT 09h и INT 16h.

Программа извлекает из буфера коды нажатых клавиш, используя различные функции прерывания INT 16h.

Помимо управления содержимым буфера клавиатуры, обработчик прерывания INT 09h отслеживает нажатия на так называемые переключающие клавиши — NumLock, ScrollLock, CapsLock, Ins. Состояние этих клавиш записывается в область данных BIOS в два байта с адресами 0000h:0417h и 0000h:0418h.

Формат байта 0000h:0417h:

Формат байта 0000h:0418h:

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

Программой обработки прерывания INT 09h отслеживаются некоторые комбинации клавиш. В таблице приведены эти комбинации и действия, выполняемые обработчиком прерывания при их обнаружении:

Многие типы клавиатур имеют отдельную альтернативную цифровую панель, напоминающую клавиатуру калькулятора. Если одновременно с нажатием на клавишу Alt набрать число на этой панели (не большее, чем 255 и не равное 0), то это число будет помещено в буфер клавиатуры, как будто бы оно было введено нажатием на одну клавишу. Это число будет также записано в слове по адресу 0000h:0419h в области данных BIOS.

При переполнении внутреннего буфера клавиатуры или буфера, расположенного в области данных BIOS, программа-обработчик прерывания INT 09h генерирует звуковой сигнал.

При составлении программ для MS-DOS у вас едва ли появится необходимость непосредственного манипулирования содержимым буфера клавиатуры — вы можете использовать прерывание BIOS INT 16h для выполнения практически всех клавиатурных операций.

В следующем разделе мы займемся непосредственно изучением средств работы с клавиатурой, предоставляемых в распоряжение прерыванием BIOS INT 16h.

Набор функций для работы с клавиатурой, предоставляемый в распоряжение программиста прерыванием BIOS INT 16h, включает в себя функции для выборки кода нажатого символа из буфера с ожиданием нажатия, функции для проверки содержимого буфера и для управления содержимым буфера, функции для изменения скоростных характеристик клавиатуры.

Функция 00h выполняет чтение кода символа из буфера клавиатуры, если он там есть. Если буфер клавиатуры пуст, программа переводится в состояние ожидания до тех пор, пока не будет нажата какая-нибудь клавиша. Скан-код и ASCII-код нажатой клавиши передаются программе.

Приведем формат вызова функции:

Приведем таблицу скан-кодов для клавиатуры IBM PC/XT:

Для остальных клавиш функция 00h прерывания INT 16h возвращает расширенный ASCII-код:

В следующей таблице приведены скан-коды клавиш, имеющихся только на 101-клавишной клавиатуре:

Буква «Д» в последней таблице обозначает дополнительную («калькуляторную») клавиатуру.

Для демонстрации использования функции 00h прерывания INT 16h мы подготовили программу, выводящую на экран скан-коды и ASCII-коды нажимаемых клавиш:

Функция 01h поможет вам проверить состояние буфера клавиатуры — есть там коды нажатых клавиш или нет. При этом программа не переводится в состояние ожидания, даже если буфер клавиатуры пуст. В этом случае в регистре флагов устанавливается в единицу флаг ZF и управление возвращается программе.

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

Кроме того, функцию можно использовать вместе с функцией 00h для сброса содержимого клавиатурного буфера. Для этого в цикле повторяют вызов функции 01h, вслед за которым идет вызов функции 00h при условии, что буфер клавиатуры не пуст. Сброс клавиатурного буфера полезно выполнять перед вводом ответственной информации, так как из-за случайного двойного или тройного нажатия на клавишу в буфере клавиатуры могут оказаться лишние символы.

Приведем текст программы, выводящей на экран в цикле символ ‘*’. При нажатии на любую клавишу, кроме ESC, программа выводит на экран строку текста — инструкцию для завершения работы программы. Если нажать на клавишу ESC, работа программы будет завершена.

Функция возвращает в регистре AL состояние переключающих клавиш (Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock, Ins). Формат байта состояния соответствует формату байта, находящегося в области данных BIOS по адресу 0000h:0417h:

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

Изменим текст предыдущей программы таким образом, чтобы завершение ее работы происходило лишь в том случае, если переключающая клавиша CapsLock находится в выключенном состоянии (соответствующий светодиод не горит):

Мы уже рассказывали о возможности изменения временных характеристик клавиатуры. Если BIOS, установленная в вашей машине, изготовлена после 15 декабря 1985 года, вы можете воспользоваться этой функцией для ускорения (или замедления) работы клавиатуры.

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

С помощью этой функции можно вставить символы в буфер клавиатуры, как будто они были введены оператором.

Приведенная программа записывает в буфер клавиатуры пять символов ‘*’. Запустите ее и посмотрите на системное приглашение. Вы увидите что-нибудь похожее на C:>*****.

Функция 10h полностью аналогична функции 00h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу.

Приведем формат вызова функции:

Функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

Функция 11h полностью аналогична функции 01h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу.

Эта функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

Функция возвращает в регистре AL состояние переключающих клавиш (Shift, Ctrl, Alt, ScrollLock, NumLock, CapsLock, Ins):

Функция 12h аналогична функции 02h, но она предназначена для работы с клавиатурой, имеющей 101 клавишу и имеет другой формат байта состояния.

Эта функция определена для BIOS, изготовленной не раньше 15 декабря 1985 года.

К сожалению, MS-DOS не предоставляет программам каких-либо существенных дополнительных возможностей по сравнению с функциями прерывания BIOS INT 16h. Поэтому многие программы работают с клавиатурой через BIOS.


Однако, если ваша программа пользуется клавиатурными функциями MS-DOS, то ей доступно средство переназначения ввода операционной системы. Это возможно благодаря тому, что клавиатурные функции MS-DOS являются функциями, работающими со стандартным вводом MS-DOS, а стандартный ввод может быть переназначен.

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

Вообще говоря, клавиатурные функции MS-DOS больше всего подходят для тех программ, которые ведут с оператором «построчный» диалог. Для таких программ при использовании средств переназначения ввода/вывода возможна организация автоматического «пакетного» выполнения, когда все сообщения выводятся в файл, а все данные, которые обычно вводятся с клавиатуры, считываются из заранее подготовленного файла «ответов».

Некоторые клавиатурные функции MS-DOS отслеживают комбинации клавиш Ctrl-C и Ctrl-Break. Если оператор ввел такую комбинацию клавиш, вызывается прерывание INT 23h, завершающее работу текущей программы. Если ваша программа не должна завершаться при нажатии этих комбинаций клавиш, можно либо создать и подключить собственный обработчик для INT 23h, либо использовать те клавиатурные функции MS-DOS, которые не выполняют проверку указанных выше комбинаций клавиш.

Приведем подробное описание клавиатурных функций прерывания MS-DOS INT 21h.

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

Введенный символ выводится на стандартное устройство вывода.

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

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

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

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

Эту функцию удобно использовать в тех случаях, когда завершение программы по нажатию комбинаций клавиш Ctrl-C или Ctrl-Break по тем или иным причинам нежелательно. Например, программа держит в оперативной памяти буфера для данных, которые перед завершением работы обязательно должны быть записаны на диск. Если оператор в неподходящий момент времени нажал Ctrl-C и программа аварийно завершила работу, содержимое буферов будет потеряно.

Функция 06h может использоваться как для ввода с консоли, так и для вывода символов на консоль. Режим работы функции зависит от содержимого регистра DL при вызове функции. Если этот регистр содержит значение 0FFh, функция выполняет ввод с консоли, в противном случае символ, код которого записан в этот регистр, выводится на консоль.

Очевидно, что с помощью этой функции нельзя вывести на консоль символ с кодом 0FFh.

Основное отличие функции 06h от всех описанных ранее заключается в том, что эта функция не ожидает, пока оператор нажмет на клавишу. Если буфер клавиатуры пуст, функция просто устанавливает флаг процессора ZF в 1.

Если в буфере клавиатуры имеются символы, флаг ZF сбрасывается и в регистр AL функция записывает ASCII-код символа.

Функция предназначена для ввода с клавиатуры строки символов. Перед вызовом функции необходимо специальным образом подготовить буфер, адрес которого передается в регистрах DS:DX — в первый байт буфера следует записать максимальную длину вводимой строки (в диапазоне от 1 до 244):

После возврата из функции буфер будет иметь следующий формат:

Ввод осуществляется до тех пор, пока либо количество введенных символов не достигнет max-1, либо пока не будет нажата клавиша Enter (код 0Dh). Если оператор уже ввел max-1 символ и продолжает вводить символы дальше, функция выдает звуковой сигнал на каждое нажатие и игнорирует вводимые символы до тех пор, пока не будет нажата клавиша Enter.

При вводе строки можно использовать стандартные средства редактирования MS-DOS, используемые при вводе команд в режиме командной строки.

Эта функция проверяет состояние клавиатурного буфера. Вы можете вызывать ее перед функциями 01h, 07h, 08h для того, чтобы избежать ожидания нажатия на клавишу.

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

Функция очищает клавиатурный буфер, затем вызывает клавиатурную функцию MS-DOS, номер которой определяется содержимым регистра AL. Если же регистр AL содержит другое значение, кроме приведенных выше, функция просто сбрасывает содержимое буфера и не выполняет никаких других действий.

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

Стандартные библиотеки трансляторов Microsoft QuickC и C 6.0 содержат набор функций, предназначенных для работы с клавиатурой. Эти функции повторяют и немного дополняют возможности функций MS-DOS и BIOS, обслуживающих клавиатуру.

Самые простые из них — getch() и getche(). Они описаны в файле conio.h.

Функция getch() имеет следующий прототип:

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

Функция обрабатывает клавиши Ctrl-С и Ctrl-Break — при вводе этих комбинаций клавиш работа программы завершается.

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

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

Приведем пример программы, отображающей на экране ASCII-коды и расширенные ASCII-коды нажимаемых клавиш:

Для проверки буфера клавиатуры на наличие символов можно использовать функцию kbhit(). Она также описана в файле conio.h:

Если буфер клавиатуры не пуст, функция возвращает ненулевое значение. В этом случае программа может прочитать символы из буфера клавиатуры при помощи фукнкций getch() и getche(). Если буфер клавиатуры пуст, функция возвращает нулевое значение.

Приведем пример программы, ожидающей нажатия на любую клавишу. Во время ожидания программа выводит на экран поочередно символы » «:

Для ввода с клавиатуры строки символов можно использовать функцию cgets(), работающую аналогично функции 0Ah прерывания MS-DOS INT 21h:

Функция описана в файле conio.h.

Перед вызовом аргумент функции buffer должен указывать на массив, размер которого должен быть достаточным для хранения вводимой строки, завершающего строку нулевого байта и двух дополнительных байтов. Первый элемент массива buffer[0] должен содержать максимальную длину вводимой строки — как и для функции 0Ah прерывания MS-DOS INT 21h.

После завершения ввода второй элемент массива buffer[1] будет содержать длину введенной строки, сама строка будет завершаться символами новой строки NL, перевода строки LF и нулем.

Функция cgets() возвращает указатель на начало введенной строки в буфере, т.е. на третий элемент массива buffer[2].

Приведем простой пример, в котором функция cgets() используется для ввода целого числа:

Существует и более удобная для использования функция, позволяющая вводить строку с клавиатуры, а точнее, из стандартного потока ввода. Это функция gets():

Функция gets() описана в файле stdio.h.

Эта функция читает строку из стандартного потока ввода stdin и запоминает ее в буфере buffer. Символ новой строки n в конце введенной строки функция заменяет на ноль.

После завершения ввода функция возвращает указатель на заполненный буфер или NULL в случае ошибки или условия «Конец файла».

Обратим ваше внимание на отличия между функциями cgets() и gets():

  • Функция cgets() позволяет редактировать вводимую строку символов, функция gets() просто записывает в буфер все символы подряд (в том числе и коды клавиш редактирования).
  • Программе, использующей для ввода с клавиатуры функцию cgets(), недоступны средства переназначения ввода операционной системы. Если же программа использует функцию gets(), которая читает строку из стандартного потока ввода, можно использовать средства переназначения.
  • Перед вызовом функции cgets() необходимо специальным образом подготовить буфер для вводимой строки (записать в первый байт буфера длину вводимой строки). Функция gets() не требует никакой подготовки буфера.

Еще одна полезная функция, которую можно использовать для ввода с клавиатуры — scanf(). Эта функция подробно описана во всех книгах по языку программирования Си, поэтому мы не будем ее подробно рассматривать. Отметим только, что с помощью этой функции можно организовать ввод чисел в заданном формате. Однако можно сначала ввести строку при помощи функций cgets() или gets(), а уже потом выполнять все необходимые проверки и преобразования этой строки.

Лекция12. Работа с клавиатурой. Системные средства ввода данных с клавиатуры

Операционная система реального режима работы микропроцессора представляет несколько способов ввода данных с клавиатуры:

-обращение к клавиатуре, как к файлу, с помощью прерывания DOS INT 21h с функцией 3Fh;

— использование группы функций DOS INT 21h из диапазона 1. Ch, обеспечивающих посимвольный ввод с клавиатуры в разных режимах;

— посимвольный ввод путем обращения в обход DOS непосредственно к драйверу BIOS с помощью прерывания INT 16h.

Рассмотрим функцию, с помощью которой можно ввести сразу несколько символов и которая допускает редактирование набираемого текста. Первый байт буфера — размер строки (1 — 254). После выполнения функций второй байт будет содержать фактическую длину вводимой строки, которая заканчивается кодом возврата каретки. Функция вводит символы до тех пор пока не будет нажата клавиша ENTER, набираемый текст можно редактировать с помощью следующих клавиш:

-Backspace — отмена последнего символа -Esc — отмена всего набранного текста Заполнение буфера:
M N S S S C
ах R

мах — число максимально возможных символов n — число введенных символов

BUF DB 10, 10 DUP (‘ ’);

MOV AH, 0Ah INT 21h

Если при вводе были набраны символы АВС, то содержимое буфера BUF будет следующим:

BUF [2] =41h (код A)

BUF [3] =42h (код B)

BUF [4] =43h (код c)

Функции BIOS работа с клавиатурой

Функции DOS имеют два очень серьезных недостатка:

1. Они не позволяют полностью реализовать возможности функциональных клавиш.

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

“BIOS предоставляет больше возможностей по сравнению с DOS”. Для считывания данных и управления клавиатурой, например, функциями DOS нельзя определить нажатие комбинаций клавиш типа Ctrl — Alt — Enter или нажатие двух клавиш Shift одновременно. DOS не может определить момент отпускания нажатой клавиши, и, наконец в DOS нет аналога функций С ungetch (), помещающей символ в буфер клавиатуры, как если бы его ввел пользователь. Все это можно осуществить, используя различные функций прерывания 16h и операции с байтами состояния клавиатуры.

INT 16 h, АН = 0, 1Oh, 20h — Чтение символа с ожиданием Ввод: АН = 00h

(83/84-key), 10h (101/102-key), 20h (122-key) Вывод: AL = ASCII-код символа, О или префикс скан-кода

АН = скан-код нажатой клавиши или расширенный ASCII-код Каждой клавише на клавиатуре соответствует так называемый скан-код, соответствующий только этой клавише. Этот код посылается клавиатурой при каждом нажатии и отпускании клавиши и обрабатывается BIOS (обработчиком прерывания INT 9). Прерывание 16h дает возможность получить код нажатия, не перехватывая этот обработчик. Если нажатой клавише соответствует ASCII-символ, то в АН возвращается код этого символа, а в AL — скан-код клавиши. Если нажатой клавише соответствует расширенный ASCII-код, в AL возвращается префикс скан- кода (например, ЕО для серых клавиш) или 0, если префикса нет, а в АН — расширенный ASCII-код. Функция 00h обрабатывает только комбинации, использующие клавиши 84-клавишной клавиатуры, l0h обрабатывает все 101- — 105-клавишные комбинации, 20h — 122-кла-вишные. Тип клавиатуры можно определить с помощью функции 09h прерывания 16h, если она поддерживается BIOS (поддерживается ли эта функция, можно узнать с помощью функции C0h прерывания 15h).

INT 16h, АН = 1, 11 h, 21h — Проверка символа Ввод: АН — 0lh (83/84- key), llh (101/102-key), 21h (122-key) Вывод: ZF = 1, если буфер пуст ZF = 0, если в буфере присутствует символ, в этом случае AL = ASCII-код символа, 0 или префикс скан-кода АН = скан-код нажатой клавиши или расширенный ASCII-код Символ остается в буфере клавиатуры, хотя некоторые BIOS удаляют символ из буфера при обработке функции 0lh, если он соответствует расширенному ASCII- коду, отсутствующему на 84-клавишных клавиатурах.

INT 16h, АН = 05h — Поместить символ в буфер клавиатуры Ввод: АН =

CL = ASCII-код Вывод: AL = 00, если операция выполнена успешно AL = Olh, если буфер клавиатуры переполнен АН модифицируется многими BIOS

Обычно можно поместить 0 вместо скан-кода в СН, если функция, которая будет выполнять чтение из буфера, будет использовать именно ASCII-код. Например, следующая программа при запуске из DOS вызывает команду DIR (но при запуске из некоторых оболочек, например FAR, этого не произойдет).

; заносит в буфер клавиатуры команду DIR так, чтобы она выполнилась сразу после

; завершения программы .model tiny . code

org 100h ; СОМ-файл

mov cl,’d’ ; CL = ASCII-код буквы «d» call ungetch

mov cl,’i’ ; ASCII-код буквы «i» call ungetch

mov cl,’r’ ; ASCII-код буквы «г» call ungetch

mov cl,ODh ; перевод строки ungetch:

mov ah,5 ; AH = номер функции

mov ch,0 ; CH = 0 (скан-код неважен)

int 16h ; поместить символ в буфер

ret ; завершить программу

INT 16h, AH = 02h, 12h, 22h — Считать состояние клавиатуры Ввод: АН =

02h (83/84-key), 12h (101/102-key), 22h (122-key) Вывод: AL = байт состояния клавиатуры 1

АН = байт состояния клавиатуры 2 (только для функций 12h и 22h)

Байт состояния клавиатуры 1 (этот байт всегда расположен в памяти по адресу 0000h:0417h или 0040h:0017h):

Бит 7: Ins включена Бит 6: CapsLock включена Бит 5: NumLock включена Бит 4: ScrollLock включена

Бит 3: Alt нажата (любая Alt для функции 02h, часто только левая Alt для 12h/22h)

Бит 2: Ctrl нажата (любая Ctrl)

Бит 1: Левая Shift нажата Бит 0: Правая Shift нажата

Байт состояния клавиатуры 2 (этот байт всегда расположен в памяти по адресу 0000h:0418h или 0040h:0018h):

Бит 7: SysRq нажата Бит 6: CapsLock нажата Бит 5: NumLock нажата Бит 4: ScrollLock нажата Бит 3: Правая Alt нажата Бит 2: Правая Ctrl нажата Бит 1: Левая Alt нажата Бит 0: Левая Ctrl нажата

Оба этих байта постоянно располагаются в памяти, так что вместо вызова прерывания часто удобнее просто считывать значения напрямую. Более того, в эти байты можно записывать новые значения, и BIOS изменит состояние клавиатуры соответственно:

; самая короткая программа для выключения NumLock, CapsLock и ScrollLock

; запускать без параметров

org 100h ; СОМ-файл. АХ при запуске СОМ-файла без параметров

; в командой строке всегда равен О

mov ds,ax ; так что теперь DS = О

mov byte pfr ds:0417h,al ; байт состояния клавиатуры 1 = О ret ; выход из программы

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

Помимо этих двух байт BIOS хранит в своей области данных и весь клавиатурный буфер, к которому также можно обращаться напрямую. Буфер занимает 15 слов с 0h:041Eh по 0h:043Dh включительно, причем по адресу 0h:041Ah лежит адрес (ближний) начала буфера, то есть адрес, по которому располагается следующий введенный символ, а по адресу 0h:041Ch лежит адрес конца буфера, так что если эти два адреса равны, буфер пуст. Буфер действует как кольцо: если начало буфера — 043Ch, а конец — 0420h, то в буфере находятся три символа по адресам 043Ch, 041 Eh и 0420h. Каждый символ хранится в виде слова — того же самого, которое возвращает функция 10h прерывания INT 16h. В некоторых случаях (если) буфер размещается по другим адресам, тогда адрес его начала хранится в области данных BIOS по адресу 0480h, а конца — по адресу 0482h. Прямой доступ к буферу клавиатуры лишь немногим быстрее, чем вызов соответствующих функций BIOS, и для приложений, требующих максимальной скорости, таких как игры или демо-программы, используют управление клавиатурой на уровне портов ввода-вывода.

Основная литература: 2[151-162], 6[22-64]

Дополнительная литература: 16[85-103],18[45-49],15[45-46]

1. Перечислите недостаток системных функций DOS.

2. С помощью каких функций BIOS можно поместить в буфер клавиатуры

ASCII код клавиши .

3.Опишите байт состояния клавиатуры 2.

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: Для студента самое главное не сдать экзамен, а вовремя вспомнить про него. 10041 — | 7504 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

Техническая документация

Содержание

1. РУКОВОДСТВО ПРОГРАММИСТА по BIOS

1.1. ПОДДЕРЖИВАЕМЫЕ ПРЕРЫВАНИЯ BIOS

1.2. ПОДДЕРЖИВАЕМЫЕ ПОЛЯ ОБЛАСТИ ПЕРЕМЕННЫХ BIOS

1.3. ИСПОЛЬЗУЕМЫЕ ПОЛЯ ОБЛАСТИ ДАННЫХ В СТАТИЧЕСКОМ ОЗУ

2. СИСТЕМНЫЕ УТИЛИТЫ

2.1. Программа SETUP.COM

2.2. Программа FLASHWR.COM

3. ОПИСАНИЕ ПРОТОКОЛА КАНАЛА УПРАВЛЕНИЯ PTSROM-DOS

3.1. ЛОГИКА КАНАЛА УПРАВЛЕНИЯ

3.2. ФОРМАТЫ УПРАВЛЯЮЩИХ ПАКЕТОВ ВЫСОКОГО УРОВНЯ

3.3. ФОРМАТЫ ПАКЕТОВ НИЗКОГО УРОВНЯ (ПАКЕТНЫЙ ПРОТОКОЛ)

1. РУКОВОДСТВО ПРОГРАММИСТА по BIOS

1.1. ПОДДЕРЖИВАЕМЫЕ ПРЕРЫВАНИЯ BIOS

INT 0 (деление на ноль)

Обработчик по умолчанию.

INT 1 (пошаговое выполнение)

Обработчик по умолчанию.

INT 2 (немаскируемое прерывание)

Обработчик по умолчанию.

INT 3 (точка останова)

Обработчик по умолчанию.

INT 4 (переполнение)

Обработчик по умолчанию.

INT 5 (копия экрана)

Обработчик по умолчанию.

INT 6 (неверный код операции)

Обработчик по умолчанию.

INT 7

Обработчик по умолчанию.

INT 8 (IRQ0 — таймер)

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

INT 9 (IRQ1 — контроллер клавиатуры)


Обработчик по умолчанию.

INT 0Ah (IRQ2 — видео)

Обработчик по умолчанию.

INT 0Bh (IRQ3 — COM2)

Обработчик по умолчанию.

INT 0Ch (IRQ4 — COM1)

Обработчик по умолчанию.

INT 0Dh (IRQ5 — LPT2)

Обработчик по умолчанию.

INT 0Eh (IRQ6 — контроллер дискет)

Обработчик по умолчанию.

INT 0Fh (IRQ7 — LPT1)

Обработчик по умолчанию.

INT 10h (Функции BIOS работы с видео)

На входе:
AH = 3 (Получить позицию и форму курсора)
BH = Номер видео страницы (игнорируется)
На выходе:
CX = Форма курсора (2000h)
DX = Позиция курсора (0)

На входе:
AH = 8 (Получить символ и атрибут из текущей позиции курсора)
На выходе:
AX = Символ (20h)
BH = Атрибут (7)

На входе:
AH = 9 (Записать символ и атрибут в текущую позицию курсора)
AL = Код символа
BH = Номер видео страницы (игнорируется)
BL = Атрибут (игнорируется)
CX = Количество символов (игнорируется)
На выходе:

На входе:
AH = 0Ah (Записать символ в текущую позицию курсора)
AL = Код символа
BH = Номер видео страницы (игнорируется)
CX = Количество символов (игнорируется)
На выходе:

На входе:
AH = 0Eh (Вывести символ с модификацией текущей позиции)
AL = Код символа
На выходе:

На входе:
AH = 0Fh (Получить текущий видео режим)
На выходе:
AH = Ширина экрана (80)
AL = Видео режим(3 = Текстовый 80×25)
BH = Активная видео страница(0)

На входе:
AH = 13h (Вывести строку символов)
AL = Номер подфункции (игнорируется)
BH = Номер видео страницы (игнорируется)
BL = Атрибут (игнорируется)
CX = Длина строки
DX = Позиция курсора (игнорируется)
ES:BP = Адрес строки
На выходе:

INT 11h (Получить список оборудования в AX)

Список оборудования см. ниже.

INT 12h (Получить размер основной памяти в AX)

INT 13h (Функции BIOS работы с дисками)

В случае ошибки устанавливается флаг переноса (CF), а код ошибки возвращается в регистре AH. Возможны следующие коды ошибок:

0 Нет ошибки. 1 Неизвестная функция. 3 Защита от записи (ошибка записи). 10h Ошибка контрольной суммы (ошибка чтения).

На входе:
AH = 0 (Сбросить дисковую систему)
DL = Номер диска
На выходе:
CF, AH

На входе:
AH = 1 (Получить состояние последней операции)
DL = Номер диска
На выходе:
CF, AH

На входе:
AH = 2 (Прочитать заданное количество секторов)
AL = Количество секторов
CH = Номер цилиндра
CL = Номер сектора
DH = Номер головки
DL = Номер диска
ES:BX = Адрес буфера
На выходе:
CF, AH
AL = Количество прочитанных секторов

На входе:
AH = 3 (Записать заданное количество секторов)
AL = Количество секторов
CH = Номер цилиндра
CL = Номер сектора
DH = Номер головки
DL = Номер диска
ES:BX = Адрес буфера
На выходе:
CF, AH
AL = Количество записанных секторов

На входе:
AH = 4 (Проверить заданное количество секторов)
AL = Количество секторов
CH = Номер цилиндра
CL = Номер сектора
DH = Номер головки
DL = Номер диска
ES:BX = Адрес буфера
На выходе:
CF, AH
AL = Количество проверенных секторов

На входе:
AH = 8 (Получить параметры диска)
DL = Номер диска
На выходе:
CF, AH
BL = Тип диска (10h)
CH = Максимальный номер цилиндра
CL = Максимальный номер сектора
DH = Максимальный номер головки
DL = Количество дисков
ES:DI = Адрес таблицы параметров дискеты

На входе:
AH = 15h (Получить тип диска)
DL = Номер диска
На выходе:
AH = Тип диска (2 = Дисковод с детектором смены)

На входе:
AH = 16h (Получить состояние детектора смены дисковода)
DL = Номер диска
На выходе:
AH = Состояние детектора смены (0 = Смены диска не было)

INT 14h (Функции BIOS работы с последовательными портами)

На входе:
AH = 0 (Инициализировать порт)
AL = Параметры инициализации
DX = Номер порта
На выходе:
AX = Состояние порта

На входе:
AH = 1 (Передать символ)
AL = Код символа
DX = Номер порта
На выходе:
AH = Состояние порта

На входе:
AH = 2 (Получить символ)
DX = Номер порта
На выходе:
AH = Состояние порта
AL = Код символа

На входе:
AH = 3 (Получить состояние порта)
DX = Номер порта
На выходе:
AX = Состояние порта

На входе:
AH = 4 (Инициализировать порт)
AL, BX, CX = Параметры инициализации
DX = Номер порта
На выходе:
AX = Состояние порта

На входе:
AH = 5 (Передать пакет)
CX = Длина пакета
DX = Номер порта
DS:SI = Пакет
На выходе:
AH = Код ошибки (0 = нет ошибки, -1 = ошибка)

На входе:
AH = 6 (Получить пакет)
CX = Размер буфера под пакет
DX = Номер порта
DS:SI = Буфер под пакет
На выходе:
AH = Код ошибки (0 = нет ошибки, -1 = ошибка)
CX = Длина пакета

INT 15h (Специальные функции)

На входе:
AH = 0E900h (Сбросить таймер-сторож)
На выходе:

На входе:
AH = 0E901h (Записать код диагностической контрольной точки)
CX = Код контрольной точки (коды 000h-1FFh зарезервированы для системы)
На выходе:

На входе:
AH = 0E902h (Установить диагностический флаг ошибки DOS)
CX = Маска диагностического флага
На выходе:

На входе:
AH = 0E903h (Разрешить запись на флэш-диск)
На выходе:

На входе:
AH = 0E904h (Запретить запись на флэш-диск)
На выходе:

На входе:
AH = 0E905h (Записать образ BIOS во флэш-память)
DS:SI = адрес буфера
На выходе:

На входе:
AH = 0E906h (Прочитать setup-информацию с флэш-диска)
DS:SI = адрес буфера
На выходе:
AL = Код ошибки(0 = нет ошибки; 1 = setup-информация не найдена)

На входе:
AH = 0E907h (Записать setup-информацию на флэш-диск)
DS:SI = адрес буфера
На выходе:

На входе:
AH = 0E908h (Установить точку останова)
CL = Флаги:
(0) = 0 Посылать отладочную информацию в канал управления.
1 Вызывать обработчик.
(1) = 0 Сработать однократно.
1 Срабатывать многократно.
ES:SI = Адрес точки останова.
DX:DI = Адрес обработчика.
На выходе:
AH = Код ошибки:

0 Нет ошибки. 1 Неправильный параметр. 2 Нет места в таблице точек останова.

На входе:
AH = 0E909h (Снять точку останова)
ES:SI = Адрес точки останова.
На выходе:
AH = Код ошибки:

0 Нет ошибки. 1 Неправильный параметр.

INT 16h (Функции BIOS работы с клавиатурой)

На входе:
AH = 0 (Получить код нажатой клавиши)
На выходе:
AH = Скан-код
AL = ASCII код

На входе:
AH = 1 (Получить состояние клавиатуры)
На выходе:
ZF = 1, если буфер клавиатуры пуст

На входе:
AH = 2 (Получить флаги клавиатуры)
На выходе:
AL = флаги клавиатуры (0)

INT 17h (Функции BIOS работы с параллельными портами)

Обработчик по умолчанию (работа с параллельным портом ведется как с COM3).

INT 18h (ROM BASIC)

Обработчик по умолчанию.

INT 19h (Перезагрузка)

INT 1Ah (Функции BIOS работы с таймером)

На входе:
AH = 0 (Получить счетчик таймера)
На выходе:
AL = Состояние переполнения счетчика таймера
CX:DX = Счетчик таймера

На входе:
AH = 1 (Установить счетчик таймера)
CX:DX = Счетчик таймера
На выходе:

INT 1Bh (Пользовательский обработчик Ctrl/Break)

INT 1Ch (Пользовательский обработчик прерывания таймера)

Vector 1Dh (Адрес таблицы видео параметров)

Указывает на фиктивную таблицу.

Vector 1Eh (Адрес таблицы параметров дискеты)

Указывает на фиктивную таблицу.

Vector 1Fh (Адрес таблицы графических символов CGA)

Указывает на фиктивную таблицу.

1.2. ПОДДЕРЖИВАЕМЫЕ ПОЛЯ ОБЛАСТИ ПЕРЕМЕННЫХ BIOS

Область переменных BIOS расположена в сегменте 0040h.

Поддерживаются следующие поля:

0000h (8 слов) Базовые адреса портов COM1-COM4 и LPT1-LPT4. 0010h (слово) Список оборудования:
0 Наличие дисководов. 1 Наличие сопроцессора. 2-3 Количество памяти (01 = 16К; 10 = 32К; 11 = 64К+). 4-5 Видео адаптер/режим (01 = 40ц; 10 = 80ц; 11 = ч/б). 6-7 Количество дисководов (00 = 1; 01 = 2; 10 = 3; 11 = 4). 8 Наличие DMA. 9-11 Количество последовательных портов. 12 Наличие игрового порта. 13 Наличие принтера у Pcjr. 14-15 Количество параллельных портов. 0013h (слово) Размер основной памяти в Кбайтах. 0017h (слово) Флаги клавиатуры. 0019h (байт) Значение, накапливаемое при Alt-вводе. 001Ah (слово) Адрес начала очереди клавиатуры. 001Ch (слово) Адрес конца очереди клавиатуры. 001Eh (32 байта) Очередь клавиатуры. 0049h (байт) Текущий видео режим. 004Ah (слово) Ширина экрана. 006Ch (2 слова) Счетчик таймера. 0070h (байт) Флаг переполнения счетчика таймера. 0071h (байт) Флаг Ctrl/Break (бит 7). 0072h (слово) Тип перезагрузки. 0084h (байт) Максимальный номер строки на экране. 0085h (слово) Высота символа.

1.3. ИСПОЛЬЗУЕМЫЕ ПОЛЯ ОБЛАСТИ ДАННЫХ В СТАТИЧЕСКОМ ОЗУ (СТРАНИЦА 7 СМЕЩЕНИЕ 0FF00H).

(Слово прямое, слово инвертированное) Размер области данных. (Слово прямое, слово инвертированное) Setup-информация загрузчика. (Слово прямое, слово инвертированное) Setup-информация BIOS. (байт прямой, байт инвертированный) Номер текущего элемента в массиве диагностической информации. (Слово прямое, слово инвертированное) Setup-информация загрузчика с флэш-диска. (Слово прямое, слово инвертированное) Setup-информация BIOS с флэш-диска. (Размер определяется исходным текстом) Массив диагностической информации.

Структура элемента массива диагностической информации:

(Слово прямое, слово инвертированное) Код последней исполненной контрольной точки. (Слово прямое, слово инвертированное) Флаги ошибок загрузчика. (Слово прямое, слово инвертированное) Флаги ошибок BIOS. (Слово прямое, слово инвертированное) Флаги ошибок DOS.

Описание кодов контрольных точек и флагов ошибок см. в документе «РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ BIOS» .

2. РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ BIOS

2.1. ПРОГРАММА SETUP.COM

Предназначена для просмотра и изменения setup-информации, записанной на флэш-диске, а также для просмотра диагностической информации.

Программа позволяет менять следующие параметры конфигурации (в скобках указаны значения по умолчанию):

Скорость канала управления: 110-115200 (9600).
Режим турбо (ON).
BIOS в ПЗУ (ON).
Таймер-сторож (ON).
Порт канала управления: COM1/COM2/COM3/COM4/LPT1 (COM1).
Скорость канала терминала: 110-115200 (115200).
Системный диск: A-E (A).
Два флаш-диска (ON).
Пропустить тестирование процессора (OFF).
Порт канала терминала: COM1/COM2/COM3/COM4/LPT1/OFF (COM1).
Пропустить тестирование обычной памяти (OFF).
Пропустить тестирование SRAM (OFF).
Пропустить тестирование EMS (OFF).

Опции разбиты на два подменю (меню setup загрузчика и меню setup BIOS). Кроме того, есть возможность загрузить значения setup по умолчанию, либо восстановить используемые в данный момент значения.

Отдельный пункт меню позволяет получить стек диагностической информации. Информация выдается в виде таблицы, состоящей из 4-х столбцов. В самой нижней строке — информация после последней перезагрузки. В первом столбце — код последней исполненной контрольной точки. Возможны следующие значения (L — загрузчик, B — BIOS, D — DOS):

L: Stack Loaded
L: IVT Initialized
L: Channel Initialized
L: Local Loading
L: Flash Tested
L: Load from ROM
L: Load ROM Comp
L: Load from Fla
L: Load Flash Co
B: Chipset Initialized
B: CPU Tested
B: Stack Tested
B: CRC Tested
B: IVT Initialized
B: Vars Initialized
B: Resident Init
B: Channel Initialized
B: Memory Tested
B: SRAM Tested
B: EMS Tested
B: PIC Initialized
B: PPI Initialized
B: DMA Initialized
B: Timer Initialized
B: Disks Initialized
B: Boot Loaded
B: Failed Boot
D: Job Point: ##

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

В остальных 3-х стоблбцах выдаются флаги накопленных ошибок соответственно для загрузчика, BIOS и DOS.

Флаги ошибок загрузчика:

Не прошел тест процессора.
Поврежден код загрузчика.
Поврежден код загрузчика в ОЗУ.
Повреждена setup-информация загрузчика во флэш-памяти.
Повреждена setup-инфрмация BIOS во флэш-памяти.
Повреждено поле смещения BIOS во флэш-памяти.
Повреждено поле размера BIOS size во флэш-памяти.
Поврежден BIOS во флэш-памяти.
Поврежден BIOS в ПЗУ.
Повреждено поле последней операции во флэш-памяти.
Ошибка канала.
Повреждена setup-информация во флэш-памяти.
Загрузка BIOS с канала управления не прошла.
Загрузка DOS с канала управления не прошла.

Флаги ошибок BIOS:

Не прошел тест процессора.
Не прошел тест стека.
Поврежден код BIOS.
Не прошел тест основной памяти.
Не прошел тест SRAM.
Не прошел тест EMS.
Поврежден boot-сектор.
Ошибка при чтении boot-сектора.
Повреждена setup-информация загрузчика.
Повреждена setup-информация BIOS.

Флаги ошибок DOS могут формироваться прикладной программой (см. документ «Руководство программиста по BIOS»)

ВНИМАНИЕ! Выход из программы SETUP с сохранением может привести к разрушению информации на EMS-диске!

2.2. ПРОГРАММА FLASHWR.COM

Предназначена для разрешения и запрещения записи на флэш-диск, а также для записи образа BIOS во флэш-память.

FLASHWR ON
Разрешает запись на флэш-диск.

FLASHWR OFF
Сбрасывает буфер флэш-диска. Запрещает запись на флэш-диск.

FLASHWR BIOS
Записывает образ BIOS из заданного файла во флэш-память.

ВНИМАНИЕ! Разрешение записи на флэш-диск может привести к разрушению информации на EMS-диске!

3. ОПИСАНИЕ ПРОТОКОЛА КАНАЛА УПРАВЛЕНИЯ PTS ROM-DOS

3.1. ЛОГИКА КАНАЛА УПРАВЛЕНИЯ

В нормальном состоянии управляемая ЭВМ (MicroPC) находится в активном состоянии, то есть она в любой момент может послать сообщение, на которое управляющая ЭВМ, находящаяся в пассивном, ждущем состоянии, должна успеть отреагировать. Если же какое-либо сообщение хочет послать управляющая ЭВМ, она каким-либо образом должна произвести удаленную перезагрузку управляемой ЭВМ. Передача сообщений между управляемой и управляющей ЭВМ производится пакетами.

3.2. ФОРМАТЫ УПРАВЛЯЮЩИХ ПАКЕТОВ ВЫСОКОГО УРОВНЯ

Извещение о перезагрузке управляемой ЭВМ.

Пакет имеет длину 4 байта, содержащие слово «LOAD», и извещает управляющую ЭВМ о том, что произошла перезагрузка и можно посылать команду.

Команда от управляющей ЭВМ.

Пакет имеет длину 6 байт, содержащие слово «COMM» и 2-х байтовый код команды. Возможны следующие команды:

01 Требует получить setup-информацию. 02 Требует передать диагностическую информацию.

Диагностическая информация.

Пакет заголовка имеет длину 6 байт, содержит слово «DIAG» и 2-х байтовую длину диагностической информации в пакетах. Далее идет сама диагностическая информация пакетами. Каждый пакет имеет длину 134 байта и содержит слово «DIAG», 2-х байтовый номер пакета и 128 байт полезной информации.

Setup-информация.

Пакет имеет длину 8 байт и содержит слово «SETP» и 2-х байтовые setup-информации загрузчика и BIOS.

Содержимое setup-информации определяет, будет ли происходить передача BIOS и/или DOS.

Запрос от управляемой ЭВМ на передачу BIOS.

Пакет имеет длину 4 байта и содержит слово «BIOS».

Заголовок BIOS.

Пакет заголовка имеет длину 6 байт и содержит слово «BIOS» и 2-х майтовую длину образа BIOS в пакетах.

Запрос от управляемой ЭВМ на передачу пакета BIOS.

Пакет имеет длину 6 байт и содержит слово «BIOS» и номер требуемого пакета.

Пакет BIOS.

Пакет имеет длину 134 байта и содержит слово «BIOS», 2-х байтовый номер пакета и 128 байт полезной информации.

Подтверждение управляемой ЭВМ окончания приема BIOS.

Пакет имеет длину 6 байт и содержит слово «BIOS» и 2 байта 0.

Запрос от управляемой ЭВМ на передачу DOS.

Пакет имеет длину 4 байта и содержит слово «PTOS».

Заголовок DOS.

Пакет заголовка имеет длину 6 байт и содержит слово «PTOS» и 2-х байтовую длину образа PTOS в пакетах.

Запрос от управляемой ЭВМ на передачу пакета DOS.

Пакет имеет длину 6 байт и содержит слово «PTOS» и номер требуемого пакета.

Пакет DOS.

Пакет имеет длину 134 байта и содержит слово «PTOS», 2-х байтовый номер пакета и 128 байт полезной информации.

Подтверждение управляемой ЭВМ окончания приема DOS.

Пакет имеет длину 6 байт и содержит слово «PTOS» и 2 байта 0.

Отладочная информация.

Пакет имеет длину 32 байта, содержащие слово «DEBU» и содержимое регистров процессора 8088 в следующем порядке: SP, SS, ES, DS, BP, DI, SI, DX, CX, BX, AX, IP, CS, FLAGS. Отладочная информация передается при достижении соответствующей точки останова (см. документ «Руководство программиста по BIOS»).

3.3. ФОРМАТ ПАКЕТОВ НИЗКОГО УРОВНЯ (ПАКЕТНЫЙ ПРОТОКОЛ)

Перед передачей пакета передающая сторона передает в канал байт 52h и ждет подтверждения от принимающей стороны в течение некоторого времени (для MicroPC это время составляет приблизительно 1 с), если подтверждение не было получено, то делается еще 4 попытки, после чего возвращается ошибка. Если же подтверждение было получено (байт 41h), то посылается следующая информация:

Два синхронизирующих байта 50h, 50h;
Байт размера пакета — 1 (данных);
Два байта CRC (данных);
Блок данных;
Два синхронизирующих байта F0h, F0h.

После этого передающая сторона ожидает подтверждения в виде двух байтов 59h, 59h. Если подтверждение не приходит, то делается еще 4 попытки, после чего возвращается ошибка.

См. документ «Руководство программиста по BIOS» .

Илон Маск рекомендует:  -ms-interpolation-mode в CSS
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL