EMM
Заранее спасибо.
Во-первых, как определить наличие в памяти драйвера EMM? Это можно сделать двумя способами
1. Открыть через функцию ДОС 3Dh файл с именем EMSXXXX0. Если не открывается, то EMM отсутствует. В противном случае нужно еще проверить, не является ли он действительно файлом, а не устройством. Это делается через функцию 44h (IOCTL) либо через подфункцию 0, возвращающую в бите 7 регистра DX 0 для файла и 1 для устройства, либо через подфункцию 7, которая вернет в AL 0 для файла и FFh для устройства. Этот способ рекомендует сама Microsoft, как надежный.
2. Извлечь вектор INT 67h - по смещению 0Ah от него должно стоять "EMSXXXX0". Этот способ не такой надежный, но работает быстрее.
Теперь о самом EMM. Доступ к нему идет через прерывание INT 67h, устанавливаемое драйвером EMS-памяти (EMM386, QEMM и т.п.). Для всех функций нужно в AH указать номер функции, в AL - номер подфункции (если нужно), в DX - номер логического сегмента (если нужно). После ее выполнения в AH будет код ошибки. Возможные значения этого кода
00h - ошибки нет, функция выполнена успешно
80h - внутренняя ошибка драйвера EMM
81h - аппаратный сбой памяти
82h - драйвер EMM занят
83h - неверный номер логического сегмента
84h - неверный номер функции
85h - нет свободных логических сегментов
86h - ошибка сохранения/восстановления карты памяти EMS
87h - запрошенное число страниц превышает объем памяти EMS
88h - запрошенное число страниц превышает число доступных в данный момент
89h - нулевое число страниц
8Ah - запрошенное число страниц превышает допустимое для данного логического сегмента
8Bh - неверный номер физической страницы
8Ch - переполнение области сохранения карты памяти EMS
8Dh - повторное сохранение карты памяти для одного и того же логического сегмента
8Eh - восстановление карты памяти без предварительного сохранения
8Fh - не определен параметр функции
90h - неопределенный тип атрибута
91h - не поддерживается драйвером
92h - часть области памяти перекрыта
93h - длина одной из областей памяти превосходит длину другой
94h - перекрытие областей основной и дополнительной памяти
95h - смещение внутри логической страницы больше ее длины
96h - длина области памяти более 1 Мбайта 97h - обе области памяти отображены в один сегмент и перекрываются
9Ah - заданный набор регистров не поддерживается
9Bh - все наборы регистров уже распределены
9Ch - нет альтернативных наборов регистров
9Dh - неопределенный и невыделенный набор регистров
A0h - нет логического сегмента с таким именем
A1h - такое имя логического сегмента уже есть
A2h - попытка перехода через границу 1 Мбайта основной памяти
A3h - массив испорчен
A4h - доступ запрещен операционной системой
Коды с номерами 90h - A4h используются только в EMS версии 4.0 и старше
Вся память EMS делится на страницы по 16 килобайт. Каждая программа может выделить для себя один или несколько логических сегментов памяти, состоящих из необходимого числа страниц (от 1 до 512). Одновременно выделяется физический сегмент памяти размером 64 килобайта, расположенный за пределами 640 килобайт основной памяти; на этот сегмент отображаются от 1 до 4 страниц.
Прерывание INT 67h имеет следующие функции
40h - вернуть в AH состояние EMM (код ошибки)
41h - вернуть в BX адрес физического сегмента
42h - вернуть общее число страниц (DX) и число свободных в данный момент страниц (BX)
43h - открыть логический сегмент размером (BX) страниц и вернуть его номер в (DX)
44h - отобразить страницу (BX) сегмента (DX) на физическую страницу (AL)
45h - удалить сегмент (DX) из памяти
46h - вернуть в AL номер версии EMS
47h - сохранить карту распределения страниц сегмента (DX)
48h - восстановить карту распределения страниц сегмента (DX)
4Bh - вернуть в BX число страниц сегмента (DX)
4Ch - вернуть в BX число открытых сегментов
4Dh - вернуть в BX число открытых сегментов
и в буфере по адресу ESDI информацию о них.
Буфер содержит (BX) элементов, состоящих из двух слов номер сегмента и число страниц
4Eh - операции с полной картой памяти; имеет четыре подфункции
0 - cохранить полную карту памяти по адресу ESDI
1 - прочитать полную карту памяти по адресу DSSI
2 - комбинация подфункций 0 и 1
3 - вернуть в AL размер карты памяти
4Fh - операции с частичной картой памяти; имеет три подфункции
0 - записать по адресу ESDI частичную карту памяти, то есть для сегментов, список которых находится по адресу DSSI
1 - прочитать частичную карту памяти по адресу DSSI
2 - вернуть в AL размер частичной карты памяти и в BX - количество сегментов в ней
50h - включить (AL=0) или выключить (AL=1) отображение массива страниц по адресу DSSI из (CX) элементов в сегмент (DX)
51h - изменить число страниц в сегменте (DX) на (BX) и вернуть в BX фактическое их число
52h - операции с атрибутом сегмента (может иметь значение 0/1, означающее, что номер сегмента можно/нельзя изменять); имеет три подфункции
0 - вернуть в AL атрибут сегмента (DX)
1 - задать новый атрибут сегмента (DX) из BL
2 - вернуть в AL максимально допустимый номер атрибута для сегмента (DX)
53h - операции с именами сегментов; имеет две подфункции
0 - запиcать имя сегмента (DX) по адресу ESDI
1 - прочитать новое имя сегмента (DX) по адресу DSSI
54h - операции с каталогом сегментов; имеет три подфункции
0 - записать каталог сегментов по адресу ESDI и вернуть в AL число сегментов в нем
1 - вернуть в DX номер сегмента с именем, записанным по адресу DSSI
2 - вернуть в BX число открытых сегментов
55h - для сегмента (DX) прочитать по адресу DSSI новую карту страниц и перейти на новую страницу (AL=0) или новый адрес (AL=1)
56h - для сегмента (DX) прочитать по адресу DSSI новую карту страниц и вызвать подпрограмму на новой странице (AL=0) или по новому адресу (AL=1), либо (AL=2) вернуть в BX необходимый размер стека
57h - перенести (AL=0) или обменять (AL=1)область памяти, описанную по адресу DSSI
58h - записать массив отображаемых адресов по адресу ESDI (AL=0) или вернуть в CX число этих адресов (AL=1)
59h - записать массив конфигурации оборудовани по адресу ESDI (AL=0) или вернуть в BX число нераспределенных страниц и в DX - общее число страниц
5Ah - распределить (BX) стандартных (AL=0) или "сырых" (AL=1) страниц и вернуть в DX номер нового сегмента
5Bh - операции с альтернативным набором регистров; имеет следующие подфункции;
0 - вернуть номер набора регистров карты в BL, либо адрес области сохранения регистров в ESDI (если BL=0)
1 - сделать активным набор регистров карты с номером (BL), либо (если BL=0) восстановить его с адреса ESDI
2 - вернуть в DX размер области сохранения
3 - вернуть номер нового набора регистров карты в BL (0, если его нельзя создать)
4 - освободить набор регистров карты с номером (BL)
5 - вернуть номер нового набора регистров ПДП в BL (0, если его нельзя создать)
6 - разрешить прямой доступ к набору (BL) через канал (DL)
7 - запретить прямой доступ к набору (BL)
8 - освободить набор регистров ПДП с номером(BL)
5Ch - подготовить EMS к теплой перезагрузке
5Dh - разрешить (AL=0) или запретить (AL=1)определенные функции ОС по ключу в BXCX, либо вернуть (AL=2) последний использованный ключ
Функции с номерами 4Fh - 5Dh допустимы только в EMS версии 4.0 и старше
[ Это Сообщение было отредактировано gerard в 2002-02-06 1402 ]