IBM 3270 – это терминал компьютерного мейнфрейма. Я давно восхищаюсь мейнфреймами от IBM, и особенно этими терминалами. У ранних моделей, 3278 и 3279, была уникальная эстетика, а их блочная система работы заметно отличается от той, которой пользовались вездесущие терминалы серии VT.
Терминал IBM 3278-2 и его пра-пра-правнук, ThinkPad X1, на котором запущен оес. Терминал подсоединён к современному z14 при помощи TN3270.
Не один я хотел попробовать подсоединить настоящий терминал от IBM к эмулятору Hercules [программный эмулятор мейнфреймов IBM (System/370, System/390, zSeries/System z) и совместимых (Amdahl)]. К сожалению, довольно трудно найти контроллер терминала IBM 3174 с интерфейсом Ethernet или Token Ring, версией софта с поддержкой TCP/IP и в рабочем состоянии. К тому же они огромные, шумные, и их сложно обслуживать, поскольку софт на них приходится загружать при помощи редких флоппи-дисков 5¼" объёмом 2,4 Мб – если повезёт, бывают ещё варианты с жёстким диском на 20 Мб. Поэтому я решил сделать собственный контроллер, а в процессе узнать что-то новое.
Немного истории IBM 3270
Судя по записям компании IBM, информационная система 3270 была представлена в 1972 году, а культовый терминал 3278 – через пять лет, в 1977. Цветные терминалы появились в 1979 с 3279. Сложновато не запутаться в моделях и годах!
3270 – один из самых узнаваемых терминалов, работающих по блочной системе. Поток данных 3270 позволяет программисту описать целый экран, содержащий текст, защищённый от редактирования, доступные для редактирования поля и атрибуты его форматирования. Доступные для редактирования поля позволяют вводить или изменять данные. Вместо того, чтобы отправлять каждое сделанное вами нажатие клавиши сразу на хост, как это происходит у символьных терминалов, этот терминал хранит ввод у себя, пока вы не нажмёте особую клавишу – к примеру, Enter. Только после этого весь ввод отправляется на хост «блоком» данных. Такая система улучшает воспринимаемую отзывчивость компьютера в случае медленной или ненадёжной связи. Также это снижает требования по мощности хоста, и позволяет подключать к нему гораздо больше блочных терминалов, чем символьных. В чём-то это весьма напоминает заполнение формы на HTML-странице.
Для ранних 3270 предлагалась всякая прикольная периферия, типа световых ручек для улучшения навигации и устройств для чтения магнитных карт – к сожалению, на eBay я их не встречал.
Терминалы соединяются с контроллером коаксиальным кабелем по топологии «звезда». При помощи балуна можно превратить её в более привычную схему подключения по витой паре, хотя, как мне кажется, IBM предпочла бы, чтобы вы использовали их систему подключения. Контроллер соединяется с мейнфреймом по разным интерфейсам, в зависимости от того, местный это контроллер или удалённый. Кроме того, подключение менялось со временем. Среди интерфейсов присутствовали:
- Parallel Channel
- ESCON Channel
- X.21
- V.35
- Token Ring
- Ethernet
В итоге контроллеры IBM 3174 и 3274 бывают самых разных форм и размеров – от небольших настольных модулей, до средних устройств, предназначенных для установки в стойку и крупных напольных сооружений.
Контроллеры терминалов от IBM по часовой стрелке, начиная снизу слева: 3174-1L, 3174-23 (без передней крышки), 3174-61R и 3274-41D.
Другие компании, включая Memorex, производили совместимые терминалы и контроллеры. С распространением персональных компьютеров терминалы начали менять на ISA, PCMCIA и потом PCI-карточки, позволявшие подсоединять по тому же коаксиальному кабелю ПК с эмулятором. Позднее, с развитием LAN и TCP/IP эти подсоединения заменил телнет TN3270, которому не требовалось специальное железо или коаксиальный кабель.
Для клиентов, обзаведшихся сетью TCP/IP, но всё ещё пользующихся большим количеством физических терминалов, поздние варианты контроллеров 3174 предлагали возможность соединять их с мейнфреймом телнетом по TCP/IP. Для подсоединения к Hercules нам нужны именно такие контроллеры. Меня очень интересовал тот факт, что они также предлагали эмуляцию VT100, с помощью которой терминал 3270 можно было соединить с хостом на UNIX или VMS так, будто бы это был VT100. Для меня это было странным – ведь терминал заточен под блочную передачу, поэтому эмуляция VT100 кажется невозможной.
Последним терминалом от IBM стал 3483, представленный в конце 1990-х. К тому времени терминалы напоминали уже тонких клиентов и использовали стандартные мониторы VGA и клавиатуры с интерфейсом PS/2.
Разбираемся в протоколе
Изначальный мой поиск навёл меня на описание кабельного подключения и потока данных для 3270. Всё это было хорошо описано, однако там ничего не сказано о протоколе передачи данных между терминалом и контроллером. Его детали я смог найти, только раскопав технические описания устаревших на сегодня чипов, использовавшихся для создания интерфейсов с ПК. Их производили CHIPS и National Semiconductor:
- CHIPS 82C570
- NS DP8340
- NS DP8341
- NS DP8344
Устройства соединяются друг с другом коаксиальным кабелем с характерным импедансом 93 Ω. Кабель этот имеет тип RG-62 – в отличие от сетей на Ethernet 10BASE2, использующих топологию шины и кабель с импедансом в 50 Ω. Для уменьшения шума в длинных участках кабеля используется разностная передача сигналов, и максимальная рекомендованная длина отрезка между устройствами по спецификации составляет 1,5 км.
Данные идут с битрейтом в 2,3587 Мб/с в Манчестерском кодировании. Эта схема обеспечивает перепад напряжения с низкого уровня на верхний уровень (или наоборот) в рамках каждого бита, что гарантирует надёжную передачу данных до получателя. В каждом кадре содержится одно или несколько 10-битных слов. Каждое слово начинается с бита синхронизации и заканчивается битом чётности. Начало и конец кадра отмечают уникальные последовательности.
Вместо тысячи слов… или, как в данном случае, 10 бит. Команда чтения состояния, отправленная с контроллера на терминал.
Все коммуникации инициирует контроллер. Он отправляет на терминал кадр, содержащий управляющее слово и опциональные слова с данными (что-то типа параметров). Терминал отвечает кадром, содержащим одно или несколько слов с данными.
Оказалось, что терминалов существует два типа — CUT и DFT. CUT перекладывают обработку потока данных 3270 на управляющий модуль, и преобразуют их в базовые операции вроде движения курсора по адресу или записи символов в буфер дисплея (он же кадровый буфер). Большую часть функций, которые люди ассоциируют с терминалом 3270, выполняет контроллер – то есть, логика терминала CUT проще, чем у сравнимого по функциональности VT1000. Терминалы DFT могут обрабатывать поток данных 3270 самостоятельно, и контролер просто передаёт поток на терминал.
Подробную документацию протокола я веду на GitHub.
Hello world
На eBay до сих пор можно найти передатчики DP8340 и приёмники DP8341 от National Semiconductor, поэтому я купил их и некоторые другие компоненты, перечисленные в техническом описании. Сначала я думал собрать интерфейс с нуля, однако эти интегральные схемы передатчика и приёмника в итоге обеспечили передачу данных.
Я также нашёл контроллер IBM 3174-23R для установки в стойку с интерфейсом Token Ring, и решил, что больше мне ничего и не надо. К сожалению, дискета с управляющей программой оказалась испорченной, и загрузить получалось только диск диагностики. Диагностическая программа показывала менюшки на терминале, чего хватило для перехвата части трафика между терминалом и контроллером для последующего анализа.
Я сделал простую схему приёмника по описанию DP8341 на макетной плате, подключил её к Arduino Mega, и при помощи т-коннектора подключился между контроллером и терминалом. Я был в восторге, впервые увидев поднятие напряжения на контакте DATA AVAILABLE и вызов моего обработчика прерываний. На то, чтобы надёжно считывать данные с приёмника, у меня ушло некоторое время. Вскоре я обнаружил, что памяти в 8 Кб на Arduino Mega мне уже не хватает, а поток данных шёл слишком быстро, чтобы в реальном времени скидывать их на ПК по последовательному порту.
Большая часть перехваченных мною сообщений была командами запросов с контроллера и подтверждениями, отправленными терминалом. Поскольку все коммуникации начинает контроллер, он постоянно должен опрашивать терминал на предмет нажатой клавиши. Отфильтровав все сообщения об отсутствии нажатия, я смог разметить скан-коды клавиш, которые возвращает терминал.
Я также перехватил счётчик адресов загрузки и команды на запись данных, связанные с буфером дисплея. Адрес извлечь было легко, однако сначала я не нашёл данных, записываемых в буфер дисплея, в ожидаемой мною кодировке EBCDIC (я ждал её, учитывая схему работы диагностического интерфейса на терминале). Также это была и не ASCII – оказалось, что терминал использует свою кодировку символов. Как она называется, я не знаю, и отсылок к ней я не нашёл. Большую часть кодировки я смог разметить при помощи диагностического интерфейса. А когда я добавил на макетную плату передатчик DP8340, то смог полностью разметить все символы – сначала, конечно же, выведя на экран «hello world»!
У терминала 3270 есть строка состояния, которая выводится в самом низу экрана. Ею, за исключением текущей позиции курсора, управляет контроллер. Сбивает с толку, что строка состояния начинается с адреса 0 в буфере экрана, хотя находится в самом низу – а адрес 80 соответствует верхней левой ячейке в режиме 80 столбцов. Также кодировка символов в строке состояния отличается от остальных, и в неё входят много необычных символов.
В итоге я смог написать библиотеку для Python, pycoax, для сериализации и десериализации кадров 3270. Код на Python работает на ПК и общается с Arduino по последовательному порту (физически через USB).
Наконец, я разработал свою первую печатную плату при помощи KiCad и отправил на изготовление в JLCPCB. Спустя неделю и $15, я получил 5 «шилдов» для Arduino, готовых к сборке. Плата работает значительно лучше макетной, количество ошибок заметно уменьшилось. Да, и признаюсь, что мне пришлось заказывать плату дважды, поскольку в первый раз я совершил ошибку при разводке.
Arduino Mega и шилд-интерфейс для коаксиала
Создание oec
Моей целью было создать замену контроллеру IBM 3174, которую можно было бы использовать совместно с Hercules. Теперь, когда я понял, что терминал типа CUT не обрабатывают поток данных 3270 самостоятельно, я понял, что реализовать сначала эмуляцию VT100 будет гораздо проще, чем TN3270.
Я нашёл pyte, обеспечивающий эмуляцию VT100 в памяти, и поддерживающий подключение к процессу (типа командной оболочки или SSH). Мне нужно было только опрашивать терминал на предмет нажатий клавиш, передавать их процессу, обновлять эмулятор pyte, передавая ему выходные данные с процесса, а потом выводить эмулированный экран терминала на сам терминале. А кроме этого ещё нужно было следить, включен терминал или отключен, и отслеживать здоровье процесса.
Первые контроллеры, существовавшие в эпоху дорогой памяти, не удерживали копию экрана в своей памяти, как я делаю это сейчас. У терминала CUT есть команды на чтение из буфера дисплея и на поиск ячеек, соответствующих определённой последовательности – типа атрибута, обозначающего начало поля ввода. Я обнаружил, что без подобных ограничений куда легче хранить копию экрана в памяти и обновлять терминал.
Вдохновившись pyte, я написал pytn3270, быблиотеку TN3270 на чистом Python, обеспечивающую похожую эмуляцию в памяти. Для интеграции с контроллером потребовалось сопоставить атрибуты полей байту атрибутов терминала 3270. Я мог бы использовать x3270, однако мне хотелось лучше разобраться в протоколе telnet и потоке данных 3270. Для протокола TN3270 я реализовал необходимый минимум – но его достаточно для подключения к z/OS, а библиотека на чистом Python может оказаться полезной и вне этого проекта.
На сегодня oec ещё далёк от поддержки абсолютно всех функций контроллера IBM 3174, однако пользоваться им можно. Скачать его можно с GitHub.
Будущее
Во-первых, хочу добавить меню связи, чтобы можно было выбирать хоста (пока что мы умеем подключаться только к одному хосту) и поддержку нескольких логических терминалов. Потом добавлю поддержку EAB и TN3270E – для этого мне нужно будет реализовать некоторые функции в pytn3270, которых пока не хватает.
Пока я работаю над интерфейсом на основе FPGA, чтобы не полагаться на устаревшие микросхемы от National Semiconductor – и в процессе изучаю протокол и немного Verilog.
Автор: Вячеслав Голованов