Аппаратное обеспечение персонального компьютера

         

- 0Dh - область часов реального времени


Ячейки с адресами 00h - 0Dh используются часами реального времени. Часам реального времени будет посвящена отдельная глава, поэтому сейчас мы не станем останавливаться на этих ячейках.



-1Ah тип первого и второго НМД


Эти ячейки содержат типы, соответственно, первого и второго НМД, если соответствующий тип имеет значение, большее 15 (см. описание ячейки 12h).



Определение конфигурации компьютера


Если ваша программа работает с устройствами компьютера на низком уровне или использует какие-либо аппаратные особенности периферии, она должна «уметь» определять конфигурацию аппаратных средств. В настоящее время выпускается много различных моделей персональных компьютеров и серверных платформ с процессором Intel, совместимых или не очень с оригинальным компьютером IBM PC/AT. В компьютере могут быть установлены процессоры различных моделей и различные версии BIOS. Что же касается номенклатуры периферийных устройств, таких как сетевые контроллеры, видеоадаптеры, сетевые и звуковые адаптеры, то она практически безгранична.

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

В следующем разделе мы рассмотрим средства BIOS, позволяющие определить конфигурацию компьютера. Об энергонезависимой памяти CMOS мы расскажем позже.



-3Fh - зарезервировано


Это поле зарезервировано, однако вы можете использовать по своему усмотрению, например, хранить здесь пароль.



Мышь


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

Что это за устройство и почему оно используется так же часто, как и клавиатура персонального компьютера?





Часы реального времени


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

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



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


Кроме часов реального времени, любой компьютер (даже простейший IBM PC) содержит устройство, называемое системным таймером. Это устройство подключено к линии запроса на прерывание IRQ0 и вырабатывает прерывание INT 8h приблизительно 18,2 раза в секунду (точное значение - 1193180/65536 раз в секунду).



Контроллер прямого доступа к памяти


Прямой доступ к памяти (Direct Memory Access - DMA) применяется для выполнения операций передачи данных непосредственно между оперативной памятью и устройствами ввода/вывода. Обычно это такие устройства, как НГМД, НМД, стримеры.

При использовании DMA процессор не участвует в операциях ввода/вывода. Контроллер прямого доступа сам формирует все сигналы, необходимые для обмена данными с устройством. Скорость такого непосредственного обмена значительно выше, чем при традиционном обмене с использованием центрального процессора и команд INP, OUT.

Заметим, что контроллеры DMA в компьютерах IBM PC/XT IBM PC/AT различаются, но совместимы снизу вверх. Поэтому вначале мы расскажем о первом типе контроллеров, затем займемся контроллером DMA компьютера IBM PC/AT.



Устройство чтения CD-ROM


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

Не останавливаясь подробно на описании различных форматов компакт-дисков, которое само по себе может составить предмет для отдельной книги, мы рассмотрим средства MS-DOS, предназначенные для работы с компакт-дисками формата ISO-9960 и со звуковыми компакт-дисками стандарта Redbook. Первые из них чаще всего применяются для хранения программ и компьютерных баз данных, вторые – для записи звуковой информации. О том, как работать со звуковыми дисками в среде операционной системы Microsoft Windows, мы рассказывали в 15 томе «Библиотеки системного программиста», который называется «Мультимедиа для Windows».



Арифметический сопроцессор


Еще одно устройство, которое мы опишем в этом томе - арифметический сопроцессор фирмы Intel. В старых моделях компьютеров сопроцессор устанавливался на системной плате в отдельной панельке и подключался непосредственно к центральному процессору. Современные процессоры Pentium содержат встроенный арифметический сопроцессор.

Арифметический сопроцессор предназначен для выполнения операций над числами в формате с плавающей точкой (вещественные числа) и длинными целыми числами. Он значительно (в десятки раз) ускоряет вычисления, связанные с вещественными числами. Сопроцессор может вычислять такие функции, как синус, косинус, тангенс, логарифмы и так далее. Разумеется, что с помощью сопроцессора можно выполнять и простейшие арифметические операции сложения, вычитания, умножения и деления.

Основная область применения арифметического сопроцессора - научные расчеты и машинная графика. Некоторые пакеты САПР, например, Autocad, отказываются работать, если в машине отсутствует сопроцессор.

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

Как программировать сопроцессор?

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

Ассемблерные мнемоники всех команд сопроцессора начинаются с буквы F, например: FADD, FDIV, FSUB и так далее. Команды сопроцессора могут адресоваться к операндам, аналогично обычным командам центрального процессора. Операндами могут быть либо данные, расположенные в основной памяти компьютера, либо внутренние регистры сопроцессора.

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

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



-16H - объем стандартной оперативной памяти


Ячейка 15h содержит младший байт, а ячейка 16h - старший байт объема основной памяти, например:

0100h – 256 Kбайт;

0200h – 512 Kбайт;

0280h – 640 Kбайт



-18H - объем расширенной памяти


Ячейки 17h и 18h содержат, соответственно, младший и старший байты размера расширенной памяти (расположенной выше границы 1 Мбайт) в килобайтах.



-31H - объем расширенной памяти


Ячейки 30h и 31h содержат, соответственно, младший и старший байты размера расширенной памяти (расположенной выше границы 1 Мбайт) в килобайтах.

Эта значение дублирует значение, записанное в ячейках с адресами 17h-18h.



Аннотация


В книге приведено описание методик программирования аппаратуры персональных компьютеров, выполненных с применением процессоров Intel, на уровне портов, прерываний DOS и BIOS, а также на уровне функций драйверов.

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



Антипереполнение


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

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



Аппаратная реализация


Компьютер может быть оснащен одним или двумя асинхронными последовательными адаптерами. Эти адаптеры расположены либо на системной плате, либо (в старых компьютерах) на отдельной плате, вставляемой в разъемы расширения системной платы.

Бывают также платы расширения, содержащие 4, 8 или большее количество асинхронных последовательных адаптеров. Их часто используют для подключения нескольких модемов к одному компьютеру.



Аппаратное прерывание клавиатуры


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

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



Арифметические команды


Сопроцессор использует шесть основных типов арифметических команд:

Команда

Описание

Fxxx

Первый операнд берется из верхушки стека (источник), второй - следующий элемент стека. Результат выполнения команды записывается в стек

Fxxx память

Источник берется из памяти, приемником является верхушка стека ST(0). Указатель стека ST не изменяется, команда действительна только для операндов с одинарной и двойной точностью

Fixxx память

Аналогично предыдущему типу команды, но операндами могут быть 16- или 32-разрядные целые числа

Fxxx ST, ST(i)

Для этого типа регистр ST(i) является источником, а ST(0) - верхушка стека – приемником. Указатель стека не изменяется

Fxxx ST(i), ST

Для этого типа регитр ST(0) является источником, а ST(i) - приемником. Указатель стека не изменяется

FxxxP ST(i), ST

Регистр ST(i) - приемник, регистр ST(0) – источник. После выполнения команды источник ST(0) извлекается из стека

Строка "xxx" может принимать следующие значения:

Значение

Операция

ADD

Сложение

SUB

Вычитание

SUBR

Обратное вычитание, уменьшаемое и вычитаемое меняются местами

MUL

Умножение

DIV

Деление

DIVR

Обратное деление, делимое и делитель меняются местами

Кроме основных арифметических команд имеются дополнительные арифметические команды:

Команда

Описание

FSQRT

Извлечение квадратного корня

FSCALE

Масштабирование на степень числа 2

FPREM

Вычисление частичного остатка

FRNDINT

Округление до целого

FXTRACT

Выделение порядка числа и мантиссы

FABS

Вычисление абсолютной величины числа

FCHS

Изменение знака числа

По команде FSQRT вычисленное значение квадратного корня записывается в верхушку стека ST(0).

Команда FSCALE изменяет порядок числа, находящегося в ST(0). По этой команде значение порядка числа ST(0) складывается с масштабным коэффициентом, который должен быть предварительно записан в ST(1). Действие этой команды можно представить следующей формулой:


ST(0) = ST(0) * 2n, где -215 <= n <= +215

В этой формуле n - это ST(1).

Команда FPREM вычисляет остаток от деления делимого ST(0) на делитель ST(1). Знак результата равен знаку ST(0), а сам результат получается в вершине стека ST(0).

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

Значение

Описание

0

Остаток от деления, полученный в ST(0), меньше делителя ST(1), команда завершилась полность

1

ST(0) содержит частичный остаток, программа должна еще раз выполнить команду для получения точного значения остатка

Команда RNDINT округляет ST(0) в соответствии с содержимым поля RC управляющего регистра.

Команда FABS вычисляет абсолютное значение ST(0). Аналогично, команда FCHS изменяет знак ST(0) на противоположный.


Авторский компакт-диск


В сентябре 1997 года в продаже появился авторский компакт-диск (как спецвыпуск журнала “Аурамедиа”), на котором вы можете найти наши первые книги серий “Библиотека системного программиста” и “Персональный компьютер. Шаг за шагом” в исходных текстах, дискеты ко всем книгам серии “Библиотека системного программиста”, статьи, написанные нами для периодических изданий, библиотеку программ FreeWare и ShareWare, ссылки на интересные ресурсы Internet, вернисаж художника Алексея Абрамкина и другую информацию.

Компакт-диск можно приобрести непосредственно в издательстве “Аурамедиа” и “Диалог-МИФИ”, а также по подписке.



Благодарности


Мы выражаем благодарность генеральному директору АО “ДиалогНаука” Антимонову Сергею Григорьевичу и его заместителю Лященко Юрию Павловичу за возможность размещения информации о наших книгах на сервере Web по адресу http://www.dials.ccas.ru/frolov, а также за возможность доступа к сети Internet через сервер АО “ДиалогНаука”.

Мы также благодарим корректора Кустова В. С. и сотрудников издательского отдела АО “Диалог-МИФИ” Голубева О. А., Голубева А. О., Дмитриеву Н. В., Виноградову Е. К., Кузьминову О. А.



Блокирование EMB


Регистры на входе:

AH = 0Ch

DX = идентификатор блока EMB

Регистры на выходе:

AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка;

DX:BX = 32-разрядный линейный адрес заблокированного EMB

Ошибки:

BL = 80h, 81h, A2h, ACh, ADh

Функция блокирует EMB и возвращает его базовый адрес как линейный 32-разрядный адрес. Для заблокированного EMB невозможно выполнить операцию копирования. Полученный линейный адрес действителен только для заблокированного EMB.



Блокирование и разблокирование компакт-диска в устройстве


// ---------------

// Код функции 1

// ---------------

#pragma pack(1)

typedef struct _LockDisk

{

  BYTE   bFunctionCode;

  BYTE   bLock;

} LockDisk;

Поле

Описание

bFunctionCode

Код функции

bLock

1 – блокирование компакт-диска;

0 – разблокирование компакт-диска



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


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

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

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

Заметим, что вы можете удалить все символы из буфера клавиатуры, установив оба указателя на начало буфера. Однако есть более предпочтительный способ с использованием прерывания BIOS INT16h, функции которого мы опишем позже в этой главе.

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

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

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



Буферизованный ввод без эхо-вывода


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

Регистры на входе:

AH = 08h

Регистры на выходе:

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

Функция проверяет комбинации клавиш <Control+C> и <Control+Break>

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



Буферизованный ввод с эхо-выводом


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

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

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

Регистры на входе:

AH = 01h

Регистры на выходе:

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

Функция проверяет комбинации клавиш <Control+C> и <Control+Break>

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



Целые числа


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

Возможно четыре формата целых чисел:

целое число;

короткое целое число;

длинное целое число;

упакованное десятичное число

Целое число занимает два байта. Его формат полностью соответствует используемому центральным процессором. Для представления отрицательных чисел используется дополнительный код. Короткое целое и длинное целое имеют аналогичные форматы, но занимают, соответственно, 4 и 8 байт.

Упакованное десятичное число занимает 10 байт. Это число содержит 18 десятичных цифр, расположенных по две в каждом байте. Знак упакованного десятичного числа находится в старшем бите самого левого байта. Остальные биты старшего байта должны быть равны 0.

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

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

В дополнительном коде положительные числа содержат нуль в самом старшем бите числа:

0XXX XXXX XXXX XXXX

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

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

0000 0000 0000 0101 = +5


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

1111 1111 1111 1010

Теперь прибавим к полученному числу +1:

1111 1111 1111 1011 = -5

На рис. 10.3 мы привели все возможные варианты представления целых чисел.



Рис. 10.3. Возможные представления целых чисел

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



Рис. 10.4. Формат упакованного десятичного числа

На этом рисунке n0...n17 означают разряды десятичного числа. Они могут изменяться в пределах от 0000 до 1001, то есть от 0 до 9 в десятичной системе счисления.

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


Численные регистры


Мы будем обозначать численные регистры как ST0 - ST7. Они приведены на рисунке 10.5.

Рис. 10.5. Численные регистры арифметического сопроцессора

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

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



Чтение данных из устройства


// ---------------

// Код функции 5

// ---------------

#pragma pack(1)

typedef struct _DriveBytes

{            

  BYTE   bFunctionCode;

  BYTE   bNumBytes;

  BYTE   bReadBuff[128];

} DriveBytes;

Поле

Описание

bFunctionCode

Код функции

bNumBytes

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

bReadBuff

Буфер для чтения размером 128 байт. После выполнения команды в него записывается информация, которая зависит от типа устройства чтения CD-ROM



Чтение длинное


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

Формат заголовка запроса:

// ---------------

// Код команды 128

// ---------------

#pragma pack(1)

typedef struct _ReadLong

{            

  ReqHdr rh;

  BYTE   bAddressMode;

  DWORD  lpTransferAddress;

  WORD   wDataSize;

  WORD   wStartSector;

  BYTE   bDataReadMode;

  BYTE   bInterleaveSise;

  BYTE   bInterleaveSkip;

} ReadLong;      

Заполнение полей заголовка запроса:

Поле

Описание

rh.wStatus

После вызова драйвера содержит слово состояния

bAddressMode

Режим адресации:

                0 – режим HSG (по умолчанию);

                1 – режим Readbook;

                2-255 – зарезервировано

lpTransferAddress

Адрес буфера

wDataSize

Размер буфера

wStartSector

Номер начального сектора, должен быть равен нулю

bDataReadMode

Режим чтения данных:

                0 – режим Cooked;

                1 – режим Raw;

                2-255 – зарезервировано

bInterleaveSize

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

bInterleaveSkip

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



Чтение длинное с предварительной выборкой


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

Формат заголовка запроса:

// ---------------

// Код команды 130

// ---------------

#pragma pack(1)

typedef struct _ReadLongPrefetch

{            

  ReqHdr rh;

  BYTE   bAddressMode;

  DWORD  lpTransferAddress;

  WORD   wDataSize;

  WORD   wStartSector;

  BYTE   bDataReadMode;

  BYTE   bInterleaveSise;

  BYTE   bInterleaveSkip;

} ReadLongPrefetch;      

Заполнение полей заголовка запроса такое же, как и для предыдущей функции.



Чтение IOCTL Input


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

Формат заголовка запроса:

// ---------------

// Код команды 3

// ---------------

#pragma pack(1)

typedef struct _IOCTL_Input

{            

  ReqHdr rh;

  BYTE   bMediaDescriptor;

  DWORD  lpTransferAddress;

  WORD   wDataSize;

  WORD   wStartSector;

  DWORD  lpVolID;

} IOCTL_Input;

Заполнение полей заголовка запроса:

Поле

Описание

rh.wStatus

После вызова драйвера содержит слово состояния

bMediaDescriptor

Байт описания среды носителя данных

lpTransferAddress

Адрес буфера

wDataSize

Размер буфера

wStartSector

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

lpVolID

Указатель на идентификатор тома, если при выполнении команды возникла ошибка с кодом 0Fh

Команда IOCTL Input может выполнять много функций. Перед вызовом драйвера вы должны подготовить заголовок функции,  указав в одном из его полей код выполняемой функции. Адрес и размер этой структуры необходимо записать в поля lpTransferAddress и wDataSize, соответственно.

Рассмотрим форматы заголовков различных функций, выполняемых в рамках команды IOCTL Input.



Чтение счетчика таймера


Функция 00h предназначена для чтения содержимого счетчика таймера:

Регистры на входе:

AH = 00h

Регистры на выходе:

CX = старший байт счетчика;

DX = младший байт счетчика;

AL = 0, если с момента перезапуска таймера прошло более 24 часов



Чтение сектора оглавления компакт-диска


При помощи функции 05h вы можете найти все оглавления тома Volume Descriptor:

Регистры на входе:

AX = 1505h;

ES:BX = адрес буфера размером 2048 байт;

CX = номер устройства чтения CD-ROM;

DX = номер дескриптора тома (0 – первый, 1 – второй и так далее)

Регистры на выходе:

CY = 0, если не было ошибок. При этом содержимое регистра AX определяет тип прочитанного дескриптора:

                AX= 1, стандартный дескриптор тома;

                AX = 0FFh, завершающий дескриптор;

                AX = 0, дескриптор другого типа;

CY = 1 при ошибке в номере устройства чтения CD-ROM. При этом регистр AX содержит код ошибки



Чтение сектора по абсолютному адресу


Функция 08h предназначена для прямого чтения секторов компакт-диска и напоминает прерывание INT 25h опреационной системы MS-DOS:

Регистры на входе:

AX = 1508h;

ES:BX = адрес буфера, в который будут прочитаны данные;

CX = номер устройства чтения CD-ROM;

DX = количество секторов, которые нужно прочитать;

SI:DI = номер начального сектора

Регистры на выходе:

CY = 1 при ошибке в номере устройства чтения CD-ROM;

AL = код ошибки



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


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

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

Регистры на входе:

AH = 00h

Регистры на выходе:

AL = код ASCII символа или 0, если AH содержит расширенный код ASCII символа;

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

Приведем таблицу скан-кодов:

01

Esc

12

E

23

H

34

. >

45

NumLock

02

1  !

13

R

24

J

35

/ ?

46

ScrLock

03

2 @

14

T

25

K

36

Shift прав.

47

Home [7]

04

3 #

15

Y

26

L

37

PrtSc

48

Up [8]

05

4 $

16

U

27

;  :

38

Alt

49

PgUp [9]

06

5 %

17

I

28

‘  “

39

Пробел

4A

[-]

07

6 ^

18

O

29

` ~

3A

CapsLock

4B

<- [4]

08

7 &

19

P

2A

Shift лев.

3B

F1

4C

[5]

09

8 *

1A

[ {

2B

\ |

3C

F2

4D

-> [6]

0A

9 (

1B

] }

2C

Z

3D

F3

4E

[+]

0B

0 )

1C

Enter

2D

X

3E

F4

4F

End [1]

0C

- _

1D

Ctrl

2E

C

3F

F5

50

Dn [2]

0D

= +

1E

A

2F

V

40

F6

51

PgDn [3]

0E

Bksp

1F

S

30

B

41

F7

52

Ins [0]

0F

Tab

20

D

31

N

42

F8

53

Del [.]

10

Q

21

F

32

M

43

F9

11

W

22

G

33

, <

44

F10

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

F1

3b

Shift+F1

54

Ctrl+F1

5e

Alt+F1

68

F2

3c

Shift+F2

55

Ctrl+F2

5f

Alt+F2

69

F3

3d

Shift+F3

56

Ctrl+F3

60

Alt+F3

6a

F4

3e

Shift+F4

57

Ctrl+F4

61

Alt+F4

6b

F5

3f

Shift+F5

58

Ctrl+F5

62

Alt+F5

6c

F6

40

Shift+F6

59

Ctrl+F6

63

Alt+F6

6d

F7

41

Shift+F7

5a

Ctrl+F7

64

Alt+F7

6e

F8

42

Shift+F8

5b

Ctrl+F8

65

Alt+F8

6f

F9

43

Shift+F9

5c

Ctrl+F9

66

Alt+F9

70

F10

44

Shift+F10

5d

Ctrl+F10

67

Alt+F10

71

Alt+A

1E

Alt+P

19

Alt+3

7A

Down

50

Alt+B

30

Alt+Q

10

Alt+4

7B

Left

4B

Alt+C

2E

Alt+R

13

Alt+5

7C

Right

4D

Alt+D

20

Alt+S

1F

Alt+6

7D

Up

48

Alt+E

12

Alt+T

14

Alt+7

7E

End

4F

Alt+S

21

Alt+U

16

Alt+8

7F

Home

47

Alt+G

22

Alt+V

2F

Alt+9

80

PgDn

51

Alt+H

23

Alt+W

11

Alt+-

82

PdUp

49

Alt+I

17

Alt+X

2D

Alt+=

83

Alt+J

24

Alt+Y

15

Ctrl+Left

73

Alt+K

25

Alt+Z

2C

Ctrl+Right

74

Alt+L

26

Shift+Tab

0F

Ctrl+End

75

Alt+M

32

Alt+0

81

Insert

52

Ctrl+Home

77

Alt+N

31

Alt+1

78

Delete

53

Ctrl+PgDn

76

Alt+O

18

Alt+2

79

PrintScr

72

Ctrl+PgUp

84

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

F11

85

Alt-Bksp

0e

Alt- Д /

a4

F12

86

Alt-Enter

1c

Alt- Д *

37

Shft-F11

87

Alt-Esc

01

Alt- Д -

4a

Shft-F12

88

Alt-Tab

a5

Alt- Д +

4e

Ctrl-F11

89

Ctrl-Tab

94

Alt- Д Enter

a6

Ctrl-F12

8a

Alt-F11

8b

Alt-up Up

98

Ctrl- Д /

95

Alt-F12

8c

Alt-down   Dn

a0

Ctrl- Д *

96

Alt-[

1a

Alt-left   <-

9b

Ctrl- Д -

8e

Alt-]

1b

Alt-right  ->

9d

Ctrl- Д +

90

Alt-;

27

 

Alt-'

28

Alt-Delete

a3

Ctrl- Д Up [8]

8d

Alt-`

29

Alt-End

9f

Ctrl- Д 5  [5]

8f

Alt-\

2b

Alt-Home

97

Ctrl- Д Dn [2]

91

Alt-,

33

Alt-Insert

a2

Ctrl- Д Ins[0]

92

Alt-.

34

Alt-PageUp

99

Ctrl- Д Del[.]

93

Буква "Д" здесь обозначает дополнительную клавиатуру.


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


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

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

Регистры на входе:

AH = 10h;

Регистры на выходе:

AL = код ASCII символа или 0, если AH содержит расширенный код ASCII символа;

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

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



Деление на нуль


Этот особый случай возникает при попытке выполнить деление конечного ненулевого числа на нуль.

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

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



Денормализованный операнд


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

(y-x)+x;

Если разность (y-x) вызывает антипереполнение и в качестве результата берется нулевое значение, то после вычисления всего выражения получится x. Если же пойти на расширение диапазона представления чисел за счет снижения точности и сформировать результат вычисления разности (y-x) как денормализованное число, выражение будет вычислено правильно и в результате получится y.

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



Драйвер устройства чтения CD-ROM


Для работы с устройством чтения CD-ROM в среде операционных систем MS-DOS и Microsoft Windows 95 вы должны установить в файле CONFIG.SYS специальный драйвер. Этот драйвер обычно поставляется вместе с устройством и программой установки на дискете.

Вот пример строки файла CONFIG.SYS, в которой загружается драйвер устройства чтения CD-ROM:

device=c:\cd\cpqidecd.sys /d:idecd01

Здесь мы передаем драйверу параметр /d:idecd01, который задает имя устройства чтения CD-ROM.

Заметим, что устройство чтения CD-ROM имеет символьный драйвер, несмотря на то что оно является дисковым и, казалось бы, для него должен применяться блочный драйвер (подробнее о типах драйверов вы можете прочитать в 18 томе “Библиотеки системного программиста”, который называется “MS-DOS для программиста»). На самом деле устройство чтения CD-ROM не похоже на обычное дисковое устройство. Операционная система MS-DOS работает с ним как с сетевым устройством через интерфейс Network Redirector.



Драйверы мыши в MS-DOS


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

Для подключения драйвера мыши файл CONFIG.SYS должен содержать строку следующего вида:

device=c:\mouse\mouse.sys

Если используется резидентная программа, она обычно вызывается в файле AUTOEXEC.BAT:

c:\mouse\mouse.com

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

отслеживает перемещения курсора и нажатия на клавиши мыши;

рисует на экране курсор, повторяющий движения мыши в графическом или текстовом режимах;

предоставляет программам интерфейс для работы с мышью, основанный на вызове прерывания INT 33h.



Другие ячейки памяти CMOS


Назначение описанных выше 64 ячеек памяти CMOS документировано и одинаково для BIOS различных изготовителей и различных версий. Тем не менее, есть исключения.

BIOS компьютера IBM PS/2 использует ячейку с адресом 37h для хранения номера текущего столетия. Ячейки 38h-3Fh в модели 50 компьютера IBM PS/2 используются для хранения пароля. Обращение к этим ячейкам выполняется по адресам 78h-7Fh, которые аппаратно отображаются на адреса 38h-3Fh.

Кроме того, имеются ячейки памяти CMOS с номерами, большими чем 3Fh. Их назначение зависит от изготовителя BIOS, поэтому обращайтесь к ним только в том случае, если у вас есть соответствующая документация.



Другие команды


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

Если вас не устраивает шрифт, который записан в ПЗУ принтера (например, в нем нет символов кириллицы), вы можете использовать команды для загрузки собственного шрифта.



Другие сообщения от мыши Microsoft IntelliMouse


Помимо только что описанных сообщений MSH_MOUSEWHEEL и WM_MOUSEWHEEL, мышь Microsoft IntelliMouse может посылать такие же сообщения, как и обычная трехкнопочная мышь. Сообщения, возникающие когда пользователь нажимает или отжимает колесо, эквивалентны сообщениям от средней кнопки трехкнопочной мыши.

Подробное описание параметров всех этих сообщений вы найдете в 11 томе «Библиотеки системного программиста», который называется «Операционная система Microsoft Windows для программиста».



Формат команды чтения слова состояния канала


С помощью команды чтения слова состояния канала вы можете выполнять операции чтения состояния каналов либо запоминание регистра счетчика CE каналов. Можно выполнять эти операции как для отдельных каналов, так и для всех каналов одновременно .

Приведем формат команды RBC чтения слова состояния канала:

Поле

Описание

0

Всегда равно 0

1

1 - выбор канала 0

2

1 - выбор канала 1

3

1 - выбор канала 2

4

Поле STAT:

                0 - читать состояние каналов;

                1 - не читать состояние каналов

5

Поле CNT:

                0 - запомнить текущее содержимое CE;

                1 - не запоминать содержимое CE

6-7

код команды RBC - 11



Формат слова состояния канала


Формат слова состояния канала напоминает формат регистра управляющего слова, за исключением двух старших разрядов 7 и 6:

Поля регистра

Описание

0

Поле BCD:

                0 - двоичный режим;

                1 - двоично-десятичный режим

1-3

Поле M:

                000 - режим 0;

                001 - режим 1;

                X10 - режим 2;

                X11 - режим 3;

                100 - режим 4;

                101 - режим 5

4-5

Поле RW:

                00 - код команды CLC (запомнить CE);

                01 - чтение/запись старшего байта;

                10 - чтение/запись младшего байта;

                11 - чтение/запись младшего, затем старшего байта

6

FN:  флаг перезагрузки констант

7

OUT: состояние выхода OUT

Разряд FN используется, в основном, в режимах 1 и 5 для определения, произошла ли загрузка константы из регистра CR  в регистр счетчика CE.

Разряд OUT позволяет определить состояние выходной линии канала OUT в момент выполнения команды RBC.



Формат управляющего регистра


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

Поля регистра

Описание

0

Поле BCD:

                0 - двоичный режим;

                1 - двоично-десятичный режим

1-3

Поле M:

                000 - режим 0;

                001 - режим 1;

                X10 - режим 2;

                X11 - режим 3;

                100 - режим 4;

                101 - режим 5

4-5

Поле RW:

                00 - код команды CLC (запомнить CE);

                01 - чтение/запись старшего байта;

                10 - чтение/запись младшего байта;

                11 - чтение/запись младшего, затем старшего байта

6-7

Поле SC:

                00 - канал 0;

                01 - канал 1;

                10 - канал 2;

                11 - код команды RBC (чтение состояния канала)

Поле BCD определяет формат константы, использующейся для счета - двоичный или двоично-десятичный. В двоично-десятичном режиме константа задается в диапазоне 1-9999.

Поле M определяет режимы работы таймера:

0 - прерывание от таймера;

1 - программируемый ждущий мультивибратор;

2 - программируемый генератор импульсов;

3 - генератор меандра;

4 - программно-запускаемый одновибратор;

5 - аппаратно-запускаемый одновибратор

Мы будем рассматривать только режим 3, так как именно он используется в каналах 0 и 2.

Поле RW определяет способ загрузки констант через однобайтовый порт. Если в этом поле задано значение 00, это управляющее слово будет использоваться для фиксации текущего содержимого регистров счетчика CE в буферном регистре OL с целью чтения программой. Это код команды CLC - фиксация регистров. Код канала, для которого будет выполняться фиксация, должен быть указан в поле SC. Поля M и BCD при этом не используются.

Поле SC определяет номер канала, для которого предназначено управляющее слово. Если в этом поле задано значение 11, будет выполняться чтение состояния канала.



Формирование задержки


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

Формат вызова функции:

Регистры на входе:

AH = 86h

CX = старшее слово времени работы счетчика, задается в микросекундах;

DX = младшее слово счетчика;

Регистры на выходе:

Регистры не используются



Функции BIOS для работы с последовательным асинхронным адаптером


В этом разделе мы расскажем о функцях BIOS, облегчающих обслуживание двух асинхронных адаптеров, COM1 и COM2. Эти функции доступны через прерывание INT 14h.



Функции BIOS для работы с принтером


В BIOS есть ряд функций, предназначенных для работы с принтером, подключенным через параллельный адаптер. Это функции 00h, 01h, 02h прерывания INT17h.



Функции getch и getche


Самые простые из функций стандартной библиотеки С, предназначенных для работы с клавиатурой - getch и getche. Они описаны в файле conio.h.

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

int getch(void);

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

Функция обрабатывает клавиши <Control+C> и <Control+Break> - при вводе этих комбинаций клавиш работа программы завершается.

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

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

int getche(void);



Функции MS-DOS для работы с принтером


Операционная система MS-DOS имеет свои срдества, предназначенные для работы с принтером. Это функция 05h прерывания INT 21h и система буферизованной печати.