Определить положение курсора при отпускании клавиши
Функция 06h возвращает программе состояние мыши, запомненное в момент отпускания клавиши, которая была заранее определена при вызове функции. Она также возвращает количество отпусканий заданной клавиши.
Регистры на входе: | AX = 0006h
BX = клавиша, при отпускании которой запоминается состояние мыши: 0 - левая; 1 - правая; 2 – средняя | ||
Регистры на выходе: | AX = состояние клавиш мыши;
BX = количество нажатий на заданную клавишу. Это значение обнуляется после вызова функции; CX = координата курсора X; DX = координата курсора Y |
Формат регистра AX, определяющий состояние клавиш мыши, такой же как и для функции 05h.
Определить порог удвоения скорости
Если вы перемещаете мышь со скоростью, превышающей порог удвоения, заданный функцией 13h, аппаратура мыши удваивает величину перемещения. Таким образом, используя медленное перемещение мыши, вы можете точно устанавливать курсор на требуемый элемент изображения. Если вам необходимо переместить курсор на значительное расстояние по экрану, вы можете увеличить скорость перемещения мыши.
Формат вызова функции 13h приведен ниже:
Регистры на входе: | AX = 0013h | ||
Регистры на выходе: | DX = значение порога удвоения, мики в секунду |
При инициализации устанавливается значение порога, равное 64 микам в секунду (1/3 дюйма в секунду). Если вам надо установить это значение, вы можете при вызове функции 13h задать DX=0.
Определить размер буфера состояния драйвера
Если вам требуется временно сохранить состояние драйвера мыши, а затем восстановить его, вы можете воспользоваться специально предназначенными для этого функциями 16h и 17h. Для этих функций требуется буфер, в котором будет храниться состояние драйвера. Размер буфера можно определить с помощью функции 15h.
Регистры на входе: | AX = 0015h | ||
Регистры на выходе: | BX = размер буфера, требующийся для хранения состояния драйвера мыши |
Когда может потребоваться запоминание и восстановление состояния драйвера? Например, при использовании мыши резидентными (TSR) программами желательно сохранить состояние драйвера перед началом работы TSR-программы и восстановить его перед завершением работы TSR-программы.
Определить содержимое счетчиков перемещения
Функция 0Bh позволяет определить относительное перемещение мыши с момента последнего вызова этой функции. Результат возвращается в указанных выше регистрах. Для измерения перемещения используется единица mickey - “мики”. Один мик соответствует 0.005 дюйма (то есть 1/200 дюйма).
Регистры на входе: | AX = 000Bh | ||
Регистры на выходе: | CX = перемещение по горизонтали с момента последнего вызова функции;
DX = перемещение по вертикали с момента последнего вызова функции |
Отрицательные значения перемещения означают движение влево и вверх, положительные - вправо и вниз.
Для преобразования миков в пикселы, соответствующие точкам экрана, можно использовать функцию 1Bh, которая будет описана позже.
Определить тип мыши
Функция 24h дает информацию о типе используемой мыши, версии драйвера мыши и об используемом номере прерывания.
Регистры на входе: | AX = 0024h | ||
Регистры на выходе: | BH = верхний (major) номер версии драйвера;
BL = нижний (minor) номер версии драйвера; CH = тип мыши: 1 - Bus Mouse; 2 - Serial Mouse; 3 - Inport Mouse; 4 - PS/2 Mouse; 5 - HP Mouse; CL = номер используемого прерывания (IRQ): 0 - IBM PS/2; 2, 3, 4, 5, 7 - IBM PC |
Ошибка в процессоре Pentium
В листинге 10.2 мы привели исходный текст программы PENTERR, с помощью которой можно обнаружить известную ошибку в арифметическом сопроцессоре, встроенном в процессор Pentium. Эта ошибка приводит к снижению точности результата при делении некоторых комбинаций чисел.
В нашем случае мы проверяем результат вычислений по следующей формуле:
(4195835 / 3145727) * 3145727
Если ошибки нет, в результате вычислений должно получиться значение 4195835. При наличии ошибки значение результата будет меньше этого числа на 256.
Листинг 10.2. Файл penterr\penterr.asm
; =====================================================
; Проверка наличия ошибки в сопроцессоре,
; встроенном в процессор Pentium
;
; (C) A. Frolov, 1997
;
; E-mail: frolov@glas.apc.org
; WWW: http://www.glasnet.ru/~frolov
; or
; http://www.dials.ccas.ru/frolov
; =====================================================
.model small
.STACK 100h
.DATA
.286
x dd 4195835.0
y dd 3145727.0
z dd ?
BugMsg db 13,10,"Pentium NPU bug detected!", "$"
OkMsg db 13,10,"Your Pentium NPU is OK", "$"
.CODE
begin:
mov ax, DGROUP
mov ds, ax
; Записываем в стек численных регистров
; значение x
fld x
; Делим содержимое верхушки стека
; на константу y
fdiv y
; Умножаем содержимое верхушки стека
; на эту же константу
fmul y
; В результате при отсутствии ошибки мы должны
; получить результат, равный x
fcom x
; Сохраняем регистр состояния сопроцессора в AX
fstsw ax
; Переписываем AH в регистр флагов
sahf
; Проверяем равенство нулю
jnz bug
; Ошибки нет
mov ah, 9
mov dx, offset OkMsg
int 21h
jmp next
; Обнаружена ошибка
bug:
mov ah, 9
mov dx, offset BugMsg
int 21h
; Завершаем работу программы и
; возвращаем управление операционной системе
next:
mov ax, 4C00h
int 21h
END begin
Основные понятия
При обсуждении спецификации XMS мы будем использовать следующие понятия и термины:
расширенная память (Extended Memory или XMS) - это память, используемая в компьютерах с процессорами 80286, 80386, 80486 и Pentium, располагающаяся в адресном пространстве выше границы 1 Мбайт;
старшая область памяти (High Memory Area или HMA) - это первые 64 Кбайт расширенной памяти, начинающиеся с адреса FFFFh:0010h. Адрес конца области HMA - FFFFh:FFFFh. Следовательно, размер области составляет 64 Кбайт без 16 байт. Следует отметить, что эта область может адресоваться процессором в реальном режиме и поэтому пригодна для обычных программ, предназначенных для работы в среде MS-DOS;
верхние блоки памяти (Upper Memory Blocks или UMB) - располагаются между границей 640 Кбайт и 1 Мбайт. Расположение и размер этих блоков могут сильно изменяться в зависимости от конфигурации аппаратуры компьютера;
расширенные блоки памяти (Extended Memory Blocks или EMB) - блоки расширенной памяти, располагающиеся выше границы HMA;
линия A20 - двадцать первая адресная линия процессора. Обычно эта линия заблокирована. Разблокировка линии открывает программам доступ к области HMA
На рис. 11.1 схематично показано расположение различных перечисленных выше блоков памяти в адресном пространстве.
Рис. 11.1. Расположение различных блоков памяти в адресном пространстве
Основные понятия и термины
Последовательная передача данных предполагает, что данные передаются с использованием единственной линии. При этом биты байта данных передается по очереди с использованием одного провода.
Для синхронизации группе битов обычно предшествует специальный стартовый бит. После группы битов данных следует бит проверки на четность и один или два стоповых бита. Иногда бит проверки на четность может отсуствовать.
Исходное состояние линии последовательной передачи данных - уровень логической 1. Стартовый бит START сигнализирует о начале передачи данных. Далее передаются биты данных, вначале младшие, затем старшие. Если используется бит четности P, то передается и он. Бит четности имеет такое значение, чтобы в пакете битов общее количество единиц (или нулей) было четно или нечетно.
В самом конце передаются один или два стоповых бита STOP, завершающих передачу байта. Затем уровень линии передачи снова устанавливается в 1 до прихода следующего стартового бита.
Использование четности, стартовых и стоповых битов определяют протокол передачи данных. Очевидно, что передатчик и приемник данных должны использовать один и тот же протокол, иначе связь будет невозможной.
Другая важная характеристика - скорость передачи данных. Она также должна быть одинаковой для передатчика и приемника.
Скорость передачи данных обычно измеряется в бодах. Боды - это количество передаваемых бит в секунду. При этом учитываются и старт/стопные биты, а также бит четности.
В технической литературе и в различной документации документации вы можете встретить и другой термин - биты в секунду (bps). Здесь имеется в виду эффективная скорость передачи данных без учета временных затрат на передачу служебных битов.
Остановка проигрывания звуковой дорожки
Команда останавливает проигрывание звуковой дорожки.
Формат заголовка запроса:
// ---------------
// Код команды 133
// ---------------
#pragma pack(1)
typedef struct _StopPlay
{
ReqHdr rh;
} StopPlay;
Заполнение полей заголовка запроса:
Поле | Описание | ||
rh.wStatus | После вызова драйвера содержит слово состояния |
Освободить блок EMB
Регистры на входе: | AH = 0Ah
DX = идентификатор освобождаемого блока EMB | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка | ||
Ошибки: | BL = 80h, 81h, A2h, B2h |
Функция освобождает блок EMB, заказанный предыдущей функцией. При этом все данные, находившиеся в блоке, будут потеряны.
Освободить область HMA
Регистры на входе: | AH = 02h | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка | ||
Ошибки: | BL = 80h, 81h, 90h, 93h |
Программы, которые запрашивали область HMA, должны освобождать ее после использования при помощи этой функции. При этом данные, которые находились в этой области, будут потеряны.
После того, как программа освободила область HMA, эта область становится доступной другим программам.
Освободить область UMB
Регистры на входе: | AH = 11h
DX = сегмент освобождаемого UMB | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка | ||
Ошибки: | BL = 80h, B2h |
После освобождения блока EMB данные, которые там находились, будут потеряны.
Отключить драйвер мыши
После вызова функции 1Fh драйвер мыши полностью отключается. Вектор прерывания INT33h остается определенным, однако теперь выполняется только одна функция прерывания INT 33h - функция 21h (программный сброс мыши).
Регистры на входе: | AX = 001Fh | ||
Регистры на выходе: | AX = результат выполнения:
001Fh - драйвер отключен; FFFFh - отключение невозможно; ES:DX = адрес предыдущего драйвера мыши |
Функцию 1Fh удобно использовать для временной замены драйвера на собственную систему обслуживания мыши. Сначала вы отключаете драйвер функцией 1Fh, запоминая адрес предыдущего драйвера, возвращаемого в регистрах ES:DX. Затем устанавливаете собственную систему обслуживания мыши, а после ее использования - восстанавливаете значение этого адреса.
Открывание устройства
Команда открывает устройство чтения CD-ROM, сообщая драйверу о том, что данное устройство будет использовано еще одной программой.
Формат заголовка запроса:
// ---------------
// Код команды 13
// ---------------
#pragma pack(1)
typedef struct _RsumePlay
{
ReqHdr rh;
} RsumePlay;
Заполнение полей заголовка запроса:
Поле | Описание | ||
rh.wStatus | После вызова драйвера содержит слово состояния |
Отмена печати файла
С помощью этой функции вы можете удалить файл из очереди печати.
Регистры на входе: | AH = 01h;
AL = 02h; DS:DX = адрес строки в формате ASCIIZ, содержащей имя файла, удаляемого из очереди для печати | ||
Регистры на выходе: | AH = состояние системы буферизованной печати |
Отмена печати всех файлов
С помощью этой функции вы можете удалить печать всех файлов, которые находятся в очереди печати.
Регистры на входе: | AH = 01h;
AL = 03h | ||
Регистры на выходе: | AH = состояние системы буферизованной печати |
Печать символа
Функция 00h предназначена для печати одного символа:
Регистры на входе: | AH = 00h;
AL = код ASCII символа, который нужно напечатать; DX = номер параллельного адаптера: 0 – LPT1, 1 – LPT2, 2 – LPT3 | ||
Регистры на выходе: | AH = слово состояния принтера |
Эта функция выводит на принтер один символ, заданный в регистре AL. В регистре DX необходимо записать номер используемого параллельного адаптера. Для адаптера LPT1 это 0, для LPT2 - 1 и так далее.
После выполнения прерывания регистр AH будет содержать слово состояния, имеющее следующий формат:
Поле | Описание | ||
0 | Истекло время ожидания при выполнении операции печати, возможно, что принтер неисправен | ||
1-2 | Не используются | ||
3 | Ошибка ввода/вывода | ||
4 | 1 - принтер выбран для работы;
0 - принтер находится в состоянии offline | ||
5 | Конец бумаги | ||
6 | Подтверждение | ||
7 | 1 - принтер готов к работе;
0 - принтер занят |
Вызвав функцию 00h прерывания INT 17h, программа должна проверить биты слова состояния и убедиться в том, что вывод байта произошел без ошибок. Пользователь часто забывает перевести принтер в состояние online, вставить бумагу, либо вообще включить принтер. В этом случае целесообразно напомнить пользователю о необходимости выполнения этих действий и затем повторить попытку печати.
Если принтер неисправен, программа должна предоставить пользователю возможность отменить печать.
Обратите внимание на бит 1 байта состояния. Если принтер находится в состоянии offline, функция 00h прерывания INT 17h ожидает некоторое время готовности принтера, после чего, если принтер так и не перешел в состояние готовности, устанавливает бит 1 в байте состояния. Область данных BIOS по адресу 0000h:0478h содержит четыре байта, которые используются в качестве счетчика времени при ожидании готовности принтера.
Передача байта
Для передачи байта используется функция 01h:
Регистры на входе: | AH = 01h;
DX = номер порта адаптера: 0 - COM1, 1 - COM2; AL = передаваемый байт | ||
Регистры на выходе: | AL сохраняется;
AH = состояние порта асинхронного адаптера. Если бит 7 регистра AH установлен, произошла ошибка |
Передача данных
Перед записью байта данных в регистр передатчика необходимо убедиться в том, что регистр хранения передатчика свободен, то есть убедиться в том, что передача предыдущего символа завершена.
Признаком того, что регистр передатчика свободен, является установленный бит 5 регистра состояния линии с адресом 3FDh.
Переключающие клавиши
Помимо управления содержимым буфера клавиатуры, обработчик прерывания INT 09h отслеживает так называемые переключающие клавиши - <NumLock>, <ScrollLock>, <CapsLock>, <Insert>. Состояние этих клавиш записывается в область данных BIOS в два байта с адресами 0000h:0417h и 0000h:0418h.
Формат байта 0000h:0417h:
Биты | Описание | ||
0 | Нажата правая клавиша <Shift> | ||
1 | Нажата левая клавиша <Shift> | ||
2 | Нажата комбинация клавиш <Ctrl+Shift> с любой стороны | ||
3 | Нажата комбинация клавиш <Alt+Shift> с любой стороны | ||
4 | Состояние клавиши <ScrollLock> | ||
5 | Состояние клавиши <NumLock> | ||
6 | Состояние клавиши <CapsLock> | ||
7 | Состояние клавиши <Insert> |
Формат байта 0000h:0418h:
Биты | Описание | ||
0 | Нажата левая клавиша <Shift> вместе с клавишей <Control> | ||
1 | Нажата левая клавиша <Shift> вместе с клавишей <Alt> | ||
2 | Нажата клавиша <SysReq> | ||
3 | Состояние клавиши <Pause> | ||
4 | Нажата клавиша <ScrollLock> | ||
5 | Нажата клавиша <NumLock> | ||
6 | Нажата клавиша <CapsLock> | ||
7 | Нажата клавиша <Insert> |
Если вы изменяете состояние светодиодов на панели клавиатуры, не забывайте устанавливать соответствующие биты в байтах состояния клавиатуры.
Программой обработки прерывания INT 09h отслеживаются некоторые комбинации клавиш. Ниже приведены эти комбинации и действия, выполняемые обработчиком прерывания при их обнаружении:
Комбинация клавиш | Выполняемые действия | ||
<Control+Alt+Delete> | Сброс и перезагрузка системы | ||
<Control+NumLock>,
<Pause> | Перевод компьютера в состояние ожидания до тех пор, пока пользователь не нажмет любую клавишу | ||
<Shift+PrintScreen> | Распечатка на принтере содержимого видеопамяти | ||
<Control+Break> | Выполнение прерывания INT 1Bh, завершающего работу программы |
Многие типы клавиатур имеют отдельную альтернативную цифровую панель, напоминающую клавиатуру калькулятора. Если одновременно с нажатием на клавишу <Alt> набрать на этой панели число, не большее, чем 255 и не равное 0, то это число будет помещено в буфер клавиатуры, как будто бы оно было введено при помощи одной клавиши. Это число будет также записано в слово, расположенное в области данных BIOS по адресу 0000h:0419h.
Заметим, что упомянутый способ работает и в приложениях Microsoft Windows.
Переполнение
Если результат выполнения операции слишком велик и не может быть представлен в формате приемника результата, фиксируется особый случай переполнения.
Этот особый случай обязательно произойдет, например, при сложении максимального числа расширенной точности самим с собой или при преобразовании этого числа в формат с двойной или одинарной точностью.
Так как для хранения промежуточных результатов используется 80-битовое представление, при выполнении операций над числами с одинарной или двойной точностью переполнения, как правило, не происходит. Огромный диапазон чисел с расширенной точностью гарантирует правильность представления больших по абсолютной величине результатов операций с числами одинарной и двойной точности.
Перевод страницы
Код команды: 0Ch
Принтер распечатывает все символы, находившиеся в буфере, затем выполняет прогон одного листа бумаги.
Перевод строки
Код команды: 0Ah
Когда этот символ посылается на принтер, все символы, находящиеся во внутреннем буфере принтера, распечатываются, затем каретка возвращается к началу строки и происходит подача листа вперед на одну строку.
Подключение принтера к компьютеру
Принтер подключается к компьютеру двумя способами: либо через асинхронный последовательный адаптер, либо через параллельный адаптер. Вы можете подключить к одному компьютеру сразу нескольких принтеров, причем принтеры могут быть подключены одновременно и к параллельному, и к асинхронному последовательному адаптеру.
Для подключения к последовательному адаптеру принтер должен быть оборудован специальным последовательным интерфейсом. Кроме того, необходимо использовать специальный кабель. Если вы подсоедините принтер к последовательному порту при помощи кабеля, предназначенного для работы с параллельным портом, то это может привести к повреждениям в оборудовании компьютера или принтера. Внимательно читайте раздел документации на принтер, посвященный подключению к компьютеру.
Поиск
Команда выполняет позиционирование головки. Она возвращает управление немедленно, не дожидаясь завершения процесса позиционирования.
Формат заголовка запроса:
// ---------------
// Код команды 131
// ---------------
#pragma pack(1)
typedef struct _Seek
{
ReqHdr rh;
BYTE bAddressMode;
DWORD lpTransferAddress;
WORD wDataSize;
WORD wStartSector;
} Seek;
Заполнение полей заголовка запроса:
Поле | Описание | ||
rh.wStatus | После вызова драйвера содержит слово состояния | ||
bAddressMode | Режим адресации:
0 – режим HSG (по умолчанию); 1 – режим Readbook; 2-255 – зарезервировано | ||
lpTransferAddress | Адрес буфера | ||
wDataSize | Размер буфера | ||
wStartSector | Номер начального сектора, должен быть равен нулю |
Получение адреса управляющей программы
Для вызова драйвера программа должна получить адрес специальной управляющей программы, которая выполняет все функции по обслуживанию расширенной памяти и области HMA.
Этот адрес можно получить, если загрузить в регистр AX значение 4310h и вызвать прерывание INT 2Fh. Прерывание возвратит сегментный адрес управляющей программы в регистре ES, смещение - в регистре BX:
; Получаем адрес управляющей функции драйвера
mov ax, 4310h
int 2fh
mov word ptr cs:[HMMEntry][0], bx
mov word ptr cs:[HMMEntry][2], es
В дальнейшем полученный адрес используется для выполнения функций по обслуживанию расширенной памяти. Перед вызовом управляющей программы код требуемой функции должен быть загружен в регистр AH:
; Получаем номер версии драйвера HIMEM.SYS
mov ax,0
call [HMMEntry]
Программы, которые обращаются к управляющей функции, должны перед вызовом функции иметь размер стека не менее 256 байт.
Получение имени файла библиографической документации
Функция 04h записывает в буфер имя файла, содержащего библиографическую документацию компакт-диска, установленного в устройстве чтения CD-ROM:
Регистры на входе: | AX = 1504h;
ES:BX = адрес буфера размером 38 байт CX = номер устройства чтения CD-ROM | ||
Регистры на выходе: | CY = 1 при ошибке в номере устройства чтения CD-ROM;
AX = код ошибки |
Функция может вернуть в выходном буфере пустую строку, состоящую из одного нулевого байта.
Получение имени файла прав собственности
Функция 02h записывает в буфер имя файла, содержащего права собственности на компакт-диск, установленный в устройстве чтения CD-ROM:
Регистры на входе: | AX = 1502h;
ES:BX = адрес буфера размером 38 байт CX = номер устройства чтения CD-ROM | ||
Регистры на выходе: | CY = 1 при ошибке в номере устройства чтения CD-ROM;
AX = код ошибки |
Функция может вернуть в выходном буфере пустую строку, состоящую из одного нулевого байта.
Получение имени файла резюме
Функция 03h записывает в буфер имя файла, содержащего резюме компакт-диска, установленного в устройстве чтения CD-ROM:
Регистры на входе: | AX = 1503h;
ES:BX = адрес буфера размером 38 байт CX = номер устройства чтения CD-ROM | ||
Регистры на выходе: | CY = 1 при ошибке в номере устройства чтения CD-ROM;
AX = код ошибки |
Функция может вернуть в выходном буфере пустую строку, состоящую из одного нулевого байта.
Получение информации о дорожке компакт-диска
// ---------------
// Код функции 11
// ---------------
#pragma pack(1)
typedef struct _TrackInfo
{
BYTE bFunctionCode;
BYTE bTrack;
DWORD dwLoc;
BYTE bInfo;
} TrackInfo;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bTrack | Номер дорожки | ||
dwLoc | Первый сектор дорожки | ||
bInfo | Формат дорожки |
Старшая тетрада формата дорожки имеет следующий формат:
Значение | Описание | ||
00*0 | Два звуковых канала без предискажений | ||
00*1 | Два звуковых канала с предискажениями | ||
10*1 | Четыре звуковых канала без предискажений | ||
10*0 | Четыре звуковых канала с предискажениями | ||
01*0 | Дорожка с данными | ||
01*1 | Зарезервировано | ||
11** | Зарезервировано | ||
**0* | Копирование дорожки запрещено | ||
**1* | Копирование дорожки разрешено |
Состояние бита, отмеченного символом *, значения не имеет.
Младшая тетрада формата дорожки содержит тип режима ADR, описанного в Redbook.
Получение информации о канале Q
// ---------------
// Код функции 12
// ---------------
#pragma pack(1)
typedef struct _QInfo
{
BYTE bFunctionCode;
BYTE bCtrlAndARD;
BYTE bTrackNumb;
BYTE bIndex;
BYTE bMin;
BYTE bSec;
BYTE bFrame;
BYTE bRunningTime;
BYTE bAminOrPmin;
BYTE bAsecOrPsec;
BYTE bAframeOrPframe;
} QInfo;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bCtrlAndARD | Формат дорожки | ||
bTrackNumb | Номер дорожки | ||
bIndex | Текущее время, которое прошло с начала проигрывания дорожки | ||
bMin | Компонента MIN адреса дорожки | ||
bSec | Компонента SEC адреса дорожки | ||
bFrame | Компонента FRAME адреса дорожки | ||
bRunningTime | Общее время проигрывания диска | ||
bAminOrPmin | Значение AMIN или PMIN | ||
bAsecOrPsec | Значение ASEC или PSEC | ||
bAframeOrPframe | Значение AFRAME или PFRAME |
Получение информации о компакт-диске
// ---------------
// Код функции 10
// ---------------
#pragma pack(1)
typedef struct _DiskInfo
{
BYTE bFunctionCode;
BYTE bLowest;
BYTE bHighest;
DWORD dwTotal;
} DiskInfo;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bLowest | Номер первой дорожки | ||
bHighest | Номер последней дорожки | ||
dwTotal | Адрес дорожки Lead-out |
Получение информации о подканале
// ---------------
// Код функции 13
// ---------------
#pragma pack(1)
typedef struct _QInfo
{
BYTE bFunctionCode;
DWORD dwStartSector;
DWORD dwTransferAddress;
DWORD dwNumberOfSectors;
} QInfo;
Поле | Описание | ||
bFunctionCode | Код функции | ||
dwStartSector | Адрес начального сектора | ||
dwTransferAddress | Адрес в оперативной памяти, по которому будет скопирована информация из подканала | ||
dwNumberOfSectors | Количество секторов, которые необходимо скопировать |
Получение информации о звуковых каналах
// ---------------
// Код функции 4
// ---------------
#pragma pack(1)
typedef struct _ChanInfo
{
BYTE bFunctionCode;
BYTE bInpChannel0;
BYTE bVolControl0;
BYTE bInpChannel1;
BYTE bVolControl1;
BYTE bInpChannel2;
BYTE bVolControl2;
BYTE bInpChannel3;
BYTE bVolControl3;
} ChanInfo;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bInpChannel0 | Номер входного канала, присвоенного выходному каналу 0. По умолчанию равно 0 | ||
bVolControl0 | Уровень громкости для канала 0. По умолчанию равно 0FFh | ||
bInpChannel1 | Номер входного канала, присвоенного выходному каналу 1. По умолчанию равно 1 | ||
bVolControl1 | Уровень громкости для канала 1. По умолчанию равно 0FFh | ||
bInpChannel2 | Номер входного канала, присвоенного выходному каналу 2. По умолчанию равно 2 | ||
bVolControl2 | Уровень громкости для канала 2. По умолчанию равно 0FFh | ||
bInpChannel3 | Номер входного канала, присвоенного выходному каналу 3. По умолчанию равно 3 | ||
bVolControl3 | Уровень громкости для канала 3. По умолчанию равно 0FFh |
Получение штрих-кода изготовителя компакт-диска
// ---------------
// Код функции 14
// ---------------
#pragma pack(1)
typedef struct _UPCCode
{
BYTE bFunctionCode;
BYTE bCtrlAndARD;
BYTE bUPCCode[7];
BYTE bZero;
BYTE bAFrame;
} UPCCode;
Поле | Описание | ||
bFunctionCode | Код функции | ||
bCtrlAndARD | Формат дорожек | ||
bUPCCode | Штрих-код | ||
bZero | Равно 0 | ||
bAFrame | Значение AFRAME |
Получение состояния переключающих клавиш
Функция 02h возвращает в регистре AL состояние переключающих клавиш, таких как <Shift>, <Control>, <Alt>, <ScrollLock>, <NumLock>, <CapsLock>, <Insert>:
Регистры на входе: | AH = 02h | ||
Регистры на выходе: | AL = Байт состояния переключающих клавиш |
Формат байта состояния соответствует формату байта, находящегося в области данных BIOS по адресу 0000h:0417h:
Биты | Описание | ||
0 | Нажата правая клавиша <Shift> | ||
1 | Нажата левая клавиша <Shift> | ||
2 | Нажата комбинация клавиш <Control+Shift> с левой или правой стороны | ||
3 | Нажата комбинация клавиш <Alt+Shift> с левой или правой стороны | ||
4 | Состояние клавиши <ScrollLock> | ||
5 | Состояние клавиши <NumLock> | ||
6 | Состояние клавиши <CapsLock> | ||
7 | Состояние клавиши <Insert> |
Функция 02h может быть использована для анализа текущего состояния переключающих клавиш.
Ниже показан фрагмент кода, в котором проверяется состояние клавиши <CapsLock>:
rg.h.ah = 2;
int86(0x16, &rg, &rg);
if((rg.h.al & 0x40) == 0)
{
// Клавиша <CapsLock> не нажата,
// соответствующий светодиод не горит
. . .
}
else
{
// Клавиша <CapsLock> нажата
. . .
}
Функция 12h возвращает в регистре AL состояние переключающих клавиш, таких как <Shift>, <Control>, <Alt>, <ScrollLock>, <NumLock>, <CapsLock>, <Insert> и используется только для 101-клавишных клавиатур:
Регистры на входе: | AH = 12h | ||
Регистры на выходе: | AL = Байт состояния переключающих клавиш |
Эта функция определена для BIOS, изготовленной после 15 декабря 1985 года.
Получение списка устройств CD-ROM
С помощью функции 01h вы можете получить список структур CD_ROM_Driver_Desc, описывающих установленные устройства CD-ROM:
Регистры на входе: | AX = 1501h;
ES:BX = адрес буфера, в который будет скопирован список устройств CD-ROM | ||
Регистры на выходе: | Не используются |
Первый байт такой структуры содержит номер устройства (unit nubmer), следом за которым идут четыре байта адреса заголовка драйвера, обслуживающего данное устройство:
typedef struct _CD_ROM_Driver_Desc
{
unsigned char cSubUnit;
unsigned long dwDevHeader;
} CD_ROM_Driver_Desc;
Перед вызовом этой функции необходимо подготовить буфер достаточного размера. Размер буфера нетрудно определить, узнав предварительно количество устройств CD-ROM, установленных в системе, с помощью функции 00h. Для каждого устройства в буфере требуется пять байт оперативной памяти.
Получить адрес альтернативного драйвера событий
Функция 19h предназначена для получения адреса драйвера событий с заданной маской событий. Получив адрес, вы можете установить новый драйвер, использующий эту же маску.
Регистры на входе: | AX = 0019h
CX = маска событий, для которой требуется получить адрес драйвера | ||
Регистры на выходе: | CX = маска событий или 0000h, если заданной маске не соответствует ни один установленный драйвер событий;
ES:DX = адрес драйвера событий, использующий заданную маску событий |
Получить блок EMB
Регистры на входе: | AH = 09h
DX = размер требуемого блока, Кбайт | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка;
DX = 16-разрядный идентификатор (handle) полученного блока EMB | ||
Ошибки: | BL = 80h, 81h, A0h, A1h |
Функция заказывает блок EMB из пула свободной расширенной памяти. При успешном выполнении запроса функция возвращает идентификатор полученного блока, который должен использоваться программой для выполнения всех операций с блоком EMB. Если блок EMB программе больше не нужен, она должна освободить его с помощью функции 0Ah.
Количество блоков EMB, которое может быть заказано, определяется в командной строке драйвера HIMEM.SYS параметром /NUMHANDLES=. Значение по умолчанию - 32, максимальное значение - 128.
Получить информацию об идентификаторе блока EMB
Регистры на входе: | AH = 0Eh
DX = идентификатор блока EMB | ||
Регистры на выходе: | AX = 0001h - если функция выполнена успешно, 0000h - если произошла ошибка;
BH = содержимое счетчика блокировок EMB; BL = количество свободных идентификаторов блоков EMB в системе; DX = размер блока, Кбайт | ||
Ошибки: | BL = 80h, 81h, A2h |
Эта функция используется для получения различной информации об используемых блоках EMB. Линейный адрес блока может быть получен с помощью фунции 0Ch.
Получить версию XMS
Регистры на входе: | AH = 00h | ||
Регистры на выходе: | BX = номер внутренней модификации драйвера;
DX = 0001h - если существует область HMA, DX = 0000h - если область HMA не существует |
Функция возвращает номера версии и модификации XMS в двоично-десятичном (BCD) формате. Например, если AX=0250h, это означает, что драйвер соответствует спецификации XMS версии 2.50. Дополнительно функция позволяет проверить наличие в системе области HMA.
Порт 0Ah
Регистр маски. Применяется для маскирования запросов на прямой доступ для отдельных каналов:
Поле | Описание | ||
0-1 | Номер канала:
00 – канал 0; 01 – канал 1 10 – канал 2; 11 – канал 3 | ||
2 | 0 - установить маску;
1 - сбросить маску | ||
3-7 | Не используются |
Порт 0Bh
Регистр режима. Служит для определения режимов работы каналов контроллера DMA:
Поле | Описание | ||
0-1 | Номер канала:
00 – канал 0; 01 – канал 1 10 – канал 2; 11 – канал 3 | ||
2-3 | Тип цикла DMA:
00 - цикл проверки; 01 - цикл записи; 10 - цикл чтения; 11 - запрещенная комбинация | ||
4 | 1 - режим автоинициализации | ||
5 | Приращение адреса:
0 - инкрементирование; 1 – декрементирование | ||
6-7 | Режим обслуживания:
00 - передача по требованию; 01 - одиночная передача; 10 – передача по блокам; 11 - каскадироание |
Порт 0Ch
Сброс триггера байтов. Для загрузки внутренних 16-разрядных регистров контроллера используется последовательный вывод младшего, затем старшего байтов слова. После сброса триггера байтов можно начинать загрузку 16-разрядных регистров.
Порт 0Dh
Запись в этот порт вызывает сброс контроллера. Для дальнейшего использования контроллер должен быть заново проинициализирован.
Порт 0Eh
Сброс регистра маски. После записи в этот регистр любого значения разрешается работа всех четырех каналов прямого доступа.
Порт 0Fh
Маскирование или размаскирование каналов. С помощью этого порта можно выполнить одновременное маскирование или размаскирование нескольких каналов:
Поле | Описание | ||
0 | 1 - маскирование канала 0;
0 - разрешение канала 0 | ||
1 | 1 - маскирование канала 1;
0 - разрешение канала 1 | ||
2 | 1 - маскирование канала 2;
0 - разрешение канала 2 | ||
3 | 1 - маскирование канала 3;
0 - разрешение канала 3 | ||
4-7 | Не используются |
Порт 3F8h
Порт 3F8h соответствует регистру данных. Для передачи необходимо записать в этот порт передаваемый байт данных. После приема данных от внешнего устройства они могут быть прочитаны порта 3F8h.
В зависимости от состояния старшего бита управляющего слова, записываемого в управляющий регистр с адресом 3FBh, назначение порта 3F8h может изменяться. Если этот бит сброшен, порт используется для записи передаваемых данных. Если же бит установлен, порт используется для вывода значения младшего байта делителя частоты тактового генератора.
Изменяя содержимое делителя, можно изменять скорость передачи данных. Старший байт делителя записывается в порт 3F9h.
Зависимость скорости передачи данных от значения делителя частоты представлена ниже:
Делитель | Скорость передачи в бодах | ||
1040 | 110 | ||
768 | 150 | ||
384 | 300 | ||
192 | 600 | ||
96 | 1200 | ||
48 | 2400 | ||
24 | 4800 | ||
12 | 9600 | ||
6 | 19200 | ||
3 | 38400 | ||
2 | 57600 | ||
1 | 115200 |
Порт 3F9h
Порт 3F9h используется либо как регистр управления прерываниями от асинхронного адаптера либо (после вывода в порт 3F9h байта с установленным старшим битом) для вывода значения старшего байта делителя частоты тактового генератора.
В режиме регистра управления прерываниями порт имеет следующий формат:
Поле | Описание | ||
0 | Разрешение прерывания при готовности принимаемых данных | ||
1 | Разрешение прерывания после передачи байта, когда выходной буфер передачи пуст | ||
2 | Разрешение прерывания по обнаружению состояния BREAK или при возникновении ошибке | ||
3 | Разрешение прерывания по изменению состояния входных линий на разъеме RS232-C (CTS, DSR, RI, DCD) | ||
4-7 | Не используются, должны быть равны 0 |
Порт 3FAh
Порт 3FAh представляет собой регистр идентификации прерывания. Считывая его содержимое, программа может определить причину прерывания.
Формат регистра:
Поле | Описание | ||
0 | 1 - Нет прерываний, ожидающих обслуживания | ||
1-2 | 00 - Прерывание по линии состояния приемника, возникает при переполнении приемника, ошибках четности или формата данных или при состоянии "BREAK". Сбрасывается после чтения состояния линии из порта 3FDh;
01 - Данные приняты и доступны для чтения. Сбрасывается после чтения данных из порта 3F8h; 10 - Буфер передатчика пуст. Сбрасывается при записи новых данных в регистр данных передатчика, порт 3F8h; 11 - Состояние модема. Устанавливается при изменении состояния входных линий CTS, RI, DCD, DSR. Сбрасывается после чтения состояния модема из порта 3FEh | ||
3-7 | Должно быть равно 0 |
Порт 3FBh
Порт 3FBh – это управляющий регистр, доступен по записи и чтению.
Формат регистра:
Поле | Описание | ||
0-1 | Длина слова в битах:
00 - 5 бит; 01 - 6 бит; 10 - 7 бит; 11 - 8 бит | ||
2 | Количество стоповых бит:
0 - 1 бит; 1 - 2 бита | ||
3-4 | Четность:
X0 - контроль на четность не используется; 01 - контроль на нечетность; 11 - контроль на четность | ||
5 | Фиксация четности. При установке этого бита бит четности всегда принимает значение 0 (если биты 3-4 равны 11) или 1 (если биты 3-4 равны 01) | ||
6 | Установка перерыва. Вызывает вывод строки нулей в качестве сигнала BREAK для подключенного устройства | ||
7 | 1 - порты 3F8h и 3F9h используются для для загрузки делителя частоты тактового генератора;
0 - порты используются как обычно |
Порт 3FCh
Порт 3FCh – это регистр управления модемом. Управляет состоянием выходных линий DTR, RTS, линий, специфических для модемов OUT1 и OUT2, для запуска диагностики.
Формат порта:
Поле | Описание | ||
0 | Линия DTR | ||
1 | Линия RTS | ||
2 | Линия OUT1 (запасная) | ||
3 | Линия OUT2 (запасная) | ||
4 | Запуск диагностики при входе асинхронного адаптера, замкнутом на его выход | ||
5-7 | Должно быть равно 0 |
Порт 3FDh
Порт 3FDh представляет собой регистр состояния линии.
Формат порта:
Поле | Описание | ||
0 | Данные получены и готовы для чтения. Сбрасывается при чтении данных | ||
1 | Ошибка переполнения. Был принят новый байт данных, а предыдущий еще не был считан программой. Предыдущий байт потерян | ||
2 | Ошибка четности. Сбрасывается после чтения состояния линии | ||
3 | Ошибка синхронизации | ||
4 | Обнаружен запрос на прерывание передачи BREAK: длинная строка нулей | ||
5 | Регистр хранения передатчика пуст, в него можно записывать новый байт для передачи | ||
6 | Регистр сдвига передатчика пуст. Этот регистр получает данные из регистра хранения и преобразует их в последовательный вид для передачи | ||
7 | Истекло время ожидания |
Порт 3FEh
Порт 3FEh представляет собой регистр состояния модема.
Поле | Описание | ||
0 | Линия CTS изменила состояние | ||
1 | Линия DSR изменила состояние | ||
2 | Линия RI изменила состояние | ||
3 | Линия DCD изменила состояние | ||
4 | Состояние линии CTS | ||
5 | Состояние линии DSR | ||
6 | Состояние линии RI | ||
7 | Состояние линии DCD |