Когда я узнал, что в Музее компьютерной истории есть работающий компьютер IBM 1401 [1], то заинтересовался, сможет ли он сгенерировать фрактал Мандельброта. Я написал программу фрактала на языке ассемблера и компьютер в течение 12 минут пыхтел, создавая изображение Мандельброта на своём строчном принтере. В процессе этой работы я узнал несколько любопытных фактов о IBM 1401, которые изложу в этой статье.
Мейнфрейм IBM 1401 (слева) из Музея компьютерной истории печатает фрактал Мандельброта на принтере 1403 (справа). Примечание: это строчный принтер, а не матричный.
Компьютер IBM 1401 появился в 1959 году, он стал самым продаваемым компьютером середины 1960-х — всего использовалось более 10 тысяч систем. 1401 сдавался в аренду за 2500 долларов в месяц [2] (примерно 20 000 долларов по нынешним ценам) — низкой цене, позволившей использовать компьютеры большему количеству компаний. Даже бизнес средних размеров мог использовать 1401 для подсчёта зарплат, ведения бухгалтерии, инвентаризации, обработки заказов, выставления счетов и множества других задач. Благодаря низкой стоимости и большой популярности 1401 прозвали «Моделью Т» компьютерной отрасли [3]. Даже для своего времени IBM 1401 имел довольно скромную производительность, особенно по сравнению с мощными бизнес-компьютерами наподобие IBM 7080 (стоимость аренды: 48 000 долларов в месяц) [2]. Однако IBM 1401 получил огромную популярность благодаря своей доступности, надёжности, простоте использования, качественному принтеру и стильному внешнему виду [4].
1401 был одним из первых полностью транзисторных компьютеров. Однако это были даже не кремниевые, а германиевые транзисторы — технология, использовавшаяся до кремния. Транзисторы и другие компоненты монтировались на печатных платах размером примерно в половину игральной карты. Они назывались платами Standard Modular System (SMS), каждая из них обеспечивала функции наподобие триггера или простых логических функций. IBM 1401 мог содержать тысячи карт SMS, это зависело от необходимых возможностей — в базовой системе использовалось примерно 933 карты [5], а в системе, с которой я работал, была 2881 карта SMS. (Подробнее о картах SMS см. в моей предыдущей статье.)
Карты SMS, установленные внутри IBM 1401. Эти карты являются частью системы управления плёночным приводом, усиливающей считываемые с плёнки сигналы.
Карты SMS вставляются в стойки (которые IBM по непонятной причине назвала «гейтами»), вытягиваемые из компьютера, как показано выше. Одной из задач при проектировании 1401 была простота обслуживания — для доступа к гейту достаточно схватиться за рукоятку и он вытягивается из компьютера, позволяя проводить техобслуживание плат и проводников. В нижней части гейта электропроводка соединяет гейт с другими частями компьютера [6]. Всего в машине 24 гейта.
Компьютер IBM 1401 изготовлен из тысяч печатных плат SMS. В этой открытой стойке (называемой «гейтом») видно около 150 карт SMS.
Необычные особенности IBM 1401
Изучать старые компьютеры интересно, потому что они работают совершенно иначе, чем современные. Одними из необычных особенностей IBM 1401 являются использование десятичной арифметики и 6-битные символы, слова произвольной длины, а также дополнительные команды, которые можно было арендовать.
IBM 1401 основан на десятичной, а не двоичной арифметике. Разумеется, внутри используются нули и единицы, но числа хранятся как цифры в формате двоично-десятичного кода (binary coded decimal, BCD). Число 123 хранится как три символа: 1, 2 и 3. При сложении 7 и 8 получаются цифры 1 и 5. Адреса указываются в десятичном виде, поэтому объём накопителя кратен 1000, а не 1024: система с 16 КБ памяти хранит ровно 16 000 символов. Вся арифметика выполняется по основанию 10. Поэтому при делении IBM 1401 аппаратно выполняет деление столбиком по основанию 10.
IBM 1401 не использует байты [9]. Вместо них используется 6-битное хранилище BCD. Каждый символ хранится как 4-битная цифра BCD с двумя дополнительными битами, называемыми «битами зоны», они имеют имена A и B [7]. Эти два дополнительных бита зоны позволяют хранить буквы в верхнем регистре (и несколько специальных символов), а также цифры [8].
Использование байта в качестве единицы операций стало популярным позже, только в IBM System/360; в начале 1960-х компьютеры использовали странные размеры слов, например, слова из 13, 17, 19, 22, 26, 33, 37, 41, 45 и 50 битов [9].
На фото ниже показан модуль памяти на магнитных сердечниках из IBM 1401, содержащий 4 000 символов памяти. Каждый бит хранится в небольшом торообразном ферритовом сердечнике с пропущенными через центр проводниками. Модуль на сердечниках сложнее, чем можно было бы подумать, суммарно он состоит из 16 слоёв (фреймов). Восемь фреймов содержат 6 битов данных плюс биты метки слова (о них будет сказано ниже) и биты чётности. Шесть фреймов содержат данные с щёток считывателей карт и печатающих молоточков для контроля данных и ошибок [10]. Оставшиеся два фрейма используются только для подключения.
Для модуля памяти с магнитными сердечниками на 4000 символов компьютера IBM 1401 требуется огромное количество электропроводки.
Вероятно, наиболее необычной особенностью 1401 является использование слов переменной длины, при этом каждое слово обозначается метками слова. Можно было бы ожидать, что слова переменной длины позволяют использовать слова длиной 8, 16 и 32 бит. Но IBM 1401 допускал использование слов с произвольным количеством символов, вплоть до полного объёма памяти! Например, команда может переместить 47-символьную строку или сложить числа из 11 цифр. (Лично я считаю, что их проще воспринимать полями переменной длины, а не словами переменной длины.)
Метка слова — это бит, задаваемый в участке памяти для обозначения границы слова (т.е. поля) [11]. Команда в IBM 1401 последовательно обрабатывает данные в памяти, пока не дойдёт до метки слова. Важно помнить, что метки слов не являются частью символов, а больше похожи на метаданные, поэтому они сохраняются при считывании и обработке новых записей данных [11].
Основной причиной использования слов с переменной длиной была экономия дорогостоящей памяти на сердечниках, поскольку каждую длину поля можно уместить ровно в требуемый размер.
Ещё один интересный факт о IBM 1401: многие команды нужно было докупать отдельно. Функция «расширенного программирования» позволяла использовать новые команды для перемещения записей, хранения регистров и использования индексных регистров; для этого требовалась установка 105 новых карт SMS и дополнительная ежемесячная оплата в 105 долларов. Даже команда сравнения оплачивалась отдельно. Так как в 1401 используется BCD, для сравнения двух чисел мы не можем просто вычесть одно число из другого, как сделали бы это на большинстве процессоров. В 1401 для операций сравнения используется набор дополнительных схем — примерно 37 карт SMS, стоящих дополнительно 75 долларов в месяц [12]. При аренде функции буфера принтера за 375 долларов в месяц вы получали отдельный модуль накопителя на сердечниках, ещё 267 карт SMS и две новые команды. Команда проверки битов стоила всего 20 долларов в месяц, а дополнительные команды контроля перфорации карт — 25 долларов в месяц. При покупке одной из этих функций инженер IBM устанавливал новые карты и переключал некоторые провода на соединительной плате. Благодаря соединительным платам с монтажом скруткой значительно упрощалось подключение на месте эксплуатации.
Память 1401 можно было расширить до 16 000 накопителя на сердечниках: 4 000 символов в самом 1401 и 12 000 символов в комплекте расширения 1406 размером примерно с посудомоечную машину. Комплект на 12 КБ продавался за 55 100 долларов (примерно 4,60 доллара за символ) или арендовался за 1 575 долларов в месяц. (Понятно, почему эффективное использование памяти было важно.) Вместе с расширенной памятью предоставлялись дополнительные команды для работы с большим интервалом адресов.
Крошечные магнитные сердечники позволяют хранить в памяти IBM 1401 4 000 символов. Проводники проходят через каждый сердечник для считывания и записи памяти. На этом фото показано несколько слоёв сердечников.
От компьютера можно ожидать наличия команды вызова подпроцедуры и стека. Всего этого у 1401 не было. Для вызова подпрограммы на IBM 1401 нужно было выполнить переход к началу подпроцедуры. В конце подпроцедуры адрес возврата записывался в команду перехода, модифицируя код, чтобы к концу подпроцедуры возвращаться к вызывавшему её участку кода [13]. Если вам нужна рекурсия, реализуйте её самостоятельно.
Некоторые продвинутые возможности 1401
По сравнению с современными компьютерами IBM 1401 чрезвычайно слаб и ограничен. Но он не так примитивен, как можно подумать, и обладает некоторыми на удивление продвинутыми возможностями.
Одной из сложных функций IBM 1401 является «редактирование» (Editing) — некий аналог printf
, реализованный аппаратно. Команда Edit получает число, например 00123456789
, и строку формата. Компьютер удаляет нули в начале и вставляет нужные запятые, выводя что-то типа 1,234,567.89. Благодаря дополнительной функции расширенного редактирования (всего на 20 долларов в месяц дороже) можно было получить плавающие символы * (******1,234.56) или плавающий символ доллара ($1,234.56), удобные для печати чеков. Не забывайте, что это форматирование выполнялось не подпроцедурой; оно реализовано полностью аппаратно, а форматирование применялось отдельными транзисторами.
Ещё одна продвинутая возможность IBM 1401 — расширенный контроль ошибок. При наличии тысяч компонентов на тысячах плат может возникать множество неполадок. 1401 отслеживает неисправности, чтобы они не приводили к катастрофам (например, к печати зарплатных чеков на миллион долларов). Во-первых, память, внутренние пути прохождения данных, декодирование команд и преобразование BCD были защищены проверками чётности и корректности. В АЛУ использовалось qui-binary addition для обнаружения арифметических ошибок. Считыватель карт считывал каждую карту дважды и сравнивал результаты [10]. В каждой строке 1401 проверял работу принтера. (Для проверки считывания, перфорации и печати использовались описанные ранее дополнительные платы памяти на сердечниках.) В результате этого 1401 оказалась очень надёжной машиной.
Поскольку IBM 1401 имел переменную длину слов, он мог выполнять арифметические вычисления произвольной точности. Например, он может умножать или делить тысячеразрядные числа одной командой. Попробуйте-ка повторить такое на процессоре Intel! (Я пробовал умножать 1000-разрядные числа на 1401; операция заняла меньше минуты.) Аппаратное умножение/деление — ещё одна дополнительно оплачиваемая функция; чтобы уложиться в требования стоимости 1401, IBM сделала её дополнительной, по довольно умеренной цене в 325 долларов. Однако за эту цену покупатель получал довольно много оборудования — примерно 246 дополнительных карт SMS, установленных в два гейта [14]. И помните, что это десятичное умножение и деление, которые гораздо сложнее реализовать аппаратно, чем двоичное.
Компьютер 1401, с которым я работал, является моделью Sterling, поддерживающей арифметические вычисления с фунтами/шиллингами/пенсами. Довольно удивительно видеть аппаратную реализацию таких вычислений. (Вплоть до 1971 британская валюта выражалась в фунтах, шиллингах и пенсах. 12 пенсов — это шиллинг, 20 шиллингов — это фунт. Как знали многие туристы, это усложняет даже сложение.) Благодаря аппаратной поддержке валютной арифметики 1401 упрощал и ускорял код [15].
Переплетение смонтированных скруткой проводов на задней части гейта соединяет платы компьютера IBM 1401. Соединения выполняли автоматизированные станки, однако при необходимости её могли модифицировать инженеры по монтажу.
Реализация Мандельброта на языке ассемблера 1401
Создание кода множества Мандельброта на 1401 — довольно сложный процесс, поскольку я писал его на языке ассемблера (под названием Autocoder). Сложнее всего было привыкнуть к меткам слов. Ещё одной проблемой было отсутствие у 1401 арифметики с плавающей запятой, поэтому я использовал фиксированную запятую: каждое число я умножал на 10000, чтобы можно было представить как целое число десятичную дробь с четырьмя знаками после запятой. 1401 проектировался для применения в бизнесе, а не в науке, поэтому он не очень хорошо подходит для генерации фракталов. Однако мне всё равно удалось это сделать.
1401 необязательно программировать на языке ассемблера, он поддерживает такие языки, как Fortran и COBOL, но я хотел полностью погрузиться в опыт работы с 1401. Всё же меня поражает то, что можно запустить компилятор COBOL на машине всего с 4 000 символов памяти. Компилятор Fortran требовал машины с 8 000 ячейками; чтобы разместить компилятор, он выполнял его за 63 этапа.
Код фрактала Мандельброта на языке ассемблера представлен ниже. В первой части кода с помощью DCW
задаются константы и переменные. Далее следуют три вложенных цикла для обхода каждой строки и столбца и итерации для каждого пикселя. Примеры команд из кода: M
(multiply, умножение), A
(add, сложение), S
(subtract, вычитание) и C
(compare, сравнение). Комментарии начинаются со звёздочек.
JOB MANDELBROT *GENERATES A MANDELBROT SET ON THE 1401 *KEN SHIRRIFF HTTP://RIGHTO.COM CTL 6641 ORG 087 X1 DCW 001 *INDEX 1, COL COUNTER TO STORE PIXEL ON LINE ORG 333 * *VALUES ARE FIXED POINT, I.E. SCALED BY 10000 *Y RANGE (-1, 1). 60 LINES YIELDS INC OF 2/60*10000 * YINC DCW 333 XINC DCW 220 *STEP X BY .0220 * *Y START IS -1, MOVED TO -333*30 FOR SYMMETRY * Y0 DCW -09990 *PIXEL Y COORDINATE * *X START IS -2.5 * X0INIT DCW -22000 *LEFT HAND X COORDINATE X0 DCW 00000 *PIXEL X COORDINATE ONE DCW 001 ZR DCW 00000 *REAL PART OF Z ZI DCW 00000 *IMAGINARY PART OF Z ZR2 DCW 00000000000 *ZR^2 ZI2 DCW 00000000000 *ZI^2 ZRZI DCW 00000000000 *2 *ZR *ZI ZMAG DCW 00000000000 *MAGNITUDE OF Z: ZR^2 + ZI^2 TOOBIG DCW 00400000000 *4 (SCALED BY 10000 TWICE) I DCW 00 *ITERATION LOOP COUNTER ROW DCW 01 ROWS DCW 60 COLS DCW 132 MAX DCW 24 *MAXIMUM NUMBER OF ITERATIONS * *ROW LOOP *X1 = 1 (COLUMN INDEX) *X0 = -2.2 (X COORDINATE) * START LCA ONE, X1 *ROW LOOP: INIT COL COUNT LCA X0INIT, X0 *X0 = X0INIT CS 332 *CLEAR PRINT LINE CS *CHAIN INSTRUCTION * *COLUMN LOOP * COLLP LCA @00@, I *I = 0 MCW X0, ZR *ZR = X0 MCW Y0, ZI *ZI = Y0 * *INNER LOOP: *ZR2 = ZR^2 *ZI2 = ZI^2 *IF ZR2+ZI2 > 4: BREAK *ZI = 2*ZR*ZI + Y0 *ZR = ZR2 - ZI2 + X0 * INLP MCW ZR, ZR2-6 *ZR2 = ZR M ZR, ZR2 *ZR2 *= ZR MCW ZI, ZI2-6 *ZI2 = ZI M ZI, ZI2 *ZI2 *= ZI MCW ZR2, ZMAG *ZMAG = ZR^2 A ZI2, ZMAG *ZMAG += ZI^2 C TOOBIG, ZMAG *IF ZMAZ > 4: BREAK BH BREAK MCW ZI, ZRZI-6 *ZRZI = ZI M ZR, ZRZI *ZRZI = ZI*ZR A ZRZI, ZRZI *ZRZI = 2*ZI*ZR MCW ZRZI-4, ZI *ZI = ZRZI (/10000) MZ ZRZI, ZI *TRANSFER SIGN A Y0, ZI *ZI += Y0 S ZI2, ZR2 *ZR2 -= ZI2 MCW ZR2-4, ZR *ZR = ZR2 (/10000) MZ ZR2, ZR *TRANSFER SIGN A X0, ZR *ZR += X0 * *IF I++ != MAX: GOTO INLP * A ONE, I *I++ C MAX, I *IF I != MAX THEN LOOP BU INLP MCW @X@, 200&X1 *STORE AN X INTO THE PRINT LINE BREAK C X1, COLS *COL LOOP CONDITION A ONE, X1 A XINC, X0 *X0 += 0.0227 BU COLLP W *WRITE LINE * *Y0 += YINC *IF ROW++ != ROWS: GOTO ROWLP * C ROW, ROWS *ROW LOOP CONDITION A ONE, ROW A YINC, Y0 *Y0 += 0.0333 BU START FINIS H FINIS HALT LOOP END START
Прежде чем приступать к запуску на реальном компьютере, я скомпилировал и запустил код при помощи компилятора и симулятора ROPE [16]. Карты перфорировались автоматически при помощи перфоратора IBM 029, управляемого PC через несколько контролируемых по USB реле. На фото ниже показан перфоратор в действии. Каждая пустая карта выпадает из подающего устройства в правом верхнем углу. Карта перфорируется, перемещаясь влево. Затем перфорированные карты переворачиваются и складываются стопкой в левой верхней области (на этом фото она пуста).
Перфоратор IBM 029 подготавливает стопку перфокарт, генерирующих фрактал Мандельброта.
Получившаяся стопка перфокарт и результат выполнения программы показаны ниже. Программа уместилась на 16 перфокартах, однако формат карт немного необычен. Машинный код программы Мандельброта перфорируется в левой половине каждой карты, например, с кодом M384417A395417
. В 1401 любопытно то, что машинный код почти читаем для человека. M384417
означает «переместить (Move) поле из адреса 384 в адрес 417». A395417
означает «прибавить (Add) число по адресу 395 к числу по адресу 417». Текст на картах — это сам исполняемый машинный код, а не ассемблерный код. Так как устройство машины основано на символах, а не двоичных значениях, нет разницы между символами «428» и адресом.
Стопка перфокарт для генерации фрактала Мандельброта на компьютере IBM 1401, а также результат работы программы. Белая полоса в правой части фрактала возникла из-за неисправного молоточка принтера.
Взглянув на правую половину карт, можно увидеть нечто совершенно иное — текст типа L033540,515522,5259534
. У компьютера нет операционной системы, поэтому, как это ни невероятно, каждая карта содержит код для копирования своего содержимого в нужное место памяти (команда L
), добавления меток слов (команда ,
) и загрузки следующей карты. Другими словами, правая половина каждой карты — это программа, выполняемая карта за картой, она загружает в память программу из левой половины стопки карт, которая исполняется после загрузки последней карты [17].
Для запуска программы нужно нажать кнопку включения питания «Power On» на панели IBM 1401. Несколько мгновений пощёлкают реле, включая питание системы, после чего компьютер готов к работе (в отличие от современных компьютеров, загружающихся так долго). Пользователь помещает карты в считыватель карт и нажимает кнопку «Load». Карты пролетают через считыватель с впечатляющей скоростью 800 карт в минуту, поэтому программа Мандельброта загружается чуть больше секунды. При выполнении программы панель компьютера мерцает, и каждые несколько секунд строчный принтер выбивает молоточком ещё одну строку фрактала. Спустя 12 минут выполнения фрактал готов. (Довольно любопытно то, что самое первое изображение множества Мандельброта было напечатано на строчном принтере в 1978 году [18].
Панель мейнфрейма IBM 1401. В верхней части показан поток данных через компьютер, из накопителя в регистры B и A и в логическое устройство. Каждое 6-битное значение отображается в виде 1248ABC, где A и B — биты зон, а C — контрольный бит (чётности). Справа в поле «OP» отображается исполняемая операция. Ниже расположены ручки для ручного доступа к памяти. Находящаяся слева кнопка «Start Reset» сбрасывает ошибку, например, сбои считывания карт, с которыми я сталкивался. Внизу расположены важные кнопки включения и отключения компьютера. Рукоятка Emergency Off мгновенно отключает питание.
Заключение
Создание программы Мандельброта для IBM 1401 было интересным проектом. Когда работаешь с десятичными числами и отслеживаешь метки слов, думаешь немного по-другому. Но должен сказать, что сравнение производительности с современными машинами (не говоря уже про объём памяти) заставляет уважать закон Мура.
Музей компьютерной истории в Маунтин-Вью проводит демонстрации IBM 1401 по средам и субботам. Потрясающе, что коллективу реставраторов удалось заставить работать этот фрагмент истории, поэтому если будете поблизости, на него определённо стоит взглянуть. Расписание можно найти здесь. Скажите проводящим демонстрацию ребятам, что вы услышали о компьютере от меня, и возможно они запустят мою программу вычисления простых чисел или программу вычисления пи. Вероятно, вы не захотите ждать, пока выполняется программа Мандельброта.
Благодарю Музей компьютерной истории и сотрудников коллектива реставраторов 1401 — Роберта Гарнера, Эда Телена, Вана Снайдера и особенно Стэна Пэддока. На сайте коллектива 1401 (ibm-1401.info) есть куча интересной информации о 1401 и его восстановлении.
Примечания и ссылки
[1] В Музее компьютерной истории есть два работающих 1401: «German 1401» и «Connecticut 1401» (названных по месту, откуда они были доставлены). Я работал с German 1401, потому что на Connecticut 1401 в то время проводили техобслуживание считывателя карт.
[2] Хотя во многих местах упоминается ежемесячная стоимость аренды 2500 долларов, цена за полную систему с несколькими плёночными приводами могла доходить до 10000 долларов. Цена сильно зависела от модели 1401, количества памяти и периферии (плёночных приводов, считывателя карт, принтера, дискового привода). Минимальная конфигурация (1401 Model A, считыватель карт 1402 и принтер 1403) сдавалась за 2 475 долларов в месяц (или продавалась за 125 600 долларов — сейчас почти 1 миллион с учётом инфляции). «Рекомендованная» конфигурация с 8 КБ памяти, дополнительными функциями процессора и ещё одним принтером сдавалась за 4 610 долларов в месяц. Плёночные приводы повышали цену на 980 долларов в месяц за интерфейс и по 1100 долларов в месяц за каждый плёночный привод 729 IV. Модуль расширения памяти на 4000 символов стоил 575 долларов в месяц.
Подробную информацию о компьютерах 1961 года, в том числе арендные цены, можно найти в интересном обзоре компьютеров 1961 года, тысячестраничном A Third Survey of Domestic Electronic Digital Computing Systems, Report No. 1115, March 1961 (Страница о 1401). Базовая арендная цена IBM указывалась с учётом одной 8-часовой смены (176 часов в месяц). Компьютеры имели счётчик времени и с пользователей взымали дополнительную плату, если они превышали выделенное им время. Клиенты часто платили повышенную цену аренды, чтобы компьютеры могли работать в режиме 24/7.
[3] Комментарий о том, что 1401 стал «Моделью Т» компьютерной отрасли, взят из статьи IBM System/360 вице-президента IBM Боба Эванса. Любопытный факт из этой статьи: IBM 1620 сдавался в аренду за 1600 долларов в месяц, благодаря чему стал первой системой IBM, арендуемой за цену меньше, чем номер модели.
[4] IBM 1401 имел довольно уникальный стиль, особенно по сравнению с предыдущими компьютерами IBM (например, 650 или 704), имевшими очень утилитарный, промышленный внешний вид. Изящный модернистский стиль 1401 не был выбран случайно, а стал результатом тщательного проектирования промышленного дизайна. В книге The Interface: IBM and the Transformation of Corporate Design представлено очень интересное обсуждение усилий, вложенных IBM в промышленный дизайн. Важные идеи дизайна придумал Эдгар Кауфманн, а дальнейшее развитие они получили благодаря Элиоту Нойесу.
[5] Количество карт SMS в IBM 1401 зависело от модели, установленных опций, инженерных изменений (например, ремонта) и объёма используемой памяти. У меня получилось число 1206: я проанализировал диаграмму подключения SMS и насчитал 933 базовых карт, 267 базовых карт Sterling, 6 карт питания и 11 карт для поддержки памяти. Данная машина является моделью Sterling, то есть она чуть сложнее обычной модели.
[6] IBM 1401 имел 32 «потенциальных» гейта: 16 спереди и ещё 16 сзади, но электронные схемы содержались только в 24 гейтах. Две потенциальные панели в левом верхнем углу заняты откидывающейся панелью управления, за которой расположена память на сердечниках. За четырьмя панелями располагаются источники питания (однако, как ни странно, бОльшая часть источников питания находится внутри считывателя карт). Ещё два участка заняты на удивление толстыми кабелями, подключающими 1401 к периферии. Остаётся 24 раскрывающихся гейтов, некоторые из которых в зависимости от установленных опций могли не использоваться.
[7] Биты зон тесно связаны с перфорациями зон в перфокартах IBM. Верхняя строка перфокарты — это зона 12 (Y), строка под ней — зона 11 (X). Число — это одно отверстие, перфорированное в соответствующей строке карты (строки с 0 по 9). Символу обычно соответствуют два пробитых отверстия: с 1 до 9 для значения BCD и отверстие зоны для бита зоны. Перфорация зоны — это зона карты 11 для установленного бита B, зона карты 12 для битов зон A и B или строка карты 0 для бита зоны A.
Однако существуют некоторые сложности, запутывающие этот паттерн. Во-первых, для символов за пределами интервала 0-9 используется две перфорации цифр: 8 и цифра для нижних трёх битов. (например, символ "#" хранится как биты 8, 2 и 1, поэтому перфорируется как 8 и 3.) Во-вторых, поскольку строка карты 0 используется и для цифры 0, и как перфорация зоны, существует конфликт, и значение 0 при определённых условиях трактуется как 10 (и перфорируется как 8 и 2). Поскольку пустой символ не имеет перфорации и хранится внутри как 0, цифра 0 хранится как 10. Различные системы IBM обрабатывают эти пограничные случаи по-разному. Для обеспечения необходимой совместимости для 1401 существовали настраиваемые функции.
[8] Кроме букв, биты зон использовались и для других вещей. Бит зоны добавляется к цифре младшего порядка числа, обозначая знак числа. Адреса памяти обозначаются тремя цифрами, что обеспечивает доступ к 1000 ячейкам; благодаря использованию битов зон адрес из трёх цифр может обеспечивать доступ к 16000 ячеек. Также биты зон отслеживают переполнение в арифметических операциях.
[9] Изначально байтом называли группу битов, используемую для кодирования символа, даже если он не состоял из 8 битов (см. Planning a Computer System: Project Stretch, стр. 40). Вот некоторые примеры необычных длин слов:
RCA 601 поддерживал 6-, 8-, 12-, 16-битные или слова переменной длины.
В SPEC использовались 13-битные слова.
В Hughes Airborne Computer использовались 17-битные слова, в Hughes D Pat — 19-битные, а в Hughes M 252 — 20-битные слова.
В RW 300 использовались 18-битные слова, а в RW 400 — 26-битные.
В Packard Cell 250 использовались 22-битные слова.
В UNIVAC 1101 использовались 24-битные слова.
В ALWAC II использовались 32-битные плюс знак (33 бита).
В COMPAC использовались 37-битные слова (36 + знак).
В AN/MJQ использовались 41-битные слова.
В SEAC использовались 45-битные (44 плюс знак).
В AN/FSQ 31 использовались 48-битные слова.
В ORACLE использовались 50-битные слова.
В компьютере Университета Райса использовались 54-битные слова.
Подробнее об этих компьютерах можно узнать в A Third Survey of Domestic Electronic Digital Computing Systems.
[10] Считыватель карт считывает каждую карту дважды и проверяет, чтобы количество отверстий было одинаковым при обоих считываниях. Если количество не совпадает, то считыватель обнаруживает ошибку и прекращает работу. Каждая карта читается «вбок», по строке из 80 позиций за раз. В двух битах хранится состояние каждого столбца. Один бит устанавливается, если есть хотя бы одно отверстие. Другой бит переключается с каждым отверстием. (То есть, строго говоря, это не подсчёт, что упрощает логику.) При втором считывании процесс обратный, то есть при правильном считывании оба бита возвращаются в состояние 0.
Так как следующая карта уже начинает считываться ещё при проверке первой карты, требуется два набора битов, один для первой и другой для второй карты. Поэтому для проверки считывания карт используется четыре платы по 80 бит каждая.
Каждая из 240 щёток считывателя карт имеет отдельный провод, проходящий через определённый сердечник в памяти 1401. Аналогично, каждый из 132 печатающих молоточков принтера соединён напрямую с отдельным сердечником. Поэтому между IBM 1401, считывателем карт и принтером проложены толстые кабели, содержащие сотни проводов.
[11] Хочу подробнее рассказать о метках слов. Очевидно, что в IBM 1401 биты хранятся от старшего к младшему, поскольку именно так числа перфорируются на картах. Поскольку арифметические операции должны начинаться с самого младшего порядка, они начинаются с «конца» числа и проходят в обратном порядке в памяти до самого старшего порядка. Поэтому команде передаётся адрес конца поля и она движется к меньшим адресам, пока не дойдёт до метки слова, то есть начала поля. Если вы программируете на C, то вам это покажется обратным порядком — обычно мы начинаем с начала сроки и движемся вперёд, пока не доберёмся до конца.
Кроме того, метки слов используются для обозначения начала каждой команды. Команды могут иметь длину от 1 до 8 символов, а наличие метки слова контролирует длину. Начальная загрузка меток слов для первых команд, загружаемых в компьютер, требует определённых хитростей.
[12] Логика сравнений сложнее, чем можно было бы ожидать. К удивлению, порядок сравнения не соответствует двоичному порядку символов. Кроме того, сравнения не реализованы при помощи вычитания (как в большинстве процессоров). Вместо этого логика сначала определяет, являются ли символы особыми — особые символы расположены перед обычными (с некоторыми исключениями: например, -
находится между I
и J
). Поэтому большое количество логики AND-OR фактически выполняет сравнение грубым перебором, рассматривая различные паттерны битов. Результаты сравнения можно увидеть на панели управления в поле Logic. Покупаемая дополнительно логика сравнений показана в Intermediate Level Diagrams (ILD), стр. 37.
[13] В прошлом был распространён самомодифицирующийся код, то есть такой, в котором программа изменяет собственные команды. В руководстве по программированию IBM 1401 1961 года есть целая глава (6), посвящённая этому. В ней говорится, «как можно оперировать командами в памяти, как если бы они были данными». Обработкой кода как данных занимались не только программисты на Lisp. В книге эта способность программы к самомодификации называется «бесспорно, самой важной функцией концепции хранимой программы». Кроме возвратов из подпроцедур, программисты IBM 1401 использовали самомодифицирующийся код для индексирования, вычисления адресов и сложного условного ветвления. На современных машинах самомодифицирующийся код встречается редко, поскольку его сложнее отлаживать и он запутывает конвейер выполнения команд.
[14] Подробности о внутреннем устройстве операций умножения и деления см. в руководстве по опциональным возможностям. Эта схема содержала в себе сложные оптимизации. Например, для ускорения многократного сложения она при необходимости прибавляла удвоенное значение. Однако для удвоения десятичного значения требуется довольно сложная схема (в отличие от двоичного удвоения, выполняемого тривиальным образом). Кроме того, присутствует контроль ошибок, чтобы удвоение происходило без проблем.
[15] Электрическая схема модели Sterling для поддержки вычислений с £sd ещё более сложна, потому что шиллинги и пенсы хранятся в сжатом виде. Очевидным решением было бы двухзначное поле для пенсов (от 0 до 11) и двухзначное поле для шиллингов (от 0 до 19). Но для экономии драгоценной памяти и места на накопителе в стандарте BSI и в несовместимом с ним стандарте IBM используются однозначные поля и особые символы. Ручкой на панели управления можно переключать используемый стандарт. Оборудование Sterling должно выполнять арифметические вычисления с этим сжатым форматом, а также обрабатывать недесятичные основания шиллингов и пенсов.
Этим переключателем на панели управления компьютера IBM 1401 выбирается режим хранения пенсов и шиллингов.
[16] Если вы хотите написать программу для компьютера 1401, инструкции по использованию симулятора ROPE можно найти здесь. Это простая IDE, позволяющая редактировать ассемблерный код (называемый Autocoder), собирать его, а затем выполнять в симуляторе. Если хотите понять, как программировать 1401, изучите A guide to IBM 1401 Programming и Programming the 1401. 1401 Reference Manual тоже полезен для понимания того, что делают команды.
[17] Каждая карта также содержит в последних столбцах четырёхзначный порядковый номер.
Он позволяет пересортировать карты, если стопку уронили и порядок программы перепутался.
[18] Первое изображение множества Мандельброта появилось в статье 1978 года Брукса и Мателски, ещё до статьи Мандельброта. (Благодарю Роберта Гарнера за то, что сообщил мне об этом.)
Ведутся споры о том, кто «на самом деле» открыл множество Мандельброта. Обсуждение см. в статье
Who Discovered the Mandelbrot Set? в Scientific American.
Автор: PatientZero