Советы по Delphi

         

Системный RAM/CMOS


Вы можете попробовать это... Функция возвращает сумму расширенной памяти CMOS (Полностью в килобайтах минус первый мегабайт).

    Function MyGetExt: Integer; Assembler; asm Mov  AX,$3031; Out  $70,AL; NOP; IN   AL,$71; XCHG AH,AL; Out  $70,AL; NOP; IN   AL,$71; end;

По-поводу CMOS-бустеров:

Обращаем ваше внимание на необходимость точного воспроизведения директив языка ассемблер. В противном случае ваш эксперимент может окончится плачевно. Впрочем, читайте дальше.

Для чтения из CMOS сделайте следующее:

запишите в порт $70 значение адреса, которое вы хотите читать или записать.
запишите в порт $71 новое значение для записи, или же прочтите его из порта $71.

CMOS имеет некоторые участки памяти, общие для всех производителей. Наиболее известные - адреса $0-$F, (установки времени, даты и таймера) и адреса $10-$1F (общие системные настройки). Позиции выше $20 каждый производитель обычно использует по-своему, поэтому стандарта на эти участки памяти просто не существует.

Мой пример будет на C, т.к. возможность использовать ASM появилась совсем недавно! Но я доберусь до Delphi через некоторое время.

запишите в порт $70 (hex) значение адреса памяти CMOS, с которым вы хотите работать. outp(0x70,0x31); { сообщаем CMOS, что мы хотим 'поговорить' со CMOS по адресу 31hex } затем читаем желаемое значение из порта $71, или записываем в порт новое значение. outp(0x71, 0x10); { записываем значение 10 hex (16 десятиричное) в CMOS по адресу 31, как было определено ранее } или x = inp(0x71); { считываем шестнадцатиричное значение из CMOS по адресу 31, как было определено ранее } Также хорошим советом является включение задержки между записью в порт 70 и чтением или записью в порт 71. Это очень важно в ассемблерном коде, и может служить причиной ошибок в случае быстрых процессоров на языках высокого уровня. Для этих целей может подойти обычный NOP.

Вы должны были заметить, что в приведенном ASM коде используются два адреса AX, 30 и 31. Необходимо учесть быструю загрузку, чтобы искать два адреса. Данный код содержит два примера, и оба читают CMOS. Значения памяти хранятся в двух последовательных ячейках, и в последней хранится значимый байт. И они также имеют отношение к сумме памяти за 1Mb, как это будет показано ниже.

OK, ok, я знаю, что код предполагается использовать в Delphi, но я прежде всего программист на C, а в Delphi возможно придется использовать Port или PortW, но точного синтаксиса я, увы, не знаю. Все-же стиль C мне кажется красивее и логичнее. Конечно, мне интересно мнение каждого, кто портировал код на Delphi. Я действительно не имею времени для изучения возможности переноса кода, и был бы благодарен опубликовать труды сделавших это.

Одно важное замечание: этим методом нельзя прочесть большое количество памяти (получить доступ к адресам в верхней памяти). Раньше никто не считал большим размер доступной памяти RAM, поэтому я более чем уверен, что память, имеющая большой размер, будет загружаться в CMOS неверно. Следовательно, описанный способ - ненадежен. Но новые версии BIOS могут уже поддерживать огромное количество памяти, но это следует проверять. Также, вам необходима карта CMOS, чтобы знать где расположены какие системные параметры. Между производителями могут существовать некоторые различия. Это добавляет нестабильности и много головной боли...

Вот что необходимо помнить при работе (редактировании) CMOS:

Если вы редактируете адрес в позиции между $10 и $2F, то вам НЕОБХОДИМО вычислить НОВУЮ контрольную сумму, вычисляя ее сложением значений, расположенных по адресам $10-$2F, и ЗАПИСАТЬ ее по адресу $3E, $3F, в противном случае вы ПОЛУЧИТЕ ОШИБКУ контрольной суммы CMOS при последующей перезагрузке! ГАРАНТИРОВАННО!!! Это ДОЛЖНО БЫТЬ вами УЧТЕНО...

Также, не пытайтесь тестировать значения $0 - $1F. Там находятся значения системных часов, ну вы знаете...

Не существует способа получения из BIOS общей суммы памяти. BIOS сообщит вам что вы имеет памяти только 640K, или того меньше (например, 256K...). С тех пор, как реальная память стала виртуальной, в переменных окружения Windows можно ознакомиться с наличием EMS, XMS, или памяти DPMI, использующие вызовы прерываний чтобы сообщать наличие свободной памяти для каждого из указанных сервисов. Я не знаю, есть ли способ узнать из-под Windows объем физической памяти, установленной в системе. Поиск такой API функции у меня результатов не дал; следовательно, вы можете узнать только полный размер виртуализованный памяти (включая swap-файлы и пр.). Я предполагаю, что Win95 содержит в себе такой метод. Я могу опубликовать здесь протоколы прерывания для получения EMS и пр., но я не думаю, что это может быть Вам полезным из-под Win. [001959]



Содержание раздела