Еще немного истории — на этот раз копаемся в OS/360
В продолжение поста о том, как работали программисты в 80-х, вспомнил и решил описать предысторию, идею и реализацию моего первого успешного проекта.
Итак, дело было году этак в… давно тому назад. Я был студентом 3 курса, и начал работать старшим лаборантом своей кафедры.
Самое начало
Вообще программировать я начал на первом курсе. Одним из предметов для первокурсников у нас был Алгол-60, и первое занятие по нему было на первой же неделе. Ну как начал программировать, сначала были лекции, как водится, потом семинары, потом и код начали писать потихоньку. На экскурсию сходили, на саму машину глянули.
Использовали мы машины М-222. Что это была за машина, можно почитать скажем тут. Понятно что занимала она пару комнат в гермозоне, и пускать туда из пользователей никого не пускали. Чтобы примерно представлять — у этой машины была память 16 килослов (48 битовых), и 27000 операций в секунду.
Вот она, М-222 (а возможно М-220, они были похожи, и по фото я вообще не отличу, если честно).
Пара любопытных фактов (тогда я кое-что из этого еще знал): разработчиком первого компилятора Алгола-60 был С. С. Лавров, который в свое время работал начальником отдела баллистики в КБ у Королева. А с другим начальником отдела баллистики Энергии, Р.Ф. Аппазовым, я пересекался позже на кафедре, он сначала преподавал баллистику у нас на потоке, а потом я уже преподавал ее вместе с ним.
Режим работы с М-222 был исключительно пакетный — на входе колода перфокарт, на выходе распечатка. То есть, ты пишешь код (на бумажке в клеточку, печатными буквами или чертежным шрифтом, перечеркивая ноль, в отличие от буквы О), сдаешь его на перфорацию, получаешь колоду перфокарт, отдаешь ее исполнение. На следующее утро получаешь распечатку, на желтой рулонной бумаге, исколотую иголками подающего барабана.
То есть, процесс был двухэтапный — перфорация и выполнение.
Так сложилось, что сдавать и забирать результаты группы ходил один человек, и этим человеком стал я. Если что-то пошло не так, то исправить код и сдать еще раз ты можешь не скоро. Цикл исправления ошибок получался иногда даже двухдневным, ведь расписание наших занятий не всегда укладывалось в расписание приемки задач в ВЦ. Постепенно мы пришли к подходу, когда я самостоятельно исправлял наиболее очевидные проблемы, типа опечаток, или диагностируемых компилятором ошибок, за всю группу. В итоге так втянулся, что с тех пор и продолжаю… :)
Кстати, подозреваю, что Алгол-60, ставший моим первым изученным языком, в значительной степени определил дальнейшее развитие на какое-то время. Был бы Фортран — было бы хуже. И как я сегодня понимаю, учили нас достаточно хорошо. С одной стороны, сам язык, с другой — основные приемы оптимизации, типа развертывания циклов т.п. Без особой теории, но по времени довольно много, и с самого начала учебы. И в целом язык не прививал никому нехорошие приемы типа goto там и сям, без которых в Фортране на то время было вообще невозможно.
Фортран, впрочем, тоже не заставил себя ждать. На соседней кафедре организовали курсы по этому языку, и я стал на них ходить.
В итоге, к середине третьего курса, я дозрел до того, чтобы начать работать на кафедре.
Задачи для студентов
Устроился я на свою кафедру 601. Группа, где я работал, занималась разработками в области автоматизации проектирования. А задачи, которые давали мне, были примерно такими: реализация методов численной оптимизации, или расчет оптимальной геометрии сопла, в общем, либо математика разного рода, либо вполне прикладные инженерные задачи, в области, например, баллистики, аэродинамики, прочности, и т.п., все в основе своей — расчетные.
Окружение
Мы тогда работали в ОС, которая называется OS/360 MVT, она же ОС ЕС. Базовый язык программирования — FORTRAN-IV. Еще в ОС доступны «из коробки» такие языки, как PL/1, ассемблер S/360, Кобол, и кажется, тот же Алгол-60.
Примерно к началу моей работы на кафедре к нам в институт стали поступать машины ЕС ряда 1 (аналог S/360, без виртуальной памяти). Чтобы снова понимать масштаб изменений — наша ЕС-1033 имела мегабайт памяти, и производительность 150-200 тыс операций в секунду. И это была на тот момент средняя машина в линейке.
В комплекте ЕС-1033 были дисплеи ЕС-7066 (а весь комплекс назывался ЕС-7906). Это текстовый дисплей, без возможности отображения какой-либо графики, только текст в формате 80 символов х 12 строк. В сущности, качество изображения было ужасным, оно иногда плавало, только зеленый текст на черном фоне, и вообще — замечательный способ испортить глаза. Но для работы это давало такие преимущества по сравнению с перфокартами, что… в общем, стоило потерпеть.
Это не наша машина и не наш дисплей. Это кажется фото архив НИИЯИ. И это одна из редчайших фотографий, где реально изображен ЕС-7066. Если спросить у гугля про это устройство, то он вам покажет все что угодно, но только не его.
Практически сразу мы имели какие-то средства, обеспечивающие редактирование текста/кода, ближайшим аналогом которых можно считать современный текстовый редактор. Немного удивительно, но это никогда не был «штатный» продукт от IBM под названием TSO, а всегда какие-то другие разработки от третьих фирм.
Машинное время было острым дефицитом. Чтобы понять, насколько, вспомню пару фактов. Мы много лет снимали машинное время в разных ВЦ Москвы, например, ГВЦ Мосэнерго (рядом с Ударником, на Болотном острове), где была ЕС-1033, и было это как правило либо поздно вечером, примерно с 19 до 24, и потом нужно было быстро-быстро бежать на Библиотеку к последнему поезду метро (Боровицкую построили намного позже). А еще среди сотрудников ходила поговорка: «Жене сказал, что пошел к любовнице, любовнице — что остался у жены, а сам на машину, и работать, работать, работать».
Сверхзадача
Конечно же, текстовым редактором жизнь не ограничивалась, и очень хотелось создать инструмент, который позволял бы работать из программы на Fortran с дисплеем ЕС-7066, вводить и выводить данные в процессе исполнения своей программы.
Проблема состояла в следующем:
- фортран не поддерживал дисплеи (PL/1, на самом деле, тоже)
- операторы ввода-вывода фортрана оперировали номерами каналов, были стандартные каналы ввода и вывода номер 5 и 6, а также любые другие.
- соответствие между номерами каналов и файлами (либо устройствами) описывались на языке JCL, в виде операторов DD этого языка.
- средства форматирования языка (операторы WRITE и FORMAT) позволяли, например, сформировать строку для печати, но не позволяли записать ее куда либо, кроме нумерованного канала, которому в задании соответствовала, например, очередь печати, или файл на диске.
Вы могли описать для фортрана DD такого вида, который ссылался бы на дисплей (собственно, просто DD UNIT=7066), вот только библиотека фортрана не могла с таким каналом работать. Или немного более техническими словами, библиотека поддерживала только устройства последовательного доступа (методы доступа BSAM/QSAM), или файлы прямого доступа (BDAM, а попросту — диски). А дисплеи — это был метод доступа BGAM (графический).
Пришлось разбираться в потрохах.
Как устроена работа с терминалом в OS/360
В общем-то, как и с другими устройствами. Есть некоторый уровень абстракции, который единообразно описывает работу с разными устройствами и файлами. Его база — это DCB, Data Control Block. В ассемблере это макрос, генерирующий секцию данных. Абстракция разумеется не полная, потому что для разных типов устройств и файлов вам придется указать множество разных, зачастую несовместимых между собой параметров.
Обычно DCB содержит:
- символическое имя файла (соответствует названию DD в JCL)
- метод доступа (последовательный, по индексу, случайный, и другие)
- физические характеристики (размер блока, логическая длина записи)
- адреса подпрограмм чтения-записи данных ОС
- другие данные, нужные этим подпрограммам
Основной из этих параметров — это метод доступа к данным.
Немного о потрохах OS/360
В какой-то момент времени, читая уже не помню какую отечественную книгу по программированию, я наткнулся на описание структур данных OS/360. Если вам интересно, то такие книжки и сегодня доступны, например вот и вот.
Из описания следовало, что моя программа, следуя по указателям между этими структурами данных, вполне может найти сначала свой TCB (task control block), а через него и открытые DCB.
Порядок был примерно такой:
Фиксированный адрес в физической памяти (10 или 4C)-> CVT (communications vector table) -> следующий и текущий TCB (по адресу CVT + 0). Поскольку мы сейчас выполняемся, то текущий TCB — это и есть наш.
А дальше можно было найти список открытых блоков DCB.
А блок DCB при этом содержит адреса подпрограмм, которые выполняют операции чтения и записи… и тут меня осенило!
Сформировалась несложная вроде бы идея:
- заставить фортран открыть DCB, записав «что-нибудь» в канал («Hello, world», между прочим, тогда не было такой уж популярной фразой).
- найти этот DCB и модифицировать указатель на подпрограммы ввода и вывода, заменив их своими
- завести свой, теневой DCB, с методом доступа BGAM, чтобы работать с дисплеем, а также некоторые свои рабочие структуры данных типа буфера экрана
- в результате, то что пишется в канал, передается нашему обработчику, и попадает на экран дисплея.
- Профит!
Как говорится, дальше оставалось сесть да закодировать. Правда, сначала пришлось немного научиться читать дампы, чтобы посмотреть, как это все выглядит живьем, и например, что и как передается в качестве параметров обработчику операции в DCB, чтобы написать свой.
Понятно, что было еще множество нерешенных вопросов, например, как обрабатывать прерывания от терминала, которые приходили по нажатию клавиши Enter. Или как управлять курсором. Все эти вещи не подразумевались, когда проектировались средства ввода-вывода Фортрана.
В общем, все вопросы удалось решить достаточно несложно, и оформить в виде нескольких процедур, вызываемых из Фортрана с параметром номера канала. С прерываниями было чуть посложнее, глобально эта задача была не решаемой, так как асинхронный обработчик на Фортране написать было нельзя по чисто техническим причинам (обработчик должен быть быть «реентерабельным», т.е. допускать повторный вход в секцию кода, но сделать это на Фортране нельзя, так как некоторые области создавались статически), но в тоже время, многозадачность или параллелизм все равно Фортраном не поддерживался, так что делать что-либо полезное в тот момент, когда мы ждем ответа от пользователя все равно было нельзя. Кроме того, нажание на Enter блокировало клавиатуру, так что и повторных прерываний можно было особо не опасаться.
Итоги первого проекта
В общем, проект получился удачным. Мы сделали его за время написания диплома на пару с моим однокурсником Игорем Глинкой, а потом я достаточно долго его еще дорабатывал и развивал.
А одним из первых применений (не считая моего диплома) была программа для расчета траекторий выведения в курсе баллистики, который и я вел чуть позже вместе с Р.Ф. Аппазовым.
Когда я уже начал работать, выяснилось, что в обозримой окрестности в СССР ничего принципиально лучше для подобных целей либо совсем нет, либо мы вполне можем конкурировать со всеми. Так что написанный во время дипломной практики софт был позже внедрен на многих предприятиях МОМ, и в других местах.
И что еще интересно — сама идея проксирования ввода-вывода оказалась плодотворнее, чем данный проект. Скажем, вы могли в фортране включить отладочную печать, и получать на принтер все изменения переменных в программе. Но это выводилось в одну колонку, и жрало кучу бумаги, да еще совершенно невозможно было рыться в этих километрах. В итоге двое наших тогда еще студентов, Виталий Ладыгин и Дмитрий Мостовой, написали на базе той же идеи программу, которая буферизовала вывод отладчика, и выводила строки только тогда, когда они заполнялись процентов на 90.