- PVSM.RU - https://www.pvsm.ru -
Статья с сайта безумного инженера-самодельщика Криса Фентона [1]
Встречайте ZedRipper – 16-ядерного зверюгу, работающего на частоте 83 МГц на базе процессоров Z80 – настолько же портативного, насколько и непрактичного. Это моя самая свежая на сегодня попытка собрать компьютер ради прикола, причём удовлетворив сразу несколько желаний:
Если у вас нет времени читать простыню текста о непрактичной компьютерной архитектуре…
ZedRipper – это результат попытки построить самый крутой компьютер с CP/M 2.2:
Это что, шахматы и Planetfall, отвлекающие меня от моего редактора Turbo Pascal?
После моих приключений с портированием игр на Kaypro [2] у меня осталось удивительно тёплое впечатление от этой примитивной операционной системы 40-летней давности, и у меня появилась идея, которую я решил развить: что, если бы история свернула в другую сторону, и ПК пошли бы по пути развития с множеством CPU прямо сразу? Даже в 1980-х сами процессоры (а вскоре и RAM) были относительно недорогими, однако многозадачность ПК базировалась исключительно на разрезании отрезков времени, когда один большой ресурс (RAM или CPU) делили между соревнующимися программами. Железо не справлялось с этим (и было очень сложно заставить программы вести себя хорошо в таких ОС, как DOS), пока мы не перешли в эру 386-х и компьютеров с объёмом памяти более 4 Мб.
В процессе занятий моими историческими хобби с компьютерами я наткнулся на нечто очень для меня интересное: на ранних этапах развития ОС CP/M [3] поддерживала «сетевую» версию под названием CP/NET. Её идея знакома большинству людей и сегодня – поставить в офисе одну-две «настоящие» машины с большими накопителями и принтерами, ресурсы которых делили бы между собой тонкие клиенты, терминалы с CPU и RAM. Каждый пользователь работал бы так, будто у него есть собственная машина под управлением CP/M с доступом к объёмным дискам и принтерам.
Как я упоминал, CPU и RAM (обычно у Z80 было 64 Кб DRAM) были не особенно дорогими, однако все внешние приблуды, необходимые для создания полезного компьютера (диски, принтеры, мониторы,..) добавляли итоговой стоимости. В то время добавление в компьютер нескольких CPU/RAM казалось несколько декадентским подходом для обеспечения одного пользователя несколькими CPU и RAM. Даже CP/M пошла по пути разделения отрезков времени для MP/M OS.
Я обнаружил, что ближе всех к этому подошла компания Exidy – в 1981 году они выпустили свою машину Multi-NET 80, позволявшая добавлять до 16 карточек, на каждой из которых был Z80 и RAM. Однако она была предназначена для работы до 16 отдельных пользователей, а не для работы одного пользователя, одновременно запускавшего 16 программ.
Так близко…
Перенесёмся на 40 лет вперёд – транзисторы реально подешевели. Мне по наследству после закрытия лаборатории досталось несколько чудовищных по размеру FPGA (Stratix IV 530GX), и я думал, что бы такого интересного сделать с одной из них. В какой-то момент я наткнулся на очень интересный проект Гранта Сёрла Multi-Comp [4], и собрать рабочую машину с CP/M и одним CPU оказалось довольно легко. Но мне нужно было больше. Я решил посмотреть, удастся ли мне создать многоядерную машину на CP/M с реальной многозадачностью – ничего хитроумного, просто метод грубой силы.
В этом проекте я в основном концентрировался на железе, и не написал ни одной строчки кода на ассемблере. CPU 0 грузится прямо с ROM, который я взял у Гранта, а остальные узлы грузятся с 4KB CP/NOS ROM, которые я взял у симулятора Atari.
Оба ROM ожидают соединения с последовательным терминалом по стандартному интерфейсу, а клиенты CP/NOS ожидают ещё одного последовательно порта, соединённого с сервером. На таких крупных FPGA легко проектировать собственную логику. Я разработал свою логику декодирования адресов, благодаря которой Z-Ring для каждого CPU появляется в схеме отображения адресов там, где надо.
Сердце ZedRipper – одна из этих огромных Stratix IV 530GX FPGA. Карта HSMC используется для дисплея, получения данных от контроллера клавиатуры и соединения с SD-картой. Для загрузки прошивки используется ethernet, поэтому сбоку корпуса есть такой порт, вместе с адаптером SD-карты и слотом для внешнего последовательного порта (пока не используется).
Клавиатура и отверстие на переднем плане, куда потом будет установлено позиционирующее устройство
У меня валялась компактная клавиатура PS/2 (от одного из моих старых проектов с ноутбуком), и я хотел подсоединить её к 2,5 В I/O моего FPGA. Я решил пойти по лёгкому пути, и добавить в связку микроконтроллер Teensy 2.0.
Контроллер на горячем клее снизу клавиатуры
Это позволило транслировать PS/2 в ASCII, а также легко разметить некоторые из дополнительных клавиш (F1-F12) на «волшебные» последовательности терминальных команд, для пущего удобства. Затем контроллер выдаёт Z80 байты по UART на 9600 бод (при помощи простого делителя напряжения, меняющего 5 В на 2,5 В для FPGA). Учитывая, что этот проект был собран из разного хлама, валявшегося у меня в мастерской, это было удобное решение, хорошо показавшее себя в работе.
Экран загрузки, в левом верхнем углу работает сервер, а на отдельных ядрах работают три разные пользовательские программы
Характеристики дисплея: 1280×800 10.1″, и он понимает VGA. FPGA использует простую сеть из резисторов для выдачи до 64 цветов (R2G2B2). Дисплею требуется таймер 83,33 МГц (1280×800@60Hz), поэтому для простоты вся схема работает на этой частоте.
В проекте Гранта, Multicomp, был код VHDL для простого ANSI-совместимого терминала. Я переписал его логику на Verilog, а потом разработал видеоконтроллер с поддержкой 16 независимых терминалов, соединённых через один узел Z-Ring. Дисплей 1280×800 считается дисплеем размером 160х50 символов (со шрифтом 8х16), а каждый терминал работает как «спрайт» 80х25, который можно переместить в любое место экрана (со списком приоритетов, настраивающим последовательность отрисовки терминалов). Поскольку каждый терминал работает независимо от других, у него есть собственный конечный автомат, с 2 Кб RAM для символов и 2 Кб RAM «атрибутов» (для хранения информации о цветах). Каждый символ поддерживает 4-битный цвет фона и символа. Поскольку у всех терминалов символы должны иметь одинаковые отступы, а в «ячейке» 8х16 может содержаться только один символ, все терминалы могут пользоваться одним и тем же 2 Кб ROM, содержащим шрифт. В целом логика дисплея использует около 66 Кб блочной RAM.
В целом получается очень простой менеджер окон для моих терминалов CP/M, почти полностью работающий за счёт железа. Это одна из наиболее богатых для исследования областей – пока что переставлять терминалы местами умеет только серверный CPU, но у меня есть далеко идущие планы по добавке позиционирующего устройства типа мыши, которое позволит, пользуясь только средствами железа, перетаскивать окна и менять приоритет дисплеев.
Поскольку контроллер терминала – это просто один из узлов Z-Ring (а перенаправлять этот интерфейс для любого из Z80 очень просто), среди будущих планов – возможно, добавление «полноэкранного» терминала 160х50 (возможно, как «фон»), и реального дисплея 1280x800x64 цвета при помощи быстрой внешней SRAM на плате.
Как соединить вместе кучку Z80? На моей работе я прочно усвоил одну вещь: разрабатывать сети сложно. Общими целями данной сети были:
Как я уже упоминал, мои Z80 ожидают подключения к последовательным портам, поэтому интерфейс сделать было довольно просто – его нужно было замаскировать под последовательный порт! По сути, Z-Ring – это синхронная однонаправленная кольцевая сеть, использующая «кредиты» для управления потоком. У каждого узла есть 1-байтовый входящий буфер для каждого из остальных узлов сети. После сброса у каждого узла есть 1 «кредит» для каждого из остальных узлов сети. Схема параметризирована, поэтому легко масштабируется до сотен узлов с добавлением совсем небольшого количества логики, однако на сегодня Z-Ring поддерживает до 32 узлов (поэтому каждому узлу нужен 32-байтный буфер).
Сама «шина» состоит из бита допустимости, ID «источника», ID «цели» и 1-байтной полезной нагрузки (19 бит). Думаю, её было бы довольно просто реализовать при помощи логики TTL (если бы человек провалился в 1981 год и не нашёл себе FPGA). У каждого «узла» есть 2 конвейера для триггеров шины – 0 и 1 этапа – и при вводе сообщения оно ждёт, пока не опустеет 0-й этап, а потом вливается в 1-й. Сообщения вводятся на узле-«источнике», и путешествуют по кольцу, пока не дойдут до цели, после чего они оказываются в соответствующем буфере и обновляют флаг «готовности данных». Когда принимающий узел считывает буфер, он заново вводит оригинальное сообщение, продолжающее путешествовать по кольцу, пока снова не дойдёт до источника, возвращая «кредит». Если отправить пакет по несуществующему адресу, кредит вернётся автоматически, пройдя полный круг.
Поскольку каждая остановка на кольце состоит из двух конвейерных этапов, а обратное давление отсутствует, у каждого сообщения уходит не более 2*(количество узлов) циклов на доставку. У текущей реализации 17 узлов (16 CPU + контроллер дисплея/клавиатуры), и она работает по таймеру 12 нс, поэтому на доставку сообщения и возврат кредита уходит порядка 400 нс. Контроллер дисплея может отправлять трафик со скоростью поступления, поэтому у каждого CPU есть 2-2,5 Мб/с пропускной способности к своему терминалу (шина пропускает достаточно, чтобы обеспечить все 16 CPU), что довольно много для терминалов.
В текущей конфигурации всё работает отлично, однако можно сделать несколько очевидных улучшений:
Но всё это может подождать до лучших времён.
FPGA требует на вход 14-20 В, дисплею нужны 12 В, а клавиатуре и контроллеру нужны 5 В. Удобно, что на FPGA есть регуляторы на 3,3, 5 и 12 В, к которым довольно легко подключиться, поэтому FPGA получает питание напрямую от литий-полимерной аккумуляторной батареи на 5000 мА*ч с напряжением 14,4 В, и потом раздаёт питание всем остальным устройствам. Одна из сложностей заключалась в том, что мне не хотелось разбирать ноутбук каждый раз для зарядки, но у батареи был обычный разъём питания + / -, а также «балансировочный» разъём, подсоединяемый к каждой отдельной ячейке. Моё неидеальное решение состоит в том, что кнопка включения переключает соединение с батареей между питанием FPGA и зарядным разъёмом, находящимся в углублении, закрытом сдвижной крышкой. Не очень удобно, однако можно просто сдвинуть крышку, и вытащить оттуда коннекторы, чтобы подсоединить их к зарядке, не пользуясь шестигранными ключами.
Зарядка выглядит странновато
Я не тестировал батарею тщательно, но она держит не менее 3 часов (чего с лихвой хватает для покрытия моих поездок на поезде). Скорее всего, она продержится порядка 6 часов без какой бы то ни было оптимизации потребления. Она не поддерживает использование одновременно с зарядкой, однако от батарейки ноутбук работает достаточно долго для того, чтобы это не было проблемой.
Корпус стандартной «хакерской» конструкции – комбинация из 3 мм фанеры лазерной резки и пластика, распечатанного на 3D-принтере. Я подпружинил экранные петли, поэтому в деле он ощущается как обыкновенный, пусть и несколько медленный, ноутбук. Мне хотелось придать ему вид 1980-х, поэтому верхние углы экрана немного напоминают Cray, а под запястья сделана подставка из искусственной кожи. Край резаной лазером фанеры очень неприятен для рук, поэтому такая подставка оказалась удивительно функциональной.
Не пробовал ни одного бенчмарка специально для CP/M (предполагаю, что они бывают, но особенно не искал). Поскольку эта машина была сделана для написания программ на Turbo Pascal, я попробовал несколько микро-тестов на скорость. Получилось 15-35 К операций с плавающей запятой в секунду (с использованием 48-битного типа Real в TP), и порядка 1 млн целочисленных операций в секунду (с 16-битным типом Integer). Неплохо для 8-битного CPU и достаточно удобной среды для программирования.
Интересным проектом на будущее может быть разработка ускорителя для операций с плавающей запятой.
Вся логика, как я уже говорил, довольно лёгкая, и отнимает всего около 7% ресурсов чипа (хотя 40% от общей блочной RAM и 100% от M144k RAM).
В моих ближайших планах (то есть, железо уже лежит в мастерской, просто надо найти время на пайку):
В более долгосрочной перспективе рассчитываю на разные железячные идеи, с которыми будет прикольно поэкспериментировать:
Пока что машина работает всего несколько дней, однако могу сказать, что мне всё очень нравится. Экран приятный и чёткий, клавиатура большая и удобная, корпус громоздкий, но весит мало (и влезает в рюкзак). Ноутбук оказался даже на удивление эргономичным для работы в поезде.
Мне кажется, я на верном пути. Возможность открыть текстовый редактор в одном окне для заметок, отлаживая код на TP в другом, чрезвычайно удобна (или возможность делать заметки, играя в Zork!). Чувствуется, что такой подход к созданию недорогих многозадачных компьютеров на базе CP/M мог существовать.
Пока что у меня нет лёгкого способа доставать файлы из машины, поэтому самая полезная часть ПО (файловый сервер CP/Net, написанный на Turbo Pascal), находится в ловушке. Оставайтесь с нами, и следите за новостями (или напишите мне емейл [6], если совсем не терпится). В какой-то момент я, наверное, присоединюсь к XXI веку и открою учётку на github. Увы, всё упирается в то самое «свободное время».
Автор: Вячеслав Голованов
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/noutbuk/340106
Ссылки в тексте:
[1] Криса Фентона: http://www.chrisfenton.com
[2] портированием игр на Kaypro: http://www.chrisfenton.com/dd9-kaypro-edition/
[3] CP/M: https://ru.wikipedia.org/wiki/CP/M
[4] Multi-Comp: http://www.searle.wales/
[5] Kermit: https://ru.wikipedia.org/wiki/Kermit_(%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB)
[6] емейл: mailto:chris@chrisfenton.com
[7] Источник: https://habr.com/ru/post/480290/?utm_source=habrahabr&utm_medium=rss&utm_campaign=480290
Нажмите здесь для печати.