Контроллер прямого доступа IBMPC/XT
Контроллер прямого доступа IBM PC/XT реализован на базе микросхемы Intel 8237A и содержит четыре канала. Эти каналы используются следующим образом:
Номер канала | Для чего применяется | ||
0 | Обновление содержимого динамической памяти компьютера.
Этот канал имеет наивысший приоритет | ||
1 | Не используется | ||
2 | Адаптер накопителя на гибком магнитном диске НГМД | ||
3 | Адаптер накопителя на магнитном диске НМД.
Этот канал имеет низший приоритет |
Копирование блоков EMB
Регистры на входе: | AH = 0Bh
DS:SI = указатель на управляющую структуру, определяющую откуда, куда и как будет выполняться копирование | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка | ||
Ошибки: | BL = 80h, 81h, 82h, A3h, A4h, A5h, A6h, A7h, A8h, A9h |
Формат управляющей структуры представлен ниже:
ExtMemMoveStruct struc
Length dd ? ; количество пересылаемых байт
SourceHandle dw ? ; индекс исходного блока
SourceOffset dd ? ; смещение в исходном блоке
DestHandle dw ? ; индекс блока-назначения
DestOffset dd ? ; смещение в блоке-назначении
ExtMemMoveStruct ends
Эта функция выполняет основную операцию с блоками EMB - копирование данных. Данные могут пересылаться между обычной памятью и блоками EMB, между различными блоками EMB и даже внутри обычной памяти.
Поле Length управляющей структуры указывает количество пересылаемых байт данных. Это количество должно быть четным.
Поля SourceHandle и DestHandle указывают, соответственно, идентификаторы исходного блока EMB и блока, в который выполняется копирование. Если в качестве идентификатора задано значение 0000h, это означает, что в качестве источника или приемника данных используется обычная память.
Поля SourceOffset и DestOffset указывают 32-разрядное смещение в блоке EMB или адрес в обычной памяти. В последнем случае этот адрес имеет стандартный формат [сегмент:смещение].
Функция копирования сама управляет линией A20, восстанавливая ее состояние после выполнения копирования. Поэтому программе не требуется управлять линией A20.
Во время выполнения копирования разрешены прерывания.
Копирование данных
FST память -> ST(0), вещественный формат
FIST память -> ST(0), целый формат
FBST память -> ST(0), десятичный формат,
(только 80387, 80486, Pentium)
Эти команды пересылают данные из верхушки стека в область памяти, указанную операндом команды. При этом содержимое указателя стека (поля ST) не изменяется.
Команда FST в качестве операнда может использовать ссылку на численный регистр ST(i), поэтому вы можете использовать эту команду для копирования верхушки стека в любой другой численный регистр.
При записи данных в оперативную память выполняется преобразование формата (в вещественный для FST, в целый для FIST и в десятичный для FBST.
Для сопроцессора 80286 вместо отсутствующей команды FBST можно выполнить следующие две команды, которые приведут к такому же результату:
FLD ST(0)
FBSTP dec_number
Литература
1. Фролов А.В., Фролов Г.В. Библиотека системного программиста. Т. 1. Часть 1, 2, 3. Операционная система MS-DOS. М: ДИАЛОГ-МИФИ, 1991, 1993
2. Фролов А.В., Фролов Г.В. Библиотека системного программиста. Т. 2. Аппаратное обеспечение IBM PC. Часть 1, 2. М: ДИАЛОГ-МИФИ, 1992
3. Фролов А.В., Фролов Г.В. Библиотека системного программиста. Т. 3. Программирование видеоадаптеров CGA, EGA и VGA. М: ДИАЛОГ-МИФИ, 1992
4. Фролов А.В., Фролов Г.В. Библиотека системного программиста. Т. 6. Защищенный режим процессоров Intel 80286/80386/80486. М: ДИАЛОГ-МИФИ, 1993
5. Фролов А.В., Фролов Г.В. Библиотека системного программиста. Т. 11-13. Операционная система Microsoft Windows для программиста. М: ДИАЛОГ-МИФИ, 1994
6. Фролов А.В., Фролов Г.В. T. 16. Модемы и факс-модемы. М: ДИАЛОГ-МИФИ, 1995
7. Фролов А.В., Фролов Г.В. T. 18. Операционная система MS-DOS для программиста. Часть 1. М: ДИАЛОГ-МИФИ, 1995
8. Фролов А.В., Фролов Г.В. T. 19. Операционная система MS-DOS для программиста. Часть 2. М: ДИАЛОГ-МИФИ, 1995
9. Голенкова Ж.К., Заблоцкий А.В., Мархасин М.Л. и др. Руководство по архитектуре IBM PC AT. Минск: ООО “Консул”, 1993
10. A. Shulman, R. Michels, J. Kyle, etc. Undocumented DOS. A Programmers’s Guide to Reserved MS-DOS Functions and Data Structures, Addison-Wesley, 1991
11. K. Porter, Stretching Quick C, New York, 1989
если функция выполнена успешно, 0000h
Регистры на входе: |
AH = 05h |
Регистры на выходе: |
AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка |
Ошибки: |
BL = 80h, 81h, 82h |
если функция выполнена успешно, 0000h
Регистры на входе: |
AH = 06h |
Регистры на выходе: |
AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка |
Ошибки: |
BL = 80h, 81h, 82h, 94h |
Микросхема UART
В основе последовательного порта передачи данных лежит микросхема Intel 8250 или более современные микросхемы, такие как 16450, 16550, 16550A. Это универсальный асинхронный приемо-передатчик (UART - Universal Asynchronous Receiver Transmitter). Микросхема содержит несколько внутренних регистров, доступных через команды ввода/вывода.
В микросхеме 8250 есть регистры передатчика и приемника данных. При передаче выходной байт записывается в буферный регистр передатчика, откуда затем переписывается в сдвиговый регистр передатчика. После этого байт выдвигается из сдвигового регистра по битам.
Аналогично работают сдвиговый и буферный регистры приемника.
Программа имеет доступ только к буферным регистрам, копирование информации в сдвиговые регистры и процесс сдвига выполняется микросхемой UART автоматически.
и 8254 состоят из трех
Таймеры 8253 и 8254 состоят из трех независимых каналов, или счетчиков. Каждый канал содержит регистры:
состояния канала RS (8 разрядов);
управляющего слова RSW (8 разрядов);
буферный регистр OL (16 разрядов);
регистр счетчика CE (16 разрядов);
регистр констант пересчета CR (16 разрядов)
Каналы таймера подключаются к внешним устройствам при помощи трех линий:
GATE - управляющий вход;
CLOCK - вход тактовой частоты;
OUT - выход таймера
Регистр счетчика CE работает в режиме вычитания. Его содержимое уменьшается по заднему фронту сигнала CLOCK при условии, что на вход GATE установлен уровень логической 1.
В зависимости от режима работы таймера при достижении счетчиком CE нуля тем или иным образом изменяется выходной сигнал OUT.
Буферный регистр OL предназначен для запоминания текущего содержимого регистра счетчика CE без остановки процесса счета. После запоминания буферный регистр доступен программе для чтения.
Регистр констант пересчета CR может загружаться в регистр счетчика, если это требуется в текущем режиме работы таймера.
Как нетрудно догадаться по названию, регистры состояния канала и управляющего слова предназначены, соответственно, для определения текущего состояния канала и для задания режима работы таймера.
Модель Intel 80286
В процессоре Intel 80286, когда он работает в реальном режиме адресации, биты 12-15 регистра FLAGS всегда сброшены в нуль, что можно использовать для обнаружения этой модели процессора.
Следующий фрагмент кода пытается записать в эти биты единичное значение:
mov ax, 0f000h
push ax
popf
Затем новое содержимое регистра FLAGS переписывается в регистр AX:
pushf
pop ax
Если содержимое битов 12-15 равно нулю, программа работает на процессоре Intel 80286:
and ax, 0f000h
jz is_80286
В противном случае необходимо продолжить проверку модели процессора.
Для того чтобы отличить процессор
Для того чтобы отличить процессор Intel 80386 от процессоров старших моделей, можно попробовать установить в регистре EFLAGS бит 18. Этот бит был впервые определен в процессоре Intel 80486 для сигнализации ошибки выравнивания. Его невозможно установить в процессоре Intel 80386.
В процессе проверки программа вначале получает исходное содержимое регистра EFLAGS, записывая его в регистры EAX и ECX:
pushfd
pop eax
mov ecx, eax
Далее программа инвертирует значение бита 18 и записывает полученный результат в регистр EFLAGS:
xor eax, 40000h
push eax
popfd
На последнем шаге идентификации новое содержимое регистра EFLAGS извлекается и сравнивается со старым:
pushfd
pop eax
xor eax, ecx
jz is_80386
Если бит 18 не изменил своего значения, мы имеем дело с процессором Intel 80386.
Отличительная особенность процессора Intel 80486
Отличительная особенность процессора Intel 80486 – невозможность изменения состояния бита 21 регистра EFLAGS. Этот бит используется процессорами Intel Pentium и более старшими моделями процессоров Intel для определения возможности вызова команды идентификации процессора CPUID, о которой мы скоро расскажем.
Фрагмент кода, который нужно использовать для обнаружения процессора Intel 80486, аналогичен фрагменту для процессора Intel 80386. Отличие заключается в том, что вместо бита 18 проверяется бит 21:
pushfd
pop eax
mov ecx, eax
xor eax, 200000h
push eax
popfd
pushfd
pop eax
xor eax, ecx
je is_80486
Если же выяснилось, что содержимое бита 21 регистра EFLAGS можно изменять, дальнейшую идентификацию модели процессора следует выполнять с использованием команды CPUID, к описанию которой мы и переходим.
основан на том факте,
Способ распознавания процессоров Intel 8086/ 8088 основан на том факте, что биты 12-15 регистра FLAGS всегда установлены в единицу.
Прежде всего программа записывает текущее содержимое регистра FLAGS в регистр AX. Для этого используется стек:
pushf
pop ax
Первоначальное содержимое регистра FLAGS сохраняется в регистре CX:
mov cx, ax
Далее программа пытается записать нулевые значения в биты 12-15 регистра FLAGS:
and ax, 0fffh
push ax
popf
Теперь нужно проверить, изменилось ли содержимое указанных битов регистра FLAGS. Для этого новое содержимое регистра FLAGS записывается через стек в регистр AX, а затем, после наложения маски 0f000h, сравнивается со значением 0f000h:
pushf
pop ax
and ax, 0f000h
cmp ax, 0f000h
je is_8086
Если биты 12-15 остались установленными в единичное значение, программа работает на процессоре Intel 8086/8088, если нет – в компьютере установлена более старшая модель процессора.
Мышь Microsoft IntelliMouse
В 1997 году Microsoft выпустила новую мышь с названием Microsoft IntelliMouse, добавив в нее принципиально новый орган управления – небольшое колесо, расположенное между левой и правой клавишами мыши. Это небольшое, на первый взгляд, усовершенствование намного упрощает работу пользователей с приложениями Windows, в которых нужно просматривать длинные документы или выполнять плавное масштабирование изображений.
Колесо имеет двойное назначение.
Во-первых, оно служит вместо третьей кнопки, которая есть в трехкнопочных мышах типа Mouse System и совместимых с ними. Ранее Microsoft упорно игнорировала третью кнопку в приложениях Windows, однако как вы увидите, теперь положение несколько изменилось.
Во-вторых, вы можете вращать колесо в обоих направлениях без ограничения угла поворота, причем такое вращение имеет дискретный характер.
Приложение Windows может использовать колесо, например, вместо вертикальной полосы просмотра Scrollbar. В этом случае для того чтобы сдвинуть содержимое окна просмотра, вам не нужно снимать руку с мыши и переносить ее на клавиатуру или перемещать курсор мыши к полосе просмотра. Достаточно просто немного повернуть колесо в нужном направлении – и содержимое окна будет сдвинуто.
К сожалению, для использования возможности новой мыши вам не достаточно просто подключить ее к компьютеру и установить соответствующий драйвер. Программы MS-DOS и приложения Microsoft Windows версии 3.1 совсем не могут пользоваться колесом, принимая новую мышь как обычную двухкнопочную мышь Microsoft. Что же касается приложений Microsoft Windows 95 и Microsoft Windows NT, то в них необходимо предусмотреть обработку сообщений, создаваемых колесом.
Заметим, что все новые приложения, созданные Microsoft, такие как Microsoft Office 97 и Microsoft Visual C++ версии 5.0, умеют работать с мышью Microsoft IntelliMouse.
Для того чтобы воспользоваться колесом в старых приложениях, таких как Microsoft Word 7.0, вы можете применить условно-бесплатное приложение Flywheel, загрузив его из Internet с сервера Web, расположенного по адресу http://www.plannetarium.com. Это приложение преобразует сообщения от колеса в сообщения от вертикальной полосы просмотра и выполняет ряд других интересных функций.
Мы же в этой книге расскажем вам, как можно оорганизовать обработку сообщений от колеса мыши Microsoft IntelliMouse в своих приложениях.
Начальный режим работы видеоадаптера
Биты с номерами 4 и 5 слова конфигурации содержат номер начального режима видеоадаптера. В современных компьютерах применяется, как правило, режим с номером 10b - цветной, 80 текстовых строк по 25 символов в каждой строке.
Наличие арифметического сопроцессора
До появления процессора i486 арифметический сопроцессор, значительно ускоряющий вычисления с плавающей точкой, был необязательным устройством. На системной плате компьютера для него предусматривалось отдельное гнездо.
Процессор i486 выпускался в двух модификациях – с встроенным арифметическим сопроцессором и без сопроцессора. В современных компьютерах на базе процессора Pentium арифметический сопроцессор присутствует всегда и находится в корпусе центрального процессора.
Анализируя бит с номером 1 в значении, полученном в регистре AX от прерывания INT11h, вы можете определить факт наличия в системе арифметического сопроцессора. Если сопроцессор установлен, программа может использовать его для выполнения вычислений. Каким именно образом - вы узнаете из главы нашей книги, посвященной этому устройству.
Наличие контроллера прямого доступа DMA
Контроллер прямого доступа DMA применяется для непосредственной передачи данных из периферийных устройств в оперативную память компьютера, минуя центральный процессор. Этот контроллер есть во всех современных компьютерах, поэтому бит с номером 8 обычно установлен в единицу.
Наличие НМД
Сейчас уже трудно найти компьютер, в котором не было бы жесткого диска (разве лишь вам встретится бездисковая рабочая станция для локальной сети или сетевой компьютер для Internet). Тем не менее, анализируя нулевой бит слова конфигурации, полученного в регистре AX от прерывания INT 11h, вы можете определить, оборудован ли данный компьютер жестким диском. Если этот бит установлен в единицу, то оборудован, если нет – жесткий диск отсутствует.
Настройка таймера для проигрывания музыки
Как мы уже говорили, канал 2 микросхемы 8254 связан с громкоговорителем компьютера. Однако громкоговоритель не просто соединен с выходом OUT канала 2. Порт вывода 61h также используется для управления громкоговорителем. Младший бит порта 61h подключен ко входу GATE канала 2 таймера. Этот бит при установке в 1 разрешает работу канала, то есть генерацию импульсов для громкоговорителя.
Дополнительно для управления громкоговорителем используется бит 1 порта 61h. Если этот бит установлен, импульсы от канала 2 таймера смогут проходить на громкоговоритель.
Таким образом, для включения звука надо выполнить следующие действия:
запрограммировать канал 2 таймера на нужную частоту (загрузить регистр счетчика канала нужным значением);
для включения звука установить два младших бита порта 61h.
Так как остальные 6 битов порта 61h используются для других целей, установка младших битов должна выполняться таким образом, чтобы значения остальных битов не были изменены. Для этого вначале надо считать байт из порта 61h в рабочую ячейку памяти, установить там нужные биты, затем вывести новое значение байта в порт 61h.
Для выключения звука надо сбросить два младших бита порта 61h, при этом нельзя изменять значение остальных битов этого порта.
Одноголосая мелодия состоит из нот, разделенных или не разделенных паузами. При проигрывании мелодии необходимо для каждой ноты программировать соответствующим образом канал 2 таймера и включать громкоговоритель (с помощью порта 61h) на определенное время, равное длительности ноты. Затем программа должна выключить динамик и выдержать паузу перед проигрыванием следующей ноты, если такая пауза требуется.
Недействительная операция
Этот особый случай возникает при попытке выполнения таких запрещенных команд, как деление нуля на нуль, извлечения корня из отрицательного числа, обращение к несуществующему регистру сопроцессора или при попытке использования в качестве операндов команд нечисел, неопределенностей или бесконечности (для трансцендентных функций).
Нефильтрованный ввод без эхо-вывода
Функция 07h читает символы со стандартного устройства ввода. Если стандартным устройством ввода является клавиатура, и буфер клавиатуры пуст, выполнение программы задерживается до нажатия на любую клавишу. Однако в отличие от функции 01h данная функция не проверяет комбинации клавиш <Control+C> и <Control+Break>.
Регистры на входе: | AH = 07h | ||
Регистры на выходе: | AL = код ASCII символа или 0. Если регистр содержит 0, то следующий вызов этой же функции возвратит в регистре AL расширенный код ASCII символа
Функция не проверяет комбинации клавиш <Control+C> и <Control+Break> |
Ее использовать в тех случаях, когда завершение программы по нажатию указанных комбинаций клавиш по тем или иным причинам нежелательно. Например, программа держит в оперативной памяти буферы для данных, которые перед завершением работы обязательно должны быть записаны на диск. Если пользователь в неподходящий момент времени нажал комбинацию клавиш <Control+Break> и программа аварийно завершила работу, содержимое буферов будет потеряно.
Неточный результат
В результате выполнения некоторых операций может возникнуть такая ситуация, когда невозможно точно представить результат. Например, при результатом деления числа 1.0 на 3.0 является бесконечная периодическая двоичная дробь 0.010101... Такое число не может быть представлено точно ни в одном формате вещественных чисел.
Обычно неточный результат является результатом округления и может не рассматриваться как ошибка.
Обмен
FXCH ST(i) -> ST(0), ST(0) -> ST(i)
Команда выполняет обмен содержимым верхушки стека ST(0) и численного регистра, указанного в качестве операнда команды.
Обработка особых случаев
В арифметическом сопроцессоре имеются два механизма обработки ошибок, возникающих при выполнении различных команд.
Первый механизм основан на генерации так называемого прерывания особого случая (INT10h). Это прерывание вырабатывается в том случае, когда происходит какая-нибудь ошибка (например, деление на нуль) при условии, что соответствующие биты масок особых случаев в регистре управления не установлены.
При втором способе обработки ошибок все особые случаи маскируются (соответствующие биты управляющего регистра устанавливаются в единицу) и в случае ошибки сопроцессор в качестве результата возвращает некоторое заранее известное особое значение (нечисло, неопределенность или бесконечность).
Программист может выбирать между этими способами обработки ошибок, маскируя или разрешая прерывание по особому случаю. Если прерывание особого случая замаскировано, можно предложить следующий способ обнаружения ошибки:
сбросить флажки особых случаев в регистре сосотояния;
выполнить одну или несколько команд сопроцессора;
проверить состояние флажков особых случаев в регистре состояния, в частности, бит суммарной ошибки ES;
если какой-либо флажок установлен, вызвать программу обработки ошибочной ситуации;
в программе обработки ошибочной ситуации можно сбросить флажки особых случаев, записав соответствующее значение в регистр состояния
Кроме того, после выполнения команды полезно проверить получившийся результат на принадлежность к множеству особых значений.
Рассмотрим возможные особые случаи сопроцессора в реальном режиме.
Обработка прерываний таймера
При инициализации BIOS устанавливает свой обработчик для прерывания таймера. Этот обработчик каждый раз увеличивает на единицу текущее значение 4-байтовой переменной, располагающейся в области данных BIOS по адресу 0000:046Ch - счетчик таймера. Если этот счетчик переполнится из-за того что прошло более 24 часов с момента запуска таймера, в ячейку 0000:0470h заносится значение 1.
Другое действие, выполняемое стандартным обработчиком прерывания таймера - контроль за работой двигателей НГМД. Если после последнего обращения к НГМД прошло более 2 секунд, обработчик прерывания выключает двигатель. Ячейка с адресом 0000:0440h содержит время, оставшееся до выключения двигателя. Это время постоянно уменьшается обработчиком прерывания таймера. Когда оно становится равно 0, двигатель НГМД отключается.
Последнее действие, которое выполняет обработчик прерывания таймера - вызов прерывания INT1Ch. После инициализации системы вектор INT 1Ch указывает на команду IRET, то есть обработчик прерывания INT 1Ch ничего не делает. Программа может установить собственный обработчик этого прерывания для того чтобы выполнять какие-либо периодические действия.
Необходимо отметить, что прерывание INT 1Ch вызывается обработчиком прерывания INT 8h до сброса контроллера прерывания, поэтому во время выполнения прерывания INT 1Ch все аппаратные прерывания запрещены. В частности, запрещены прерывания от клавиатуры.
Обработчик прерывания INT 1Ch должен заканчиваться командой IRET. Если же вы подготавливаете собственный обработчик для прерывания INT 8h, перед завершением его работы необходимо сбросить контроллер прерываний. Это можно сделать, например, так:
mov al, 20h
out 20h, al
Таймер обычно реализуется на микросхеме Intel 8253 (для компьютеров IBM PC и IBM PC/XT) или 8254 (для компьютеров IBM PC/AT и IBM PS/2), а также на аналогах этих микросхем. Следующий раздел книги посвящен описанию микросхемы 8254.
Мы не будем подробно рассказывать о всех возможностях микросхем 8253 и 8254, так как обычно используются только несколько режимов работы (а чаще всего один). Полное описание вы сможете найти в справочной литературе по микросхемам 8253/8254, а также по их отечественным аналогам КР1810ВИ53 и КР1810ВИ54.
Оглавление
АННОТАЦИЯ................................................................................................................
ВВЕДЕНИЕ....................................................................................................................
БЛАГОДАРНОСТИ.....................................................................................................
АВТОРСКИЙ КОМПАКТ-ДИСК.................................................................................
КАК СВЯЗАТЬСЯ С АВТОРАМИ..............................................................................
1 ОПРЕДЕЛЕНИЕ КОНФИГУРАЦИИ КОМПЬЮТЕРА.........................................
Определение конфигурации с помощью BIOS..................................................
Наличие НМД..............................................................................................................
Наличие арифметического сопроцессора...............................................................
Начальный режим работы видеоадаптера.............................................................
Количество установленных НГМД..........................................................................
Наличие контроллера прямого доступа DMA..........................................................
Количество асинхронных последовательных адаптеров....................................
Игровой адаптер........................................................................................................
Последовательный порт компьютера PCjr..............................................................
Количество параллельных адаптеров....................................................................
Размер оперативной памяти....................................................................................
Программа HDWCFG................................................................................................
Код модели компьютера и версия BIOS...........................................................
Ограничения при использовании области HMA
К сожалению, на программы, использующие область HMA, накладываются значительные ограничения. Они связаны с тем, что MS-DOS, а также BIOS не рассчитаны на работу с адресами памяти выше границы 1 Мбайт. Приведем список этих ограничений.
нельзя передавать MS-DOS дальние указатели на данные, размещенные в области HMA. Это связано с тем, что функции MS-DOS проверяют правильность таких указателей;
не рекомендуется использование области HMA для выполнения обмена данных с диском через прерывания MS-DOS, BIOS или другими способами;
драйверы и резидентные программы, использующие область HMA, не должны держать линию A20 постоянно включенной, так как это может привести к неправильной работе программ, не рассчитанных на наличие и доступность этой области;
векторы прерываний не должны указывать в область HMA. Это результат предыдущего ограничения.
Описание функций драйвера HIMEM.SYS
Все функции драйвера HIMEM.SYS могут быть разделены на следующие пять групп:
функции получения информации о драйвере (0h);
функции управления областью HMA (1h...2h);
функции управления линией A20 (3h...7h);
функции управления расширенной памятью (8h...Fh);
функции управления блоками UMB (10h...11h).
Приведем подробное описание этих функций в соответствии со спецификацией XMS версии 2.0.
Определение адреса заголовка драйвера CD-ROM
// ---------------
// Код функции 0
// ---------------
#pragma pack(1)
typedef struct _RAddr
{
BYTE bFunctionCode;
DWORD lpDeviceHeader;
} RAddr;
Поле | Описание | ||
bFunctionCode | Код функции | ||
lpDeviceHeader | Адрес заголовка драйвера CD-ROM |
Зная адрес заголовка драйвера, вы можете определить имя драйвера и его атрибуты. Подробности об атрибутах драйверов вы найдете в 18 томе «Библиотеки системного програмиста».
Определение количества устройств CD-ROM
Сегодня все большее количество компьютеров оснащается сразу несколькими устойствами чтения CD-ROM. С помощью функции 00h можно определить количество устройств чтения CD-ROM, имеющихся в системе, номер первого устройства CD-ROM, а также проверить, установлена ли программа MSCDEX:
Регистры на входе: | AX = 1500h; | ||
Регистры на выходе: | BX = количество устройств чтения CD-ROM, установленных в системе;
CX = номер первого устройства чтения CD-ROM. Значение 0 соответствует устройству A:, 1 – B: и так далее |
Заметим, что буквенные обозначения устройств не обязательно должны идти последовательно, начинаясь со значения, которое функция 00h возвращает в регистре CX. Если вам нужно определить обозначения всех устройств чтения CD-ROM, следует воспользоваться функцией 150Dh, о которой мы расскажем ниже в этом разделе.
Определение конфигурации с помощью BIOS
Во время инициализации системы BIOS опрашивает порты, к которым подключены перемычки, и определяет содержимое ячеек памяти CMOS, содержащие информацию о конфигурации компьютера. Результат записывается в область данных BIOS, откуда программа может его извлечь с помощью прерываний BIOS.
Сведения о наличии основных устройств компьютера записывается в область данных BIOS с адресом 0000:0410 размером в двухбайтовое слово - слово конфигурации. С помощью прерывания INT11h программа может получить в регистре AX слово конфигурации из указанной выше области данных BIOS.
Биты регистра AX | Содержимое | ||
0 | В системе установлен накопитель на магнитном диске (НМД) | ||
1 | В системе установлен арифметический сопроцессор | ||
2 – 3 (все модели, кроме IBM PS/2) | Количество банков оперативной памяти на системной плате. Для компьютера IBM PC размер одного банка равен 16 Кбайт, для IBM PC/XT – 64 Кбайт. Для определения объема оперативной памяти в более современных компьютерах следует использовать другие средства, о которых мы расскажем позже | ||
2 (IBM PS/2) | Компьютер IBM PS/2 оборудован мышью | ||
3 (IBM PS/2) | Не используется в IBM PS/2 | ||
4 – 5 | Начальный режим видеоадаптера:
00 – EGA или VGA 01 – цветной, 40x25 10 – цветной, 80x25 11 – монохромный, 80x25 | ||
6 – 7 | Количество установленных накопителей на гибких магнитных дисках (НГМД) | ||
8 | Установлен контроллер прямого доступа к памяти DMA | ||
9 – 11 | Количество установленных асинхронных последовательных портов | ||
12 | Установлен игровой порт | ||
13 | Установлен последовательный порт (только для компьютера PCjr) | ||
14 – 15 | Количество установленных параллельных адаптеров |
Определение обозначения устройств чтения CD-ROM
При помощи функции 0Dh вы можете заполнить массив номерами установленных в системе устройств чтения CD-ROM:
Регистры на входе: | AX = 150Dh;
ES:BX = адрес массива, в который будут записаны обозначения устройств CD-ROM | ||
Регистры на выходе: | Не используются |
Размер массива должен быть равен количеству установленных в системе устройств чтения CD-ROM, которое можно определить с помощью функции 00h.
Определение положения головки
// ---------------
// Код функции 1
// ---------------
#pragma pack(1)
typedef struct _HeadLocation
{
BYTE bFunctionCode;
BYTE bAddressMode;
DWORD lpHeadLocation;
} HeadLocation;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bAddressMode | Режим адресации:
0 – HSG; 1 – Redbook; 2 – 255 – зарезервировано | ||
lpHeadLocation | Положении головки. Значение зависит от режима адресации |
Здесь необходимо сделать замечание относительно режимов адресации.
По умолчанию устройство чтения CD-ROM находится в режиме адресации HSG, описанный в стандарте High Sierra. При этом в качестве адреса указывается логический номер блока.
Другой режим адресации описан в стандарте Redbook. В нем адрес представляет собой набор из трех значений: минуты (MIN), секунды (SEC), фреймы (FRAME). Каждое значение занимает один байт, причем в младшем байте хранится значение FRAME, в следующем байте - значение SEC, и в последнем, третьем байте, - значение MIN.
С помощью следующей формулы вы можете преобразовать адрес из формата Redbook в формат HSG:
SECTOR = MIN * 60 * 75 + SEC * 75 + FRAME – 150
Определение размера сектора
// ---------------
// Код функции 7
// ---------------
#pragma pack(1)
typedef struct _SectorSize
{
BYTE bFunctionCode;
BYTE bReadMode;
DWORD dwSectorSize;
} SectorSize;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bReadMode | Режим чтения | ||
dwSectorSize | Размер сектора. Для режима Cooked Reading он равен 2048 байт, для режима Raw Reading – 2352 байт |
Определение размера свободной расширенной памяти
Регистры на входе: | AH = 08h | ||
Регистры на выходе: | AX = размер наибольшего свободного блока расширенной памяти, Кбайт;
DX = общий размер свободной расширенной памяти, Кбайт | ||
Ошибки: | BL = 80h, 81h, A0h |
При определении размера свободной расширенной памяти в возвращаемое значение не включается 64 Кбайт области HMA, даже если эта область не используется программами.
Определение размера тома
// ---------------
// Код функции 8
// ---------------
#pragma pack(1)
typedef struct _VolumeSize
{
BYTE bFunctionCode;
DWORD dwVolumeSize;
} VolumeSize;
Поле | Описание | ||
bFunctionCode | Код функции | ||
dwVolumeSize | Размер тома |
Функция возвращает адрес дорожки Lead-out, преобразованное в численное значение по следующей формуле:
frame + (sec * 75) + (min * 60 * 75)
Это значение является адресом первого сектора, который располагается за самым последним адресуемым сектором диска.
Определение состояния асинхронного адаптера
Состояние порта асинхронного адаптера можно узнать с помощью функции 03h:
Регистры на входе: | AH = 03h;
DX = номер порта адаптера: 0 - COM1, 1 - COM2; | ||
Регистры на выходе: | AL = состояние модема;
AH = состояние порта асинхронного адаптера. Если бит 7 регистра AH установлен, произошла ошибка |
Определение состояния и блокировка системы буферизованной печати
С помощью этой функции можно заблокировать систему буферизованной печати, определить ее состояние и получить доступ к списку файлов, находящихся в очереди печати.
Регистры на входе: | AH = 01h;
AL = 04h | ||
Регистры на выходе: | AH = состояние системы буферизованной печати;
FFh – система буферизованной печати установлена; DS:SI = адрес очереди печати (массив строк в формате ASCIIZ, конец массива отмечен строкой, состоящей из 0; DX = количество ошибок при попытке напечатать последний символ |
если линия A20 открыта, 0000h
Регистры на входе: |
AH = 07h |
Регистры на выходе: |
AX = 0001h - если линия A20 открыта, 0000h - если линия A20 закрыта |
Ошибки: |
BL = 00h, 80h, 81h |
Определение состояния принтера
Слово состояния принтера может быть получено с помощью функции 02h:
Регистры на входе: | AH = 02h;
DX = номер параллельного адаптера: 0 – LPT1, 1 – LPT2, 2 – LPT3 | ||
Регистры на выходе: | AH = слово состояния принтера |
Эту функцию удобно использовать перед началом печати для определения готовности принтера к работе.
Определение состояния устройства
// ---------------
// Код функции 6
// ---------------
#pragma pack(1)
typedef struct _DeviceStatus
{
BYTE bFunctionCode;
DWORD dwDeviceParameters;
} DeviceStatus;
Поле | Описание | ||
bFunctionCode | Код функции | ||
dwDeviceParameters | 32-разрядное слово состояния устройства |
Описания отдельных бит слова состояния приведено ниже:
Бит | Описание | ||
0 | 1 – устройство открыто, в него можно вставлять диск;
0 – устройство закрыто | ||
1 | 0 – устройство заблокировано, из него нельзя извлечь диск;
1 – устройство разблокировано | ||
2 | 0 – устройство может работать только в режиме Cooked Reading;
1 – дополнительно может использоваться режим Raw Reading | ||
3 | 0 – устройстов может только читать компакт-диски;
1 – устройство может читать и записывать компакт-диски | ||
4 | 0 – устройство может работать только с дорожками, содержащими данные:
1 – дополнительно устройство может проигрывать звуковые дорожки или дорожки с видео | ||
5 | 0 – устройство не способно работать с чередованием данных;
1 – устройство работает с чередованием данных в стандарте ISO?9660 | ||
6 | Зарезервировано | ||
7 | 0 – предварительная выборка не применяется;
1 – устройство способно выполнять запросы на предварительную выборку | ||
8 | 0 – устройство не работает со звуковыми каналами;
1 – устройство может работать со звуковыми каналами | ||
9 | 0 – устройство может работать в режиме адресации HSG;
1 – дополнительно можно использовать режим адресации Redbook | ||
10 | Зарезервировано | ||
11 | 0 – в устройстве находится компакт-диск;
1 – в устройстве нет компакт-диска | ||
12 | 0 – устрйство не работает с подканалами R-W;
1 – указанные каналы используются | ||
13-31 | Зарезервировано и равно нулю |
Немного о режимах Cooked и Raw.
По умолчанию устройство чтения CD-ROM работает в режиме Cooked. Этот режим предполагает аппаратную обработку циклической контрольной суммы. Размер блока данных равен 2048 байт.
В режиме Raw драйвер возвращает 2352 байта данных, в которые входят заголовок блока данных и контрольная сумма.
Определение текущего времени
Для того, чтобы определить текущее время, можно воспользоваться функцией 2Ch:
Регистры на входе: | AH = 2Ch | ||
Регистры на выходе: | CH = часы (0-24);
CL = минуты (0-59); DH = секунды(0...59); DL = сотые доли секунды (0-99) |
Точность времени, полученного при помощи этой функции, определяется таймером (его счетчик обновляется 18,2 раза в секунду).
Определение текущей даты
Для определения текущей даты используется функция 2Ah:
Регистры на входе: | AH = 2Ah | ||
Регистры на выходе: | DL = день (0...31);
DH = месяц (1...12); CX = год (1980...2099); AL = номер дня недели: 0 - воскресенье; 1 - понедельник; 2 - вторник; . . . 6 - суббота |
Обратите внимание на то, что функция возвращает вам номер дня недели, который она вычисляет на основе даты.
Определение типа центрального процессора
В некоторых случаях эффективность работы программы можно заметно повысить, если использовать команды новых моделей процессоров Pentium, такие как, например, команды MMX. На сервере Intel с адресом http://www.intel.com вы найдете исчерпывающую информацию о том, как распознать различные модели процессоров, созданных этой фирмой. В нашей книге мы рассмотрим упрощенную методику, которая, тем не менее, может быть использована в большинстве случаев.
Определение величины свертки
Как мы уже говорили, колесо мыши Microsoft IntelliMouse вращается дискретно, как будто на нем есть засечки. При повороте колеса на каждую такую засечку приложение, получив от мыши сообщение, обычно свертывает документ на заранее определенное количество строк или на целую страницу.
Величина свертки определяется настройкой драйвера мыши. По умолчанию каждый поворот колеса соответствует сдвигу на 3 строки. Вы, однако, можете установить другое значение, либо указать, что свертка должна выполняться постранично.
Когда вы обрабатываете сообщения, поступающие от колеса мыши, величина и вид свертки должны определяться с учетом параметров, установленных для драйвера мыши. Способ определения величины свертки зависит от версии операционной системы.
В среде операционных систем Microsoft
В среде операционных систем Microsoft Windows 95 и Microsoft Windows NT версии 3.51 для определения величины свертки вначале необходимо зарегистрировать сообщение MSH_SCROLL_LINES:
UINT uMSH_SCROLL_LINES = 0;
uMSH_SCROLL_LINES = RegisterWindowMessage(MSH_SCROLL_LINES);
Затем это сообщение посылается приложению MSWheel с помощью функции SendMessage:
UINT uiScrollLines = 3;
uiScrollLines =
(BOOL)SendMessage(hwndMSHWheel, uMSH_SCROLL_LINES, 0, 0);
Функция возвращает величину свертки в строках или значение WHEEL_PAGESCROLL, если в параметрах драйвера мыши задано, что при вращении колеса мыши должна выполняться постраничная свертка.
Если приложение работает в среде операционной системы Microsoft Windows NT версии 4.0, то оно должно определять величину свертки с помощью функции SystemParametersInfo:
UINT uiScrollLines = 3;
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
&uiScrollLines, 0);
Эта функция предназначена для определения различных системных параметров. В качестве первого параметра функции SystemParametersInfo передается значение SPI_GETWHEELSCROLLLINES, а в качестве третьего – адрес переменной типа UINT, в которую будет записана величина свертки.
Определение версии MSCDEX
Функция 0Ch предназначена для определения версии установленной программы MSCDEX:
Регистры на входе: | AX = 150Ch; | ||
Регистры на выходе: | BH = старший номер верии MSCDEX;
BL = младший номер версии MSCDEX |
Определить чувствительность мыши
Функция 1Bh позволяет определить текущие значения для чувствительности мыши и порога удвоения.
Регистры на входе: | AX = 001Bh | ||
Регистры на выходе: | BX = горизонтальная чувствительность в миках на пиксел;
CX = вертикальная чувствительность в миках на пиксел; DX = значение порога удвоения, мики в секунду |
Определить номер страницы видеопамяти
Функция 1Eh возвращает номер страницы видеопамяти, на которой в настоящее время отображается курсор мыши.
Регистры на входе: | AX = 001Eh | ||
Регистры на выходе: | BX = номер страницы видеопамяти |
Определить положение курсора
Функция 03h возвращает текущие координаты курсора мыши и состояние клавиш.
Регистры на входе: | AX = 0003h | ||
Регистры на выходе: | BX = состояние клавиш мыши;
CX = координата X курсора; DX = координата Y курсора |
В зависимости от того, была ли нажата какая-либо клавиша мыши в момент вызова функции, в регистре BX могут быть установлены следующие флаги:
Установленный бит регистра BX | Клавиша, которая была нажата | ||
0 | Левая | ||
1 | Правая | ||
2 | Средняя |
Для графических режимов координаты располагаются в различных диапазонах, в зависимости от текущего режима видеоадаптера:
Размер экрана в пикселах | Номер режима | Диапазон координат по оси X | Диапазон координат по оси Y | ||||
320x200 | 4, 5 | 0 - 638 | 0 - 199 | ||||
640x200 | 6 | 0 - 639 | 0 - 199 | ||||
320x200 | 0Dh | 0 - 638 | 0 - 199 | ||||
640x200 | 0Eh | 0 - 639 | 0 - 199 | ||||
640x350 | 0Fh | 0 - 639 | 0 - 349 |
Программы, работающие в текстовом режиме, должны разделить полученные координаты на 8 (как координату X, так и координату Y).
Определить положение курсора при нажатии клавиши
Регистры на входе: | AX = 0005h
BX = клавиша, при нажатии которой запоминается состояние мыши: 0 - левая; 1 - правая; 2 - средняя | ||
Регистры на выходе: | AX = состояние клавиш мыши;
BX = количество нажатий на заданную клавишу. Это значение обнуляется после вызова функции; CX = координата курсора X; DX = координата курсора Y |
В зависимости от того, была ли нажата какая-либо клавиша мыши в момент вызова функции, в регистре AX могут быть установлены следующие флаги:
Установленный бит регистра AX | Клавиша, которая была нажата | ||
0 | Левая | ||
1 | Правая | ||
2 | Средняя |
В отличие от функции 03h эта функция возвращает программе не текущее состояние мыши, а запомненное в момент последнего нажатия на клавишу, заранее определенную при вызове функции. Она также возвращает количество нажатий на заданную клавишу, которое вы можете использовать для обнаружения двойных щелчков.