Задачка такая, надо написать прогу для работы с USB флешкой под ДОС'ом. Для USB контроллера надо задать адрес начала списка кадров. Т.е. указатель на массив... но как при загруженом драйвере emm386 и himem получить физический адрес (указатель) этого массива?
1. Точно в emm используется страничная адресация ? Если не используется, то проблемы вообще нет; 2. Что мешает принудительно разместить блоки в нижней памяти (< 1Мег), для которой точно известен физический адрес ?
для программы, никакой, я смогу по этому указателю просмотреть элементы массива и все прочее... Но для USB контроллера я должен передать адрес этого массива в виде числа... и вот получается так что это число не соответствует физическому адресу размещения массива в оперативной памяти (при включенных emm386.sys и himem.sys)... Пример создание массива: Memory model - Large Code (Text): void *Handle = malloc(8192); //выделение 8К для массива если вывести на экран значение (unsigned long)Handle будет приблизительно так: 0x8FD90004 вот и хочется узнать как получить ФИЗИЧЕСКИЙ адрес по которому USB контроллер сможет считать информацию (на сколько я понял он использует DMA доступ к памяти).
По идее если emm, то там используются кадры памяти, значит при выбранном кадре он проецируется на адресное пространство куда-то. Адрес этот физический, т.к. виртуальных в dos'е вроде как нет. Про dump'ь память и найди этот кадр.
Gerret, а как ты узнал, что физический адрес не совпадает с линейным, если ты не можешь определить этот физический адрес? И причем тут EMM/XMM? Функция malloc выделяет блок памяти в хипе (который целиком находится в нижней памяти) и возвращает указатель блока (в твоем примере - 8FD9:0004). himem.sys и emm386.exe манипулируют только дополнительной и верхней памятью, а нижнюю не трогают. Так что для первых 640 килобайт линейный адрес должен совпадать с физическим.
да все понял созняюсь, ступил... я неправильно адрес записывал )) я его писал как есть ) 8FD90004... бывает же...
Если буфер располагается в базовой памяти... тогда физ. адрес буфера можно определить ч/з VCPI (функция 0DE06h). Но, надо полагать, что для нужд USB ~600-500К основной памяти будет маловато. Стандартные средства работы с расширенной памятью как обычно не подходят... работать ч/з отображаемые в 1М страницы с NN мегабайтами расширенной памяти -- это уподобится гинекологу из анекдота, обклеившему квартиру обоями ч/з замочную скважину. Свой собственный ProtMode memory manager писать наверное не в радость. Хороший вариант -- изменение программно-недоступного регистра предела (внутреннего) для какого-нибудь сегментного регистра (например GS). Необязательно с помощью LOADALL386 (которой может и не быть), можно и ч/з скачок в защищенный режим и обратно с пропуском инициализации сегментных регистров. После этого всё работает как обычно, но можно обращаться ко всей памяти, используя этот (допустим GS) сегментный регистр и 32-х разрядные операции. Да, EMM при этом лучше не пользовать.
_BC_, Кулакова читал? Можно изменить предел ВСЕХ сегментных регистров, а потом менять их как угодно - предел не изменится (если не входить в защищенный режим). Если использовать XMS, то можно узнать физический адрес выделленного блока с помощью функции XMM 0Ch (Lock extended memory block).
Вот что надо было посоветовать первым -- какой-нить хороший DOS-Extender. Нет. А зачем ВСЕ менять? Популярные сегментные регистры (типа CS, DS, ES, SS) перезагрузит V86-менеджер, а GS... кому он нафиг сдался этот GS ?
_BC_ прав, 500К для USB моловато... так что придется всетаки эксперементировать с линейной адресацией...