Для отлавливания блох была сделана трассировка записей в "память" с трассировкой оригинального МАРСа на эмуляторе. Таким образом нашлось несколько опечаток (в частности, в номере бита при проверке условия перехода после СЛЦ 😒) и пропущенных зависимостей от содержимого сумматора после записи выражений в упрощенном виде.
Многие тесты стали проходить с "полным" совпадением содержимого зон БД: создание каталога областей, области длиной несколько зон, записи в неё массива, помещающегося в одну зону; массива, требующего фрагментации; замены содержимого массива на данные большей длины, и пр.
После этого я стал выносить распознанные процедуры в коде, заменяя их на честные вызовы сишных функций.
Однако, создание большого количества мелких записей и последующего их удаления с помощью итератора после успешного удаления примерно половиных из них привело к потере управления и бессмысленной ошибке "ШАГЗ.ВЕЛИК" - при полном совпадении содержимого памяти с оригинальным запуском вплоть до момента потери управления.
Оказалось, что В. И. Филиппов, мир его праху, использовал установку индекс-регистра в ноль, и где-то потом условный переход по нулю индекс-регистра, рассчитывая на то, что после ПВ куда-то по этому регистру его содержимое будет гарантированно ненулевым.
Также были замечены следующие ошибки (которые вообще-то видны и в БЕМШе):
- процедура поиска "слова-конца" в памяти (упрощённо):
fnendw уи М16 сюда входят с "-length" на См
сч base
слц length
зп work
мод work <--- переход в цикле должен быть сюда
сч (М16)
нтж endwrd
по found
цикл fnendw(М16)
Маловероятно, что ровно два битика на диске побились (00473/00475), скорее всего в метке в команде цикла была опечатка, а встроенным поиском слова-конца для вычисления длины массива или не пользовались, или, обнаружив ошибку, просто писали собственную процедуру.
Вторая ошибка заключается в следующем: имеется переменная, используемая на манер указателя на функцию, но хранится в ней разность указателей. Грубо говоря, возможные присваиваемые значения - 0, =А(ВБАЗУ-ИЗБАЗЫ), =А(СРАВН-ИЗБАЗЫ), =А(А00317-ИЗБАЗЫ). Для перехода делается МОД эта переменная, ПБ ИЗБАЗЫ. Ради каких-то целей в одном месте делается сравнение этой переменной со значением =А(ГОТОВО-ИЗБАЗЫ), какое никогда не присваивается.
В чём же дело? А вот
ГОТОВО СЧ USRLОС
СЛЦ curpos(M13)
ЗП USRLОС
А00317 ...
Возможно, когда-то инкремент usrloc += curpos делался в другом месте, и метка ГОТОВО (на которую есть явные переходы в нескольких местах) смотрела туда же, куда сейчас А00317. Потом сделали рефакторинг, метки разнеслись, и в одном месте, где упомянута разность, метку исправили, а в другом - упустили. Будущим исследователям предстоит выяснить, что же тут имелось в виду.
Трудность в том, что это происходит в коде, назначение которого неясно (как нетрудно видеть, раз метка А00317 не переименована во что-нибудь осмысленное).
Leo