Как выглядела разработка… ну скажем в 80-х годах прошлого века

Уже много раз в исторических постах на Хабре я видел вопросы такого плана: «А как вообще выглядела разработка тогда, когда машины были большими»? Как был построен процесс, как устроена сборка, существовал ли отладчик (заменить на любой другой инструмент), как происходило взаимодействие в команде, и т.п.

Попробую рассказать об этом на своем примере.

Итак, 80-е годы прошлого века.

xbpl9qdemj4rdjr1vkhru648pkw.jpeg


На фото — заставка с терминала IBM 3270, система VM/370.

Как выглядела разработка тогда, ну скажем, скажем в 1989 году. Для определенности, опишу ту среду, в которой работал сам, это была VM/SP (известная также как СВМ/ПДО), версии с 3 по 6.

У этой ОС долгая история, она носила другие названия, например CP-40, CP-67, VM/370, и начиналось все еще с моделей S/360, для которых эта ОС была изначально разработана, как первая система не для пакетной работы, а с разделением времени. Официально считается, что VM существует с 1972 года, то есть уже 48 лет. Последний релиз был кажется в 2018 под названием z/VM.

Первой же реально работавшей ОС с виртуализацией всего железа пожалуй была CP-40, это 1964–1967 годы.

Теперь немного про саму ОС. Собственно VM/SP — это система, основа которой виртуальные машины. Т.е., для ОС пользовательские задачи выглядят как виртуальные машины S/370, где могут выполняться любые ОС, предназначенные для этой системы. В том числе — и сама VM/SP. А для пользовательских задач VM/SP выглядит как предоставленная им реальная машина, на которой можно работать так, как будто это просто S/370, с ограниченными ресурсами.

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

Иными словами, роль API для взаимодействия между ОС и программой тут играет набор команд S/370. И никакого другого API, похожего скажем на POSIX, не существует. Ну или, если быть точным, то была такая команда DIAG, которая на реальной машине выполняла функции диагностики оборудования, а на виртуальной — позволяла выполнять команды ОС, например. Но у нее было всего-то 6 функций, т.е. на API уровня POSIX, или Win32 это никак не тянет все равно.

ОС состоит из так называемой управляющей программы, или CP, загрузчика, драйверов устройств. Конфигурация устройств описывается при генерации системы в виде макрокоманд ассемблера. Это типично для большинства ОС на этой архитектуре, поскольку с точки зрения процессора все периферийные устройства одинаковы, и отличаются только запускаемыми канальными программами. То есть, мы (системный программист) должны сообщить ОС, какие устройства ей доступны, и под какими адресами они подключены.

CP выполняет загрузку и запускает виртуальные машины, какие-то автоматически, например машину оператора, какие-то — когда пользователь осуществляет вход в систему. Прикладное же ПО выполняется уже в виртуальных машинах, в той или иной гостевой ОС.

Работа в VM/SP


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

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

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

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

Виртуальные машины


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

Для машины естественно выделяется некоторый объем памяти. Значение по умолчанию задается в оглавлении, как минимум и максимум. С определенного момента стало можно указывать архитектуру, которую должна поддерживать машина (от этого, в частности, зависит максимально адресуемый объем памяти). S/370 имела 32 битовые адреса, из которых только 24 бита использовались, далее появилась архитектура XA с поддержкой 31 битовых адресов, а затем и ESA с 32-битовыми.

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

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

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

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

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

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

По умолчанию гостевая ОС описывается в виде устройства, с которого происходит загрузка виртуальной машины. Как правило это диск (минидиск). Кроме того, ОС позволяет создавать снимки памяти уже загруженной системы, с которых потом можно загружаться существенно быстрее. Это именуется хранимыми сегментами (saved segments), и они являются именованными и глобальными. То есть, если у нас имеется сегмент CMS, то загрузка ОС CMS (не следует их путать) может быть выполнена как в виде IPL 190, с минидиска, так и IPL CMS, из хранимого сегмента.

USER GUEST 12345678 16M 64M G
IPL CMS PARM AUTOCR
MACHINE ESA
CONSOLE 009 3270
SPOOL C 2540 READER A
SPOOL D 2540 PUNCH A
SPOOL E 1403 A 
MDISK 191 3390 USRPK1 510 10 MR ALL ALL ALL
LINK DIRMAINT 190 190 RR
LINK DIRMAINT 19E 19E RR

CMS


Специально для целей разработки была создана однопользовательская и однозадачная ОС, которая могла работать только на виртуальной машине. Эта ОС называлась CMS (Conversational Monitor System/Cambridge Monitor System), в разных вариантах, по назначению и по месту разработки. Это не британский Кембридж, если что, а тот что в Бостоне.

Эта ОС предназначена для того, чтобы один пользователь мог работать в ней, пользуясь дисплеем и клавиатурой, разрабатывать программы, или допустим набирать и форматировать тексты. Дисплей с клавиатурой представляет из себя консоль управления виртуальной машиной, с которой можно вводить как команды VM/SP (относящиеся к т.н. Control Program, CP), так и команды самой CMS. У вас есть командная строка, есть строка состояния, где отображается текущий статус, и строки вывода результатов. В этом режиме дисплей моделирует поведение пишущей машинки. Вы можете также запустить программы, использующие все возможности дисплея, например, для редактирования текста или для просмотра файлов.

Если вы видели MS DOS, то многое вам будет привычно. Причем речь идет про MS DOS до версии 2.

Рассмотрим некоторые типовые (не все, разумеется) задачи, которые пользователю нужно выполнять при разработке:

  • Навигация по файловой системе, поиск файлов в проекте, просмотр их атрибутов
  • Просмотр и редактирование содержимого файлов
  • Копирование, переименование, перемещение и удаление файлов
  • Архивирование (на ленту), восстановление из архива
  • Компиляция файлов на каком-либо языке программирования
  • Подготовка документации

Файлы


В качестве места для хранения файлов у ОС есть диски, они именуются буквами от A до Z. Буква не обозначает физический том с определенным набором файлов, и может быть изменена. Обычно диски S и Y были системными, где располагались файлы CMS, а диск A был свой, с доступом на запись, и там хранились файлы пользователя.

То есть, с дисками мы можем делать примерно следующее:

  • Присоединить к виртуальной машине физический диск (или минидиск другой виртуальной машины), командой LINK
  • Открыть диск на доступ, назначив ему букву алфавита командой ACCESS
  • Закрыть доступ к файлам диска и отсоединить диск
  • Отформатировать диск

Файлы именуются тремя компонентами: имя, тип, и буква диска. Скажем, ABC ASSEMBLE A — файл ABC с типом ASSEMBLE на диске A. Букву назначает команда ACCESS.

Соответственно, структура файловой системы плоская (это не совсем так, но главное что она не древовидная, как мы привыкли сегодня). Папок с файлами не предусмотрено. Имеются файлы типа «библиотека», содержащие например макросы ассемблера —, но на этом сложные структуры пожалуй заканчиваются (хотя в какой-то степени поддерживались файлы от OS/360, типа MVT).

Просмотр дисков осуществляется в порядке алфавита. То есть, если мы ищем ABC ASSEMBLE *, и файл с таким именем и типом найден на диске A, то поиск на этом прекращается. Как вы уже догадались, были так называемые wildcards, но достаточно ограниченные.

Чтобы работать с файлами, имеется широкий набор команд. Они могут быть реализованы как бинарные скомпилированные программы (тип MODULE), так и на нескольких скриптовых языках, например EXEC2 или REXX. И те, и другие запускаются из командной строки путем ввода имени файла (т.е. происходит автоматический поиск файлов с этими типами).

Разумеется, можно посмотреть список файлов — командой LIST, можно просмотреть содержимое — командой BROWSE, можно вызвать текстовый редактор — XEDIT. Чтобы напечатать файл, существует команда PRINT. Скриптовые языки позволяют наборы команд автоматизировать и оформить как одну команду. Для обмена данными между командами имеется такая структура, как стек — так что вызвав скажем команду LIST * * * (STACK, вы получите в этом самом стеке список файлов, который скрипт может прочитать, и обработать.

Хочу Нортон коммандер!


Чтобы работать со списком файлов интерактивно, имеется также команда FLIST. Это и было ближайшим аналогом Norton Commander, только панель тут была одна.

 LVL 0 - A 191       18000 BLKS 3390 R/W  69%     FILE          1 OF    12
DTRYLST  TXTAQ0   A1           F         80         44          1  12/20/01 10:41
DTRYLST  AUXAQO   A1           F         80          1          1  12/26/01  1:45
DTRYLST  LISTING  A1           F        121       1301          1  12/26/01  1:45
DTRYLST  SJ871AQ0 A1           F         80          2          1  12/26/01  1:44
DTRYLST  TXTAQ0   A1           F         80        445          1  12/26/01  1:45
DTRYSAD  AUXAQ0   A1           F         80          1          1  12/10/01  4:08
DTRYSAD  SJ966QQ0 A1           F         80          1          1  12/18/01 23:42
DTRYSAD  TXTAQ0   A1           F         80         51          1  12/18/01 23:43
FLIST    MAPAQ0   A5           F        100          2          1  12/26/01  1:46
FLIST    MODULE   A2           F       1312          3          1  12/26/01  1:46
FLIST1   $PROFILE A2           V         78         31          1  12/26/01  2:06
GOPAL    NETLOG   A0           V        108         37          1  12/26/01 17:02

 1         2     3            4          5    6     7       8     9      10     

 PF: 1 HLP 2 BRW 3 END 4 XED 5 SPL 6 /SB 7 SCB 8 SCF 9 /SD 10 /ST 11 >I  12 CAN

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

Мы видим тут колонку имени, типа и буквы диска. Далее идут формат файла — фиксированной длины строки или переменной (F/V), длина строки, размер в блоках, дата изменения.

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

У команд разрешаются параметры, обозначающие текущий файл или компоненты его названия: /, /N, /T, /M, т.е. полный ID файла, имя, тип, mode (так именуется буква диска).

Например, команда PRINT / в третьей строке выполнится с подстановкой полного ID, т.е. PRINT DTRYLST LISTING A. Если у файла тип скажем PRINT, то ввод просто /T / приведет к выполнению команды PRINT «имя» «тип» «буква диска», т.е. к печати текущего файла. То есть, тип файла тут используется как имя команды.

А в последней строке вы видите подсказку по функциональным клавишам (PF), которых было ровно 12: HLP — справка, BRW — BROWSE, END — выход, XED — XEDIT, SPL — разделить экран по строке курсора, /SB — сортировать по размеру, SCB — лдистать назад, SCF — листать вперед, /SD — сортировать по дате, /ST — сортировать по типу, >I — увеличить строку команды, CAN — убрать разделение.

А вот скриншот с экрана ПДО. Все в общем тоже самое, только некоторые надписи переведены:

xdnzclyy81lgzq8f-qrzsdtwcm4.png

И на этот раз перед вами содержимое системного диска S, с файлами самой CMS.

Обмен файлами


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

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

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

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

XEDIT


Пожалуй, текстовый редактор заслуживает отдельного поста. Но поскольку XEDIT был популярен сам по себе, и в разных вариациях выпускался позже для разных других ОС, включая MS DOS, то как раз он в какой-то степени может быть многим знаком.

Поэтому про него — коротко.

Во-первых, файл должен был полностью помещаться в память. Это позволяло работать быстро. Ограничение — примерно объем памяти виртуальной машины. Напомню, что адресация у S/370 была лишь 24-битовая, расширена до 31 и далее 32 она была позже в VM/XA и ESA.

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

Функциональные клавиши


Почему важны функциональные клавиши? Дело в том, что терминал IBM 3270 (ЕС-7927) имел собственный экранный буфер размером 24 строки на 80 символов. Нажатие обычных клавиш алфавита, пунктуации и т.п. приводили к изменению содержимого буфера. А вот в программу буфер передавался только по нажатию клавиш Enter, PF1-PF12, т.е. специальных. Только они вызывали прерывания ввода-вывода. То есть, с одной стороны, терминал брал на себя многие функции редактирования (вставки, удаления, замены), а с другой — гибкость взаимодействия обеспечивали только функциональные клавиши, только они могли программироваться. Не было и такого, чтобы вы могли запрограммировать сочетания клавиш, такие как ctrl-буква, например.

Максимум что было доступно — это терминалы с 24 функциональными клавишами.

Плюсами такой архитектуры была низкая нагрузка на процессор. Фактически, за счет этого машина типа ЕС-1046, например, всего с 4 мегабайтами памяти, могла обслуживать несколько десятков терминалов (в нашей практике — до 60), при условии, что пользователи занимаются набором и редактированием текста.

Принципы редактирования


Буфер терминала IBM 3270 мог быть программно разбит на поля, каждое из которых имело определенные атрибуты, например доступность для редактирования. Или яркость, например (а в более новых моделях и цвет).

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

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

Набор команд? Ну, если вы знакомы с чем-то типа vi, или скажем sed знаете, то в вы вполне сможете сориентироваться в XEDIT довольно быстро. Я бы сказал, что в XEDIT все даже проще в некотором роде, например потому, что нет такой вещи, как состояния. Текст сам по себе, командная строка — сама по себе, чтобы ввести команду — нужно перейти в строку команд, в строке текста вы вводите или редактируете текст (режим вставки или замены реализован аппаратно). Удобнее ли это в целом — не знаю, но в среднем это проще.

Перейти на строку, или найти строку, выполнить замену подстроки, удалить или вставить строки, скопировать или переместить — в общем, вполне обычный набор. Префиксные команды немного интереснее. Скажем, пара команд CC в разных строках файла, и третья команда (Before/aFter), указывающая куда скопировать — практически это было максимально близко к тому, что есть и на сегодня, с учетом отсутствия GUI.

0anwbgega9qdkvekbmstiymxxu0.png

Компиляция, сборка, версионирование


Собственно, в этом месте ничего необычного не было. Командная строка (или FLIST), команда компиляции в зависимости от языка, дальше файл (или файлы), и после круглой скобки — параметры (так было принято в CMS). В итоге получается объектный файл с типом TEXT, который потом линкуется с другими такими же файлами и библиотеками командой LOAD, и строится файл MODULE при помощи GENMOD. Или можно загруженный код просто запустить, например. Библиотеки макросов или модулей для линкера описываются командой GLOBAL.

Самих компиляторов было множество. Интерпретаторов тоже. В CMS были реализации для множества языков, как широко распространенных, так и довольно экзотических. Наиболее распространенными в моем окружении были FORTRAN (сначала IV, а позже 77), PL/1, ассемблер, REXX, LISP (в форме REDUCE), PASCAL/VS от IBM. Позже появился C, но широкого распространения тогда не получил, по ряду причин (в первую очередь наверное различия в парадигмах между UNIX и ОС от IBM, что в итоге приводило к некоторым неудобствам). Были и такие экзотические штуки, как PL/S, эдакий «ассемблер высокого уровня», то есть по сути — C, но для для S/370.

Инструменты полноценного версионирования файлов тогда еще не появились в CMS. Даже в виде полного аналога diff/patch (в UNIX это уже было, diff появился в середине 70-х). Версионирование существовало, но сводилось к одному файлу. И работало это примерно так: когда вы открывали файл в XEDIT, вы могли вместо сохранения нового содержимого сохранить файл UPDATE (что-то типа .patch). Впоследствии его можно было применить к исходному файлу, и получить обновленное содержимое. Ну и для полноты картины были списки таких UPDATE файлов, указывающие последовательность их применения.

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

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

Документация


Для подготовки документации было минимум два похожих инструмента. Один — это продукт SCRIPT UW, разработка университета Ватерлоо, Канада (собственно, UW — это он и есть). Второй, очень похожий инструмент — это разработка IBM под названием Script/VS.

Из того, что мы знаем сегодня, оба продукта больше всего похожи пожалуй на TeX.Т. е. вы пишете текст, и расставляете внутри него разметку, например : p. для обозначения параграфа. Потом текст обрабатыватся программой SCRIPTVS, и мы получаем файл, который можно напечатать на принтере. Поддержка принтеров — ограниченная. Поскольку обычный принтер для S/360 не умел делать ничего специфического, в частности, не имел загружаемых или сменных шрифтов, то максимум, что нам было доступно — это повторная печать строки поверх предыдущей, и получение шрифта bold. И весьма ограниченное позиционирование текста на странице. Заголовки, сбор оглавления, колонтитулы, фрагменты предформатированного текста… это все было. В общем, было довольно много чего, что вы можете представить сегодня также и по HTML, например.

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

Главное — и трава была зеленее…


Вот как-то так в целом выглядела тогда разработка. Обычный и на сегодня цикл — создание кода в текстовом редакторе, сохранение, компиляция, линковка, запуск, отладка. Далее — редактирование, и все снова. Разумеется, XEDIT — это не IDE. Да и FLIST это даже не FAR. Все несколько попроще, и масштабируется немного похуже.

Ну так и железки были слегка другие — не забудьте, что в нашем распоряжении только текстовый экран 24×80, такой же чисто текстовый принтер, порядка 16 мегабайт памяти у виртуальной машины, и столько же, если не меньше — у машины реальной. Ну и для полноты картины — самые большие диски, что я застал, были 317 мегабайт, и это были несменные устройства, и у нас их было порядка 8 штук максимум. То есть, вся дисковая память типовой EC-1046 была по порядку примерно пару гигабайт + сколько-то сменных пакетов, которые можно было установить при необходимости. Диски для персоналок по-моему доросли до этого объема примерно к 2000, когда появились модели емкостью порядка гигабайта.

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

Но тогда, уже давненько, многое из этого все равно казалось чудом…

© Habrahabr.ru