Главная / Статьи / Формат .ms14

Как устроен файл .ms14 и почему Multisim молча отказывается его открывать

Разбор формата NI Multisim 14 — по следам того, как навык учился писать такие файлы.

Чтобы нейросеть отдавала не «инструкцию, как нарисовать», а готовый файл, сначала пришлось понять, что такое .ms14 изнутри. Оказалось, что это история про алгоритм сжатия из восьмидесятых, капризный XML и программу, которая никогда не объясняет, почему не открывает файл.

Снаружи: заголовок и чанки

Файл начинается с 36-байтной ASCII-строки MSMCompressedElectronicsWorkbenchXML, затем два 32-битных числа: полный размер XML и ноль. Дальше идут чанки: размер распакованных данных (до 900 000 байт), размер сжатых и сами данные.

"MSMCompressedElectronicsWorkbenchXML"   36 байт
uint32  размер XML
uint32  0
чанки:  uint32 распакованный | uint32 сжатый | данные

Сжатие: PKWARE DCL implode

Данные сжаты алгоритмом PKWARE Data Compression Library — implode с ASCII-литералами и словарём 4 КБ. Распаковщик — порт классического blast.c Марка Адлера. А вот со сжатием вышла первая ловушка: поток из одних литералов формально корректен, распаковщик его читает, но Multisim такой файл молча не открывает. Пришлось написать полноценный implode с поиском совпадений. Чтобы он был быстрым на Python, поиск идёт через встроенный bytes.rfind, а коды Хаффмана развёрнуты заранее.

Внутри: XML с сюрпризом

Под сжатием — XML. Вторая ловушка: в значениях атрибутов встречаются настоящие переводы строк. Любой XML-парсер по стандарту их нормализует, и после пересохранения Multisim снова молча отказывается открывать файл. Решение — перед разбором заменить переводы строк внутри атрибутов на 
, а при записи вернуть обратно. Пересериализация оригинала после этого даёт файл байт в байт.

Строки Multisim хранит в двух видах: &ASC… для ASCII и &UNI… с шестнадцатеричными вставками для Юникода. Графика (символы, провода, точки) и электрика (компоненты, порты, узлы) лежат в разных ветках документа и связаны числовыми ID.

Детали: клонировать, а не синтезировать

Первая версия собирала элементы «синтезом»: брала резистор и подменяла SPICE-шаблон, модель и рисунок. Конденсатор так получился — но Multisim показывал его ёмкость в омах: подпись номинала строится по коду типа, а код остался от резистора.

Правильный путь — переносить элемент целиком из файла, сохранённого самим Multisim: символ, SPICE-модель, запись базы, окно свойств. Такой элемент неотличим от поставленного руками. Источники — примеры, которые ставятся с Multisim, и сам Multisim: в его интерфейсе автоматизации есть ReplaceComponent, которым можно заменить заготовку в шаблоне любой деталью базы и сохранить файл.

Из 14 МБ файлов-доноров вырезаются только блоки деталей — по 3–4 КБ. Весь каталог из ~250 деталей занимает около мегабайта.

Ловушки, найденные только в Multisim

  • Переименование проекта. Безобидная правка имени внутри файла — и он перестаёт открываться. Имя листа остаётся от образца.
  • Одинаковые GUID. Два файла, собранные на одной основе, имели одинаковые GUID. Открытые одновременно, они путались: мультиметр останавливал моделирование, показания замирали. Теперь все GUID новые и зависят от имени файла — сборка остаётся повторяемой.
  • «This circuit has no power sources». КМОП-инвертор в покое не потребляет ток, и Multisim не может сам выбрать шаг моделирования. Помогает записать шаг TMAX = 10 мкс прямо в файл.
  • Прыгающий ключ. У переключателя есть кадры анимации, их нужно поворачивать вместе с символом — иначе при нажатии ключ прыгает на старое место.
  • Перевёрнутая надпись. У интерактивного источника есть отдельная надпись с показанием; если вращать её как графику, она зеркалится.

Проверка без Multisim

Нетлист для ngspice собирается из того же XML, который увидит Multisim, а шаблоны деталей разворачиваются по тем же правилам. Две находки: модели ОУ Multisim пишут ток как 1.516e-005A — Multisim букву «A» игнорирует, а ngspice читает её как «атто» (10⁻¹⁸); мультиметр Multisim — это вольтметр на 1 ГОм, и без такой нагрузки разомкнутый выход в ngspice «висит». После этих правок для схемы SN74LS00 ngspice дал 0,530 В, а мультиметр в Multisim — 529,947 мВ.

Итог

Формат .ms14 прост, пока его читаешь, и коварен, когда пишешь: почти каждая ошибка проявляется одинаково — файл просто не открывается. Всё найденное собрано в reference.md проекта.

← Все статьи