Приложение для осциллографа FNRSI 2C53T

Друг, который одолжил мне осциллограф, оставил мне его до выходных — в надежде, что я его расширю его возможности по-максимуму.

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

Экран приложения для управления осциллографом FNRSI 2C53T с настройками каналов, калибровкой нуля и отображением сигнала.
Текущая версия приложения. Собираюсь её ещё расширять под различный сценарии

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

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

Останавливает меня пока только одно — у меня почти полтора десятка проектов в одновременной разработке, это как будто очень много. Тяжело это всё менеджерить, надо бы поджать некоторые из проектов и больше их не трогать.

4 комментария

Сигнал ИК-адаптера «SigmaTel»

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

Вчера наконец-то дошли руки измерить сигнал, который идёт на один из приобретённых мной инфракрасников — «SigmaTel STIr4200». Проблема там в том, что на скорости 38400 бод при приёме у него иногда возникают ошибки. Мы с нейросетью подумали, что дело, возможно, в каких-то программных настройках адаптера и решили измерить входной сигнал осциллографом, чтобы точно выяснить все тайминги.

Для этого я сначала в моменте решил купить собственный осциллограф, потом подостыл, передумал, тем более, что у одного из моих друзей нашёлся подходящий, с одним недостатком — сигнал там нужно было ловить вручную, что радости не добавляло.

Хорошо, что у нас есть нейросети! Нейросеть расковыряла его прошивку и сначала добавила туда возможность автоматически останавливать измерение при появлении сигнала, а потом и вовсе сделала его управляемым по ЮСБ.

Потом я собрал отдельную плату из трёх деталей без логики, роль которой — передавать принятый аналоговый сигнал на осциллограф. Два адаптера установил один напротив другого, а рядом в тот же поток поместил собранную плату.

Графики сигналов инфракрасного адаптера SigmaTel STIr4200 на скоростях 38400 бит/с и 115200 бит/с для байтов 0x00, 0x55 и 0xFF.

Запись сигнала показала, что программно тут подкручивать нечего — все сигналы идут ровно так, как ожидается, однако «СигмаТел» их иногда искажает без видимой причины. Нейросеть сгоряча предложила отлаживать дальше аппаратную часть, но по-моему, это лишнее — я ведь не собираюсь перепаивать адаптер, даже если он неисправен или недоработан.

Оставить комментарий

Алгоритм LUT8

На сегодня нейросеть в обвязке внутри «МК-61s», запущенная на «ПикоКалке», работает со скоростью примерно 0,43 секунды на токен. Постепенно становится быстрее, но ещё на порядок быстрее не станет,  тут уже нужно что-то принципиально менять.

Последний заметный прирост производительности дал алгоритм LUT8, о котором я расскажу чуть ниже, и можно было бы на этом поставить точку, но меня уговорили приобрести ПЛИС.

Нейросеть МК-61s на ПикоКале использует алгоритм LUT8 для ускорения вычислений путём замены умножения поиском в таблице и сложением.
Вот такие примеры сейчас способна правильно решить нейросеть после нескольких дней обучения

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

Теперь про LUT8 — идея в том, чтобы заменить умножение поиском по таблице и сложением для восьми активаций сразу.

Для восьми значений мы считаем таблицу сумм из 256 элементов. Если порядок в таблице представить в виде битовой маски, то получится восемь флагов (256 значений от 00000000 до 11111111) — учитывается ли каждая активация в сумме или нет. Причём таблица строится с помощью 255 сложений, на каждом шаге, кроме первого (там всегда ноль), мы используем уже вычисленную маску, отличающуюся от текущей ровно на один бит.

Дальше нам надо посчитать скалярное произведение восьми активаций и восьми весов. Веса разложены хитрым образом. Они у нас тут четырёхбитные, и восемь весов хранятся в четырёх байтах следующим образом: первый байт хранит восемь самых младших бит всех восьми весов, следующий — следующие биты и так далее.

Каждый такой байт — готовая маска, которая показывает, входит ли каждая активация в сумму или нет. Для четырёх байт мы четыре раза ходим в таблицу, умножая каждый раз на множитель — ×1, ×2, ×4, ×8. Для «ПикоКалка» это могут быть три умножения (на один умножать не нужно) или три сдвига, не принципиально, то и другое занимает один такт.

В итоге, для восьми элементов в LUT8 у нас нужно будет прочитать четыре маски, четыре раза обратиться к таблице, выполнить три умножения или сдвига и три сложения.

2 комментария

ПРОЛ-2: поиски продолжаются

На деревянном столе лежат три старых советских учебника по кибернетике, вычислительной математике и авиационно-космическим системам.
Книги из библиотеки из КНИТУ-КАИ, которые мне передали

После документального фильма о «Буране», который снял мой добрый друг Иван Черняков, я очень заинтересовался языком программирования «ПРОЛ-2».

На нём писались программы для этого космического корабля. Мне нравится копаться в истории программирования, а тут прям интрига — в интернете сведений почти нет, все, в основном, копируют у друг друга один и тот же абзац. В ходе своих исследований мне удалось добыть кое-какую информацию и я даже написал на этом языке «Песню о пиве», но хочется разузнать о нём побольше.

Пытаюсь пока раздобыть кое-какую литературу, где может оказаться информация о нём, но идёт тяжело — книги редкие, сканов нет, да и в не каждой библиотеке их найдёшь. Те, что на снимке, мне достались из библиотеки казанского вуза КНИТУ-КАИ. Упоминались они в списке литературы, который мне удалось получить из института, в котором проектировался «ПРОЛ-2», но, похоже, это ложный след — я пока только полистал их, но, кажется, они ничем не помогут.

Буду исследовать дальше, но есть вероятность, что на части документов по «Бурану» до сих пор есть какой-то гриф секретности, который не сняли по недосмотру, возможно информация по «ПРОЛу-2» находится в тех же документах.

Оставить комментарий

Осень → зима

Холодное утро: снег покрыл еловые лапы, белые розы и опавшие листья, предвещая скорую зиму.
Снег во дворе, прямо поверх цветущих цветов

Вчера как-то неожиданно снег выпал — просыпаюсь, а он уже лежит. Надеюсь, температура и дальше будет быстро падать — с осенью в этом году очень повезло, тёплая выдалась, почти без слякоти и промозглой погоды. Если теперь всё окончательно замёрзнет, будет чудесно — грязь я не люблю.

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

Теперь просыпаюсь в сумерках и с работы иду в сумерках.

Надо бы реже сидеть по ночам, сегодня чувствую себя уставшим. Благо в «ОпенЭйАй» закончили свой марафон сброса токенов, а то я как одержимый их тратил. С одной стороны, ни в чём себе не отказывал, кроме сна, с другой стороны, слишком перебрал с этим занятием.

У дочки началась новая четверть, вставала сегодня с неохотой. Новая школа нравится, но сказать, что она туда ходит с каким-то особенным желанием, не могу. В конце прошлой четверти прислали отчёт, учителя в основном хвалят, кроме учителя английского, на фоне остальных его отзыв выглядит довольно сдержанно.

Дочка в этом учебном году как-то особенно сильно налегает на бассейн. Нашла там несколько подруг, в этой небольшой компании стало, видимо, плавать веселее. Другие кружки тоже не забыты — ходит на конный спорт и в художественную школу. Только шахматы выпали, жаль, но времени на них не хватает. Вместо шахмат в список попал китайский язык — Еве почему-то он очень понравился, она уже несколько лет хочет им заняться, а тут оказалось, что в новой школе на него можно ходить.

В этом году произошло что-то удивительное — я как-то по инерции жалел, что лето прошло, пока не понял, что мне, в общем-то, и не жаль. Прошло и ладно. Зато два месяца до Нового года, здо́рово же!

Оставить комментарий

Casio WQV и осциллограф

На фотографии показан портативный цифровой осциллограф Fluke ScopeMeter серии 125 с подключенными щупами.
Осциллограф «FNIRSI 2C53T» и сигнал с инфракрасного датчика на нём

Приходил сегодня в гости друг с осциллографом — свой я что-то передумал заказывать, а посмотреть, почему у меня один из инфракрасников иногда теряет пакеты при чтении снимков из часов «Касио», хочется.

К его приходу я спаял небольшую плату — всего три детали, — подключили её к осциллографу и начали смотреть сигналы, но по пути отвлеклись на другое, и не все эксперименты успели закончить.

Недаром говорят — когда в руках молоток, всё вокруг кажется гвоздями. Посмотрел я на осциллограф и подумал: а нельзя ли в нём что-то улучшить? Попросил нейросетку разобраться в прошивке, раз у них теперь почему-то нет запрета всё дизассемблировать.

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

А сейчас сетка трудится над исправлением странного поведения осциллографа при калибровке и переносит туда функции служебной прошивки. Во вторник друг придёт ещё раз, продолжим экспериментировать и посмотрим новую прошивку.

2 комментария

MK-61s и «Спектрум»

С момент как мне подарили «ПикоКалк» хотел поэксперементировать там с цветом. Поскольку у меня теперь основная оболочка для него — прошивка ретроконсоли «МК-61s», то сначала была мысль добавить цвет туда, но я эту идею пока отложил. Вместо этого решил добавить в консоль эмулятор какой-нибудь платформы, где цвет уже имеется.

Перебрав несколько, остановился на «Спектруме», отчасти из-за аппаратных требований, которые реально было повторить на таком железе, отчасти из-за эффекта утёнка — всё-таки это был мой второй компьютер.

На экране МК-61s показан интерфейс эмулятора ZX Spectrum с игрой, отображающей лабиринт и игровое меню.
Несколько игр из скачанной из интернета подборки, в которые я попробовал поиграть

В качестве основы мы взяли готовый эмулятор, но его пришлось сильно доработать, чтобы достичь хорошей скорости выполнения программ на ядрах «Кортекса-М0+», которые стоят в «ПикоКалке». Сейчас игры просчитываются с той скоростью, с которой они выполнялись бы на настоящем «Спектруме», но с меньшим количеством кадров, в эмуляторе на «ПикоКалке» средняя скорости — 48,8 кадра в секунду.

Это связано со скоростью шины, её пришлось разогнать по максимуму, плюс сделать алгоритм частичной перерисовки экрана, но полную скорость это не дало, впрочем играть довольно комфортно.

Отдельным сюрпризом стало сколько всего модифицировали в «Спектруме» за прошедшие годы — там и игры с расширенной палитрой «ULAPlus», и память до мегабайта, и звуковые процессоры.

На экране показаны скриншоты ZX Spectrum игр: лабиринт, аркада с прыжками через препятствия, платформер с зелеными врагами и счетчик очков.
Игры с расширенной графикой, в детстве о таком я и мечтать не мог

Разумеется мне захотелось реализовать вообще все возможности, раз уж я занялся. В принципе, всё удалось реализовать без заметных проблем, но со звуковыми процессорами пришлось повозиться. Код, опять-таки, был взят готовый, но несмотря на все ухищрения, центральный процессор его не тянул.

Пришлось его разогнать до 200 МГц, это помогло, но выглядело как-то неспортивно. Обычно в таких случаях я читаю спецификацию на «железо», в надежде, что на борту устройства найдётся что-то аппаратное, что поможет победить проблему.

В случае «ПикоКалка» такое устройство нашлось — оказалось, что у него есть аналог южного моста — микроконтроллер «STM32F103C8T6» с процессором «Кортекс-М3», обслуживающий периферию. Он обменивается данными с центральным процессором через довольно медленную шину I²C, но соединён с ним ещё и через UART, где скорость на порядок выше.

В общем, мне в голову пришла довольно очевидная идея — гонять по шине команды в этот процессор для синтеза звука, раз центральный не справляется.

У него отдельная прошивка, для доступа к которой надо разбирать корпус. Чтобы постоянно этим не заниматься, я сделал заливку прошивки через ту же шину, сделав для этого отдельную систему команд. Плюс реализовал возможность запуска там небольших приложений — оперативной памяти там совсем мало.

Ещё у меня была идея ускорить таким образом инференс модели для программирования на «МК-61», но оказалось, что скорость шины съедает весь выигрыш. Зато звук удалось синтезировать без задержке даже без разгона центрального процессора.

4 комментария

LUT и SWAR

Ночные эксперименты с нейросеткой на «ПикоКалке» дали, кстати, неплохой результат — теперь на токен тратится чуть больше секунды. Тут есть вклад оборудования, например, разгона центрального процессора до 270 МГц (выше плата зависает), но есть и чисто программные моменты. Я испытал несколько способов перемножить несколько чисел — в вычислениях любой нейросетки такого много.

Быстрее всего оказался обычный INT8 — прямое целочисленное умножение. Веса у меня четырёхбитные, чтобы сетка поместилась в память: в одном байте хранятся два веса. Для расчёта они распаковываются и по отдельности умножаются на восьмибитные активации.

Произведения складываются в 32-битном аккумуляторе, затем применяется масштаб. По сравнению с вариантом LUT_FLOAT32 здесь меняется и точность активаций: вместо чисел с плавающей точкой используются восьмибитные целые, но на работе нейросети это не сказалось.

Пока с этим возился, познакомился с несколькими интересными методами считать такие суммы, о двух таких алгоритмах хочу рассказать. В моём «ПикоКалке» стоит RP2040 с целочисленным умножителем, но нет FPU — аппаратного блока вычислений с плавающей точкой.

В каждом случае будем считать скалярное произведение двух векторов: веса — 3, 6, 1, 4 и активации — 2, 3, 5, 7.

LUT

Первый называется LUT («Look-Up Table»), я его вчера уже упоминал. Он очень простой для понимания.

Сначала веса раскладываем на степени двойки (то есть по битам):

3 = 1 + 2  6 = 2 + 4  1 = 1  4 = 4

Теперь нам надо получить скалярное произведение вектора весов и вектора активаций:

(1 + 2) × 2 + (2 + 4) × 3 + (1) × 5 + (4) × 7

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

1 × (2 + 5) + 2 × (2 + 3) + 4 × (3 + 7)

Из четырёх активаций получается шестнадцать возможных наборов, включая пустой. Заранее считаем сумму каждого набора и записываем в таблицу LUT.

Чтобы дать наборам адреса, назначаем позициям активаций флажки 1, 2, 4, 8. Адрес набора, или маска, — сумма флажков выбранных позиций. Например, младшие биты весов 3, 6, 1, 4 дают выбор 1, 0, 1, 0: берём первую и третью активации, то есть 2 и 5. Адрес этого набора — 1 + 4 = 5, поэтому LUT[5] = 2 + 5 = 7.

Для разряда ×2 выбираются первая и вторая активации: адрес 1 + 2 = 3, сумма LUT[3] = 2 + 3 = 5. Для разряда ×4 — вторая и четвёртая: адрес 2 + 8 = 10, сумма LUT[10] = 3 + 7 = 10. Нужное скалярное произведение таким образом находится по таблице:

1 × LUT[5] + 2 × LUT[3] + 4 × LUT[10] = 7 + 10 + 40 = 57

Таблицы строятся для текущего вектора активаций и используются для всех строк матрицы весов. У каждой строки свои маски, а таблицы готовых сумм общие. При смене вектора активаций их пересчитывают.

Максимальная ширина входа слоя у меня — 384 активации. Делим их на четвёрки, для каждой храним 16 сумм. Одна сумма в моём варианте LUT_FLOAT32 занимает четыре байта, получается: (384 / 4) × 16 × 4 = 6144 байта. Столько внутренней SRAM занимает весь набор таблиц LUT.

SWAR

Второй метод называется SWAR («SIMD Within A Register»), где SIMD — «Single Instruction, Multiple Data».

Тут мы считаем два произведения одной командой. Проще всего проиллюстрировать принцип в привычной нам десятичной системе. Пусть нам надо подсчитать следующее скалярное произведение:

3 × 2 + 6 × 3

Для этого мы применяем такой любопытный приём:

(6 × 100 + 3) × (2 × 100 + 3) или 603 × 203 = 122409

Если взять средние две цифры, это будет сумма произведений:

3 × 2 + 6 × 3 = 24

Почему это работает? Станет понятно, если по-другому расставить скобки:

12 × 10000 + (6 × 3 + 3 × 2) × 100 + 9

Остаются вопросы — как мы получаем среднюю часть числа и где тут экономия, ведь в раскрытой формуле куча умножений?

Эта формула объясняет результат одной команды. В коде мы не вычисляем её слагаемые по отдельности: упаковываем числа сдвигами и битовыми масками, выполняем одно обычное умножение и извлекаем нужную часть результата.

В настоящем расчёте вместо основания 100 используется 65536: два числа упаковываются в 32-битное слово с двумя 16-битными полями. Команда умножения сохраняет младшие 32 бита произведения, поэтому член с множителем 65536² выпадает сам собой — для него просто нет места. В нашем примере остаётся 24 × 65536 + 9. Сдвиг вправо на 16 бит убирает младшее поле и оставляет 24.

Размеры полей и диапазоны чисел нужно подбирать так, чтобы переносы между полями не испортили результат. Для отрицательных активаций нужны дополнительные поправки; положительный десятичный пример показывает только принцип.

2 комментария

MK-61s: обвязка на PicoCalc

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

Решил реализовать заведомо непрактичную, но давно засевшую у меня в голове идею — запустить внутри ретроконсоли «МК-61s» какую-нибудь нейросеть. Наверное месяц крутил эту мысль в голове, но ничего достойного реализации мне в голову не приходило, пока вчера ночью не осенило — надо сделать обвязку («харнесс») для программирования на языке «Электроника МК-61»!

Для этого я выбрал русскоязычную модель «Flourish-3M», у которой около трёх миллионов параметров и попробовал дообучить её на Nvidia B200 синтаксису «МК-61». 

Даже сеть таких скромных размеров в памяти ретроконсоли не поместилась бы, несмотря на то, что я выбрал самую мощную аппаратную платформу, которая у меня есть — «ПикоКалк», поэтому пришлось её квантировать до четырёх бит.

Так же я пробовал сети побольше с квантированием до двух бит, а так же несколько вариантов гибридного квантирования, по соотношению сообразительность/размер выиграла эта конфигурация.

Было использовано 462 листинга, материалы девяти книг и несколько сотен синтетических упраженений. Полученные программы выполнялись в эмуляторе.

На видеокарте NVIDIA B200 запущено три процесса Python, использующих почти всю память GPU.
Процесс обучения нейросети; большая часть памяти занята «Квеном», который помогал корректировать обучение

Чтобы ускорить матричные вычисления, пришлось использовать предвычисленные таблицы — LUT и оба ядра процессора (все остальные процессы в этот момент замирают), разогнанные с 125 до 250 МГц.

Несмотря на все усилия, скорость генерации невелика  — около 4,67 секунды на токен. Математического сопроцессора нет, всё считается ядрами центрального процессора.

На экране консоли отображено число 0,374666 — результат вычисления синуса угла 22 градуса программой, написанной ИИ Flourish-3M специально для калькулятора MK-61.
Игру эта сеть не напишет, ей бы с синусом справиться!

С такими параметрами этой обвязкой, конечно, в здравом уме пользоваться не будешь, тем более что и сеть получилась тупенькой — из трёхсот заданий с тремя параметрами она правильно выполняет лишь девятнадцать.

Я, наверное, потренирую её ещё немного и сотру, даже в репозиторий класть не буду — интересно было повозиться, но никакого смысла такой результат сохранять нет.

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

Casio WQV: драйверы

Экран настройки драйверов Casio WQV Link показывает состояние подготовки драйвера KingSun KS-959.
Компиляция линуксового драйвера внутри браузера в веб-ассемблер

Нейросети, конечно, позволяют делать совершенно фантастические вещи, лишь бы фантазия была.

Потихоньку дописываю своё веб-приложение для часов «Касио» серии «WQV» — недавно добавил туда поддержку десятой модели и инструкции в переводе на все языки, которые «Касио» когда-либо сделала. Заодно добавил их и в интерфейс — кроме русского и английского теперь появились японский, немецкий, испанский и финский.

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

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

На словах идея выглядит просто — драйвер компилируется из Си в веб-ассемблер и встаивается в страницу, у которой есть эмуляция того же АПИ, что доступно для драйверов такого типа в Линуксе.

Несмотря на то, что компилятор писать не пришлось (есть готовое решение), всё равно сама идея для реализации непростая, боюсь даже представить, сколько у меня ушло бы на это времени. А тут я порисовал прототипы на бумаге, попросил нейросеть отрисовать их в стиле нашего приложения, внёс замечания, написал техническое задание, описал тесты и пошёл заниматься своими делами.

Для меня это до сих пор какое-то новое ощущение, чистое творчество, сколько уже этим занимаюсь, а до сих пор испытываю какое-то невероятное острое приятное чувство, когда идеи воплощаются с такой скоростью!

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

«MK-61s»: ещё приложения

Может показаться, что я занялся другими проектами и совсем забыл про ретроконсоль «МК-61s». Это совершенно не так.

Моё молчание отчасти объясняется тем, что почти все токены я сейчас трачу на попытку сделать нормальную арифметику для «ПикоКалка» — хочется, чтобы сишный тип double вёл себя там, как в стандартном Си и при этом все операции с ним выполнялись быстро, а это непросто.

Тем не менее и другими вещами я тоже занимаюсь, в частности в коллекции «МК-61s» появились ещё три приложения, созданных с разными целями.

На экране калькулятора МК-61 отображаются ячейки таблицы с числовыми значениями, формулами и итоговой суммой.
Приложение для работы с таблицами на экране «ПикоКалка»

Первое — это приложение для работы с таблицами. Попытка ответить на вопрос: «А для чего я мог бы использовать эту ретроконсоль в реальной жизни?». Я участвую в проекте создания этой ретроконсоли для собственного развлечения, но иногда в команде возникает вопрос: а могло бы это пригодиться кому-то для чего-то полезного, помимо ностальгии?

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

Формулы записываются в привычной для «МК-61» обратной польской записи. Например, чтобы перемножить количество из A2 и цену из B2, нужно ввести A2 В↑ B2 ×. На картинке два предмета по 125 дают 250. Меняешь количество или цену — зависимые ячейки пересчитываются. Формулу можно скопировать или протянуть вниз, относительные ссылки при этом сдвигаются.

Ссылку не обязательно набирать: можно выбрать нужную ячейку прямо в таблице. Есть и фиксация строки или столбца знаком доллара, как в больших электронных таблицах. Циклическая ссылка показывает ошибку, но не мешает считать независимые ячейки.

Экран консоли МК-61с с интерфейсом игры «Гонка»
Игра «Погоня», написанная с применением расширенных команд калькулятора

Следующая программа — игра «Погоня», написанная на языке калькулятора «МК-61» с расширенными командами.

Я давно хотел понять нельзя ли сделать на калькуляторе динамическую игру хоть с какой-то изометрией. Не скажу, что получилось очень здорово, но играть можно. Управление традиционное для калькулятора — переключение режимов «Г», «ГРД» и «Р».

На всю гонку даётся три жизни, проехать нужно двадцать участков. Машина может занимать пять положений. За столкновение со стеной или соперником отнимается жизнь, после удара есть короткая передышка, когда повторный урон не наносится.

Даже в динамике не очень очевидно, что происходит на экране, но ориентироваться помогает нижняя метка: она указывает свободный путь, к которому надо подрулить. Графика тут довольно условная, зато её мог бы осилить обычный сегментный экран «Электроники».

Экран консоли МК-61с с интерфейсом игры «Лодраннер»
Игра «Лодраннер», опять-таки написанная с применением расширенных команд калькулятора

Следующую игру я написал, чтобы обкатать идею управления динамической игрой на калькуляторе не через переключатель тригонометрических режимов, а другими клавишами. У меня было несколько идей, хотелось их опробовать. В итоге я оказался от идеи добавить в команды калькулятора дополнительные возможности, а выкрутился другим способом, о котором расскажу ниже.

У «МК-61s» есть скриптовый язык, который называется «M61», у него простой и относительно бедный синтаксис, но его плюс в том, что он как клей может скреплять между собой несколько разных программ. Логику опроса клавиатуры я вывел именно туда — ввёл новую конструкцию, запускающую указанные подпрограммы, при нажатии и отпускании клавиш. Эти подпрограммы меняют содержимое регистров калькулятора, таким образом сообщая программе что нажато на клавиатуре.

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

От преследователя можно уйти, прожигая пол слева или справа. Герой через такую дырку падает на этаж ниже, а враг застревает. Через четыре секунды пол восстанавливается, и пойманный враг возвращается к месту старта. Бесконечно дырявить всё вокруг нельзя: одновременно открыт только один прожиг, лестницы и нижний этаж защищены.

1 комментарий

99 бутылок: cURL

На сайте «Оупеннет», который я давно читаю, стараясь зажмуриваться на комментариях (там чистые Содом и Гоморра), увидел сегодня статью «В конфигурационных файлах curl случайно реализована полнота по Тьюрингу». Естественно, мимо такого названия я пройти не мог. Не беда, что «Песня о пиве» уже реализована, в первый раз что ли? Реализую свою!

88. cURL — это очень известная утилита, о которой вспоминают, в основном, когда нужно что-то скачать в командной строке. Я знал, что в ней есть переменные и чтение файлов, но про остальные возможности не знал. Оказывается там есть строковые функции, которые, впрочем мне не пригодились, работа с подстроками и рекурсивное включение конфигурационных файлов друг в друга.

#!/usr/bin/env curl -qsK 99.conf
# Written by Evgeny Stepanischev, Nov 2026

# 99.conf

url = 0
variable = b=xxxxxxxxx
variable = B=xxxxxxxxx
variable = "bottles=no bottles"
variable = output@final.txt
variable = r1=x0
variable = run=step.conf
expand-variable = dc[0-0]={{b}}{{B}}
expand-variable = run{{dc}}=/dev/null
expand-config = {{run}}
expand-write-out = {{output}}

# inc.conf

expand-variable = digit[1-1]={{c}}
expand-variable = c[2-]={{c}}
expand-variable = i={{carry}}{{digit}}
expand-variable = digit[{{i}}-{{i}}]=01234567891234567890
expand-variable = carry[{{i}}-{{i}}]=00000000000000000001
expand-variable = n1={{digit}}{{n1}}
expand-variable = r1={{r1}}x{{digit}}
expand-variable = dc[0-0]={{c}}
expand-variable = inc{{dc}}=/dev/null
expand-config = {{inc}}

# step.conf

expand-variable = dc[0-0]={{b}}
expand-variable = b{{dc}}=xxxxxxxxxx
expand-variable = B{{dc}}[1-]={{B}}
expand-variable = b[1-]={{b}}
expand-variable = dc[0-0]={{b}}{{B}}
expand-variable = run{{dc}}=/dev/null
expand-config = {{run}}

expand-variable = next={{bottles}}
variable = carry=1
expand-variable = c={{r1}}
variable = r1=
variable = n1=
variable = inc=inc.conf
config = inc.conf
expand-variable = n{{carry}}=1{{n1}}
expand-variable = r{{carry}}={{r1}}x1
expand-variable = "bottles={{n1}} bottle{{plural}}"
expand-variable = "output={{next}} of beer on the wall.\n\n{{output}}"
expand-variable = "output=Take one down and pass it around, {{output}}"
expand-variable = "output={{bottles}} of beer.\n{{output}}"
expand-variable = "output={{bottles}} of beer on the wall, {{output}}"
variable = plural=s

# final.txt

No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.

Для запуска нужен cURL версий 8.12…8.16, в более поздних рекурсию ограничили до пяти уровней, так что пример работать не будет.

У меня тут используется несколько трюков.

Во-первых, конец я читаю из текстового файла final.txt. Очень удобно, что есть синтаксис для чтения диапазона, в одной из первых версий я этим пользовался, но потом решил, что это слишком запутывает программу.

Во-вторых, циклы и ветвления реализованы при помощи включения конфигурационных файлов друг в друга при помощи конструкции expand-config, так в параметре этой конструкции можно использовать переменные, возможно передавать управление в разные конфигурационные файлы в зависимости от содержимого переменных.

В-третьих, и тут самое сложное, как выводятся цифры. Я сильно упрощаю для понимания (в моей программе сделано чуть веселее), но общий принцип такой.

При помощи строковой конструкции var[1-] урезается контрольная строка, содержащая буквы «x». Таких строк две — одна содержит количество равное десяткам, другое — единицам.

Эта строки нужны для ветвления. Если взять первый символ конструкцией var[0-0], то добавив его к имени конфигурационного файла, можно получить условный переход — мы перейдём на config, если буквы закончились и на configx, если нет.

Таким образом, узнаём, что мы прошли всю длину контрольной строки. Параллельно мы точно так же отрезаем строку, содержащую цифры. Как только цикл остановился, срезаем первый символ и получаем нужную цифру, отдельно десятки и единицы, которые надо вывести.

На этих трюках основан весь код программы.

4 комментария

Несовместимость ARK3116T с «МакОСью»

Я несколько раз, пока рассказывал о своих исследованиях часов «Касио» серии «WQV», упоминал несовместимость инфракрасного порта «ARK3116T» c «МакОСью». Пока не забыл в чём она заключается (всё-таки не самые востребованные знания), расскажу побольше об этом.

Когда я подключаю инфракрасный порт к компьютеру или ноутбуку через USB, устройство рассказывает как с ним работать. В частности, сообщает список своих конфигураций. Каждая конфигурация описывает интерфейсы и каналы, через которые можно передавать данные. Компьютер читает это описание, выбирает конфигурацию, после чего предоставляет её интерфейсы программам.

Заголовок дескриптора конфигурации USB, указывающий на шестибайтное значение bConfigurationValue.

Чтобы выбрать какую-то конфигурацию, нужно указать число из её поля bConfigurationValue. Обычно там стоит число от единицы и больше. Ноль означает специальный случай: убрать выбранную конфигурацию и оставить устройство без рабочего набора интерфейсов.

«ARK3116T» объявляет единственную конфигурацию, но у него в этом поле как раз ноль. Возможно, когда это устройство проектировали, такой договорённости не было или разработчики просто этот момент не учли, я даже не пытался разобраться, но с обычным смыслом команд для работы с USB это не согласуется.

Поэтому «МакОСь» это число успешно читает, а ноль трактует стандартным образом: рабочая конфигурация не выбрана. Поэтому устройство в системе есть, а интерфейсов, через которые можно было бы передавать данные, нет.

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

На всякий случай я попросил нейросеть перебрать все возможные 256 индексов — вдруг есть конфигурация, которое устройство почему-то не объявляет. Увы, на каждое чтение вернулся тот же самый результат с нулевой конфигурацией. Похоже, при такой запросе индекс вообще игнорируется.

Интересно, что в ядре «Линукса» этот случай предусмотрен. Если устройство объявляет конфигурацию со значением ноль, система соглашается с ним работать и создаёт интерфейсы. В коде даже есть комментарий с объяснением этого исключения:

The USB spec says configuration 0 means unconfigured.
But if a device includes a configuration numbered 0,
we will accept it as a correctly configured state.
Use -1 if you really want to unconfigure the device.

В «Маке», похоже, единственная возможность заставить его работать — написать собственный драйвер, подписанный учёткой разработчика. У меня её нету, поэтому рассматривать этот вариант не буду.

Оставить комментарий

Русский след в «Президенте Кёртисе»

Девушка с хвостиком задумчиво смотрит на экран компьютера, где мелькают строчки программного кода.
Седьмая серия первого сезона

В проходном, но неплохом мультсериале «Президент Кёртис» я, как мне кажется, углядел привет всем русскоязычным зрителям — на экране, где героиня сериала Ро Бэнкс смотрит на экран с кодом, есть строчка, где написано let brin = yut + vred / 2. Мне кажется, эта формула означает: «Брин — это уют плюс половина вреда».

Там вокруг много других надписей, совпадающих с именами команды, занимавшихся сериалом, так что версия, как мне кажется, правдоподобная:

На экранеВ титрах
Adm.BAdam Burnier, артдиректор
Ken.SKen Siu, ведущий дизайнер персонажей
EmilyWEmily Walus, художница реквизита
SinhNSinh Nguyen, художник реквизита
KyleCKyle Capps, художник реквизита

Правда никакого Брина я найти в титрах не смог, думаю, что консультант, писавший им этот псевдо-ДжаваСкрипт, мог оставить такую шутку «для своих».

2 комментария

Casio WQV-3: взломал протокол «SWAN»

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

В прошлый раз с протоколом «SWAN», который «Касио» вставила в часы для взаимодействия с консолью компании «Бандай», мы расстались, когда я был в унынии. Уверенности, что протокол удастся взломать, у меня не было — часы выдавали одну и ту же последовательность и ни на что больше не реагировали.

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

Параллельно я за 50 рублей купил на «Авито» инфракрасник «KS959» и это была очень удачная покупка. Вообще я его покупал, чтобы посмотреть смогу ли я легко адаптировать под него своё приложение, но очень повезло — этот адаптер проинтерпретировал то, что часы выдают в режиме «SWAN» совсем другой набор байт, в котором нейронка узнала что-то похожее на протокол часов второй модели с некоторыми отличиями:

WQV‑2 OTHERSWQV‑3 SWAN
Заголовок04 FA…10 FA…
Подтверждение060D
Данные0511
Изображение120×120, 16 градаций серого176×144, RGB332

Оказалось, кстати, что обмен надо вести на скорости 38400 бод, а не 9600, как я считал ранее. Предыдущий адаптер видел байты только на этой скорости и это казалось логичным, так как в интернете есть упоминание, что приставка работает по инфракрасному порту именно на этой скорости.

В итоге я успешно прочитал снимки из памяти часов и закачал их назад, остались небольшие детали, после чего я смогу обновить своё приложение. Кстати, я уже добавил туда поддержку второй модели часов.

Остаётся раздобыть ещё две модели — первую и десятую, ну и взломать последний протокол часов, который предназначался для обмена картинками между двумя часами.

Оставить комментарий

Разбираюсь в сортах инфракрасников

Оказывается, мне очень сильно повезло, что один из двух инфракрасных передатчиков, которые я когда-то купил для часов «Касио» оказался «SigmaTel STIr4200». Я-то думал, что все эти устройства плюс-минус одинаковые, но оказалось, что они работают очень сильно по-разному.

Мне повезло, что этот инфракрасник заработал под «МакОСью» («Ark3116T», например, оказался несовместимым), повезло, что его параметры совпали с теми, что используют мои часы и повезло, что с этим адаптером можно общаться с веб-страницы. Иначе мой недавний проект не получился бы.

Как глубока кроличья нора, я понял только сегодня в ходе экспериментов. На днях мне пришли заказанные ранее «Casio WQV-2» в шикарном состоянии. Это более ранняя модель, ещё с чёрно-белой камерой, у которой протокол давно взломан.

Вместе с ним я заказал ещё один инфракрасный передатчик «KingSun KS-959», подумал, что он мне пригодится, тем более, что он стоил-то всего 50 рублей. Оказалось я был прав — пригодился.

Прекрасно работавший с «WQV-3» инфракрасник «SigmaTel STIr4200» вдруг стал иногда неправильно считывать байты при работе со второй моделью. Зато свежекупленный «KingSun KS-959» работает с идеально с обеими моделями. Зато с веб-страницей он оказался совместим не полностью.

Теперь у меня три инфракрасника: «SigmaTel STIr4200» работает с часами третьей модели и веб-страницей, «KingSun KS-959» работает с часами второй и третьей моделей, но с веб-страницей только через специально написанный адаптер, а «Ark3116T» не работает ни с чем, так как не совместим с «МакОСью».

Оставить комментарий

Гомер Симпсон и Великая теорема Ферма

На школьной доске Гомер Симпсон выводит уравнения, намекающие на опровержение Великой теоремы Ферма.
Гомер Симпсон пишет программу для калькулятора «Электроника МК-61»

Братишка сегодня рассказал, что «Симпсонах» как-то упоминалась Великая теорема Ферма в виде очень нетривиальной шутки.

Смысл теоремы в том, что для целых степеней n > 2 уравнение xⁿ + yⁿ = zⁿ не имеет целочисленных решений.

В сериале Гомер пишет на доске 3987¹² + 4365¹² = 4472¹². Серия вышла в 90-х и если взять заграничный инженерный калькулятор тех годов, то можно легко убедиться, что равенство выполняется. В этом виновата ошибка округления, которую калькуляторы тех лет, как правило, отобразить не могли. Так что можно было разыграть своих друзей-математиков.

Разумеется у меня возник вопрос — получится ли равенство, если вычислять то же самое на ретроконсоли «MK-61s»? Для этого я написал небольшую программу, которую видно на рисунке с Гомером.

На экране калькулятора Электроника МК-61 отображаются числа 92, 37 и 4471993, рядом видна надпись "Электроника МК-61 Classic".
Слева — возведение в степень трёх чисел, сложение и вычитание, справа — возведение в степень, сложение и нахождения корня 12-й степени

Ответа на аппаратном калькуляторе я его дождаться не смог, очень уж медленно, запустил в эмуляторе и там теорему Ферма опровергнуть не удалось — ни программой на доске, ни в варианте с вычитанием правой части из левой.

Советского математика Гомер обмануть бы не смог!

Добавлено: в комментариях справедливо указали, что вычисляется на самом деле 3987¹² + 4365¹² + 12, всё верно. Это я уже по привычке пытаюсь сделать любую программу меньше. Тут нейросеть предложила короткий способ снять число 12 со стека, я согласился, потому что при вычислении корня 12-й степени это значения не имеет.

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

«Электроника МК-61»: область Ms

Зелёная плата микрокалькулятора Электроника МК-61 с дорожками, контактами и надписью "Ms".
Будущая плата для чтения внутренностей калькулятора

Внутри калькулятора «Электроника МК-61» есть своя терра инкогнита — территория, на которую практически не ступала нога советского программиста. Речь, конечно, об Ms — дополнительной области памяти, доступ к части которой в серийном «МК-61» возможен только при помощи хаков.

В «МК-61s» я доделал команды для работы с ней, которые проектировщики не реализовали, но меня эта область памяти всё равно манит.

Во-первых, очень хотелось бы найти какой-то обходной путь, который позволит с ней работать без модификации прошивки калькулятора. Не исключено, что такой способ удастся подобрать при помощи нейросетей.

Во-вторых, не исключено, что там образовываются случайные числа, которые можно было бы прочитать и использовать для того, чтобы потом использовать их для генерации серий случайных чисел. Для «МК-61» существует точный аппаратный эмулятор и в нём эта область на старте заполнена нулями, но мало ли…

Случайные числа это проблема для «МК-61» — генератор после включения всегда генерирует одно и то же число. Наверное это неважно для расчётов, но для игр настоящая катастрофа.

В общем, хочу в эту тему погрузиться поглубже. Для этого я списался с Сергеем Фроловым, автором статьи «Внедрение в архитектуру советских программируемых калькуляторов „Электроника МК-52“», чтобы получить у него схему платы, которую он разработал для подобных исследований и заказал на «Авито» калькулятор «МК-52» — аппаратно он очень близок к «МК-61».

У Сергея оказалась дополнительная плата, которую он выслал абсолютно бесплатно. Плата уже приехала, компоненты к ней тоже скоро приедут. Собрать всё воедино согласился Алексей Сугоняев, член команды разработки ретроконсоли «МК-61s». Спасибо Сергею и Алексею, надеюсь, эксперименты принесут какие-нибудь интересные результаты!

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

Casio WQV-3 и приставка «Bandai WonderSwan»

Из оставшихся трёх режимов, которые я пока не реализовывал для своих «Касио» с фотокамерой, сосредоточился на двух — «OTHER» (работа с КПК и прочими устройствами) и «SWAN» (приставка компании «Бандай Намко»).

Протокол «OTHER» оказался максимально упрощённой версией «IrTran-P» со скоростью 115200 бод без всех опциональных возможностей. Так что тут без неожиданностей — быстро обнаружились приложения для КПК, которые реально использовались для связи с часами и только дело техники повторить тот же протокол, который они используют.

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

С тем как часы работают в режиме «SWAN» пока большие сложности.

Связку консоли компании «Бандай» и часов впервые презентовали в 2000-м году на выставке «WPC EXPO» осенью 2000-го года. Информации мало, но кое-то можно восстановить по редким фотографиям и нескольким сохранившимся репортажам.

На фото представлены Casio WQV-3 и Bandai WonderSwan Color с функцией синхронизации через камеру часов.
Что интересно 2000-м году показали часы WQV-2, хотя, судя по руководству, режима «SWAN» в нём нет

Часы обменивались с приставкой через модуль «WonderWave», который поддерживает одну-единственную скорость обмена — 9600 бод, режим — «SIR». Судя по тому, что у него внутри, своей собственной логики модуль не имеет, весь протокол обмена должен был реализовываться приложением внутри приставки. Это плохие новости, потому что приложение так и не появилось, хотя в часах реализация обмена осталась в модели «WQV-3» и более поздней «WQV-10».

Инструкция по подключению портативной игровой приставки Bandai WonderSwan к часам Casio WQV-3 через инфракрасную связь.
Это я при помощи ИИ совместил два руководства и показал как могла бы выглядеть инструкция для обмена часов и приставки

Это всё сильно затрудняет работу над протоколом. Надежды я не теряю, но выяснить пока удалось немного. Думаю, что протокол симметричный — если записать, что часы передают, а потом проиграть это в том же порядке часам в режиме приёма, то велика вероятность, что всё заработает, но пока я до этого ещё не дошёл. Если это не так, то я вряд ли его взломаю.

Пока всё, что я имею — в режиме передачи часы повторяют последовательность 76 06 F0, ни на один известный протокол передачи по инфракрасному порту это не похоже. Передаются 22 группы за 14,31 секунды. Попробую передать эту последовательность обратно. Пока движется медленно — часы у меня одни, а исследовать параллельно приходится оба протокола.

Кстати, опять же убедился, что у нейросетей пока до печального туго с фантазией. Даже нехитрую мысль «давай запишем в одном режиме и воспроизведём в другом» мне пришлось предлагать самому, хотя догадаться до этого, вроде бы, несложно.

Оставить комментарий

Другие режимы обмена Casio WQV-3

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

Меня заинтересовало меню выбора устройства для обмена фотографиями. В меню обмена кроме компьютера, есть ещё три варианта: «WATCH», «OTHERS» и «SWAN».

На экране часов отображается надпись IRCOM, затем спустя секунду появляется меню IR MENU с четырьмя пунктами.

С «WATCH» всё довольно понятно: можно передавать фотографии между двумя часами. На одних выбираешь «SEND», на других — «RECEIVE». Снимки передаются по одному, получателю компьютер вообще не нужен.Часы Casio WQV-3 демонстрируют процесс отправки и приёма фотографий между устройствами через инфракрасное соединение.

В инструкции этот вариант подробно описан: кладёшь часы инфракрасными окошками друг к другу под углом не больше пятнадцати градусов друг другу. Никаких загадок, кроме самого протокола обмена, который нигде, разумеется, не описан.Часы Casio WQV-3 располагаются напротив друг друга инфракрасными портами под углом не более 15°, расстояние между ними должно составлять максимум 10 см (4 дюйма).

Из оставшихся вариантов проще всего оказалось понять что такое «SWAN» — по всей видимости это игровая приставка «Bandai WonderSwan». Для неё существовал инфракрасный модуль «WonderWave», а связку приставки с часами-камерой «Касио» показывали на выставке «Tokyo Game Show» весной 2001 года.

Со стороны «WonderSwan» нашлись старые описания обмена через «WonderWave» и исходники утилит. Попробовал использовать их как отправную точку, но пока ответа от часов пока не получил. Как именно часы работают в режиме «SWAN», ещё предстоит выяснить.

Сложнее всего было понять что такое «OTHERS». Разобраться удалось благодаря заметке на сайте Маркуса Грёбера, автора программы для подключения старых часов «Касио» к коммуникаторам «Нокиа». Оказывается часы в этом режиме передают снимки по стандартному протоколу «IrTran-P».

Например коммуникатор «Нокиа 9210» поддерживал такой протокол нативно и, по всей видимости, умел обмениваться снимками с часами напрямую.

2 комментария