К началу августа мигающий треугольничек `` стал в КБ таким же привычным, как стул у кульмана.
Включаешь стенд — вспыхивает растр, пару секунд думает ЦУБ, потом в левом углу появляется этот знак и квадратик рядом, подмигивает: давай, говори.
Первые дни все к нему подходили почти торжественно. Считали «два плюс два», печатали «ПРИМЕР», радовались, что буквы не прыгают.
Через неделю отношение упростилось. `` превратился в инструмент. Вопрос был не «умеет ли машина разговаривать», а «что ей теперь сказать, чтобы она делала не только арифметику».
Ответ лежал пластмассовой коробочкой на краю стола.
— Вот, — сказал Игорь, ставя на стол тяжёлый магнитофон с надписью «Весна‑202». — Связующее звено между поэзией высоких технологий и прозой бытовой ленты.
Пыльный, с потёртыми углами, с двумя большими ручками громкости, «Весна» заняла пол‑стола. На боку — исцарапанный круглый разъём.
— Спасибо, Игорь, — сказал Алексей. — Давно пора уже перейти к хранению данных. Главное, с питанием не напортачить.
— Я от трансформатора отдельно, — успокоил Игорь. — Тут только сигнал. Смотрите.
Он развернул самодельную плату — на ней торчали два маленьких трансформатора, пара К155 и знакомую уже компанию им составляла пара конденсаторов К50‑16, горделиво подпираемая резисторами МЛТ.
— Это что за зверь? — спросил Евгений, заходя и зацепляя ногой табурет.
— Блок сопряжения, — с достоинством сказал Игорь. — сигнал сюда, прямоугольники отсюда. Запись — по одному уровню, чтение — через компаратор. Почти телетайп, только по‑современному.
Евгений взял плату двумя пальцами, повертел.
— Монструозно, — оценил он. — По сравнению с перфолентой — революция. По сравнению с нормальной лентой — костыль. Впрочем, у нас всё так.
Алексей склонился к плате, проверил схему: входной трансформатор, ограничение по уровню, простенький формирователь.
— Однобитный мир, — сказал он. — Условно ноль, условно единица. Как вы хотите кодировать?
— Импульс — один, пауза — ноль, — ответил Игорь. — Или наоборот. Тут, — он ткнул пальцем в схему, — счётчик считает длительность, если короче, чем опорная, — это ноль, если длиннее — единица.
Алексей дёрнул головой. В другом времени, на другом столе, всплыла белая надпись на сером фоне: `PRESS PLAY ON TAPE`. И характерный треск динамика, который то превращался в игру, то — в надпись «Ошибка загрузки».
Он моргнул, картинка растворилась в запахе канифоли.
— Если лента пойдёт чуть быстрее или медленнее — ваш «длиннее‑короче» поедет, — сказал он. — А у пользователей стоят не повенькие «Вёсны», а что‑нибудь старенькое и ненадёжное. Головки царапанные, моторы уставшие, пасики растянутые.
— А мы им скажем: «Покупайте хороший магнитофон», — невинно предложил Евгений. — Делов‑то. Вон у нас в вычислительном центре ленты не каждый аппарат читает. Нормально живут.
— В вычислительном центре над каждой лентой отдельная Тихонова стоит, — отрезал Алексей. — А мы хотим, чтобы условный шестиклассник сам мог вечером дома запустить программу, а не таскал магнитофон к оператору.
Игорь пожал плечами.
— Сначала давайте просто посмотрим, что он нам выдаст, — примирительно сказал он. — А потом уже будете его ругать.
Подключение получилось почти торжественным.
Игорь вставил вилку-«пятёрку» в магнитофон, вторую — в плату сопряжения. Плату — к свободному разъёму на задней стенке стенда. Саша, который вертелся рядом, подносил отвёртку, держал лампу‑ограничитель как талисман.
— Записываем пока из ниоткуда, — сказал Алексей. — Генерируем тестовый массив прямо на линии: чередование нулей и единиц, пусть как‑то выглядит.
Игорь щёлкнул клавишей «Запись», нажал «Пуск». Кассета с треском прокрутилась, мотор запел.
По жгуту от платы к «Сфере» побежали импульсы, негромко щёлкало реле в блоке сопряжения. На столе лежал осциллограф с кривой, похожей на кривые акульи плавники.
Записали минуту. Остановили.
— Получилось, — удовлетворённо сказал Игорь. — Во всяком случае, магнитофон что‑то записал. Теперь читаем.
— Стоп, — поднял руку Алексей. — Читать нам пока нечем.
Он кивнул на экран.
` _`
— У нас нет программы чтения ленты, — напомнил он. — В ПЗУ только монитор: строка ввода, печать, пара служебных команд. Все ваши «длиннее‑короче» мы пока можем только глазами смотреть.
Игорь замер.
— А загрузчик? — осторожно спросил Саша. — Ну, как вы говорили: «маленькая программка, которая сначала, а потом уже всё остальное»?
— В ПЗУ его нет, — сухо ответил Алексей. — Мы прожгли микросхемы две недели назад, когда протокола магнитофона еще не существовало. А перепрошить К556 нельзя — это билет в один конец, сам же помнишь, как мы не ту тетраду прожгли. Новых чипов у нас нет. Так что пока — руками.
Евгений фыркнул.
— Классика курицы и яйца, — сказал он. — Чтобы прочитать ленту, нужна программа, которая умеет читать ленту. А чтобы такая программа появилась, надо её сначала прочитать с ленты.
— Поэтому, — продолжил Алексей, будто не слышал, — придётся сделать, как в древних сказаниях. Взять шестнадцатеричный листинг, открыть тетрадь и вручную, руками, набить загрузчик в ОЗУ. Каждый раз при включении.
Саша тихо выругался.
— Вы хотите сказать… — начал он.
— Да, — кивнул Алексей. — Сейчас я буду вручную набирать байты кода. Двадцать штук. Потом командой «ПРХ» перейти на начало, а эта маленькая штука уже сама начнёт дёргать магнитофон и читать массив.
Он достал из папки тонкую тетрадь. На развороте — столбик:
`0400: 3E`
`0401: 01`
`0402: D3`
`0403: F0`
…
— Это что? — спросил Игорь.
— Мини‑загрузчик, — ответил Алексей. — Вход по адресу 0400. Выставляет в порт управление, ждёт фронт, считывает биты, собирает байты, складывает, начиная с 0500. Без изысков, без проверки контрольной суммы. Я пока экономил каждую инструкцию. И последние три байта — сравнение с контрольной суммой. Если не совпадет — зажги лампу «Ошибка»
— И сколько он весит? — уточнил Евгений.
— Двадцать четыре байта, — чуть виновато сказал Алексей. — Будет жить в ОЗУ. Пока.
Он повернулся к Саше:
— Пиши, я диктую. Адрес — код.
Саша сел к клавиатуре.
Курсор, как будто повеселев, продолжил своё мигание.
— Команда «ЗП» по адресу 0400, значение 3E, — диктовал Алексей. — Потом «ЗП 0401, 01». Потом «ЗП 0402, D3». Не торопись.
Экран наполнялся скучными строками:
`ZP 0400,3E`
`ZP 0401,01`
Многие в отделе на этом месте зевнули бы и пошли пить чай. Но для Алексея этот ручной ввод был как распевка: проверка точности рук и головы.
К третьему байту Саша пошёл быстрее, к пятнадцатому начинал сбиваться, Алексей останавливал, сверял с листингом, ругался вполголоса.
— Чувствую себя арифмометром, — ныл Саша. — Одно и то же, одно и то же…
— Арифмометр хотя бы не думает, — заметил Евгений. — А у тебя есть возможность осознанно страдать.
Скоро загрузчик был набит.
— Проверяем? — спросил Игорь.
— Проверяем, — сказал Алексей. — Команда «ПРХ 0400».
Курсор исчез. На секунду экран застыл. Где‑то в недрах ОЗУ крошечная программка начала бестолково дёргать порт, ждать фронты, собирать биты — правда, пока в никуда.
— Теперь можно и «Пуск» нажать, — разрешил Алексей.
Игорь включил магнитофон. Лента побежала, динамик зашипел треском. По осциллографу замелькали напряжения.
Секунды тянулись.
На экране ничего не происходило. Глазу там было нечего ловить: загрузчик тихо клал байты в память, никуда их не печатая.
— Всё? — спросил Саша. — Считало?
— Сейчас узнаем, — ответил Алексей. — Стоп.
Магнитофон остановился. В лаборатории стало непривычно тихо.
— Теперь команда «СМОТР 0500,0020», — сказал он. — Посмотрим первые тридцать два байта, что там есть.
Саша набрал команду. На экране побежали шестнадцатеричные пары.
`0500: AA AA AA 2B 9C 40…`
Алексей поморщился.
— Мы записывали «чередование нулей и единиц», — напомнил он. — Должно было быть типа «AA AA AA AA». А у нас тут уже на четвёртой позиции мусор.
— Меньше хаоса, чем в моей жизни, — философски заметил Евгений. — Но да, красиво не вышло.
Игорь склонился к осциллографу.
— Скорость плывёт, — признал он. — Нагрузку поставили, мотор чуток проседает. Длительность импульсов гуляет. Для «длиннее‑короче» это смерть.
Алексею ответа не требовалось. Всё было и так понятно.
В другом, ещё не наступившем для окружающих времени перед глазами стоял знакомый экран: чёрный фон, белая надпись. Раз за разом: треск, ожидание, и через пять минут вместо игры — короткое: «Tape loading error». А потом — опять перемотка, опять «нажмите play».
Здесь он только подходил к той же стене, но уже знал, сколько раз о неё можно удариться лбом.
— Нам нужен код, которому всё равно, что там с длительностью, — сказал он. — Фаза. Или хотя бы чередование по фронтам. Чтобы важны были не миллисекунды, а последовательность.
— То есть? — не понял Саша.
— Представь качели, — сказал Алексей. — Ты не считаешь точное время, а смотришь: пошли вверх, пошли вниз. Можно закодировать «ноль» как фронт в одну сторону, «единицу» — в другую. Тогда, если качели поедут чуть быстрее, последовательность не изменится.
Игорь задумчиво кивнул.
— Фазовая манипуляция, — сказал он. — Для этого нам понадобится либо более хитрый формирователь, либо часть задачи переложить на программу. То есть считать не длительность, а порядок смены.
— Именно, — подтвердил Алексей. — Мы и так собираемся программой смотреть на каждый такт. Добавить ещё одну проверку — не велика беда.
Евгений ухмыльнулся.
— Как говорил один наш программист, — заметил он, — любое железо можно исправить программой. Ты предлагаешь ровно это.
— Я предлагаю подгонять мир под пользователя, а не пользователя под мир, — возразил Алексей. — Потому что у нас есть мы, трое могучих умов с золотыми руками. А там будут тысячи людей с руками разной кривизны и магнитофонами разной усталости.
— Ты оптимист, — отрезал Евгений. — Думаешь, у нас будет «тысячи».
— Если будет десяток, мне уже спокойнее, — ответил Алексей. — Но пусть хотя бы им не придётся вместо задач по физике разбираться, почему у них повернулся фронт.
Фазовый эксперимент занял две недели.
Днём Алексей рисовал схемы, менял местами триггеры, ругался с Игорем, который пытался засунуть весь анализ в железо.
— Я хочу, чтобы на выходе был сразу байт, — ворчал Игорь. — Вот сюда подаю шум, отсюда получаю цифру. Всё. А ты мне предлагаешь оставить шум, а цифру вытаскивать мозгами машины.
— У машины мозги уже есть, — упрямо отвечал Алексей. — У тебя их на плате всего десяток К155. И к каждому надо потом бежать с паяльником. А программу я перепишу ночью из тетради — и всё.
Ночью Евгений на ЕС‑ке гонял модель: писал короткие программы, которые принимали на вход псевдосигнал с фазовыми сдвигами и проверяли, насколько криво можно его исказить, пока всё ещё удаётся восстановить исходную последовательность. В листингах фигурировали странные слова «PHASE0», «PHASE1», таблицы переходов.
— Если наша «Сфера» хотя бы на четверть так упряма, как ЕС, — заключил он, — она это осилит.
Параллельно продолжались ежедневные ритуалы с набивкой двадцати четырёх байт загрузчика.
Саша, ворча, освоил эту последовательность до автоматизма. На третий день мог называть коды по памяти. На пятый начал придумывать мнемонику:
— «3E» — это как «ЗЕ», значит, загрузка, — рассуждал он. — «D3» — «дёргай третий порт». Видите, всё логично.
— Через месяц ты будешь во сне диктовать эти коды, — обещал Евгений. — А через год ненавидеть.
Алексей молчал. Для него это было ценой входа. Пока так. Потом он найдёт, как дописать в ПЗУ лишние тридцать два байта. И не только их.
Первый более‑менее приличный результат получили в жаркое субботнее утро.
Двор завода плавился, асфальт у ворот был мягким, как резина, в окнах КБ висели мокрые марлечки — кто‑то пытался бороться с жарой.
В лаборатории стоял тяжёлый запах припоя и нагретого пластика. Магнитофон загудел, лента побежала, в динамике потянулся ровный, почти музыкальный треск — после всех фильтров и фазовых фокусов шум стал действительно похож на рваный, но ритмичный узор, а не на кашель простуженной линии связи.
Алексей и Саша опять набили загрузчик. Евгений включил «Пуск».
— Поехали, — сказал он. — Если сейчас вылезет не «рыжая каша», а что‑то похожее на наш тест, я пойду к Тихоновой и скажу, что её ленты — детские игрушки.
Минуту они просто слушали.
Потом остановили, дали команде «ПРХ 0400» вернуть управление в монитор, и Алексей тихо сказал:
— Смотрим с 0500.
Саша набрал команду.
На экране появилась строка:
`0500: AA AA AA AA AA AA AA AA`
Впервые.
Никаких случайных «9C», никаких дырок.
Следующая строка была такой же. И дальше — тоже. Там, где специально вставляли контрольный байт «55», он честно торчал в нужном месте.
— Ну, ну… — Евгений наклонился к экрану так, словно хотел его укусить. — Ещё чуть‑чуть вниз.
До конца тестового блока ошибок не было.
— Кажется, мы победили одну «Весну‑202», — выдохнул Игорь. — Осталось победить остальные.
— Осталось победить тот магнитофон, который у Миши дома на табуретке стоит, — поправил Алексей. — Но это уже будем делать, когда Миша у нас появится.
Евгений усмехнулся.
— Значит, очередного школьника ты тоже планируешь использовать как стенд, — сказал он. — Последовательный ты человек, Морозов.
— Не стенд, — возразил Алексей. — Пользователя. Разница большая.
Он чувствовал странную смесь облегчения и раздражения.
Облегчение — от того, что наконец между железом и треском появилась понятная дорожка: набор правил, которому всё равно, насколько устал мотор.
Раздражение — от того, что каждый шаг к этой дорожке начинался с ручной набивки двадцати четырёх байт. Без права ошибиться. Потому что ошибёшься — придётся всё по кругу.
— Всё равно не понимаю, зачем так извращаться, — заявил вечером Евгений, раскладывая листинги на столе. — На ЕС‑ке лента жёстко привязана к аппаратуре, никто не думает про то, как она там дёргается.
— На ЕС‑ке у каждого лентопротяжного свой инженер, — напомнил Алексей. — А у нас будет один инженер — мы, один магнитофон — какой достанут, и десять пар школьных рук. Если мы заложим туда такую же прихотливость, как у ЕС, — через неделю вся партия будет стоять в кладовке.
— Я бы такое в отчёт не писал, — усмехнулся Евгений. — «Мы специально сделали прибор, совместимый с кривыми руками и убитыми магнитофонами».
— В отчёт — нет, — согласился Алексей. — Но в код — да. Пусть наша фазовая манипуляция за них отрабатывает. Всё равно эта сложность либо будет в железе, либо в голове оператора. Я предпочитаю — в железе.
Игорь, молча возившийся с новой версией платы сопряжения, поднял глаза.
— В железе и в программе, — уточнил он. — Ты нас не забудь, когда будешь ярлыки развешивать.
— Не забуду, — пообещал Алексей. — Вы будете теми самыми людьми, которых через десять лет будут ругать все школьные техники, когда лента запишется с перевёрнутой фазой.
Саша поднял голову от тетради.
— А нам самим не надоест каждый раз эти байты забивать? — спросил он. — Может, всё‑таки выкинуть из ПЗУ пару надписей и впихнуть туда загрузчик?
Алексей помолчал.
В листинге монитора было много приятных вещей: аккуратные сообщения об ошибках, режим просмотра памяти с красивым форматированием, даже одна лишняя проверка, которую он оставил «на будущее», надеясь, что будет время её использовать.
— Пока нельзя, — сказал он наконец. — Мы только что добились, чтобы монитор вообще заработал. Если сейчас полезем туда выдирать байты, Михалыч нас убьёт. Надо сначала показать стабильную работу, тогда уже просить вторую редакцию ПЗУ.
— «Вторую редакцию», — протянул Евгений. — Как будто речь о книжке.
— Так и есть, — серьёзно ответил Алексей. — Сейчас у нас тонкий букварь. Потом будет толстый справочник. И где‑то между ними найдётся место для того, чтобы маленькая программка по чтению ленты жила не только в тетради Саши.
— Я не против, — поспешно сказал Саша. — Я, если что, и в третьей редакции согласен помочь.
Поздно вечером, уже в общаге, Алексей достал из кармана сложенный вдвое листок.
На нём, в две колонки, были карандашом написаны:
`0400: 3E`
`0401: 01`
`0402: D3`
`0403: F0`
`0404: 0E`
…
Он поймал себя на том, что дописывает строки без подсказки. Рука сама выводила шестнадцатеричные пары. Пальцы помнили их, как чужой телефон.
В другой жизни, это было бы изменение в конфигурационном файле: прописал один раз, сохранил, забыл. Здесь, чтобы иметь право в любой момент подцепить магнитофон и вытянуть из треска программу для «Сферы», приходилось каждый раз проделывать одни и те же двадцать четыре шага.
Он посидел немного, слушая приглушённые голоса за стеной, хриплый «Маяк» где‑то в коридоре и редкие шаркающие шаги дежурной.
Потом аккуратно подписал лист:
«Загрузчик. Редакция 0. Ручной».
Свернул, убрал в тетрадь с заголовком «Сфера‑80. Монитор».
И подумал:
«Когда‑нибудь надо сделать так, чтобы Миша из шестого „Б“ не учил шестнадцатеричные коды наизусть. Пускай у него единственной надписью будет: „Включите магнитофон“».
А пока — треск в динамике, фазовая манипуляция и двадцать четыре байта, которыми каждый день приходится оплачивать право иметь внешнюю память.