На главную

Битва за память: как сэкономить драгоценные килобайты для программ

   Представим себе такую ситуацию. 90-е годы. У геймера (назовем его условно Васей) есть 486-й компьютер с 8 МБ оперативной памяти. Скачал с BBS-ки Вася (как вариант – купил в магазине или переписал у друзей) новую игру, распаковал, установил, запустил, а она ему в ответ: «Извини, Вася, но у тебя слишком мало свободной оперативной памяти, попробуй удалить резиденты и т.д., и т.п.». Начинает Вася читать системные требования, а там – «минимум 580 КБ свободной нижней памяти, рекомендуется 610 КБ + 320 КБ XMS\EMS» Первая его реакция – «странно, ведь у меня же целых 8 метров памяти, чего же ей не хватает?» И удалил Вася игру эту, и забыл ее как страшный сон…
   На этом рассказ наш прерывается. Действительно, требования у игр и программ в отношении количества оперативной памяти широко варьируются – одни работают и при свободных 300 килобайтах, другие требуют все 620, третьи жить не могут без EMS или XMS, четвертые же наоборот – ненавидят EMS и всячески на него ругаются, вплоть до незапуска, ну а пятые же вообще работают в защищенном режиме (под DOS-расширителем типа DOS4G/W) и на ограничения реального режима им глубоко наплевать. Как же удовлетворить запросы всех приложений, предоставив им идеальную среду для работы?

   Сразу обозначим наш «круг интересов»:
   – Операционная система – MS-DOS 6.22 либо 7.x (если установлена Windows 9x);
   – Должны работать как приложения, использующие только нижнюю память, так и использующие EMS/XMS;
   – Также должны работать с незначительными изменениями резидентные программы (русификаторы экрана и клавиатуры, драйверы CD-ROM, сетевых карт и других устройств);
   – Компьютер должен иметь как минимум 1 МБ памяти и процессор 386SX или выше;
   – QEMM не используется, обойдемся стандартными средствами – HIMEM.SYS + EMM386.EXE.

   Подчеркну последний пункт. Конечно, QEMM предоставляет замечательные возможности по оптимизации оперативной памяти, однако проблемы совместимости с некоторыми программами не позволяют рекомендовать его для управления памятью. Дело в том что, даже имея связку HIMEM + EMM386, можно добиться результатов не хуже, а зачастую и лучше, чем при использовании QEMM, о чем я и собираюсь Вам рассказать.

Теория

   Но сначала немного теории. Когда в 1981 году фирма IBM представила публике свой первый PC, в нем стоял 16-битный с 8-битной шиной данных процессор Intel 8088. Адресуемая память этого процессора составляет 1 мегабайт, адресация происходит при помощи связки из двух 16-битных машинных слов – сегмента и смещения. Для получения 20-битного адреса адрес сегмента умножается на 16 и к нему прибавляется смещение, образуя 20-битный адрес в памяти. В принципе, это факт давно уже общеизвестный, поэтому углубляться дальше не стану. В процессоре Intel 80286, ставшем основой IBM PC/AT, адресное пространство расширено до 16 МБ, так как число адресных линий составляет уже 24. Кроме этого, появился защищенный режим, дескрипторы, селекторы и т.д., но при этом реальный режим, в котором 8088 работал, остался, и в нем процессор работает сразу после включения, таким образом обеспечивая совместимость с IBM PC и PC/XT.
   В 80386 впервые архитектура расширена до 32 бит, появилась возможность адресовать до 4 ГБ памяти, но самое главное – процессор был полностью совместим со своими предшественниками! Кроме того, в защищенном режиме есть возможность использовать виртуальные задачи реального режима (режим V86). Но общее в этих и последующих процессорах одно – все они поддерживают реальный режим, и все они в реальном режиме адресуют лишь первый мегабайт адресного пространства! А DOS, целевая система для наших экспериментов, как раз работает в реальном режиме.
   Снова вернемся к IBM PC. Чтобы эффективно использовать доступный им мегабайт, было решено поделить память на 16 сегментов по 64 килобайта. Первые 10 сегментов (те самые 640 килобайт) отданы под оперативную память, следующие два сегмента (128 КБ) зарезервированы для видеокарт, а оставшиеся 4 сегмента (256 КБ) распределены между системным ПЗУ (Basic Input-Output System, BIOS) и ПЗУ адаптеров расширения. Более подробно распределение памяти отражено на этой схеме:
 адрес
          -----
  00000  |xxxxx| Таблица векторов прерываний реального режима
         |-----|
  00400  |xxxxx| Область данных BIOS (BIOS Data Area, BDA)
         |-----|
  00500  |xxxxx| DOS, драйверы и системные переменные
         |-----|
  xxxxx  |xxxxx| Резидентные программы
         |-----|
  xxxxx  |xxxxx| COMMAND.COM
         |-----|
  xxxxx  |     | Свободная память для программ
          .....
         |     |
         |-----|
  xxxxx  |xxxxx| Расширенная область данных BIOS (Extended BDA)
         |xxxxx| (присутствует на PS\2, а также на большинстве 486-х)
         |-----|
  A0000  |VVVVV| EGA\VGA кадровый буфер для графических режимов
         |-----|
  B0000  |VVVVV| MDA\EGA\VGA буфер для монохромных текстовых режимов
         |-----|
  B8000  |VVVVV| CGA\EGA\VGA буфер для цветных текстовых режимов
         |-----|
  C0000  |RRRRR| EGA\VGA видео-BIOS 
         |-----|
  C8000  |RRRRR|
          .....  ПЗУ карт расширения, также блоки верхней памяти
  EFFFF  |RRRRR| (Upper Memory Block, UMB)
         |-----|
  F0000  |BBBBB| Системный BIOS
         |-----|
 100000  |     | Область верхней памяти (High Memory Area, HMA)
         |-----|
 1FFFF0  |     | Оставшаяся память, доступна в защищенном режиме
         |     | либо через EMS\XMS
         |-----|
 xxxxxx  |VVVVV| Области памяти VLB\PCI-устройств
          -----

   Как мы видим, память четко распределена между программами и устройствами. Казалось бы, вот у нас есть в реальном режиме 640 килобайт, как же использовать больший объем памяти, не переключаясь в защищенный режим?
   Компания Microsoft, как и другие производители ПО, задавались теми же вопросами, поэтому было решено посмотреть в сторону новых возможностей новых процессоров. Во-первых, в 286 есть недокументированная команда LOADALL, которая позволяет, особым образом загрузив регистры, получать доступ к ранее недоступной памяти. На основе данного метода и работает драйвер HIMEM.SYS, предоставляя расширенную память при помощи данного метода по спецификации eXtended Memory Specification (XMS). Вторая особенность 286-го, а также и последующих процессоров – линия A20, являющаяся 21-й адресной линией, позволяет при задании сегмента FFFF обращаться к памяти свыше первого мегабайта, адресуя блок вплоть до 65520 байт (это почти 64 килобайта)! Обычно в данную область загружается часть MS-DOS, для того чтобы сэкономить основные 640 КБ для остальных программ. Для совместимости с 8088 эта линия управляется контроллером клавиатуры, который может ее принудительно посадить на низкий уровень, «заворачивая» нас на начало памяти, впрочем, линия эта прекрасно управляется, и HIMEM.SYS с этой задачей справляется.
   Далее. Спецификация Expanded Memory Specification (EMS) позволяет адресовать расширенную память через «окно» в 16 или более килобайт, чаще всего расположенное в области C8000-EFFFF (так как такая память часто находилась на картах расширения). С появлением 80386 появилась возможность исполнять задачи реального режима внутри защищенного (уже упомянутый V86), а механизм страничной адресации позволяет эмулировать EMS через обычную или XMS-память. Так работает EMM386.EXE. Кроме того, он «вставляет» в «дырки» в области ПЗУ адаптеров свободные участки памяти (те самые UMB-блоки), позволяя грузить туда резидентные программы.
    Но есть и оборотная сторона медали под именем EMM386.EXE. Так как в итоге все программы и DOS работают в своем роде «песочнице» реального режима, любая попытка программ выйти из этой «песочницы» (к примеру, попыткой перехода в защищенный режим не через интерфейс DPMI) заканчивается исключением процессора, выводом предупреждающего сообщения, а иногда и зависанием компьютера. Зачастую такие капризные программы неплохо работают и с HIMEM.SYS, но EMM386 на дух не переносят, заранее предупреждая пользователя. Кроме того, для работы EMM386 наличие HIMEM.SYS в памяти обязательно.

   Исходя из этого, составим стратегию оптимизации памяти:

   – Создадим загрузочное меню, которое позволит нам выбрать варианты загрузки – чистая загрузка, HIMEM, HIMEM + EMM, также возможны варианты с раздельной загрузкой драйверов устройств и т.д.;
   – Оптимизируем порядок загрузки резидентов и драйверов, задействуем более «экономичные» и функциональные аналоги;
   – Задействуем некоторые особенности чипсетов материнских плат.

Тестовая платформа

   В качестве тестовой платформы я использую следующую конфигурацию:

   – Процессор Intel Pentium MMX 200
   – Материнская плата FIC VA-502 (VIA Apollo VPX, 256 КБ кэша)
   – 128 МБ SDRAM PC-133
   – Видеокарта Matrox Millennium I (2 МБ VRAM)
   – Жесткий диск Seagate ST340016A (40 ГБ IDE)
   – Windows 98 SE + MS-DOS 7.10

   Большая часть нижеприведенных «твиков» ориентированы на MS-DOS 7.10, но также будут работать и на 6.22

С чего начнем?

   Итак, у нас есть свежеустановленная Windows 98 (или MS-DOS 6.22, кому как), с примерно таким содержанием конфигурационных файлов, к примеру, вот AUTOEXEC.BAT:
mode con codepage prepare=((866) C:\WINDOWS\COMMAND\ega3.cpi)
mode con codepage select=866
keyb ru,,C:\WINDOWS\COMMAND\keybrd3.sys
CONFIG.SYS:
Device=C:\WINDOWS\HIMEM.SYS /testmem:off
device=C:\WINDOWS\COMMAND\display.sys con=(ega,,1)
Country=007,866,C:\WINDOWS\COMMAND\country.sys
   Попробуем данную конфигурацию в действии. Запишем «лог» работы программы MEM.EXE, для чего запустим ее так: MEM.EXE /C >> DEFAULT.LOG
   Результат работы программы приведен ниже:

 Тип памяти       Размер       Занято     Свободно
 -------------  -----------  ---------   ----------
 Обычная            655 360     71 168      584 192
 Верхняя                  0          0            0
 Зарезервировано    393 216    393 216            0
 Память XMS     133 169 152     65 536  133 103 616
 -------------  -----------  ---------  ----------
 Всего памяти:  134 217 728    529 920  133 687 808

   Негусто. Из плюсов отмечу наличие поддержки XMS-памяти, из минусов – всего 570 килобайт, чего явно недостаточно для некоторых программ, к тому же мы не можем использовать EMS-память. Надо проводить оптимизацию.

Загрузочное меню

   Замечательной особенностью MS-DOS 6.0 и выше является возможность создания загрузочного меню с различными конфигурациями. Именно меню позволяет добиться наибольшей гибкости в плане управления памятью, чем мы и воспользуемся.
   Вначале внесем несколько изменений в CONFIG.SYS, вставим в начало следующий блок:

[menu]
MenuItem win98, Windows 98 (normal boot)
MenuItem himem, DOS Prompt - Boot with HIMEM
MenuItem emm, DOS Prompt - Boot with HIMEM + EMM386
MenuItem clean, DOS Prompt - Clean Boot
MenuDefault 1, 1
MenuColor 7,0

   В секции [menu] задается основные настройки меню – количество и описание пунктов меню (MenuItem), цвет самого меню (MenuColor), а также пункт по умолчанию и задержку (MenuDefault). Далее опишем сами настройки для каждой конфигурации:

[win98]
device=c:\WINDOWS\HIMEM.SYS /testmem:off
device=C:\windows\ifshlp.sys

[himem]
device=C:\windows\himem.sys /testmem:off
     
[emm]
Device=C:\WINDOWS\HIMEM.SYS /testmem:off
DEVICEHIGH=C:\WINDOWS\EMM386.EXE I=B000-B7FF X=B800-C7FF I=C800-EFFF FRAME=C800 RAM D=64
DEVICEHIGH=C:\windows\ifshlp.sys

[clean]

   Как мы видим, мы добавили EMM386.EXE в список загружаемых драйверов, а также загрузили дополнительно драйвер IFSHLP.SYS – это на тот случай, если во время загрузки Windows вылетает с ошибкой инициализации устройства VFAT. В свое время я столкнулся с этой ошибкой, и что только не делал, чтобы от нее избавиться – даже винчестер форматировал, сохранив модифицированные AUTOEXEC.BAT и CONFIG.SYS и восстановив их после переустановки, после чего я долго не мог понять, почему эта ошибка не вылечилась. :)
   Но вернемся к теме. Вместо команды DEVICE мы загружаем драйверы командой DEVICEHIGH, которая пытается загрузить IFSHLP.SYS в UMB. Также у нас есть пункт «чистая загрузка», при которой вообще не производится загрузка драйверов и резидентных программ – это полезно для самых капризных программ.
   Последняя секция нового CONFIG.SYS – [common] – задает настройки для всех конфигураций, и мы ее помещаем последней:

[common]
DOS=HIGH,UMB
Country=007,866,C:\WINDOWS\COMMAND\country.sys
devicehigh=C:\WINDOWS\COMMAND\display.sys con=(ega,,1)
BUFFERS=20

   Первая строка – самая важная, она загружает часть DOS в область HMA, а также в UMB, если это возможно, экономя основную память. Вторая строка задает региональные настройки (формат даты и времени, денежных единиц, кодовую страницу), третья позволяет использовать встроенный в DOS русификатор дисплея и драйвер клавиатуры, которые грузятся уже из AUTOEXEC.BAT, к которому мы сейчас и перейдем. Третья строка несильно влияет на объем свободной памяти, она задает количество буферов ввода-вывода DOS.
   Название конфигурации (первый параметр в пункте MenuItem) хранится в переменной окружения CONFIG, позволяя произвести в AUTOEXEC.BAT ветвление по конфигурациям. Ниже – сам AUTOEXEC.BAT:

@echo off
goto %config%
:normal
:emm
path=c:\dos\sb
SET SOUND=C:\DOS\SB
REM Sound Blaster configuration
C:\DOS\SB\CTCM\CTCM.EXE
SET BLASTER=A220 I5 D1 H5 P330 E620 T6
C:\DOS\SB\MIXERSET /P
cd c:\dos\sb
LH AWEUTIL /s
cd ..\..

:win98
PATH=%path%;C:\WINDOWS;C:\WINDOWS\COMMAND;C:\DOS
mode con codepage prepare=((866) C:\WINDOWS\COMMAND\ega3.cpi)
mode con codepage select=866
LH keyb ru,,C:\WINDOWS\COMMAND\keybrd3.sys
goto end

:clean
:end

   Часть строк – конфигурация звуковой карты (у меня стоит Sound Blaster 32), другая часть – ветвление и загрузка русификатора.
   Сохранив полученный «конфиг», можно проводить тесты. Запустим аналогичным образом MEM.EXE, создав еще три лога – HIMEM.LOG, EMM386.LOG и CLEAN.LOG.

HIMEM.LOG:

 Сведения о памяти:

 Тип памяти       Размер      Занято      Свободно
 ------------   -----------  ---------   ----------
 Обычная            655 360     58 464      596 896
 Верхняя                  0          0            0
 Зарезервировано    393 216    393 216            0
 Память XMS     133 169 152     65 536  133 103 616
 -------------  -----------  ---------   ----------
 Всего памяти:   134 217 728   517 216  133 700 512

 Ниже 1 МБ:         655 360     58 464      596 896


   Весьма неплохой результат – 583 КБ свободной памяти, но для некоторых приложений все равно маловато.

CLEAN.LOG:

 Сведения о памяти:

 Тип памяти         Размер    Занято       Свободно
  ---------------  --------  ---------    ---------
 Обычная           655,360      90,768      564,592
 Верхняя                 0           0            0
 Зарезервировано         0           0            0
 Память XMS     67,043,328  67,043,328            0
 ---------------   --------  ---------    ---------
 Всего памяти:  67,698,688  67,134,096      564,592

 Ниже 1 МБ:        655,360      90,768      564,592

   551 килобайт свободен – печальный результат при «чистых» настройках :(.

EMM386.LOG:

 Сведения о памяти:

 Тип памяти        Размер       Занято     Свободно
 -------------  -----------  ---------   ----------
 Обычная            655 360     16 384      638 976
 Верхняя            125 408     43 872       81 536
 Зарезервировано    393 216    393 216            0
 Память (XMS)*  133 043 744    677 408  132 366 336
 -------------  -----------  ---------   ----------
 Всего памяти:  134 217 728  1 130 880  133 086 848

 Ниже 1 МБ:         780 768     60 256      720 512

   624 свободных килобайта – великолепный результат, но и это еще не предел! Данная конфигурация позволяет запускать практически любой софт, требующий EMS\XMS или большой объем нижней памяти, и при этом не мешает загрузке Windows, однако в случае, если программа не работает под EMM386 и требует 600 килобайт нижней памяти или больше, наш «конфиг» надо будет отредактировать. Для этой цели можно провести оптимизацию резидентных программ, о чем и пойдет речь в следующих разделах.

Русификация – дело тонкое

   Первый пункт нашей оптимизации – русификатор. Обычно такой драйвер «весит» около 10 килобайт, храня в себе фонты 8x8, 8x16 и часто 8x14 для текстового режима, а также драйвер клавиатуры и дисплея. Конечно, вы можете взять KEYRUS и обрезать его до 2 килобайт, а можете просто оставить стандартный mode con prepare. Однако есть один русификатор, который имеет все возможности дисплейного модуля KEYRUS, но при этом не занимает ни байта памяти! Это S_FONT Алексея Шамарокова, автора FFORMAT.
   И снова начнем с теории :). Одной из главных особенностей наборов системной логики, или чипсетов для материнских плат, стала возможность копировать содержимое ПЗУ устройств (включая системный и видео-BIOS) в оперативную память, серьезно ускоряя доступ к записанному туда коду. Данный процесс называется затенением ПЗУ (shadowing). При этом обычно на затененную область памяти ставится защита от записи (как в случае работы непосредственно с ПЗУ), таким образом, из такой области можно только читать данные или исполнять программный код.
   Напрашивается простой вопрос – как же в такую область копируются ПЗУ адаптеров и BIOS? Ответ простой – средствами чипсета BIOS разрешает запись в такую область памяти, копирует туда содержимое ПЗУ и по окончании запрещает запись в эту область. S_FONT делает по сути то же самое – открывает область видео-BIOS на запись, записывает туда новые фонты, а затем закрывает эту область и просто завершает работу, как результат, видеоадаптер уже «русифицирован», а в памяти от S_FONT не осталось и следа! Разумеется, для каждого чипсета метод открытия\закрытия теневой памяти разный. Кроме того, теневая память сбрасывается после перезагрузки или выключения компьютера, поэтому S_FONT нужно загружать каждый раз заново.
   Для начала зайдем в BIOS Setup и включим Video BIOS Caching, иначе у нас ничего работать не будет. На всякий случай включим кэширование для всех областей ПЗУ адаптеров – пригодится позднее. Далее качаем сам русификатор отсюда:

http://absh.net.ru/files/folders/s_font/default.aspx

   (на момент написания статьи ссылка не работает, альтернативный линк на мой FTP-сервер: http://tslabs.info/wormsbiysk/files/dos/S_FONT.zip) и распаковываем в любую удобную папку – у меня это C:\DOS\S_FONT. Формат запуска такой – S_FONT.COM xx, где xx – код чипсета вашей материнской платы. Если вы знаете название чипсета, можете глянуть нужный ключ для запуска S_FONT в документации. Если же вы такой информацией не обладаете, можно запустить программу ATTEMPT2.EXE, которая постарается сама обнаружить нужный чипсет путем чтения\записи теневой памяти. Запускать ее нужно из чистого DOS, желательно с загрузочной дискеты, так как на нее пишутся некоторые файлы на тот случай, если в результате незаконных операций с чипсетом компьютер зависнет, и чтобы можно было продолжить процесс обнаружения. Как только ATTEMPT2.EXE определит Ваш чипсет, она тут же оповестит Вас об этом, к примеру, вот что выдает программа на моем компьютере:

2D Checking VIA Apollo 580 ... 
- <========== Ok! ====<<<< :-0

Detected chipset: VIA Apollo 580, for use this chipset add the following line into your config.sys file:

DEVICE=S_FONT.COM [2D]

   Дополнительно программа предупредит Вас о необходимости перезагрузки компьютера путем отключения и включения питания – это на тот случай, если в результате таких «экспериментов» повреждено содержимое теневой памяти. Кстати – ATTEMPT2.EXE предлагает грузить S_FONT через CONFIG.SYS, мы же загрузим его в AUTOEXEC.BAT. Дело в том, что при загрузке драйвера через CONFIG.SYS он посылает системе сигнал ошибки инициализации сразу после того, как программа отработает, и если это произойдет во время загрузки Windows, загрузочный экран сразу исчезнет, что не очень приятно. В случае загрузки драйвера через AUTOEXEC.BAT S_FONT отрабатывает как обычный нерезидентный COM-файл и загрузочный экран остается на месте.
   После того как мы узнали код нашего чипсета, пора вставить наш русификатор, для этого удалим строки:

mode con codepage prepare=((866) C:\WINDOWS\COMMAND\ega3.cpi)
mode con codepage select=866

   И вставим вместо них следующую строку:

C:\DOS\S_FONT\S_FONT.COM XX

   Перезагружаемся. Вуаля! Теперь не нужно больше мучаться с неожиданно «слетающими» фонтами – русификация работает всегда в абсолютно всех режимах, ведь видео-BIOS будет грузить эти фонты как родные, совершенно не подозревая о подлоге!
   Дополнительно в CONFIG.SYS можно убрать следующую строчку

devicehigh=C:\WINDOWS\COMMAND\display.sys con=(ega,,1)

   Она нужна только для MODE.COM, но в то же время почти все его функции, кроме загрузки фонтов, работают нормально. Строку

Country=007,866,C:\WINDOWS\COMMAND\country.sys

   обязательно надо оставить – она нужна для работы большинства программ, работающих с файлами.
   Теперь от достоинств плавно перейдем к недостаткам. Во-первых, не на всех чипсетах S_FONT работает корректно либо вообще работает. По своему опыту скажу, что на чипсетах от VIA и Intel проблем у меня не было, все работало так, как было задумано. Во-вторых, некоторые видео-BIOS’ы расположены в сегменте E000, и я, честно говоря, не знаю, будет ли работать S_FONT в таком случае. В-третьих, у некоторых новых видеокарт (начиная примерно с NVidia Riva TNT) видеобиосы иногда имеют объем 64 килобайта, занимая адреса от C0000 до CFFFF, и, как в случае с прошлым пунктом, ничего сказать я не могу по этому поводу, так как использовать S_FONT на таких картах не доводилось. В-четвертых, опять-таки в новых картах зачастую по спецификации VESA отсутствует фонт 8x14, вызывая, таким образом, глюки в некоторых программах (например, в установщике игры SimCity 2000). Я регулярно сталкиваюсь с эти фактом на моем Matrox Millennium, причем S_FONT сам такой недостаток в видеобиосе не вылечит, но может оставить фонт резидентным (ключ /A как раз для таких случаев). Пятый факт – S_FONT русифицирует только видеоадаптер, для русификации клавиатуры можно оставить KEYB.COM, а можно поставить любой другой русификатор. В комплекте поставки S_FONT есть программа S_KBGR2.COM – это драйвер клавиатуры. Загружать его надо вместо KEYB.COM (отредактируйте AUTOEXEC.BAT для этого), настроить его можно через программу S_KCONF.EXE. В случае же возникновения проблем, рекомендую почитать документацию – многие проблемы там описаны.
   В целом, S_FONT настоятельно рекомендуется для использования вместо штатного русификатора дисплея, предоставляя невиданные доселе возможности, и при этом совершенно не затрачивая драгоценные байты памяти.

UMBPCI – задействуем аппаратный UMB

   Теневую память можно использовать не только для русификации видеокарт, но и для создания блоков оперативной памяти в области ПЗУ карт расширения – не пропадать же памяти даром! :) Именно так и работает UMBPCI.
   Этот драйвер в оригинале был написан Andreas Stiller, редактором немецкого компьютерного журнала c`t в 1995 году, затем разработку взял на себя Uwe Sieber. Сам драйвер выполняет только две функции – открывает теневую память на чтение и запись и добавляет в интерфейс XMS функцию «Request XMS-UMB» (Запросить UMB-блок памяти). EMM386.EXE с параметром «RAM» делает в точности то же самое, но создает такие блоки за счет работы в защищенном режиме со всеми вытекающими последствиями, о которых я уже упомянул ранее. UMBPCI же полностью свободен от недостатков EMM386.EXE, занимая только 160 БАЙТ в нижней памяти.
   Уже заинтересовались? :). Тогда скачайте UMBPCI отсюда: http://www.uwe-sieber.de/files/umbpci_e.zip и распакуйте в любую папку – у меня это C:\DOS\UMBPCI. Если Вы уже установили S_FONT, то, надеюсь, название чипсета Вы уже знаете. Создадим новый пункт меню конфигурации, например, «DOS Prompt - Boot with HIMEM + UMBPCI», присвоим ему идентификатор, например, umbpci, и присвоим следующие настройки:

[himem]
device=C:\windows\himem.sys /testmem:off
device=C:\DOS\UMBPCI\UMBPCI.SYS

   А AUTOEXEC.BAT модифицируем следующим образом:

...
:normal
:emm
REM добавили новый пункт ниже
:umbpci
path=c:\dos\sb

   После чего можно перезагружать компьютер и выбирать новый пункт загрузки. Если все прошло нормально, должно появиться примерно следующее сообщение:

UMBPCI c't 11/95 - Siering/Schaepers/Stiller
V3.84 - support for new chipsets, Intel PPro, AMD K7
Uwe Sieber 04/1996-01/2013
Using C800-EFFF
VIA Apollo VP/VPX found
Program installed

   Если же появилось следующее сообщение:

No supported chipset found.
Problem programming the chipset.

   То вам не повезло, и чипсет не поддерживается. Если ваш чипсет поддерживается, но до конца не оттестирован, появится следующее сообщение:

This chipset is untested!
Mail me the name of the chipset and if it works so I can remove this break.
Press any key...

   Если UMBPCI работает стабильно, напишите письмо автору, адрес можно взять здесь: http://www.uwe-sieber.de/email.html.
   После этого посмотрите с помощью MEM.EXE, сколько памяти теперь свободно. Думаю, результат вас удивит – если ранее драйверы и резиденты теснились в нижней памяти, теперь они спокойно размещаются в верхней, при этом освобождая драгоценные килобайты для работы программ! У меня остались свободными аж 629 килобайт, даже больше, чем при использовании EMM386.EXE.
   Разумеется, у программы есть и недостатки, главный из них связан со спецификой работы теневой памяти – проблемы с работой DMA-каналов в верхней памяти на некоторых чипсетах, что особенно неприятно при использовании дискет (контролер дисковода использует DMA). Для проверки, поддерживается ли DMA в верхней памяти, при загруженном UMBPCI запустите из той же папки файл DMACHK.COM (если его там нет, скачать недостающие файлы можно отсюда: http://www.mdgx.com/umb.htm) – в идеале результат должен быть таков:

ISA-DMA-Checker for UMBPCI V1.13, (c)1999-2004 by Heiko Nocon, Uwe Sieber 
http://www.uwe-sieber.de

 North-Bridge:  Vendor: 1106  Device: 0585
 South-Bridge:  Vendor: 1106  Device: 0586

C000-C3FF : write protected
C400-C7FF : write protected
C800-CBFF : read/write ok, ISA-DMA ok
CC00-CFFF : read/write ok, ISA-DMA ok
D000-D3FF : read/write ok, ISA-DMA ok
D400-D7FF : read/write ok, ISA-DMA ok
D800-DBFF : read/write ok, ISA-DMA ok
DC00-DFFF : read/write ok, ISA-DMA ok
E000-E3FF : read/write ok, ISA-DMA ok
E400-E7FF : read/write ok, ISA-DMA ok
E800-EBFF : read/write ok, ISA-DMA ok
EC00-EFFF : read/write ok, ISA-DMA ok

   Если же хоть один из пунктов гласит «ISA-DMA failed», сразу рекомендую после UMBPCI.SYS в файле CONFIG.SYS поставить загрузку файла LOWDMA.COM – он исправляет проблемы работы DMA-каналов при работе с дискетами путем копирования блока данных в нижнюю память. Отмечу – LOWDMA.COM нужно грузить в нижнюю память! Честно скажу, мне повезло, и на Intel 430TX (мой любимый пентиумный чипсет, да вот «помидорина» 5STX начала глючить), а также на VIA Apollo VPX проблем с DMA-каналами в верхней памяти нет.
   Отмечу также, что для работы UMBPCI требуется чипсет с поддержкой шины PCI. Не знаю, почему, но программа требует как минимум Pentium, хотя шина PCI есть и на некоторых 486-х. Как утверждает сам автор, в BIOS’ах 486-х материнок нет поддержки работы с шиной PCI через прерывание INT 1Ah. К сожалению, проверить данный факт за неимением соответствующей материнской платы я не могу, так что если вам не повезло, можно попробовать аналог UMBPCI – HIRAM, скачать его можно здесь : http://www.mdgx.com/umb.htm#HIR

Драйверы CD-ROM, резидентные «полезняшки» и все-все-все…

   Если же хочется работать с CD-ROM под DOS – милости просим. Для таких случаев у меня есть отдельные конфигурации с поддержкой CD-ROM. В качестве драйвера я использую UDVD2.SYS (скачать можно отсюда – http://johnson.tmfc.net/dos/driver.html), а взамен MSCDEX.EXE – SHSUCDX.COM (скачать можно отсюда – http://johnson.tmfc.net/dos/shsucdx.html). При этом компакт-диски читаются без проблем, музыка с них играется замечательно. Кроме того, никто не запрещает Вам поставить дисковый кэш типа SmartDrive, тем более, что его можно грузить в верхнюю память! Для загрузки в верхнюю память программ следует использовать команды DEVICEHIGH в CONFIG.SYS и LH в AUTOEXEC.BAT или в командной строке. Дополнительный параметр /L позволяет задать область верхней памяти, в которую будет загружена программа.

«Конфиги» напоследок

   Напоследок приложу сюда мои конфигурационные файлы, оптимизированные на максимальное освобождение памяти.

   CONFIG.SYS:

[common]
[common]
FILES=80
DOS=HIGH,UMB
LASTDRIVE=F

[menu]
MenuItem win98, Windows 98 (normal boot)
MenuItem himem, DOS Prompt - Boot with HIMEM
MenuItem umbpci, DOS Prompt - Boot with HIMEM + UMBPCI
MenuItem umbpci_cdrom, DOS Prompt - Boot with HIMEM + UMBPCI, CD-ROM support
MenuItem emm, DOS Prompt - Boot with HIMEM + EMM386
MenuItem emm_cdrom, DOS Prompt - Boot with HIMEM + EMM386, CD-ROM support
MenuItem clean, DOS Prompt - Clean Boot
MenuDefault 1, 1
MenuColor 7,0


[win98]
device=c:\WINDOWS\HIMEM.SYS /testmem:off
device=C:\windows\ifshlp.sys

[himem]
device=C:\windows\himem.sys /testmem:off

[umbpci]
device=C:\windows\himem.sys /testmem:off
device=C:\dos\tweak\umbpci\umbpci.sys
DEVICEHIGH=C:\windows\ifshlp.sys

[umbpci_cdrom]
device=C:\windows\himem.sys /testmem:off
device=C:\dos\tweak\umbpci\umbpci.sys
DEVICEHIGH=C:\DOS\CDROM\UDVD2.SYS /D:12345678
DEVICEHIGH=C:\windows\ifshlp.sys
     
[emm]
Device=C:\WINDOWS\HIMEM.SYS /testmem:off
DEVICEHIGH=C:\WINDOWS\EMM386.EXE I=B000-B7FF X=B800-C7FF I=C800-EFFF FRAME=C800 RAM D=64
DEVICEHIGH=C:\windows\ifshlp.sys

[emm_cdrom]
Device=C:\WINDOWS\HIMEM.SYS /testmem:off
DEVICEHIGH=C:\WINDOWS\EMM386.EXE I=B000-B7FF X=B800-C7FF I=C800-EFFF FRAME=C800 RAM D=64
DEVICEHIGH=C:\DOS\CDROM\UDVD2.SYS /D:12345678
DEVICEHIGH=C:\windows\ifshlp.sys

[clean]
buffers=5
files=20

[common]
Country=007,866,C:\WINDOWS\COMMAND\country.sys
BUFFERS=20

   AUTOEXEC.BAT:

@echo off
goto %config%

:himem
:umbpci
:umbpci_cdrom
:emm
:emm_cdrom
path=c:\dos\sb
:: Sound Blaster configuration
C:\DOS\SB\CTCM\CTCM.EXE
SET BLASTER=A220 I5 D1 H5 P330 E620 T6
C:\DOS\SB\MIXERSET /P
cd c:\dos\sb
LH AWEUTIL /s
cd ..\..

:win98
PATH=%path%;C:\WINDOWS;C:\WINDOWS\COMMAND;C:\DOS;C:\BP\BIN;C:\BC;D:\FPC\BIN\GO32v2
C:\DOS\S_FONT\S_FONT.COM 2D
REM_LH_keyb_ru,,C:\WINDOWS\COMMAND\keybrd3.sys
LH /L:1 C:\DOS\S_FONT\S_KBGR2.COM
if %CONFIG%==win98 goto cls
if %CONFIG%==emm_cdrom goto cdrom
if %CONFIG%==umbpci_cdrom goto cdrom
goto end

:clean
SET BLASTER=A220 I5 D1 H5 T4
C:\DOS\SB\MIXERSET /p
C:\DOS\S_FONT\S_FONT.COM 2D
goto end

:cdrom
C:\DOS\CDROM\SHCDX33F.COM /D:12345678
LH C:\WINDOWS\SMARTDRV.EXE 4096
goto end

:cls
CLS

:end

   С данными настройками стабильно работают 99,9% программ, при этом памяти остается достаточно практически для любых приложений.
   Кстати, стоит сказать пару слов о ключах EMM386.EXE. Ключ I= задает используемый диапазон памяти, ключ X= указывает диапазон памяти, который программа не будет использовать. Ключ FRAME= задает сегмент «окна» EMS-памяти, ну а ключ D= задает размер буфера DMA в килобайтах. Таким образом, EMM386 может использовать память монохромных режимов MDA\EGA\VGA, а также свободную область ПЗУ карт расширения, в итоге нам доступно 192 килобайта верхней памяти, из которых 128 КБ – UMB, остальные 64 КБ – «окно» EMS-памяти.
   UMBPCI же может использовать в качестве UMB 160 килобайт памяти, чего достаточно для загрузки практически любых резидентов.

Полезные ссылки

   – http://www.mdgx.com/ – масса советов по оптимизации DOS и Windows, множество полезных утилит.
   – http://johnson.tmfc.net/dos/index.html – аналогично – множество программ и советов по оптимизации

   Удачи в борьбе за свободную память!


Артем Васильев (wormsbiysk ^ LSA)

На главную