6.1. Сервисные прерывания DOS

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

6.3. Коэффициенты пересчета для нот

6.4. Значение цветов в байте атрибута

6.5. Буфер клавиатуры

6.1. Сервисные прерывания DOS

Информация в этом и следующем разделах пособия в основном взята из книги К.Г. Финогенова «Самоучитель по системным функциям MS DOS».

INT 21h, функция 01h ‑ ввод символа с эхом. Вводит ASCII-код символа с клавиатуры, при этом вводимый символ автоматически отображается на экране в позиции курсора (эхо ‑ отображение). Для чтения СКЭН-кода клавиши требуется повторное выполнение этой функции. При отсутствии символа функция ждет его ввода.

При вызове: ah = 01h.

При возврате: al = ASCII- (СКЭН)-код символа.

INT 21h, функция 02h ‑ вывод символа. Выводит символ на экран. Коды ASCII: 07h – звонок, 08h – шаг назад, 09h – табуляция, 0dh – возврат каретки, 0ah – перевод строки рассматриваются как управляющие и выполняют соответствующие действия.

При вызове: ah = 02h.

dl = ASCII-код выводимого символа.

INT 21h, функция 06h ‑ прямой ввод ‑ вывод. Вводит код символа с клавиатуры или выводит его на экран. В режиме вывода коды ASCII: 07h – звонок, 08h – шаг назад, 0dh – возврат каретки, 0ah – перевод строки рассматриваются как управляющие и выполняют соответствующие действия. Для чтения СКЭН-кода требуется повторное выполнение данной функции. При вводе функция не ждет нажатия клавиши, а возвращает управление в программу.

При вызове: ah = 06h.

dl = ASCII-код символа (00-FEh) при выводе.

dl = FFh при вводе.

При возврате: al = ASCII-код символа при вводе, если символа нет ‑ zf = 1.

INT 21h, функция 07h ‑ нефильтрованный ввод без эха. Аналогична функции 01h (см. выше), только нет эхо - отображения.

INT 21h, функция 08h ‑  ввод символа без эха. Практически аналогична функции 07h.

INT 21h, функция 09h ‑ вывод строки. Выводит на экран строку символов. Строка должна заканчиваться символом $. Коды ASCII: 07h – звонок, 08h – шаг назад, 0dh – возврат каретки, 0ah – перевод строки рассматриваются как управляющие и выполняют соответствующие действия.

При вызове: ah = 09h.

ds:dx = адрес первого символа строки.

INT 21h, функция 0ah ‑ буферизированный ввод с клавиатуры. Вводит строку символов с клавиатуры в созданный в программе буфер. Вводимая строка отображается на экране. Строка должна заканчиваться кодом ENTER (0dh).

При вызове: ah = 0ah.

ds:dx = адрес буфера.

При возврате: Данные помещены в буфер. Формат буфера:

байт 0 – ожидаемая длина строки;

байт 1 – фактическая длина введенной строки;

байт 2 и далее – строка, заканчивающаяся 0dh.

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

NT 21h, функция 25h ‑ установка вектора прерывания. Позволяет записать новый вектор в заданное место таблицы прерываний.

При вызове: ah = 25h.

al = тип подменяемого вектора.

ds:dx  =  новый вектор.

INT 21h, функция 2ah. Получение текущей даты.

При вызове: ah = 2ah.

При возврате: cx = год (от 1980 до 2099); dh = месяц (от 1 до 12); dl = день (от 1 до 31); al = день недели (0 – воскресенье и т.д.).

INT 21h, функция 2ch ‑ получение текущего времени.

При вызове: ah = 2ch.

При возврате: ch = часы (от 0 до 23); cl = минуты (от 0 до 59); dh = секунды (от 0 до 59).

INT 21h, функция 31h ‑ завершение программы и сохранение ее резидентной в памяти.

При вызове: ah = 31h.

dx = объем оставляемой в памяти части программы.

Объем оставляемой части измеряется здесь в параграфах. Параграф – 16 байт. Если нам известен объем в байтах (n), то объем в параграфах считается так:(целое от n/16)+1.

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

При вызове: ah = 4ch.

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

При вызове: al = номер дисковода (0 – А, 1 – В,…).

cx = число читаемых секторов.

dx = логический номер начального сектора.

ds:bx = начальный адрес буфера.

При ошибке: флаг cf = 1, ax = код ошибки.

Примечание.

Коды ошибки в ah:

- 01hнеправильная команда;

- 02h – неправильная адресная метка;

-04hзапрошенный сектор не найден;

- 08hошибка прямого доступа к памяти;

- 10h – ошибка данных (неправильная контрольная сумма);

- 20h ошибка контроллера;

- 40h ошибка позиционирования.

Коды ошибки в al:

- 00hошибка защиты записи;

01h – неизвестное устройство;

02hдисковод не готов;

- 03hнеизвестная команда;

04hошибка данных (неправильная контрольная сумма);

06h ошибка позиционирования;

07h неизвестный тип носителя;

- 08h – сектор не найден.

INT 26h ‑ Абсолютная запись на диск. Позволяет записать из памяти на диск группу секторов, начиная с заданного, из созданного в памяти буфера. После этого прерывания в стеке задачи остается слово, содержащее значение регистра флагов. Если это слово не удалить, может нарушиться дальнейший ход программы.

При вызове: al = номер дисковода (0 – А, 1 – В,…).

cx = число записываемых секторов.

dx = логический номер начального сектора.

ds:bx = начальный адрес буфера.

При ошибке: флаг cf = 1.

ax = код ошибки (смотри INT 25h).

INT 27h ‑ завершить программу, оставив в памяти ее резидентную часть.

При вызове: dx = размер оставляемой в памяти части в байтах.

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

INT 10h, функция 00h ‑ установка видеорежима. Устанавливает текущий видеорежим.

При вызове: ah = 00h.

al = видеорежим:

- 03h – текстовый 80*25;

- 04h – графический 320*200;

- 10h – графический 640*350;

- 12h – графический 640*480;

INT 10h, функция 01h ‑ установка конфигурации курсора. Позволяет задать начальную и конечную строки развертки курсора в текстовых видеорежимах.

При вызове: ah = 01h.

ch = начальная (верхняя) строка развертки.

сl = конечная (нижняя) строка развертки.

INT 10h, функция 02h ‑ установка позиции курсора. Задает положение курсора на экране в текстовых координатах на указанной видеостранице.

При вызове: ah = 02h.

bh = № видеостраницы; dh = строка; dl = столбец.

INT 10h, функция 03h ‑получение позиции и размера курсора. Возвращает положение курсора на экране для заданной видеостраницы.

При вызове: ah = 03h.

bh = № видеостраницы.

При возврате: ch = начальная (верхняя) строка развертки курсора.

cl = конечная (нижняя) строка развертки курсора; dh = строка;

dl = столбец.

INT 10h, функция 06h ‑ инициализация или прокрутка окна вверх. Инициализирует окно с указанными координатами, заполняя его пробелами с заданным атрибутом, или прокручивает содержимое окна вверх на заданное число строк. Действует для активной видеостраницы. При прокрутке появляющиеся снизу строки заполняются пробелами с заданным атрибутом.

При вызове: ah = 06h.

al = число строк прокрутки; если al = 0, все окно очищается.

bh = атрибут символов в окне.

ch = Y ‑ координата верхнего левого угла окна.

cl = X ‑ координата верхнего левого угла окна.

dh = Y ‑ координата нижнего правого угла окна.

dl = X ‑ координата нижнего правого угла окна.

INT 10h, функция 07h ‑ инициализация или прокрутка окна вниз. Инициализирует окно с указанными координатами, заполняя его пробелами с заданным атрибутом, или прокручивает содержимое окна вниз на заданное число строк. Действует только для активной видеостраницы. При прокрутке появляющиеся сверху строки заполняются пробелами с заданным атрибутом.

При вызове: ah = 07h.

al = число строк прокрутки; если al = 0, все окно очищается.

bh = атрибут символов в окне.

ch = Y ‑ координата верхнего левого угла окна.

cl = X ‑ координата верхнего левого угла окна.

dh = Y ‑ координата нижнего правого угла окна.

dl = X ‑ координата нижнего правого угла окна.

INT 10h, функция 08h ‑ чтение символа и атрибута в позиции курсора. Возвращает ASCII.код символа, расположенного в позиции курсора на заданной видеостранице, и его атрибут.

При вызове: ah = 08h.

bh = № видеостраницы.

При возврате: al = ASCII-код символа.

ah = атрибут.

INT 10h, функция 09h ‑ запись символа и атрибута в позицию курсора. Записывает символ и его атрибут в текущую позицию курсора. Курсор при этом не смещается, а остается в исходной позиции. Коэффициент повторения позволяет выводить строки одинаковых символов (но курсор не смещается!). Если коэффициент повторения равен 0, на экран ничего не выводится.

При вызове: ah = 09h.

al = ASCII-код символа.

bh = № видеостраницы.

bl = атрибут.

cx = коэффициент повторения.

INT 10h, функция 0ah ‑ запись символа в позицию курсора. Записывает ASCII-код символа в текущую позицию курсора. Символ принимает атрибут, установлен-ный ранее для этой позиции. Курсор при выводе не смещается, а остается в исходной позиции. Коэффициент повторения позволяет выводить строки одинаковых символов (но курсор не смещается!). Если коэффициент повторения равен 0, на экран ничего не выводится.

При вызове: ah = 0ah.

bh = № видеостраницы.

al = ASCII-код символа.

cx = коэффициент повторения.

INT 10h, функция 0eh ‑ запись символа в режиме телетайпа. Записывает ASCII код символа в текущую позицию курсора на активной видеостранице. Курсор после вывода автоматически смещается к следующей позиции. Коды ASCII: 07 – звонок, 08 – шаг назад, 0ah – перевод строки, 0dh – возврат каретки рассматриваются как управляющие и выполняют соответствующие действия. Действует автоматический перевод курсора на следующую строку и скроллинг экрана. Атрибут символа задать нельзя, действует атрибут, установленный ранее для этой позиции.

При вызове: ah = 0eh.

alASCII-код символа.

INT 10h, функция 10h, подфункция 03h ‑ переключение бита «мерцание/яркость». Определяет назначение старшего (7-го) бита атрибута символа: мерцание символа или яркость фона.

При вызове: ax = 1003h.

bl = назначение старшего бита атрибута:

- 0 – яркость фона;

- 1 – мерцание символа.

INT 10h, функция 13h ‑ запись строки в режиме телетайпа ‑ записывает строку символов в заданную видеостраницу, начиная с указанной позиции. Коды ASCII: 07 – звонок, 08 – шаг назад, 09 – табуляция, 0ah – перевод строки, 0dh – возврат каретки рассматриваются как управляющие и выполняют соответствующие действия.

При вызове: ah = 13h.

al = режим записи:

- 0 – атрибут в bl, строка содержит только коды символов, курсор после вывода не смещается;

- 1 - атрибут в bl, строка содержит только коды символов, курсор после вывода  смещается;

- 2 - строка содержит попеременно коды символов и атрибутов, курсор после вывода не смещается;

- 3 - строка содержит попеременно коды символов и атрибутов, курсор после вывода смещается;

bh = № видеостраницы.

bl = атрибуты ( если в al 0 или 1).

cx = число выводимых символов (атрибуты не учитываются); dh = номер строки на экране; dl = номер столбца на экране; es:bp = адрес строки в памяти.

INT 15h, функция 86h ‑ программная задержка на заданное число микросекунд. Выполняет задержку на число микросекунд, заданное в регистрах cx (старшая часть) и dx (младшая часть).

При вызове: ah = 86h.

cx,dx  =  микросекунды.

INT 16h, функция 00h (10h) ‑ чтение символа с клавиатуры. Читает из кольцевого буфера клавиатуры ASCII- и СКЭН-коды нажатой клавиши. Если буфер пуст, ждет нажатия клавиши. Функция 10h предназначена для расширенной клавиатуры (101 клавиша), функция 0h – для 84-клавишной.

При вызове: ah = 00h (или 10h).

При возврате: ah = СКЭН-код; al = ASCII-код.

INT 16h, функция 01h (11h) ‑ чтение символа с клавиатуры. Определяет, есть ли в буфере клавиатуры ожидающие ввода символы. Если есть, то читает из кольцевого буфера клавиатуры ASCII- и СКЭН-коды нажатой клавиши, однако при этом из буфера эти коды не удаляются и будут снова получены при обращении к буферу. Если буфер пуст, то управление передается следующей команде программы. Функция 11h предназначена для расширенной клавиатуры (101 клавиша), функция 1h – для 84-клавишной.

При вызове: ah = 01h (или 11h).

При возврате: Если символ ожидает:

zf = 0;

ah  =  СКЭН-код;

al  =  ASCII-код.

Если буфер пуст: zf = 1.

INT 16h, функция 02h (12h) ‑ получение статуса клавиатуры. Для функции 02h возвращает байт флагов, описывающий состояние управляющих клавиш клавиатуры. Для функции 12h возвращает слово флагов, при этом младший байт этого слова совпадает с байтом, возвращаемым функцией 02h.

При вызове: ah = 02h (или 12h).

При возврате: Функция 02h: al = флаги.

Функция 12h: ax = флаги.

Биты флагов имеют следующие значения:

- бит 0 = 1 – нажат правый SHIFT;

- бит 1 = 1 – нажат  левый SHIFT;

- бит 2 = 1 – нажат CTRL;

- бит 3 = 1 – нажат ALT;

- бит 4 = 1 – включен режим SCROLL LOCK;

- бит 5 = 1 – включен режим NUM LOCK;

- бит 6 = 1 – включен режим CAPS LOCK;

- бит 7 = 1 – включен режим INSERT (последующие флаги возвращает только функция 12h);

- бит 8 = 1 ‑ нажат левый CTRL;

- бит 9 = 1 – нажат левый ALT;

- бит 10 = 1 – нажат правый CTRL;

- бит 11 = 1 – нажат правый ALT;

- бит 12 = 1 – нажат SCROLL LOCK;

- бит 13 = 1 – нажат NUM LOCK;

- бит 14 = 1 – нажат CAPS LOCK;

- бит 15 = 1 – нажат SYSREG.

INT 1ah, функция 0h ‑ число тиков таймера. Возвращает число тиков таймера с момента последнего сброса системы. Таймер тикает через каждые 55 миллисекунд, т.е. примерно 18 раз в секунду (1092 раза в минуту).

При вызове: ah = 00h.

При возврате: cx,dx = число тиков (в сх – старшая часть); al = 0, если системные часы не переходили через сутки.

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

6.3. Коэффициенты пересчета для нот

Коэффициенты пересчета округлены до ближайшего целого и приведены в табл. 6.1.

Таблица 6.1

Ноты

Малая октава

Первая октава

Вторая октава

Третья октава

до

7790

3895

1947

974

до#

7353

3676

1838

919

ре

6940

3470

1735

867

ре#

6551

3275

1638

819

ми

6183

3091

1546

773

фа

5836

2918

1459

729

фа#

5508

2754

1377

689

соль

5199

2599

1300

650

соль#

4907

2454

1227

613

Ля

4632

2316

1158

579

Ля#

4372

2284

1093

546

Си

4127

2063

1032

516

Как правило, хорошо звучат ноты третьей октавы.

6.4. Значение цветов в байте атрибута

     Коды значений цветов приведены в табл. 6.2.

Таблица 6.2

Значение

Бит яркости

Цвет

000

0

черный

001

0

синий

010

0

зеленый

011

0

голубой

100

0

красный

101

0

пурпурный

110

0

коричневый

111

0

светло-серый

000

1

темно-серый

001

1

светло-синий

010

1

светло-зеленый

011

1

светло-голубой

100

1

светло-красный

101

1

светло-пурпурный

110

1

желтый

111

1

белый

6.5. Буфер клавиатуры

Буфером клавиатуры называются 32 байта памяти, расположенные в области переменных BIOS, начиная с адреса 0041eh и заканчивая адресом 0043ch. Буфер может накапливать до 15 нажатий клавиш, при этом для каждой клавиши в буфере отводится слово, младший байт которого содержит ASCII-, а старший – СКЭН-коды нажатой клавиши.

Буфер клавиатуры называется кольцевым, поскольку представляет собой циклическую очередь, реализующую процедуру FIFO (первый пришел – первый ушел). Это означает, что в буфере нет определенной ячейки памяти, с которой начинается его заполнение. Зато имеются понятия «голова буфера» и «хвост буфера».

Головой буфера считается слово, в которое занесены коды первой нажатой клавиши, а хвостом – слово за ячейкой, в которой находятся коды последней нажатой клавишей (рис. 6.1)

0041eh

 

Голова

   

Хвост

 

0043ch

Своб.

Своб

Код

Код

Код

Своб

Своб

Своб

Рис. 6.1

.Для того чтобы с буфером можно было работать, в памяти выделены еще два слова с адресами 0041ah и 0041ch. В первой из них хранится смещение ячейки, являющейся в настоящий момент головой буфера, относительно адреса 00400h.

Принято говорить, что в ячейке 0041ah хранится указатель головы буфера. Соответственно, в ячейке 0041ch хранится указатель хвоста. Например, последовательно нажаты две клавиши, коды которых попали в буфер, который до этого был пуст. При этом код первой клавиши попал в ячейку 00432h, а код второй – в ячейку 00434h. Тогда указатель головы (содержимое ячейки 0041ah) будет равен 32h, а указатель хвоста (содержимое ячейки 0041ch) – 36h.

Когда  нажимаем  клавишу  на  клавиатуре, обработчик 9-го прерывания заносит его код в буфер по адресу, на который указывает указатель хвоста, а затем прибавляет к указателю хвоста двойку. Указатель хвоста всегда указывает на первую свободную ячейку буфера.

Когда адресное пространство, отведенное под буфер, заканчивается, указатель хвоста устанавливается на начало буфера (двойка в этом случае не прибавляется), и ввод клавиш может быть продолжен. Например, пусть указатель хвоста равен 3ch (установлен на последнее слово буферной области). Тогда при нажатии клавиши ее код попадет в ячейку 0043ch, а в указатель хвоста будет записано новое значение 1eh (установлен на первое слово буферной области). Именно из-за такой организации буфер и называется кольцевым.

Когда программа считывает код клавиши из буфера, этот код берется из ячейки, на которую установлен указатель головы, после чего к этому указателю надо прибавить двойку (или записать в него 1eh, если буферная область кончилась).

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

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

Два байта, расположенные в ячейках памяти 00417h и 00418h, называются байтами состояния клавиатуры. Они имеют следующий формат:

Байт 417h      бит 0 = 1 – нажат правый Shift;

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

бит 2 = 1 – нажат Ctrl (любой);

бит 3 = 1 – нажат Alt (любой);

бит 4 = 1 – включен ScrollLock;

бит 5 = 1 – включен NumLock;

бит 6 = 1 – включен CapsLock;

бит 7 = 1 – включен режим Ins;

Байт 418h      бит 0 = 1 – нажат левый Ctrl;

бит 1 = 1 – нажат левый Alt;

бит 2 = 1 – нажат SysReg;

бит 3 = 1 – установлен режим «ПАУЗА»;

бит 4 = 1 – нажат ScrollLock;

бит 5 = 1 – нажат NumLock;

бит 6 = 1 – нажат CapsLock;

бит 7 = 1 – нажат Ins.

Список литературы

1. Микропроцессорный комплект К1810. Справочная книга / Под ред. Ю.М. Казаринова. ‑ М: Высшая школа, 1990. ‑  269 c.

2. Григорьев В.Л. Микропроцессор i 486. Архитектура и программирование: В 2 т. ‑ М:  ГРАНАЛ, 1993. ‑ 747 с.

3. Вычислительные машины, системы и сети / Под ред. А.П. Пятибратова. ‑ М:  Финансы  и  статистика,  1991. ‑ 399 с.

4. Балашов Е.П. и др. Микро- и мини-ЭВМ: Учебное пособие для вузов. ‑ Л: Энергоатомиздат, 1984. – 375 с.

5. Артюхов В.Г и др. Проектирование микропроцес-сорной электронно-вычислительной аппаратуры: Справоч-ник. ‑ Киев: Тэхнiка, 1988. ‑ 263 с.

6. Ю-Чжен Лю, Гибсон Г. Микропроцессоры семейства 8086/8088. ‑ М: Радио и связь, 1987. ‑ 512 с.

7. Орловский Г.В. Введение в архитектуру микропро-цессора 80386. ‑ СПб: Сеанс-Пресс LTD, 1992. ‑ 189 с.

8. Алексенко А.Г. и др. Проектирование радиоэлектрон-ной аппаратуры на микропроцессорах. – М.: Радио и связь, 1984. ‑ 270 с.

9. Джордейн Р. Справочник программиста персональных компьютеров типа IBM PC, XT и АТ. – М.: Финансы и статистика, 1992. ‑ 543 с.

10. Абель П. Язык ассемблера для IBM PC и програм-мирования. – М.: Высшая школа, 1992. ‑ 447 с.

11. Финогенов К.Г. Самоучитель по системным функциям MS-DOS. – М.: Радио и связь, 1993. ‑ 382 с.

12. Intel Architecture Software Developer’s Manual. Intel Corporation, 2001. ‑ 1500 c.

13. Гук М. Процессоры Intel от 8086 до Pentium II. – СПб.: Питер Паблишинг, 1997. ‑ 221 с.

14. Гук М. Процессоры Pentium II, Pentium Pro и просто Pentium. ‑ СПб.: Питер Паблишинг,  1999. ‑ 282 с.