Мы в нашем Музее компьютерной истории недавно приобрели набор перфокарт для компьютерной музыкальной программы 50-летней давности. Тогда у большинства компьютеров не было звуковых карт, но творческие программисты нашли способы выдавать музыку при помощи линейных принтеров. Мы немного волновались, что эта программа может повредить принтеру, но всё же рискнули запустить её на древнем мейнфрейме IBM 1401. Как вы могли предполагать, музыка в исполнении линейного принтера звучит ужасно — но мелодию можно разобрать, а принтер не пострадал.
Бизнес-компьютер IBM 1401 представили в 1959 году, и он стал самым продаваемым компьютером середины 1960-х – было поставлено более 10 000 таких систем. Ключевым конкурентным преимуществом IBM 1401 был высокоскоростной линейный принтер IBM 1403. Быстро вращавшаяся цепь с символами позволяла принтеру печатать по 10 строк в секунду с отличным качеством – считается, что это было наилучшее качество до появления лазерных принтеров в 1970-х.
Печатная цепь принтера 1401. На ней есть 48 разных символов, которые повторяются по 5 раз.
Линейные принтеры очень шумели, но программисты вскоре выяснили, что при печати определённых строк символов из шума можно извлекать определённые частоты. Было возможно сыграть ноту, распечатывая нужные строки. В районе 1970-го года специалист по информатике Рон Мак закодировал несколько песенок на перфокартах используя имевшуюся музыкальную программу. Недавно он наткнулся на свои старые программы и дал нам возможность испробовать их.
Как работает линейный принтер
Для печати символов принтер использует цепочку из звеньев с символами, вращающуюся с высокой скоростью напротив бумаги, а между бумагой и цепью находится чернильная лента. Принтер выдаёт строки по 132 колонки – то есть, у каждой колонки есть свой молоточек и электромагнит. В нужный момент, когда мимо молоточка движется нужный символ, электромагнит прижимает молоточек к бумаге, и бумага вместе с лентой ударяют по звену, распечатывая символ.
Механизм печати линейного принтера IBM 1401 (из инструкции)
Чтобы этот процесс работал, принтеру требуется тщательно рассчитать время операций. Цепь вращается со скоростью 2,3 м/с, и каждые 11,1 мкс очередное звено оказывается напротив молоточка. У управляющей схемы едва хватает времени, чтобы считать местоположение этого символа из основной памяти, сравнить его с символом, расположенным под молоточком, и ударить молоточком в случае совпадения. За 132 временных интервалов у каждого молоточка есть возможность распечатать один символ; это называется «сканом». Поскольку в наборе есть 48 символов (без прописных букв), чтобы распечатать все символы в любом столбце, нужно повторить этот процесс 48 раз. За каждый скан цепь сдвигается всего на одну ширину символа.
Набор молоточков принтера IBM 1403. Внизу видны точки ударов 132 молоточков (по одному на столбец). Вверху видны катушки и провода 33-х из 132 молоточков.
Внизу на фото показан один молоточек. Слева вверху – электромагнитная катушка и провода. Этот молоточек нам пришлось заменить после того, как катушка перегрелась и задымилась – на фото видно её почерневший участок (это случилось давно, и не связано с музыкой).
Генерация музыки
Поняв, как работает принтер, у молоточка которого есть возможность срабатывать каждые 11,1 мкс, легче будет разобраться в стратегии получения музыки. Печатая тщательно отобранный текст, можно контролировать время срабатывания молоточков. Если молоточки будут срабатывать через определённые промежутки, получится создавать нужные частоты. К примеру, ноту ля (440 гц) можно получить, печатая строку текста так, чтобы молоточки срабатывали каждую 1/440 долю секунды. Этого можно достичь, печатая 1 в 1-й колонке (первый молоточек), потом # в 14-й колонке на следующем скане, запятую в 30-й колонке, и так далее. Далее приведена вся строка, которую нужно распечатать для создания ноты. Вас может удивить, что имея всего 48 позиций, набор символов включает такие странные вхождения, как ⌑ и ‡.
1 ⌑Y C# 0 Q 3, ‡F R T 4 - , I U $7 M V . * 9N ⌑ ZE @ P3
Ниже на диаграмме показано временное распределение молоточков, равномерная частота 440 Гц, выдаваемая приведённой строкой символов. По оси x отложено время, красными полосками отмечен каждый распечатываемый символ. Красные полоски распределены равномерно, на расстоянии в 1/440 секунды, что выдаёт ноту в 440 Гц. Каждая полоска отмечена связанным с ней символом и столбцом на странице. Отметьте, что символы напечатаны не в том порядке, в каком они появляются в строке. Между расположением символов в строке и их временной последовательностью нет простого взаимоотношения. Показано несколько серых линий, где должен был бы сработать молоточек, но отсутствует символ. В этот момент происходит синхронизация сети, поэтому она не может печатать.
Диаграмма временного распределения для ноты ля.
Напечатав другую строчку, можно сгенерировать другую ноту. Ниже – нота си, 987 Гц (выше более чем на октаву). Как и следовало ожидать, для ноты с большей частотой требуется больше символов:
1 @EQ4S J 8. N D ‡ S H 7 AM Y#2 G- KV . 0 D Q S J 7& N D ‡/4 H AMX0 2 Q G J W. 0 DP‡ S 7&AM ‡/4G * MX0 D 3
Диаграмма временного распределения для ноты си.
Ниже приведена строчка для ноты до-диез (138 Гц). Сначала мне было непонятно, почему для этой ноты требуется печать строки, где все символы собраны в кучу, а не разбросаны, как у других нот. Оказывается, что 138 Гц как раз совпадает с молоточками, идущими подряд. И хотя символы стоят рядом друг с другом, они равномерно распределяются по времени.
16#UZKP*E&38
Диаграмма временного распределения для ноты до-диез.
В чём риск цепной музыки
Нас беспокоило, что эта музыкальная программа может повредить наш принтер. Есть множество историй о том, как люди ломали принтеры, распечатывая строку, которая заставляет срабатывать все молоточки одновременно. Думаю, что это в основном городские легенды (молоточки на 1403 срабатывают по очереди). Тем не менее, мы беспокоились по поводу того, что цепная музыка может перегрузить цепь принтера и она порвётся. На фото ниже показана порванная во время обычного использования цепь; видно порванные провода и отдельные звенья.
Цепь для принтера изготавливали, заплетая тонкий провод в ленту и присоединяя к нему блоки с буквами. До недавнего времени эти цепи встречались редко, и их невозможно было заменить; если рвался провод, починить его было нельзя. Однако в музее Techworks! из Бингемтона недавно придумали способ восстановления печатных цепей. Поэтому наш гуру по IBM 1401, Фрэнк Кинг, нехотя одобрил использование восстановленной цепи для воспроизведения музыки. К счастью, цепь прекрасно пережила генерацию музыки. Изучив музыкальную программу, я пришёл к выводу, что она гораздо меньше напрягает цепь, чем обычная печать, если, конечно, в ней не возникнет особенно неудачный резонанс.
Печатная цепь (вверх ногами) с близкого расстояния
Программа
Исходный код для программы давно канул в Лету, поэтому я дизассемблировал машинные коды с карт, чтобы понять, как она работает (листинг привожу отдельно). Сначала она считывает «частотные карты», определяющие, какую строку для какой ноты печатать. Она создаёт в памяти массив строк для печати, вместе с таблицей с названиями нот и адресами строк для печати. Потом программа считывает ноты песен, по одной ноте на карту (на фото видно, что для некоторых песен приходится использовать множество карточек). Для каждой ноты программа ищет соответствующую строку для печати в таблице. Она печатает строку нужное количество раз, в зависимости от длительности ноты. Дальше отрабатывает цикл тишины, от 200 до 2000 раз.
Перфокарты с машинным кодом музыкальной программы. Содержимое каждой карты зачем-то пропечатано на ней дважды.
Машинный код 1401 сильно отличается от современных компьютеров. Одно из отличий состоит в том, что раньше самомодифицирующийся код использовался часто, а сегодня такие практики порицают. К примеру, таблица строк для печати создаётся через изменение инструкций загрузки, где меняется поле адреса. Даже возврат из подпрограмм используют самомодифицирующийся код, помещая адрес возврата в инструкцию jmp в конце подпрограммы. Для обработки ноты программа на лету генерирует последовательность из трёх инструкций для загрузки строки, перехода к коду печати, и затем перехода обратно в основной цикл. Самомодифицирующийся код усложнял мне задачу понимания программы, поскольку дизассемблированный код не совпадает с тем, который реально запускался.
За карточками с программой идут частотные карточки, определяющие строки для каждой ноты. Код поддерживает до 20 разных нот, поэтому частотные карточки подбирались для каждой песни отдельно. Каждая строка в 132 символа разбивается на две карты, первая из которых определяет правую часть строки. На каждой карте справа в углу напечатаны название ноты и частота.
Частотные карточки
Итоговый набор карт создаёт мелодию, и каждой ноте (или промежутку) соответствует своя карта. На каждой карте напечатана нота и длительность. Длинная мелодия может задействовать сотни карт. Сохранить на картах новую мелодию легко – нужно просто пробивать ноты на картах. Ноты обозначены в американской системе нотации, где за названием ноты следует номер октавы. К примеру, C4 – это среднее до. Поскольку лишь на некоторых печатных цепях есть символ #, диезы обозначаются буквой S, то есть CS вместо C#.
Фото карты с мелодией «Серебряные колокольчики» крупным планом.
Заключение
Мы успешно проиграли музыку на принтере IBM 1403, запустив программы, которые никто не запускал уже почти 50 лет. Хотя качество музыки оказалось не особенно высоким, мы обрадовались тому, что принтер не саморазрушился. В последний раз Рон Мак запускал эти программы в 1970; по ссылочке вы найдёте некоторые мелодии. На видео ниже показан отрывок из «Марсельезы»; в этом видео можно наблюдать за печатью каждой строки.
Музей компьютерной истории в Маунтин-Вью демонстрирует IBM 1401 в работе по средам и субботам, поэтому если вы окажетесь поблизости, рекомендую вам посетить нашу экспозицию.
Автор: Вячеслав Голованов