Начальная

Windows Commander

Far
WinNavigator
Frigate
Norton Commander
WinNC
Dos Navigator
Servant Salamander
Turbo Browser

Winamp, Skins, Plugins
Необходимые Утилиты
Текстовые редакторы
Юмор

File managers and best utilites

Журнал ЖЖ. Мк 61 эмулятор


Эмулятор МК-61 на Андроиде - Stanislav Borutsky

Эмулятор МК-61 на Андроиде - Stanislav Borutsky

[Свежие записи][Архив][Друзья][Личная информация]

05:06 pm

[Ссылка]

Эмулятор МК-61 на АндроидеРешил испытать силушку свою программистскую на поприще мобильных приложений, и написал то, что сам долго ждал.Ждал много лет, что, наконец, появится, да не дождался.А именно - программируемый калькулятор "Электроника МК 61", с которого и началось моё очное и близкое знакомство с вычислительной техникой в далёком 1986-м году.Кто знает, что это за зверь и в детстве выписывал "Технику-Молодёжи" с "Наукой и жизнью", в дальнейших пояснениях не нуждается.

Моя аппликация использует результаты гениального исследования человека с очень мощным микроскопом, реверс-инженера и программиста Феликса Лазарева, автора проекта emu145. Благодаря ему эмулятор в мельчайших подробностях повторяет поведение настоящего калькулятора, со всеми его недокументированными возможностями. Достигается это благодаря прямому исполнению микрокода, который Феликс "вытащил" микроскопом из микросхем калькулятора.

Чем эмулятор от симулятора отличается, и какая неонка внутри у моей аппликации - читайте у мэтра калькуляторных наук и хранителя музея советских калькуляторов Сергея Фролова здесь.

А сам калькулятор для телефонов/планшетов на Андроиде можно скачать в Google Play. Он так и называется - "МК 61".

Tags: programming, ностальгия

 
From:Date:
raydac
Декабрь 12, 2013 12:02 pm
(Link)

клева, надо будет сравнить с поведением реального который в столе лежит

From:Date:
raydac
Декабрь 12, 2013 01:27 pm
(Link)
под HTC Legend с Android 2.1 вроде как нормально заработалпара замечаний для HTC Legend1. при первом старте мне показалось что приложение убило телефон, жкран вырубился исекунд 8 ничего не происходило, как понимаю приложение производило инициализацию какую то при первом пуске, лучше что то писать на экране при таком2. было бы очень хорошо ускорить старт, сейчас старт 1.5 секунды где то

Edited at 2013-12-12 16:08 (UTC)

From:Date:
cax
Декабрь 12, 2013 07:36 pm
(Link)

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

From:Date:
raydac
Декабрь 12, 2013 07:38 pm
(Link)

там отрисовывается на лету чтоль при старте? а то может один раз отрисовав сохранить картинку целиком в кэщ и оттуда грузить?

From:Date:
cax
Декабрь 12, 2013 08:46 pm
(Link)

Давайте так:Вы изучите Android SDK вместе с его особенностями поведения на относительно старых и неоптимизированных версиях Андроида и, по современным меркам, медленных телефонах с не очень большим объёмом оперативной памяти, поэкспериментируете и пришлёте мне готовый фрагмент кода, который либо будет кешировать картинку, либо будет оптимизировать поведение программы каким-либо иным способом.Я с удовольствием воспользуюсь Вашей помощью, т.к. ограничен во времени и не имею подобных телефонов для тестирования и экспериментов.

From:Date:
raydac
Декабрь 13, 2013 05:01 am
(Link)

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

From:Date:
cax
Декабрь 12, 2013 07:38 pm
(Link)

Сравнивайте :) Будете приятно удивлены.

Ещё не пробовал, но уже восхищён!

From:Date:
winpooh
Декабрь 12, 2013 04:29 pm
(Link)

Спасибо за программу! И сразу - запрос от пользователя. Можно ли в некоторых слотах поместить предустановленные программы - главные хиты, вроде "Лунолётов"?

From:Date:
cax
Декабрь 12, 2013 07:38 pm
(Link)

Набейте программу сами - получите неописуемый ностальгический восторг, особенно если будут ошибки при наборе :)

From:Date:
winpooh
Декабрь 16, 2013 09:23 am
(Link)
Набил, летает. Вроде, всё как положено.Правда, "юнит тест" из журнала не проходит.Я имею в виду вот эту статью: http://epizodsspace.no-ip.org/bibl/tm/1985/6/istinn-prav.htmlПервый шаг - 65 кг топлива за 3 секунды. В статье он приводит к перегрузке выше 3g, и выводу сообщения об ошибке.У меня лунолёт оказывается где-то в 100 метрах над Луной, без аварийной ситуации.

Могут какие-то ошибки в арифметике происходить, или это исключено?

From:Date:
cax
Апрель 12, 2014 02:53 am
(Link)
Наконец-то, в честь дня космонавтики, я нашёл время проверить "юнит тест".Вынужден Вас расстроить (а может быть и обрадовать) - тест проходит в точности по журналу, с перегрузкой, и опосля неё - с высотой 169.16425 и скоростью 84.112449

Я не поленился и проверил (на всякий случай) в обоих режимах эмуляции - МК-54 и МК-61.По ходу дела (как и 28 лет назад) я делал ошибки в наборе, и лунолёт заносило черти куда, но как только я перепроверил и поправил неверно набранную программу и регистры, всё сразу же устаканилось.Полагаю, что и у Вас где-то ошибочка в наборе вышла.

Edited at 2014-04-12 02:55 (UTC)

From:Date:
winpooh
Декабрь 16, 2013 09:26 am
(Link)

Кстати, вот ещё пожелание, которое очень легко реализовать. Сделать вычисление контрольной суммы программы (или всего состояния калькулятора). Отлавливать ошибочно введённые программы сразу станет легче.

Ух ты, класс. :)Если бы еще и на айпаде...

Поставил на MIPS-based таблет (Ainol Novo7) - внешний вид отличный, но страшно тормозит. Каждое нажатие клавиши отрабатывается за две-три секунды.

На другом MIPS-таблете (Actions ATM7019) совсем другие проблемы. Все вполне шустро, но:1) Цифровой индикатор съехал вниз, видна только верхняя половина цифр.2) Обозначения на клавишах чуть крупноватя и смещены на несколько пикселов ниже оптимума.

Edited at 2013-12-12 19:22 (UTC)

From:Date:
cax
Декабрь 12, 2013 07:35 pm
(Link)

Ainol Novo: проверьте как ведёт себя эмулятор в быстром режиме (переключение бысто/медленно нажатием на индикатор), помогает ли это быстродействию.Actions ATM7019: в меню есть настройки размеров надписей, попронуйте их уменьшить.

Ура, помогло и то и другое. Спасибо! И вообще, великолепная затея.

cax.livejournal.com

Путь программиста - 1: МК-61

Я - программист, причем хотел им стать еще с детства. Но в моем детстве далеко не сразу появился вожделенный ПК, поэтому мой путь был извилист. Попробую напрячь свою память и приглашаю в путешествие по ключевым этапам.

Первым устройством, с которого началось мое знакомство с IT и программированием, пожалуй стал программируемый микрокалькулятор Электроника МК-61.

Дома он появился, когда я был еще маленьким, причем, хотя мои родители инженеры, я не помню, чтобы кто-то из них всерьез работал с ним и раскрывал его потенциал. На тот момент я учился в младших классах и, соответственно, знал арифметические операции и умел работать с простым калькулятором. Но МК-61 - это вам не простой калькулятор! Поясню - чтобы сложить 2 и 3 на обычном калькуляторе нажимаем так: "2", "+", "3", "=" и вуаля, а на МК-61: "2", "вэ-со-стрелочкой", "3", "+". И это просто взрывало мой детский мозг - где кнопка "=", что за ужас? Много позже (вроде уже на первом курсе КПИ) я узнал, что это называется "обратная польская запись". В общем пользоваться им для своих простых расчетов я не любил, но загадочный аппарат с большим количеством кнопочек и непонятных надписей все же интриговал и притягивал-дразнил-манил детскую любознательность-любопытство.

Вот как выглядел этот зверь-монстр:

(та самая упомянутая "вэ-со-стрелочкой" - внизу справа, "В↑")

В комплекте была толстая книжечка-инструкция, которую я периодически безуспешно пытался осилить. [PDF ~6Mb]

И может так бы все бесславно и закончилось, но в то время программы для таких микрокалькуляторов печатали в журналах и выходили даже целые книги. Причем не только какие-то скучные заумные расчеты, а и настоящие игры! Игры - вот настоящий двигатель интереса ребенка! Где-то через одноклассников, знакомых или из библиотеки удавалось доставать эти игры, а самые интересные обязательно переписывались в тетрадку от руки. Выглядели они примерно так:

Для непосвященного - адская абракадабра. Первое время я даже не пытался вникнуть в суть буквочек-и-цифирок, а просто научился старательно и дотошно вводить эти заклинания, магические письмена в недра могучего устройства-аппарата-МК-61. Без навыка уходило просто уйма времени на то, чтобы загнать всю программу (ну это чем-то похоже как печатать свой первый текст на клавиатуре компьютера: пока найдешь нужную букву - уже забудешь что хотел изобразить). А выключишь калькулятор - и все, в следующий раз надо снова начинать с чистого листа.

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

Мне тогда попалась отличная книга - А. Г. Гайштут "Калькулятор - твой помощник и соперник в играх" [DOC ~13Mb]

Кстати занятное предисловие ;)

Или вот еще, для примера, "Пещера сокровищ" в журнале "Техника молодежи"

Сейчас наверно трудно представить - как это, игры на калькуляторе? Попробую вкратце пояснить. Кроме цифр калькулятор мог отобразить на экране еще некоторые символы (Г, С, Е, L, -), плюс некоторые цифры очень похожи на буквы (0 - O, 1 - i или l, 2 - рукописное г, 3 - з, 4 - ч, 5 - s, 6 - б, 8 - в, 9 - рукописное д). Так что можно было даже вывести на экран некоторые "слова". Не говоря уже о культовом сообщении "ЕГГОГ" (error, ошибка, которая возникала, например, при делении на ноль или умножении двух огромных чисел). Большинство игр строились по такой схеме: запускаем программу, некоторое время идут вычисления, потом программа останавливается и выдает некоторое сообщение (число, два числа через десятичную запятую, некий набор условных символов, "слово"), которое характеризует текущую ситуацию (текущую скорость, высоту, радиус изгиба трассы, количество топлива, ход калькулятора), ты ее анализируешь, вводишь условленную команду (тормозить, разгоняться, ничего не делать, повернуть, поставить крестик в клетку X) и снова запускаешь программу. Этот цикл повторялся либо до победы-финиша, либо до поражения (разбился, закончилось топливо). Но были еще адские игры, которые не останавливались и не давали времени на раздумья - нужно было внимательно вглядываться в мерцание чисел на экране (во время исполнения программы на экран кратковременно выводились промежуточные результаты очередной команды), чтобы уловить демонстрируемую иногда ситуацию и отреагировать (например, игра "вратарь", в какой-то момент мелькало что-то типа "1008.001", где 1 - это границы ворот, 0 - пустое место, 8 - позиция вратаря, а . - мяч и нужно было срочно дергать переключатель Р-ГРД-Г (радианы-грады-градусы), чтобы "прыгнуть" влево/вправо или остаться на месте). Вот и все, подключаем фантазию - и мы уже мчимся-прыгаем-стреляем.

Со временем я все же немного разобрался и начал сам составлять несложные программы (первая вроде была вычисление корней квадратного уравнения), но многие тонкости-нюансы так и остались за пределами моего понимания.

Продолжение: Путь программиста - 2: Бейсик для детей

P.S. Интересно что до сих пор есть энтузиасты программируемых микрокалькуляторов:Эмулятор МК-61 Android, iOS, вебИгровые программы для МК-52, МК-61

alik-ntu.livejournal.com

Перенос эмулятора МК-61 на платформу msp430

От редактора. Текст Алексея Сугоняева (digitalinvitro) является итогом многих недель работы по переносу кода существующих эмуляторов МК-61 на аппаратную платформу msp430. Работе сопутствовали обсуждения на нашем форуме и активная переписка, отражавшая текущий ход событий. Много времени было потрачено на оптимизацию: первоначальные варианты эмулятора работали в разы медленнее оригинала 35-летней давности! Алексею пришлось не просто оптимизировать код, а менять некоторые принципы. К слову, на практике выяснилось, что генерируемый компилятором Си код, как правило, не хуже ассемблерного, а накладные расходы Си++ касаются памяти, а не быстродействия. О ходе этой увлекательной работы я попросил Алексея написать статью. Надеемся, она будет не только интересна любителям советских ПМК, но даст возможность развивать поднятую тему.

Текущее состояние макета на фото, предоставленное Алексеем. В качестве прототипа используется калькулятор МК-51.

На правах вступительного слова

За эмуляцию комплекта К145ИК130x мне приходилось уже один раз браться, в прошлый раз меня на это сподвиг призыв Феликса Лазарева к сообществу любителей на сайте zx.pk.ru. Комплект оказался непростой. Мы привыкли вычитывать из радиоэлектронных справочников информацию гораздо более полную, омраченную, может быть, двумя-тремя опечатками и парой ошибок от разработчиков. В случае же с 145-м комплектом информации было просто “кот наплакал”. Наверное наиболее полным источником была книга Я.К.Трохименко “Программируемые микрокалькуляторы устройство и пользование”. Пока моя посылка с микросхемами для Феликса велением почты РФ путешествовала по ЮАР вместо Штатов, Феликс компилировал имеющиеся данные, пытаясь заставить мои скудные извилины работать. Но комплект был весьма необычным, а язык Трохименко в книге - слишком специфичным для меня. Где то на одной десятой блок схемы К145ИК130х я и “слился”. К тому времени посылка с закупленными на убой горячей концентрированной серной кислотой К145 - была подана Феликсом в розыск. Всплыла она в Йоханнесбурге по причине того, что в деревню с очень схожим с Бока-Рейтон названием почтовое отправление невозможно доставить - попросту нет дорог. Карты сложились, и посылку Феликс таки получил. К тому времени я уже окончательно разуверился в своих силах и только и мог наблюдать, что происходит у Феликса с реверсом кристаллов. В конце концов все получилось, Феликс порадовал нас кодом МК-61 для PC и iOS, а другие разработчики подхватили флаг и усилили наступление, добавив в эти ряды Андроид и JavaScript. По причине полного мной непонимания принципов работы К145 комплекта соваться в код и пытаться там что то окончательно для себя выяснить желания не было... Пока Сергей Тарасов не предложил перенести имеющийся у него исходный код эмулятора на msp430. Колеса истории МК-61 снова закрутились.

Исследование платформы МК-61 по исходному коду эмулятора

Чтобы знать, с чем мы имеем дело, стоит кратко описать комплект К145 присутствующий в МК-61:

К145ИК1302 - 1шт К145ИК1303 - 1шт К145ИК1306 - 1шт К145ИР2 - 2шт

Сразу же скажу, что имеющийся эмулятор (причем не только Ф.Лазарева, но и С.Вакуленко) скрывает от нас особенности аппаратной реализации МК-61, а значит в каких то случаях он сильно не оптимален в угоду унификации кода. Поскольку начал с изучения эмулятора С.Тарасова, то в первую очередь пришлось столкнуться с объектным подходом. ООП также маскирует схемотехнику устройства за счет еще большей унификации кода. Необходимо было понять из каких же блоков состоит К145ИК130х, как они взаимосвязаны между собой, выяснить этапы и циклы работы комплекта, поскольку платформа, на которую предполагалось мигрировать, отличается производительностью от ПК раз так в 200-300.

Взяв за основу класс IK13, покопаемся в его "кишках":

class IK13 { const IK13_ROM *ROM; io_t R[IK13_MTICK_COUNT]; io_t M[IK13_MTICK_COUNT]; io_t ST[IK13_MTICK_COUNT]; io_t S, S1, L, T, P; mtick_t mtick; microinstruction_t microinstruction; io_t AMK, ASP, AK, MOD; io_t input; io_t output; int8_t key_x, key_y, comma; };

Оставляем только данные класса, поскольку только они отражают аппаратные особенности К145. Наблюдаем массивы R, M, ST. С них и начнем рассматривать комплект. Благодаря Трохименко и его книге, нам известно, что оперативная память комплекта преимущественно динамическая. Видимо, на тот момент разработчики нащупали очень удачное топологическое решение, состоящее в том, что динамическая память ― это последовательная цепочка коммутируемых транзисторами конденсаторов. Для того чтобы заряд конденсатора не успел “рассосаться” его передают в следующий за ним каскад с таким же точно конденсатором. Если в привычной нам DRAM имеется возможность при доступе к ячейке на чтение перезарядить ее, то в данной схемотехнике происходит постоянное чтение-перезаряд ячейки с передачей ее состояния следующей. Ячейки расположены друг за другом как в FIFO буфере. Буфер кольцевой, таким образом, информация в нем не теряется, достигнув конца.

Ключевая особенности К145 в том, что аппаратура имеет доступ только к одной ячейке, стоящей самой первой в буфере. Считав ее один раз, в следующий раз считать значение можно только через 42*4 такта. Почему на 4? Фактически ячеек 168, но удобней при рассмотрении серии К145 абстрагироваться до тетрады (4 бит). Конечно внутри К145 комплекта абсолютно все однобитное, но даже x86 не способен был бы работать с приемлемой скоростью, эмулируй он такую особенность комплекта. Опускаясь на уровень тетрад, мы не сильно грешим против истины, так как тактируется К145 - 4 фазами тактового сигнала, позволяющего аппаратуре привязаться в битовом потоке к началу и концу тетрад. В исходном коде эмулятора общее кол-во тактов на цикл 168, однако инкремент переменной счетчика тактов происходит на 4 за один такт. Массив М, R и ST имеют 42 тетрады, которые в коде представлены байтами, иначе пришлось бы тратить слишком много процессорного времени на доступ к ним.

Забегая вперед, скажу, что ошибочно считал переход к слову (msp430 ― 16-битный микроконтроллер) способом повышения быстродействия. Это не так из-за следующей особенности. Если необходимо получить доступ к тетраде номер X, то ее адрес, измеряемый в байтах, это X. Но при доступе к тетраде, как к слову, X требуется умножить на два, а это дополнительная операция при каждом доступе к регистровым кольцам в К145. Загрузка же, что слова, что байта, для msp430 идентична по таймингу.

Заметим для себя, что не всегда переход к родной разрядности платформы дает выигрыш в производительности.

Массив М в реальной жизни разомкнут, его вход и выход выведены на ноги микросхем (input, output) для каскадирования в большое кольцо-магистраль. Магистраль ― это оперативная память МК-61: любая ячейка магистрали посещает все каскадированные в магистраль микросхемы, то есть все шесть микросхем. Для МК-61 это происходит в следующем порядке: ИР2.1 -> ИР2.2 -> ИК1306 -> ИК1303 -> ИК1302. Магистраль ― это кольцо, и выход ИК1302 замыкается на вход ИР2.1.

Рис.1

Заметим, что память МК-61 ― это все что у него есть: память программ, регистровая память, стековая память ― совокупно это объем памяти магистралей всех регистров М. Для всех ИК130х объем магистрального регистра внутри 42 тетрады, для регистров ИР2 ― это 252 тетрады. Именно за счет регистров и расширяется память микрокалькуляторов ряда БЗ и МК. Вдобавок, последние модели были оснащены ИК1306, дающей еще 42 тетрады в магистральное кольцо.

Массив R и массив ST ― внутренние объемы ЗУ, и МК-61 они не доступны. В этих кольцевых регистрах происходят все промежуточные вычисления при исполнении микрокода. Будем считать их служебным хранилищем.

Изначально в эмуляторе для доступа к байтам-тетрадам кольцевых регистров используется переменная mtick, фактически это тактовый сигнал комплекса. Изменяется mtick от 0 до 167. При реализации основного цикла в котором mtick пробегает до 167, используется еще и внешний цикл for от 0 до 41. Выглядит расточительно два счетчика реализующих одну и ту же функциональность. В качестве оптимизации явно проситься убрать один цикл и развернуть его в последовательные 42 вызова процедуры эмулирующей аппаратуру IK13 (m_IK1302.Tick()). Если при этом mtick (в моем случае signal_I) будет адресовать байты, а не слова в кольце, то получим еще один небольшой бонус в производительности. Для этого переменная signal_I должна инкрементироваться на 1 каждый такт. В конце 41-го такта она должна обнулиться. Будем считать что 41 такт ― это один этап вычисления. 560 этапов вычисления составляют полный цикл устройства.

Процедура эмуляции такта К145 может быть условно разделена на модули по функциональности:1) выборка текущей микрокоманды;2) обработка возможного нажатия кнопки;3) вычисление значение входа сумматора Alpha;4) вычисление значение входа сумматора Beta;5) обработка возможного нажатия кнопки и отображения на дисплей;6) вычисление значение входа сумматора Gamma;7) вычисление значения выхода сумматора;8) запись в регистр R;9) расчет значения регистра L;10) расчет значения текущей ячейки магистрального кольца М;11) расчет значения регистра S;12) расчет значения регистра S1;13) запись в регистр ST.

Перед тем как перейти к оптимизации выборки микрокоманды, обратим внимание, что ИК1302, ИК1303, ИК1306 по своей сути ― конечные автоматы, переход между состояниями которых реализуется посредством программозадатчика. Программозадатчик, используя встроенное масочное ПЗУ микросхем, оперирует такими абстракциями, как “инструкция”, “микропрограмма”, “микрокоманда”. Инструкция ― это совокупность микропрограмм, микропрограмма совокупность микрокоманд. Основная единица программозадатчика ― микрокоманда. Каждый такт конечный автомат отрабатывает по выбираемой микрокоманде. Наиболее общая единица, с которой работает программозадатчик ― инструкция, она отрабатывается один раз за этап (этап, как уже оговаривалось ― 42 такта). Инструкция выбирается в начале этапа в нулевом такте. То, какая инструкция будет считана из ПЗУ, определяет байт, состоящий из тетрад кольцевого регистра R: R[39]..R[36]. При самом первом пуске все регистры комплекта обнуляются, таким образом, самая первая инструкция, выполняемая комплексом, выбирается по адресу 00. ПЗУ представлена нижеприведенной структурой ROM для ИК1302, ИК1303, ИК1306.

typedef struct { microinstruction_t microinstructions[68]; // микрокоманды instruction_t instructions[256]; // команды uint8_t microprograms[1152]; // микропрограммы } IK13_ROM;

Всего инструкций 256, их адрес восьмиразрядный, поэтому достаточно двух тетрад, чтобы позиционироваться в нем. Инструкция занимает 32 бита или 4 байта в ширину. Три младших байта задают адрес в ПЗУ микропрограмм, сменяясь поочередно. Таким образом, инструкция содержит три смещения в ПЗУ микропрограмм. При внимательном изучении кода эмулятора выясняем, что адрес микропрограммы меняется только три раза за этап. В эмуляторе это привязано к значению k=mtick/36. Вычисления смещения в ПЗУ микропрограмм происходят при k<3 mtick=0...107, k==3 mtick=108...143, k==4 mtick=144...167. Как мы помним, mtick меняется в диапазоне 0..167. Для k<3 смещение внутри ПЗУ определяется по нулевому байту инструкции, для k==3 по первому байту инструкции и при k=4 по третьему байту инструкции.

Рис.2

Несмотря на то, что код эмулятора каждый такт вычисляет смещение ASP, оно неизменно в заданных интервалах mtick. Для тактового сигнала signal_I, равного mtcik/4, расчет смещения ASP достаточно проводить в начале нулевого такта, в начале 27 такта и в начале 36 такта. Поскольку все 42 такта уже развернуты вместо цикла, то это еще один путь для оптимизации производительности эмулятора. В 36-м такте происходит вычисление адреса новой инструкции, в тетрады 38 и 39 кольцевого регистра R заносится ее адрес. После того, как смещение ASP известно, происходит выборка микрокоманды. Так как происходит это в каждом такте, то смещение необходимой к исполнению микрокоманды зависит от mtick. Смещение микрокоманды ― это ASP, умноженное на 9, к которому суммируется значение из таблицы, сопоставленное такту. В эмуляторе индексом является mtick/4, в моем же случае ― просто signal_I. Вот эта таблица.

static mtick_t J[] = { 0, 1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5 };

Не теряя такты на чтение из массива по индексу, попросту передаем внутрь процедуры на каждом такте соответствующую ему константу. Я рассуждал следующим образом: чтение из массива занимает не меньше трех, а то и четырех тактов в то время, как загрузка константы ― это два такта. Однако некоторые константы для msp430 загружаются с приятным бонусом: за один такт грузятся константы из ряда 0, 1, 2, 4, 8, -1. Если оптимизатор компилятора достаточно умный, он не будет по традиции ANSI C (если быть совсем точным то ABI) передавать параметры через стек (stdcall), а будет отправлять их в регистрах (fastcall). В этом дополнительном слагаемом мне не удалось увидеть никакой системы с простой зависимостью от signal_I или mtick.

Микрокоманда ― это 32-разрядная величина, каждый бит которой управляет мультиплексором или дешифратором записи внутри К145. Условно можно разделить микрокоманду на 16 старших и 16 младших разрядов. Но поле одного из дешифраторов записи находится очень неудобно для такого деления: начинается с 15-го и завершается 17-м битом. Но так удобнее для понимания, что младшая часть микрокоманды управляет сумматором, организуя для него слагаемые Alpha, Beta и Gamma. Ниже на рисунке я попытался представить механизм суммирования в виде управляемых битовыми полями мультиплексоров. Надо понимать, что комбинации битов приводят к подключению через механизм OR любой совокупности входов мультиплексора. И, конечно, схемотехнически ― это не мультиплексор, а селектор, выходы которого объединены огромным шинным OR. Это очень удобный и широко используемый прием, такой мультиплексор проще схемотехнически чем строгий, запрещающий комбинацию входов. Однако забегу вперед и скажу: анализ полей всех микрокоманд показал, что хоть комбинации битов и используются для выбора входных линий, но далеко не все, количество комбинаций ограничено. Этот факт тоже можно использовать для увеличения производительности, перейдя от последовательного списка условий к конструкции с выбором (switch). Сумматор вычисляет байт, младшая тетрада которого это значение Sigma, а старшая ― регистр P. От значения регистра P зависит только значение регистра L, а вот Sigma ― это результат который может попасть в S, S1, R[], ST[], M[]. Управляет записью Sigma, старшая часть микрокоманды ― дешифратор записи результата.

Рис.3

Рис.4

Рис.5

Рис.6

Запись в кольцевой регистр ST в зависимости от битов 26 и 27 может происходить следующим образом:

  • биты 26,27 = 0,0 - нет записи результатов;
  • биты 26,27 = 0,1 - прямой порядок записи результатов;
  • биты 26,27 = 1,0 - обратный порядок записи результатов;
  • биты 26,27 = 1,1 - запись результатов через логическое ИЛИ.

Рис.7

Однако при анализе не удалось найти микрокоманды ни для одной из микросхем ИК1302, ИК1303, ИК1306 с установленными в “1” битами 27 и 26. Вероятно использование таких микрокоманд было отложено “на потом”, либо применено в других приборах, кто знает из чего в СССР делали баллистические вычислители для артиллеристов. В эмуляторе С.Вакуленко код для реализации записи результата через ИЛИ оказался вырезан, что косвенно подтверждает отсутствие необходимости в данной аппаратуре у МК-61. Вырезал этот код из эмулятора для MSP430 и я.

В поисках возможностей увеличить производительность наткнулся на то, что все три эмулятора от Ф.Лазарева, С.Тарасова и С.Вакуленко использовали необычную модель кольцевого регистра, а именно массивы в памяти IK1302.M, IK1303.M, IK1306.M, IR21.M, IR22.M проводили закольцовку через запись в ячейку с индексом mtick/4 (signal_I). Последнее значение, взятое из IR22.M, писалось в IK1302.M и mtick/4, завершив кольцо. Это было не оптимально, так как на каждый объект класса IK13 следовало три присвоения: входной переменной input из предыдущего объекта класса, потом выходной переменной output из массива M[42], затем массиву M[42] из входной переменной input. Увеличить производительность можно было представив кольцевой регистр М как массив в памяти равный суммарной емкости всех магистральных регистров комплекса, 42*3+252*2=630. При этом, просто двигая три указателя внутри него, можно было отказаться от присвоений, да и от объектов IR22, IR21. Регистровые файлы ИР2 ничего кроме магистрали не инкапсулировали, их функциональность сводилась к трем присваиваниям. В конце 42-го такта необходимо было ввести проверку выхода указателя за рамки массива с переносом его на нулевой элемент если выход произошел. При этом инкременты указателей были не нужны: signal_I и так это делал, оставалось его использовать в качестве индекса дополнительно к указателям.

Рис.8

В итоге эмулятор стал слишком не похож на своих собратьев, и пришлось выискивать в кольце адреса памяти ПМК для всех необходимых типов: регистров, стека и шагов программы. Поскольку расположение регистров М различных микросхем может быть разным, например:a) IR2.1 -> 1306 -> 1303 -> 1302 -> IR2.2;b) IR2.2 -> IR2.1 -> 1306 -> 1303 -> 1302;то приведу смещения в массиве для своего распределения в кольце М.

Рис.9

uint16_t pack7[15] = { &ring_M[461],&ring_M[461+42],&ring_M[461+84],&ring_M[461+126],&ring_M[461+168], &ring_M[41] ,&ring_M[41+42] ,&ring_M[41+84] ,&ring_M[41+126] ,&ring_M[41+168], &ring_M[251],&ring_M[251+42],&ring_M[251+84],&ring_M[251+126],&ring_M[251+168] }

Шаги программной памяти разбиты пакетами по 42 байта (так как байт представляет собой тетраду, то 42 тетрады). Пакеты смещены по массиву кольца указанным выше способом с шагом в 42 тетрады. Внутри пакета распределены 7 шагов программной памяти. Распределены они нелинейно, в конце пакета идет ШАГ-0, в начале ШАГ-1, далее по нарастающей ШАГ-3, 4, 5, 6. Логически это объясняется только тем, что Шаг-0 по малому кольцу переходит в Шаг-1, но физически на этом уровне кольца нет. Так как шагов 7 а байт-тетрад 42, то период равен 42/7 = 6. Таким образом старшая тетрада (смещение +6) кода ШАГ-а, находится впереди младшей (смещением +3). Код ШАГ-а ― это байт.

Рис.10

Так как в ШАГ входит 6 тетрад, а заняты из них только 2, то, очевидно, остальные тетрады используются под размещение регистров от 0 до Е и стека X, Y, Z, X1. Регистры залегают в пакетах, младший разряд мантиссы идет со смещения 0 в пакете с шагом +3 для каждого следующего разряда. Младший разряд порядка сдвинут на +26 от начала пакета, старший разряд смещен на +3 относительно младшего разряда порядка. Регистр 0 (П0) располагается в пакете с ШАГ-0..ШАГ-6 памяти программ. Следующий регистр ― в следующем пакете и так далее до регистра Е (ПЕ). Становится понятным, почему в такой структуре памяти не получался регистр F: не вписывался в систему. Регистры стека X1, X, Y, Z, T залегают рядом с разрядами регистров памяти, начиная с пакета для ШАГ-64..ШАГ-70.

Клавиатура

Рис.11

Нажатия кнопок передаются в эмулятор через свойства IK1302 (она отвечает за клавиатуру и отображение в МК-61). Для этого IK1302 использует переменные key_x, key_y, означающие активность столбца и колонки для замкнутой клавиши. Например:

0 - {2,1}, 1 - {3,1}, 2 - {4,1}, F - {11,3}, K - {10, 9}, С/П - {2,9}

Максимальное количество функций, повешенных на кнопку, равно трем, поэтому задействование дополнительных функций происходит в следующих циклах сканирования матрицы клавиатуры Y=1..3, 4..6, 7..9 при неизменном X. Например для кнопки С/П обработка производится в 9-м цикле сканирования.

Эмулятор проверяет каждый столбец три такта подряд (по количеству сканирования Y), от 3 до 5 ― это столбец с координатой 2, от 6 до 8 ― столбец 3, последний столбец 11 проверяется в тактах 33..35. Приведу код:

switch (microinstruction >> 24 & 3) { case 2: case 3: if ((mtick / 12 | 0) != key_x - 1) if (key_y > 0) S1 |= key_y; break; }

Я его несколько “подрихтовал” для достижения меньшего времени исполнения проверок на вход. Заодно при передаче значения key_x во избежание потерь на вычисления, решил рассчитать заранее и IK1302_key_xm = key_x - 1. Думаю, что имеет смысл проверку key_y на ноль исключить, так как в эмуляторе мы формируем нажатие только при его наличии.

if((mi_hi | ~0x0300) == 0xFFFF) if (div3_table[signal_I] != IK1302_key_xm) if (IK1302_key_y > 0) IK1302_S1 |= IK1302_key_y;

Столбца 0 не существует, так же как и столбцов 12, 13, 14, поэтому в этих тактах проверка бессмысленна. Возможно это повод подумать об оптимизации, заменив в этих тактах вызов Tick() на вызов схожей по коду процедуры, без проверки нажатия. Исходный эмулятор для передачи нажатия в комплект использует процедуру KeyPress, так как при нажатии кнопки на реакцию калькулятора требуется дополнительный цикл работы. После любого цикла значение key_x, key_y обнуляется. Вполне вероятно, что эффективней будет использовать специальную процедуру DoStep (отработка цикла комплекта) осуществляющую проверку клавиатурной матрицы. А для циклов, в которых нажатие кнопки не передается, использовать упрощенный код.

Эмулятор МК-61 на платформе MSP430

На данном этапе работы, получившийся переработанный код эмулятора, в 2,3 раза быстрее реального МК-61. Но необходимо учесть, что для этого пришлось изрядно перекроить программу под находящийся в ПЗУ МК-61 микрокод и схему МК-61. Таким образом пришлось пожертвовать универсальностью кода для всего комплекта К145ИК130х. И даже в этом случае на частоте 25-27 МГц эмулятор способен лишь вдвое обогнать своего собрата, работающего на частоте 100 КГц! Расчет производительности осуществлял по программе из теста “Счастливые билеты”.

00 01 02 03 04 05 06 07 08 09 00 ИП8 П0 ИП0 ИП1 + ИП2 + ИП3 - ИП4 10 - ИП5 - Fx=0 19 ИП7 1 + П7 FL0 20 03 С/П

Для МК-61 время счета составило 40 секунд, для MK61msp ― 17 секунд.

О затратах памяти

Для портирования МК-61 на другие платформы разберем затраты оперативной памяти:1) основное магистральное кольцо М - 630 байт;2) кольцевые регистры (ST,R) ИК130х - 84*3 байта;3) логические регистры (L,T) ИК130x - 2*3 байта;4) временные регистры (S,S1,P) ИК130х - 3*3 байта;5) регистры клавиатуры (key_x, key_y) - 2*2 байта;6) флаг MOD - 1*3 байта.

Итого на комплект К145 для МК-61 требуется 904 байта. Однако в самом эмуляторе присутствуют дополнительные структуры данных для обслуживания эмулятора (клавиатуры, ЖК, терминала, стек микроконтроллера). В моем случае потребность в ОЗУ достигла 1215 байт. Потребность в ПЗУ (флеш) намного выше: только ПЗУ микрокода занимает 7344 байта. Объем ПЗУ в моем случае достиг 24-25 Кб.

pmk.arbinada.com

Эмулятор МК-61. Охота в потемках

От редактора. После публикации предыдущей статьи Алексея Сугоняева "Перенос эмулятора МК-61 на платформу msp430" встал вопрос о расширении возможностей МК-61. В самом деле, почему бы не добавить устройству немного памяти, ведь для этого даже не надо ничего паять на макете, достаточно изменить работу эмулятора! Вот что из этого получилось. Алексей продолжает рассказывать.

Неожиданный поворот

После моей публикации, совершенно случайно я наткнулся на статью Алексея Полушкина “Усовершенствованный микрокалькулятор Б3-34” на сайте Кон-Тики. В глаза бросился бутерброд из двух микросхем К145ИР2, собранный для увеличения памяти Б3-34. Опираясь на опыт предыдущих исследований, мы знаем, что вся память МК-61 содержится в кольцевой магистрали М. Схема Б3-34 состоит из микросхем ИК1302, ИК1303 и двух регистров ИР2. Количество шагов программы при таком объеме магистрали — 98, количество регистров — 14. Автору статьи удалось добиться увеличения памяти программ и, видимо, регистров тоже. Зная объемы ЗУ каждой микросхемы комплекта, можно предположить, что у Б3-34 теперь появилось 42 + 42 + 252 + 252 + 252 = 840 тетрад, то есть 7 * 840/42 = 140 шагов памяти программ и 840/42 = 20 регистров памяти. Ого, вот так модернизация! К сожалению, точные количественные характеристики улучшений автор не привел. В комментариях к статье пользователи ПМК интересовались, неужели память добавилась и сколько же ее стало? “Неожиданный поворот истории, — подумал я, — неужели все так просто?” Конечно, проверять предположения, запаивая в кольцо МК-61 еще один регистр ИР2 — дело и безнадежное и бессмысленное: корпусировка комплекта К745 для МК-61 — та еще штучка. Но… а зачем? Ведь у меня уже есть эмулятор МК-61 и добавить в массив ringM[] еще одну ИР2 дело нескольких минут. “Да хоть десять ИР2”, — подумал я и приступил к эксперименту.

Кольцевая магистраль МК-61 особенности

В погоне за производительностью эмулятора я не стал делать удобного смещения в кольце М нулевого пакета с шагами 0-6 программы МК-61. Совершенно зря, как выяснилось. Теперь я решил исправить этот недостаток, сделав доступ к регистрам и шагам программы линейным смещением в массиве с шагом в 42 байта. И тут всплыли неожиданные особенности организации кольца М: тасуя микросхемы по кругу, добиться перехода пакета с шагами 0-6 в первые 42 байта массива ringM было невозможно. Точнее, достичь этого можно было лишь нарушив порядок их коммутации. Это выглядело подозрительным: неужели разработчики калькулятора МК-61 заранее обрекли себя на неудобство в доступе к содержимому магистрали М? Я решил заглянуть в заводскую схему, выписав последовательность коммутации оттуда. Ниже — вырезка соответствующих блоков с разметкой магистрали.

Входы микросхем согласно еще советским ГОСТ-ам должны находится слева УГО, справа УГО находятся выхода. Паспорт на К745ИК130х мне не удалось найти, однако паспорт на К145ИК1302 и схема Б3-34 это также подтверждают. Таким образом, становится виден порядок коммутации микросхем в магистраль, заложенный в схему: ИК1302 -> ИК1303 -> ИК1306 -> ИР2.1 -> ИР2.2 с замыканием ИР2.2 в кольцо на ИК1302. Продемонстрируем различия в коммутации микросхем в эмуляторе и на схеме:

Налицо “чехарда” ИК130х, сейчас же хватаюсь за исходный код эмулятора МК-61 С.Тарасова. И... наблюдаю в полный рост свой эпический “косяк”. Привожу код, демонстрирующий мою неаккуратность

void MK61Emu::Tick() { m_IK1302->input = m_IR2_2->output; m_IK1302->Tick(); m_IK1303->input = m_IK1302->output; m_IK1303->Tick(); if (m_mode == mk61emu_mode_61) { m_IK1306->input = m_IK1303->output; m_IK1306->Tick(); m_IR2_1->input = m_IK1306->output; } else m_IR2_1->input = m_IK1303->output;   m_IR2_1->Tick(); m_IR2_2->input = m_IR2_1->output; m_IR2_2->Tick(); m_IK1302->M[((m_IK1302->mtick >> 2) + 41) % 42] = m_IR2_2->output; }

Согласно этому фрагменту подключение соответствует схеме, видимо при переделки магистрали на монолитный массив я проглядел этот нюанс, сделав размещение во таким:

IK1302_pM = (uint8_t*) &ringM[42+42]; IK1303_pM = (uint8_t*) &ringM[42]; IK1306_pM = (uint8_t*) &ringM[0];

Но удивительно здесь другое — это работало не только на простых проверках функций и примерах на арифметику, но и на гораздо более сложном тесте “Счастливые билеты”. Оставив эту тайну “на потом”, я изменил схему коммутации на следующую:

const uint8_t* IK1302_M_START = &ringM[42+252]; const uint8_t* IK1303_M_START = &ringM[42+252+42]; const uint8_t* IK1306_M_START = &ringM[42+252+42+42];   IK1302_pM = (uint8_t*) IK1302_M_START; IK1303_pM = (uint8_t*) IK1303_M_START; IK1306_pM = (uint8_t*) IK1306_M_START;

Видно, что в кольцо после ИР2.2 пришлось разместить 42 тетрады, не принадлежащие ни одной микросхеме, только так пакет 0 с шагами 0-6 становился в начало массива ringM. Как будто эти 42 тетрады отошли по кругу в начало кольца из ИР2.1:

Эмулятор продолжал работать, все запланированные тесты проходили исправно. При внесении в ШАГ-0 команды и просмотра области массива в отладчике код команды обнаруживался в пакете-0 в начале массива ringM[]. Делаем следующий шаг: добавляем память в кольцо.

Небольшое отступление. Как человек очень любопытный, на самом деле этот шаг я сделал, еще даже не исправив эмулятор, согласно схеме, точнее про эту ошибку я еще не знал. Добавил я сразу одну ИР2 в массив магистрали, Сергей Тарасов и Виталий Самуров тому свидетели :) И конечно сразу же попытался что то писать в шаги 105, 106, 107. И вроде бы получилось, однако… Однако, как показали эксперименты, памяти добавилось всего 7 шагов. Поскольку смещения микросхем в массиве в то время не соответствовали линейной развертке, было очень трудно понять в каком месте программной памяти осуществляется заворот. Процедуры просмотра памяти программ (DumpCode) в эмуляторе на MSP430 использовали развертку добытую в отладчике еще в самом начале эпопеи и поэтому “бессовестно врали” отображая шаги 105..111 на шаг 70. Все эти соображения мы с С.Тарасовым проверили через простенькую программу и петли на 70 шаг не обнаружили. Тогда стало понятно что организацию массива надо привести в порядок. Если добавилось 7 шагов, рассуждал я, то значит добавился пакет памяти в 42 тетрады, а, значит, добавился еще один регистр. И он действительно добавился — регистр F. Конечно же напрямую доступ к нему не получить (хотя может быть я чего-то и не знаю), только косвенно. В регистры от 0 до Е был записан набор чисел: 0, 1, 2, 3, 4, 5, 6, 7, 8, 15, 10, 11, 12, 13, потом считан для проверки возможного наложения. Нет, наложения не произошло — это демонстрирует экран терминала MK-61 на MSP430. “РЕЖ” — это клавиша МК-51, осуществляющая замену клавиши “К” в МК-61. Терминал MK61msp демонстрирует, что косвенная запись КП9, а затем и чтение по КИП9, прошли успешно.

Таким образом мы выяснили, что при добавлении 252 тетрад в память магистрали М для МК-61 добавляется всего 42. А значит добавление целого регистра ИР2 избыточно.

Модернизированный МК-61 на платформе MSP430 без излишеств получил в кольцо дополнительно 42 тетрады (байта) следующим образом:

const uint8_t* IK1302_M_START = &ringM[42+42+252]; const uint8_t* IK1303_M_START = &ringM[42+42+252+42]; const uint8_t* IK1306_M_START = &ringM[42+42+252+42+42];   IK1302_pM = (uint8_t*) IK1302_M_START; IK1303_pM = (uint8_t*) IK1303_M_START; IK1306_pM = (uint8_t*) IK1306_M_START;

Эмулятор опять прошел все тесты, не показав снижения производительности, что косвенно подтверждает: размер кольца не должен влиять на длительность цикла.

Тайны и загадки МК-61, будут ли ответы?

Фактически за цикл каждый пакет из 42 тетрад пробегает по кольцу N раз. Размер кольца в пакетах 630/42=15 и (630+42)/42=16. Тогда 560/15 = 37,3(3) и 560/16 = 35 дает нам N для MK-61 и измененного МК-61. Почему это не влияет на производительность — понятно: количество циклов не меняется. Но почему это не влияет на правильность вычислений — совсем неясно. Более того, непонятно и дробное число проходов пакета по кольцу.В эмуляторе С.Вакуленко есть наводящие на размышления строки:

i = k % 14; if (i >= 12) { // Clear display. } else { if (i < 3) { // Exponent.   } else { // Mantissa.   }   if (ik1302.dot == 11) { // Run mode: blink once per step with dots enabled.   } else if (ik1302.enable_display) { // Manual mode.   } else { // Clear display.   } }

Как видно из кода, для отображения на дисплеи мантиссы и порядка используется остаток от деления на 14 в интервале 0..11. Все что выше, этапы 12, 13 и 14, вероятно, используется для вычислений другого рода. 560/14 = 40 дает целое число групп вычислений. 40 раз за цикл аппаратура работает над каждым десятичным разрядом. Что характеризует величина “40”? Указывает ли она на максимально возможное количество обработок числа? Заранее заложенная избыточность по количеству этапов? А что же означает отсутствие жесткой позиции микросхемы в кольце?

МК-61 не так прост как хотелось бы и, по всей вероятности, мы только в начале очень длинного пути по открытию тайн отечественных программируемых калькуляторов.

pmk.arbinada.com

Перенос эмулятора МК-61 на платформу msp430

От редактора. Текст Алексея Сугоняева (digitalinvitro) является итогом многих недель работы по переносу кода существующих эмуляторов МК-61 на аппаратную платформу msp430. Работе сопутствовали обсуждения на нашем форуме и активная переписка, отражавшая текущий ход событий. Много времени было потрачено на оптимизацию: первоначальные варианты эмулятора работали в разы медленнее оригинала 35-летней давности! Алексею пришлось не просто оптимизировать код, а менять некоторые принципы. К слову, на практике выяснилось, что генерируемый компилятором Си код, как правило, не хуже ассемблерного, а накладные расходы Си++ касаются памяти, а не быстродействия. О ходе этой увлекательной работы я попросил Алексея написать статью. Надеемся, она будет не только интересна любителям советских ПМК, но даст возможность развивать поднятую тему.

Текущее состояние макета на фото, предоставленное Алексеем. В качестве прототипа используется калькулятор МК-51.

На правах вступительного слова

За эмуляцию комплекта К145ИК130x мне приходилось уже один раз браться, в прошлый раз меня на это сподвиг призыв Феликса Лазарева к сообществу любителей на сайте zx.pk.ru. Комплект оказался непростой. Мы привыкли вычитывать из радиоэлектронных справочников информацию гораздо более полную, омраченную, может быть, двумя-тремя опечатками и парой ошибок от разработчиков. В случае же с 145-м комплектом информации было просто “кот наплакал”. Наверное наиболее полным источником была книга Я.К.Трохименко “Программируемые микрокалькуляторы устройство и пользование”. Пока моя посылка с микросхемами для Феликса велением почты РФ путешествовала по ЮАР вместо Штатов, Феликс компилировал имеющиеся данные, пытаясь заставить мои скудные извилины работать. Но комплект был весьма необычным, а язык Трохименко в книге - слишком специфичным для меня. Где то на одной десятой блок схемы К145ИК130х я и “слился”. К тому времени посылка с закупленными на убой горячей концентрированной серной кислотой К145 - была подана Феликсом в розыск. Всплыла она в Йоханнесбурге по причине того, что в деревню с очень схожим с Бока-Рейтон названием почтовое отправление невозможно доставить - попросту нет дорог. Карты сложились, и посылку Феликс таки получил. К тому времени я уже окончательно разуверился в своих силах и только и мог наблюдать, что происходит у Феликса с реверсом кристаллов. В конце концов все получилось, Феликс порадовал нас кодом МК-61 для PC и iOS, а другие разработчики подхватили флаг и усилили наступление, добавив в эти ряды Андроид и JavaScript. По причине полного мной непонимания принципов работы К145 комплекта соваться в код и пытаться там что то окончательно для себя выяснить желания не было... Пока Сергей Тарасов не предложил перенести имеющийся у него исходный код эмулятора на msp430. Колеса истории МК-61 снова закрутились.

Исследование платформы МК-61 по исходному коду эмулятора

Чтобы знать, с чем мы имеем дело, стоит кратко описать комплект К145 присутствующий в МК-61:

К145ИК1302 - 1шт К145ИК1303 - 1шт К145ИК1306 - 1шт К145ИР2 - 2шт

Сразу же скажу, что имеющийся эмулятор (причем не только Ф.Лазарева, но и С.Вакуленко) скрывает от нас особенности аппаратной реализации МК-61, а значит в каких то случаях он сильно не оптимален в угоду унификации кода. Поскольку начал с изучения эмулятора С.Тарасова, то в первую очередь пришлось столкнуться с объектным подходом. ООП также маскирует схемотехнику устройства за счет еще большей унификации кода. Необходимо было понять из каких же блоков состоит К145ИК130х, как они взаимосвязаны между собой, выяснить этапы и циклы работы комплекта, поскольку платформа, на которую предполагалось мигрировать, отличается производительностью от ПК раз так в 200-300.

Взяв за основу класс IK13, покопаемся в его "кишках":

class IK13 { const IK13_ROM *ROM; io_t R[IK13_MTICK_COUNT]; io_t M[IK13_MTICK_COUNT]; io_t ST[IK13_MTICK_COUNT]; io_t S, S1, L, T, P; mtick_t mtick; microinstruction_t microinstruction; io_t AMK, ASP, AK, MOD; io_t input; io_t output; int8_t key_x, key_y, comma; };

Оставляем только данные класса, поскольку только они отражают аппаратные особенности К145. Наблюдаем массивы R, M, ST. С них и начнем рассматривать комплект. Благодаря Трохименко и его книге, нам известно, что оперативная память комплекта преимущественно динамическая. Видимо, на тот момент разработчики нащупали очень удачное топологическое решение, состоящее в том, что динамическая память ― это последовательная цепочка коммутируемых транзисторами конденсаторов. Для того чтобы заряд конденсатора не успел “рассосаться” его передают в следующий за ним каскад с таким же точно конденсатором. Если в привычной нам DRAM имеется возможность при доступе к ячейке на чтение перезарядить ее, то в данной схемотехнике происходит постоянное чтение-перезаряд ячейки с передачей ее состояния следующей. Ячейки расположены друг за другом как в FIFO буфере. Буфер кольцевой, таким образом, информация в нем не теряется, достигнув конца.

Ключевая особенности К145 в том, что аппаратура имеет доступ только к одной ячейке, стоящей самой первой в буфере. Считав ее один раз, в следующий раз считать значение можно только через 42*4 такта. Почему на 4? Фактически ячеек 168, но удобней при рассмотрении серии К145 абстрагироваться до тетрады (4 бит). Конечно внутри К145 комплекта абсолютно все однобитное, но даже x86 не способен был бы работать с приемлемой скоростью, эмулируй он такую особенность комплекта. Опускаясь на уровень тетрад, мы не сильно грешим против истины, так как тактируется К145 - 4 фазами тактового сигнала, позволяющего аппаратуре привязаться в битовом потоке к началу и концу тетрад. В исходном коде эмулятора общее кол-во тактов на цикл 168, однако инкремент переменной счетчика тактов происходит на 4 за один такт. Массив М, R и ST имеют 42 тетрады, которые в коде представлены байтами, иначе пришлось бы тратить слишком много процессорного времени на доступ к ним.

Забегая вперед, скажу, что ошибочно считал переход к слову (msp430 ― 16-битный микроконтроллер) способом повышения быстродействия. Это не так из-за следующей особенности. Если необходимо получить доступ к тетраде номер X, то ее адрес, измеряемый в байтах, это X. Но при доступе к тетраде, как к слову, X требуется умножить на два, а это дополнительная операция при каждом доступе к регистровым кольцам в К145. Загрузка же, что слова, что байта, для msp430 идентична по таймингу.

Заметим для себя, что не всегда переход к родной разрядности платформы дает выигрыш в производительности.

Массив М в реальной жизни разомкнут, его вход и выход выведены на ноги микросхем (input, output) для каскадирования в большое кольцо-магистраль. Магистраль ― это оперативная память МК-61: любая ячейка магистрали посещает все каскадированные в магистраль микросхемы, то есть все шесть микросхем. Для МК-61 это происходит в следующем порядке: ИР2.1 -> ИР2.2 -> ИК1306 -> ИК1303 -> ИК1302. Магистраль ― это кольцо, и выход ИК1302 замыкается на вход ИР2.1.

Рис.1

Заметим, что память МК-61 ― это все что у него есть: память программ, регистровая память, стековая память ― совокупно это объем памяти магистралей всех регистров М. Для всех ИК130х объем магистрального регистра внутри 42 тетрады, для регистров ИР2 ― это 252 тетрады. Именно за счет регистров и расширяется память микрокалькуляторов ряда БЗ и МК. Вдобавок, последние модели были оснащены ИК1306, дающей еще 42 тетрады в магистральное кольцо.

Массив R и массив ST ― внутренние объемы ЗУ, и МК-61 они не доступны. В этих кольцевых регистрах происходят все промежуточные вычисления при исполнении микрокода. Будем считать их служебным хранилищем.

Изначально в эмуляторе для доступа к байтам-тетрадам кольцевых регистров используется переменная mtick, фактически это тактовый сигнал комплекса. Изменяется mtick от 0 до 167. При реализации основного цикла в котором mtick пробегает до 167, используется еще и внешний цикл for от 0 до 41. Выглядит расточительно два счетчика реализующих одну и ту же функциональность. В качестве оптимизации явно проситься убрать один цикл и развернуть его в последовательные 42 вызова процедуры эмулирующей аппаратуру IK13 (m_IK1302.Tick()). Если при этом mtick (в моем случае signal_I) будет адресовать байты, а не слова в кольце, то получим еще один небольшой бонус в производительности. Для этого переменная signal_I должна инкрементироваться на 1 каждый такт. В конце 41-го такта она должна обнулиться. Будем считать что 41 такт ― это один этап вычисления. 560 этапов вычисления составляют полный цикл устройства.

Процедура эмуляции такта К145 может быть условно разделена на модули по функциональности:1) выборка текущей микрокоманды;2) обработка возможного нажатия кнопки;3) вычисление значение входа сумматора Alpha;4) вычисление значение входа сумматора Beta;5) обработка возможного нажатия кнопки и отображения на дисплей;6) вычисление значение входа сумматора Gamma;7) вычисление значения выхода сумматора;8) запись в регистр R;9) расчет значения регистра L;10) расчет значения текущей ячейки магистрального кольца М;11) расчет значения регистра S;12) расчет значения регистра S1;13) запись в регистр ST.

Перед тем как перейти к оптимизации выборки микрокоманды, обратим внимание, что ИК1302, ИК1303, ИК1306 по своей сути ― конечные автоматы, переход между состояниями которых реализуется посредством программозадатчика. Программозадатчик, используя встроенное масочное ПЗУ микросхем, оперирует такими абстракциями, как “инструкция”, “микропрограмма”, “микрокоманда”. Инструкция ― это совокупность микропрограмм, микропрограмма совокупность микрокоманд. Основная единица программозадатчика ― микрокоманда. Каждый такт конечный автомат отрабатывает по выбираемой микрокоманде. Наиболее общая единица, с которой работает программозадатчик ― инструкция, она отрабатывается один раз за этап (этап, как уже оговаривалось ― 42 такта). Инструкция выбирается в начале этапа в нулевом такте. То, какая инструкция будет считана из ПЗУ, определяет байт, состоящий из тетрад кольцевого регистра R: R[39]..R[36]. При самом первом пуске все регистры комплекта обнуляются, таким образом, самая первая инструкция, выполняемая комплексом, выбирается по адресу 00. ПЗУ представлена нижеприведенной структурой ROM для ИК1302, ИК1303, ИК1306.

typedef struct { microinstruction_t microinstructions[68]; // микрокоманды instruction_t instructions[256]; // команды uint8_t microprograms[1152]; // микропрограммы } IK13_ROM;

Всего инструкций 256, их адрес восьмиразрядный, поэтому достаточно двух тетрад, чтобы позиционироваться в нем. Инструкция занимает 32 бита или 4 байта в ширину. Три младших байта задают адрес в ПЗУ микропрограмм, сменяясь поочередно. Таким образом, инструкция содержит три смещения в ПЗУ микропрограмм. При внимательном изучении кода эмулятора выясняем, что адрес микропрограммы меняется только три раза за этап. В эмуляторе это привязано к значению k=mtick/36. Вычисления смещения в ПЗУ микропрограмм происходят при k<3 mtick=0...107, k==3 mtick=108...143, k==4 mtick=144...167. Как мы помним, mtick меняется в диапазоне 0..167. Для k<3 смещение внутри ПЗУ определяется по нулевому байту инструкции, для k==3 по первому байту инструкции и при k=4 по третьему байту инструкции.

Рис.2

Несмотря на то, что код эмулятора каждый такт вычисляет смещение ASP, оно неизменно в заданных интервалах mtick. Для тактового сигнала signal_I, равного mtcik/4, расчет смещения ASP достаточно проводить в начале нулевого такта, в начале 27 такта и в начале 36 такта. Поскольку все 42 такта уже развернуты вместо цикла, то это еще один путь для оптимизации производительности эмулятора. В 36-м такте происходит вычисление адреса новой инструкции, в тетрады 38 и 39 кольцевого регистра R заносится ее адрес. После того, как смещение ASP известно, происходит выборка микрокоманды. Так как происходит это в каждом такте, то смещение необходимой к исполнению микрокоманды зависит от mtick. Смещение микрокоманды ― это ASP, умноженное на 9, к которому суммируется значение из таблицы, сопоставленное такту. В эмуляторе индексом является mtick/4, в моем же случае ― просто signal_I. Вот эта таблица.

static mtick_t J[] = { 0, 1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5 };

Не теряя такты на чтение из массива по индексу, попросту передаем внутрь процедуры на каждом такте соответствующую ему константу. Я рассуждал следующим образом: чтение из массива занимает не меньше трех, а то и четырех тактов в то время, как загрузка константы ― это два такта. Однако некоторые константы для msp430 загружаются с приятным бонусом: за один такт грузятся константы из ряда 0, 1, 2, 4, 8, -1. Если оптимизатор компилятора достаточно умный, он не будет по традиции ANSI C (если быть совсем точным то ABI) передавать параметры через стек (stdcall), а будет отправлять их в регистрах (fastcall). В этом дополнительном слагаемом мне не удалось увидеть никакой системы с простой зависимостью от signal_I или mtick.

Микрокоманда ― это 32-разрядная величина, каждый бит которой управляет мультиплексором или дешифратором записи внутри К145. Условно можно разделить микрокоманду на 16 старших и 16 младших разрядов. Но поле одного из дешифраторов записи находится очень неудобно для такого деления: начинается с 15-го и завершается 17-м битом. Но так удобнее для понимания, что младшая часть микрокоманды управляет сумматором, организуя для него слагаемые Alpha, Beta и Gamma. Ниже на рисунке я попытался представить механизм суммирования в виде управляемых битовыми полями мультиплексоров. Надо понимать, что комбинации битов приводят к подключению через механизм OR любой совокупности входов мультиплексора. И, конечно, схемотехнически ― это не мультиплексор, а селектор, выходы которого объединены огромным шинным OR. Это очень удобный и широко используемый прием, такой мультиплексор проще схемотехнически чем строгий, запрещающий комбинацию входов. Однако забегу вперед и скажу: анализ полей всех микрокоманд показал, что хоть комбинации битов и используются для выбора входных линий, но далеко не все, количество комбинаций ограничено. Этот факт тоже можно использовать для увеличения производительности, перейдя от последовательного списка условий к конструкции с выбором (switch). Сумматор вычисляет байт, младшая тетрада которого это значение Sigma, а старшая ― регистр P. От значения регистра P зависит только значение регистра L, а вот Sigma ― это результат который может попасть в S, S1, R[], ST[], M[]. Управляет записью Sigma, старшая часть микрокоманды ― дешифратор записи результата.

Рис.3

Рис.4

Рис.5

Рис.6

Запись в кольцевой регистр ST в зависимости от битов 26 и 27 может происходить следующим образом:

  • биты 26,27 = 0,0 - нет записи результатов;
  • биты 26,27 = 0,1 - прямой порядок записи результатов;
  • биты 26,27 = 1,0 - обратный порядок записи результатов;
  • биты 26,27 = 1,1 - запись результатов через логическое ИЛИ.

Рис.7

Однако при анализе не удалось найти микрокоманды ни для одной из микросхем ИК1302, ИК1303, ИК1306 с установленными в “1” битами 27 и 26. Вероятно использование таких микрокоманд было отложено “на потом”, либо применено в других приборах, кто знает из чего в СССР делали баллистические вычислители для артиллеристов. В эмуляторе С.Вакуленко код для реализации записи результата через ИЛИ оказался вырезан, что косвенно подтверждает отсутствие необходимости в данной аппаратуре у МК-61. Вырезал этот код из эмулятора для MSP430 и я.

В поисках возможностей увеличить производительность наткнулся на то, что все три эмулятора от Ф.Лазарева, С.Тарасова и С.Вакуленко использовали необычную модель кольцевого регистра, а именно массивы в памяти IK1302.M, IK1303.M, IK1306.M, IR21.M, IR22.M проводили закольцовку через запись в ячейку с индексом mtick/4 (signal_I). Последнее значение, взятое из IR22.M, писалось в IK1302.M и mtick/4, завершив кольцо. Это было не оптимально, так как на каждый объект класса IK13 следовало три присвоения: входной переменной input из предыдущего объекта класса, потом выходной переменной output из массива M[42], затем массиву M[42] из входной переменной input. Увеличить производительность можно было представив кольцевой регистр М как массив в памяти равный суммарной емкости всех магистральных регистров комплекса, 42*3+252*2=630. При этом, просто двигая три указателя внутри него, можно было отказаться от присвоений, да и от объектов IR22, IR21. Регистровые файлы ИР2 ничего кроме магистрали не инкапсулировали, их функциональность сводилась к трем присваиваниям. В конце 42-го такта необходимо было ввести проверку выхода указателя за рамки массива с переносом его на нулевой элемент если выход произошел. При этом инкременты указателей были не нужны: signal_I и так это делал, оставалось его использовать в качестве индекса дополнительно к указателям.

Рис.8

В итоге эмулятор стал слишком не похож на своих собратьев, и пришлось выискивать в кольце адреса памяти ПМК для всех необходимых типов: регистров, стека и шагов программы. Поскольку расположение регистров М различных микросхем может быть разным, например:a) IR2.1 -> 1306 -> 1303 -> 1302 -> IR2.2;b) IR2.2 -> IR2.1 -> 1306 -> 1303 -> 1302;то приведу смещения в массиве для своего распределения в кольце М.

Рис.9

uint16_t pack7[15] = { &ring_M[461],&ring_M[461+42],&ring_M[461+84],&ring_M[461+126],&ring_M[461+168], &ring_M[41] ,&ring_M[41+42] ,&ring_M[41+84] ,&ring_M[41+126] ,&ring_M[41+168], &ring_M[251],&ring_M[251+42],&ring_M[251+84],&ring_M[251+126],&ring_M[251+168] }

Шаги программной памяти разбиты пакетами по 42 байта (так как байт представляет собой тетраду, то 42 тетрады). Пакеты смещены по массиву кольца указанным выше способом с шагом в 42 тетрады. Внутри пакета распределены 7 шагов программной памяти. Распределены они нелинейно, в конце пакета идет ШАГ-0, в начале ШАГ-1, далее по нарастающей ШАГ-3, 4, 5, 6. Логически это объясняется только тем, что Шаг-0 по малому кольцу переходит в Шаг-1, но физически на этом уровне кольца нет. Так как шагов 7 а байт-тетрад 42, то период равен 42/7 = 6. Таким образом старшая тетрада (смещение +6) кода ШАГ-а, находится впереди младшей (смещением +3). Код ШАГ-а ― это байт.

Рис.10

Так как в ШАГ входит 6 тетрад, а заняты из них только 2, то, очевидно, остальные тетрады используются под размещение регистров от 0 до Е и стека X, Y, Z, X1. Регистры залегают в пакетах, младший разряд мантиссы идет со смещения 0 в пакете с шагом +3 для каждого следующего разряда. Младший разряд порядка сдвинут на +26 от начала пакета, старший разряд смещен на +3 относительно младшего разряда порядка. Регистр 0 (П0) располагается в пакете с ШАГ-0..ШАГ-6 памяти программ. Следующий регистр ― в следующем пакете и так далее до регистра Е (ПЕ). Становится понятным, почему в такой структуре памяти не получался регистр F: не вписывался в систему. Регистры стека X1, X, Y, Z, T залегают рядом с разрядами регистров памяти, начиная с пакета для ШАГ-64..ШАГ-70.

Клавиатура

Рис.11

Нажатия кнопок передаются в эмулятор через свойства IK1302 (она отвечает за клавиатуру и отображение в МК-61). Для этого IK1302 использует переменные key_x, key_y, означающие активность столбца и колонки для замкнутой клавиши. Например:

0 - {2,1}, 1 - {3,1}, 2 - {4,1}, F - {11,3}, K - {10, 9}, С/П - {2,9}

Максимальное количество функций, повешенных на кнопку, равно трем, поэтому задействование дополнительных функций происходит в следующих циклах сканирования матрицы клавиатуры Y=1..3, 4..6, 7..9 при неизменном X. Например для кнопки С/П обработка производится в 9-м цикле сканирования.

Эмулятор проверяет каждый столбец три такта подряд (по количеству сканирования Y), от 3 до 5 ― это столбец с координатой 2, от 6 до 8 ― столбец 3, последний столбец 11 проверяется в тактах 33..35. Приведу код:

switch (microinstruction >> 24 & 3) { case 2: case 3: if ((mtick / 12 | 0) != key_x - 1) if (key_y > 0) S1 |= key_y; break; }

Я его несколько “подрихтовал” для достижения меньшего времени исполнения проверок на вход. Заодно при передаче значения key_x во избежание потерь на вычисления, решил рассчитать заранее и IK1302_key_xm = key_x - 1. Думаю, что имеет смысл проверку key_y на ноль исключить, так как в эмуляторе мы формируем нажатие только при его наличии.

if((mi_hi | ~0x0300) == 0xFFFF) if (div3_table[signal_I] != IK1302_key_xm) if (IK1302_key_y > 0) IK1302_S1 |= IK1302_key_y;

Столбца 0 не существует, так же как и столбцов 12, 13, 14, поэтому в этих тактах проверка бессмысленна. Возможно это повод подумать об оптимизации, заменив в этих тактах вызов Tick() на вызов схожей по коду процедуры, без проверки нажатия. Исходный эмулятор для передачи нажатия в комплект использует процедуру KeyPress, так как при нажатии кнопки на реакцию калькулятора требуется дополнительный цикл работы. После любого цикла значение key_x, key_y обнуляется. Вполне вероятно, что эффективней будет использовать специальную процедуру DoStep (отработка цикла комплекта) осуществляющую проверку клавиатурной матрицы. А для циклов, в которых нажатие кнопки не передается, использовать упрощенный код.

Эмулятор МК-61 на платформе MSP430

На данном этапе работы, получившийся переработанный код эмулятора, в 2,3 раза быстрее реального МК-61. Но необходимо учесть, что для этого пришлось изрядно перекроить программу под находящийся в ПЗУ МК-61 микрокод и схему МК-61. Таким образом пришлось пожертвовать универсальностью кода для всего комплекта К145ИК130х. И даже в этом случае на частоте 25-27 МГц эмулятор способен лишь вдвое обогнать своего собрата, работающего на частоте 100 КГц! Расчет производительности осуществлял по программе из теста “Счастливые билеты”.

00 01 02 03 04 05 06 07 08 09 00 ИП8 П0 ИП0 ИП1 + ИП2 + ИП3 - ИП4 10 - ИП5 - Fx=0 19 ИП7 1 + П7 FL0 20 03 С/П

Для МК-61 время счета составило 40 секунд, для MK61msp ― 17 секунд.

О затратах памяти

Для портирования МК-61 на другие платформы разберем затраты оперативной памяти:1) основное магистральное кольцо М - 630 байт;2) кольцевые регистры (ST,R) ИК130х - 84*3 байта;3) логические регистры (L,T) ИК130x - 2*3 байта;4) временные регистры (S,S1,P) ИК130х - 3*3 байта;5) регистры клавиатуры (key_x, key_y) - 2*2 байта;6) флаг MOD - 1*3 байта.

Итого на комплект К145 для МК-61 требуется 904 байта. Однако в самом эмуляторе присутствуют дополнительные структуры данных для обслуживания эмулятора (клавиатуры, ЖК, терминала, стек микроконтроллера). В моем случае потребность в ОЗУ достигла 1215 байт. Потребность в ПЗУ (флеш) намного выше: только ПЗУ микрокода занимает 7344 байта. Объем ПЗУ в моем случае достиг 24-25 Кб.

pmk.arbinada.com

Эмулятор МК-61. Охота в потемках

От редактора. После публикации предыдущей статьи Алексея Сугоняева "Перенос эмулятора МК-61 на платформу msp430" встал вопрос о расширении возможностей МК-61. В самом деле, почему бы не добавить устройству немного памяти, ведь для этого даже не надо ничего паять на макете, достаточно изменить работу эмулятора! Вот что из этого получилось. Алексей продолжает рассказывать.

Неожиданный поворот

После моей публикации, совершенно случайно я наткнулся на статью Алексея Полушкина “Усовершенствованный микрокалькулятор Б3-34” на сайте Кон-Тики. В глаза бросился бутерброд из двух микросхем К145ИР2, собранный для увеличения памяти Б3-34. Опираясь на опыт предыдущих исследований, мы знаем, что вся память МК-61 содержится в кольцевой магистрали М. Схема Б3-34 состоит из микросхем ИК1302, ИК1303 и двух регистров ИР2. Количество шагов программы при таком объеме магистрали — 98, количество регистров — 14. Автору статьи удалось добиться увеличения памяти программ и, видимо, регистров тоже. Зная объемы ЗУ каждой микросхемы комплекта, можно предположить, что у Б3-34 теперь появилось 42 + 42 + 252 + 252 + 252 = 840 тетрад, то есть 7 * 840/42 = 140 шагов памяти программ и 840/42 = 20 регистров памяти. Ого, вот так модернизация! К сожалению, точные количественные характеристики улучшений автор не привел. В комментариях к статье пользователи ПМК интересовались, неужели память добавилась и сколько же ее стало? “Неожиданный поворот истории, — подумал я, — неужели все так просто?” Конечно, проверять предположения, запаивая в кольцо МК-61 еще один регистр ИР2 — дело и безнадежное и бессмысленное: корпусировка комплекта К745 для МК-61 — та еще штучка. Но… а зачем? Ведь у меня уже есть эмулятор МК-61 и добавить в массив ringM[] еще одну ИР2 дело нескольких минут. “Да хоть десять ИР2”, — подумал я и приступил к эксперименту.

Кольцевая магистраль МК-61 особенности

В погоне за производительностью эмулятора я не стал делать удобного смещения в кольце М нулевого пакета с шагами 0-6 программы МК-61. Совершенно зря, как выяснилось. Теперь я решил исправить этот недостаток, сделав доступ к регистрам и шагам программы линейным смещением в массиве с шагом в 42 байта. И тут всплыли неожиданные особенности организации кольца М: тасуя микросхемы по кругу, добиться перехода пакета с шагами 0-6 в первые 42 байта массива ringM было невозможно. Точнее, достичь этого можно было лишь нарушив порядок их коммутации. Это выглядело подозрительным: неужели разработчики калькулятора МК-61 заранее обрекли себя на неудобство в доступе к содержимому магистрали М? Я решил заглянуть в заводскую схему, выписав последовательность коммутации оттуда. Ниже — вырезка соответствующих блоков с разметкой магистрали.

Входы микросхем согласно еще советским ГОСТ-ам должны находится слева УГО, справа УГО находятся выхода. Паспорт на К745ИК130х мне не удалось найти, однако паспорт на К145ИК1302 и схема Б3-34 это также подтверждают. Таким образом, становится виден порядок коммутации микросхем в магистраль, заложенный в схему: ИК1302 -> ИК1303 -> ИК1306 -> ИР2.1 -> ИР2.2 с замыканием ИР2.2 в кольцо на ИК1302. Продемонстрируем различия в коммутации микросхем в эмуляторе и на схеме:

Налицо “чехарда” ИК130х, сейчас же хватаюсь за исходный код эмулятора МК-61 С.Тарасова. И... наблюдаю в полный рост свой эпический “косяк”. Привожу код, демонстрирующий мою неаккуратность

void MK61Emu::Tick() { m_IK1302->input = m_IR2_2->output; m_IK1302->Tick(); m_IK1303->input = m_IK1302->output; m_IK1303->Tick(); if (m_mode == mk61emu_mode_61) { m_IK1306->input = m_IK1303->output; m_IK1306->Tick(); m_IR2_1->input = m_IK1306->output; } else m_IR2_1->input = m_IK1303->output;   m_IR2_1->Tick(); m_IR2_2->input = m_IR2_1->output; m_IR2_2->Tick(); m_IK1302->M[((m_IK1302->mtick >> 2) + 41) % 42] = m_IR2_2->output; }

Согласно этому фрагменту подключение соответствует схеме, видимо при переделки магистрали на монолитный массив я проглядел этот нюанс, сделав размещение во таким:

IK1302_pM = (uint8_t*) &ringM[42+42]; IK1303_pM = (uint8_t*) &ringM[42]; IK1306_pM = (uint8_t*) &ringM[0];

Но удивительно здесь другое — это работало не только на простых проверках функций и примерах на арифметику, но и на гораздо более сложном тесте “Счастливые билеты”. Оставив эту тайну “на потом”, я изменил схему коммутации на следующую:

const uint8_t* IK1302_M_START = &ringM[42+252]; const uint8_t* IK1303_M_START = &ringM[42+252+42]; const uint8_t* IK1306_M_START = &ringM[42+252+42+42];   IK1302_pM = (uint8_t*) IK1302_M_START; IK1303_pM = (uint8_t*) IK1303_M_START; IK1306_pM = (uint8_t*) IK1306_M_START;

Видно, что в кольцо после ИР2.2 пришлось разместить 42 тетрады, не принадлежащие ни одной микросхеме, только так пакет 0 с шагами 0-6 становился в начало массива ringM. Как будто эти 42 тетрады отошли по кругу в начало кольца из ИР2.1:

Эмулятор продолжал работать, все запланированные тесты проходили исправно. При внесении в ШАГ-0 команды и просмотра области массива в отладчике код команды обнаруживался в пакете-0 в начале массива ringM[]. Делаем следующий шаг: добавляем память в кольцо.

Небольшое отступление. Как человек очень любопытный, на самом деле этот шаг я сделал, еще даже не исправив эмулятор, согласно схеме, точнее про эту ошибку я еще не знал. Добавил я сразу одну ИР2 в массив магистрали, Сергей Тарасов и Виталий Самуров тому свидетели :) И конечно сразу же попытался что то писать в шаги 105, 106, 107. И вроде бы получилось, однако… Однако, как показали эксперименты, памяти добавилось всего 7 шагов. Поскольку смещения микросхем в массиве в то время не соответствовали линейной развертке, было очень трудно понять в каком месте программной памяти осуществляется заворот. Процедуры просмотра памяти программ (DumpCode) в эмуляторе на MSP430 использовали развертку добытую в отладчике еще в самом начале эпопеи и поэтому “бессовестно врали” отображая шаги 105..111 на шаг 70. Все эти соображения мы с С.Тарасовым проверили через простенькую программу и петли на 70 шаг не обнаружили. Тогда стало понятно что организацию массива надо привести в порядок. Если добавилось 7 шагов, рассуждал я, то значит добавился пакет памяти в 42 тетрады, а, значит, добавился еще один регистр. И он действительно добавился — регистр F. Конечно же напрямую доступ к нему не получить (хотя может быть я чего-то и не знаю), только косвенно. В регистры от 0 до Е был записан набор чисел: 0, 1, 2, 3, 4, 5, 6, 7, 8, 15, 10, 11, 12, 13, потом считан для проверки возможного наложения. Нет, наложения не произошло — это демонстрирует экран терминала MK-61 на MSP430. “РЕЖ” — это клавиша МК-51, осуществляющая замену клавиши “К” в МК-61. Терминал MK61msp демонстрирует, что косвенная запись КП9, а затем и чтение по КИП9, прошли успешно.

Таким образом мы выяснили, что при добавлении 252 тетрад в память магистрали М для МК-61 добавляется всего 42. А значит добавление целого регистра ИР2 избыточно.

Модернизированный МК-61 на платформе MSP430 без излишеств получил в кольцо дополнительно 42 тетрады (байта) следующим образом:

const uint8_t* IK1302_M_START = &ringM[42+42+252]; const uint8_t* IK1303_M_START = &ringM[42+42+252+42]; const uint8_t* IK1306_M_START = &ringM[42+42+252+42+42];   IK1302_pM = (uint8_t*) IK1302_M_START; IK1303_pM = (uint8_t*) IK1303_M_START; IK1306_pM = (uint8_t*) IK1306_M_START;

Эмулятор опять прошел все тесты, не показав снижения производительности, что косвенно подтверждает: размер кольца не должен влиять на длительность цикла.

Тайны и загадки МК-61, будут ли ответы?

Фактически за цикл каждый пакет из 42 тетрад пробегает по кольцу N раз. Размер кольца в пакетах 630/42=15 и (630+42)/42=16. Тогда 560/15 = 37,3(3) и 560/16 = 35 дает нам N для MK-61 и измененного МК-61. Почему это не влияет на производительность — понятно: количество циклов не меняется. Но почему это не влияет на правильность вычислений — совсем неясно. Более того, непонятно и дробное число проходов пакета по кольцу.В эмуляторе С.Вакуленко есть наводящие на размышления строки:

i = k % 14; if (i >= 12) { // Clear display. } else { if (i < 3) { // Exponent.   } else { // Mantissa.   }   if (ik1302.dot == 11) { // Run mode: blink once per step with dots enabled.   } else if (ik1302.enable_display) { // Manual mode.   } else { // Clear display.   } }

Как видно из кода, для отображения на дисплеи мантиссы и порядка используется остаток от деления на 14 в интервале 0..11. Все что выше, этапы 12, 13 и 14, вероятно, используется для вычислений другого рода. 560/14 = 40 дает целое число групп вычислений. 40 раз за цикл аппаратура работает над каждым десятичным разрядом. Что характеризует величина “40”? Указывает ли она на максимально возможное количество обработок числа? Заранее заложенная избыточность по количеству этапов? А что же означает отсутствие жесткой позиции микросхемы в кольце?

МК-61 не так прост как хотелось бы и, по всей вероятности, мы только в начале очень длинного пути по открытию тайн отечественных программируемых калькуляторов.

pmk.arbinada.com

DarkNess: Моя любимая программа android - MK61/52/34

Недавно наткнулся на программу, полностью эмулирующую советский микрокалькулятор MK61, и она сразу стала любимой :) - ностальгия, и не только :)  Это программируемый калькулятор, позволяющий проводить расчеты как вручную, так и с помощью своих программ, при этом с очень понятным и легко изучаемым "языком" программирования. Представитель линейки советских программируемых калькуляторов, на которых училось не одно поколение студентов, и работали многие научные сотрудники, и на которых решались задачи от простейших до довольно сложных. При чем данная программа это не просто "симулятор" - в ней используется оригинальный микрокод этого калькулятора, то есть он позволяет выполнять любую из множества программ, наработанных под него и доступных в интернете, от игрушек до научных и радиотехнических расчетов. Для примера вот сборник любительских "игровых" программ под него:  http://lordbss.narod.ru/pmk.html. Очень удобен как для повседневного использования, так и для начального обучения основам программирования, благодаря очень простому и понятному "языку".

Посмотреть как выглядели калькуляторы этой серии, можно посмотреть в вики: МК61, и МК52. Они полностью идентичны за исключением того, что в МК-52 был встроенный "диск", позволявший запоминать программы и  данные.Эмулятор, как я уже сказал выше, основан на оригинальном микрокоде, и полностью повторяет все как документированные, так и не документированные возможности этих калькуляторов. Отличие только в том, что в эмуляторе предусмотрено 100 слотов для записи программ и данных (записывается полный образ как перограммы так и все содержимое всех ячеек памяти, включая стэк), для повторного их использования. А также "турбо" режим - активируется прикосновением к "индикатору". При отключенном "турбо" эмулятор работает идентично оригинальному даже по скорости и "эффектам" на индикаторе.Скачать программу можно в google play бесплатно - последнюю версию, либо текущую на момент написания заметки у меня с googl диск. Исходные коды эмулятора, можно просмотреть и скачать с https://github.com/cax/pmk-android.Инструкции по использованию, включая полное обучение всем его возможностям и программированию на нем, Вы можете взять здесь: МК52 инструкция часть 1, и МК52 инструкция часть 2. А также очень короткую инструкцию к МК61 (без полноценного обучения всем возможностям м примеров программирования).  Большой учебник по программированию с использованием калькуляторов МК61/52 Трофименко, можете скачать здесь. Впрочем для полного освоения калькулятора и его программирования, вполне достаточно полной инструкции.Кому как, а мне эта программа очень понравилась, и стала самой любимой :) Может потому что это был первый собственный программируемый "компьютер" :) Если не считать отданного в мое распоряжение при работе на "ядерке" Б3-21, но тот был послабее.

vyacheslav.blogspot.com


 

..:::Новинки:::..

Windows Commander 5.11 Свежая версия.

Новая версия
IrfanView 3.75 (рус)

Обновление текстового редактора TextEd, уже 1.75a

System mechanic 3.7f
Новая версия

Обновление плагинов для WC, смотрим :-)

Весь Winamp
Посетите новый сайт.

WinRaR 3.00
Релиз уже здесь

PowerDesk 4.0 free
Просто - напросто сильный upgrade проводника.

..:::Счетчики:::..