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

         

Программирование сопроцессора


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

библиотека эмулятора;

библиотека, рассчитанная на наличие сопроцессора;

библиотека альтернативной математики

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

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

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

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

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

резидентные программы;

драйверы;

программы, предъявляющие жесткие требования к точности и скорости вычислений


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

Механизм вызова программ эмуляции основан на использовании прерываний с номерами 34h - 3Eh. Перед тем как оставить программу резидентной, функция _dos_keep восстанавливает содержимое указанных векторов прерываний, делая невозможным доступ резидентной программе к модулям эмулятора. Да и самих этих модулей уже нет в памяти - на их место может быть загружена новая программа.

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

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

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

Какие средства можно использовать для составления программ для сопроцессора?

Обычно это или ассемблер MASM (возможно использование TASM), либо интегрированная среда разработки, содержащая встроенный ассемблер.


Программирование таймера на уровне портов




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

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

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

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

40h - канал 0;

41h - канал 1;

42h - канал 2;

43h - управляющий регистр



Проигрывание музыки в фоновом режиме


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

Основная идея заключается в использовании прерывания INT1Ch, которое вырабатывается таймером с частотой примерно 18,2 Гц. Ваш обработчик этого прерывания осуществляет контроль за выборкой нот из массива, содержащего мелодию, и программирование микросхемы 8254. Например, один раз в полсекунды обработчик проверяет, не пора ли прекратить звучание одной ноты и начать проигрывание следующей ноты. Если пора, он выключает громкоговоритель и перепрограммирует канал 8254 на новую частоту, соответствующую следующей ноте.

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

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

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

Нота

Частота, Гц

До

261,7

До-диез

277,2

Ре

293,7

Ре-диез

311,1

Ми

329,6

Фа

349,2

Фа-диез

370,0

Соль

392,0

Соль-диез

415,3

Ля

440,0

Ля-диез

466,2

Си

493,9

Для других октав при понижении или повышении тона значения частот надо умножать (при повышении тона) или делить (при понижении тона) на 2.



Проигрывание звуковой дорожки


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

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

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

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

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

#pragma pack(1)

typedef struct _Play

{            

  ReqHdr rh;

  BYTE   bAddressMode;

  WORD   wStartSector;

  WORD   wNumberOfSectors;

} Play;

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

Поле

Описание

rh.wStatus

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

bAddressMode

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

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

                1 – режим Readbook;

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

wStartSector

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

wNumberOfSectors

Количество секторов, которые нужно проиграть



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


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

Формат вызова функции представлен ниже:

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

AH = 01h

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

ZF = 0, если в буфере имеется код нажатой клавиши;

ZF = 1, если буфер клавиатуры пуст;

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

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

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

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

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



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


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

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

AH = 11h

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

ZF = 0, если в буфере имеется код нажатой клавиши;

ZF = 1, если буфер клавиатуры пуст;

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

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

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



Проверка наличия мыши Microsoft IntelliMouse


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

Способ проверки зависит от операционной системы.



Проверка подключения драйвера


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

Для этого надо загрузить в регистр AX значение 4300h и вызвать прерывание INT2Fh. Если после этого регистр AL будет содержать значение 80h, драйвер установлен, в противном случае - нет.

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

; Проверяем, установлен ли драйвер HIMEM.SYS

  mov   ax, 4300h

  int   2fh

  cmp   al, 80h

; Если драйвер установлен, выполняем переход

  je    HMM_installed



Проверка состояния стандартного ввода


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

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

AH = 0Bh

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

AL = 0FFh, если в буфере имеется код нажатой клавиши;

AL = 0,    если буфер клавиатуры пуст.

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

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



Проверка установки системы буферизованной печати


С помощью этой функции программа может проверить, установлена система печати или нет, а также определить возможность ее установки:

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

AH = 01h;

AL = 00h

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

AH = состояние системы буферизованной печати

Байт состояния системы буферизованной печати описан ниже:

Содержимое регистра AH

Состояние системы буферизованной печати

00h

Не установлена, но ее можно установить командой PRINT

01h

Не установлена и ее установка невозможна

FFh

Установлена



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


При помощи функции 0Bh вы можете проверить, является диск устройством чтения CD-ROM, доступ к которому возможен через функции MSCDEX:

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

AX = 150Bh;

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

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

BX = ADADh, если программа MSCDEX установлена;

AX = признак, является ли диск устройством чтения CD-ROM:

                если содержимое AX не равно нулю, то диск – устройство CD-ROM;

                если содержимое AX равно нулю, доступ к данному устройству с помощью функций MSCDEX невозможен



В текущей на момент написания


В текущей на момент написания книги версии Microsoft Windows 95 драйвер мыши Microsoft IntelliMouse отсутствует. Если вы купили такую мышь, необходимо установить драйвер с дискеты, которая прилагается к мыши.

Для проверки наличия мыши с колесом в среде Microsoft Windows 95 вам следует сначала зарегистрировать сообщение с кодом MSH_WHEELSUPPORT, вызвав для этого функцию RegisterWindowMessage:

UINT uMSH_SUPPORT = 0;

uMSH_SUPPORT = RegisterWindowMessage(MSH_WHEELSUPPORT);

Идентификатор MSH_WHEELSUPPORT, а также другие идентификаторы, необходимые для программирования новой мыши, находятся в файле zmouse.h, который можно бесплатно переписать в составе Microsoft IntelliMouse SDK с сервера Microsoft с адресом http://www.microsoft.com.

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

HWND hwndMSHWheel  = NULL;

hwndMSHWheel = FindWindow(MSH_WHEELMODULE_CLASS,

  MSH_WHEELMODULE_TITLE);

Если сообщение MSH_WHEELSUPPORT успешно зарегистрировано, а указанный выше идентификатор определен, можно послать сообщение MSH_WHEELSUPPORT в окно приложения MSWheel, вызвав для этого функцию SendMessage:

BOOL fWheel = FALSE;

if(uMSH_SUPPORT != 0 && hwndMSHWheel != 0)

{

  fWheel =

    (BOOL)SendMessage(hwndMSHWheel, uMSH_SUPPORT, 0, 0);

}

Если мышь Microsoft IntelliMouse подключена, функция SendMessage  возвратит значение TRUE, если нет – FALSE.


Операционная система Microsoft Windows NT


Операционная система Microsoft Windows NT версии 4.0 содержит драйвер мыши Microsoft IntelliMouse, поэтому установка дополнительных драйверов не требуется.

Проверить наличие мыши с колесом можно при помощи обычной функции GetSystemMetrics, передав ей в качестве параметра значение SM_MOUSEWHEELPRESENT:

if(!GetSystemMetrics(SM_MOUSEWHEELPRESENT))

{

  MessageBox(NULL, "Microsoft IntelliMouse not found",

  "Error message", MB_OK);

}

Если функция возвратит нулевое значение, значит мышь Microsoft IntelliMouse не подключена к компьютеру.


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


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

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

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

#pragma pack(1)

typedef struct _MediaChange

{            

  BYTE   bFunctionCode;

  BYTE   bMedia;

} MediaChange;

Поле

Описание

bFunctionCode

Код функции

bMedia

1 – носитель не заменялся;

0 – не известно, выполнялась замена носителя данных, или нет;

0FFh – носитель заменялся



Работа через драйвер CD-ROM


Перед тем как приступить к чтению этого раздела, мы рекомендуем вам обратиться к 6 главе 18 тома “Библиотеки системного программиста”, которая называется “Драйверы”. В ней мы привели минимум сведений, которые необходимы для создания собственных драйверов устройств, а также для работы с уже имеющимися драйверами.

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

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

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

Как найти адреса этих программ?

Они есть в заголовке драйвера, который, однако, тоже еще нужно найти. Операционная система MS-DOS не имеет в своем составе документированных средств для поиска заголовков драйверов. В 18 томе “Библиотеки системного программиста” мы описали, как это можно сделать с применением недокументированной векторной таблицы связи MS-DOS.

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



Работа с перезапуском


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



Расширение MSCDEX


Вторая компонента, необходимая для работы в среде MS-DOS с устройством чтения CD-ROM – программа Microsoft CD-ROM Extention, которая находится в файле MSCDEX.EXE. Этот файл входит в комплект MS-DOS и иногда поставляется вместе с устройством чтения CD-ROM на той же дискете, что и драйвер. Для того чтобы избежать несовместимости, мы рекомендуем всегда использовать ту программу MSCDEX.EXE, что устанавливается на диск вместе с MS-DOS.

Программа MSCDEX.EXE подключается в файле AUTOEXEC.BAT операционной системы MS-DOS следующим образом:

c:\dos\mscdex /d:idecd01

Обратите внимание, что значение параметра /d должно совпадать со значением аналогичного параметра для драйвера.

В среде операционной системы Microsoft Windows 95 программа MSCDEX.EXE не нужна, так как все выполняемые ей функции встроены в операционную систему.

Что же касается Microsoft Windows NT, то в ней только часть функций расширения MSCDEX.EXE моделируется для виртуальной машины DOS. Поэтому не все программы, исходные тексты которых приведены в этой главе, будут там правильно работать.



Расширенная оперативная память


Функция 88h прерывания INT 15h позволяет определить размер доступной расширенной памяти в килобайтах, возвращая соответствующее значение в регистре AX.

Учтите, что если в системе установлен драйвер расширенной памяти, такой как, например, HIMEM.SYS, указанная выше функция может вернуть нулевое значение. Это происходит из-за того что драйвер берет на себя функции управления расширенной памятью. Заметим также, что с помощью параметра /int15 вы можете указать драйверу HIMEM.SYS размер зарезервированной расширенной памяти, доступной через интерфейс прерывания INT 15h:

device=c:\dos\himem.sys /int15=xxxx



Разблокирование EMB


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

AH = 0Dh

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

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

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

Ошибки:

BL = 80h, 81h, A2h, AAh

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



Разблокирование системы буферизованной печати


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

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

AH = 01h;

AL = 05h

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

AH = состояние системы буферизованной печати



Разъем параллельного адаптера


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

Контакт разъема адаптера

Контакт разъема принтера

Назначение

Вход или выход

1

1

STROBE

Строб

Выход, инверсия

2

2

Данные, бит 0

Выход

3

3

Данные, бит 1

Выход

4

4

Данные, бит 2

Выход

5

5

Данные, бит 3

Выход

6

6

Данные, бит 4

Выход

7

7

Данные, бит 5

Выход

8

8

Данные, бит 6

Выход

9

9

Данные, бит 7

Выход

10

10

ACK

Подтверждение

Вход, инверсия

11

11

BUSY

Занятость

Вход

12

12

PE

Конец бумаги

Вход

13

13

SLCT

Выбор

Вход

14

14

Auto Line Feed

Авт. перевод строки

Выход, инверсия

15

32

ERROR

Ошибка

Вход, инверсия

16

31

INIT

Сброс принтера

Выход, инверсия

17

36

SLCT IN

Принтер выбран

Выход, инверсия

18-25

16,17, 19-30,33

Земля

-

       

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

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

Следует также учитывать, что нагрузка на выходную линию параллельного адаптера не должна превышать одного входа TTL (то есть к одному выходу адаптера вы можете подключить не более одного входа микросхемы серии 155).



Разъемы адаптера


Внешние устройства подключаются к порту ввода/вывода через разъем DB25P (имеющий 25 выводов) или DB9P (имеющий 9 выводов). Приведем разводку разъема последовательной передачи данных DB25P:

Номер контакта

Назначение контакта

Вход или выход

1

Защитное заземление

-

2

Передаваемые данные (Transmitted Data)

Выход

3

Принимаемые данные (Received Data)

Вход

4

Запрос для передачи (Request to send, RTS)

Выход

5

Сброс для передачи (Clear to Send, CTS)

Вход

6

Готовность данных (Data Set Ready, DSR)

Вход

7

Сигнальное заземление (Signal Ground)

-

8

Детектор принимаемого с линии сигнала (Data Carrier Detect, DCD)

Вход

 9-19

Не используются

20

Готовность выходных данных (Data Terminal Ready, DTR)

Выход

21

Не используется

22

Индикатор вызова (Ring Indicator, RI)

Вход

23-25

Не используется

Наряду с 25-контактным разъемом часто используется 9-контактный разъем:

Номер контакта

Назначение контакта

Вход или выход

1

Детектор принимаемого с линии сигнала (Data Carrier Detect, DCD)

Вход

2

Принимаемые данные (Received Data)

Вход

3

Передаваемые данные (Transmitted Data)

Выход

4

Готовность выходных данных (Data Terminal Ready, DTR)

Выход

5

Сигнальное заземление (Signal Ground)

-

6

Готовность данных (Data Set Ready, DSR)

Вход

7

Запрос для передачи (Request to send, RTS)

Выход

8

Сброс для передачи (Clear to Send, CTS)

Вход

9

Индикатор вызова (Ring Indicator, RI)

Вход

Уровни напряжения на линиях разъема составляют для логического нуля ?15 вольт, для логической единицы +15 вольт.

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



- Различная информация


В компьютерах IBM PC/AT этот байт используется программой BIOS Setup для собственных нужд.



Размер оперативной памяти


В компьютере имеются различные виды оперативной памяти. В первых компьютерах применялся так называемый реальный режим работы процессора, не позволявший адресовать более 1 Мбайт памяти. Начальная область адресов от 0 до 640 Кбайт использовалась для оперативной памяти, а область от 640 Кбайт до 1 Мбайт – для памяти и регистров периферийных устройств, таких как видеоадаптеры и дисковые контроллеры.

Раньше оперативная память была очень дорогая, поэтому далеко не в каждом компьютере было установлен максимально возможный объем – 1 Мбайт. Можно было встретить компьютеры с объемом оперативной памяти, например, 512 Кбайт. Программы в те времена, конечно, тоже были не очень требовательны к объему памяти.

С появлением операционных систем Microsoft Windows и IBM OS/2 требования к объему памяти, установленной в компьютере, резко возросли. Компания Intel выпустила процессор i80286, способный адресовать в защищенном режиме до 16 Мбайт физической памяти.

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



Регистр состояния


Поля регистра состояния сопроцессора 8087 показаны на рисунке 10.9.

Рис. 10.9. Формат регистра состояния сопроцессора 8087

Регистр состояния сопроцессоров 80287/80387 и сопроцессора, входящего в состав современных процессоров, имеет немного другой формат. Мы показали его на рис. 10.10.

Рис. 10.10. Формат регистра состояния современных сопроцессоров

В обоих форматах биты 0-5 - флажки особых случаев. Они устанавливаются всегда при возникновении особых случаев, даже замаскированных установкой в 1 соответствующих битов регистра управления.

Приведем таблицу флажков особых случаев:

Флажок

Особый случай

IE

Недействительная операция

DE

Денормализованный результат

ZE

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

OE

Переполнение

UE

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

PE

Неточный результат

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

Назначение бита 7 регистра состояния различно для сопроцессора 8087 и сопроцессоров 80287/80387.

Для сопроцессора 8087 этот бит обозначается IR и содержит флаг запроса прерывания при возникновении незамаскированного особого случая. В этом случае флаг устанавливается в 1.

Сопроцессоры 80287/80387 используют бит 7 в качестве флага суммарной ошибки, который устанавливается в 1 при возникновении незамаскированного особого случая.

Биты C0, C1, C2, C3 - это коды условий. Они определяются по результату выполнения команд сравнения и команды нахождения остатка. Мы расскажем о них при описании соответствующих команд сопроцессора.

Поле ST занимает три бита 11-13 и содержит номер численного регистра, являющегося вершиной стека численных регистров.

Бит B - бит занятости. Он устанавливается в 1, когда процессор выполняет команду или когда происходит прерывание от сопроцессора. Если сопроцессор свободен, бит занятости установлен в 0.



Регистр состояния A


Адрес первого регистра состояния – 0Ah. Формат битовых полей представлен ниже:

Биты регистра

Описание

0-3

Переключатель скорости. По умолчанию установлен в 0110

4-6

22-разрядный делитель. По умолчанию установлен в 010

7

Флаг обновления. Значение 0 означает готовность данных для чтения



Регистр состояния B


Адрес второго регистра состояния – 0Bh. Ниже вы найдете формат битовых полей этого регистра:

Биты регистра

Описание

0

Летнее или стандартное время:

                1 - летнее время;

                0 – стандартное время

1

12 или 24-часовой режим:

                 0 - 12-часовой режим 

                1 – 24-часовой режим (установлен по умолчанию)

2

Формат данных:

                1 – двоичный;

                0 - BCD (установлен по умолчанию)

3

Разрешение прямоугольного сигнала:

                1 – включение сигнала, частота которого определяется разрядами 0-3 первого регистра состояния;

                0 – сигнал выключен

4

Разрешение прерывания по окончанию изменения данных (по умолчанию сброшен)

5

Разрешение прерывания будильника (по умолчанию сброшен)

6

Разрешение периодических прерываний (по умолчанию сброшен)

7

Запрет счета:

               

1 – счетчик остановлен;

                0 – счетчик запущен



Регистр состояния C


Адрес третьего регистра состояния – 0Сh. Этот регистр доступен только для чтения и содержит биты состояния прерывания.



Регистр состояния D


Адрес четвертого регистра состояния – 0Dh. Если бит 7 этого регистра сброшен, это означает,       что разрядился  аккумулятор, питающий память CMOS.



Регистр тегов


Этот регистр разделен на восемь двухбитовых полей, которые мы обозначим как TAG0...TAG7. Каждое поле относится к своему численному регистру (рис. 10.6).

Рис. 10.6. Формат регистра тегов

Поля регистра тегов классифицируют содержимое "своего" численного регистра:

Поле

Описание

00

Регистр содержит действительное ненулевое число

01

В регистре находится нуль

10

Регистр содержит недействительное число  - нечисло, бесконечность, неопределенность

11

Пустой неинициализированный регистр

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



Регистр управления


Регистр управления для сопроцессора 8087 показан на рисунке 10.7.

Рис. 10.7. Формат регистра управления для сопроцессора 8087

Регистр управления сопроцессоров 80287/80387 и сопроцессора, входящего в состав более современных процессоров, имеет аналогичный формат, за исключением того, что бит 7 в нем не используется (рис. 10.8).

Рис. 10.8. Формат регистра управления для современных сопроцессоов

Биты 0...5 - маски особых случаев. Особые случаи иногда возникают при выполнении команд сопроцессора, например, при делении на нуль, переполнении и так далее.

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

Приведем таблицу масок особых случаев:

Маска

Особый случай

IM

Недействительная операция

DM

Денормализованный результат

ZM

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

OM

Переполнение

UM

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

PM

Особый случай при неточном результате

IEM

Маскирование одновременно всех особых случаев вне зависимости от установки бит 0-5 регистра управления. Этот бит действителен только для сопроцессора 8087

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

Поле PC управляет точностью вычислений в сопроцессоре:

Поле

Описание

00

Использование расширенной точности. Этот режим устанавливается при инициализации сопроцессора

10

Округление результата до двойной точности

11

Округление результата до одинарной точности

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


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

Поле

Описание

00

округление к ближайшему числу, этот режим устанавливается при инициализации сопроцессора

01

округление в направлении к отрицательной бесконечности

10

округление в направлении к положительной бесконечности

11

округление в направлении к нулю

Ниже демонстрируются перечисленные выше режимы округления. Символами "o" обозначены точные значения вещественных чисел, символами "x" приближенные значения. Стрелки "<<" и ">>" указывают направление округления. В центре линии расположен нуль числовой оси, на ее левом и правом конце - отрицательная и положительная бесконечности.

Округление в направлении к ближайшему числу:

-беск.<-o-<<-x-------o---- 0 -----o-----x->>--o---->+беск.

Округление в направлении к отрицательной бесконечности:

-беск.<-o-<<-x-------o---- 0 -----o---<<----x-o---->+беск.

Округление в направлении к положительной бесконечности:

-беск.<-o-x-->>------o---- 0 -----o------x->>-o---->+беск.

Округление в направлении к нулю:

-беск.<-o-x-->>------o---- 0 -----o---<<----x-o---->+беск.

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

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

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

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

1 - афинный режим

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

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


Регистры часов реального времени


Использование регистров памяти CMOS часами реального времени приведено ниже.



Регистры каналов DMA


Каждый канал DMA содержит следующие 16-разрядные регистры:

регистр текущего адреса CAR, содержит текущий адрес ячейки памяти при выполнении операции обмена данными с использованием DMA;

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

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

регистр хранения базового числа циклов прямого доступа к памяти WCR. Этот регистр хранит число циклов DMA и его содержимое также не изменяестя;

регистр режима MR, определяющий режим работы канала.

Приведем адреса регистров и их форматы для компьютеров IBM PC/XT.


Приведем описание регистров каналов DMA для IBM PC/AT.



Регистры счетчиков


В регистрах 0, 2, 4, 6 и 8 хранится текущее значение времени и дата. Регистры с номерами 1, 3, 5, 7 и 9 – это регистры будильника. Вы можете установить будильник, и когда он сработает, произойдет прерывание.

Регистр

Счетчик, который содержится в регистре

0

Секунды

1

Секунды будильника

2

Минуты

3

Минуты будильника

4

Часы

5

Часы будильника

6

День недели (1 - воскресенье)

7

День месяца

8

Номер месяца

9

Последние две цифры текущего года



Регистры сопроцессора


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



Регистры страниц


Приведем назначение и адреса регистров страниц контроллера для IBM AT:

Порт

Описание

81h

Регистр страниц канала 2

82h

Регистр страниц канала 3

83h

Регистр страниц канала 1

87h

Регистр страниц канала 0

89h

Регистр страниц канала 6

8Bh

Регистр страниц канала 5

8Ah

Регистр страниц канала 7

8Fh

Регенерация динамической памяти

Для 16-разрядных каналов 4-7 передача данных начинается с границы слова и все адреса относятся к 16-разрядным словам.



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


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

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

Рис. 10.11. Указание адреса команды в сопроцессоре 8087

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

Защищенный режим работы центрального процессора и сопроцессора описан в 6 томе «Библиотеки системного программиста». Для полноты изложения приведем формат указателей и для этого режима.

В защищенном режиме адрес состоит из селектора и смещения. Формат указателя команды для защищенного режима представлен на рисунке 10.12.

Рис. 10.12. Формат указателя команды для защищенного режима

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

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

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

Рис. 10.13. Формат указателя операнда для реального режима

Формат указателя операнда для защищенного режима мы показали на рис. 10.14.

Рис. 10.14. Формат указателя операнда для защищенного режима



Режим автоповтора


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

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



Режим автозагрузки


В режиме автозагрузки регистр CR автоматически переписывается в регистр CE после завершения счета. Сигнал на выходе OUT появляется только при наличии на входе GATE уровня логической 1. Этот режим используется для создания программируемых импульсных генераторов и генераторов прямоугольных импульсов (меандра).



Режим однократного выполнения функций


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



Режимы работы клавиатуры


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



Режимы работы таймера


Возможны шесть режимов работы таймера. Они разделяются на три типа:

режимы 0, 4 - однократное выполнение функций.

режимы 1, 5 - работа с перезапуском.

режимы 2, 3 - работа с автозагрузкой



Сброс будильника


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

AH = 07h

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

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

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



Сброс буфера клавиатуры


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

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

AH = 0Сh

AL = 1, 6, 7, 8 или 0Ah

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

Не опеределены

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

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



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


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

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

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

#pragma pack(1)

typedef struct _ResetDrive

{

  BYTE   bFunctionCode;

} ResetDrive;

Поле

Описание

bFunctionCode

Код функции



Сброс входных буферов


Команда освобождает все входные буферы и отменяет все запущенные команды.

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

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

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

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

#pragma pack(1)

typedef struct _Flush

{            

  ReqHdr rh;

} Flush;

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

Поле

Описание

rh.wStatus

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



Сбросить драйвер мыши


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

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

AX = 0021h

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

AX = результат:

                0021h - драйвер сброшен успешно;

                FFFFh - невозможно сбросить драйвер (например, из-за того что драйвер не установлен);

BX = количество клавиш на корпусе мыши



Система буферизованной печати


Более интересные возможности по управлению процессом печати предоставляет резидентная программа буферизованной печати PRINT.EXE. Напомним, что команда PRINT операционной системы MS-DOS предназначена для выполнения печати в фоновом режиме.

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

Для связи с системой буферизованной печати можно использовать несколько функций прерывания INT 2Fh, которые мы рассмотрим ниже.



Система команд сопроцессора


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

Команды с обращением к памяти могут занимать от двух до четырех байт, в зависимости от способа адресации операнда, находящегося в памяти (рис. 10.15).

Рис. 10.15. Формат команд с обращением к памяти

Первые пять бит соответствуют команде центрального процессора ESC. Поля КОП1 и КОП2 определяют выполняемую команду, то есть содержат код операции. Поля MOD и R/M вместе с полями "Смещение1" и "Смещение2" задают адрес операнда в памяти аналогично тому, как это происходит в процессорах. Однако есть и отличия, связанные с возможностью адресации численных регистров сопроцессора.

Ниже мы покажем зависимость способа адресации от содержимого полей MOD и R/M:

Поле

Поле MOD

R/M

00

01

10

11

000

(bx)+(si)

(bx)+(si)+disp8

(bx)+(si)+disp16

ST0

001

(bx)+(di)

(bx)+(di)+disp8

(bx)+(di)+disp16

ST1

010

(bp)+(si)

(bp)+(si)+disp8

(bp)+(si)+disp16

ST2

011

(bp)+(di)

(bp)+(di)+disp8

(bp)+(di)+disp16

ST3

100

(si)

(si)+disp8

(si)+disp16

ST4

101

(di)

(di)+disp8

(di)+disp16

ST5

110

disp16

(bp)+disp8

(bp)+disp16

ST6

111

(bx)

(bx)+disp8

(bx)+disp16

ST7

Если в таблице указаны значения смещения disp8 или disp16, это означает, что в команде присуствует один или два байта смещения, соответственно.

Если поле MOD содержит значение 11, возможна адресация численных регистров ST0...ST1. При этом команда не содержит байтов смещения.

Формат команды с обращением к численному регистру приведен на рис. 10.16.

Рис. 10.16. Формат команд с обращением к численному регистру

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


Самый простой формат имеют команды без явного обращения к операндам (рис. 10.17).



Рис. 10.17. Формат команд без явного обращения к операндам

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

Все команды сопроцессора можно разделить на несколько групп:

команды пересылки данных;

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

команды сравнений чисел;

трансцендентные команды;

управляющие команды

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

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

Команды сравнения сравнивают вещественные и целые числа, выполняют анализ чисел.

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

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

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


Скан-код клавиши


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