Здравствуйте! Собственно вопрос сводится к тому, как определить и использовать EISA- и прочие расширения DMA при программировании Sound Blaster совместимой звуковухи? Т.е. старый DMA, описаний работы с которым в сети что грязи, способен работать лишь в пределах первого мегабайта физической памяти. Это все знают. Чтобы, запускаясь из-под DPMI, узнать физический адрес из линейного, можно: 1) проследить линейный адрес по таблице страниц, но это возможно только на 0-м кольце привилегий; или 2) обратиться к т.н. VDS - Virtual DMA Services (int 4Bh), получив через него физический адрес начала блока с указанным линейным адресом; но VDS может и отсутствовать в системе; или 3) выделить память через XMS и там же получить физический адрес, хотя бы первой страницы - однако этот вариант предполагает выделение памяти за пределами 1-го мегабайта, что для старого DMA неприемлимо, как раз для этого и нужна информация о расширениях DMA; или 4) отобразить линейный адрес на физический (или наоборот?) посредством DPMI, но и этот вариант предполагает выделение памяти за пределами 1-го мегабайта, снова нужна конкретика о расширениях DMA; или 5) предположить, что все линейные адреса соответствуют физическим, что не всегда соответствует действительности. Я уж не говорю об ограничениях вроде невозможности пересечения границ 64k/128k и т.д. Это уже преодолимо. Главное - как в DMA задать физический адрес выше первого мегабайта? Спасибо. P.S. Читал тут статью про PCI DMA, но вроде как это мне не подходит.
Ykidia Не все, так как DMA способен работать до 16МБайт. В регистре страниц задается диапозон для линий A23-A16 Главное открыть вентиль A20. Собственно он у тебя должен быть открыт раз работаешь с DPMI. Делается так. Выделяешь физическую мапять потом преоброзуешь ее в линейную. Можно выделять до первого мегобайта. Преобразование физического адреса в линейный Функция может быть использована для работы с периферийными устройствами, адресное пространство ввода/вывода которых отображается в диапазон физических адресов. Преобразование физического адреса в линейный Регистры на входе AX 0800h BX:CX Физический адрес памяти. SII Размер блока памяти в байтах. Регистры на выходе: CARRY 0, если функция выполнилась без ошибки, 1, если произошла ошибка. BX:CX Линейный адрес памяти. Суть PCI DMA в том что любое PCI устройство способно работать с памятью напрямую минуя центральный процессор. Такии устройства должны иметь флаг Bus Master в своем конфигурационном пространстве. Программирование зависит от устройства. В статье приведен пример программирования IDE контролера. Так что это тебе никак не поможет.
И точно, это я сильно ступил (и, главное, долго же это продолжалось!)... Прошу прощения за столь досадное недоразумение и огромное спасибо за дельную информацию и терпение к тупизне! Тогда у меня еще пара вопросов, немного других: 1) Как осуществлялся полный дуплекс у поздних ISA-шных звуковух Sound Blaster по одному и тому же DMA каналу? 2) Где можно найти описание работы с DMA с возможностями scatter/gather и отсутствием ограничений на пересечение границ 64k/128k?
по старым саунд бластерам есть хорошие доки от creative, в т.ч. и с описанием работы с буфером в разных DMA-режимах.
Можете скинуть ссылку на какие-нибудь из них? У меня есть уже одна, Sound Blaster Series Hardware Programming Guide называется. Там много интересного, но нет ничего про то, о чем я спрашиваю.
Снова подниму тему - есть кое-какие неясности. Как выделяется физическая память? В доках по DPMI пишут, что память ниже 1М (которую можно выделить при помощи DOS-функций) отображена на физическую 1:1, т.е. в этом случае линейный адрес равен физическому. А как же тогда так получается, когда, скажем, под Windows запущено сразу несколько DOS-окон - возможно ли такое соответствие или уже нет? НЕЛЬЗЯ. Об этом сказано как в документации по DPMI, так и на практике - при попытке преобразовать физический адрес < 1М я получил отлуп. Может, что-то не так делаю? В той же документации по DPMI сказано, что для DMA вместо функции 0800h надо использовать VDS - Virtual DMA Services. Однако под DOSBox'ом VDS отсутствует (бит 5 по адресу 0040:007Bh сброшен), а в виндовом DOS-окне он вроде бы и есть, но при вызове функции 8103h (int 4Bh) ничего не происходит - ни физический адрес, ни id буфера не заполняются. Как быть в этом случае? Как вообще принято выделять буфер по физическому адресу и работать с ним в среде DPMI? Какова последовательность действий? Вот загрузил DOS-extender программу и запустил ее в PM с плоской моделью памяти. Программа нашла SB-совместимую звуковуху и т.д. Далее как выделить память по физическим адресам? Откуда мне знать, какие адреса выше 1M заняты, а какие нет? Вот я выделил буфер 16K по адресу 000100000h и узнал линейный адрес с помощью функции DPMI 0800h. Далее я заполнил этот буфер нулями, но тогда почему при запуске DMA-передачи в SB циклически проигрывается какая-то грязь, а не тишина? У кого какие соображения? Могу кинуть код, как и что делается. Сто раз перепроверил, раз десять исправлял/переписывал, но мало ли зенки совсем замылены...
Ykidia Возможно, просто DOS- программы работают не паролельно, а последовательно. А во вторых надо почитать про VM86 Нашел один способ но он под win16 поэтом действовать будет только в win3.11 и win9x. WinXP вроде не позволяет выполнять DPMI 0800h
Как же производится работа с физической памятью в таких DOS-монстрах, как Warcraft, Blood, Doom? Запускаются они так же, из-под DOS-extender'а, и нормально звучат . Есть ли какая информация? Наверняка кто-то из здешних делал, но почему же молчит?
Pavia Спасибо за попытки помочь , но нельзя ли как-нибудь поконкретнее? Не хотелось бы опять изобретать велосипед... P.S. Попробую сделать как описано здесь, посредством XMS.
Так оно и было, пока гребаны микрософтсы не насрали на спецификацию DPMI. Чего на эту функцию напали то? Она преобразует физический адрес в линейный. А для DMA, насколько помню, нужен именно физический. Да и в любом случае, эта функция не выделяет память. О VDS можешь сразу забыть. Мне пришлось патчить немало прог, которые пытались его использовать. Переправлял на dos get mem. Под 9x вполне помогало. Под ХРюном - вообще ничего не помогает. Через DOS. Об этом же и в спецификации написано. Еще раз, зачем тебе линейный адрес? Контроллер работает напрямую, в обход процессора, и он не знает, какая там адресация включена, его интересует только физический адрес. А они разве идут под XP? У меня тишина. Warcraft вообще не запускается Не заморачивайся. Память выделяй через DOS. По крайней мере под DOSом и Win9x будет нормально работать. Под хрюном скорее всего обломчик будет.
Привет! Спасибо за ответ. Линейный адрес нужен мне для того, чтобы был смысл заполнять буфер. Не зная линейного адреса я не смогу заполнять НУЖНУЮ область физической памяти (ибо в выбранных средах мне недоступно управление механизмом страничной адресации), зато смогу настроить DMA; но не зная физического адреса, я не смогу правильно настроить DMA, зато смогу заполнять буфер сколько влезет. Идут. Идут и под Win2k3. Однако сейчас у меня ничего из этого не работает, но по другой причине. В итоге я тоже хочу, чтобы моя прога работала под WinXP. В данном случае вопрос по ссылке выше я надеюсь все же разрешить, так что остается лишь один - способы получения достоверного соответствия физического и линейного адресов. О как загнул...
А звучат они оч. просто Они рассчитаны на работу в DOS и такими вещами как преобразование физических адресов в линейные не заморачиваются. Просто для DOS-задач Windows эмулирует наличие SoundBlaster и эмулирует DMA. Проверялось это на практике. Просто забываем что мы в Windows, выделяем блок памяти, заполняем его данными и программируем DMA на передачу этого блока указав адрес полученный при выделении. Т.е. при выделении адрес получили Seg:Offs=1234h:0000h - в DMA надо программировать 12340h. По сути это линейный адрес, но поскольку в DOS он был равен физическому - Windows это дело эмулирует и все преобразования производит сама. А точнее она вообще ничего не преобразовывает - берёт из указанного буфера сэмплы и передаёт драйверу реальной звуковой карты - SB ведь тоже эмулируется Вот и всё - и слышим звук.
Короче, завтра выложу свои сорсы, специально писал для своего плеера, под SB. Работает со всеми каналами, под DOS4GW или PMODE/W.
Забыл добавить У меня на компе стоит исашная SB. Но под ХРюном звука нет! Более того, половина программ просто виснут :-( Подозреваю что из за таймера.
плеера не нашел Но есть несколько файликов, вроде с тех времен остались. Судя по всему это было начало моих экспериментов, по кодированию SB, так что, прошу не судить строго
В доке на VCPI обнаружил рекомендуемую последовательность выделения физической памяти: (1) VCPI, (2) XMS, (3) extended memory (т.е. вручную). Но через VCPI выделять по странице и следить за тем, чтобы они составляли непрерывный блок физической памяти, оказалось немного геморройно, тем более учитывая, что теоретически память может быть фрагментирована, значит надо выделять страницы до тех пор, пока не встретится непрерывный кусок нужного кол-ва страниц, а потом освободить ненужные страницы (чем еще больше фрагментировать память); однако ни в DOSBox'е, ни в Windows DOS-окне этот метод не сработал - VCPI вроде и есть, но посылает куда подальше... С EMS'ом работать сложновато, а потому лень, хоть VCPI и считается надстройкой над ним... Так что забил я пока на этот метод. В результате у меня получилось так: (1) нахожу XMS - в Windows DOS-окне дает выделить сколько надо, но не дает заблокировать область памяти, так что физический адрес не получить; а в DOSBox'е просто не дает выделить - мол, все уже роздано. Подозреваю, что все захапывает DOS-extender при загрузке, но не знаю, как оттяпать из этого хоть что-то для себя... Есть может какие-нибудь соображения? (2) Беру уже выделенный через DOS блок памяти и отвожу часть его под DMA, проследив за непересечением границ 64k/128k и т.д. и предполагаю, что физические и линейные адреса идентичны. (3) на всякий случай проверяю VDS, если есть, то пытаюсь произвести преобразование адресов. В Windows DOS-окне бит 5 по адресу 0047Bh установлен, однако вызов функции блокировки области памяти ничего не дает - поля buffer ID и physical addr не заполняются; в DOSBox'е VDS не предоставляется. Итого все равно пока получается то, что мне и советовали - выделить память через DOS и не рыпаться . За исходники большое спасибо. Откровенно приятно было смотреть на упорядоченный код. Мне бы эти исходники, да лет 5 назад.... Эх!
Есть А почему не воспользоваться памятью, которую отхватывает dos-extender? Есть же сервис DPMI. Зачем в обход это делать? Но если и не устраивает этот вариант, то почти любому экстендеру можно задать размер памяти, который он "откусит" при запуске. В pmode/w точно есть такая фича. Это они типа из соображений безопасности сделали Попутно и 800h-ю функцию DPMI отрубили Долго я мучился с прогой, которая использовала пакет Midas, работающий через VDS. Пришлось ручками отключать проверку на наличие VDS, после чего я наконец-то услышал звук под виндой VDS не работает! Лучше сразу на него забить Насколько знаю, пока еще не изобрели другого способа