- •Аннотация
 - •Введение
 - •Благодарности
 - •Авторский компакт-диск
 - •Как связаться с авторами
 - •1 Определение конфигурации компьютера
 - •Определение конфигурации с помощьюBios
 - •Наличие нмд
 - •Наличие арифметического сопроцессора
 - •Начальный режим работы видеоадаптера
 - •Стандартная оперативная память
 - •Расширенная оперативная память
 - •ПрограммаHdwcfg
 - •Код модели компьютера и версияBios
 - •ПрограммаBiosinfo
 - •Конфигурация в памяти cmos
 - •00H - 0Dh - область часов реального времени
 - •0Eh - байт диагностики
 - •0Fh - байт отключения
 - •10H - тип накопителей нгмд
 - •11H - зарезервировано дляIbm pc/at, тип нмд дляIbm ps/2
 - •12H - тип первого и второго нмд
 - •13H - зарезервировано
 - •14H - конфигурация оборудования
 - •15H-16h - объем стандартной оперативной памяти
 - •ПрограммаCmosshow
 - •Определение типа центрального процессора
 - •МоделиIntel 8086/8088
 - •Модель Intel 80286
 - •МодельIntel 80386
 - •МодельIntel 80486
 - •Команда cpuid
 - •ПрограммаCpuinfo
 - •2 Клавиатура
 - •Как работает клавиатура
 - •Клавиатурная матрица
 - •Скан-код клавиши
 - •КодAscii нажатой клавиши
 - •Режим автоповтора
 - •Типы клавиатур
 - •Порты для работы с клавиатурой
 - •КомпьютерIbm pc/xt
 - •Современные компьютеры
 - •ПрограммаKbdled
 - •Аппаратное прерывание клавиатуры
 - •Стандартный обработчик прерывания int 09h
 - •Буфер клавиатуры
 - •Переключающие клавиши
 - •Средства bios для работы с клавиатурой
 - •Чтение символа с ожиданием
 - •ПрограммаKbdscan
 - •Проверка буфера на наличие в нем символов
 - •ПрограммаChkbuf
 - •Получение состояния переключающих клавиш
 - •Установка временных характеристик клавиатуры
 - •Запись символов в буфер клавиатуры
 - •Чтение символа с ожиданием для 101-клавишной клавиатуры
 - •Проверка буфера на наличие в нем символов для 101-клавишной клавиатуры
 - •Получение состояния переключающих клавиш для 101-клавишной клавиатуры
 - •Режимы работы клавиатуры
 - •Сравнение режимов
 - •Изменение режима
 - •Средства ms-dos для работы с клавиатурой
 - •Буферизованный ввод с эхо-выводом
 - •Буферизованный ввод без эхо-вывода
 - •Нефильтрованный ввод без эхо-вывода
 - •Вводс консоли и вывод на консоль
 - •Ввод строки символов
 - •Проверка состояния стандартного ввода
 - •Сброс буфера клавиатуры
 - •Клавиатурные функции стандартной библиотеки c
 - •Функции getch и getche
 - •ПрограммаKbdascii
 - •Функцияkbhit
 - •ПрограммаKbdhit
 - •Функция cgets
 - •Функция gets
 - •Функция scanf
 - •Как устроена мышь?
 - •Драйверы мыши в ms-dos
 - •Прерывание для обслуживания мыши
 - •Инициализация мыши
 - •Включить курсор мыши
 - •Выключить курсор мыши
 - •ПрограммаMscursor
 - •Определить положение курсора
 - •ПрограммаMsgcurs
 - •Установить курсор
 - •Определить положение курсора при нажатии клавиши
 - •Определить положение курсора при отпускании клавиши
 - •Задать диапазон движения курсора по горизонтали
 - •Задать диапазон движения курсора по вертикали
 - •Задать форму курсора в графическом режиме
 - •ПрограммаMsgform
 - •Задать форму курсора в текстовом режиме
 - •ПрограммаMstform
 - •Определить содержимое счетчиков перемещения
 - •Установить драйвер событий
 - •ПрограммаMsdriver
 - •Включить эмуляцию светового пера
 - •Выключить эмуляцию светового пера
 - •Задать скорость перемещения курсора мыши
 - •Установить область исключения для курсора
 - •Задать увеличенный графический курсор
 - •Определить порог удвоения скорости
 - •Заменить драйвер событий
 - •Определить размер буфера состояния драйвера
 - •Сохранить состояние драйвера
 - •Восстановить состояние драйвера
 - •Установить альтернативный драйвер событий
 - •Получить адрес альтернативного драйвера событий
 - •Установить чувствительность мыши
 - •Определить чувствительность мыши
 - •Установить частоту прерываний для Inport Mouse
 - •Установить номер страницы видеопамяти
 - •Определить номер страницы видеопамяти
 - •Отключить драйвер мыши
 - •Восстановить драйвер мыши
 - •Сбросить драйвер мыши
 - •Определить тип мыши
 - •МышьMicrosoft IntelliMouse
 - •Проверка наличия мыши Microsoft IntelliMouse
 - •Проверка в среде Microsoft Windows 95 и Microsoft Windows nt версии 3.51
 - •Проверка в среде Microsoft Windows nt версии 4.0
 - •Определение величины свертки
 - •Определение величины свертки в среде Microsoft Windows 95 и Microsoft Windows nt версии 3.51
 - •Определение величины свертки в среде Microsoft Windows nt версии 4.0
 - •Сообщение msh_mousewheel
 - •Сообщение wm_mousewheel
 - •Другие сообщения от мыши Microsoft IntelliMouse
 - •ПриложениеRtfpad
 - •4 Часы реального времени
 - •Регистры часов реального времени
 - •Регистры счетчиков
 - •Регистр состоянияA
 - •Регистр состояния b
 - •Регистр состояния c
 - •Регистр состояния d
 - •Прерывание от часов реального времени
 - •Функции прерыванияInt 1Ah
 - •Сброс будильника
 - •ПрограммаRtcalarm
 - •5 Системный таймер
 - •Обработка прерываний таймера
 - •Микросхемы таймера 8253 и 8254
 - •Режимы работы таймера
 - •Режим однократного выполнения функций
 - •Работа с перезапуском
 - •Формат управляющего регистра
 - •Формат команды чтения слова состояния канала
 - •Формат слова состояния канала
 - •Последовательность действий
 - •ПрограммаTimerst
 - •Средства bios для работы с таймером
 - •Чтение счетчика таймера
 - •Установка счетчика таймера
 - •Установка таймера с сигнализацией
 - •Формирование задержки
 - •Второй способ проигрывания музыки
 - •Проигрывание музыки в фоновом режиме
 - •ПрограммаTmsound
 - •ПрограммаIosound
 - •ПрограммаRandom
 - •6 Асинхронный последовательный адаптер
 - •Основные понятия и термины
 - •Аппаратная реализация
 - •МикросхемаUart
 - •Разъемы адаптера
 - •Порты асинхронного адаптера
 - •Порт 3f8h
 - •Порт 3f9h
 - •Порт 3fAh
 - •Порт 3fBh
 - •Порт 3fCh
 - •Порт 3fDh
 - •Порт 3fEh
 - •Функции bios для работы с последовательным асинхронным адаптером
 - •Инииализация портов асинхронного адаптера
 - •Передача байта
 - •Прием байта
 - •Определение состояния асинхронного адаптера
 - •Программирование асинхронного адаптера
 - •Инициализация асинхронного адаптера
 - •Передача данных
 - •Прием данных
 - •ПрограммаComtest
 - •Использование прерываний
 - •7 Параллельный адаптер
 - •Порты параллельного адаптера
 - •Порт 378h
 - •Порт 37Ah
 - •Порт 379h
 - •Разъем параллельного адаптера
 - •Вывод байта на принтер через параллельный адаптер
 - •Функции bios для работы с принтером
 - •Печать символа
 - •Инициализация принтера
 - •Определение состояния принтера
 - •ПрограммаPrintfl
 - •Функции ms-dos для работы с принтером
 - •ФункцияMs-dos для вывода на принтер
 - •Система буферизованной печати
 - •Проверка установки системы буферизованной печати
 - •Запуск процесса печати файла
 - •Отмена печати файла
 - •Отмена печати всех файлов
 - •Определение состояния и блокировка системы буферизованной печати
 - •Разблокирование системы буферизованной печати
 - •Коды ошибок
 - •Программирование принтера
 - •Подключение принтера к компьютеру
 - •Установка переключателей конфигурации
 - •Программирование режимов работы принтера
 - •Инициализация принтера
 - •Контроллер прямого доступа ibm pc/xt
 - •Регистры каналов dma
 - •Порты 00h - 07h
 - •Порт 08h
 - •Порт 09h
 - •Порт 0Ah
 - •Порт 0Bh
 - •Порт 0Ch
 - •Порт 0Dh
 - •Порт 0Eh
 - •Порт 0Fh
 - •Порты 81h-8Fh
 - •Инициализация канала dma
 - •Контроллер прямого доступа ibm at
 - •Регистры каналовDma
 - •Регистры страниц
 - •Порты 0c0h - 0dFh
 - •Порты 0d0h-0dFh
 - •9 Устройство чтения cd-rom
 - •Драйвер устройства чтенияCd-rom
 - •РасширениеMscdex
 - •ФункцииMscdex
 - •Определение количества устройствCd-rom
 - •Получение списка устройств cd-rom
 - •Получение имени файла прав собственности
 - •Получение имени файла резюме
 - •Получение имени файла библиографической документации
 - •Чтение сектора оглавления компакт-диска
 - •Чтение сектора по абсолютному адресу
 - •Проверка устройства чтения cd-rom
 - •Определение версии mscdex
 - •Определение обозначения устройств чтения cd-rom
 - •Вызов драйвера cd-rom
 - •Работа через драйверCd-rom
 - •Заголовок запроса
 - •Команды драйвера cd-rom
 - •Инициализация
 - •ЧтениеIoctl Input
 - •Определение адреса заголовка драйвера cd-rom
 - •Определение положения головки
 - •Получение информации о звуковых каналах
 - •Чтение данных из устройства
 - •Определение состояния устройства
 - •Определение размера сектора
 - •Определение размера тома
 - •Проверка замены носителя данных
 - •Получение информации о компакт-диске
 - •Получение информации о дорожкекомпакт-диска
 - •Получение информации о канале q
 - •Получение информации о подканале
 - •Получение штрих-кода изготовителя компакт-диска
 - •Сброс входных буферов
 - •ЗаписьIoctl Output
 - •Извлечение компакт-диска
 - •Блокирование и разблокирование компакт-диска в устройстве
 - •Сброс устройства чтения cd-rom
 - •Управление звуковыми каналами
 - •Запись в устройство управляющей строки
 - •Чтение длинное с предварительной выборкой
 - •Проигрывание звуковой дорожки
 - •Остановка проигрывания звуковой дорожки
 - •Возобновление проигрывания звуковой дорожки
 - •ПрограммаCdinfo
 - •ПрограммаCdplay
 - •10 Арифметический сопроцессор
 - •Вещественные числа
 - •Целые числа
 - •Регистры сопроцессора
 - •Численные регистры
 - •Регистр тегов
 - •Регистр управления
 - •Регистр состояния
 - •Регистры указателя команды и указателя операнда
 - •Система команд сопроцессора
 - •Команды пересылки данных
 - •Запись в стек
 - •Извлечение из стека
 - •Копирование данных
 - •Загрузка констант
 - •Арифметические команды
 - •Команды сравнений чисел
 - •Трансцендентные команды
 - •Управляющие команды
 - •Программирование сопроцессора
 - •ПрограммаNpu1
 - •Обработка особых случаев
 - •Неточный результат
 - •Переполнение
 - •Антипереполнение
 - •Деление на нуль
 - •Недействительная операция
 - •Денормализованный операнд
 - •Ошибка в процессореPentium
 - •11 Расширенная память
 - •Основные понятия
 - •Установка драйвера himem.Sys
 - •Спецификация xms
 - •Проверка подключения драйвера
 - •Получение адреса управляющей программы
 - •Описание функций драйвера himem.Sys
 - •Получить версию xms
 - •Запросить область hma
 - •Освободить область hma
 - •Глобальное открывание линии a20
 - •Глобальное закрывание линии a20
 - •Освободить блок emb
 - •Копирование блоков emb
 - •Блокирование emb
 - •Разблокирование emb
 - •Получить информацию об идентификаторе блока emb
 - •Изменить размер emb
 - •Запросить область umb
 - •Освободить область umb
 - •Коды ошибок
 - •Ограничения при использовании области hma
 - •Примеры программ
 - •ПрограммаTesthma
 - •ПрограммаCallhma
 - •Предметный указатель
 - •Литература
 - •Оглавление
 - •1 Определение конфигурации компьютера 7
 - •2 Клавиатура 38
 - •3 Мышь 64
 - •4 Часы реального времени 102
 - •5 Системный таймер 113
 - •6 Асинхронный последовательный адаптер 132
 - •7 Параллельный адаптер 149
 - •8 Контроллер прямого доступа к памяти 162
 - •9 Устройство чтения cd-rom 170
 - •10 Арифметический сопроцессор 216
 - •11 Расширенная память 243
 
Установить драйвер событий
Функция 0Ch позволяет программе создать свой собственный драйвер (обработчик) событий, связанных с перемещением мыши, а также с нажатием или отпусканием клавиш мыши.
| 
			 Регистры на входе:  | 
			 AX = 000Ch CX = маска вызова; ES:DX = адрес подключаемого драйвера событий  | 
| 
			 Регистры на выходе:  | 
			 Регистры не используются  | 
Биты маски вызова, передаваемой функции в регистре CX,определяют условие вызова драйвера событий:
| 
				 Бит маски вызова  | 
				 Когда выполняется вызов  | 
| 
				 0  | 
				 Перемещение мыши  | 
| 
				 1  | 
				 Нажатие левой клавиши  | 
| 
				 2  | 
				 Отпускание левой клавиши  | 
| 
				 3  | 
				 Нажатие правой клавиши  | 
| 
				 4  | 
				 Отпускание правой клавиши  | 
| 
				 5  | 
				 Нажатие средней клавиши  | 
| 
				 6  | 
				 Отпускание средней клавиши  | 
Если записать в регистр CX значение 7Fh, драйвер будет вызываться при возникновении любого события, а если 00h – драйвер будет отключен.
Адрес процедуры драйвера передается при вызове функции в регистровой паре ES:DX. Драйвер должен быть оформлен в виде процедуры типа FAR, завершающейся командой дальнего возврата RETF.
Когда драйвер получает управление, в регистрах процессора содержатся следующие значения:
| 
				 Регистр  | 
				 Описание  | 
| 
				 AX  | 
				 Маска вызова, такая же, как и при вызове функции 0Ch  | 
| 
				 BX  | 
				 Состояние клавиш мыши: бит 0 - левая клавиша; бит 1 - правая клавиша; бит 2 - средняя клавиша  | 
| 
				 CX  | 
				 Координата X курсора мыши  | 
| 
				 DX  | 
				 Координата Y курсора мыши  | 
| 
				 SI  | 
				 Относительное перемещение мыши по горизонтали в миках  | 
| 
				 DI  | 
				 Относительное перемещение мыши по вертикалив миках  | 
| 
				 DS  | 
				 Сегмент данных драйвера мыши  | 
Так как регистр DS при вызове драйвера событий содержит сегмент данных драйвера мыши, ваш драйвер событий должен позаботиться о правильной установке этого регистра. Однако драйвер событий не обязан сохранять и восстанавливать содержимое регистра DS и других регистров процессора.
Отметим, что если вам необходимо отключить драйвер, выполните повторный вызов функции 0Ch, записав в регистр CX нулевое значение. Если ваша программа, устанавливающая собственный драйвер событий, завершает свою работу и передает управление MS-DOS, предварительно она обязательно должна отключить драйвер событий.
Составление программы драйвера событий имеет некоторые особенности. Драйвер событий вызывается не из программы пользователя, а из драйвера мыши. При этом сегментный регистр DS будет указывать на сегмент данных драйвера мыши, а не на сегмент данных вашей программы.
Драйвер событий может также организовать очередь событий, записывая в эту очередь состояние мыши на момент появления события и время появления события. Прикладная программа будет затем извлекать события из очереди и анализировать их.
ПрограммаMsdriver
Программа MSDRIVER иллюстрирует способ работы с драйвером событий.
Исходный текст драйвера событий, составленный на языке ассемблера, представлен в листинге 3.5.
Листинг 3.5. Файлmsdriver\handler.asm
;**
;.Name ms_handl
;.Title Драйвер событий
;
;.Descr Драйвер событий вызывается драйвером мыши,
; когда происходит какое-нибудь событие из числа
; заданных при установке драйвера событий.
; Функция не должна вызываться из программы
; пользователя, ее вызывает только драйвер мыши.
;
;.Proto void far ms_handl(void);
;
;.Params Не используются
;**
DOSSEG
DGROUP GROUP _DATA
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'CODE'
ASSUME cs:_TEXT, ds:DGROUP, ss:DGROUP
; Флаг вызова драйвера событий
extrn _ms_flag:word
; Внешние переменные для записи содержимого регистров
extrn _ms_bx:word
extrn _ms_cx:word
extrn _ms_dx:word
extrn _ms_si:word
extrn _ms_di:word
extrn _ms_ds:word
public _ms_handl
_ms_handl proc far
mov _ms_ds, ds
; Так как на входе в драйвер событий регистр DS указывает на
; сегмент данных драйвера мыши, устанавливаем его на сегмент
; данных программы;
push ax
mov ax, DGROUP
mov ds, ax
pop ax
mov _ms_bx, bx
mov _ms_cx, cx
mov _ms_dx, dx
mov _ms_si, si
mov _ms_di, di
; Устанавливаем флаг вызова драйвера в 1, сигнализируя
; программе о том, что произошло событие.
mov _ms_flag, 1
ret
_ms_handl endp
_TEXT ENDS
END
При вызове этот драйвер вызове устанавливает глобальную переменную _ms_flag в единицу, затем переписывает содержимое всех нужных регистров в соответствующие глобальные переменные.
Программа, установив драйвер событий и сбросив флаг _ms_flag, может выполнять какие-либо действия (например, вывод на экран движущегося изображения), постоянно проверяя флаг _ms_flag. Как только произойдет какое-либо событие (нажатие или отпускание клавиши мыши, перемещение мыши) драйвер событий установит флаг в единицу. Программа при этом может узнать состояние мыши, прочитав содержимое глобальных переменных _ms_bx, _ms_dx, и т.д.
Исходный текст программы MSDRIVERпредставлен в листинге 3.6.
Листинг 3.6. Файлmsdriver\msdriver.с
// =====================================================
// Работа с драйвером событий
//
// (C) Фролов А.В, 1997
//
// E-mail: frolov@glas.apc.org
// WWW: http://www.glasnet.ru/~frolov
// или
// http://www.dials.ccas.ru/frolov
// =====================================================
#include <dos.h>
#include <stdio.h>
#include <conio.h>
union REGS reg;
struct SREGS segregs;
extern void far MS_HANDL(void);
void ms_seth(int mask, void (far *hand)());
// Флаг драйвера событий. При вызове драйвер событий
// запишет в эту переменную значение 1
unsigned MS_FLAG;
// Область для содержимого регистров на входе
// в драйвер событий.
unsigned MS_BX;
unsigned MS_CX;
unsigned MS_DX;
unsigned MS_SI;
unsigned MS_DI;
unsigned MS_DS;
int main (void)
{
MS_FLAG=0;
// Инициализируем мышь
reg.x.ax = 0;
int86(0x33, ®, ®);
if(reg.x.bx == 0)
{
printf("Mouse not found\n");
return -1;
}
// Подключаем драйвер событий, устанавливаем маску таким
// образом, чтобы драйвер вызывался при нажатии на левую
// или правую клавиши мыши
ms_seth(2 | 8, MS_HANDL);
// Включаем курсор
reg.x.ax = 1;
int86(0x33, ®, ®);
// Ожидаем вызова драйвера событий.
for(;;)
{
if(MS_FLAG)
{
printf("\nRegisters on driver entry:"
"\nms_bx: %0X"
"\nms_cx: %0X"
"\nms_dx: %0X"
"\nms_si: %0X"
"\nms_di: %0X"
"\nms_ds: %0X",
MS_BX, MS_CX, MS_DX, MS_SI, MS_DI, MS_DS);
printf("\nPress any key...");
getch();
return 0;
}
}
}
void ms_seth(int mask, void (far *hand)())
{
reg.x.ax = 0x14;
reg.x.cx = mask;
reg.x.dx = FP_OFF(hand);
segregs.es = FP_SEG(hand);
int86x(0x33,®,®,&segregs);
}
