Серия «Некромантия старой школы»

26

GNUstep: разрывая все шаблоны

Серия Некромантия старой школы

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

Внимание! Начинается процесс форматирования мозга!

Внимание! Начинается процесс форматирования мозга!

О чем речь

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

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

Даже краткая аннотация из википедии легко вгоняет в диссонанс современных MacOS‑разработчиков:

GNUstepсвободная реализация Cocoa (ранее OpenStep) — объектно-ориентированного API (Objective-C) для объектно-ориентированных операционных систем.

Objective‑C (основной язык разработки под MacOS и iOS) и свободная реализация Cocoa (главный UI/UX фреймворк Apple) — расскажите об этом типичному разработчику под Mac, потратившему несколько тысяч долларов на покупку железа Apple и платную подписку на XCode, увидите как у человека начинается нервный тик.

Еще можно троллинга шутки ради сдать тестовое задание на позицию «MacOS Developer»:

#import <AppKit/AppKit.h>
int main(int argc, const char *argv[])
{
return NSApplicationMain (argc, argv);
}

Код выше ничем не отличается от стандартного main() на обычном маковском Objective-C, при этом никакого отношения к Apple и MacOS не имеет.

Даже если немного усложнить и углубиться в реализацию:

@implementation CalcBrain: NSObject
-(id) init
{
[super init];
result = 0;
enteredNumber = 0;
operation = none;
fractionalDigits = 0;
decimalSeparator = NO;
editing = YES;
face = nil;
return self;
}

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

Вот так выглядит «showcase» GNUStep — тестовое приложение с демонстрацией функционала:

Вся «королевская рать», запущено что характерно на обычном Linux.

Вся «королевская рать», запущено что характерно на обычном Linux.

История

Разумеется история появления такого чуда не менее прекрасна и удивительна:

Проект был начат Паулем Кунцем (Paul Kunz) с командой из Стенфордского Центра линейного ускорителя (Stanford Linear Accelerator Center) которым был нужен порт HippoDraw из NeXTSTEP на другую платформу. Вместо того, чтобы переписывать программу с нуля, используя ее архитектуру, разработчики решили переписать слой NeXTSTEP, от которого зависело приложение. Это была первая версия libobjcX.

Именно так выглядит настоящий хардкор в разработке:

взять и переписать часть операционной системы ради портирования одного приложения.

«Как тебе такое, Илон Маск?» (ц)

Справедливости ради стоит заметить, что в те былинные времена графические библиотеки были сильно проще, а само действо происходило в «закрытом НИИ» и на государственные гранты. Что конечно несколько отличается от современных потогонных реалий и перегретого рынка разработки ПО.

Поэтому не удивляйтесь, когда на предложение «переписать часть операционной системы в рамках проекта» вместо одобрения или хотя‑бы обсуждения, вам сразу же вызовут санитаров из дурки.

Разрыв шаблона номер один

На дворе далекий 1994й год, времена модемов, досок BBS, ФИДО и первых персональных компьютеров.

А кое-где уже cуществовал самый настоящий Graphical Interface Builder:

Представляете это в 1994м году?

Представляете это в 1994м году?

Вот в качестве иллюстрации снимок с ЭЛТ монитора тех лет:

2008 в&nbsp;левом углу экрана — дата создания самого снимка, обычным фотоаппаратом.

2008 в левом углу экрана — дата создания самого снимка, обычным фотоаппаратом.

Это не шутка, самый настоящий конструктор интерфейсов был реализован еще в далеком 1988 году:

Gorm (Graphical Object Relationship Modeller) is a graphical user interface builder application. It is part of the developer tools of GNUstep. Gorm is the equivalent of Interface Builder that was originally found on NeXTSTEP, then OPENSTEP, and finally on Mac OS X. It supports the old .nib files as well as its own .gorm file format.

Был создан и работал задолго до рождения большинства читающих сейчас эту статью. Вот вам для иллюстрации еще один снимок тех лет, с местной «косынкой»:

NeXTSTEP 0.8 <a href="https://pikabu.ru/story/gnustep_razryivaya_vse_shablonyi_14161981?u=http%3A%2F%2Ftoastytech.com%2Fguis%2Fns082.html&t=%D0%B7%D0%B0%D0%BF%D1%83%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9%20%D0%B2%20%D1%8D%D0%BC%D1%83%D0%BB%D1%8F%D1%82%D0%BE%D1%80%D0%B5&h=215f44262e83cc8fbd975c95b3c70ea069f29b04" title="http://toastytech.com/guis/ns082.html" target="_blank" rel="nofollow noopener">запущенный в эмуляторе</a>.

NeXTSTEP 0.8 запущенный в эмуляторе.

А теперь внимание на даты:

A preview release of NeXTSTEP (version 0.8) was shown with the launch of the NeXT Computer on October 12, 1988

Мне тогда было 5 лет а на дворе был Советский Союз. Для сравнения, вот так примерно в те времена выглядел весь софт в СССР а затем и в РФ:

Да, это <a href="https://pikabu.ru/story/gnustep_razryivaya_vse_shablonyi_14161981?u=https%3A%2F%2Fwinworldpc.com%2Fproduct%2Ffoxpro%2F2x&t=FoxPro&h=9aa063d819698f3d31f677af12c4bb94ee30663a" title="https://winworldpc.com/product/foxpro/2x" target="_blank" rel="nofollow noopener">FoxPro</a>. Ощутили разницу?

Да, это FoxPro. Ощутили разницу?

Так что шаблон «раньше был страшный черный MS DOS и текстовые интерфейсы» только что треснул.

Еще один замечательный и интересный пример:

Текущая версия текстового редактора <a href="https://pikabu.ru/story/gnustep_razryivaya_vse_shablonyi_14161981?u=https%3A%2F%2Fmediawiki.gnustep.org%2Findex.php%2FInk.app&t=Ink&h=5dad67bcea19ff4ac3d0c4f9b57df77d7f59ab73" title="https://mediawiki.gnustep.org/index.php/Ink.app" target="_blank" rel="nofollow noopener">Ink</a>.

Текущая версия текстового редактора Ink.

Видите на снимке выше открытый текстовый документ, с разными шрифтами, кернингом и лигатурой?

Как бы это не было удивительно, но данный функционал был реализован невероятно, даже шокирующе давно — вот так выглядел в 1988 году его далекий предок:

Внимание на верхний правый угол: <a href="https://pikabu.ru/story/gnustep_razryivaya_vse_shablonyi_14161981?u=https%3A%2F%2Fwinworldpc.com%2Fproduct%2Fnextstep%2F0x&t=Next%200.8&h=e81b0e6c7cb765f428646e55538dc3a96ea0e3bc" title="https://winworldpc.com/product/nextstep/0x" target="_blank" rel="nofollow noopener">Next 0.8</a> от 1987 года (!)

Внимание на верхний правый угол: Next 0.8 от 1987 года (!)

Расширение файла .wn не что иное как формат текстового процессора WriteNow:

WriteNow is a word processor application for the original Apple Macintosh and later computers in the NeXT product line. The application is one of two word processors that were first developed with the goal that they be available at the time of the Mac product launch in 1984, and was the primary word processor for computers manufactured by NeXT.[2

Так что корни современных текстовых процессоров уходят невероятно далеко в прошлое, дальше чем вы думали.

Рабочая станция <a href="https://pikabu.ru/story/gnustep_razryivaya_vse_shablonyi_14161981?u=https%3A%2F%2Foldcomputers.net%2Fnext-cube.html&t=Next%20%22Cube%22&h=3fda71ab0d213352a5c3179ee76b7a99a64e5909" title="https://oldcomputers.net/next-cube.html" target="_blank" rel="nofollow noopener">Next "Cube"</a>.

Рабочая станция Next "Cube".

Разрыв шаблона номер два

Компания NeXT давно закрыта, никакие ее продукты уже давно не продаются, даже само API OpenStep — фактически заброшено, а «свободная реализация» в виде GNUstep на сегодняшний день выглядит как оживший труп из далекого прошлого.

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

Ни за что не догадаетесь кто это все затеял и зачем, что лишний раз показывает как мало мы знаем о мире информационных технологий:

Windows Bridge for iOS (codenamed "Islandwood") is an open-source middleware toolkit that allows iOS apps developed in Objective-C to be ported to Windows 10 by using Visual Studio 2015 to convert the Xcode project into a Visual Studio project.[7][9][10] An early build of Windows Bridge for iOS was released as open-source software under the MIT License on August 6, 2015, while the Android version was in closed beta.[7]

This "WinObjC" project is open source on GitHub. It contains code from various existing implementations of Cocoa Touch like Cocotron and GNUstep as well as Microsoft's own code that implements iOS frameworks using UWP methods. It uses a version of the LLVM clang compiler.[11]

Вот такие дела: Microsoft использовал исходный код GNUStep для создания конвертера проектов XCode под Windows. Причем проект очень даже живой.

Но выглядит это.. весьма своеобразно:

Сборка и запуск

Праздник «старой школы» был бы неполным без рассказа о том как собрать и запустить GNUstep своими силами.

Для написания статьи использовался Mageia Linux, но инструкции актуальны и для всех других дистрибьютивов и ОС.

Поскольку проект GNUstep находится в полузаброшенном состоянии, не стоит пытаться ставить его из пакетов — в большинстве дистрибутивов эти пакеты не имеют ментейнера и присутствуют «для галочки», просто потому что собираются.

Вместо этого, мы соберем GNUstep непосредственно из исходников.

tools-make

Начать придется со своей специфичной и уникальной системы сборки:

The makefile package is a simple, powerful and extensible way to write makefiles for a GNUstep-based project. It allows the user to write a project without having to deal with the complex issues associated with configuration, building, installation, and packaging. It also allows the user to easily create cross-compiled binaries.

Да, я тоже был удивлен, но наверное не так сильно, поскольку многие старые проекты (например оригинальный CDE) имеют собственные системы сборки.

Забираем это чудо:

git clone https://github.com/gnustep/tools-make.git

Собираем:

cd tools-make
./configure --prefix=/opt/gnustep
make
make install

Как видите тут используется ключ --prefix - указание на установку в нестандартное место, которое нужно чтобы собираемый проект не попал при установке в системные каталоги.

Еще это означает, что придется добавлять путь /opt/gnustep в переменные окружения, либо в LD_LIBRARY_PATH либо в PATH:

export PATH=/opt/gnustep/bin:$PATH

libs-base

Следующим шагом собираем commons — общую библиотеку классов:

The GNUstep Base Library is a library of general-purpose, non-graphical Objective C objects. For example, it includes classes for strings, object collections, byte streams, typed coders, invocations, notifications, notification dispatchers, moments in time, network ports, remote object messaging support (distributed objects), and event loops.

Стоит помнить, что речь идет об использовании этих библиотек для сборки, поэтому необходимо устанавливать версии пакетов «для разработчиков» — с заголовочными.h файлами.

Забираем исходный код проекта:

git clone https://github.com/gnustep/libs-base.git

Запускаем сборку:

./configure --prefix=/opt/gnustep
make
make install

libs-gui

Следующий шаг — сборка еще одной общей библиотеки, в этот раз графической, отвечающей за интерфейс:

The GNUstep gui library is a library of graphical user interface classes written completely in the Objective-C language; the classes are based upon Apple's Cocoa framwork (which came from the OpenStep specification). These classes include graphical objects such as buttons, text fields, popup lists, browser lists, and windows; there are also many associated classes for handling events, colors, fonts, pasteboards and images.

Каких-либо проблем с этими библиотеками не было, поскольку они все старые и очень стабильные. Забираем исходники:

git clone https://github.com/gnustep/libs-gui.git

Собираем:

./configure --prefix=/opt/gnustep
make
make install

libs-back

Еще одна библиотека, в этот раз — с реализацией «бекэнда» графического рендера. Забираем исходный код:

git clone https://github.com/gnustep/libs-back.git

Собираем:

./configure --prefix=/opt/gnustep
make
make install

Перед запуском конечных приложений на GNUstep необходимо выполнить:

defaults write NSGlobalDomain GSBackend libgnustep-xlib

Эта команда установит бекэнд по-умолчанию, сама настройка будет сохранена в каталоге ~/GNUstep

На этом сборка самого фреймворка GNUstep завершена и можно наконец запускать примеры.

Примеры

Выложены в официальный репозиторий Github, вместе с самим проектом GNUstep, все примеры отлично собираются и запускаются.

Забираем исходники:

git clone https://github.com/gnustep/tests-examples.git

Каждый пример является отдельным проектом, собираемым через специфичный make GNUstep, поэтому для сборки необходимо иметь путь /opt/gnustep в переменной PATH.

Вот так выглядит в работе пример графического редактора:

Этот скриншот был <a href="https://pikabu.ru/story/gnustep_razryivaya_vse_shablonyi_14161981?u=https%3A%2F%2Fwww.linux.org.ru%2Fgallery%2Fscreenshots%2F17377294&t=%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D0%BD%20%D0%BD%D0%B0%20%D0%9B%D0%9E%D0%A0%D0%B5&h=70e3b442197d3b15eab2946a2dfcd1ae6fe08ec1" title="https://www.linux.org.ru/gallery/screenshots/17377294" target="_blank" rel="nofollow noopener">опубликован на ЛОРе</a>.

Этот скриншот был опубликован на ЛОРе.

Также стоит рассказать о еще двух интересных проектах из мира древних и усопших.

Gorm

Тот самый «interface builder», которым я столько восхищался в начале статьи:

Gorm (Graphical Object Relationship Modeller) is a graphical user interface builder application. It is part of the developer tools of GNUstep. Gorm is the equivalent of Interface Builder that was originally found on NeXTSTEP, then OPENSTEP, and finally on Mac OS X. It supports the old .nib files as well as its own .gorm file format.

В запущенном виде он выглядит как-то так:

И сейчас мы будем его собирать, забираем исходный код:

git clone https://github.com/gnustep/apps-gorm.git

Напоминаю про специфичный make для GNUstep и необходимость наличия /opt/gnustep в переменной PATH, сама сборка выполняется вот так:

make

К сожалению autotools для этого проекта нет, поэтому попытка использования make install приведет к установке в системный каталог /usr/lib, что разумеется не очень надо.

Поэтому для теста было решено запускать бинарник gorm сразу из места сборки:

export LD_LIBRARY_PATH=/opt/gnustep/lib:./InterfaceBuilder/obj:./GormObjCHeaderParser/obj:./GormCore/GormCore.framework/Versions/0
./Applications/Gorm/Gorm.app/Gorm

За что я конечно буду гореть в аду для программистов. Но потом.

Projectcenter: IDE для GNUstep

Да, у них в могиле есть даже свой собственный IDE:

IDE — Integrated Development Environment. PC manages code and builds applications, frameworks and libraries, use GORM for Interface editing.

И его тоже я смог собрать и запустить, выглядит в работе он как-то так:

Забираем:

git clone https://github.com/gnustep/apps-projectcenter.git

Сборка аналогична описанной выше сборке проекта Gorm, по тем же причинам я снова произвел «закат солнца вручную» для запуска:

export LD_LIBRARY_PATH=/opt/gnustep/lib:./Framework/ProjectCenter.framework/Versions/0.7.0
./ProjectCenter.app/ProjectCenter

Совместимость

После размещения статьи на ЛОРе, читатели задали интересный вопрос по поводу совместимости с оригинальной и современной Cocoa. Был взят минимальный пример и немного адаптирован:

#import <Cocoa/Cocoa.h>
int main()
{
[NSAutoreleasePool new];
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
id menubar = [[NSMenu new] autorelease];
id appMenuItem = [[NSMenuItem new] autorelease];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
id appMenu = [[NSMenu new] autorelease];
id appName = [[NSProcessInfo processInfo] processName];
id quitTitle = [@"Quit " stringByAppendingString:appName];
id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
action:@Selector(terminate:) keyEquivalent:@"q"] autorelease];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(10, 10, 200, 200)
styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]
autorelease];
[window setTitle:appName];
[window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
[NSApp run];
return 0;
}

И.. оно заработало! Пусть и с минимальными переделками, но заработало.

Вот так выглядит запущенное приложение на Linux:

Да, это тот самый "minimal Cocoa example" для MacOS. Только на Linux.

Да, это тот самый "minimal Cocoa example" для MacOS. Только на Linux.

Современность

Разработка GNUstep как ни странно до сих пор продолжается, так выглядит наверное самое популярное приложение (из еще актуальных) на этом фреймворке:

Обратите внимание на даты в почте — 10 лет назад.

Обратите внимание на даты в почте — 10 лет назад.

Но только все графические примитивы и паттерны использования, заложенные в GNUstep — устарели, слабо представляю как такой UI/UX возможно соотнести с современным использованием десктопа, даже профессионального.

А вы смогли бы пользоваться таким ПО каждый день?

Версия для.. Windows

Ну и наконец последний разрыв шаблона на сегодня:

вы можете легко и просто поставить GNUstep.. на Windows.

Вот так это выглядит в работе:

Даже готовый инсталлятор есть, так что ничего не помешает «прикоснуться к прекрасному с минимальными усилиями».

Эпилог

Разумеется как NEXTstep так и GNUstep ныне являются чистой историей, поскольку даже заложенные в них подходы к построению UI/UX — концептуально устарели. Устарели настолько, что пользоваться таким интерфейсом даже автору (видевшему многое) — откровенно тяжело.

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

Тем не менее, о существовании такого проекта стоит знать, хотя‑бы для понимания — насколько далеко в прошлое уходят корни современных технологий.

Но рабочие станции конечно были очень красивые, для тех-то лет:

P.S.

Статья была опубликована на Хабре, более трешевый оригинал которой доступен в нашем блоге.

Показать полностью 16
22

Plexus P/20: самый редкий UNIX-сервер

Серия Некромантия старой школы

Который был оживлен и запущен в эмуляторе, спустя 40 лет после банкротства компании‑создателя. Самая редкая операционная система и самое редкое железо из всего что автор когда‑либо видел за жизнь.

Ни один житель СССР и РФ не мог видеть эти строчки запуска, поскольку машины Plexus были редкостью даже в самих США и абсолютно точно их продукция никогда не попадала в наши края.

Ни один житель СССР и РФ не мог видеть эти строчки запуска, поскольку машины Plexus были редкостью даже в самих США и абсолютно точно их продукция никогда не попадала в наши края.

Plexus

Всего было создано около 2500 таких машин, производила их с 1980 по 1988 небольшая калифорнийская компания Plexus Computers:

3833 North First Street San Jose, California, 95134, United States (408)943-9433

В 1989 году компания обанкротилась и производство было остановлено навсегда. Вот тут выложен интересный PDF-документ с отсканированной брошюрой, описывающей их продукцию:

Еще кто-то выложил в сеть отсканированное руководство администратора для одной из последних моделей Plexus P/90:

Вот так выглядит один из последних сохранившихся образцов, Plexus P/75:

Кнопка запуска вблизи:

Обратите внимание на бежевые панели - это не пластик а самое настоящее железо.

Обратите внимание на бежевые панели - это не пластик а самое настоящее железо.

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

Вот так выглядит еще один из доживших образцов попроще — Plexus P/35:

Эта же модель на брошюре с описанием возможностей, в свои лучшие годы:

Еще один отсканированный обзор:

Действующий Plexus P/20

В 2024м году одному компьютерному энтузиасту из Калифорнии удалось заполучить Plexus P/20 в свои лапы и вернуть его к жизни. Весь процесс оживления, а также детальный обзор этой машины он записал в серию видео, которые затем выложил на Ютуб.

Но это еще не все, поскольку довольно быстро в комментариях под видео появились живые свидетели, заставшие эти удивительные машины:

About Plexus Computer, Inc. : It started operating in 1981 and in 1988 sold its Unix and hardware side of their business to Motorola. By this time they 've already gone up to the 68020 processor with up to 48 MB of RAM and adopted the VMEbus in their P/95 product. They kept on developing their expensive and niche software imaging products under chapter 11 protection (bankruptcy) until 1989 when they finally sold the remaining software assets to "Recognition Equipment".

Сочетание фраз up to 48 MB of RAM и 1988 год думаю заставит дернуться не один читательский глаз.

Как видите, если создать действительно неубиваемый сервер — им будут пользоваться и через 20 лет после банкротства производителя:

So cool to see one of those again! I worked for a Circuit City location years ago that in the 2000s was still running serial terminals over a PLEXUS server. I do know it was based on 68030 CPUs, with a pair of 160MB SCSI drives in mirror. But it so happened that I was the only non-corporate person who had root level login on the command line. The rest of the store was based on a locked menu for sales, inventory management, etc. I had just quit consulting and as the ONLY person on site with Unix certificates, I got saddled with emergency on-call. It never happened, but oh that brings back memories!

Обратите внимание на объемы: диски по 160 мегабайт в 1988м году (!), времена ленточных накопителей и дискет на 360 килобайт.

Эмулятор Plexus P/20

https://github.com/Spritetm/plexus_20_emu

В 2024м году команда энтузиастов смогла реализовать полноценный эмулятор этой редкой машины:

This emulator emulates most aspects of a Plexus P/20 system: you can boot from a hard disk image, log into UNIX and play around. The things currently unsupported are the tape drive, floppy drive, and any Multibus cards.

Если вы простой обыватель, далекий от UNIX и программирования, но каким‑то удивительным образом дочитали до этого места — у эмулятора существует веб‑версия, которая позволит увидеть UNIX System 5.2 в работе без описанных ниже приседаний со сборкой из исходников и запуском.

Мы же пойдем как обычно путем хардкора — соберем и запустим все собственными руками. Проект эмулятора свежий, поэтому спокойно и без ошибок собирается самым обычным штатным clang на FreeBSD:

cc -v
FreeBSD clang version 18.1.6 (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c2e05e67)
Target: x86_64-unknown-freebsd14.2
Thread model: posix
InstalledDir: /usr/bin

Поэтому проблем со сборкой в линуксе не будет.

Но в Windows/Mac так просто проект не соберется — соответствующих ветвлений в исходниках нет.

Забираем проект, внутри всего одна ветка — текущая:

git clone https://github.com/Spritetm/plexus_20_emu.git

Собираем:

cd plexus_20_emu
gmake

Эмулятор маленький, собирается очень быстро, после сборки появится готовый бинарник emu:

Для работы эмулятора необходимы два ROM-файла и образ диска, все три находятся в соседнем репозитории с информацией по Plexus P/20.

Вот так выглядит вся последовательность действий:

git clone https://github.com/misterblack1/plexus-p20.git
cd plexus-p20
cp ROMs/U1*-MERGED.BIN ../plexus_20_emu/
cp disk/plexus-sanitized.img.gz ../plexus_20_emu/
gunzip ../plexus_20_emu/plexus-sanitized.img.gz

В результате в корневом каталоге эмулятора у вас должно появиться три файла: два.BIN и один.img. Их имена зашиты в код эмулятора, поэтому переименовывать нельзя.

Запускаем эмулятор:

./emu

После прохождения тестов оборудования появится стадия single mode:

Для продолжения загрузки в многопользовательский режим, введите:

init 2

Появится диалог задания даты и времени, думаю очевидно что тут есть проблема 2000 и задать можно только дату до 1996го года.

Затем пойдут проверки файловой системы:

И наконец появится приглашение авторизации:

Введите root, затем вместо ввода пароля нажмите <Enter>, появится приглашение командной строки от суперпользователя, с полным доступом:

Добро пожаловать в самый редкий UNIX на свете:

Вот так выглядит список процессов:

Вывод корневых каталогов:

Поскольку образ диска был снят с реальной машины, в системе есть пользователь adrian (тот самый энтузиаст), в домашнем каталоге которого есть кое‑что интересное, в частности инструкции по работе в этой системе.

Для попадания можно использовать.. стандартный su:

su adrian

Или же зайти под ним из приглашения (пароля нет):

В системе есть cat и работают пайпы:

И даже есть вот такой артефакт:

Вывод содержимого классического /etc/passwd, до сих пор присутствующего во всех UNIX-системах:

Как видите в системе используется C shell (csh), расположенный в весьма нестандартном месте:

/usr/plx/csh

К сожалению man-ы (системные руководства и справка по командам) повреждены:

Вот так выглядят переменные окружения:

Есть vi, grep, find, bison и компилятор Си:

Удивительная система из далекого прошлого, о которой я абсолютно ничего не знал пока не наткнулся на видео от Адриана.

P.S.

Статья была опубликована на Хабре, оригинал статьи как обычно в нашем блоге.

Показать полностью 22
31

OSF/1 в эмуляторе1

Серия Некромантия старой школы

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

Так это выглядит в работе.

Так это выглядит в работе.

История

OSF/1 это еще одна редкая UNIX-система из далекого прошлого, которую вы врядли могли наблюдать в живую:

OSF/1 is a variant of the Unix operating system developed by the Open Software Foundation during the late 1980s and early 1990s. OSF/1 is one of the first operating systems to have used the Mach kernel developed at Carnegie Mellon University, and is probably best known as the native Unix operating system for DEC Alpha architecture systems.

Прямой участник корпоративных Unix‑разборок 90х известных как Unix Wars, но в отличие от A/UX (которую автор оживил и запустил в прошлом выпуске) OSF/1 не канула в лету в бурные 90е а будучи переименованной в TRUE64 UNIX поддерживалась аж до 2012го года.

Вот вам и «динозавр», внезапно отказавшийся умирать.

Еще из интересных фактов стоит упомянуть использование этой ОС для суперкомпьютеров:

IBM used OSF/1 as the basis of the AIX/ESA operating system for System/370 and System/390 mainframes.[12] Intel Paragon supercomputers used a version of OSF/1 featuring the Mach 3.0 kernel.[13] OSF/1 was also ported by Kendall Square Research to its proprietary microarchitecture used in the KSR1 supercomputer.

Суперкомпьютер KSR1 Единственное <a href="https://pikabu.ru/story/osf1_v_yemulyatore_14080919?u=https%3A%2F%2Fglobal.museum-digital.org%2Fsingleimage%3Fimagenr%3D2310146&t=%D1%84%D0%BE%D1%82%D0%BE&h=4b7b079fa2995c9379cb8f99799979f7e7eb5c34" title="https://global.museum-digital.org/singleimage?imagenr=2310146" target="_blank" rel="nofollow noopener">фото</a> в приличном разрешении этой редкой машины.

Суперкомпьютер KSR1 Единственное фото в приличном разрешении этой редкой машины.

А также попытку адаптации компанией Apple в качестве замены A/UX:

Apple Computer intended to base A/UX 4.0 for its PowerPC-based Macintoshes upon OSF/1,[11] but the project was cancelled and PowerOpen deprecated.

Которая была отменена вместе с самой A/UX.

OpenBSD/luna88k running inside GXemul, on an emulated SGI O2 running OpenBSD/sgi (on a FreeBSD/amd64 host). Теперь попробуйте осознать прочитанное.

OpenBSD/luna88k running inside GXemul, on an emulated SGI O2 running OpenBSD/sgi (on a FreeBSD/amd64 host). Теперь попробуйте осознать прочитанное.

Эмулятор

Полностью оно называется Gavare's eXperimental Emulator за авторством Anders Gavare и согласно официальному описанию с сайта проекта, считает себя фреймворком для виртуализации:

GXemul is a framework for full-system computer architecture emulation, mostly written in 2003-2005. Several real machines were implemented within the framework, consisting of processors (ARM, MIPS, Motorola 88K, PowerPC, and SuperH) and surrounding hardware components such as framebuffers, interrupt controllers, busses, disk controllers, and serial controllers. The emulation is working well enough to allow several unmodified "guest" operating systems to run.

По сути это такой сильно разросшийся «pet project», созданный одним энтузиастом ради эмуляции особо редких систем:

Простым обывателям из этого списка знакомы наверное только игровые платформы, в лучшем случае еще «малинка» (Rastberri Pi) а про некоторые особо редкие не знал даже автор, так что будут еще изыскания и эксперименты, посвященные этому удивительному проекту.

Сборка

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

В этот раз все действия производились на обычном Mageia Linux, без BSD и прочих изысков, с использованием стандартного GCC:

Несмотря на строчку из документации по сборке:

This should work on most Unix-like systems, with few or no modifications to the source code. The basic requirement is a reasonably modern C compiler (C99).

Эмулятор написан все же на C++ а не на чистом С, поэтому для сборки требуется компилятор C++, который ныне устанавливается отдельным пакетом.

Но в остальном автор не врет:

GXemul does not require any additional third-party libraries to build.

И проект действительно не использует никаких внешних библиотек. Кроме X11, ради эмуляции графического экрана:

  • X11 headers and libraries: for graphical framebuffer emulation.

Так что ничего дополнительно устанавливать не придется.

С версии 0.6 разработка переехала на Github, откуда мы и заберем последние правки исходников (ветка master):

git clone https://github.com/BitEdits/gxe.git

Главная проблема с этим эмулятором — неправильная работа с некоторыми эмулируемыми ОС без специального ключа сборки --debug:

When compiling on Linux via a modern GCC please bear in mind that the emulator wont work correctly if compiled with -O optimization flags. Please use -debug configure option to disable such optimization

Что выяснилось далеко не с первой попытки.

Изучаемая OSF/1 как раз из числа проблемных, поэтому попытка запуска в версии эмулятора, собранного без этого волшебного ключа выдает kernel panic:

Теперь вы тоже видели как выглядел kernel panic в 1992м, поздравляю.

Теперь вы тоже видели как выглядел kernel panic в 1992м, поздравляю.

Согласно официальному описанию, ключ --debug всего лишь отвечает за отладочную сборку:

configure for a debug build (turn off optimizations)

На практике все несколько сложнее и этим ключом помимо отключения оптимизаций, еще собирается отдельный оконный отладчик. Чтобы не вводить параметр каждый раз, я прописал в начале скрипта configure вот такой параметр:

DEBUG=YES

Скрипт кстати не из известного пакета autotools а полностью собственной разработки. После каждой правки configure скрипта или шаблонов Makefile.skel (см. ниже) необходимо перезапускать настройку вызовом:

./configure

Теперь запускаем make для запуска сборки и ждем приключений.

Первая ошибка не заставит себя ждать:

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

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

В файле src/main/Makefile.skel в конец значения параметра CXXFLAGS необходимо дописать указание на версию спецификации --std=c++14:

CXXFLAGS=$(CWARNINGS) $(COPTIM) $(DINCLUDE) -std=c++14

Заново запускаем configure и сборку:

./configure
make

Следующая ошибка также связана с изменением в поведении компилятора:

И да, эта ошибка также обоснована и по хорошему код стоит отрефакторить. Когда-нибудь потом.

А на сейчас я просто отключил предупреждение, добавив в файл src/main/promemul/Makefile.skel параметр -Wno-narrowing:

CXXFLAGS=$(CWARNINGS) $(COPTIM) $(DINCLUDE) -Wno-narrowing

Повторно запускаем configure и сборку:

./configure
make

В этот раз сборка должна завершиться успешно и в корне проекта появится бинарник gxemul:

Запуск

К сожалению не удалось найти установочный диск OSF/1, поэтому я использовал готовый образ диска, в котором ОС уже была развернута.

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

Команда запуска выглядит так:

./gxemul -e 3max -X -d osf1_mips.img -j vmunix

Где -e 3max указание на тип эмулируемой машины, 3max это например DECstation 5000/200 (3MAX):

Ключ -X указывает использовать графический фреймбуфер, без него вы не увидите графического приглашения. Ключ -d указывает на путь к образу диска (в архиве по ссылке выше) а вот -j это уже особая уличная магия:

-j name  set the name of the kernel;

for DECstation emulation, this passes the name to the bootloader, for example:  --j netbsd  (NetBSD/pmax) 

-j bsd  (OpenBSD/pmax)

-j vmsprite  (Sprite/pmax)  

-j vmunix  (Ultrix/RISC)

Войти в систему можно под учетной записью root с паролем Jaguar64.

Новый пользователь создается в терминале xterm, с помощью команды adduser:

Изменить пароль можно стандартной командой passwd.

Сеть

Разумеется без поддержки сети толку от такой эмуляции было бы немного. К счастью эмулятор сделает за вас большую часть работы по пробросу сети в эмулируемую систему (сторону хоста) — сам поднимет виртуальный интерфейс, назначит IP‑адрес и даже выставит DNS.

Вам остается только вторая половина — настроить сеть в системе 1992 года.

Как уже описал выше, эмулятор сам создает виртуальный сетевой адаптер, который со стороны гостевой OSF/1 называется ln0.

Должна отрабатывать команда:

ifconfig ln0

В выводе должно быть видно текущее состояние адаптера.

Также эмулятор самостоятельно создает исходящий адаптер с IP-адресом 10.0.0.254, который также является маршрутизатором.

Эти детали отображаются в консоли при запуске эмулятора:

simulated network: 10.0.0.0/8 (max outgoing: TCP=100, UDP=100) simulated gateway+nameserver: 10.0.0.254 (60:50:40:30:20:10) simulated nameserver uses real nameserver 192.168.1.1

Так выглядит запрос состояния устройства со стороны гостевой OSF/1:

Как только назначим IP-адрес 10.0.0.2 виртуальному адаптеру, должна отрабатывать команда pingк хосту:

Таким образом обеспечен сетевой доступ к хосту из гостевой ОС.

Но чтобы заработал доступ еще и наружу — в интернет, необходимо включить маршрутизацию в гостевой ОС (со стороны хоста это NAT):

В этот момент автор наткнулся на свежую статью 2024го года от Kevin Read, где случились два важных открытия:

  • в интернете есть более современная версия OSF/1 2.0 (да оно официально так называется),

  • существует и подробно описана стандартная настройка сети.

Шаги настройки описанные выше в правильной версии закрываются командой netsetup:

Так вы получите базовую настройку сети и маршрутизацию, но вот с DNS все несколько сложнее. Отвечает за настройку работы резолвера команда bindsetup:

Вся последовательность выглядит как-то так:

Enter the default BIND domain name []: localdomain

Enter your choice [c]: c

Enter the host name of a BIND server: vigor

Enter the Internet address for 10.0.0.254. []: 10.0.0.254

# affected: /etc/rc.config, /etc/hosts

Would you like to run svcsetup now to edit the /etc/svc.conf file (y/n) [y] ?

Enter your choice(s).

For example "0 3 5" [no default] : 2 "hosts" database [2]: 3

# affected: /etc/svc.conf

# hosts: local,bind

Главное это задать IP-адрес хоста, который отвечает за DNS.

В результате всех этих манипуляций должен отрабатывать ping из гостевой OSF/1 и с использованием доменного имени:

OSF/1 2.0

С помощью образов дисков, взятых отсюда, удалось запустить и версию 2.0 этой системы:

Отличить можно по качеству картинки - в 2.0 версии больше цветов. Учетная запись в этой копии: root/test123

Команда запуска также несколько отличается:

./gxemul -X -e 3max -d osf1-2.0-root-full.img -d osf1-2.0-opt.img -M 128 -j genvmunix

Еще тут в каталоге /usr/local/src находится куча полезного софта в виде исходников, для примера удалось запустить сборку bash:

К сожалению не до конца:

Хотя Kevin пишет что should compile fine:

The installed MIPS C compiler is good enough to compile some basic things, and gcc 2.9.5 should compile fine. Apparently binutils is broken, but ld is installed anyway.

Думаю реальная проблема в лицензиях, которые в те времена выдавались на компиляторы в коммерческих UNIX-системах.

P.S.

Статья была опубликована на Хабре, оригинал в нашем блоге.

Показать полностью 19
8

Retro68: если вам скучно жить на свете

Серия Некромантия старой школы

Конец ноября в Питере — крайне мрачное время года, на улице лишь холод, сырость и уныние. Что определенно влияет на психику местных обитателей, порождая в головах самые нездоровые желания и идеи, которые затем попадают в криминальную хронику.

Видимо по этой причине, одним мрачным осенним днем мне захотелось создать графическое приложение на современном C++ под.. классический Mac из 90х.

В действии.

История

Честно не знаю что вам сказать, на этот раз у меня нет оправданий или логических объяснений для того что я опять сотворил.

Cпишем на плохую погоду и рептилоидов с Нибиру:

рассказываю и показываю как создавать приложения на современном C++ для классического Apple Macintosh начала 90х.

Примерно такого:

Macintosh Quadra 700. Компьютер как компьютер.

Macintosh Quadra 700. Компьютер как компьютер.

The Macintosh Quadra 700 is a personal computer designed, manufactured and sold by Apple Computer from October 1991 to March 1993.

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

The Quadra 700 originally had a list price of US$5,700

Такое и сегодня далеко не для всех.

Однако времена славы Макинтошей давно прошли, ныне все эти некогда «звездные» компьютеры — те что еще остались в рабочем состоянии, являются музейными экспонатами и предметами коллекционирования.

Поэтому, то что опишу ниже — точно не имеет никакого практического применения:

все это лишь эталонная, дистиллированная дичь, без примесей и добавок.

Это на тот случай, если вы вдруг ожидаете от статьи чего-то большего.

Весь сетап целиком.

Весь сетап целиком.

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

A GCC-based cross-compilation environment for 68K and PowerPC Macs. Why? Because there is no decent C++17 Compiler targeting Apple's System 6. If that's not a sufficient reason for you, I'm sure you will find something more useful elsewhere.

Разве можно было пройти мимо столь вдохновляющего описания?

Я тоже не удержался, убив в итоге несколько лишних дней на оживление и запуск этого чудовища чуда. Но прежде чем пойдем дальше, стоит рассказать читателям немного старой доброй матчасти:

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

Матчасть

Представьте, что на вашем столе лежит вот такой кусок текстолита с железом, для которого надо написать программу:

Хотя именно <a href="https://pikabu.ru/story/retro68_esli_vam_skuchno_zhit_na_svete_14072507?u=https%3A%2F%2Flinuxdevices.org%2Ftiny-linux-mips-system-runs-on-3-watts%2F&t=%D1%8D%D1%82%D0%BE%D1%82%20%D0%B4%D0%B5%D0%B2%D0%B0%D0%B9%D1%81&h=3f102c8688b75f6dcd0978108dd586021fafe38e" title="https://linuxdevices.org/tiny-linux-mips-system-runs-on-3-watts/" target="_blank" rel="nofollow noopener">этот девайс</a> на самом деле весьма мощный.

Хотя именно этот девайс на самом деле весьма мощный.

Да, на фото выше самый настоящий компьютер:

c процессором, памятью и портами ввода-вывода — все как положено.

Но только слишком слабый для развертывания полноценной среды разработки непосредственно на нем.

Поэтому если вы не маньяк-психопат LISP-разработчик — будет откровенно сложно вести какую-либо разработку на такой хне без кросс-компиляции.

Кросс-компиляция это когда на обычном офисном компьютере без отрыва от игор cобирается приложение, предназначенное для запуска на принципиально другом устройстве:

смартфоне, роутере, соковыжималке, встраиваемой платформе умного дома, коптере или еще каком боевом роботе.

Или на другой операционной системе — сборка на линуксе под Windows это тоже вполне себе кросс-компиляция.

Тулчейн для кросс-компиляции обычно устанавливается (и даже собирается) отдельно, часто бывая очень сложным. Еще он содержит компиляторы, линкеры, ассемблеры для «вражеской» архитектуры и многое другое, не менее интересное.

В некоторых случаях тулчейн включает и части целевой системы:

заголовочные файлы, ресурсы и даже готовые библиотеки для линковки.

Без которых создавать что-то сложнее «Hello, world» с помощью кросс-компиляции было бы проблематично.

Так выглядит тот самый "Hello,world", собранный через кросс-компиляцию и запущенный в эмуляторе с MacOS 7.

Так выглядит тот самый "Hello,world", собранный через кросс-компиляцию и запущенный в эмуляторе с MacOS 7.

Retro68

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

a gcc-based cross-compiler for classic 68K and PPC Macintoshes

Во-первых «gcc-based», что означает определенную совместимость с нормальными и современными компиляторами, а также отсутствие экзотических проблем, характерных для редких и/или устаревших компиляторов, вроде bcc.

Во-вторых тут две разных целевых архитектуры: 68k и PowerPC.

А значит можно собирать софт для всей линейки Маков с начала 90х и до начала 2000х — до MacOS X Tiger, последней поддерживающей архитектуру PowerPC.

Но пожалуй самое важное это поддержка трех разных UI-фреймворков на целевых системах:

Что означает возможность создавать приложения с графическим интерфейсом для всего зоопарка винтажных маков.

Типа такого:

Так выглядит демо с диалогом, созданное при помощи кросс-компиляции.

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

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

Терминал

Когда только начинал собирать материал для этой статьи, узнал что в первых MacOS (внезапно) не было консоли и абсолютно все приложения были только и исключительно графическими:

Консоль появилась только в <a href="https://pikabu.ru/story/retro68_esli_vam_skuchno_zhit_na_svete_14072507?u=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMacOS&t=MacOS%20X&h=5fffa674be624100557b82e8803e28d255798bb0" title="https://en.wikipedia.org/wiki/MacOS" target="_blank" rel="nofollow noopener">MacOS X</a>, в 2001м году.

Консоль появилась только в MacOS X, в 2001м году.

Поэтому тот факт, что классическое консольное приложение на С:

#include <stdio.h>

int main(int argc, char** argv)
{
printf("Hello, world.\n");
printf("\n(Press Return)\n");
getchar();
return 0;
}

возможно собрать в графическое, с таким псевдо-терминалом в комплекте:

Тоже является заслугой тулчейна Retro68 и ключем линковки при сборке:

LDFLAGS=-lRetroConsole

Сборка на FreeBSD

Тулчейн официально поддерживает несколько популярных операционных систем:

  • Linux, Mac OS X or Windows (via Cygwin)

И действительно совершенно спокойно, без каких-либо проблем и нюансов собирается на линуксе.

Что мне показалось слишком скучным, поэтому ради гусарской забавы портировал этот проект на FreeBSD.

Всегда так делаю.

Если вам такие забавы не близки, сообщаю что для линукса достаточно по шагам выполнить инструкцию в README. И все сразу будет хорошо, только не у вас.

Ну а мы как обычно пойдем путем хардкора — соберем весь тулчейн на FreeeBSD с нуля.

Кстати форк Retro68 с поддержкой сборки на FreeBSD выложен в отдельном репозитории. Первым делом надо установить ряд инструментов для разработки и системных библиотек:

pkg install cmake gmp mpfr mpc boost-all bison flex texinfo ruby

Забираем исходники и поскольку репозиторий большой — выгружаем без истории коммитов (ключ depth):

git clone --depth 1 https://github.com/autc04/Retro68.git

Выкачиваем зависимые репозитории:

git submodule update --init
git pull
git submodule update

Теперь надо немного изменить скрипт сборки, для учета особенностей FreeBSD.

Первым делом заменяем вызовы make на gmake, поскольку FreeBSD использует свою версию утилиты make, несовместимую с GNU-версией. Которая конечно также присутствует в пакетах, но только называется gmake.

Дальше необходимо переделать вызовы configure для вложенных проектов из скрипта сборки, суть правок:

пробросить указание на использование библиотек из каталога /usr/local, куда устанавливаются все внешние с точки зрения системы библиотеки в FreeBSD.

Например для строки:

$SRC/binutils/configure --target=m68k-apple-macos --prefix=$PREFIX --disable-doc

необходимо дописать в конец:

CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib

Таким образом переменные CFLAGS и LDFLAGS будут переданы скрипту configure в качестве аргумента при вызове.

Чуть сложнее со сборкой GCC (да, мы тут собираем компилятор из исходников), строка:

$SRC/gcc/configure --target=m68k-apple-macos --prefix=$PREFIX \
--enable-languages=c,c++ --with-arch=m68k --with-cpu=m68000 \
--disable-libssp MAKEINFO=missing

Тут уже нельзя использовать переменные окружения CFLAGS и LDFLAGS из-за особенностей сборки GCC и необходимо передавать пути для ключевых библиотек специальными аргументами:

--with-mpc=/usr/local --with-mpfr=/usr/local --with-gmp=/usr/local --with-isl=/usr/local --with-libiconv-prefix=/usr/local

Дописав их в конец вызова configure.

Таким же образом необходимо поправить еще два места в скрипте сборки: раз и два.

После чего можно запускать сборку.

Запускается она из отдельного каталога:

mkdir ../Retro68-build
cd ../Retro68-build
../Retro68/build-toolchain.bash

После весьма продолжительной (даже на мощном компьютере) и жутко выглядящей сборки, по накалу страстей на экране напоминающей знаменитый make buildworld из FreeBSD:

..все упадет на вот такой «страшной» ошибке:

Для исправления ситуации, надо всего лишь изменить один import в файле portable_endian.h , в этом месте:

#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)

# include <sys/endian.h>

Суть проблемы в том что расположение заголовка endian.h поменялось и теперь его необходимо включать без указания каталога sys:

# include <endian.h>

Исправляем импорт и перезапускаем сборку.

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

На этот раз падение произойдет на стадии сборки из cmake:

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

удалением импорта этого заголовка из файла PEFTools/MakePEF.cc

Поскольку его содержимое в последних версиях FreeBSD добавили в stdlib. Так что смело удаляем импорт и перезапускаем сборку.

Следующее падение сборки и следующая проблема заключается в пересечении заголовков — системного, из самой FreeBSD и локального — из библиотеки libelf:

Тут к сожалению я не нашел изящного решения, достойного быть упомянутым в летописях, поэтому сделал «колхоз»:

скопировал файл gelf.h из libelf/include в каталог Elf2Mac, и поменял ссылки на этот заголовок из глобального на локальный.

Было:

#include <gelf.h>

Стало:

#include "gelf.h"

Поменять ссылки необходимо во всех файлах проекта Elf2Mac где встречается данный импорт. Наконец последняя ошибка сборки, связанная с особенностями FreeBSD:

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

Для исправления достаточно добавить:

#include <netinet/in.h>

в файл LaunchAPPL/Client/TCP.cc

Так выглядит успешное завершение сборкиRetro68:

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

Теперь переходим к эмулятору, поскольку живого Mac тех лет, на котором возможно запустить результат сборки у меня нет.

Эмулятор

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

Такова сила бренда, созданного Стивом Джобсом.

Я буду использовать один из самых популярных и известных эмуляторов классических Macintosh:

Basilisk II is an Open Source 68k Macintosh emulator.

Разработан он был еще в начале 2000х, немецким инженером Christian Bauer, ныне активная разработка уже не ведется. Поэтому вместо нее я использовал более современный форк, в котором решены вопросы совместимости с современным же окружением и обновлены используемые библиотеки.

И внезапно добавлен JIT (Just-In-Time Compiler).

Еще форкнутая версия немного стабильнее, с более адекватным поведением перехвата курсора.

Эмулятор использует следующие библиотеки, которые необходимо установить до попыток сборки:

pkg install sdl2 autoconf automake mpfr gmp

Теперь забираем исходники:

git clone https://github.com/kanjitalk755/macemu.git

Собираем:

cd macemu/BasiliskII/src/Unix
$ ./autogen.sh
$ gmake

В результате в текущем каталоге появится бинарник BasiliskII, которым и запускается эмулятор:

Для того чтобы запускать MacOS7 в эмуляторе, нужен загружаемый образ диска с установленной системой (или ее инсталлятор) и ROM-файл.

Образ диска можно взять например тут или тут, ROM-файл например отсюда или отсюда. Еще пара вариантов.

Еще вот тут находится крайне интересная табличка, с описанием практически каждого доступного ROM, его особенностей и работоспособности.

Напомню, что для этой статьи я эмулировал модель Quadra 600:

Для эмулятора использовался вот такой ROM-файл:

Указав в разделе «Volumes» путь к образу диска с MacOS7, затем в разделе «Memory/Misc» путь к ROM-файлу, можно наконец запускать эмулятор:

Теперь переходим к самому веселому — к разработке.

Разработка с помощью Retro68

Собственно после сборки Retro68, у вас будет все что нужно для разработки конечного софта, поскольку в каталоге build-target/Samples будут собранные примеры приложений:

Эти примеры собираются автоматически, во время сборки самого тулчейна Retro68, в качестве дополнительных тестов работоспособности.

Для сборки во всех случаях используется cmake, исходники находятся в каталоге Retro68/Samples.

Чтобы собрать проект с HelloWorld отдельно, выполняем:

сd /opt/src/Retro68/Samples/HelloWorld
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=/opt/src/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake
gmake

Результат сборки:

Каждый пример при сборке генерирует образ диска, который можно сразу подключить к эмулятору:

Достаточно указать путь к dsk-файлу, который находится в каталоге build и запустить эмулятор:

На рабочем столе появится иконка с названием, совпадающим с названием примера:

После двойного клика по этой иконке, раскроется окно с содержимым этого виртуального диска в виде единственного запускаемого файла:

Двойной клик по файлу HelloWorld запустит наше приложение.

Примеры приложений

Как уже упоминал, в составе Retro68 есть довольно много демонстрационных приложений.

Каждый пример раскрывает аспект разработки и создан так, чтобы его можно было использовать в качестве основы для собственных проектов.

Автор тулчейна постарался, поэтому все примеры логичны, просты и понятны.

Retro68/Samples/Raytracer

Трассировщик лучей, реализующий генерацию псевдотрехмерной картинки в реальном времени. Собственно процесс отрисовки в этом приложении как раз показан на заглавной картинке к статье.

В проекте на самом деле присутствуют сразу две реализации, одна на С, другая на C++, видимо для сравнения во время работы.

Так выглядит финальный результат рендеринга:

Проект ценен в первую очередь как демонстрация расчетной логики и операций с числами с плавающей точкой.

Retro68/Samples/Dialog

Демонстрация работы с модальными диалогами — как задавать размеры и расположение элементов, как создавать формы ввода, как получать вводимые данные и так далее.

В работе:

Retro68/Samples/WDEF

Демонстрация работы с многооконными интерфейсами (MDI), создание окна с кастомным оформлением и работа с ресурсами окон.

Так это выглядит в действии:

Кратко по остальным примерам, реализующим какую-то специфическую логику.

Retro68/Samples/MPWTool

Реализует расширение для MPW (Macintosh Programmer's Workshop), точнее для MPWShell, с обработкой запуска оттуда и корректного возвращения в консоль.

Retro68/Samples/SharedLibrary

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

Retro68/Samples/SystemExtension

Пример простейшего расширения для самой операционной системы MacOS 7, в данном случае вся видимая логика заключается в показе новой иконки при запуске ОС.

Retro68/Samples/Launcher

Реализует запуск сторонних приложений через перетаскивание (Drag&Drop).

"Masters of Hardcore" - вбейте в поиск если не жалко уши и соседей.

"Masters of Hardcore" - вбейте в поиск если не жалко уши и соседей.

Настоящий хардкор

Вы же не думали, что я успокоюсь на банальной сборке тулчейна с эмулятором под FreeBSD и запуске пары тестов?

Праздник должен продолжаться:

Clapkit (CLassic APplication KIT) is a framework for developing applications for Classic Mac OS (System 7.x - Mac OS 9.x), basically a C++/object-oriented wrapper for Macintosh Toolbox functions.

Да, глаза вас не подводят, это самый настоящий современный графический фреймворк для компьютеров начала 90х.

Так это выглядит:

Картина неизвестного питерского художника "Мак под маком".

Картина неизвестного питерского художника "Мак под маком".

Так выглядит код:

#include <ckApp.h>

int main() {

CKApp* app = CKNew CKApp();

app->CKNewMsgBoxNote("Hello world!", nullptr, "OK",
nullptr, [app](int button) {
app->CKQuit();
});
// Run loop: without this, your app will quit as soon as it launches.
while (!app->CKLoop(5));
delete app;
return 0;
}

Так выглядит мое тестовое приложение на современном C++, собранное с помощью cmake на FreeBSD и запущенное на MacOS 7 из 90х:

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

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

Ну что дорогие читатели, ударим шизой по осенней летней хандре?

MPW

Конечно ударим, но прежде стоит рассказать про нормальную разработку для продукции Apple, как это происходило у нормальных людей.

Разумеется на маках всегда была собственная среда разработки:

Macintosh Programmer's Workshop (MPW) is a software development environment for the Classic Mac OS operating system, written by Apple Computer.

Ее вполне можно использовать до сих пор, благо образов дисков в сети хватает. Именно так я и советую поступать (т.е. использовать MPW) в случае любого более-менее серьезного проекта, поскольку где и когда закончатся возможности кросс-компиляции и вы опустите руки — предсказать не берусь.

Как-то так MPW выглядит в эмуляторе:

Тут находится отличная статья по созданию «Hello, world» на MPW в эмуляторе, которой вполне хватит для начала приключений. Но в этот раз нам нужен не MPW а только его часть — системные заголовки, которые мы будем использовать для злодейства сборки.

В Retro68, в каталоге InterfacesAndLibraries находится файл Readme.md, содержимое которого явно намекает на дальнейшие действия:

Find a copy of Apple's Universal Interfaces 3.x (preferrably 3.4) and put them here.

Вообще «Find a copy» это такой толерантный и социально приемлемый синоним старого доброго «скачать варез», прямо из 90х. Потому как купить официально старое ПО уже не представляется возможным, если подобное вдруг придет в голову. Даже если компания-разработчик существует (как в случае Apple), старые версии своих продуктов она так просто не продаст.

Потому что есть поддержка, гарантии и защита прав потребителей.

И репутация компании.

Поэтому сообщаю по секрету, что «найти» эти самые универсальные интерфейсы можно например тут:

wget https://henlin.net/images/Interfaces\&Libraries.zip
unzip "Interfaces&Libraries.zip" -d /opt/src/Retro68/InterfacesAndLibraries

Ссылка кстати взята из другой интересной статьи, в которой автор реализует слой рендера для фреймворка Nuklear, о котором я уже внезапно писал.

Так это демо выглядит в работе, порт эмулятора на Javascript внезапно оказался встроен в статью:

JS-версия загружается довольно долго, браузер может подвисать.

JS-версия загружается довольно долго, браузер может подвисать.

Хотя этот проект успешно собрался из исходников, при попытке запуска в эмуляторе программа на базе Nuklear вылетала.

Разгадка оказалась в необходимости использовать другой эмулятор и собственно полностью другую эмулируемую систему.

Так что расскажу про связку из Nuklear, QuickDraw и Retro68 в другой раз, чтобы не раздувать эту статью до совсем уж космических размеров.

А пока для затравки, показываю эту связку в действии:

Не пугайтесь размеров элементов интерфейса в эмуляторе - игрался с зумом, проиграл.

Не пугайтесь размеров элементов интерфейса в эмуляторе - игрался с зумом, проиграл.

Но вернемся к фреймворку ClapKit, благо история с ним еще не закончена.

После распаковки заголовков из MPW, необходимо перезапустить сборку самого тулчейна Retro68:

cd Retro68-build
../Retro68/build-toolchain.bash

И наконец можно приступать к половым утехам с самим ClapKit. Забираем исходники:

git clone https://github.com/macinlink/clapkit.git

Сборка построена на cmake, но перед тем как собирать Clapkit, необходимо указать путь к Retro68 в скрипте сборки:

# Ensure Retro68 toolchain is set BEFORE defining project
set(CMAKE_TOOLCHAIN_FILE "/opt/src/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake")

и чуть ниже:

# Define Retro68 path properly
set(RETRO68_PATH /opt/src/Retro68-build/toolchain/m68k-apple-macos)

К сожалению в проекте есть небольшой баг с пропущенными заголовками, из-за которых он не собирается.

Для исправления достаточно добавить в include/ckTypes.h два импорта:

#include <Quickdraw.h>
#include <Events.h>

В репозитории проекта находится готовый Showcase с демонстрацией возможностей фреймворка, на базе которого я и делал свое тестовое приложение (см. ниже).

Так выглядит сам Showcase в работе:

Напоминаю, что все это создано с помощью кросс-компиляции и затем запущено в целевой MacOS 7.

Напоминаю, что все это создано с помощью кросс-компиляции и затем запущено в целевой MacOS 7.

Выглядит заметно веселее, чем примеры из самого Retro68, согласитесь.

Тестовый образец

Я не хотел сразу пускаться во все тяжкие и портировать Doom/Quake/Cyberpunk 2077 под винтажные Маки из 90х — надо же оставить место воображению, поэтому мой тестовый образец для этой статьи это в первую очередь пример автономного, отделяемого приложения с минимальной логикой.

Которое собирается без привязки к иерархии каталогов Clapkit или Retro68.

Проект выложен в отдельном репозитории на Github.

Так мое приложение выглядит в работе на MacOS 7:

Все что оно делает:

отображает меню «Yo» в Finder, с единственным пунктом «Run me», по клику на который вызывается модальный диалог с двумя кнопками. По нажатию на «Quit» произойдет завершение работы программы.

Фигня-фигней, но только разработано и собрано оно полностью и целиком вне инфраструктуры MacOS и без средств разработки от Apple, даже без техники Apple.

На современном С++, под FreeBSD темной питерской ночью.

Так выглядит основной код на C++, файл main.cpp:

#include "main.h"
#include <ckMenu.h>

CKTestAlexs* app;

int main() {
// класс переименован ради тестов
app = CKNew CKTestAlexs();
// false - не использовать стандартные пункты меню
CKMenuBar* menuBar = CKNew CKMenuBar(false);
// добавляем свой пункт меню в Finder
CKMenu* menuTests = CKNew CKMenu("Yo");
menuBar->AddMenu(menuTests);
// затем элемент в выпадающем списке
CKMenuItem* item = CKNew CKMenuItem("Run me", 'R', [&item](CKEvent e) {
// по клику произойдет отображение стандартного
// модального диалога
app->CKNewMsgBoxNote("Welcome to old school!",
"Hello world", "Mkay", "Quit", [](int button) {
// если нажали Quit - завершить работу приложения.
if (button == 0) {
app->CKQuit();
}
});
});
// связывание элемента с пунктом меню
menuTests->AddItem(item);
// связывание меню с приложением
app->CKSetMenu(menuBar);
// бесконечный цикл ожидания для отрисовки,
// без которого приложение сразу завершится
while (!app->CKLoop(5));
delete app;
return 0;
}

Класс описан в заголовке main.h, декларации методов я убрал за ненадобностью:

#include <ckApp.h>

class CKTestAlexs : public CKApp {
};

Так выглядит скрипт сборки для cmake, как можно заметить тут происходит автоматическое скачивание родительского фреймворка Clapkit и наложение патча с пропущенными импортами (описаны выше):

cmake_minimum_required(VERSION 3.16)

# Ensure Retro68 toolchain is set BEFORE defining project
set(RETRO68_PATH "/opt/src/Retro68-build/toolchain/m68k-apple-macos")
set(CMAKE_TOOLCHAIN_FILE "${RETRO68_PATH}/cmake/retro68.toolchain.cmake")

project(clapkit VERSION 1.0)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Include Retro68 headers
include_directories(${RETRO68_PATH}/include)

# Set default build type to Release if not specified
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type (Debug or Release)" FORCE)
endif()

set(CLAPKIT_LOCAL_PATH "${CMAKE_SOURCE_DIR}/../../")
option(USE_LOCAL_CLAPKIT "Use local checkout of clapkit instead of fetching from Git" ON)

if(USE_LOCAL_CLAPKIT AND EXISTS "${CLAPKIT_LOCAL_PATH}/CMakeLists.txt")
message(STATUS "Using local clapkit at ${CLAPKIT_LOCAL_PATH}")
add_subdirectory(${CLAPKIT_LOCAL_PATH} clapkit)
set(USE_LOCAL_CLAPKIT ON)
else()

set(cktypes_patch git apply ${CMAKE_SOURCE_DIR}/patches/cktypes.patch)

message(STATUS "Fetching clapkit from GitHub...")
include(FetchContent)
FetchContent_Declare(
clapkit
GIT_REPOSITORY https://github.com/macinlink/clapkit.git
GIT_TAG main
PATCH_COMMAND ${cktypes_patch}
UPDATE_DISCONNECTED 1
)
FetchContent_MakeAvailable(clapkit)
set(USE_LOCAL_CLAPKIT OFF)
endif()

# Add application
add_application(CKTestAlexs
TYPE "APPL"
CREATOR "CKTS"
main.cpp
cktest.r
)

# Debug vs Release settings
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Configuring Debug Build")
target_compile_definitions(CKTestAlexs PRIVATE kCKAPPDEBUG=1)
target_compile_definitions(clapkit PRIVATE kCKAPPDEBUG=1)

set_target_properties(CKTestAlexs PROPERTIES
COMPILE_FLAGS "-O0 -Wall -g -fdata-sections -ffunction-sections"
LINK_FLAGS "-Wl,--mac-single"
)

elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
message(STATUS "Configuring Release Build")
target_compile_definitions(CKTestAlexs PRIVATE NDEBUG) # Disable debugging in Release
target_compile_definitions(clapkit PRIVATE NDEBUG)

set_target_properties(CKTestAlexs PROPERTIES
COMPILE_FLAGS "-s -O1 -Wall -fmerge-all-constants -fmerge-constants -fstrict-aliasing -fomit-frame-pointer -fdata-sections -ffunction-sections -finline-functions"
LINK_FLAGS "-Wl,--mac-single -Wl,--mac-strip-macsbug"
)
endif()

# Link clapkit
target_link_libraries(CKTestAlexs PRIVATE clapkit)

Поскольку пути к Retro68 задаются внутри скрипта сборки, а фреймворк Clapkit автоматически скачивается из Github, сама сборка максимально упрощена:

mkdir build
cd build
cmake ..
gmake

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

Продолжение банкета

Ниже несколько интересных (но все еще социально одобряемых) идей, на тему что еще можно сделать с эмулятором винтажного Macintosh.

Для начала, можно довести накал программерского угара до предела — интегрировав Retro68 с полноценным IDE и отладчиком:

Developing vintage 68K Macintosh apps with CodeLite IDE, Retro68 and pce-macplus emulator

С автодополнением из среды разработки:

С запуском собранного приложения в эмуляторе сразу из среды разработки:

И даже с удаленной отладкой через эмуляцию последовательного порта:

Тут можно найти отдельное видео с демонстрацией работы.

Следующая замечательная идея в моем списке это очевидная попытка использовать Rust для кросс-компиляции под старые Mac. Нет, автор не шутит, он действительно это сделал:

Through some luck and a little persistence I have actually managed to get Rust code running on classic Mac OS (I’ve tried Mac OS 7.5 and 8.1)

Репозиторий находится тут, проект достаточно свежий (2023 год) и вполне рабочий.

Но предупреждаю сразу, что от исходного кода может случиться сердечный приступ, если любите классический C — на это лучше не смотреть.

Так оно выглядит в работе:

Кстати приложение сетевое, так что на Rust реализована не только работа с интерфейсом, но и с TCP/IP и даже HTTP протоколом.

Для операционной системы из 1994 года.

P.S.

Статья была опубликована на Хабре, более вольный оригинал как обычно в нашем блоге, форк Retro68 с поддержкой сборки на FreeBSD выложен в отдельном репозитории на Github.

Показать полностью 41
5

Sun-2 Workstation в эмуляторе

Серия Некромантия старой школы

На экране стильно оформленная FreeBSD, в которой под задорную песенку происходит загрузка SunOS 2.0 из 1985 года:

Этим роликом можно приманивать сисадминов ;)

Сам эмулятор выложен на Github, но работает только под BSD-системами.

Показать полностью
37

Заводной абрикос

Серия Некромантия старой школы

Помимо всем известной Apple, на свете существовала еще одна «фруктовая» компания, выпускавшая очень популярные компьютеры.

И сейчас мы цинично оживим и запустим эмулятор этих замечательных машин.

Главный герой все же справа а не слева.

Главный герой все же справа а не слева.

Поскольку и сама компания и ее компьютеры и даже их эмулятор (вместе с его автором)  — с берегов «туманного альбиона», большая часть ссылок в статье ведет в никуда на ресурсы, заблокированные для доступа из РФ, родной РКН к этому никакого отношения не имеет.

Поэтому надеваем монокли, цилиндры и поднимаем тост «За обход иностранных блокировок».

Кто бы мне сказал еще десять лет назад, что попасть на фанатский сайт о старых британских компьютерах станет сложнее, чем на официальный сайт Северной Кореи.

Его звали "Apricot"

Изучая материалы из недавнего компьютерного прошлого, в который уж раз убеждаюсь:

за каждой успешной историей в ИТ есть натуральное кладбище из неудач и провалов.

А нынешние и всем известные «лидеры ИТ-индустрии» были отнюдь не первыми в своем деле и часто далеко не самыми инновационными. Еще у людей короткая память:

вчерашний «лидер рынка» и «король продаж» может легко и просто, а главное — невероятно быстро пропасть с концами из информационного поля.

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

Apricot Computers Ltd., originally Applied Computer Techniques Ltd. (ACT), was a British electronic company active from 1965 to 2005.

Как вам такие факты:

  • Who owned up to 30% market share in the UK, extended its sales in the USA and was ahead of IBM in the mid-80s in Europe?

  • Who was the first to launch speech recognition system for PC… in 1984?

  • Who introduced the first 3.5’’ floppy drive? The infrared trackball ? The keyboard with programmable functions keys along with a built-in LCD screen?

  • Who decided to deliver stylish designs, high resolution screens (800×400 in 1983), through a fully integrated conception in Scotland, allowing to manufacture in the early 90s one of the world’s most secure x86-based PCs?

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

Так выглядел один из «абрикосов», предназначенный для корпоративного рынка:

<a href="https://pikabu.ru/story/zavodnoy_abrikos_14063656?u=https%3A%2F%2Fclassic.technology%2Fwp-content%2Fuploads%2F2017%2F10%2Fapricot_xi.pdf&t=%D0%A2%D1%83%D1%82&h=ba2d230b90be5629622fd4f923e9dc9292c97030" title="https://classic.technology/wp-content/uploads/2017/10/apricot_xi.pdf" target="_blank" rel="nofollow noopener">Тут</a> в высоком разрешении.

Тут в высоком разрешении.

Название к кириллице разумеется отношения не имеет — на экране отнюдь не буква «Ж», а стилизованное «Xi».

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

Эмулятор

Эмулятор компьютеров Apricot называется QDAE:

QDAE is a Quick and Dirty Apricot Emulator for Linux, Windows and MacOS X. This version emulates the Apricot F1, Xi and Portable; it may support other F-series and PC-series Apricots as well.

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

Сам эмулятор полностью оправдывает название «Quick & Dirty», поскольку был создан действительно «на коленке», на основе кодовой базы DOS-приложения а стабильность его работы — примерно как у Windows 95 оставляет желать лучшего.

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

Но разумеется все это меня не остановило.

Готовая сборка QDAE существует только для Windows, как оказалось в дальнейшем, автор эмулятора создавал эти сборки с помощью кросс-компиляции из-под Linux, причем очень старым компилятором.

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

Исходники находятся на личном сайте автора, никаких копий на GitHub обнаружено не было. Поэтому забирать придется оттуда:

wget https://www.seasip.info/Unix/QDAE/qdae-0.0.10.tar.gz

Также архив с исходниками присутствует в Windows-версии эмулятора — будет лежать в каталоге установленного приложения. На всякий случай оставлю еще пару линков на сборки, поскольку непонятно как долго еще будет существовать личный сайт автора.

Образы ROM

Первой проблемой с этим эмулятором оказалось полное отсутствие ROM-файлов, необходимых для работы. Сам автор с истинно британским юмором советует «снять дамп с работающей машины»:

For copyright reasons, QDAE is not supplied with any BIOS ROMs or disk images. Accordingly, when you launch QDAE for the first time, it will abort with the message: "Could not open f1.rom". You will need a dump of the F1 ROM (the F10 ROM is not suitable; the F2 ROM may work but has not been tested).

Если у вас есть возможность сгонять на выходные в Лондон, найти там одну из примерно таких сохранившихся машин:

И затем уломать владельца на проведение жестоких экспериментов с его музейным экспонатом — проблемы разумеется нет.

Но я был не в настроении путешествовать и подумал, что будет разумнее поискать эти самые ROM в сети.

И немедленно нашел прекрасное:

Только вдумайтесь:

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

Представляете как надо было запугать людей? Зато обнаружился и легкий намек на то, как эти самые образы можно получить:

Дальнейшие изыскания показали, что образы вообщем-то в сети есть, причем их довольно много. Только с ними есть нюанс:

Файлов ROM оказалось два.

А эмулятору нужен один.

Что это вообще такое и как быть?

Не буду утруждать читателя всей историей изысканий, но мои поиски в итоге привели к этому gist:

Use this script to merge a pair of even+odd / low+high roms into a single file. You'll need to do this for games which have 16-bit CPUs which use 8-bit ROMs. Then, once you've merged each high/low pair, concatenate all the merged pairs into one single file to use in your disassembler.

Приведу код скрипта целиком:

#!/usr/bin/perl
#
# Merge a pair of hi/low byte roms into a single file
#
# Usage: merger.pl <low_or_even_byte_rom> <high_or_odd_byte_rom> >outputfile.bin
open LO, $ARGV[0] || die $!;
open HI, $ARGV[1] || die $!;

$i=0;
while(!(eof(LO) | eof(HI)))
{
$a=getc(LO);
print $a;

$a=getc(HI);
print $a;
}

Тут происходит чтение LO и HI-файлов, переданных в качестве аргументов а затем их побайтовая перекодировка в символы:

getc returns the next character from the input file attached to FILEHANDLE

В этом-то и была главная хитрость, выносившая мне мозг пару недель — надо не просто слить два ROM-файла в один, а еще и перекодировать.

Образы дисков

С дисками все оказалось сильно проще, они неплохо каталогизированы и доступны для скачивания:

Еще на известном Archive.org выложена огромная коллекция образов (~90Гб!), среди которых присутствуют интересные образы дисков и для машин Apricot.

Запуск и работа

При попытке запуска версии для Windows, эмулятор откажется работать, выдав сообщение о том что ROM-файлы не найдены:

ROM-файлы читаются из каталога ~/.qdae/Roms, либо из %USERPROFILE%/Documents/QDAE в Windows.

Однако имена самих файлов зашиты в коде, например для машины «Apricot F1» файл называется f1.rom. Соответственно для того чтобы ROM-файл был найден и загружен эмулятором — недостаточно просто положить его в нужный каталог, нужно еще и соблюсти именование.

Напоминаю:

Без ROM-файлов эмулятор не заработает, совсем.

Как уже было отмечено выше, ROM-файл еще нужно собрать из двух частей, поскольку все доступные в интернете образы разделены на HI и LO части. В качестве примера, покажу весь процесс на ROM-файле для Apricot F1.

Скачиваем архив, например отсюда или отсюда.

Как нетрудно догадаться по адресам сайтов, эти ROM были созданы для более известного и популярного эмулятора Mame, но мы ведь не ищем легких путей, правда?

В архиве будет два файла, которые необходимо соединить в один:

Вот так выглядит вся цепочка:

perl merger.pl lo_f1_1.6.8f hi_f1_1.6.10f > f1.rom

Копируем полученный ROM в домашний каталог с эмулятора:

cp f1.rom ~/.qdae/Roms/

Дальше можно пробовать запускать c использованием образа диска apr00007.dsk:

/opt/own/qdae/bin/qdae ~/Downloads/apr00007.dsk

Будет загружен MS-DOS 2.11 прямиком из 1984 года, так это выглядит:

Сборка

Если вы считаете себя нормальным или хотя-бы психически стабильным — просто скачайте готовую Windows-версию, благо она отлично устанавливается и затем запускается с помощью Wine.

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

Скачав и распаковав архив с исходниками:

wget https://www.seasip.info/Unix/QDAE/qdae-0.0.10.tar.gz
tar xvf ~/Downloads/qdae-0.0.10.tar.gz

Получим каталог с набором трешевых исходников на C и C++ и скриптов сборки (autotools разумеется):

cd qdae-0.0.10
./configure --prefix=/opt/own/qdae

Сборка происходила на Linux Manjaro, ниже будут детали и особенности только по этому дистрибутиву. Эмулятор использует известную библиотеку SDL, причем первую версию, убедитесь что она установлена:

Как видите, я использовал даже не саму 1.х версию а слой совместимости для более современного SDL2

Как видите, я использовал даже не саму 1.х версию а слой совместимости для более современного SDL2

Запускаем сборку командой make и готовимся к первому «боссу». Первая ошибка, которая появляется при сборке на Linux выглядит так:

compress.c: In function ‘comp_open’:
compress.c:137:37: error: implicit declaration of function ‘major’ [-Wimplicit-function-declaration]
137 | if (S_ISBLK(st.st_mode) && (major(st.st_rdev) == 2)) return DSK_ERR_NOTME;

Связана она с тем что функции major и minor объявлены устаревшими в заголовках текущей версии ядра Linux:

/* BSD defines `major', `minor', and `makedev' in this header.
However, these symbols are likely to collide with user code, so we are
going to stop defining them here in an upcoming release. Code that needs
these macros should include <sys/sysmacros.h> directly. Code that does
not need these macros should #undef them after including this header. */
# define __SYSMACROS_DEPRECATED_INCLUSION
# include <sys/sysmacros.h>
# undef __SYSMACROS_DEPRECATED_INCLUSION

Для исправления, необходимо добавить использование заголовка sys/sysmacros.h в начало файла LibDsk/lib/compress.c и перезапустить сборку.

Следующая ошибка, также связанная с этой проблемой выглядит так:

drvlinux.c: In function ‘linux_open’:
drvlinux.c:182:13: error: implicit declaration of function ‘major’ [-Wimplicit-function-declaration]
182 | if (major(st.st_rdev) != 2) return DSK_ERR_NOTME;

Исправление аналогично предыдущей ошибке — просто добавляем эти строки в начало файла LibDsk/lib/drvlinux.c:

#include <sys/sysmacros.h>

После перезапуска сборки, появится куча ошибок вида:

f1_keyboard.cxx:57:32: error: invalid use of incomplete type ‘struct tm’
57 | pkt[ 3] = 0x403 | ((ptm->tm_hour % 10) << 4);
| ^~

Связаны эти ошибки с изменением структуры заголовков, конкретно — с переносом описания структуры времени из sys/time.h в просто time.h.

Для исправления ситуации, необходимо добавить включение этого заголовка в файле bin/sysdep.h:

#include <time.h>

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

Поэтому необходимо выполнить установку:

make install

В каталоге /opt/own/qdae появится сборка эмулятора, бинарник будет находиться в каталоге /opt/own/qdae/bin.

И уже отсюда собранный эмулятор можно наконец запустить.

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

Мигающие индикаторы фиска и флоппи - как раз легкий намек на отсутствующий загрузочный диск.

Казалось бы все и вот она — победа, достойный результат многомесячного превозмогания, гугления и заморочек с ROM-файлами.

Увы но нет, дела с этим эмулятором обстояли куда сложнее, чем казалось изначально.

Внимание на экран:

На этом интересном месте происходит зависание эмулятора, отладчика и эмулируемой ОС — проще говоря:

наступает полный и тотальный.. конец всему.

Полный Пэ

Перед вами баг в эмуляторе компьютеров из 1980х от компании, которой больше не существует. Доживших до наших дней, действующих компьютеров Apricot осталось крайне мало, ближайший находится где-то в Лондоне.

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

Чтобы просто запустить эту йобу, пришлось потратить месяц на поиск и сборку ROM-файлов. Более-менее работает лишь Windows-версия, собранная последний раз в 2012м году.

Для Windows 7.

Мануалов фактически нет, исходный код внутри такой, что одним своим видом может напугать неподготовленного человека.

Даже без знания C/C++.

Ну что, взялись бы за работу по исправлению при таких-то вводных?

Письмо автору

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

Greetings Mr. Elliott.

I'm trying to resurrect the QDAE emulator and found a problem that I cannot solve.

I was able to fix the build process on Linux, found and successfully merged ROM files, found working disk images. But when emulator loads any graphical environment (ex. Activity) — emulated OS crashes or reboots.

Same problem persist with all types of emulated machines: right after it goes into graphics mode — emulated OS reboots or crashes.

I’ve tried to use this «server version» of MS DOS, found some disk images without automatic start for graphics. That worked and was more-less stable. But without graphics. Not fun.

Then tried to reduce speed ticks (in source code) — down to 1000, 500 or even 100 — emulation has became much slower, but issue not gone.

Tried to use fake year (1985) instead of calculated from the current timestamp — also didn’t help.

I’m not asking for exact solution, just point to right direction, because issues like that always come from something small or stupid.

There were some minor fixes I did, related to missing headers (due to changes in Linux kernel sources) with date-time functions, but don't think that it could be responsible for described issue.

Как видите, прежде чем писать письмо, было перепробовано много разных вариантов исправления ситуации для такого рода проблем, но ни один не сработал.

Дорога приключений

Собственно при таких раскладах оставалось только два пути:

потратить пару лет жизни (опять) на ковыряние кривых исходников на древнем C++, либо попытаться восстановить сборку Windows-версии, поскольку та по какой-то причине продолжала работать.

Для завершения этой статьи я выбрал второй путь. Так выглядит установка Windows-версии QDAE в Wine:

Инсталлятор NSIS - проект на века ;)

Кстати на ролике выше используется новый 10й Wine, с режимом WOW64 — т.е одна и та же версия может запускать как 32 так и 64-битные приложения, без всяких отдельных префиксов:

Так выглядит запуск Windows-версии эмулятора в Wine:

ROM-файлы необходимо скопировать в каталог .wine/drive_c/Program\ Files\ \(x86\)/QDAE/Lib/Roms/ :

Изучение

Я решил применить свои «особые навыки» и залезть внутрь Windows-версии эмулятора, использовав PE Explorer, который оказывается весьма неплохо работает под Wine:

Ковыряем один эмулятор с помощью инструментов, запущенных в другом эмуляторе.

Ковыряем один эмулятор с помощью инструментов, запущенных в другом эмуляторе.

Конечно я догадывался, что шансов встретить серьезную защиту в таком ПО не очень много, поэтому не заняло много времени выяснить ряд важных деталей:

  1. сборка Windows-версии осуществлялась кросс-компиляцией из Linux, с помощью MinGW окружения;

  2. использовалась 32-битная версия компилятора и соответственно получился 32-битный бинарник;

  3. использовалась отдельная библиотека ministl (набор заголовков), вместо обычного STL — см. ниже.

Версия MinGW, используемого автором для сборки эмулятора оказалась невероятно древней:

Чтобы вы оценили всю винтажность этой штуки, нашел информацию о релизе:

GCC-2.95.2 for Mingw (i386-mingw32) -- Release information =================================================================== Release date: Nov 7, 1999. I'm pleased to announce prebuilt gcc-2.95.2 packages for GNU Mingw (i386-mingw32).

1999 год!

И вот этой ископаемой штукой, автор QDAE делал сборки своего эмулятора аж до 2012 года, причем из-под Linux.

Но это еще не все.

История с ministl

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

В случае программирования на C++ такой вещью является кастомный STL — «левая» реализация (от Васяна) стандартной библиотеки шаблонов «в переводе Гоблина».

Это самый темный угол C++, кладезь бесконечных и самых феерических багов, король дичи и программного треша, которые только можно сотворить в этом замечательном языке.

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

Думаю вы уже догадались, что автор QDAE как раз из таких использовал кастомный ministl при создании сборок своего эмулятора:

Тут должно быть драматическое молчание и МХАТовская пауза — для осознания.

Чиним сборку с ministl

Коль уж мы идем по пути восстановления сборки — придется пытаться собрать эмулятор с этим недоразумением вместо нормального STL.

Для этого необходимо запустить скрипт configure с указанием специального параметра:

./configure --with-ministl

И заново запустить сборку:

make clean
make

Разумеется сборка немедленно упадет:

Вы правда думали, что код на C++ из 1996 года соберется в современном окружении?

Вы правда думали, что код на C++ из 1996 года соберется в современном окружении?

Хотя конкретно эта ошибка исправляется легко и просто — достаточно заменить устаревший заголовок <iostream.h> на просто <iostream>:

#include <iostream>

Сохраняем изменения в файле ministl/bstring.h и перезапускаем сборку. Но вот дальше.. дальше начинается ад и вьетнамские джунгли:

Хотя за исправление такого треша мне и платят.

Хотя за исправление такого треша мне и платят.

Вас ожидает простыня ошибок из самых разных интересных мест, общий смысл которых:

иди своей дорогой сталкер, тебе тут не рады

Как понять, что вас ждут ад и погибель удивительные приключения и сутки тяжелой отладки?Копирайт с датами начала 90х в заголовке исходника на C++:

Copyright (c) 1994-1995 Modena Software Inc.,

Стоит рассказать потомкам, откуда вообще взялся этот bstring.h, вот так выглядит его оргинал из 1996 года. Все дело в том, что на свете есть одна известная и очень старая книжка по C++, которая называется:

STL Tutorial and Reference Guide:C++ Programming with the Standard Template Library

By David R. Musser and Atul Saini
Addison-Wesley Professional Computing Series
ISBN 0-201-63398-1 Hardcover 432 pages * 1996

Книга, повторюсь, известная (даже я о ней слышал), думаю кое-кто из читателей держал такую на полке в свое время:

В комплекте с книгой шли примеры исходного кода на C++, одним из которых как раз и был наш bstring.h. Но это все лирика, реалии к сожалению таковы, что сил моих на исправление и переделку под современный C++17 этого древнего шаблона уже не хватило.

Точнее хватить-то хватило (на bstring.h), но обновленная версия ministl сломала весь остальной проект эмулятора, с концами.

Поэтому я его просто.. удалил.

Да, это еще одно тайное знание о заменяемом STL — возможность замещения системных шаблонов по частям.

На самом деле удалить нужно лишь файл string, из которого уже включается bstring.h:

rm ministl/string

Точно также я поступил и с vector.h, где вылезла следующая ошибка на тему новых стандартов и ограничений:

error: ‘void* operator new(size_t, void*)’ may not be declared as static

Объяснить с

Затем с list.h и ошибкой:

h6301.hxx:71:14: error: ‘list’ in namespace ‘std’ does not name a template type
71 | std::list<unsigned char> m_input;
| ^~~~

Наконец последняя ошибка, связанная с ministl:

Path.cxx:199:9: error: ‘sort’ was not declared in this scope; did you mean ‘short’?
199 | sort(v.begin(), v.end());
| ^~~~

«Исправил» ее я аналогичным образом — цинично удалив заголовок ministl/algorithm.

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

Но и использовать «васянские» STL вместо стандартных — экстрим еще тот.

Со всеми этими правками, костылями и патчами сборка эмулятора наконец успешно завершается.

(бурные аплодисменты)

Но только собранный эмулятор все также не работает, зависая ровно на том же самом месте.

З2 веселых бита

Как мы уже успели выяснить выше, работающая сборка эмулятора под Windows — 32-битная и была создана 32-битным компилятором, поэтому следующий логичный шаг это попытка сборки 32-битной версии.

И скажу сразу:

в современной системе такая сборка — то еще скотство

Нужно будет установить gcc multilib и 32-битные версии библиотек: SDL и всех остальных используемых библиотек, например libxml2. И все зависимости.

Так выглядит набор параметров, передаваемых скрипту configure для сборки и линковки 32-битного приложения в 64-битном окружении:

./configure --build=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32

Если скрипт и проследующая сборка пройдут без ошибок, в каталоге bin появится 32-битный бинарник:

Который наконец заработает как надо.

Результат

Показываю наконец результат всех этих адских мучений:

эмулируемые системы Apricot в действии.

Обратите внимание на даты — многие из читателей имеют отцов, которые младше этих систем;)

Использован образ диска: apr00230.dsk , описание:

apricot SOFTWARE *** BETA TEST COPY ***

Date Issued:15/07/85

Return by:29/07/85

F1 (UK) MSDOS 2.11 BIOS 1.6 Disk One - Activity, Tutor Disk Two - Diary,Sketch,Async,GWBASIC 1F1U04B Disk 1 of 3

Образ диска: apr00256.dsk , описание:

APRICOT DEMONSTRATION PICTURES BIOS V1.4 JAN 1984

Так выглядел далекий предок Microsoft World

Образ диска: apr00076.dsk , описание:

24/4/84 PS PSMATE SUB-MASTER 211 NOT FOR RELEASE

Образ диска: apr00190.dsk , описание:

2.6 BOOT PC/XI WITH LINKWORD INC MSBASIC MASTER 61

Образ диска: apr00264.dsk , описание:

BASIC GAMES, ENCHANTE, MASON, QUEST MASTER 19

В качестве эпилога:

P.S.

Статья была опубликована на Хабре, более вольный оригинал как обычно в нашем блоге.

Будут еще статьи по Apricot, поскольку не влезла история с 32-битной сборкой эмулятора на FreeBSD и установкой первых версий Windows.

Ntcn

Показать полностью 31
7

Запуск Doom на IBM AS/400

Серия Некромантия старой школы

Отвечая за запросы читателей, показываю как выглядит запуск Doom на этой столь редкой системе.

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

Небольшой ролик как это выглядит:

Показать полностью 1
6

Восстановлен оригинальный редактор карт DoomEd на NeXT

Серия Некромантия старой школы

Многие не в курсе, что Doom разрабатывался на NeXT. Еще меньше народу знает, что Ромеро недавно (всего лишь 10 лет назад) выложил исходники первой версии редактора карт для Doom, как раз для NeXT.

Зато теперь вы знаете, что я собрал этот самый редактор карт DoomEd под NeXT. Из исходников, вот этими самыми руками, да.

Осталось разобраться с текстурами и ресурсами и будет полностью восстановленный процесс разработки оригинального Doom.😍
Кстати Ромеро в своем посте выложил еще и "unreleased soundtrack" - дополнительные мелодии, не вошедшие в оригинальный Doom, с которым рекомендую ознакомиться.

В качестве пруфа.

В качестве пруфа.

На скриншоте выше эмулятор NeXT с NeXTSTEP, сетью, средой разработки и собранным редактором карт для Doom - именно той версии, которая использовалась Ромеро для оригинальной разработки.

Собственно запуск оригинального Doom под NeXT, задолго до того как он появится под MS-DOS:

Более развернутое обсуждение было в нашем канале, сейчас пилим полный процесс оригинального картостроения - выйдет большой разбор.

Показать полностью 1 1
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества