Редакция 1.21. Руководство пользователя.
Распространяется на условиях GNU General Public License версии 3 (файл LICENSE).
Драйвер даёт программам MS-DOS 6.22, PC-DOS 7.0 и DR-DOS 6.0 доступ к памяти выше первого мегабайта по стандарту XMS версии 2.0. Работает с этой памятью напрямую через контроллер виртуальной памяти КА1843ВГ1 (КВП), не обращаясь к функции INT 15H AH=87h БСУВВ.
Что становится доступным:
- электронный диск
RAMDRIVE.SYS /E; - дисковый кэш
SMARTDRV; - все программы, берущие рабочую память через XMS: архиваторы, среды разработки Borland, программы сортировки и т. п.;
- верхние блоки памяти (
DOS=UMB,DEVICEHIGH,LOADHIGH) — по ключу/U.
Чего драйвер не даёт:
- области HMA (
DOS=HIGH): КВП исполняет код выше мегабайта, но база дескриптора CS одна на весь код машины — поставить её под HMA, не сдвинув остальной код, нельзя. Под монитором 286 режима драйвер объявляет HMA занятой, чтобы туда не писали ни DOS, ни Windows (раздел 12); EMM386— ему нужен процессор 80386;- расширителей DOS и Windows без монитора 286 режима — им нужен процессор 80286 и старше. Под монитором 286 режима Windows 3.0 и 3.1 в стандартном режиме работают и берут расширенную память через ECXMS (раздел 12).
В CONFIG.SYS, первой или одной из первых строк:
DEVICE=C:\ECXMS.SYS
Требование «пораньше» не формальное: драйвер должен разместиться ниже 64 Кбайт физической памяти, иначе окно переноса поставить некуда, и он откажется устанавливаться, прямо об этом сказав.
Типичные наборы:
; только расширенная память
DEVICE=C:\ECXMS.SYS
DEVICE=C:\DOS\RAMDRIVE.SYS 1024 512 64 /E
; расширенная память и верхние блоки
DEVICE=C:\ECXMS.SYS /U
DOS=UMB
DEVICEHIGH=C:\DOS\ANSI.SYS
; со стыком С2 на 9600 бит/с (модем, терминал) - см. ключ /C
DEVICE=C:\ECXMS.SYS /C:256
Пишутся в той же строке CONFIG.SYS, через пробел, в любом порядке.
| ключ | что делает | по умолчанию |
|---|---|---|
/C:nnn |
размер участка переноса в байтах, 64…16384 | 4096 |
/U |
включить окно 0E000h и отдать его, 64 Кбайт, как верхний блок | выключено |
/M:nnn |
ограничить объём расширенной памяти nnn Кбайт | весь |
/T |
проверить расширенную память записью и чтением | нет |
/H:nn |
число описателей блоков, 1…32 | 32 |
/K |
не перехватывать INT 15H | перехватывать |
/Z |
не заполнять верхние 384 Кбайт | заполнять |
/Q |
не выводить сообщений, кроме отказов | выводить |
Что это. Перенос через окно КВП идёт участками. На время каждого участка драйвер запрещает все прерывания, включая немаскируемое: пока окно открыто, обработчик прерывания получил бы смещённые базы сегментов и испортил бы память. Между участками прерывания разрешаются.
Базы дескрипторов DS и ES действуют одновременно, а физический адрес равен
«база + (сегмент × 16 + смещение) в пределах 16 разрядов» (проверено на
машине). Поэтому драйвер, как и БСУВВ, на время переноса обнуляет
сегментные регистры, и перенос «расширенная память → расширенная память»
выполняется одной REP MOVSW, без промежуточного буфера в основной памяти.
Значит, размер участка — это самая долгая пауза, в течение которой машина не отвечает на прерывания, пока идёт работа с расширенной памятью.
| /C | пауза при 8 МГц | при 4 МГц | стык С2 успевает до | потеря скорости |
|---|---|---|---|---|
| 64 | 0,11 мс | 0,19 мс | 51 000 бит/с | ≈ 22% |
| 128 | 0,19 мс | 0,35 мс | 28 000 бит/с | ≈ 12% |
| 256 | 0,36 мс | 0,65 мс | 15 000 бит/с | ≈ 6% |
| 512 | 0,69 мс | 1,26 мс | 7 900 бит/с | ≈ 3% |
| 1024 | 1,37 мс | 2,47 мс | 4 000 бит/с | ≈ 1,5% |
| 2048 | 2,71 мс | 4,91 мс | 2 000 бит/с | ≈ 1% |
| 4096 | 5,40 мс | 9,77 мс | 1 000 бит/с | — |
| 8192 | 10,8 мс | 19,5 мс | 510 бит/с | прибавки нет |
| 16384 | 21,5 мс | 39,0 мс | 250 бит/с | прибавки нет |
Паузы посчитаны с учётом тактов ожидания по ТО1 п.4.7: обращение к памяти
через КВП получает 2 лишних такта при 8 МГц и 1 при 4 МГц; при переносе
слова обращений два — чтение и запись. Итого REP MOVSW — около 21 такта
на слово при 8 МГц и 19 при 4 МГц.
Столбец «стык С2 успевает до» дан для худшего случая — частоты 4 МГц, то есть при отключённом ускорении. Он рассчитан так: адаптер стыка С2 собран на КР580ВВ51А, у которого приёмный буфер на один знак; знак при восьми разрядах данных и одном стоповом занимает десять тактов стыка; если за время паузы приходит второй знак, первый затирается.
Когда уменьшать.
-
Работаете со стыком С2 — модем, терминал, передача файлов по нуль-модему — одновременно с электронным диском или дисковым кэшем. Это главный случай. При участке по умолчанию стык в момент переноса надёжно принимает лишь около 1100 бит/с, на больших скоростях знаки теряются.
скорость стыка ключ до 1200 бит/с не нужен при 8 МГц; при 4 МГц — /C:20482400 /C:10244800 /C:5129600 /C:25619 200 /C:128 -
Нужна точная выдержка времени через INT 15H AH=86h. Её отсчитывают часы реального времени прерыванием 1024 раза в секунду, то есть каждые 0,98 мс. Пауза длиннее этого срока сливает несколько тиков в один, и выдержка затягивается. Для точной работы —
/C:512при 8 МГц или/C:256при 4 МГц. -
Диагностика. Если данные на электронном диске портятся, повторите проверку с
/C:512. Если с малым участком данные целы, а с обычным нет — дело в длинных обращениях к памяти, а не в самом переносе.
Когда увеличивать. Практически никогда. Перенастройка дескрипторов КВП на каждом участке стоит около 160 тактов, а перенос 4 Кбайт — около 35 000. Увеличение участка сверх 4096 байт ускоряет работу меньше чем на полпроцента, а паузу удлиняет вдвое и вчетверо.
Чего бояться не надо. Системный таймер тикает раз в 55 мс, так что даже наибольший участок при 4 МГц тиков не теряет. Клавиатура буферизуется контроллером, НГМД работает через прямой доступ к памяти. Эти устройства пауз не замечают.
Значения меньше 64 и больше 16384 не принимаются, нечётное округляется вниз.
Включает разрядом 4 порта 73h окно 0E000h–0EFFFh, куда подаётся часть области в 384 Кбайт, обычно уходящей в расширенную память, и отдаёт его DOS целиком, 64 Кбайт, как верхний блок. Уменьшать блок смысла нет.
Подробности, цена и совместимость — в разделе 6.
Драйвер будет раздавать не больше nnn Кбайт. Больше найденного не станет.
/M:0 означает «без ограничения».
Сочетается с /U правильно: если /M уже отрезал верхние 384 Кбайт,
включение окна объём не уменьшает. И наоборот, если /M оставил часть
этой области в раздаче, она всё равно заполняется при установке.
Нужен, если часть расширенной памяти должна остаться другой программе,
которая работает с ней напрямую.
При установке записывает образец в первый и последний килобайт расширенной памяти, читает обратно и сверяет. Неисправный модуль обнаруживается сразу, а не через час работы с электронным диском.
Self test of extended memory... passed.
Сколько блоков расширенной памяти можно раздать одновременно. Каждый описатель занимает 8 байт постоянной части драйвера. Уменьшать имеет смысл, только если важен каждый байт нижней памяти.
По умолчанию после установки функция INT 15H AH=88h отвечает нулём: иначе программа, не знающая об XMS, взяла бы расширенную память в обход драйвера и затоптала чужие блоки. Так поступает и HIMEM.
Отменять перехват нужно, только если какая-то программа отказывается работать, не видя расширенной памяти по INT 15H, и при этом с XMS она не работает.
Отменяет заполнение верхних 384 Кбайт при установке. Самотестирование проверяет эту область записью, но не всегда: проверку прерывает Esc, а при горячей перезагрузке её нет вовсе (раздел 7). Если тогда программа прочитает блок XMS в этой области до записи в него, при разрешённом NMI машина остановится ошибкой чётности. Ключ имеет смысл, только если машина всегда загружается холодным пуском с полной проверкой памяти.
Выводятся только сообщения об отказе от установки.
Каждая строка отвечает своему шагу установки. Если вывод оборвался, последняя строка указывает место.
ECXMS 1.21 - EC-1842 extended memory via the KVP
Драйвер получил управление.
INT 15H AH=88h returned: 4480
Extended memory found: 4480 KB
Объём по данным БСУВВ. Оба числа должны совпадать.
Move window placed at physical address XXXXh
Драйвер лежит ниже 64 Кбайт, окно переноса размещено.
Self test of extended memory... passed.
Только с ключом /T.
Switching the 384 KB block into the 0E000h window...
The whole 384 KB left extended memory for it. Extended is now 4096 KB
Window filled with zeroes: parity bits set, memory verified.
Upper memory block at 0E000h, 64 KB.
Do NOT run M286.COM while this block is in use: ...
Только с ключом /U.
Top 384 KB: setting parity bits (the memory test may have been skipped)... done.
Только без ключа /U.
Stack guard intact.
Driver installed. HMA and UMB are not available.
Установлен. При /U последняя строка сообщает о верхнем блоке.
| сообщение | причина |
|---|---|
No extended memory found. |
БСУВВ сообщает, что расширенной памяти нет |
An XMS driver is already installed. |
другой драйвер XMS уже загружен |
A VDISK driver already owns the extended memory. |
память занята драйвером VDISK |
Driver loaded above 64 KB... |
поставьте строку в CONFIG.SYS раньше |
WARNING: stack guard damaged... |
не хватило стека при установке — сообщите |
Драйвер выполняет все функции описания XMS 2.0. Соответствие проверено выполнением каждой функции, всего 29 проверок, включая отказы.
| AH | функция | вход | выход |
|---|---|---|---|
| 00h | версия | — | AX=0200h, BX=0111h, DX=0 (HMA нет) |
| 01h | запросить HMA | DX | AX=0, BL=90h |
| 02h | освободить HMA | — | AX=0, BL=90h |
| 03h | включить A20 глобально | — | AX=1 |
| 04h | выключить A20 глобально | — | AX=1 |
| 05h | включить A20 местно | — | AX=1 |
| 06h | выключить A20 местно | — | AX=1 |
| 07h | состояние A20 | — | AX=1 или 0 |
| 08h | сколько свободно | — | AX=наибольший блок, DX=всего, Кбайт |
| 09h | выделить блок | DX=Кбайт | AX=1, DX=описатель |
| 0Ah | освободить блок | DX=описатель | AX=1 |
| 0Bh | перенести | DS:SI=описание переноса | AX=1 |
| 0Ch | запереть блок | DX=описатель | AX=1, DX:BX=линейный адрес |
| 0Dh | отпереть блок | DX=описатель | AX=1 |
| 0Eh | сведения о блоке | DX=описатель | AX=1, BH=запираний, BL=своб. описателей, DX=Кбайт |
| 0Fh | изменить размер | DX=описатель, BX=Кбайт | AX=1 |
| 10h | запросить верхний блок | DX=параграфов | AX=1, BX=сегмент, DX=параграфов |
| 11h | освободить верхний блок | DX=сегмент | AX=1 |
Все регистры, кроме возвращающих значение, сохраняются.
Вентиль A20. Его в машине нет. Функции 03h–07h ведут учёт запросов и сообщают об успехе, чтобы не ломать программы, которые включают A20 перед пересылкой. Области HMA драйвер не обещает, поэтому обращаться к адресам FFFF:xxxx программам незачем.
Функция 0Bh. Длина должна быть чётной. Области могут перекрываться в любую сторону — драйвер сам выбирает направление обхода. Описание XMS требует правильной работы только при переносе вперёд; здесь правильно работает и назад.
Функция 0Fh. Уменьшение выполняется всегда. При увеличении, если следом за блоком нет места, драйвер ищет новое, переносит туда содержимое и освобождает старое. Проверено: 16 Кбайт данных после переезда целы.
| BL | значение |
|---|---|
| 80h | функция не реализована |
| 90h | области HMA нет |
| 0A0h | вся расширенная память роздана |
| 0A1h | описатели кончились |
| 0A2h | неверный описатель |
| 0A3h | неверный описатель источника |
| 0A4h | неверное смещение источника |
| 0A5h | неверный описатель приёмника |
| 0A6h | неверное смещение приёмника |
| 0A7h | неверная (нечётная) длина |
| 0A9h | повторный вход в функцию переноса |
| 0AAh | блок не заперт |
| 0ABh | блок заперт |
| 0ACh | переполнение счётчика запираний |
| 0B0h | есть только блок меньшего размера (DX = его размер) |
| 0B1h | верхних блоков нет |
| 0B2h | неверный сегмент верхнего блока |
Код 0A9h в описании XMS означает ошибку чётности; здесь он употреблён для случая, когда функцию переноса вызвали повторно из обработчика прерывания посреди другого переноса.
Область в 384 Кбайт — это часть первого мегабайта на плате процессора, закрытая видеопамятью и ПЗУ. Порт 73h подаёт её либо за границу мегабайта, либо в окно 0E000h–0EFFFh.
По умолчанию (после любой перезагрузки) окно выключено, и эти 384 Кбайт идут как расширенная память.
С ключом /U драйвер:
- устанавливает разряд 4 порта 73h и обнуляет разряды 1–3 — ровно так, как это делает загрузчик эмулятора команд 286; разряд 0 сохраняет;
- проверяет окно двумя соседними ячейками разными значениями — так, чтобы не обмануться плавающей шиной;
- проходит записью всё окно целиком — на случай, если проверка памяти при загрузке была пропущена: тогда первое же чтение из окна дало бы ошибку чётности (раздел 7);
- отдаёт окно как верхний блок.
Если окно не отозвалось, всё возвращается как было: порт 73h, объём расширенной памяти, признаки. Печатается, что именно прочиталось из окна.
Из расширенной памяти уходят все 384 Кбайт, а в окне видны только 64. Остальные 320 недоступны. Стоит того, если нужны верхние блоки: нижней памяти не хватает всегда, а расширенной на машине несколько мегабайт.
Загрузчик M286.COM заполняет все 64 Кбайт окна числом 55h и только
потом кладёт туда себя: код по E000:0000, данные по E800:0000, теневой
стек на E800:4000. Делить окно с ним нельзя.
- Пока действует
/U, запускатьM286.COMнельзя — он затрёт всё, что DOS разместила в верхней памяти. - Если эмулятор уже в памяти к моменту установки драйвера, верхний блок не выдаётся вовсе.
Выбирать придётся: верхние блоки или эмулятор. Эмулятор нужен только
программам, использующим команды 80186/286, которых у КМ1810ВМ86М нет
(BOUND, IMUL с непосредственным операндом, сдвиги на непосредственную
величину, ENTER), — обычно собранным с директивой .186 или .286.
M286.COM — файл типа COM, его место в AUTOEXEC.BAT, то есть он
запускается уже после обработки CONFIG.SYS. Поэтому окно для верхних
блоков должен включать сам драйвер: к моменту обработки DOS=UMB больше
некому.
Память на плате процессора ЕС-1842, в том числе область 384 Кбайт, имеет контроль чётности.
У памяти с контролем чётности, в которую ни разу не писали после включения питания, разряды чётности не установлены, и первое же чтение даёт ошибку чётности — при разрешённом NMI это немаскируемое прерывание и остановка машины обработчиком БСУВВ.
Подпрограмма add_384k БСУВВ прибавляет эти 384 Кбайт к объёму
расширенной памяти, а проверяет их сразу за ней ext_test_start — той же
записью, что и всю расширенную память. Значит при обычной загрузке
паритет в этих 384 Кбайт установлен, и заполнение драйвером не нужно.
Но проверка выполняется не всегда: ext_test_start прерывается клавишей
«Esc», а при горячей перезагрузке (УПР+АЛТ+УД) самотестирование её
пропускает. Если перед этим после включения питания в область не писали,
разряды чётности там не установлены, и первое же чтение при разрешённом
NMI остановит машину. Заполнение драйвером — страховка на эти случаи: при
полной проверке оно безвредно, при пропущенной необходимо.
NMI после загрузки DOS обычно запрещено (DOS читает часы, а функции часов БСУВВ запрещают NMI побочно), но драйвер после каждого переноса его разрешает — так же, как функция INT 15h AH=87h самой БСУВВ.
Поэтому драйвер при установке проходит эту область записью:
- без
/U— все 384 Кбайт наверху расширенной памяти; - с
/U— 64 Кбайт окна 0E000h; остальные 320 недоступны никому.
Признак того, что область была прибавлена, — остаток от деления объёма на 1024 равен 384. Заполнение занимает около полусекунды при 8 МГц и около секунды при 4 МГц.
| среда | состояние |
|---|---|
| MS-DOS 6.22 | проверено: RAMDRIVE /E, SMARTDRV, DOS=UMB, DEVICEHIGH |
| PC-DOS 7.0 | проверено |
| DR-DOS 6.0 | должна работать: драйвер следует описанию XMS 2.0 |
DOS=HIGH |
неприменимо: без монитора области HMA нет, под монитором 286 режима она объявлена занятой |
EMM386 |
неприменимо: нужен процессор 80386 |
| расширители DOS, Windows | без монитора 286 режима неприменимо: нужен 80286 и старше; под монитором 286 режима Windows 3.0 и 3.1 в стандартном режиме работают |
M286.COM |
несовместим с /U |
Программы, работающие через XMS 2.0: RAMDRIVE, SMARTDRV, архиваторы
PKZIP, ARJ, LHA, среды Turbo Pascal и Turbo C, Norton Utilities, программы
сортировки и работы с базами данных.
Вывод оборвался при загрузке. Последняя напечатанная строка
указывает шаг (раздел 4). Загрузитесь с дискеты без CONFIG.SYS
и уберите строку.
Driver loaded above 64 KB. Поставьте DEVICE=ECXMS.SYS выше,
перед другими драйверами.
Теряются знаки на стыке С2. Уменьшите участок ключом /C, таблица
в разделе 3.1.
Данные на электронном диске портятся. Повторите с /C:512
и сообщите, помогло ли.
С /U окно не отозвалось. Порт 73h возвращён как был, драйвер
работает без верхних блоков. Два числа из строки Window test read back
стоит сохранить: по ним видно, отвечает ли шина.
Зависание или ошибка чётности при обращении к верхней памяти.
Проверьте, не запущен ли M286.COM.
Исходник рассчитан на MASM 4.x/5.x. Для сборки на самой ЕС-1842 файл надо перевести в кодировку, в которой машина показывает русский текст, — ISO-8859-5; сообщения драйвера на английском и от кодировки не зависят.
masm ecxms.asm, ecxms.obj;
link ecxms.obj;
exe2bin ecxms.exe ecxms.sys
Компоновщик предупредит об отсутствии сегмента стека — так и должно быть.
В исходнике не употребляются команды 80186 и старше, в том числе
PUSHA, POPA и сдвиги на непосредственную величину. Директиву .186
включать нельзя.
| проверка | итог |
|---|---|
| соответствие собранного кода исходнику | 1416 команд, расхождений 0 |
| команды вне набора 8086 | 0 |
| функции XMS по описанию 2.0 | 29 из 29 |
| все сочетания восьми ключей, включая неверные значения, в разном порядке и регистре | 2844 из 2844 |
| перенос длин от 2 до 65 538 байт при участках 64, 512, 4096 | расхождений 0 |
| перенос с перекрытием областей в обе стороны | верно |
| переезд блока при увеличении размера | данные целы |
| срабатывания NMI при установке в любых сочетаниях ключей | 0 |
| на машине: электронный диск, дисковый кэш | работают |
на машине: DOS=UMB, DEVICEHIGH, чтение и запись в окно |
работают |
Если при загрузке есть монитор 286 режима (INT 15h AX=4D32h отвечает 324Dh), ECXMS работает в режиме монитора: КВП программам закрыт, поэтому переносы идут через INT 15h AH=87h (его выполняет сам монитор); проб через КВП нет; A20 считается всегда включённой; HMA объявлена существующей, но занятой (запрос - ошибка 91h), чтобы ни DOS, ни Windows туда не писали. Версия драйвера сообщается как 2.60
- WIN.COM Windows 3.0 требует HIMEM не ниже 2.60. После установки ECXMS сообщает монитору (INT 15h AX=4D33h), и INT 15h AH=88h для остальных программ возвращает 0: вся расширенная память - за XMS.
Функции XMS возвращают только те регистры, которые им положено возвращать по описанию XMS 2.0; остальные (в том числе BX и DX) сохраняются. В 1.20 функции 03h–06h, 09h, 0Bh, 0Dh, 0Fh и 0Ah портили BX, а перенос (0Bh) и изменение размера (0Fh) — ещё и DX. Программы, которые держат в этих регистрах свои значения между вызовами (например, загрузчик оверлеев ASTRA), после этого работали неверно и зависали.
Эта программа — свободное программное обеспечение: её можно распространять и изменять на условиях GNU General Public License версии 3, опубликованной Free Software Foundation. Программа распространяется без каких-либо гарантий. Полный текст лицензии — в файле LICENSE.