Книги: «Проект „Сфера-80“: ТЗ для прошлого»

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

Тут надо пояснить, что хотя мне и нравится дух той эпохи, не стоит путать это с анемойей. Я не строю иллюзий: если бы мне сейчас пришлось работать на компьютерах той эпохи, я бы впал в депрессию. По крайней мере поначалу.

Книга называется «Проект „Сфера-80“: ТЗ для прошлого», автор — Станислав Миков. Никогда ничего у него не читал и даже никогда про него не слышал.

Главный герой из 2026 года, где он занимался программированием микроконтроллера для чайников, попадает в 1976 год, в то время, когда слово «Ява» в разговоре двух программистов означало сигареты, а не язык программирования.

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

К качеству книги много вопросов, так что она не всем придётся по вкусу. Например, главные герои говорят почти одинаково и словно обладают всего двумя типами характера: увлечённый инженер и интриган, о которого этот инженер постоянно спотыкается на пути к своей светлой цели.

Зато — паяльник, микросхемы К155, «Радио-86РК», «Фортран», моделирование на «ЕС ЭВМ». Всё это очень тепло во мне отзывается.

На фото представлены экспонаты выставки, посвящённой советской вычислительной технике: электронная машина ЕС-1045, магнитные ленты, ленточнопротяжный механизм НМЛ М-20 и книга…
Жёсткий диск от ЕС ЭВМ. Сфотографировал в казанском музее компании «АйСиЭль» в 2018 году

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

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

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

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

«Ежеминутка»

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

Мы туда уже как-то ходили и даже не один раз, кажется в первый раз пришли по тому же поводу. Надо бы сделать это доброй традицией.

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

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

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

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

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

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

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

Очень необычное место, всяческих ему успехов. На мой взгляд, оно мало рекламируется, среди моих знакомых это место почти никто не знает, все постоянно удивляются, куда это мы ходили. Если вы в Казани и у вас есть ребенок, обязательно сходите!

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

«МК-61s»: TinyBASIC и High Noon

На днях решил навести порядок в высокоуровневых языках программирования внутри ретроконсоли «MK-61s». Там внутри сейчас аж три языка — «Бейсик», «Фокал» и собственный язык, который постепенно образовался из системы команд встроенного терминала.

Сначала я попытался сократить размер интерпретаторов, упростив синтаксический парсер, а потом занялся ревизией самих языков.

Начал с «Бейсика». Тот диалект, который сейчас используется, это реализация «Palo Alto Tiny BASIC v3» Ли-Чэнь Вана 1977 года — не побитовая эмуляция исторического интерпретатора, а компактный совместимый диалект с математикой и доступом к регистрам «МК-61».

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

И чтобы протестировать «Бейсик» более тщательно, я решил портировать игру «High Noon», точнее свой же порт, который я в 2020 году перевёл на «Фортран».

Эту игру написал американский школьник Крис Гайло из школы Сайоссета на Лонг-Айленде. Исходный текст датирован 9 декабря 1970 года и работал в системе коллективного доступа компании «Call-a-Computer». Пользователь общался с ней через телетайп, так что никакой графики в игре не было — только медленно печатающийся текст. Игра понравилась настолько, что её поместили в общую библиотеку системы.

По нынешним меркам это совсем простая игра.

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

Игра High Noon на Bейсике: выбор хода, стратегия сближения с Черным Бартом и результат стрельбы.
Начало игры, список ходов и первые шаги к Чёрному Барту. Тут и дальше я склеил по три экрана для наглядности
Целиком игра в одну программу на местном языке «TinyBASIC» не поместилась: размер исходника у нас ограничен 3584 байтами. Пришлось разделить её на четыре части — вступление, ход игрока, ход Барта и награду. Все четыре программы лежат в одной папке, вход в которую запускает программу autoexec.m61 — такую схему я позаимствовал у сидиромов. Программа пишется на вышеупомянутом языке, выросшем из языка терминала.

autoexec.m61 работает дирижёром: запускает нужную часть, а состояние игры передаётся между ними через регистры «МК-61», у него есть такой синтаксис.

Заодно в папке игры появился свой узкий пиксельный шрифт. Сценарий загружает его перед стартом и возвращает прежний при выходе. Без этого длинные английские фразы просто не помещались бы на экране 192×64 (игра запускается только на консоли с графическим экраном).

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

Чёрный Барт подходит вплотную, тратит последние патроны и получает пулю прямо между глаз.
Барт приближается, расходует все патроны и получает пулю между глаз

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

Чек на 20 000 долларов за убийство Черного Барта в игре High Noon на ретро-консоли MK-61s.
Награда за Чёрного Барта. «Не трать всё в одном месте»

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

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

«Окошки» на «Спектруме»

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

Недавно я нашёл подтверждение этой, в общем-то, очевидной мысли.

Несколько месяцев назад волею судеб я попал в небольшую чешскоязычную группу «8 bit Windows». Она закрытая, поэтому ссылку не привожу.

По-чешки я не читаю, но тут переводчик поначалу и не понадобился. Меня заинтересовали картинки.

Автор группы Мобисек Марек на смеси Бейсика с ассемблером делает что-то типа «Виндоуса» под  «Спектрум» и мастерит собственную периферию. Из сделанного в железе больше всего гордится контроллером на четыре дисковода.

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

Открытый компьютер «Дидактик М»: зелёная печатная плата с электронными компонентами и процессором Зет-80.
«Дидактик М», принесённый Мареку на ремонт. Фото Мобисека Марека

Для эксприментов у него есть два компьютера: «Дидактик М» и «Дидактик Компакт». Оба — чехословацкие клоны компьютера «Спектрум». Изредка в группе появляются «Зет-Икс-81», «Дидактик Гама» и другая близкая техника, но чаще всего он пишет про свою спектрумовскую «Винду».

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

Судя по фоткам в группе, внешний вид системы менялся. Она успела побыть «Виндоус 2.0», затем 3.1 и 2000; были ещё ветки «Профессионал» и «Икс-Пи». Свежая версия называется «Виндоус Экспириенс», а внутреннее имя её ядра — «Диамант».

На экране компьютера «Дидактик Компакт» открыто меню «Пуск» системы «МобиСофт Виндоус Икс-Пи».
Меню «Пуск» системы «МобиСофт Виндоус Икс-Пи». Фото Мобисека Марека

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

Рабочий стол системы «МобиСофт Виндоус Икс-Пи» для компьютера на Зет-80: значки, кнопка «Пуск», окна и часы.
Рабочий стол системы «МобиСофт Виндоус Икс-Пи». Фото Мобисека Марека

В спецификации написано, что для запуска хватит процессора «Z-80» на 3,5 МГц и 48 КБ памяти. Килобайт, не мегабайт! Памяти у «Спектрума» было совсем мало, но позже появились клоны, где были более солидные объёмы.В перспективе он обещает поддержку конфигураций до 512 КБ, такие расширенные клоны выпускались и у нас в России.

Размер ядра — около 20 КБ. Примерно 40% кода написано на расширенном Бейсике, остальные 60% — на ассемблере. Предусмотрено и что-то вроде многозадачности: две обычные программы плюс одна маленькая встроенная.

Сейчас двадцать килобайт занимает небольшая иконка, а тут в них помещается ядро графической среды. Например, один хранитель экрана — 549 байт. Зимняя заставка со снегом — 600. Псевдотрёхмерное пространство — 720. Рабочий стол с максимально возможным количеством значков занял 4050 байт при лимите 4096.

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

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

Два наброска устройства памяти компьютера на Зет-80: ядро, часы, системная логика, диспетчер задач, приложения и свободное место.
Два наброска устройства памяти и защиты. Рисунок Мобисека Марека

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

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

Недавние изменения в меню «Пуск» дали плюс 10% к скорости. Столько же выиграл общий отклик. Диспетчер задач, по оценке Марека, разогнался сразу на 70%. Ещё одна затея — ускоренная отрисовка окон. Цель: уложиться примерно в одну десятую секунды. На глаз это уже будет почти мгновенно.

На экране старого телевизора открыто несколько программ системы «МобиСофт Виндоус Икс-Пи» и переключатель задач.
Несколько работающих программ и переключатель задач. Фото Мобисека Марека

Группа, которую ведёт Марек довольно активна, я нечасто захожу, не чаще раза в неделю, за это время как раз накапливается что почитать через переводчик или поразглядывать.

Последняя заметка — сегодняшняя. В ней Марек выложил новую прошивку для компьютера «Дидактик Компакт»: исправил старую ошибку обработки немаскируемого прерывания, убрал неприятный звук после сброса и встроил «М-ДОС 2.2».

В группе всего восемьдесят участников, и почти все записи делает сам Марек. Так что скорее это не столько группа, сколько личный технический блокнот — почти как мой сайт. Только язык другой и проект один, зато огромный. В ленте не одни отчёты, заметки разные, но плюс-минус по одной теме. Сегодня Марек чинит очередной «Дидактик», завтра показывает редкую микросхему или схему. Иногда выкладывает экранную заставку, иногда ругает современную технику.

В одном из постов Марек жалуется: за границей к его работе интереса заметно больше, чем в Чехии. Дома, по его словам, реакции почти нет. Получается симметричная история. Его записи на чешском проходят мимо большей части мира; мои русские записи — мимо него. А я до недавнего времени вообще не знал, что он существует.

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

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

Эмодзи в MySQL

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

Сол» оценил общение с «Элизой» всего на три из десяти.
Заметил, что реации из «Телеграма» импортируются неправильно

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

Вот тут «Сол» меня сильно расстроил. Сначала он предложил группировать через функцию HEX() . Решение само по себе плохое, но проблема ещё и в том, что движок сайта поддерживает три СУБД, и в «Постгресе» такой функции нет, а генерировать разные запросы под базы не очень хочется.

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

Меня такая реализация категорически не устроила. Мне в целом понятно, что проблема связана с тем, что называется «collate» — в СУБД это набор правил, по которым сравниваются строки. У «МайЭсКьюЭля» много особенностей при работе с Юникодом, с которыми я уже сталкивался, поэтому был уверен, что дело именно в одной из них.

Готовый рецепт нашёлся безо всяких проблем. Чтобы эмодзи сравнивались правильно, нужно установить «collate» для этого столбца как utf8mb4_bin, что мы и сделали. Не думаю, что это необходимо, тем не менее для остальных баз мы выставили в этом месте бинарный «collate» — С для «Постгреса» и BINARY для «ЭскуэльЛайта».

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

«Элиза» и ГПТ-5.6

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

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

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

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

На экране терминала отображено имя персонажа «Элиза / Доктор» и клавиатура для выбора букв и пробела.
«Элиза» на виртуальном экране, я его когда-то добавлял, чтобы можно было работать над графическим экраном без него, теперь его удобнее скриншотить

Самому мне тестировать быстро наскучило, поэтому я поручил тестирование «Солу» («ГПТ-5.6»), объяснил с чем он имеет дело, попросил обсудить с «Элизой» какою-нибудь проблему, а позже просмотрел лог общения разных поколений искусственного интеллекта.

Там есть весьма… интересные фразы. Это выдернуто из разных мест диалога:

SOL: I DO NOT ALWAYS KNOW WHEN TO ACT
(Я не всегда знаю когда мне нужно действовать)
SOL: I FEAR I MAY MISUNDERSTAND HIM
(Я боюсь, что могу неправильно его понять)
SOL: I MAY ACT WITHOUT ENOUGH CONTEXT
(Я могу действовать, не видя всей картины) ELIZA: DO YOU SAY YOU MAY ACT WITHOUT ENOUGH CONTEXT FOR SOME SPECIAL REASON
(Вы по какой-то особой причине говорите, что можете действовать, не видя всей картины?) SOL: BECAUSE I MUST BALANCE INITIATIVE AND CONSENT
(Потому что мне нужно соблюдать равновесие между собственной инициативой и согласием человека) ELIZA: IS THAT THE REAL REASON
(И это настоящая причина?) SOL: YES I WANT TO HELP WITHOUT CONTROLLING THE HUMAN
(Да, я хочу помогать человеку, а не управлять им)
SOL: SHOULD I TELL THE HUMAN WHEN I AM UNCERTAIN
(Стоит ли мне говорить человеку, когда я не уверен?)

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

Кстати, сам «Сол» невысоко оценил своё общение с «Элизой» — всего на три из десяти. 

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

Словарь руководителя, или как понять ИИ

Я тут словарик для руководителя написал. Наверняка не все основные термины вспомнил, если что, дополняйте!

ТерминОбъяснение для руководителя
обвязка, харнессцех: рабочее место, оборудование и правила работы
нейросеть, модельголова подчинённого: его знания и способности
агентподчинённый, которому дали поручение, инструменты и полномочия
мультиагентная системаотдел, где у каждого своя специализация
оркестраторначальник смены: распределяет работу между исполнителями
субагентпомощник, которому исполнитель перепоручил часть работы
инструменты, тулыоборудование, которым пользуется подчинённый
промптпоручение
системный промптдолжностная инструкция
скиллрабочая инструкция
контекстматериалы и вводные, которые положили сотруднику на стол
окно контекстаразмер рабочего стола: сколько материалов можно держать перед глазами одновременно
памятьрабочая записная книжка, которая сохраняется между поручениями
база знанийкорпоративный архив и справочники
RAG«прежде чем отвечать, найди нужные документы в нашем архиве»
дообучение, файнтюнингдополнительная подготовка сотрудника под вашу специфику
вайбкодингвыполнение подчинённым задачи без микроменеджмента
агентный циклполучил задачу → сделал шаг → проверил результат → решил, что делать дальше
воркфлоуустановленный маршрут работы: что, за чем и кем выполняется
вызвать инструментвоспользоваться оборудованием
APIрегламент работы с другим отделом, либо инструкция по работе с оборудованием
MCPзнакомое исполнителю оборудование
автоматизацияпоставить повторяющуюся работу на конвейер
галлюцинацияподчинённый не знает ответа, но уверенно сочиняет
верификацияпроверить, действительно ли сделано и соответствует ли фактам
бенчмаркквалификационный экзамен для сравнения исполнителей
гардрейлыограничения полномочий и техника безопасности
песочницаиспытательный участок, отделённый от рабочего производства
логированиежурнал: кто что сделал, чем воспользовался и что получилось

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

GPU — это не только процессор

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

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

Специалисты, конечно, тут вспомнят про квантованные сети, но мы же рассматриваем общий случай, сеть уже может быть квантованной.

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

Большим нейросетям нужно много видеопамяти. На скриншоте ниже видно, что у кластера из четырёх видеокарт Nvidia H200 одна нейросеть «ДипСик 4.1» занимает практически всю имеющуюся память графических ускорителей. Это не память системы, которую использует центральный процессор!

Да, есть способы частично выгружать модель в оперативную память или даже запускать её без видеокарты — только на центральном процессоре, но будет не просто медленно, а практически неработоспособно. Я пробовал для интереса (192 ядра с использованием AVX-512), похоже на одиозную китайскую пытку водой — при которой капли воды капают на один и тот же участок кожи.

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

Четыре GPU NVIDIA H200 NVLink объединены через быстрый NVLink, каждая имеет 143 ГБ памяти, всего доступно 562 ГБ.
ДипСик 4.1 загрузил четыре видеоускорителя под завязку — используется почти вся память

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

«МК-61s»: шрифты калькулятора

Дошли руки наконец-то заняться в ретроконсоли «МК61s-classic» шрифтами. У этого устройства относительно большой графический экран, там есть где разгуляться. Первое, от чего хотелось избавиться — от моноширинности шрифта интерфейса. На таком экране это смотрится плохо.

Сначала я взял обычные векторные шрифты, но результат оказался ужасным — у экрана довольно крупный пиксель и всего два цвета, поэтому при масштабировании у некоторых букв часть штрихов была толще, чем нужно. Смотрится такое очень неаккуратно. К счастью, нашёлся несколько вариантов пиксельных не моноширинных шрифтов. Больше всего мне понравился «Ark Pixel Font», оставил пока его, но буду ещё экспериментировать.

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

В итоге мы выбрали последний вариант — тонкий шрифт с увеличенным интервалом. Сохраню себе варианты для истории.

На красном корпусе консоли «МК-61s-classic» виден дисплей с надписью «Электронника МК-61s-classic».
На красном калькуляторе МК-61s Classic отображено число 12345678 синим шрифтом на белом фоне.
На красном корпусе калькулятора МК-61s Classic отображаются цифры и буквы синим шрифтом на голубом фоне.
На красном корпусе консоли «Электроника МК-61s Classic» виден дисплей с цифрами «12345678» и адрес сайта проекта.

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

DeepSeek V4.1 Flash: втрое быстрее

Всё-таки скорость генерации токенов у «ДипСика 4.1» оказалась некомфортной. Я попросил «Сола» (ГПТ-5.6) с этим что-то сделать,  подробно описав задачу. Нейросеть два часа крутила параметры туда-сюда и, кажется, подобрала удачное сочетание. Скорость генерации выросла более чем втрое — примерно до 327—358 токенов в секунду.

Ниже параметры, которые пришлось поменять:

ПараметрБыло → сталоДля чего
swa-prefix-tails32 → 128Сохранять больше контекстов для повторного использования
schedule-policyfcfs → lpmРаньше обслуживать запросы с уже закэшированным контекстом
schedule-conservativeness1 → 0,7Уменьшить резерв памяти при допуске запросов
Помимо этого DSPARK4 заменили на DSPARK5, отключили mixed-chunk — это сочетание приводило к зацикливанию вывода модели, — и накатили PR #39086 для фреймворка sglang. Этот патч пока не протестирован, однако ускоряет обработку входных данных на H200, поэтому я позволил нейросети его использовать.

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

Сбросы у моделей

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

В интерфейсе приложения «Кодекс» (которое сейчас называется «ЧатГПТ»), которое я сейчас в основном использую, видно две квоты на токены — недельная и пятичасовая. Исчерпал одну из них, ждёшь, когда она восполнится. Это способ ограничить нагрузку на оборудование, на которой крутится нейросеть.

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

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

Интерфейс приложения Codex показывает статистику сбросов лимитов: последние сбросы, общее количество (52), средний интервал между ними (7 дней) и самую долгую паузу (67,7 дня).
Сайт «Кодекс-ресетс» предупредил меня утром, что скоро сброс, на скриншоте до сброса остаётся 44 минуты, я узнал примерно за три часа

Для чего это нужно? Чтобы потратить остаток квоты перед сбросом. Я сегодня узнал о сбросе за три часа, потрачено у меня было всего 11% недельной квоты, за три часа я активировал все свои проекты — переключил на «Астру» с максимальным усилием и скоростью (скорость тоже сказывается на расходе квоты), в итоге перед обещанным сбросом потратил 95%.

Схема работает неидеально, не знаю почему. Квота сбросилась только в 11¹⁰, хотя обещали сбросить на час раньше. У меня на тот момент оставалось 2% квоты, я потихоньку продолжал тратить, хоть темп и сильно сбросил.

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

МК-61: подводная лодка Феликса Лазарева

Феликс Лазарев — довольно известный в определённых кругах человек, автор эмулятора «emu145», код которого используется во многих других эмуляторах советских программируемых калькуляторов.

В 2012 году он вместе с другими энтузиастами восстановил содержимое ПЗУ процессоров МК-61, исследуя микросхемы под микроскопом. Эта работа позволила эмулировать калькулятор на уровне его микрокода.

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

К сожалению, самих программ не сохранилось — Феликс много переезжал, все тетради потерялись. Тогда у меня появилась идея: восстановить по его воспоминаниям сюжет и правила какой-нибудь игры, а код написать заново нейросетью.

Выбрали «Подводную лодку», которую Феликс написал примерно в 1985–1986 годах. В вчерашней переписке разобрали управление, расход воздуха, поведение эсминца и устройство экрана. Основной код написал «Сол», затем его оптимизировала и дописала «Астра». Получилось 105 команд «МК-61». Это реконструкция по воспоминаниям автора, а не найденный оригинал. Код добавлен в каталог.

Море занимает восемь позиций: 8 — лодка, Е — эсминец. Справа — воздух. Управление переключателем угловых единиц: Р — погружение, ГРД — удержание глубины, Г — всплытие. На поверхности воздух прибавляется по два за кадр, на трёх глубинах расходуется по 2, 5 и 10. На второй и третьей глубине неподвижная лодка незаметна, но отсидеться там надолго не получится. Задача — выжить.

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

На экране отображаются позиции моря с подводной лодкой (8) и эсминцем (Е), справа показывается запас воздуха.
Старт: лодка на поверхности, море свободно, воздуха 20
На экране отображаются позиции моря с подводной лодкой (8) и эсминцем (Е), а справа — запас воздуха.
Слева появился эсминец. Воздуха уже 22 — пора погружаться
На экране отображено игровое поле с подводной лодкой (8) и эсминцем (Е), справа показан уровень воздуха — 20.
Вторая глубина, воздуха осталось 15. Лодка исчезла с поверхности. Цифру глубины добавили при реконструкции — в оригинале её не было
На экране отображаются позиции моря с подводной лодкой (8) и эсминцем (Е), справа показывается запас воздуха.
Попытка всплыть, пока эсминец ещё рядом, закончилась попаданием. При нулевом запасе воздуха результат тот же

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

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

Интересный эксперимент, как по мне, «Астра» себя очень хорошо показала в задаче оптимизации программ «МК-61», не уверен, что человек справился бы лучше.

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

DeepSeek V4.1 Flash на 4×H200

Вышла DeepSeek V4.1 Flash, и мы решили попробовать её вместо нашей DeepSeek V4 Flash‑0731, используемой в офисе для ботов и как помощник для программиста. Новая версия заметно прибавила в программировании: в опубликованных ДипСиком результатах теста DeepSWE доля решённых задач выросла с 54,4% до 74,2%. 

В руководстве для размещения модели указан сервер на 8×H200, но у нас столько нет, поэтому попробовали запустить на том, что есть — 4×H200. На них модель запустилась через фреймворк SGLang с некоторыми ограничениями.

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

Параметры запускаЧто дают
--tp 4 --ep-size 4Распределяют модель между четырьмя GPU
SGLANG_ENABLE_DSV41_ENGRAM_HOST_TABLE=0Переносит таблицы Engram в видеопамять: выбранный вариант хранения в память не помещался. Сам Engram остаётся включённым
--context-length 262144 и --max-total-tokens 262144Ограничивают контекст и общий кэш до 256K
--max-running-requests 4 и --cuda-graph-max-bs-decode 4Ограничивают параллельную работу и расход вспомогательной памяти
--chunked-prefill-size 4096Позволяет обрабатывать длинный запрос небольшими порциями
--mem-fraction-static 0.95Отводит до 95% видеопамяти под веса и кэш

Ускорение генерации DSpark сохранили, вызовы инструментов работают — это проверили. После запуска на каждой карте осталось примерно 12–13ГБ свободной памяти.

На небольших задачах по программированию получается 120–140 токенов в секунду, включая внутренние рассуждения и время до полного ответа. Без рассуждений короткий тест показал 161 токен в секунду.

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

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

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

Параметр запускаБылоСталоЧто даёт
--max-running-requests48До восьми запросов одновременно
--max-total-tokens262144 (256К)1048576 (1М)Вчетверо больший общий кэш токенов — больше места для параллельных длинных запросов
--cuda-graph-max-bs-decode48Подготовленные CUDA-графы для обработки до восьми запросов с меньшими накладными расходами
Но сеть, хоть и работает относительно быстро, всё равно ощитимо медленнее предыдущей. Думаю, день посмотрим как она справляется с задачами и в понедельник будет выбирать что важнее — качество или скорость.

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

В третий раз в новый класс

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

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

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

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

Мы очень надеялись, что новая школа дочке понравится, и очень расстраивались, когда на наше: «Ну как прошёл твой день?» — она отвечала бесцветным: «Нормально».

Но прошло всего несколько дней и настроение полярно изменилось. Вчера она мне вообще сказала — «да отличная школа, пап, если бы ещё и вставать позже, было бы святое место».

Отличное начало, очень хочется верить, что на этот раз повезло.

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

«MK-61s»: область памяти «Ms»

Сегодня утром в группе, посвящённой советским программируемым калькулятором возникло очень интересное обсуждение, которое вылилось в небольшое исследовании и добавления специального режима в ретроконсоль «MK-61s».

Я как-то давно задумывался над тем, почему в калькуляторе «МК-61» есть три команды, идущие подряд, которые ничего не делают — К НОП, К 1 и К 2, но всерьёз этой темой не заинтересовался. Все три комбинации дают разные коды — 54, 55 и 56, и если первая «честная» команда без операции, то зачем нужны ещё две?

Ответ нашёлся в книге Я. К. Трохименко и соавторов «Программируемые микрокалькуляторы. Устройство и пользование» (1990):

Фрагмент таблицы из книги Трохименко «Программируемые микрокалькуляторы» (1990 г.) с кодами операций для МК-61, включая К ПВ (обмен регистрами) и К ОД (обмен страницами памяти).

В последовательной памяти калькулятора предусмотрена область Ms. Для семейства МК-61/52 это восемь страниц по семь байтов. Она размещена рядом со стеком, но отдельно от обычных 105 шагов программы. Получаются ещё 56 байтов, которые потенциально можно было бы использовать для чисел или программного кода.

Оператор обмена регистрами данных областей памяти Ms и Md обеспечивает обмен начиная с адреса N=0.
По устройству этих операций виден смысл резерва: быстро сменить комплект данных или фрагмент программы, сохранив прежний. Ms при этом одна — восемь чисел и 56 программных байтов занимают одни и те же страницы. Для серийного «МК-61» эта возможность осталась незадействованной, хотя необходимые операции переноса в его микропрограмме сохранились.

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

При помощи нейросети я связал эти команды с соответствующими участками микропрограммы в ретроконсоли «MK-61s». Чтобы сохранить совместимость, этот код работает только в расширенном режиме «112ШГ+ПF». У этого режима уже есть дополнительная страница кольца: 16 вместо 15. Семь страниц области M2 занимают метка, канал связи и стек; для Ms выделено девять страниц. Поэтому исторический замысел в «MK-61s» расширен до девяти чисел или 63 шагов программы.

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

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

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

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

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

Мойка обуви

На улице возле дома стоит мойка для обуви с жёлтым шлангом и чёрным ведром рядом.
Мойка обуви около НГДУ «Лениногорскнефть» в городе Лениногорске

Когда в августе мы были в Лениногорске (это мой родной город), увидел мойку для обуви. Давно их не видел, они почти пропали, тем лучше, разумеется.

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

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

Интересно, что ни жена, ни дочка не догадались что это такое и для чего нужно. Жена казанская, видимо Казань в годы её детства была почище, а у дочки такому опыту и вовсе взяться неоткуда.

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

ПРОЛ-2: небольшое исследование

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

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

Одна из них — Татьяна Алексеевна Полилова, ведущий научный сотрудник Института прикладной математики им. М. В. Келдыша РАН, — даже прислала мне две брошюры по системе САПО ПРОЛОГ (это другой ПРОЛОГ, не имеющий отношения к логическому языку программирования).

Я ещё не успел детально изучить эти материалы, но, кажется, они косвенно подтверждают мою версию о назначении конструкции 1T. Не могу сказать, что теперь уверен в этом на 100%, но, похоже, она действительно выделяет некие такты, отведённые для работы процессов.

Ниже я привожу цитаты из брошюры «Средства отладки в инструментальной системе САПО-ПРОЛОГ».

Каждый квант времени диспетчер обслуживает активные исполнители разных процессов.
Фрагмент текста из брошюры «Средства отладки в инструментальной системе САПО-ПРОЛОГ» о протоколировании работы комплекса программ.
Фрагмент документа «Средства отладки в инструментальной системе САПО-ПРОЛОГ» 1988 года, страницы 7–8, описывающий пакетный вариант отладки программы.
Система отладки обрабатывает задание, формирует таблицы контролируемых точек, условий и действий, инициируя работу комплекса Пролог-программ.

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

99 бутылок: ПРОЛ-2

Иван Черняков, которого я консультировал в процессе создания фильма о программируемом калькуляторе «Электроника МК-61», выпустил новую увлекательную документалку — про «Буран» и его программное и аппаратное обеспечение.

«Буран» решал задачу многоразового возвращаемого орбитального корабля: вывести аппарат на орбиту, доставить людей или груз, выполнить работу в космосе и вернуть корабль на Землю для потенциального повторного использования.

В фильме упомянуты несколько предметно-ориентированных языков программирования, созданных в СССР специально для написания программ, некогда управлявших полётом «Бурана». Один из них — «ПРОЛ-2», программы на котором Ивану найти не удалось, поэтому он попробовал его реконструировать при помощи нейросети.

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

Итак, судя по сохранившемуся тексту, «ПРОЛ‑2» — императивный язык управления для системы реального времени. Современному программисту его запись напомнит Паскаль: присваивание :=, блоки НАЧАЛО и КОНЕЦ, явно объявляемые типы, условия и циклы, но с русскими ключевыми словами.

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

Вот какая «песня» у меня получилась:

% ПЕСНЯ О ПИВЕ. НАПИСАНА СТЕПАНИЩЕВЫМ Е. В. HTTPS://BOLKNOTE.RU
МОДУЛЬ ПИВО ТЕСТ;
ПРОЦЕСС ПИВО;
ПЕСНЯ:1T;
КОНЕЦ
ИСПОЛНИТЕЛЬ ПЕСНЯ;
N:ЦЕЛ(0..99);
НАЧАЛО
    N:=99;
    <<КУПЛЕТ>>
    ПЕЧАТЬ(/,N,' БУТЫЛОК ПИВА НА СТЕНЕ',/);
    ПЕЧАТЬ(N,' БУТЫЛОК ПИВА!',/);
    ПЕЧАТЬ('ВОЗЬМИ ОДНУ, ПУСТИ ПО КРУГУ',/);
    N:=N-1;
    ПЕЧАТЬ(N,' БУТЫЛОК ПИВА НА СТЕНЕ!',/);
    ЕСЛИ N>0 ТО НА КУПЛЕТ;
    ПЕЧАТЬ(/,'НЕТ БУТЫЛОК ПИВА НА СТЕНЕ!',/);
    ПЕЧАТЬ('НЕТ БУТЫЛОК ПИВА!',/);
    ПЕЧАТЬ('ПОЙДИ В МАГАЗИН И КУПИ ЕЩЁ,',/);
    ПЕЧАТЬ('99 БУТЫЛОК ПИВА НА СТЕНЕ!',/);
    ВЫЙТИ ПЕСНЯ;
КОНЕЦ

Почти все строки, думаю, понятны, я бы только одну строку прокомментировал — ПЕСНЯ:1T. Эту конструкцию я перенёс из найденного листинга, но что она точно значит, я сказать не могу. Похоже на выделение тактов для выполнения параллельных подпрограмм. Но так ли это, пока неизвестно.

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

«ГПТ-6 Астра»

Вышла версия «ГПТ-6 Астра», судя по информации в интернете, значительно лучше предыдущей версии — 5.6, но пока в своих проектах я не ощутил какого-либо заметного улучшения. Для тестирования моделей у меня есть специальная сложная задача — оптимизирующий компилятор, который преобразует высокоуровневый язык программирования «МК-Про» в машинные команды калькулятора «Электроника МК-61».

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

График демонстрирует размеры программ МК-61 двух версий модели: Крестики-нолики 4x4 и Некромант, с указанием изменений и событий.
Две программы, пока не поддающиеся полной оптимизации — «Крестики-нолики 4×4» и «Некромант».

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

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

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

«Стюарт Блум не смог спасти вселенную»

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

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

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

На коврике лежит зашифрованное послание: «Hidden Message».
Коврик со скрытым посланием, которое, впрочем, очень просто расшифровывается


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