Баг теста паттерна таймингов mmcm.

Разбираясь с проблемой неработоспособности программы mmcm.tap в Спектрамине под моделью +3, выяснил, что проблема не в эмуляторе, это баг процедуры определения типа таймингов.

Суть бага — процедура определения типа таймингов зависима от состояния системной переменной FRAMES (#5C78) на момент своего старта.

Прилагаю два SZX файла: mega.nz/#!Zq5RQbrb!ISHMXpxYkr2z3iVOzqAGOoTjq8pxuWAgZHo0cZA8gTU
Один из них отрабатывает корректно — mmcm-correct.szx,
второй — mmcm-wrong.szx — выдает сообщение о нераспознанном паттерне таймингов.

но если в первом вбить в ячейку #5C78 значение #1F, он выдает сообщение о нераспознанном паттерне,
а если во втором в ту же ячейку вбить #F9 — он благополучно проходит тест.

Так что это баг не эмулятора, а программы. Проверено на SpecEmu и Spectaculator. То есть на реальном +3 она иногда загрузится без проблем, а иногда выведет сообщение о нераспознанных таймингах.

5 комментариев

avatar
Очень круто что ты поймал этот баг — я не наблюдал его ни разу.

Суть бага не в состоянии описанной тобой переменной. Мой код действительно берёт значение этой переменной, но использует его исключительно для инициализации генератора ПСЧ. А проблема происходит из-за того, что за 12 прогонов счётчика, программа оказалась не в состоянии выровняться на фрейм. На самом деле я слегка обсчитался. Конец цикла сделан по конкретному значению в B. За один фрейм в B вдвигается один бит. Все биты в B заменятся за 8 итераций счётчика в D. Если не повезёт, нужно будет сделать ещё до 3-х дополнительных итераций для того, чтобы сдвинуть паттерн битов в B в правильное положение. Именно поэтому в D кладётся значение 8+3=11. Ошибка же вот в чём: первая итерация в D считаться не должна, т.к. первый вход в цикл происходит где-то посередине фрейма, неизвестно где именно. Поэтому оказывается, что если самый первый бит оказался неверным и если нам так не повезло, что паттерн сдвигов именно что требует 11 итераций, одной итерации может не хватить до нормального выравнивания.

Это можно проверить следующим образом. В файле mmcm-wrong.szx поставь break point на #8000, чтобы отловить запуск модуля определения железа. Когда код встанет, в отладчике внеси в ячейку #8DE9 значение #0C вместо #0B которое там лежит сейчас. Тогда код запустится успешно.

Есть и плохая новость. По идее, описанный баг вполне может произойти на любой машине (кроме жёлтого скорпиона). А поскольку я использую этот код выравнивания на такт уже давно, думаю, что описанный баг может проявиться в любой из моих программ с мультиколором. Увы…
avatar
Это ты его поймал) а я его вытащил на поверхность, выясняя, что не так с эмулем. Ну зато с эмулем тут всё ок)
avatar
Так у этой задачи таки есть точное решение? С бородатых времен, когда тайминг подстраивали вручную (первые настройщики были «нажми кнопку и нажимай пока не совпадет») осталось ощущение, что там остается определенная неопределенность Гезенберга…
avatar
Алон Кодер решил эту проблему много лет назад. В 1990е тоже должны были быть решения этой задачи, например у Code Busters, но они не делились своими методами, насколько я знаю.
avatar
Да, вспомнил что у Робуса тоже должно быть своё решение, т.к. OSCOSS без этого не напишешь.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.