Функции MSCDEX
В этом разделе мы приведем краткое описание основных функций программного интерфейса расширения MSCDEX.EXE, доступные в среде MS-DOS.
Все функции расширения MSCDEX.EXE вызываются через мультиплексное прерывание INT2Fh. При этом в регситр AH записывается значение 15h, а в регистр AL – код функции.
Функции прерывания INT 1Ah
Для работы с часами реального времени вы можете обращаться непосредственно к перечисленным выше ячейкам памяти CMOS, используя порты 70h и 71h. Однако лучше всего воспользоваться функциями 2 - 7 прерывания INT 1Ah, описанными ниже.
Функции стандратной библиотеки С
Стандартные библиотеки C содержат многочисленные функции для работы с датой и временем. Они основаны на описанных выше функциях MS-DOS и предоставляют широкие возможности для отображения даты и времени в различных форматах. Подробное описание этих функций и примеры их использования вы найдете в документации на библиотеку С.
Функция cgets
Для ввода с клавиатуры строки символов можно использовать функцию cgets, работающую аналогично функции 0Ah прерывания MS-DOS INT 21h:
char *cgets(char *buffer);
Функция cgets описана в файле conio.h.
Перед вызовом cgets аргумент функции buffer должен указывать на массив, размер которого должен быть достаточным для хранения вводимой строки, завершающего строку нулевого байта и двух дополнительных байтов. Первый элемент массива buffer[0] должен содержать максимальную длину вводимой строки - как и для функции 0Ah прерывания MS-DOS INT 21h.
После завершения ввода второй элемент массива buffer[1] будет содержать длину введенной строки, сама строка будет завершаться символами новой строки NL, перевода строки LF и нулем.
Функция cgets возвращает указатель на начало введенной строки в буфере, то есть на третий элемент массива buffer[2].
В следующем фрагменте программы функция cgets используется для ввода целого числа:
#define MAX 80
char buf[MAX];
. . .
int i;
char *bufptr;
// Устанавливаем максимально допустимую длину строки
buf[0] = MAX + 2;
printf("\nВведите целое число: ");
// Вводим число, можно использовать клавиши редактирования
bufptr = cgets(buf);
// Преобразуем введенное число к формату int
// и выводим его
i = atoi(bufptr);
printf("\nВы ввели число %d", i);
Функция gets
Существует и более удобная по сравнению с cgets функция, предназначенная для ввода строки с клавиатуры, а точнее, из стандартного потока ввода. Это функция gets:
char *gets(char *buffer);
Функция gets описана в файле stdio.h.
Эта функция читает строку из стандартного потока ввода stdin и запоминает ее в буфере buffer. Символ новой строки \n в конце введенной строки функция заменяет на нуль. После завершения ввода функция возвращает указатель на заполненный буфер или NULL в случае ошибки или условия "Конец файла".
Обратим ваше внимание на отличия между функциями cgets и gets:
Функция cgets позволяет редактировать вводимую строку символов, функция gets просто записывает в буфер все символы подряд (в том числе и коды клавиш редактирования).
Программе, использующей для ввода с клавиатуры функцию cgets, недоступны средства переназначения ввода операционной системы. Если же программа использует функцию gets, которая читает строку из стандартного потока ввода, можно использовать средства переназначения.
Перед вызовом функции cgets необходимо специальным образом подготовить буфер для вводимой строки (записать в первый байт буфера длину вводимой строки). Функция gets не требует никакой подготовки буфера.
Функция kbhit
Для проверки буфера клавиатуры на наличие символов можно использовать функцию kbhit. Она также описана в файле conio.h:
int kbhit(void);
Если буфер клавиатуры не пуст, функция возвращает ненулевое значение. В этом случае программа может прочитать символы из буфера клавиатуры при помощи фукнкций getch и getche. Если буфер клавиатуры пуст, функция возвращает нулевое значение.
Функция MS-DOS для вывода на принтер
Для печати символа на стандартном печатающем устройстве PRN вы можете использовать функцию 05h прерывания MS-DOS INT21h:
Регистры на входе: | AH = 05h;
DL = код ASCII символа для печати | ||
Регистры на выходе: | AH = слово состояния принтера |
Ниже мы привели исходный текст функции printchar, которая распечатывает символ, передаваемый ей в качестве параметра, при помощи описанной выше функции MS-DOS:
int printchar(int chr)
{
// Дублируем распечатываемый символ на экране
putch(chr);
// Вызываем функцию 5 прерывания INT 21h -
// распечатка символа на принтере.
rg.h.ah = 5;
rg.h.dl = chr;
int86(0x21, &rg, &rg);
}
Функция 05h по умолчанию работает с устройством PRN, однако с помощью команды MODE вы можете переназначить стандартное устройство печати LPT1, например, на асинхронный последовательный адаптер COM1:
MODE LPT1:=COM1
Заметим, что функция 05h прерывания INT 21h не возвращает состояния принтера при ошибке ввода/вывода. Вместо этого вызывается стандартный обработчик критических ошибок MS-DOS, который выводит на экран хорошо знакомое вам сообщение:
Write fault error writing device PRN
Abort, Retry, Ignore, Fail?
Вы можете ответить Retry, нажав клавишу <R>, и тогда MS-DOS выполнит попытку повторить печать символа. Если ответить Abort (нажав клавишу <A>), MS-DOS завершит работу вашей программы.
Если вас не устраивают действия, выполняемые стандартным обработчиком критических ошибок MS-DOS, вы можете составить собственный. О том, как это сделать, можно узнать из 18 и 19 томов «Библиотеки системного программиста», посвященных программированию для MS-DOS.
Функция scanf
Еще одна полезная функция, которую можно использовать для ввода с клавиатуры - scanf. Эта функция подробно описана во всех книгах по языку программирования Си, поэтому мы не будем ее подробно рассматривать. Отметим только, что с помощью этой функции можно организовать ввод чисел в заданном формате. Однако можно сначала ввести строку при помощи функций cgets или gets, а уже потом выполнять все необходимые проверки и преобразования этой строки.
Генерация звукового сигнала
Код команды: 07h
Если послать этот байт, принтер издаст звуковой сигнал. Этот сигнал удобно использовать для привлечения внимания оператора, например, когда кончилась бумага.
если функция выполнена успешно, 0000h
Регистры на входе: |
AH = 03h |
Регистры на выходе: |
AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка |
Ошибки: |
BL = 80h, 81h, 82h |
Следует отметить, что для многих типов системных плат переключение линии A20 - достаточно медленная операция.
если функция выполнена успешно, 0000h
Регистры на входе: |
AH = 04h |
Регистры на выходе: |
AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка |
Ошибки: |
BL = 80h, 81h, 82h, 94h |
H-2Fh - контрольная сумма ячеек 10h - 20h
Для ячеек памяти CMOS с адресами от 10h до 20h при инициализации системы BIOS выполняет проверку контрольной суммы. Эта контрольная сумма хранится также в памяти CMOS в ячейках 2Eh и 2Fh (соответственно, старший и младший байты).
H - байт диагностики
Байт диагностики (расположенный в памяти CMOS по адресу 0Eh) содержит результаты выполнения диагностики при включении питания компьютера. Выполнив анализ содержимого байта 0Eh, программа может выявить неисправность НМД, часов реального времени, разрядку аккумулятора и ошибки в конфигурации. Приведем формат этого байта:
Бит | Описание | ||
0-1 | Не используется, равно 0 | ||
2 | 0 - неправильная установка часов реального времени;
1 - часы реального времени установлены правильно | ||
3 | 0 - НМД исправен;
1 - неисправность НМД, невозможно загрузить операционную систему с жесткого диска | ||
4 | 0 - размер оперативной памяти указан правильно;
1 - фактический размер оперативной памяти не соответствует указанному в памяти CMOS | ||
5 | 0 - конфигурация указана правильно;
1 – ошибка в конфигурации системы, фактическая конфигурация не соответствует указанной в байте конфигурации оборудования (ячейка 14h) | ||
6 | 0 - контрольная сумма памяти CMOS правильная;
1 - ошибка в контрольной сумме памяти CMOS | ||
7 | 0 – аккумулятор, питающий память CMOS, исправен и заряжен;
1 - разрядка аккумулятора выше нормы |
H - байт отключения
Байт отключения 0Fh используется процессорами 80286, 80386, 80486 и Pentium для определения способа возврата из защищенного режима в реальный после аппаратного сброса.
Вы, вероятно, знаете, что эти процессоры могут работать либо в реальном режиме, который соответствует режиму работы процессора 8086, либо в защищенном. Защищенный режим работы используется такими операционными системами, как Microsoft Windows, IBM OS/2 и UNIX. В этом режиме процессор может непосредственно адресовать всю память, лежащую выше границы 1 Мбайт.
Подробное рассмотрение защищенного режима работы мы привели в 6 томе «Библиотеки системного программиста», который так и называется – «Защищенный режим процессоров Intel 80286/80386/80486». Здесь же мы только кратко расскажем о переходе процессора 80286 из реального режима в защищенный и обратно для иллюстрации использования ячейки памяти CMOS с адресом 0Fh.
Для перевода процессора 80286 из реального режима в защищенный можно использовать специальную команду LMSW:
mov ax,1
lmsw ax
Разумеется, двух строк, приведенных выше, недостаточно для правильной работы процессора в защищенном режиме.
Для того, чтобы вернуть процессор 80286 из защищенного режима в реальный, необходимо выполнить аппаратный сброс (отключение) процессора. Это можно сделать следующим образом:
mov ax, 0FEh ; команда отключения
out 64h, ax
Перед выдачей команды отключения программа должна записать в ячейку 0Fh памяти CMOS причину отключения:
Значение | Причина отключения | ||
0 | Программный сброс при помощи комбинации клавиш <Ctrl-Alt-Delete> или неожиданный сброс. Выполняется обычный перезапуск системы, но процедура тестирования при включении питания не запускается | ||
1 | Сброс после определения объема памяти | ||
2 | Сброс после тестирования памяти | ||
3 | Сброс после обнаружения ошибки четности в оперативной памяти | ||
4 | Сброс с запросом перезагрузки | ||
5 | После сброса перезапускается контроллер прерываний, затем управление передается по адресу, который находится в области данных BIOS с адресом 0000h:0467h | ||
6, 7, 8 | Сброс после выполнения проверки работы процессора в защищенном режиме | ||
9 | Сброс после выполнения копирования блока памяти из основной памяти в расширенную | ||
0Ah | После сброса управление немедленно передается по адресу, взятому из области данных BIOS с адресом 0000h:0467h |
Для перевода процессоров 80386, 80486 и Pentium из реального режима в защищенный и обратно можно использовать загрузку специального управляющего регистра CR0 обычной командой MOV. Однако будет работать и метод, основанный на применении команды LMSW и команды отключения.
Вы можете использовать сведения о команде отключения для организации программного перезапуска системы.
Игровой адаптер
Если установлен бит с номером 12, к компьютеру подключен игровой адаптер, предназанченный для джойстика.
INDEX \c "2"
12-часовой режим, 64
16450, 81
16550, 81
16550A, 81
24-часовой режим, 64
8042, 28
8254, 70
ACK, 91
ADD, 138
BIOS Setup, 82
bps, 81
BUSY, 92
BYTE, 108
CD-ROM, 105
cgets, 41
Clear to Send, 82
CMOS, 14; 64
COM1, 82; 90; 96
COM2, 82; 90
Cooked, 112
CPUID, 21
CTS, 82
Data Carrier Detect, 82
Data Set Ready, 82
Data Terminal Ready,, 82
DB25P, 82
DB9P, 82
DCD, 82
Direct Memory Access, 100
DIV, 138
DIVR, 138
DMA, 9; 100
DSR, 82
DTR, 82; 84
DWORD, 108
EMB, 148
Epson FX, 97
Epson LQ, 97
Epson LQ-2550, 97
ERROR, 91
ESC, 129
Extended Memory, 148
Extended Memory Blocks, 148
eXtended Memory Specification, 148
F2XM1, 140
FABS, 138
FBLD, 137
FBST, 138
FBSTP, 137
FCHS, 138
FCLEX, 141
FCOM, 139
FCOMP, 139
FCOMPP, 139
FCOS, 140
FDECSTP, 141
feature flags, 21
FFREE, 141
FICOM, 139
FICOMP, 139
FILD, 137
FINCSTP, 141
FINIT, 141
FIST, 138
FISTP, 137
FLD, 137
FLD1, 138
FLDCW, 141
FLDENV, 141
FLDL2E, 138
FLDL2T, 138
FLDLG2, 138
FLDLN2, 138
FLDPI, 138
FLDZ, 138
Flywheel, 58
FNCLEX, 141
FNINIT, 141
FNOP, 141
FNSAVE, 141
FNSTCW, 141
FNSTENV, 141
FNSTSW, 141
FPATAN, 140
FPREM, 138
FPTAN, 140
FRAME, 110
FRNDINT, 138
FRSTOR, 141
FSAVE, 141
FSCALE, 138
FSETPM, 141
FSIN, 140
FSINCOS, 140
FSQRT, 138
FST, 138
FSTCW, 141
FSTENV, 141
FSTP, 137
FSTSW, 141
FSTSW AX, 140
FTST, 139
FX-1050, 97
FX-80, 97
FX-850, 97
FXAM, 139
FXCH, 138
FXTRACT, 138
FYL2X, 140
FYL2XP1, 140
getch, 39
getche, 39
gets, 41
GetSystemMetrics, 58
High Memory Area, 148
High Sierra, 110
HIMEM.SYS, 3; 10; 148; 149; 151; 153; 154; 157; 158; 160
HMA, 148
HMAMIN, 148; 150
HSG, 110
INT 0Bh, 90
INT 15h, 10
INT 1Ah, 65
INT09h, 29; 30
INT 0Ch, 90
INT 0Dh, 91
INT 0Fh, 91
INT 10h)., 145
INT 11h, 8
INT 14h, 85
INT 15h, 11; 12; 74
INT 16h, 30; 31
INT 17h, 93
INT 1Ah, 74
INT 1Ch, 70
INT 21h, 37; 75; 86; 95
INT 23h, 37
INT 2Fh, 96; 105; 149
INT 33h, 43
INT 4Ah, 65
INT 8h, 70
Intel 80286, 19
Intel 80386, 19
Intel 80486, 19
Intel 8086/8088, 19
Intel 8250, 81
Intel 8253, 70
IOCTL Input, 110
IOCTL Output, 114
IRQ3, 82
IRQ4, 82
IRQ5, 91
IRQ7, 91
IRQ8, 65
ISO?9660, 111
ISO-9960, 105
kbhit, 40
Lead-out, 112
LPT1, 91; 96
LPT2, 91
Microsoft CD-ROM Extention, 105
Microsoft IntelliMouse, 57
MIN, 110
MK_CONTROL, 60
MK_LBUTTON, 60
MK_MBUTTON, 60
MK_RBUTTON, 60
MK_SHIFT, 60
MODE, 86; 96
MSCDEX.EXE, 105
MSH_MOUSEWHEEL, 59; 60
MSH_SCROLL_LINES, 59
MSH_WHEELSUPPORT, 58
MSWheel, 58
MUL, 138
Network Redirector, 105
NUMHANDLES, 148
OUT1, 84
OUT2, 84
PE, 91
PRINT, 96
PRINT.EXE, 96
PRN, 96
PUSH, 137
Raw, 112
Received Data, 82
Redbook, 105; 110
RegisterWindowMessage, 58
Request to send, 82
RI, 82
Ring Indicator, 82
RS232-C, 81
RTS, 82; 84
SAHF, 140
Scan Code, 27
scanf, 41
SEC, 110
SendMessage, 58
Signal Ground, 82
SLCT, 91
SM_MOUSEWHEELPRESENT, 58
SPI_GETWHEELSCROLLLINES, 59
stepping, 21
SUB, 138
SUBR, 138
SystemParametersInfo, 59
Transmitted Data, 82
UART, 81
UMB, 148
Universal Asynchronous Receiver Transmitter, 81
Upper Memory Blocks, 148
Volume Descriptor, 107
WHEEL_PAGESCROLL, 59
Windows, 172
WM_MOUSEWHEEL, 59; 60
WORD, 108
XMS, 148
альтернативный драйвер событий, 55
арифметические команды, 137
арифметический сопроцессор, 129
байт ESC, 98
байт состояния отключения, 15
биты в секунду, 81
Боды, 81
буфер клавиатуры, 30
версии BIOS, 12
верхние блоки памяти, 148
Вещественные числа, 129
возможности процессора, 21
встроенный арифметический сопроцессор, 129
Вызов драйвера CD-ROM, 107
Двойная точность, 130
дополнительные коды моделей, 12
драйвер событий, 51
драйвер устройства чтения CD-ROM, 105
задержки, 75
значения битов кодов условия, 139
инициалищзация системы, 8
код ASCII, 27
код модификации модели, 21
коды моделей, 12
Команда CPUID, 20
команды сравнений чисел, 137
контроллер прерываний 8259, 12
конфигурация оборудования, 16
косинус, 129
КР1810ВИ53, 70
КР1810ВИ54, 70
линия A20, 148
логарифмы, 129
модели процессоров, 18
модель компьютера, 11
наибольшее отрицательное число, 131
наибольшее положительное число, 131
наименьшее отрицательное число, 131
наименьшее положительное число, 131
неопределенность, 131
нечисло, 131
нуль, 131
объем расширенной памяти, 17
объем стандартной оперативной памяти, 17
Одинарная точность, 130
операции, связанные с обслуживанием мыши, 43
особые случаи сопроцессора, 145
Ошибка в процессоре Pentium, 146
положительная и отрицательная бесконечность, 131
порог удвоения скорости, 54
Последовательная передача данных, 81
представление чисел с плавающей точкой, 129
программа буферизованной печати, 96
расширенная память, 148
Расширенная точность, 130
расширенные блоки памяти, 148
режим автоповтора, 27
режимы работы клавиатуры, 36
синус, 129
система буферизованной печати, 95
скан-код, 27
Скорость передачи данных, 81
слово состояния 8042, 28
случайные числа, 79
содержимое регистра состояния сопроцессора, 140
состояние BREAK, 85
Спецификация XMS, 149
список частот для нот второй октавы, 76
старшая область памяти, 148
схема клавиатуры, 26
таблица скан-кодов, 31
тангенс, 129
текущее столетие, 17
технология MMX, 21
тип первого и второго НМД, 17
трансцендентные команды, 137; 140
Упакованное десятичное число, 131
управляющие команды, 137
целые числа, 131
Инициализация
Команда инициализации вызывается из MS-DOS только один раз.
Ниже мы привели формат заголовка запроса для этой команды:
// ---------------
// Код команды 0
// ---------------
#pragma pack(1)
typedef struct _Init
{
ReqHdr rh;
BYTE bNumberOfUnits;
DWORD lpEndAddress;
DWORD lpAddressOfBPB;
BYTE bNumberOfBlockDevice;
} Init;
После выполнения команды поля структуры заполняются драйвером следующим образом:
Поле | Описание | ||
rh.wStatus | Слово состояния | ||
bNumberOfUnits | Количество устройств, обслуживаемых драйвером. Равно 0 | ||
lpEndAddress | Конечный адрес резидентной порции драйвера в оперативной памяти | ||
lpAddressOfBPB | Указатель на символ = в строке файла CONFIG.SYS, с помощью которой загружен драйвер CD-ROM. Может быть использован для анализа параметров драйвера | ||
bNumberOfBlockDevice | Равно 0 |
Инициализация асинхронного адаптера
Первое, что должна сделать программа, работающая с асинхронным адаптером - установить протокол обмена и скорость передачи данных. После загрузки операционной системы для асинхронных адаптеров устанавливается скорость 2400 бод, не выполняется проверка на четность, используются один стоповый бит и восьмибитовая длина передаваемого символа. Вы можете изменить этот режим командой MS-DOS MODE.
Выполнив ввод из порта 3FBh, программа может получить текущий режим адаптера. Для установки нового режима измените нужные вам поля и запишите новый байт режима по адресу 3FBh.
Если вам надо задать новое значение скорости обмена данными, перед записью байта режима установите старший бит этого байта. Затем последовательно двумя командами вывода загрузите делитель частоты тактового генератора. Младший байт запишите в порт 3F8h, старший - в порт 3F9h.
Перед началом работы необходимо также проинициализировать регистр управления прерываниями (порт 3F9h), даже если в вашей программе не используются прерывания от асинхронного адаптера. Если прерывания вам не нужны, запишите в этот порт значение 0.
На этом инициализацию можно считать законченной.
Инициализация канала DMA
Для инициализации канала программа должна выполнить следующие шаги:
сбросить триггер байтов командой записи в регистр 0Ch;
задать режим работы канала, выполнив запись по адресу 0Bh в регистр режима MR;
записать младшие 16 бит 20-битового адреса области памяти, которая будет использована для передачи данных, в регистр базового адреса. Адрес порта зависит от номера канала: канал 0 использует адрес 00h, канал 1 - 02h, канал 2 - 04h, канал 3 - 06h;
записать номер страницы (старшие 4 бита 20-битового адреса) в регистр страниц 81h;
загрузить регистр циклов прямого доступа к памяти CWR значением, на 1 меньшим требуемого количества передаваемых байт. Адреса соответствующих портов для каналов 0-3, равны, соответственно, 01h, 03h, 05h и 07h;
разрешить работу канала, выполнив запись в регистр маски каналов по адресу 0Ah.
Сразу после разрешения канал начинает передачу данных. После окончания передачи устройство обычно вырабатывает прерывание, которое служит признаком окончания операции ввода или вывода данных.
Инициализация мыши
Эта функция с кодом 00h выполняет аппаратный сброс мыши и программную установку драйвера мыши в начальное состояние. Заметим, что с помощью функции 21h можно выполнить установку драйвера в исходное состояние, не выполняя аппаратного сброса мыши.
Регистры на входе: | AX = 0000h | ||
Регистры на выходе: | AX = состояние мыши;
BX = количество клавиш у мыши |
Если на выходе из прерывания регистр AX содержит значение 0000h, значит драйвер мыши не установлен. Если же содержимое этого регистра равно 0FFFFh, драйвер имеется и вы можете использовать другие функции для работы с мышью.
В регистре BX возвращается количество клавиш мыши:
Содержимое регистра BX | Количество клавиш | ||
0 | Больше или меньше, чем две | ||
2 | Две клавиши | ||
3 | Мышь системы Mouse Systems, имеет три клавиши |
При установке драйвера мыши в исходное состояние для программ, работающих в текстовом режиме, выполняются следующие действия:
курсор перемещается в центр экрана и гасится;
разрешается перемещение курсора по всей поверхности экрана, причем на экране отсутствуют зоны, в которых курсор является невидимым;
устанавливается режим отображения курсора - инвертирование атрибута символа, на который указывает курсор;
для изображения курсора выбирается нулевая страница видеопамяти;
разрешается эмуляция светового пера (хотя это вам едва ли пригодится);
устанавливается начальная скорость перемещения курсора
Инициализация принтера
Функция 01h инициализирует принтер:
Регистры на входе: | AH = 01h;
DX = номер параллельного адаптера: 0 – LPT1, 1 – LPT2, 2 – LPT3 | ||
Регистры на выходе: | AH = слово состояния принтера |
Эта функция выполняет аппаратный сброс принтера. Если вы загрузили в принтер какой-либо шрифт (например, с символами кириллицы), после сброса загрузку шрифта придется выполнять заново. Поэтому не следует выполнять без необходимости сброс принтера. Обычно принтер приходится сбрасывать либо перед настройкой его на заданный режим работы, которая выполняется один раз, либо при изменении этого режима.
Код команды: ESC "@"
Для сброса принтера в исходное состояние программа должна послать на принтер два байта - байт ESC (1Bh) и байт, соответствующий ASCII-символу "@" (40h).
Инииализация портов асинхронного адаптера
Первая функция с кодом 00h предназначена для инициализации портов асинхронного адаптера:
Регистры на входе: | AH = 00h;
DX = номер порта адаптера: 0 - COM1, 1 - COM2; AL = параметры инициализации | ||
Регистры на выходе: | AH = состояние порта асинхронного адаптера;
AL = состояние модема |
Параметры инициализации, предаваемые в регистре AL, перечислены ниже:
Поле | Описание | ||
0-1 | Длина слова:
00 - 5 бит; 01 - 6 бит; 10 - 7 бит; 11 - 8 бит | ||
2 | Количество стоповых бит:
0 - 1 бит; 1 - 2 бита | ||
3-4 | Контроль четности:
X0 - контроль на четность не используется; 01 - контроль на нечетность; 11 - контроль на четность | ||
5-7 | Скорость передачи данных в бодах:
000 – 110; 001 – 150; 010 – 300; 011 – 600; 100 – 1200; 101 – 2400; 110 – 4800; 111 – 9600 |
После вызова функции 00h в регистр AH записывается состояние порта асинхронного адаптера.
Формат регистра:
Поле | Описание | ||
0 | Истекло время ожидания. Если установлен этот бит, другие биты не имеют значения | ||
1 | Регистр сдвига передатчика пуст | ||
2 | Буферный регистр передатчика пуст | ||
3 | Обнаружено состояние BREAK | ||
4 | Ошибка синхронизации | ||
5 | Ошибка четности | ||
6 | Ошибка переполнения входного регистра | ||
7 | Данные готовы |
Регистр AL содержит байт состояния модема.
Формат регистра:
Поле | Описание | ||
0 | Линия CTS изменила состояние | ||
1 | Линия DSR изменила состояние | ||
2 | Линия RI изменила состояние | ||
3 | Линия DCD изменила состояние | ||
4 | Состояние линии CTS | ||
5 | Состояние линии DSR | ||
6 | Состояние линии RI | ||
7 | Состояние линии DCD |
Использование прерываний
Так как процесс последовательной передачи данных протекает достаточно медленно, имеет смысл выполнять его в фоновом режиме, используя прерывания по окончанию передачи или приема символа. Напомним, что порту COM1 соответствует аппаратное прерывание INT 0Ch, а COM2 - INT 0Bh.
Для разрешения прерываний необходимо установить биты порта управления прерываниями 3F9h, соответствующие тем прерываниям, которые нужно обрабатывать.
Когда происходит прерывание, программа-обработчик прерывания должна проанализировать причину прерывания, прочитав содержимое порта идентификации прерывания с адресом 3FAh.
Не забудьте, что в конце обработчика аппаратного прерывания должна находится последовательность команд:
mov al, 20h
out 20h, al
iret
Может случиться так, что одновременно произойдет несколько прерываний. В этом случае будет установлен бит 0 регистра идентификации прерывания. Если такая ситуация имеет место, перед завершением обработки прерывания вам надо снова прочитать регистр идентификации прерывания и обработать следующее прерывание. Так следует поступать до тех пор, пока бит 0 регистра идентификации прерывания не станет равным нулю.
Более подробное описание способов работы с последовательным асинхронным адаптером с применением прерываний и соответствующие примеры программ вы найдете в 16 томе «Библиотеки системного программиста», который называется «Модемы и факс-модемы».
Изменение режима
Едва ли вам потребуется изменять режим работы клавиатуры. Тем не менее, мы покажем, как это можно сделать, программируя контроллер клавиатуры.
Ниже мы приведем команды и параметры, которые нужно посылать контроллеру клавиатуры для установки описанных выше режимов работы:
Режим | Команда | Параметр | |||
1 | 0F0h | 01h | |||
2 | 0F0h | 02h | |||
3 | 0F0h | 03h |
Изменить размер EMB
Регистры на входе: | AH = 0Fh
DX = идентификатор блока EMB; BX = новый размер EMB, Кбайт | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка | ||
Ошибки: | BL = 80h, 81h, A0h, A1h, A2h, ABh |
Функция изменяет размер незаблокированного EMB. Если размер блока уменьшается, данные в старших адресах блока будут потеряны.
Извлечение из стека
FSTP память -> ST(0), вещественный формат
FISTP память -> ST(0), целый формат
FBSTP память -> ST(0), десятичный формат
Команды извлечения чисел из стека выполняют действие, обратное только что описанному. Содержимое численного регистра, номер которого определяется полем ST регистра состояния, преобразуется в необходимый формат и записывается в ячейки оперативной памяти, заданные операндом команды.
После записи содержимое поля ST увеличивается на единицу. Эти действия аналогичны выполняемым командой POP центрального процессора.
В зависимости от команды (FSTP, FISTP или FBSTP) производится преобразование формата (из расширенного в вещественный, целый или десятичный, соответственно). В процессе преобразования для команд FSTP и FISTP выполняется округление в соответствии с содержимым поля RC регистра управления. Для команды FBSTP округление всегда выполняется следующим образом - прибавляется число 0.5, затем дробная часть результата отбрасывается.
Извлечение компакт-диска
// ---------------
// Код функции 0
// ---------------
#pragma pack(1)
typedef struct _EjectDisk
{
BYTE bFunctionCode;
} EjectDisk;
Поле | Описание | ||
bFunctionCode | Код функции |
Как работает клавиатура
Клавиатура выполнена, как правило, в виде отдельного устройства, подключаемого к компьютеру тонким кабелем. Малогабаритные блокнотные компьютеры содержат встроенную клавиатуру.
Что же находится внутри клавиатуры?
Оказывается, там есть компьютер! Только этот компьютер состоит из одной микросхемы и выполняет специализированные функции. Когда вы нажимаете на клавиши, он посылает номер нажатой клавиши в центральный компьютер.
Как связаться с авторами
Полную информацию о всех наших книгах серий “Библиотека системного программиста” и “Персональный компьютер. Шаг за шагом”, а также дискеты к книгам, статьи и другую информацию вы можете найти в сети Internet на серверах Web по следующим адресам:
http://www.glasnet.ru/~frolov
http://www.dials.ccas.ru/frolov
Вы можете передать нам свои замечания и предложения по содержанию этой и других наших книг через электронную почту по адресам:
frolov@glas.apc.org
frolov.alexandr@usa.net
Если электронная почта вам недоступна, присылайте ваши отзывы в АО “Диалог-МИФИ” по адресу:
115409, Москва, ул. Москворечье, 31, корп. 2,
тел. 324-43-77
Приносим свои извинения за то что не можем ответить на каждое письмо. Мы также не занимаемся продажей и рассылкой книг, дискет, компакт-дисков, рекламы, отдельных фрагментов наших книг и исходных текстов к книгам. По этим вопросам обращайтесь непосредственно в издательство “Диалог-МИФИ”. Авторский комопакт-диск можно приобрести также в издательстве “Аурамедиа”.
Как устроена мышь?
Как вы знаете, мышь - это небольшая коробочка с двумя или тремя клавишами, которая соединяется с компьютером тонким кабелем. Сверху на корпусе расположены кнопки. Обычно их две или три. Назначение этих кнопок полностью определяется программами. Снизу виден шарик. Он обычно покрыт резиной для лучшего сцепления с поверхностью стола.
Все, что вам нужно делать с мышью - это катать ее по любой гладкой поверхности и нажимать на кнопки. Программа свяжет перемещения мыши по поверхности стола с перемещениями, например, курсора по поверхности экрана. Перемещая мышь по столу (и, соответственно, курсор по экрану), вы можете указывать (выбирать) различные объекты, находящиеся на экране. Для того, чтобы выбрать какой-нибудь объект, обычно требуется указать на этот объект курсором и нажать на одну из кнопок мыши.
Если вы откроете корпус мыши, то увидите простой механизм, состоящий из шарика, двух осей с резиновыми валиками, двух дисков с отверстиями и четырех фотодатчиков.
При перемещении мыши по поверхности стола вращение шарика передается через резиновые валики двум дискам с отверстиями. Около каждого диска расположены фотодатчики (по два на диск). Они фиксируют направление вращения и угол поворота дисков. Во время движения мыши фотодатчики вырабатывают импульсы, которые передаются в компьютер. Количество этих импульсов линейно зависит от величины перемещения мыши.
В настоящее время изготовители компьютерного оборудования предлагают большой выбор мышей разного типа. Мыши отличаются не только внешним видом и количеством клавишей, но также и способом подключения к компьютеру. Мыши могут иметь различную точность и различный программный интерфейс.
Можно выделить три наиболее часто используемых способа подключения мыши к компьютеру:
через асинхронный последовательный порт (COM1, COM2);
через специальный адаптер, который вставляется в разъем расширения материнской платы компьютера;
через интерфейс типа PS/2
Выбирая мышь, используйте тот способ подключения, который вам более удобен.
При этом не следует забывать о существовании компьютеров, не имеющих разъемов расширения (обычно это блокнотные компьютеры). Для таких компьютеров больше подойдет мышь, подключающаяся через последовательный порт.
Что касается программного интерфейса, то можно выделить два типа:
трехкнопочная мышь системы Mouse Systems;
двухкнопочная мышь Microsoft
Некоторые мыши могут эмулировать оба типа. Тип такой мыши зависит от состояния переключателя, находящегося на нижней крышке корпуса мыши или от того, была ли нажата клавиша мыши во время включения питания компьютера.
Мы рекомендуем вам приобрести мышь фирмы Microsoft. Эта мышь удобна в работе, может подключаться к порту PS/2 и имеет переходник для подключения к последовательному порту. Новая версия мыши Microsoft IntelliMouse снабжена небольшим колесиком, которое можно вращать или нажимать. Это дополнение очень удобно при работе с приложениями Windows, так как упрощает просмотр документов, которые не помещаются целиком в окне приложения.
в системных часах времени суток
Канал 0 используется в системных часах времени суток (не следует путать с часами реального времени, реализованными на другой микросхеме). Этот канал работает в режиме 3 и используется как генератор импульсов с частотой примерно 18,2 Гц. Именно эти импульсы вызывают аппаратное прерывание INT8h.
используется для регенерации содержимого
Канал 1 используется для регенерации содержимого динамической памяти компьютера. Выход канала OUT используется для запроса к каналу прямого доступа DMA, который и выполняет обновление содержимого памяти. Вам не следует перепрограммировать этот канал, так как это может привести к нарушениям в работе основной оперативной памяти компьютера.
и может быть использован для
Канал 2 подключен к громкоговорителю компьютера и может быть использован для генерации различных звуков или музыки, либо как генератор случайных чисел. Канал использует режим 3 таймеров 8253 и 8254.
Каналы таймера
В соверменных компьютерах задействованы все три канала таймера.
Клавиатурная матрица
Если рассмотреть сильно упрощенную принципиальную схему клавиатуры, представленную на рисунке, можно заметить, что все клавиши находятся в узлах матрицы (рис. 2.1).
Рис.2.1. Упрощенная схема клавиатуры
Все горизонтальные линии матрицы подключены через резисторы к источнику питания +5 В. Клавиатурный компьютер имеет два порта - выходной и входной. Входной порт подключен к горизонтальным линиям матрицы (X0-X4), а выходной - к вертикальным (Y0-Y5).
Устанавливая по очереди на каждой из вертикальных линий уровень напряжения, соответствующий логическому нулю, клавиатурный компьютер опрашивает состояние горизонтальных линий. Если ни одна клавиша не нажата, уровень напряжения на всех горизонтальных линиях соответствует логической единице (так как все эти линии подключены к источнику питания +5 В через резисторы).
Если вы нажмете на какую-либо клавишу, то соответствующая вертикальная и горизонтальная линии окажутся замкнутыми. Когда на этой вертикальной линии процессор установит значение логического нуля, то уровень напряжения на горизонтальной линии также будет соответствовать логическомунулю.
Как только на одной из горизонтальных линий появится уровень логического нуля, клавиатурный процессор фиксирует нажатие на клавишу. Он посылает в центральный компьютер запрос на прерывание и номер клавиши в матрице. Аналогичные действия выполняются и тогда, когда вы отпускаете нажатую ранее клавишу.
Клавиатурные функции стандартной библиотеки C
Стандартные библиотеки C содержат набор функций, предназначенных для работы с клавиатурой. Эти функции повторяют и немного дополняют возможности функций MS-DOS и BIOS, обслуживающих клавиатуру.
Код ASCII нажатой клавиши
Обычно программе нужен не порядковый номер нажатой клавиши, а код, соответствующий обозначению на этой клавише (код ASCII).
Код ASCII не связан напрямую со скан-кодом, так как одной и той же клавише могут соответствовать несколько значений кода ASCII в зависимости от состояния других клавиш. Например, клавиша с обозначением «1» используется еще и для ввода символа «!» (если она была нажата вместе с клавишей <Shift>).
Поэтому все преобразования скан-кода в код ASCII выполняются программно. Как правило, в операционной системе MS-DOS эти преобразования выполняют модули BIOS. Для использования символов кириллицы эти модули расширяются клавиатурными драйверами, как входящими в состав локализованных версий MS-DOS, так и созданными в виде отдельных программ.
Код модели компьютера и версия BIOS
На этапе инициализации BIOS записывает в свою область данных по адресу FFFFh:FFFEh байт идентификатора модели компьютера. Ниже мы привели возможные значения этого байта:
Байт | Модель компьютера | ||
FF | IBM PC | ||
FE | IBM XT, Portable PC | ||
FD | PCjr | ||
FC | IBM PC/AT | ||
FB | IBM XT с памятью 640 Кбайт на системной плате | ||
FA | IBM PS/2 модель 25 или 30 | ||
F9 | Convertible PC | ||
F8 | IBM PS/2 модели 55SX, 70, 80 | ||
9A | Compaq XT, Compaq Plus | ||
30 | Sperry PC | ||
2D | Compaq PC |
Более подробную информацию можно получить, вызвав функцию C0h прерывания BIOS INT 15h:
Регистры на входе: | AH = C0h | ||
Регистры на выходе: | ES:BX = адрес таблицы конфигурации, которая находится в ПЗУ BIOS;
CF = 0 при успешном вызове прерывания; CF = 1 если в данной версии BIOS функция C0h не реализована |
После выполнения прерывания регистры ES:BX будут указывать на таблицу в области ПЗУ BIOS. В этой таблице имеется более точная информация о типе компьютера, номер версии BIOS, сведения об аппаратных особенностях конкретной модели.
Приведем формат указанной таблицы:
Смещение | Размер, байт | Описание | |||
0 | 2 | Размер таблицы в байтах | |||
2 | 1 | Код модели | |||
3 | 1 | Дополнительный код модели | |||
4 | 1 | Модификация версии BIOS | |||
5 | 1 | Байт конфигурации аппаратных средств | |||
6 | 2 | Зарезервировано и равно 0 | |||
8 | 2 | Зарезервировано и равно 0 |
Ниже мы привели описание отдельных бит байта конфигурации аппаратных средств.
Номер бита | Описание | ||
0 | Зарезервирован | ||
1 | Если этот бит установлен в 1, то используется системная шина Micro Channel, в противном случае – шина ISA | ||
2 | Применяется расширенная область данных BIOS | ||
3 | В BIOS реализована функция ожидания внешнего события | ||
4 | Каждый раз после вызова прерывания от клавиатуры INT 9h вызывается функция 4Fh прерывания INT 15h | ||
5 | Установлены часы реального времени | ||
6 | Установлен второй контроллер прерываний 8259 | ||
7 | Канал DMA номер 3 используется BIOS для работы с диском |
В следующей таблице приведены коды моделей, дополнительные коды моделей и версии BIOS для некоторых известных типов компьютеров:
Код модели |
Доп. код модели |
Модификация версии BIOS |
Тип компьютера |
FFh |
- |
- |
Оригинальная версия IBM PC |
FEh |
- |
- |
IBM PC/XT |
FDh |
- |
- |
PCjr |
FCh |
00h |
01h |
IBM PC/AT, модель 239 |
FCh |
01h |
00h |
IBM PC/AT |
FCh |
02h |
00h |
IBM PC/XT-286 |
FCh |
04h |
00h |
IBM PS/2 модель 50 |
FCh |
05h |
00h |
IBM PS/2 модель 60 |
FBh |
00h |
01h |
IBM PC/XT |
FBh |
00h |
02h |
IBM PC/XT |
FAh |
00h |
00h |
IBM PS/2 модель 30 |
FAh |
00h |
01h |
IBM PS/2 модель 30 |
FAh |
01h |
00h |
IBM PS/2 модель 25 |
F9h |
00h |
00h |
PC Convertible |
F8h |
00h |
00h |
IBM PS/2 модель 80 с тактовой частотой 16 Мгц |
F8h |
01h |
00h |
IBM PS/2 модель 80 с тактовой частотой 20 Мгц |
F8h |
04h |
02h, 03h |
IBM PS/2 модель 70 |
F8h |
09h |
02h, 03h |
IBM PS/2 модель 70 |
F8h |
0Ch |
00h |
IBM PS/2 модель 55 SX |
F8h |
1Bhh |
00h |
IBM PS/2 модель 70-486 |
9Ah |
- |
- |
Compaq XT или Compaq Plus |
30h |
- |
- |
Sperry PC |
2Dh |
- |
- |
Compaq PC или Compaq Deskpro |
Большинство современных так называемых IBM-совместимых персональных компьютеров имеют код модели FCh, а дополнительный код модели 01h. Такие значения, например, записаны в таблице конфигурации компьютера Compaq Deskpro 6000 с процессором Pentium Pro 200.
Коды ошибок
Если после вызова перечисленных выше функций установлен флаг переноса CF, регистр AX содержит код ошибки:
Код | Описание | ||
01h | Неправильный код функции | ||
02h | Файл не найден | ||
03h | Путь не найден | ||
04h | Слишком много открытых файлов | ||
05h | Доступ запрещен | ||
06h | Неправильный идентификатор файла | ||
08h | Переполнение очереди | ||
09h | Занято | ||
0Ch | Слишком длинная строка пути к файлу (больше 64 байт) | ||
0Fh | Диск указан неправильно |
Приведем таблицу кодов ошибок, возвращаемых функциями в регистре BL:
Код | Ошибка | ||
00h | Нет ошибки, нормальное завершение | ||
80h | Функция не реализована в текущей версии драйвера | ||
81h | Обнаружен драйвер VDISK.SYS, с этим драйвером драйвер HIMEM.SYS несовместим | ||
82h | Ошибка при работе с линией A20 | ||
8Eh | Общая ошибка драйвера | ||
8Fh | Катастрофическая ошибка драйвера | ||
90h | Область HMA не существует | ||
91h | Область HMA уже используется | ||
92h | Содержимое регитра DX меньше парметра /HMAMIN= | ||
93h | Область HMA не распределена программе | ||
94h | Линия A20 все еще разблокирована | ||
A0h | Вся расширенная память уже распределена | ||
A1h | Больше нет свободных индексов EMB | ||
A2h | Неправильный индекс EMB | ||
A3h | Неправильный SourceHandle | ||
A4h | Неправильный SourceOffset | ||
A5h | Неправильный DestHandle | ||
A6h | Неправильный DestOffset | ||
A7h | Неправильный Length | ||
A8h | Неразрешенное перекрытие данных при выполнении операции пересылки данных | ||
A9h | Произошла ошибка четности | ||
AAh | EMB не заблокирован | ||
ABh | EMB заблокирован | ||
ACh | Переполнение счетчика блокировок EMB | ||
ADh | Не удалось выполнить блокировку EMB | ||
B0h | Доступен UMB меньшего размера | ||
B1h | Нет доступных блоков UMB | ||
B2h | Задан неправильный сегмент UMB |
Количество асинхронных последовательных адаптеров
В поле, образованное битами 9, 10 и 11, хранится количество асинхронных последовательных адаптеров, установленных в системе и обнаруженных BIOS в процессе инициализации.
Количество параллельных адаптеров
В поле, образованное битами с номерами 14 и 15, записывается количество параллельных адаптеров, обнаруженных на этапе инициализации.
Количество установленных НГМД
Поле размером два бита с номерами 6 и 7 содержит количество накопителей НГМД, установленных в системе, минус единица. То есть, если в компьютере установлен один НГМД, в этом поле записано нулевое значение, если два – значение 1 и так далее.
Современные модели компьютеров обычно оборудуют одним накопителем НГМД, предназначенным для чтения дискет размером 3,5 дюйма. Что же касается дискет размером 5,25 дюйма, то они уже ушли в прошлое.
Команда CPUID
В новых процессорах фирмы Intel появилась команда CPUID, специально предназначенная для определения модели процессора. В своей программе, составленной на языке ассемблера, вы можете определить эту команду следующим образом:
CPU_ID MACRO
db 0fh
db 0a2h
ENDM
Как работает команда CPUID?
Перед вызовом этой команды необходимо загрузить в регистр EAX значение, которое определяет выполняемые действия. В первый раз вы должны вызвать команду CPUID, загрузив предварительно в регистр EAX нулевое значение:
mov eax, 00h
CPU_ID
Команда вернет в регистре EAX максимальное значение, которое можно передавать команде CPUID для определения выполняемых действий. Кроме того, в регистрах EBX, ECX и EDX будут находиться байты текстовой строки описания фирмы-изготовителя процессора. Для процессоров Intel это будет строка GenuineIntel.
Следующая последовательность команд перепишет эти байты в буфер _vendor_id_msg в формате, пригодном для вывода на консоль средствами BIOS:
_vendor_id_msg db "............", 0dh, 0ah, "$"
. . .
mov dword ptr _vendor_id_msg, ebx
mov dword ptr _vendor_id_msg[+4], edx
mov dword ptr _vendor_id_msg[+8], ecx
Для определения модели процессора следует вызвать команду CPUID, загрузив предварительно в регистр EAX значение 1:
mov eax, 1
CPU_ID
При этом в регистр EAX будет загружено слово сигнатуры, по которому можно определить модель процессора, а в регистр EDX – слово, состоящее из отдельных флагов, характеризующих возможности процессора (feature flags). Регистры EBX и ECX зарезервированы для моделей процессоров, которые будут разработаны в будущем.
Ниже приведен фрагмент кода, в котором слово сигнатуры и слово возможностей записываются в переменные _cpu_signature и _features_edx для дальнейшего анализа:
_cpu_signature dd 0
_features_edx dd 0
. . .
mov _cpu_signature, eax
mov _features_edx, edx
Рассмотрим формат слова сигнатуры, возвращаемое командой CPUID в регистре EAX:
Биты | Описание | ||
0-3 | Код модификации модели (stepping) | ||
4-7 | Код модели | ||
8-11 | Код семейства моделей | ||
12-13 | Тип процессора | ||
14-31 | Зарезервировано |
Слово сигнатуры состоит из отдельных полей, назначение которых будет описано ниже.
Биты 12 и 13 определяют тип процессора:
Значение битов 12 и 13 |
Тип процессора |
00 |
Процессор, изготовленный производителем OEM |
01 |
Процессор OverDrive |
10 |
Процессор типа Dual, который можно использовать в двухпроцессорных системах |
11 |
Зарезервировано |
Ниже мы привели таблицу, с помощью которой по содержимому трех полей слова сигнатуры (тип процессора, код семейства и код модели) можно распознать процессор:
Тип процессора |
Код семейства |
Код модели |
Описание процессора |
00 |
0100 |
0100 |
Intel 486 SL |
00 |
0100 |
0111 |
Intel DX2 |
00 |
0100 |
1000 |
Intel DX4 |
00, 01 |
0100 |
1000 |
Intel DX4 OverDrive |
00 |
0101 |
0001 |
Pentium 60, 66; Pentium OverDrive для процессоров Pentium 60, 66 |
00 |
0101 |
0010 |
Pentium 75, 90, 100, 120, 133, 150, 166, 200 |
01 |
0101 |
0010 |
Pentium OverDrive для процессоров Pentium 75, 90, 100, 120, 133 |
01 |
0101 |
0011 |
Pentium OverDrive для систем на базе процессора Intel 486 |
00 |
0101 |
0100 |
Pentium 166, 200 с командами MMX |
01 |
0101 |
0100 |
Зарезервировано. Будет использоваться процессорами Pentium OverDrive для процессоров Pentium 75, 90, 100, 120, 133 |
00 |
0110 |
0001 |
Pentium Pro |
00 |
0110 |
0011 |
Pentium II |
00 |
0110 |
0101 |
Зарезервировано для новых процессоров P6 |
01 |
0110 |
0011 |
Зарезервировано для процессоров Pentium OverDrive для процессоров Pentium Pro |
Приведем описание битов, возвращаемых командой CPUID в регистре EDX.
Напомним, что это слово состоит из отдельных флагов, характеризующих возможности процессора (feature flags).
Бит |
Описание |
0 |
На кристалле процессора имеется арифметический сопроцессор, совместимый по командам с сопроцессором Intel 387 |
1 |
Процессор может работать в режиме виртуального процессора 8086 |
2 |
Процессор может работать с прерываниями ввода/вывода, а также с битом DE регистра CR4 |
3 |
Возможно использование страниц памяти размером 4 Мбайт |
4 |
В процессоре есть команда RDTSC, которая может работать с битом TSD регистра CR4 |
5 |
Набор регистров процессора, специфический для модели, доступен с помощью команд RDMSR, WRMSR |
6 |
Возможна физическая адресация памяти с использованием шины с шириной, большей чем 32 разряда |
7 |
В процессоре реализовано исключение Machine Check (исключение с номером 18). Возможно использование бита MCE регистра CR4 |
8 |
В процессоре реализована команда сравнения и обмена 8 байт данных CMPXCHG8 |
9 |
В процессоре есть локальный APIC |
10 |
Зарезервировано |
11 |
В процессоре реализованы команды быстрого вызова системы SYSENTER и SYSEXIT |
12 |
В процессоре есть регистры Memory Type Range |
13 |
Доступен глобальный бит в PDE и PTE, а также бит PGE в регистре CR4 |
14 |
Применена архитектура Machine Check Architecture |
15 |
В процессоре реализованы команды условного перемещения данных CMOVCC и (при установленном бите 0) FCMOVCC и FCOMI |
16-22 |
Зарезервировано |
23 |
Применена технология MMX |
24-31 |
Зарезервировано |
Команды драйвера CD-ROM
В этом разделе мы расскажем о командах драйвера CD-ROM. Заметим, что в рамках одной команды может выполняться несколько функций. Код функции при этом записывается в расширение загловка запроса.
Команды пересылки данных
Приведем описание команд, предназначенных для пересылки данных.
Команды сравнений чисел
В центральном процессоре команды условных переходов выполняются в соответствии с установкой отдельных битов регистра флагов процессора. В арифметическом сопроцессоре существуют специальные команды сравнений, по результатам выполнения которых устанавливаются биты кодов условий в регистре состояния:
Команда | Описание | ||
FCOM | Сравнение | ||
FICOM | Целочисленное сравнение | ||
FCOMP | Сравнение и извлечение из стека | ||
FICOMP | Целочисленное сравнение и извлечение из стека | ||
FCOMPP | Сравнение и двойное извлечение из стека | ||
FTST | Сравнение операнда с нулем | ||
FXAM | Анализ операнда |
Команда FCOM вычитает содержимое операнда, размещенного в оперативной памяти, из верхушки стека ST(0). Результат вычитания никуда не записывается и указатель верхушки стека ST не изменяется.
Обозначим операнд команды сравнения как "x". В следующей таблице приведем значения битов кодов условия после выполнения команды "FCOM x":
C3 | C0 | Условие | |||
0 | 0 | ST(0) > x | |||
0 | 1 | ST(0) < x | |||
1 | 0 | ST(0) = x | |||
1 | 1 | ST(0) и x не сравнимы |
Последняя комбинация возникает при попытке сравнения нечисел, неопределенностей или бесконечностей, а также в некоторых других случаях.
Команда FICOM работает с 16- или 32-разрядными числами, в остальном она аналогична команде FCOM.
Команды FCOMP и FICOMP аналогичны, соответственно, командам FCOM и FICOM, за исключением того, что после выполнения операнд извлекается из стека.
Команда FCOMPP выполняет те же действия, что и FCOM, но она после выполнения извлекает из стека оба операнда, участвовавших в сравнении.
Для сравнения операнда с нулем предназначена команда FTST. После ее выполнения коды условий устанавливаются в соответствии со следующей таблицей:
C3 | C0 | Условие | |||
0 | 0 | ST(0) > 0 | |||
0 | 1 | ST(0) < 0 | |||
1 | 0 | ST(0) = 0 | |||
1 | 1 | ST(0) и 0 не сравнимы |
Команда FXAM анализирует содержимое ST(0). После ее выполнения устанавливаются коды условий, по которым можно судить о знаке числа, о его конечности или бесконечности, нормализованности и так далее.
Бит C1 содержит знак анализируемого числа:
C1 |
Знак числа |
0 |
Положительный |
1 |
Отрицательный |
C0 |
Описание |
0 |
Конечное число |
1 |
Бесконечное число |
C3 |
C2 |
Описание числа |
0 |
0 |
Ненормализованное число |
0 |
1 |
Нормализованное число |
1 |
0 |
Нулевое число |
1 |
1 |
Число денормализовано |
C3 |
C2 |
Описание числа |
0 |
0 |
Нечисло |
0 |
1 |
Бесконечное число |
1 |
0 |
Пустое число |
1 |
1 |
Пустое число |
Например, в следующем фрагменте программы выполняется переход к метке error, если операнды несравнимы:
.286
. . .
fcom
fstsw ax
sahf
je error
Компьютер IBM PC/XT
Для работы с клавиатурой типа IBM PC/XT используются порты с адресами 60h и 61h.
Порт 60h доступен только для чтения. После выполнения этой операции он содержит скан-код последней нажатой клавиши.
Порт 61h доступен как для чтения, так и для записи. Он управляет не только клавиатурой, но и другими устройствами компьютера, например, работой встроенного динамика. Если в старший бит порта 61h записать значение 1, клавиатура будет заблокирована, если 0 - разблокирована.
Так как порт 61h управляет не только клавиатурой, при изменении содержимого старшего бита необходимо сохранить состояние остальных битов этого порта. Для этого можно сначала выполнить чтение содержимого порта в регистр, изменить состояние старшего бита, затем выполнить запись нового значения в порт:
. . .
in al, 61h
or al, 80h
out 61h, al
. . .
- Конфигурация оборудования
В этом байте находится информация о количестве установленных НГМД, о наличии арифметического сопроцессора, а также о типе видеоадаптера, подключенного к системе. Приведем формат байта конфигурации:
Бит | Описание | ||
0 | 1 - в системе установлены НГМД;
0 - НГМД не используются | ||
1 | 1 - установлен арифметический сопроцессор;
0 - арифметический сопроцессор не установлен | ||
2-3 | не используются, равны 0 | ||
4-5 | Тип видеоадаптера и видеорежим:
00 - не используется или EGA; 01 - CGA, EGA, VGA в режиме 40x25; 10 - CGA, EGA, VGA в режиме 80x25; 11 – монохромный видеоадаптер | ||
6-7 | Количество установленных НГМД, уменьшенное на единицу;
00 – один НГМД; 01 – два НГМД; 10 – три НГМД; 11 – четыре НГМД |
Конфигурация в памяти CMOS
Как мы уже говорили, энергонезависимая память CMOS используется в современных компьютерах для хранения текущей конфигурации аппаратных средств. Эта память состоит из набора ячеек, доступ к которым для чтения и записи выполняется через порты ввода и вывода с адресами 70h и 71h.
Процедура чтения ячейки памяти CMOS состоит из двух шагов. На первом шаге программа записывает в выходной порт с адресом 70h номер ячейки, из которой необходимо прочитать информацию. На втором шаге программа читает содержимое данной ячейки из входного порта с адресом 71h:
int nCellContent;
outp(0x70, nCell);
nCellContent = inp(0x71);
Запись данных в ячейку памяти CMOS выполняется аналогично, только после записи номера ячейки в порт 70h программа должна записать новое значение для этой ячейки в порт с адресом 71h:
outp(0x70, nCell);
outp(0x71, nNewValue);
В памяти CMOS хранится текущее время и дата, сведения о конфигурации системы, результат тестирования при включении питания и другая информация, приведенная ниже:
Адрес ячейки | Содержимое | ||
00h - 0Dh | Используются часами реального времени | ||
0Eh | Байт состояния диагностики при включении питания | ||
0Fh | Байт состояния отключения | ||
10h | Тип НГМД | ||
11h | Зарезервировано | ||
12h | Тип НМД (если меньше 15) | ||
13h | Зарезервировано | ||
14h | Конфигурация оборудования | ||
15h - 16h | Объем основной памяти | ||
17h - 18h | Объем расширенной памяти | ||
19h | Тип первого НМД (если он больше 15) | ||
1Ah | Тип второго НМД (если он больше 15) | ||
1Bh - 20h | Зарезервировано | ||
21h - 2Dh | Зарезервировано | ||
2Eh - 2Fh | Контрольная сумма ячеек 10h - 20h | ||
30h - 31h | Объем расширенной памяти | ||
32h | Текущее столетие в двоично-десятичном коде (19h для 19-го столетия) | ||
33h | Различная информация | ||
34h - 3Fh | Зарезервировано |
Рассмотрим подробно назначение отдельных ячеек CMOS-памяти.
Контроллер прямого доступа IBM AT
Контроллер DMA компьютера IBM PC/AT совместим снизу вверх с контролером IBM PC/XT. Он состоит из двух каскадно включенных микросхем Intel 8237A-5. Второй контроллер обслуживает каналы DMA с номерами 4-7.
Приведем назначение каналов DMA для IBM AT:
Поле | Описание | ||
0 | Зарезервировано | ||
1 | Зарезервировано | ||
2 | Адаптер накопителя на гибком магнитном диске (НГМД) | ||
3 | Адаптер накопителя на магнитном диске (НМД) | ||
4 | Используется для каскадного соединения с первым контроллером DMA | ||
5-7 | Зарезервировано |
В разных моделях компьютеров назначение каналов DMA могут различаться. Кроме того, современные компьютеры допускают изменение назначения каналов с помощью программы BIOS Setup.
Каналы 0-3 являются 8-разрядными, а каналы 4-7 - 16-разрядными.
В связи с этим используются все 8 бит регистров страниц. Формируется 24-битовый адрес из 16 младших бит адреса, которые записываются в базовые регистры и 8 старших бит адреса, которые записываются в регистры страниц.
Размер страницы составляет 128 Кбайт, поэтому при передаче данных с использованием DMA не должна пересекаться граница 128 Кбайт.